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

Commit a36591ba authored by Wei Jia's avatar Wei Jia Committed by Android (Google) Code Review
Browse files

Merge "NuPlayer: hook up seekTo for precise seeking."

parents 74d3601b 14486829
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -65,6 +65,13 @@ public:
    virtual status_t        setSyncSettings(const AVSyncSettings& sync, float videoFpsHint) = 0;
    virtual status_t        getSyncSettings(AVSyncSettings* sync /* nonnull */,
                                            float* videoFps /* nonnull */) = 0;
    // When |precise| is true, it's required that the first rendered media position after seekTo
    // is precisely at |msec|, up to rounding error of granuality, e.g., video frame interval or
    // audio length of decoding buffer. In this case, it might take a little long time to finish
    // seekTo.
    // When |precise| is false, |msec| is a hint to the mediaplayer which will try its best to
    // fulfill the request, but it's not guaranteed. This option could result in fast finish of
    // seekTo.
    virtual status_t        seekTo(int msec, bool precise = false) = 0;
    virtual status_t        getCurrentPosition(int* msec) = 0;
    virtual status_t        getDuration(int* msec) = 0;
+14 −17
Original line number Diff line number Diff line
@@ -1254,10 +1254,7 @@ status_t NuPlayer::GenericSource::doSeek(int64_t seekTimeUs, bool precise) {

sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
        MediaBuffer* mb,
        media_track_type trackType,
        int64_t seekTimeUs,
        bool precise,
        int64_t *actualTimeUs) {
        media_track_type trackType) {
    bool audio = trackType == MEDIA_TRACK_TYPE_AUDIO;
    size_t outLength = mb->range_length();

@@ -1294,12 +1291,6 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
    CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
    meta->setInt64("timeUs", timeUs);

    if (precise && seekTimeUs > timeUs) {
        sp<AMessage> extra = new AMessage;
        extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
        meta->setMessage("extra", extra);
    }

    if (trackType == MEDIA_TRACK_TYPE_VIDEO) {
        int32_t layerId;
        if (mb->meta_data()->findInt32(kKeyTemporalLayerId, &layerId)) {
@@ -1339,10 +1330,6 @@ sp<ABuffer> NuPlayer::GenericSource::mediaBufferToABuffer(
        meta->setBuffer("mpegUserData", mpegUserData);
    }

    if (actualTimeUs) {
        *actualTimeUs = timeUs;
    }

    mb->release();
    mb = NULL;

@@ -1468,9 +1455,19 @@ void NuPlayer::GenericSource::readBuffer(

            queueDiscontinuityIfNeeded(seeking, formatChange, trackType, track);

            sp<ABuffer> buffer = mediaBufferToABuffer(
                    mbuf, trackType, seekTimeUs, precise,
                    numBuffers == 0 ? actualTimeUs : NULL);
            sp<ABuffer> buffer = mediaBufferToABuffer(mbuf, trackType);
            if (numBuffers == 0 && actualTimeUs != nullptr) {
                *actualTimeUs = timeUs;
            }
            if (seeking && buffer != nullptr) {
                sp<AMessage> meta = buffer->meta();
                if (meta != nullptr && precise && seekTimeUs > timeUs) {
                    sp<AMessage> extra = new AMessage;
                    extra->setInt64("resume-at-mediaTimeUs", seekTimeUs);
                    meta->setMessage("extra", extra);
                }
            }

            track->mPackets->queueAccessUnit(buffer);
            formatChange = false;
            seeking = false;
+7 −5
Original line number Diff line number Diff line
@@ -71,7 +71,7 @@ struct NuPlayer::GenericSource : public NuPlayer::Source {
    virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
    virtual ssize_t getSelectedTrack(media_track_type type) const;
    virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
    virtual status_t seekTo(int64_t seekTimeUs, bool precise = false);
    virtual status_t seekTo(int64_t seekTimeUs, bool precise = false) override;

    virtual status_t setBuffers(bool audio, Vector<MediaBuffer *> &buffers);

@@ -276,13 +276,15 @@ private:

    sp<ABuffer> mediaBufferToABuffer(
            MediaBuffer *mbuf,
            media_track_type trackType,
            int64_t seekTimeUs,
            bool precise,
            int64_t *actualTimeUs = NULL);
            media_track_type trackType);

    void postReadBuffer(media_track_type trackType);
    void onReadBuffer(const sp<AMessage>& msg);
    // |precise| is a modifier of |seekTimeUs|.
    // When |precise| is true, the buffer read shall include an item indicating skipping
    // rendering all buffers with timestamp earlier than |seekTimeUs|.
    // When |precise| is false, the buffer read will not include the item as above in order
    // to facilitate fast seek operation.
    void readBuffer(
            media_track_type trackType,
            int64_t seekTimeUs = -1ll, bool precise = false,
+1 −1
Original line number Diff line number Diff line
@@ -47,7 +47,7 @@ struct NuPlayer::HTTPLiveSource : public NuPlayer::Source {
    virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
    virtual ssize_t getSelectedTrack(media_track_type /* type */) const;
    virtual status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
    virtual status_t seekTo(int64_t seekTimeUs, bool precise = false);
    virtual status_t seekTo(int64_t seekTimeUs, bool precise = false) override;

protected:
    virtual ~HTTPLiveSource();
+15 −14
Original line number Diff line number Diff line
@@ -70,16 +70,18 @@ private:
};

struct NuPlayer::SeekAction : public Action {
    explicit SeekAction(int64_t seekTimeUs)
        : mSeekTimeUs(seekTimeUs) {
    explicit SeekAction(int64_t seekTimeUs, bool precise)
        : mSeekTimeUs(seekTimeUs),
          mPrecise(precise) {
    }

    virtual void execute(NuPlayer *player) {
        player->performSeek(mSeekTimeUs);
        player->performSeek(mSeekTimeUs, mPrecise);
    }

private:
    int64_t mSeekTimeUs;
    bool mPrecise;

    DISALLOW_EVIL_CONSTRUCTORS(SeekAction);
};
@@ -682,7 +684,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                    int64_t currentPositionUs = 0;
                    if (getCurrentPosition(&currentPositionUs) == OK) {
                        mDeferredActions.push_back(
                                new SeekAction(currentPositionUs));
                                new SeekAction(currentPositionUs, false /* precise */));
                    }
                }

@@ -1213,7 +1215,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                // only once if needed. After the player is started, any seek
                // operation will go through normal path.
                // Audio-only cases are handled separately.
                onStart(seekTimeUs);
                onStart(seekTimeUs, precise);
                if (mStarted) {
                    onPause();
                    mPausedByClient = true;
@@ -1229,7 +1231,7 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                                           FLUSH_CMD_FLUSH /* video */));

            mDeferredActions.push_back(
                    new SeekAction(seekTimeUs));
                    new SeekAction(seekTimeUs, precise));

            // After a flush without shutdown, decoder is paused.
            // Don't resume it until source seek is done, otherwise it could
@@ -1318,13 +1320,13 @@ status_t NuPlayer::onInstantiateSecureDecoders() {
    return OK;
}

void NuPlayer::onStart(int64_t startPositionUs) {
void NuPlayer::onStart(int64_t startPositionUs, bool precise) {
    if (!mSourceStarted) {
        mSourceStarted = true;
        mSource->start();
    }
    if (startPositionUs > 0) {
        performSeek(startPositionUs);
        performSeek(startPositionUs, precise);
        if (mSource->getFormat(false /* audio */) == NULL) {
            return;
        }
@@ -1540,7 +1542,7 @@ void NuPlayer::restartAudio(
        mRenderer->flush(false /* audio */, false /* notifyComplete */);
    }

    performSeek(currentPositionUs);
    performSeek(currentPositionUs, false /* precise */);

    if (forceNonOffload) {
        mRenderer->signalDisableOffloadAudio();
@@ -1997,10 +1999,9 @@ void NuPlayer::processDeferredActions() {
    }
}

void NuPlayer::performSeek(int64_t seekTimeUs) {
    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs)",
          (long long)seekTimeUs,
          seekTimeUs / 1E6);
void NuPlayer::performSeek(int64_t seekTimeUs, bool precise) {
    ALOGV("performSeek seekTimeUs=%lld us (%.2f secs), precise=%d",
          (long long)seekTimeUs, seekTimeUs / 1E6, precise);

    if (mSource == NULL) {
        // This happens when reset occurs right before the loop mode
@@ -2011,7 +2012,7 @@ void NuPlayer::performSeek(int64_t seekTimeUs) {
        return;
    }
    mPreviousSeekTimeUs = seekTimeUs;
    mSource->seekTo(seekTimeUs);
    mSource->seekTo(seekTimeUs, precise);
    ++mTimedTextGeneration;

    // everything's flushed, continue playback.
Loading