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

Commit d8731629 authored by Chong Zhang's avatar Chong Zhang Committed by Android (Google) Code Review
Browse files

Merge "notify seek complete upon first video output frame" into lmp-mr1-dev

parents f20c4356 f8d71777
Loading
Loading
Loading
Loading
+53 −18
Original line number Diff line number Diff line
@@ -80,6 +80,21 @@ private:
    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
};

struct NuPlayer::ResumeDecoderAction : public Action {
    ResumeDecoderAction(bool needNotify)
        : mNeedNotify(needNotify) {
    }

    virtual void execute(NuPlayer *player) {
        player->performResumeDecoders(mNeedNotify);
    }

private:
    bool mNeedNotify;

    DISALLOW_EVIL_CONSTRUCTORS(ResumeDecoderAction);
};

struct NuPlayer::SetSurfaceAction : public Action {
    SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
        : mWrapper(wrapper) {
@@ -163,6 +178,7 @@ NuPlayer::NuPlayer()
      mTimedTextGeneration(0),
      mFlushingAudio(NONE),
      mFlushingVideo(NONE),
      mResumePending(false),
      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
      mStarted(false) {
    clearFlushComplete();
@@ -553,11 +569,11 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                        new SimpleAction(&NuPlayer::performScanSources));
            }

            // After a flush wihtout shutdown, decoder is paused.
            // Don't resume it until source is seeked, otherwise it could
            // After a flush without shutdown, decoder is paused.
            // Don't resume it until source seek is done, otherwise it could
            // start pulling stale data too soon.
            mDeferredActions.push_back(
                    new SimpleAction(&NuPlayer::performResumeDecoders));
                    new ResumeDecoderAction(false /* needNotify */));

            processDeferredActions();
            break;
@@ -747,6 +763,8 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                }

                finishFlushIfPossible();
            } else if (what == DecoderBase::kWhatResumeCompleted) {
                finishResume();
            } else if (what == DecoderBase::kWhatError) {
                status_t err;
                if (!msg->findInt32("err", &err) || err == OK) {
@@ -923,11 +941,11 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
            mDeferredActions.push_back(
                    new SeekAction(seekTimeUs, needNotify));

            // After a flush wihtout shutdown, decoder is paused.
            // Don't resume it until source is seeked, otherwise it could
            // After a flush without shutdown, decoder is paused.
            // Don't resume it until source seek is done, otherwise it could
            // start pulling stale data too soon.
            mDeferredActions.push_back(
                    new SimpleAction(&NuPlayer::performResumeDecoders));
                    new ResumeDecoderAction(needNotify));

            processDeferredActions();
            break;
@@ -1499,15 +1517,6 @@ void NuPlayer::performSeek(int64_t seekTimeUs, bool needNotify) {
    mSource->seekTo(seekTimeUs);
    ++mTimedTextGeneration;

    if (mDriver != NULL) {
        sp<NuPlayerDriver> driver = mDriver.promote();
        if (driver != NULL) {
            if (needNotify) {
                driver->notifySeekComplete();
            }
        }
    }

    // everything's flushed, continue playback.
}

@@ -1593,13 +1602,39 @@ void NuPlayer::performSetSurface(const sp<NativeWindowWrapper> &wrapper) {
    }
}

