Loading services/audioflinger/Threads.cpp +35 −29 Original line number Diff line number Diff line Loading @@ -5889,6 +5889,20 @@ uint32_t AudioFlinger::PlaybackThread::trackCountForUid_l(uid_t uid) const return trackCount; } bool AudioFlinger::PlaybackThread::checkRunningTimestamp() { uint64_t position = 0; struct timespec unused; const status_t ret = mOutput->getPresentationPosition(&position, &unused); if (ret == NO_ERROR) { if (position != mLastCheckedTimestampPosition) { mLastCheckedTimestampPosition = position; return true; } } return false; } // isTrackAllowed_l() must be called with ThreadBase::mLock held bool AudioFlinger::MixerThread::isTrackAllowed_l( audio_channel_mask_t channelMask, audio_format_t format, Loading Loading @@ -6317,10 +6331,14 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep // fill a buffer, then remove it from active list. // Only consider last track started for mixer state control if (--(track->mRetryCount) <= 0) { const bool running = checkRunningTimestamp(); if (running) { // still running, give us more time. track->mRetryCount = kMaxTrackRetriesOffload; } else { ALOGV("BUFFER TIMEOUT: remove track(%d) from active list", trackId); 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 // indicate to client process that the track was disabled because of // underrun; it will then automatically call start() when data is available track->disable(); // only do hw pause when track is going to be removed due to BUFFER TIMEOUT. // unlike mixerthread, HAL can be paused for direct output Loading @@ -6331,6 +6349,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep doHwPause = true; mHwPaused = true; } } } else if (last) { mixerStatus = MIXER_TRACKS_ENABLED; } Loading Loading @@ -6540,6 +6559,7 @@ void AudioFlinger::DirectOutputThread::cacheParameters_l() void AudioFlinger::DirectOutputThread::flushHw_l() { PlaybackThread::flushHw_l(); mOutput->flush(); mHwPaused = false; mFlushPending = false; Loading Loading @@ -6675,8 +6695,7 @@ void AudioFlinger::AsyncCallbackThread::setAsyncError() AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, bool systemReady) : DirectOutputThread(audioFlinger, output, id, OFFLOAD, systemReady), mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true), mOffloadUnderrunPosition(~0LL) mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true) { //FIXME: mStandby should be set to true by ThreadBase constructo mStandby = true; Loading Loading @@ -6893,19 +6912,7 @@ 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; uint64_t position = 0; struct timespec unused; // The running check restarts the retry counter at least once. status_t ret = mOutput->stream->getPresentationPosition(&position, &unused); if (ret == NO_ERROR && position != mOffloadUnderrunPosition) { running = true; mOffloadUnderrunPosition = position; } if (ret == NO_ERROR) { ALOGVV("underrun counter, running(%d): %lld vs %lld", running, (long long)position, (long long)mOffloadUnderrunPosition); } const bool running = checkRunningTimestamp(); if (running) { // still running, give us more time. track->mRetryCount = kMaxTrackRetriesOffload; } else { Loading Loading @@ -6976,7 +6983,6 @@ 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 +10 −6 Original line number Diff line number Diff line Loading @@ -1376,6 +1376,14 @@ protected: struct audio_patch mDownStreamPatch; std::atomic_bool mCheckOutputStageEffects{}; // A differential check on the timestamps to see if there is a change in the // timestamp frame position between the last call to checkRunningTimestamp. uint64_t mLastCheckedTimestampPosition = ~0LL; bool checkRunningTimestamp(); virtual void flushHw_l() { mLastCheckedTimestampPosition = ~0LL; } }; class MixerThread : public PlaybackThread { Loading Loading @@ -1493,7 +1501,7 @@ public: virtual bool checkForNewParameter_l(const String8& keyValuePair, status_t& status); virtual void flushHw_l(); void flushHw_l() override; void setMasterBalance(float balance) override; Loading Loading @@ -1558,7 +1566,7 @@ public: OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, bool systemReady); virtual ~OffloadThread() {}; virtual void flushHw_l(); void flushHw_l() override; protected: // threadLoop snippets Loading @@ -1575,10 +1583,6 @@ 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 +35 −29 Original line number Diff line number Diff line Loading @@ -5889,6 +5889,20 @@ uint32_t AudioFlinger::PlaybackThread::trackCountForUid_l(uid_t uid) const return trackCount; } bool AudioFlinger::PlaybackThread::checkRunningTimestamp() { uint64_t position = 0; struct timespec unused; const status_t ret = mOutput->getPresentationPosition(&position, &unused); if (ret == NO_ERROR) { if (position != mLastCheckedTimestampPosition) { mLastCheckedTimestampPosition = position; return true; } } return false; } // isTrackAllowed_l() must be called with ThreadBase::mLock held bool AudioFlinger::MixerThread::isTrackAllowed_l( audio_channel_mask_t channelMask, audio_format_t format, Loading Loading @@ -6317,10 +6331,14 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep // fill a buffer, then remove it from active list. // Only consider last track started for mixer state control if (--(track->mRetryCount) <= 0) { const bool running = checkRunningTimestamp(); if (running) { // still running, give us more time. track->mRetryCount = kMaxTrackRetriesOffload; } else { ALOGV("BUFFER TIMEOUT: remove track(%d) from active list", trackId); 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 // indicate to client process that the track was disabled because of // underrun; it will then automatically call start() when data is available track->disable(); // only do hw pause when track is going to be removed due to BUFFER TIMEOUT. // unlike mixerthread, HAL can be paused for direct output Loading @@ -6331,6 +6349,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep doHwPause = true; mHwPaused = true; } } } else if (last) { mixerStatus = MIXER_TRACKS_ENABLED; } Loading Loading @@ -6540,6 +6559,7 @@ void AudioFlinger::DirectOutputThread::cacheParameters_l() void AudioFlinger::DirectOutputThread::flushHw_l() { PlaybackThread::flushHw_l(); mOutput->flush(); mHwPaused = false; mFlushPending = false; Loading Loading @@ -6675,8 +6695,7 @@ void AudioFlinger::AsyncCallbackThread::setAsyncError() AudioFlinger::OffloadThread::OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, bool systemReady) : DirectOutputThread(audioFlinger, output, id, OFFLOAD, systemReady), mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true), mOffloadUnderrunPosition(~0LL) mPausedWriteLength(0), mPausedBytesRemaining(0), mKeepWakeLock(true) { //FIXME: mStandby should be set to true by ThreadBase constructo mStandby = true; Loading Loading @@ -6893,19 +6912,7 @@ 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; uint64_t position = 0; struct timespec unused; // The running check restarts the retry counter at least once. status_t ret = mOutput->stream->getPresentationPosition(&position, &unused); if (ret == NO_ERROR && position != mOffloadUnderrunPosition) { running = true; mOffloadUnderrunPosition = position; } if (ret == NO_ERROR) { ALOGVV("underrun counter, running(%d): %lld vs %lld", running, (long long)position, (long long)mOffloadUnderrunPosition); } const bool running = checkRunningTimestamp(); if (running) { // still running, give us more time. track->mRetryCount = kMaxTrackRetriesOffload; } else { Loading Loading @@ -6976,7 +6983,6 @@ 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 +10 −6 Original line number Diff line number Diff line Loading @@ -1376,6 +1376,14 @@ protected: struct audio_patch mDownStreamPatch; std::atomic_bool mCheckOutputStageEffects{}; // A differential check on the timestamps to see if there is a change in the // timestamp frame position between the last call to checkRunningTimestamp. uint64_t mLastCheckedTimestampPosition = ~0LL; bool checkRunningTimestamp(); virtual void flushHw_l() { mLastCheckedTimestampPosition = ~0LL; } }; class MixerThread : public PlaybackThread { Loading Loading @@ -1493,7 +1501,7 @@ public: virtual bool checkForNewParameter_l(const String8& keyValuePair, status_t& status); virtual void flushHw_l(); void flushHw_l() override; void setMasterBalance(float balance) override; Loading Loading @@ -1558,7 +1566,7 @@ public: OffloadThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, audio_io_handle_t id, bool systemReady); virtual ~OffloadThread() {}; virtual void flushHw_l(); void flushHw_l() override; protected: // threadLoop snippets Loading @@ -1575,10 +1583,6 @@ 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