From 7d05308b16a688436331de2e94d89e46d05d8d1d Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Thu, 27 Aug 2015 16:18:59 -0700 Subject: NuPlayerRenderer: Do not deliver audio too soon after stop For non-offloaded audio, do not deliver audio data too soon after stop when in paused mode. Otherwise the audio MixerThread will keep the track playing, instead of inactivating the track. Bug: 23167401 Change-Id: If376148c742fde2d20dc5d23bf0b894fe378e71a (cherry picked from commit b03dcb34cd44d77e5fe1559e72323e03c59931db) --- .../nuplayer/NuPlayerRenderer.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp') diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp index 04a46f4..de7f5e7 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp @@ -106,6 +106,7 @@ NuPlayer::Renderer::Renderer( mNotifyCompleteVideo(false), mSyncQueues(false), mPaused(false), + mPauseDrainAudioAllowedUs(0), mVideoSampleReceived(false), mVideoRenderingStarted(false), mVideoRenderingStartGeneration(0), @@ -630,6 +631,14 @@ void NuPlayer::Renderer::postDrainAudioQueue_l(int64_t delayUs) { return; } + // FIXME: if paused, wait until AudioTrack stop() is complete before delivering data. + if (mPaused) { + const int64_t diffUs = mPauseDrainAudioAllowedUs - ALooper::GetNowUs(); + if (diffUs > delayUs) { + delayUs = diffUs; + } + } + mDrainAudioQueuePending = true; sp msg = new AMessage(kWhatDrainAudioQueue, this); msg->setInt32("drainGeneration", mAudioDrainGeneration); @@ -1338,8 +1347,16 @@ void NuPlayer::Renderer::onFlush(const sp &msg) { mAudioSink->flush(); // Call stop() to signal to the AudioSink to completely fill the // internal buffer before resuming playback. + // FIXME: this is ignored after flush(). mAudioSink->stop(); - if (!mPaused) { + if (mPaused) { + // Race condition: if renderer is paused and audio sink is stopped, + // we need to make sure that the audio track buffer fully drains + // before delivering data. + // FIXME: remove this if we can detect if stop() is complete. + const int delayUs = 2 * 50 * 1000; // (2 full mixer thread cycles at 50ms) + mPauseDrainAudioAllowedUs = ALooper::GetNowUs() + delayUs; + } else { mAudioSink->start(); } mNumFramesWritten = 0; -- cgit v1.1