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 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