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

Commit 28a8a9ff authored by Wei Jia's avatar Wei Jia
Browse files

NuPlayerRenderer: allow flush() to be called multiple times.

Also fix racing condition on accessing some members.

Bug: 16982307
Bug: 13133027
Change-Id: I0d4a605146e24ad7396a07369d501593cad73f41
parent 426c719a
Loading
Loading
Loading
Loading
+43 −25
Original line number Diff line number Diff line
@@ -93,10 +93,14 @@ void NuPlayer::Renderer::flush(bool audio) {
    {
        Mutex::Autolock autoLock(mFlushLock);
        if (audio) {
            CHECK(!mFlushingAudio);
            if (mFlushingAudio) {
                return;
            }
            mFlushingAudio = true;
        } else {
            CHECK(!mFlushingVideo);
            if (mFlushingVideo) {
                return;
            }
            mFlushingVideo = true;
        }
    }
@@ -115,6 +119,14 @@ void NuPlayer::Renderer::signalTimeDiscontinuity() {
    mSyncQueues = false;
}

void NuPlayer::Renderer::signalAudioSinkChanged() {
    (new AMessage(kWhatAudioSinkChanged, id()))->post();
}

void NuPlayer::Renderer::signalDisableOffloadAudio() {
    (new AMessage(kWhatDisableOffloadAudio, id()))->post();
}

void NuPlayer::Renderer::pause() {
    (new AMessage(kWhatPause, id()))->post();
}
@@ -251,14 +263,6 @@ void NuPlayer::Renderer::postDrainAudioQueue_l(int64_t delayUs) {
    msg->post(delayUs);
}

void NuPlayer::Renderer::signalAudioSinkChanged() {
    (new AMessage(kWhatAudioSinkChanged, id()))->post();
}

void NuPlayer::Renderer::signalDisableOffloadAudio() {
    (new AMessage(kWhatDisableOffloadAudio, id()))->post();
}

void NuPlayer::Renderer::prepareForMediaRenderingStart() {
    mAudioRenderingStartGeneration = mAudioQueueGeneration;
    mVideoRenderingStartGeneration = mVideoQueueGeneration;
@@ -716,6 +720,15 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) {
    int32_t audio;
    CHECK(msg->findInt32("audio", &audio));

    {
        Mutex::Autolock autoLock(mFlushLock);
        if (audio) {
            mFlushingAudio = false;
        } else {
            mFlushingVideo = false;
        }
    }

    // If we're currently syncing the queues, i.e. dropping audio while
    // aligning the first audio/video buffer times and only one of the
    // two queues has data, we may starve that queue by not requesting
@@ -734,17 +747,18 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) {
        {
            Mutex::Autolock autoLock(mLock);
            flushQueue(&mAudioQueue);
        }

        Mutex::Autolock autoLock(mFlushLock);
        mFlushingAudio = false;

        mDrainAudioQueuePending = false;
            ++mAudioQueueGeneration;

            prepareForMediaRenderingStart();

            if (offloadingAudio()) {
                mFirstAudioTimeUs = -1;
            }
        }

        mDrainAudioQueuePending = false;

        if (offloadingAudio()) {
            mAudioSink->pause();
            mAudioSink->flush();
            mAudioSink->start();
@@ -752,9 +766,6 @@ void NuPlayer::Renderer::onFlush(const sp<AMessage> &msg) {
    } else {
        flushQueue(&mVideoQueue);

        Mutex::Autolock autoLock(mFlushLock);
        mFlushingVideo = false;

        mDrainVideoQueuePending = false;
        ++mVideoQueueGeneration;

@@ -852,13 +863,15 @@ void NuPlayer::Renderer::notifyPosition() {
void NuPlayer::Renderer::onPause() {
    CHECK(!mPaused);

    mDrainAudioQueuePending = false;
    {
        Mutex::Autolock autoLock(mLock);
        ++mAudioQueueGeneration;

    mDrainVideoQueuePending = false;
        ++mVideoQueueGeneration;

        prepareForMediaRenderingStart();
    }

    mDrainAudioQueuePending = false;
    mDrainVideoQueuePending = false;

    if (mHasAudio) {
        mAudioSink->pause();
@@ -895,7 +908,12 @@ void NuPlayer::Renderer::onAudioOffloadTearDown() {
    uint32_t numFramesPlayed;
    CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);

    int64_t currentPositionUs = mFirstAudioTimeUs
    int64_t firstAudioTimeUs;
    {
        Mutex::Autolock autoLock(mLock);
        firstAudioTimeUs = mFirstAudioTimeUs;
    }
    int64_t currentPositionUs = firstAudioTimeUs
            + (numFramesPlayed * mAudioSink->msecsPerFrame()) * 1000ll;

    mAudioSink->stop();