Loading services/audioflinger/Threads.cpp +18 −17 Original line number Diff line number Diff line Loading @@ -1565,6 +1565,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge mEffectBufferFormat(AUDIO_FORMAT_INVALID), mEffectBufferValid(false), mSuspended(0), mBytesWritten(0), mFramesWritten(0), mActiveTracksGeneration(0), // mStreamTypes[] initialized in constructor body mOutput(output), Loading Loading @@ -2863,6 +2864,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() // and associate with the sink frames written out. We need // this to convert the sink timestamp to the track timestamp. if (mNormalSink != 0) { // Note: The DuplicatingThread may not have a mNormalSink. // We always fetch the timestamp here because often the downstream // sink will block whie writing. ExtendedTimestamp timestamp; // use private copy to fetch Loading @@ -2872,25 +2874,22 @@ bool AudioFlinger::PlaybackThread::threadLoop() timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]; mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]; // sinkFramesWritten for non-offloaded tracks are contiguous } // mFramesWritten for non-offloaded tracks are contiguous // even after standby() is called. This is useful for the track frame // to sink frame mapping. const int64_t sinkFramesWritten = mNormalSink->framesWritten(); mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = sinkFramesWritten; mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = mFramesWritten; mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime(); const size_t size = mActiveTracks.size(); for (size_t i = 0; i < size; ++i) { sp<Track> t = mActiveTracks[i].promote(); if (t != 0 && !t->isFastTrack()) { t->updateTrackFrameInfo( t->mAudioTrackServerProxy->framesReleased(), sinkFramesWritten, mFramesWritten, mTimestamp); } } } saveOutputTracks(); if (mSignalPending) { Loading Loading @@ -3026,6 +3025,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() mSleepTimeUs = suspendSleepTimeUs(); // simulate write to HAL when suspended mBytesWritten += mSinkBufferSize; mFramesWritten += mSinkBufferSize / mFrameSize; mBytesRemaining = 0; } Loading Loading @@ -3076,6 +3076,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() } else { mBytesWritten += ret; mBytesRemaining -= ret; mFramesWritten += ret / mFrameSize; } } else if ((mMixerStatus == MIXER_DRAIN_TRACK) || (mMixerStatus == MIXER_DRAIN_ALL)) { Loading services/audioflinger/Threads.h +1 −0 Original line number Diff line number Diff line Loading @@ -693,6 +693,7 @@ protected: volatile int32_t mSuspended; int64_t mBytesWritten; int64_t mFramesWritten; // not reset on standby private: // mMasterMute is in both PlaybackThread and in AudioFlinger. When a // PlaybackThread needs to find out if master-muted, it checks it's local Loading services/audioflinger/Tracks.cpp +11 −3 Original line number Diff line number Diff line Loading @@ -960,9 +960,17 @@ bool AudioFlinger::PlaybackThread::Track::presentationComplete( (long long)mPresentationCompleteFrames, audioHalFrames); } if ((!isOffloaded() && !isDirect() && !isFastTrack() && framesWritten >= mPresentationCompleteFrames && mAudioTrackServerProxy->isDrained()) || isOffloaded()) { bool complete; if (isOffloaded()) { complete = true; } else if (isDirect() || isFastTrack()) { // these do not go through linear map complete = framesWritten >= mPresentationCompleteFrames; } else { // Normal tracks, OutputTracks, and PatchTracks complete = framesWritten >= mPresentationCompleteFrames && mAudioTrackServerProxy->isDrained(); } if (complete) { triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE); mAudioTrackServerProxy->setStreamEndDone(); return true; Loading Loading
services/audioflinger/Threads.cpp +18 −17 Original line number Diff line number Diff line Loading @@ -1565,6 +1565,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge mEffectBufferFormat(AUDIO_FORMAT_INVALID), mEffectBufferValid(false), mSuspended(0), mBytesWritten(0), mFramesWritten(0), mActiveTracksGeneration(0), // mStreamTypes[] initialized in constructor body mOutput(output), Loading Loading @@ -2863,6 +2864,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() // and associate with the sink frames written out. We need // this to convert the sink timestamp to the track timestamp. if (mNormalSink != 0) { // Note: The DuplicatingThread may not have a mNormalSink. // We always fetch the timestamp here because often the downstream // sink will block whie writing. ExtendedTimestamp timestamp; // use private copy to fetch Loading @@ -2872,25 +2874,22 @@ bool AudioFlinger::PlaybackThread::threadLoop() timestamp.mPosition[ExtendedTimestamp::LOCATION_KERNEL]; mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL] = timestamp.mTimeNs[ExtendedTimestamp::LOCATION_KERNEL]; // sinkFramesWritten for non-offloaded tracks are contiguous } // mFramesWritten for non-offloaded tracks are contiguous // even after standby() is called. This is useful for the track frame // to sink frame mapping. const int64_t sinkFramesWritten = mNormalSink->framesWritten(); mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = sinkFramesWritten; mTimestamp.mPosition[ExtendedTimestamp::LOCATION_SERVER] = mFramesWritten; mTimestamp.mTimeNs[ExtendedTimestamp::LOCATION_SERVER] = systemTime(); const size_t size = mActiveTracks.size(); for (size_t i = 0; i < size; ++i) { sp<Track> t = mActiveTracks[i].promote(); if (t != 0 && !t->isFastTrack()) { t->updateTrackFrameInfo( t->mAudioTrackServerProxy->framesReleased(), sinkFramesWritten, mFramesWritten, mTimestamp); } } } saveOutputTracks(); if (mSignalPending) { Loading Loading @@ -3026,6 +3025,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() mSleepTimeUs = suspendSleepTimeUs(); // simulate write to HAL when suspended mBytesWritten += mSinkBufferSize; mFramesWritten += mSinkBufferSize / mFrameSize; mBytesRemaining = 0; } Loading Loading @@ -3076,6 +3076,7 @@ bool AudioFlinger::PlaybackThread::threadLoop() } else { mBytesWritten += ret; mBytesRemaining -= ret; mFramesWritten += ret / mFrameSize; } } else if ((mMixerStatus == MIXER_DRAIN_TRACK) || (mMixerStatus == MIXER_DRAIN_ALL)) { Loading
services/audioflinger/Threads.h +1 −0 Original line number Diff line number Diff line Loading @@ -693,6 +693,7 @@ protected: volatile int32_t mSuspended; int64_t mBytesWritten; int64_t mFramesWritten; // not reset on standby private: // mMasterMute is in both PlaybackThread and in AudioFlinger. When a // PlaybackThread needs to find out if master-muted, it checks it's local Loading
services/audioflinger/Tracks.cpp +11 −3 Original line number Diff line number Diff line Loading @@ -960,9 +960,17 @@ bool AudioFlinger::PlaybackThread::Track::presentationComplete( (long long)mPresentationCompleteFrames, audioHalFrames); } if ((!isOffloaded() && !isDirect() && !isFastTrack() && framesWritten >= mPresentationCompleteFrames && mAudioTrackServerProxy->isDrained()) || isOffloaded()) { bool complete; if (isOffloaded()) { complete = true; } else if (isDirect() || isFastTrack()) { // these do not go through linear map complete = framesWritten >= mPresentationCompleteFrames; } else { // Normal tracks, OutputTracks, and PatchTracks complete = framesWritten >= mPresentationCompleteFrames && mAudioTrackServerProxy->isDrained(); } if (complete) { triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE); mAudioTrackServerProxy->setStreamEndDone(); return true; Loading