Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7d05308b authored by Andy Hung's avatar Andy Hung
Browse files

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 b03dcb34)
parent 5dc3d992
Loading
Loading
Loading
Loading
+18 −1
Original line number Original line Diff line number Diff line
@@ -106,6 +106,7 @@ NuPlayer::Renderer::Renderer(
      mNotifyCompleteVideo(false),
      mNotifyCompleteVideo(false),
      mSyncQueues(false),
      mSyncQueues(false),
      mPaused(false),
      mPaused(false),
      mPauseDrainAudioAllowedUs(0),
      mVideoSampleReceived(false),
      mVideoSampleReceived(false),
      mVideoRenderingStarted(false),
      mVideoRenderingStarted(false),
      mVideoRenderingStartGeneration(0),
      mVideoRenderingStartGeneration(0),
@@ -630,6 +631,14 @@ void NuPlayer::Renderer::postDrainAudioQueue_l(int64_t delayUs) {
        return;
        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;
    mDrainAudioQueuePending = true;
    sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, this);
    sp<AMessage> msg = new AMessage(kWhatDrainAudioQueue, this);
    msg->setInt32("drainGeneration", mAudioDrainGeneration);
    msg->setInt32("drainGeneration", mAudioDrainGeneration);
@@ -1338,8 +1347,16 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) {
            mAudioSink->flush();
            mAudioSink->flush();
            // Call stop() to signal to the AudioSink to completely fill the
            // Call stop() to signal to the AudioSink to completely fill the
            // internal buffer before resuming playback.
            // internal buffer before resuming playback.
            // FIXME: this is ignored after flush().
            mAudioSink->stop();
            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();
                mAudioSink->start();
            }
            }
            mNumFramesWritten = 0;
            mNumFramesWritten = 0;
+1 −0
Original line number Original line Diff line number Diff line
@@ -170,6 +170,7 @@ private:


    // modified on only renderer's thread.
    // modified on only renderer's thread.
    bool mPaused;
    bool mPaused;
    int64_t mPauseDrainAudioAllowedUs; // time when we can drain/deliver audio in pause mode.


    bool mVideoSampleReceived;
    bool mVideoSampleReceived;
    bool mVideoRenderingStarted;
    bool mVideoRenderingStarted;