Loading include/media/AudioRecord.h +1 −1 Original line number Diff line number Diff line Loading @@ -275,7 +275,7 @@ public: STOPPED = 1 }; status_t obtainBuffer(Buffer* audioBuffer, bool blocking); status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount); void releaseBuffer(Buffer* audioBuffer); Loading include/media/AudioTrack.h +1 −1 Original line number Diff line number Diff line Loading @@ -358,7 +358,7 @@ public: STOPPED = 1 }; status_t obtainBuffer(Buffer* audioBuffer, bool blocking); status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount); void releaseBuffer(Buffer* audioBuffer); Loading include/media/ToneGenerator.h +1 −1 Original line number Diff line number Diff line Loading @@ -134,7 +134,7 @@ private: Condition mWaitCbkCond; // condition enabling interface to wait for audio callback completion after a change is requested float mVolume; // Volume applied to audio track int mStreamType; // Audio stream used for output int mProcessSize; // Size of audio blocks generated at a time by audioCallback() (in PCM frames). unsigned int mProcessSize; // Size of audio blocks generated at a time by audioCallback() (in PCM frames). bool initAudioTrack(); static void audioCallback(int event, void* user, void *info); Loading include/private/media/AudioTrackShared.h +8 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,11 @@ namespace android { #define MAX_SAMPLE_RATE 65535 #define THREAD_PRIORITY_AUDIO_CLIENT (ANDROID_PRIORITY_AUDIO) // Maximum cumulated timeout milliseconds before restarting audioflinger thread #define MAX_STARTUP_TIMEOUT_MS 3000 // Longer timeout period at startup to cope with A2DP init time #define MAX_RUN_TIMEOUT_MS 1000 #define WAIT_PERIOD_MS 10 struct audio_track_cblk_t { Loading Loading @@ -55,9 +60,11 @@ struct audio_track_cblk_t int16_t flowControlFlag; // underrun (out) or overrrun (in) indication uint8_t out; // out equals 1 for AudioTrack and 0 for AudioRecord uint8_t forceReady; uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger uint16_t waitTimeMs; // Cumulated wait time // Padding ensuring that data buffer starts on a cache line boundary (32 bytes). // See AudioFlinger::TrackBase constructor int32_t Padding[4]; int32_t Padding[3]; audio_track_cblk_t(); uint32_t stepUser(uint32_t frameCount); Loading media/libmedia/AudioRecord.cpp +27 −19 Original line number Diff line number Diff line Loading @@ -245,6 +245,8 @@ status_t AudioRecord::start() if (android_atomic_or(1, &mActive) == 0) { mNewPosition = mCblk->user + mUpdatePeriod; mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; mCblk->waitTimeMs = 0; if (t != 0) { t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT); } else { Loading Loading @@ -342,7 +344,7 @@ status_t AudioRecord::getPosition(uint32_t *position) // ------------------------------------------------------------------------- status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, bool blocking) status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) { int active; int timeout = 0; Loading @@ -362,14 +364,21 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, bool blocking) active = mActive; if (UNLIKELY(!active)) return NO_MORE_BUFFERS; if (UNLIKELY(!blocking)) if (UNLIKELY(!waitCount)) return WOULD_BLOCK; timeout = 0; result = cblk->cv.waitRelative(cblk->lock, seconds(1)); result = cblk->cv.waitRelative(cblk->lock, milliseconds(WAIT_PERIOD_MS)); if (__builtin_expect(result!=NO_ERROR, false)) { cblk->waitTimeMs += WAIT_PERIOD_MS; if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { LOGW( "obtainBuffer timed out (is the CPU pegged?) " "user=%08x, server=%08x", cblk->user, cblk->server); timeout = 1; cblk->waitTimeMs = 0; } if (--waitCount == 0) { return TIMED_OUT; } } // read the server count again start_loop_here: Loading @@ -382,6 +391,8 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, bool blocking) "but didn't need to be locked. We recovered, but " "this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server); cblk->waitTimeMs = 0; if (framesReq > framesReady) { framesReq = framesReady; } Loading Loading @@ -430,7 +441,9 @@ ssize_t AudioRecord::read(void* buffer, size_t userSize) audioBuffer.frameCount = userSize/mChannelCount/sizeof(int16_t); status_t err = obtainBuffer(&audioBuffer, true); // Calling obtainBuffer() with a negative wait count causes // an (almost) infinite wait time. status_t err = obtainBuffer(&audioBuffer, -1); if (err < 0) { // out of buffers, return #bytes written if (err == status_t(NO_MORE_BUFFERS)) Loading @@ -457,7 +470,7 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) { Buffer audioBuffer; uint32_t frames = mRemainingFrames; size_t readSize = 0; size_t readSize; // Manage marker callback if (mMarkerPosition > 0) { Loading @@ -477,17 +490,19 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) do { audioBuffer.frameCount = frames; status_t err = obtainBuffer(&audioBuffer, false); // Calling obtainBuffer() with a wait count of 1 // limits wait time to WAIT_PERIOD_MS. This prevents from being // stuck here not being able to handle timed events (position, markers). status_t err = obtainBuffer(&audioBuffer, 1); if (err < NO_ERROR) { if (err != WOULD_BLOCK) { if (err != TIMED_OUT) { LOGE("Error obtaining an audio buffer, giving up."); return false; } break; } if (err == status_t(STOPPED)) return false; if (audioBuffer.size == 0) break; size_t reqSize = audioBuffer.size; mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); readSize = audioBuffer.size; Loading @@ -514,13 +529,6 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) } } // If no data was read, it is likely that obtainBuffer() did // not find available data in PCM buffer: we release the processor for // a few millisecond before polling again for available data. if (readSize == 0) { usleep(5000); } if (frames == 0) { mRemainingFrames = mNotificationFrames; } else { Loading Loading
include/media/AudioRecord.h +1 −1 Original line number Diff line number Diff line Loading @@ -275,7 +275,7 @@ public: STOPPED = 1 }; status_t obtainBuffer(Buffer* audioBuffer, bool blocking); status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount); void releaseBuffer(Buffer* audioBuffer); Loading
include/media/AudioTrack.h +1 −1 Original line number Diff line number Diff line Loading @@ -358,7 +358,7 @@ public: STOPPED = 1 }; status_t obtainBuffer(Buffer* audioBuffer, bool blocking); status_t obtainBuffer(Buffer* audioBuffer, int32_t waitCount); void releaseBuffer(Buffer* audioBuffer); Loading
include/media/ToneGenerator.h +1 −1 Original line number Diff line number Diff line Loading @@ -134,7 +134,7 @@ private: Condition mWaitCbkCond; // condition enabling interface to wait for audio callback completion after a change is requested float mVolume; // Volume applied to audio track int mStreamType; // Audio stream used for output int mProcessSize; // Size of audio blocks generated at a time by audioCallback() (in PCM frames). unsigned int mProcessSize; // Size of audio blocks generated at a time by audioCallback() (in PCM frames). bool initAudioTrack(); static void audioCallback(int event, void* user, void *info); Loading
include/private/media/AudioTrackShared.h +8 −1 Original line number Diff line number Diff line Loading @@ -28,6 +28,11 @@ namespace android { #define MAX_SAMPLE_RATE 65535 #define THREAD_PRIORITY_AUDIO_CLIENT (ANDROID_PRIORITY_AUDIO) // Maximum cumulated timeout milliseconds before restarting audioflinger thread #define MAX_STARTUP_TIMEOUT_MS 3000 // Longer timeout period at startup to cope with A2DP init time #define MAX_RUN_TIMEOUT_MS 1000 #define WAIT_PERIOD_MS 10 struct audio_track_cblk_t { Loading Loading @@ -55,9 +60,11 @@ struct audio_track_cblk_t int16_t flowControlFlag; // underrun (out) or overrrun (in) indication uint8_t out; // out equals 1 for AudioTrack and 0 for AudioRecord uint8_t forceReady; uint16_t bufferTimeoutMs; // Maximum cumulated timeout before restarting audioflinger uint16_t waitTimeMs; // Cumulated wait time // Padding ensuring that data buffer starts on a cache line boundary (32 bytes). // See AudioFlinger::TrackBase constructor int32_t Padding[4]; int32_t Padding[3]; audio_track_cblk_t(); uint32_t stepUser(uint32_t frameCount); Loading
media/libmedia/AudioRecord.cpp +27 −19 Original line number Diff line number Diff line Loading @@ -245,6 +245,8 @@ status_t AudioRecord::start() if (android_atomic_or(1, &mActive) == 0) { mNewPosition = mCblk->user + mUpdatePeriod; mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS; mCblk->waitTimeMs = 0; if (t != 0) { t->run("ClientRecordThread", THREAD_PRIORITY_AUDIO_CLIENT); } else { Loading Loading @@ -342,7 +344,7 @@ status_t AudioRecord::getPosition(uint32_t *position) // ------------------------------------------------------------------------- status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, bool blocking) status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount) { int active; int timeout = 0; Loading @@ -362,14 +364,21 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, bool blocking) active = mActive; if (UNLIKELY(!active)) return NO_MORE_BUFFERS; if (UNLIKELY(!blocking)) if (UNLIKELY(!waitCount)) return WOULD_BLOCK; timeout = 0; result = cblk->cv.waitRelative(cblk->lock, seconds(1)); result = cblk->cv.waitRelative(cblk->lock, milliseconds(WAIT_PERIOD_MS)); if (__builtin_expect(result!=NO_ERROR, false)) { cblk->waitTimeMs += WAIT_PERIOD_MS; if (cblk->waitTimeMs >= cblk->bufferTimeoutMs) { LOGW( "obtainBuffer timed out (is the CPU pegged?) " "user=%08x, server=%08x", cblk->user, cblk->server); timeout = 1; cblk->waitTimeMs = 0; } if (--waitCount == 0) { return TIMED_OUT; } } // read the server count again start_loop_here: Loading @@ -382,6 +391,8 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, bool blocking) "but didn't need to be locked. We recovered, but " "this shouldn't happen (user=%08x, server=%08x)", cblk->user, cblk->server); cblk->waitTimeMs = 0; if (framesReq > framesReady) { framesReq = framesReady; } Loading Loading @@ -430,7 +441,9 @@ ssize_t AudioRecord::read(void* buffer, size_t userSize) audioBuffer.frameCount = userSize/mChannelCount/sizeof(int16_t); status_t err = obtainBuffer(&audioBuffer, true); // Calling obtainBuffer() with a negative wait count causes // an (almost) infinite wait time. status_t err = obtainBuffer(&audioBuffer, -1); if (err < 0) { // out of buffers, return #bytes written if (err == status_t(NO_MORE_BUFFERS)) Loading @@ -457,7 +470,7 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) { Buffer audioBuffer; uint32_t frames = mRemainingFrames; size_t readSize = 0; size_t readSize; // Manage marker callback if (mMarkerPosition > 0) { Loading @@ -477,17 +490,19 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) do { audioBuffer.frameCount = frames; status_t err = obtainBuffer(&audioBuffer, false); // Calling obtainBuffer() with a wait count of 1 // limits wait time to WAIT_PERIOD_MS. This prevents from being // stuck here not being able to handle timed events (position, markers). status_t err = obtainBuffer(&audioBuffer, 1); if (err < NO_ERROR) { if (err != WOULD_BLOCK) { if (err != TIMED_OUT) { LOGE("Error obtaining an audio buffer, giving up."); return false; } break; } if (err == status_t(STOPPED)) return false; if (audioBuffer.size == 0) break; size_t reqSize = audioBuffer.size; mCbf(EVENT_MORE_DATA, mUserData, &audioBuffer); readSize = audioBuffer.size; Loading @@ -514,13 +529,6 @@ bool AudioRecord::processAudioBuffer(const sp<ClientRecordThread>& thread) } } // If no data was read, it is likely that obtainBuffer() did // not find available data in PCM buffer: we release the processor for // a few millisecond before polling again for available data. if (readSize == 0) { usleep(5000); } if (frames == 0) { mRemainingFrames = mNotificationFrames; } else { Loading