Loading services/audioflinger/Threads.cpp +27 −7 Original line number Diff line number Diff line Loading @@ -5359,7 +5359,8 @@ void AudioFlinger::AsyncCallbackThread::setAsyncError() AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, uint32_t device, bool systemReady) : DirectOutputThread(audioFlinger, output, id, device, OFFLOAD, systemReady), mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true) mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true), mOffloadUnderrunPosition(~0LL) { //FIXME: mStandby should be set to true by ThreadBase constructor mStandby = true; Loading Loading @@ -5569,12 +5570,30 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr // No buffers for this track. Give it a few chances to // fill a buffer, then remove it from active list. if (--(track->mRetryCount) <= 0) { bool running = false; if (mOutput->stream->get_presentation_position != nullptr) { uint64_t position = 0; struct timespec unused; // The running check restarts the retry counter at least once. int ret = mOutput->stream->get_presentation_position( mOutput->stream, &position, &unused); if (ret == NO_ERROR && position != mOffloadUnderrunPosition) { running = true; mOffloadUnderrunPosition = position; } ALOGVV("underrun counter, running(%d): %lld vs %lld", running, (long long)position, (long long)mOffloadUnderrunPosition); } if (running) { // still running, give us more time. track->mRetryCount = kMaxTrackRetriesOffload; } else { ALOGV("OffloadThread: BUFFER TIMEOUT: remove(%d) from active list", track->name()); tracksToRemove->add(track); // indicate to client process that the track was disabled because of underrun; // it will then automatically call start() when data is available track->disable(); } } else if (last){ mixerStatus = MIXER_TRACKS_ENABLED; } Loading Loading @@ -5631,6 +5650,7 @@ void AudioFlinger::OffloadThread::flushHw_l() mPausedBytesRemaining = 0; // reset bytes written count to reflect that DSP buffers are empty after flush. mBytesWritten = 0; mOffloadUnderrunPosition = ~0LL; if (mUseAsyncWrite) { // discard any pending drain or write ack by incrementing sequence Loading services/audioflinger/Threads.h +4 −0 Original line number Diff line number Diff line Loading @@ -1027,6 +1027,10 @@ private: size_t mPausedWriteLength; // length in bytes of write interrupted by pause size_t mPausedBytesRemaining; // bytes still waiting in mixbuffer after resume bool mKeepWakeLock; // keep wake lock while waiting for write callback uint64_t mOffloadUnderrunPosition; // Current frame position for offloaded playback // used and valid only during underrun. ~0 if // no underrun has occurred during playback and // is not reset on standby. }; class AsyncCallbackThread : public Thread { Loading Loading
services/audioflinger/Threads.cpp +27 −7 Original line number Diff line number Diff line Loading @@ -5359,7 +5359,8 @@ void AudioFlinger::AsyncCallbackThread::setAsyncError() AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, uint32_t device, bool systemReady) : DirectOutputThread(audioFlinger, output, id, device, OFFLOAD, systemReady), mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true) mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true), mOffloadUnderrunPosition(~0LL) { //FIXME: mStandby should be set to true by ThreadBase constructor mStandby = true; Loading Loading @@ -5569,12 +5570,30 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::OffloadThread::prepareTr // No buffers for this track. Give it a few chances to // fill a buffer, then remove it from active list. if (--(track->mRetryCount) <= 0) { bool running = false; if (mOutput->stream->get_presentation_position != nullptr) { uint64_t position = 0; struct timespec unused; // The running check restarts the retry counter at least once. int ret = mOutput->stream->get_presentation_position( mOutput->stream, &position, &unused); if (ret == NO_ERROR && position != mOffloadUnderrunPosition) { running = true; mOffloadUnderrunPosition = position; } ALOGVV("underrun counter, running(%d): %lld vs %lld", running, (long long)position, (long long)mOffloadUnderrunPosition); } if (running) { // still running, give us more time. track->mRetryCount = kMaxTrackRetriesOffload; } else { ALOGV("OffloadThread: BUFFER TIMEOUT: remove(%d) from active list", track->name()); tracksToRemove->add(track); // indicate to client process that the track was disabled because of underrun; // it will then automatically call start() when data is available track->disable(); } } else if (last){ mixerStatus = MIXER_TRACKS_ENABLED; } Loading Loading @@ -5631,6 +5650,7 @@ void AudioFlinger::OffloadThread::flushHw_l() mPausedBytesRemaining = 0; // reset bytes written count to reflect that DSP buffers are empty after flush. mBytesWritten = 0; mOffloadUnderrunPosition = ~0LL; if (mUseAsyncWrite) { // discard any pending drain or write ack by incrementing sequence Loading
services/audioflinger/Threads.h +4 −0 Original line number Diff line number Diff line Loading @@ -1027,6 +1027,10 @@ private: size_t mPausedWriteLength; // length in bytes of write interrupted by pause size_t mPausedBytesRemaining; // bytes still waiting in mixbuffer after resume bool mKeepWakeLock; // keep wake lock while waiting for write callback uint64_t mOffloadUnderrunPosition; // Current frame position for offloaded playback // used and valid only during underrun. ~0 if // no underrun has occurred during playback and // is not reset on standby. }; class AsyncCallbackThread : public Thread { Loading