void NuPlayer::performResumeDecoders() {
void NuPlayer::performResumeDecoders(bool needNotify) {
    if (needNotify) {
        mResumePending = true;
        if (mVideoDecoder == NULL) {
            // if audio-only, we can notify seek complete now,
            // as the resume operation will be relatively fast.
            finishResume();
        }
    }

    if (mVideoDecoder != NULL) {
        mVideoDecoder->signalResume();
        // When there is continuous seek, MediaPlayer will cache the seek
        // position, and send down new seek request when previous seek is
        // complete. Let's wait for at least one video output frame before
        // notifying seek complete, so that the video thumbnail gets updated
        // when seekbar is dragged.
        mVideoDecoder->signalResume(needNotify);
    }

    if (mAudioDecoder != NULL) {
        mAudioDecoder->signalResume();
        mAudioDecoder->signalResume(false /* needNotify */);
    }
}

void NuPlayer::finishResume() {
    if (mResumePending) {
        mResumePending = false;
        if (mDriver != NULL) {
            sp<NuPlayerDriver> driver = mDriver.promote();
            if (driver != NULL) {
                driver->notifySeekComplete();
            }
        }
    }
}

+7 −1
Original line number Diff line number Diff line
@@ -93,6 +93,7 @@ private:
    struct Action;
    struct SeekAction;
    struct SetSurfaceAction;
    struct ResumeDecoderAction;
    struct FlushDecoderAction;
    struct PostMessageAction;
    struct SimpleAction;
@@ -169,6 +170,9 @@ private:
    FlushStatus mFlushingAudio;
    FlushStatus mFlushingVideo;

    // Status of flush responses from the decoder and renderer.
    bool mResumePending;

    int32_t mVideoScalingMode;

    bool mStarted;
@@ -205,6 +209,8 @@ private:

    void flushDecoder(bool audio, bool needShutdown);

    void finishResume();

    void postScanSources();

    void schedulePollDuration();
@@ -217,7 +223,7 @@ private:
    void performReset();
    void performScanSources();
    void performSetSurface(const sp<NativeWindowWrapper> &wrapper);
    void performResumeDecoders();
    void performResumeDecoders(bool needNotify);

    void onSourceNotify(const sp<AMessage> &msg);
    void onClosedCaptionNotify(const sp<AMessage> &msg);
+24 −1
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ NuPlayer::Decoder::Decoder(
      mFormatChangePending(false),
      mBufferGeneration(0),
      mPaused(true),
      mResumePending(false),
      mComponentName("decoder") {
    mCodecLooper = new ALooper;
    mCodecLooper->setName("NPDecoder-CL");
@@ -208,6 +209,7 @@ void NuPlayer::Decoder::onConfigure(const sp<AMessage> &format) {
        requestCodecNotification();
    }
    mPaused = false;
    mResumePending = false;
}

void NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
@@ -226,8 +228,12 @@ void NuPlayer::Decoder::onGetInputBuffers(
    }
}

void NuPlayer::Decoder::onResume() {
void NuPlayer::Decoder::onResume(bool notifyComplete) {
    mPaused = false;

    if (notifyComplete) {
        mResumePending = true;
    }
}

void NuPlayer::Decoder::onFlush(bool notifyComplete) {
@@ -265,6 +271,10 @@ void NuPlayer::Decoder::onFlush(bool notifyComplete) {

void NuPlayer::Decoder::onShutdown(bool notifyComplete) {
    status_t err = OK;

    // if there is a pending resume request, notify complete now
    notifyResumeCompleteIfNecessary();

    if (mCodec != NULL) {
        err = mCodec->release();
        mCodec = NULL;
@@ -494,6 +504,9 @@ bool NuPlayer::Decoder::handleAnOutputBuffer() {
        mSkipRenderingUntilMediaTimeUs = -1;
    }

    // wait until 1st frame comes out to signal resume complete
    notifyResumeCompleteIfNecessary();

    if (mRenderer != NULL) {
        // send the buffer to renderer.
        mRenderer->queueBuffer(mIsAudio, buffer, reply);
@@ -884,5 +897,15 @@ void NuPlayer::Decoder::rememberCodecSpecificData(const sp<AMessage> &format) {
    }
}

void NuPlayer::Decoder::notifyResumeCompleteIfNecessary() {
    if (mResumePending) {
        mResumePending = false;

        sp<AMessage> notify = mNotify->dup();
        notify->setInt32("what", kWhatResumeCompleted);
        notify->post();
    }
}

}  // namespace android
+4 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ protected:
    virtual void onConfigure(const sp<AMessage> &format);
    virtual void onSetRenderer(const sp<Renderer> &renderer);
    virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers);
    virtual void onResume();
    virtual void onResume(bool notifyComplete);
    virtual void onFlush(bool notifyComplete);
    virtual void onShutdown(bool notifyComplete);
    virtual void doRequestBuffers();
@@ -85,6 +85,7 @@ private:

    int32_t mBufferGeneration;
    bool mPaused;
    bool mResumePending;
    AString mComponentName;

    void handleError(int32_t err);
@@ -103,6 +104,8 @@ private:
    bool supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const;
    void rememberCodecSpecificData(const sp<AMessage> &format);

    void notifyResumeCompleteIfNecessary();

    DISALLOW_EVIL_CONSTRUCTORS(Decoder);
};

+8 −3
Original line number Diff line number Diff line
@@ -86,8 +86,10 @@ void NuPlayer::DecoderBase::signalFlush() {
    (new AMessage(kWhatFlush, id()))->post();
}

void NuPlayer::DecoderBase::signalResume() {
    (new AMessage(kWhatResume, id()))->post();
void NuPlayer::DecoderBase::signalResume(bool notifyComplete) {
    sp<AMessage> msg = new AMessage(kWhatResume, id());
    msg->setInt32("notifyComplete", notifyComplete);
    msg->post();
}

void NuPlayer::DecoderBase::initiateShutdown() {
@@ -159,7 +161,10 @@ void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {

        case kWhatResume:
        {
            onResume();
            int32_t notifyComplete;
            CHECK(msg->findInt32("notifyComplete", &notifyComplete));

            onResume(notifyComplete);
            break;
        }

Loading