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

Commit f8d71777 authored by Chong Zhang's avatar Chong Zhang
Browse files

notify seek complete upon first video output frame

Bug: 18541814
Change-Id: Ie4e0976885f26eb253460eab371cb181ea85f2db
parent bc0f452b
Loading
Loading
Loading
Loading
+53 −18
Original line number Original line Diff line number Diff line
@@ -80,6 +80,21 @@ private:
    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
    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 {
struct NuPlayer::SetSurfaceAction : public Action {
    SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
    SetSurfaceAction(const sp<NativeWindowWrapper> &wrapper)
        : mWrapper(wrapper) {
        : mWrapper(wrapper) {
@@ -163,6 +178,7 @@ NuPlayer::NuPlayer()
      mTimedTextGeneration(0),
      mTimedTextGeneration(0),
      mFlushingAudio(NONE),
      mFlushingAudio(NONE),
      mFlushingVideo(NONE),
      mFlushingVideo(NONE),
      mResumePending(false),
      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
      mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW),
      mStarted(false) {
      mStarted(false) {
    clearFlushComplete();
    clearFlushComplete();
@@ -553,11 +569,11 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                        new SimpleAction(&NuPlayer::performScanSources));
                        new SimpleAction(&NuPlayer::performScanSources));
            }
            }


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


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


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


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


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


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

    // everything's flushed, continue playback.
    // 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) {
    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) {
    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 Original line Diff line number Diff line
@@ -93,6 +93,7 @@ private:
    struct Action;
    struct Action;
    struct SeekAction;
    struct SeekAction;
    struct SetSurfaceAction;
    struct SetSurfaceAction;
    struct ResumeDecoderAction;
    struct FlushDecoderAction;
    struct FlushDecoderAction;
    struct PostMessageAction;
    struct PostMessageAction;
    struct SimpleAction;
    struct SimpleAction;
@@ -169,6 +170,9 @@ private:
    FlushStatus mFlushingAudio;
    FlushStatus mFlushingAudio;
    FlushStatus mFlushingVideo;
    FlushStatus mFlushingVideo;


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

    int32_t mVideoScalingMode;
    int32_t mVideoScalingMode;


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


    void flushDecoder(bool audio, bool needShutdown);
    void flushDecoder(bool audio, bool needShutdown);


    void finishResume();

    void postScanSources();
    void postScanSources();


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


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


void NuPlayer::Decoder::onSetRenderer(const sp<Renderer> &renderer) {
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;
    mPaused = false;

    if (notifyComplete) {
        mResumePending = true;
    }
}
}


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


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

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

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


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

    if (mRenderer != NULL) {
    if (mRenderer != NULL) {
        // send the buffer to renderer.
        // send the buffer to renderer.
        mRenderer->queueBuffer(mIsAudio, buffer, reply);
        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
}  // namespace android
+4 −1
Original line number Original line Diff line number Diff line
@@ -42,7 +42,7 @@ protected:
    virtual void onConfigure(const sp<AMessage> &format);
    virtual void onConfigure(const sp<AMessage> &format);
    virtual void onSetRenderer(const sp<Renderer> &renderer);
    virtual void onSetRenderer(const sp<Renderer> &renderer);
    virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers);
    virtual void onGetInputBuffers(Vector<sp<ABuffer> > *dstBuffers);
    virtual void onResume();
    virtual void onResume(bool notifyComplete);
    virtual void onFlush(bool notifyComplete);
    virtual void onFlush(bool notifyComplete);
    virtual void onShutdown(bool notifyComplete);
    virtual void onShutdown(bool notifyComplete);
    virtual void doRequestBuffers();
    virtual void doRequestBuffers();
@@ -85,6 +85,7 @@ private:


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


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


    void notifyResumeCompleteIfNecessary();

    DISALLOW_EVIL_CONSTRUCTORS(Decoder);
    DISALLOW_EVIL_CONSTRUCTORS(Decoder);
};
};


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


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


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


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

            onResume(notifyComplete);
            break;
            break;
        }
        }


Loading