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

Commit 146e4768 authored by Andreas Huber's avatar Andreas Huber Committed by Android Git Automerger
Browse files

am 8f0f10a8: Merge "Experiment with seeking to closest frame instead of closest syncframe"

* commit '8f0f10a8':
  Experiment with seeking to closest frame instead of closest syncframe
parents 1a4f18b8 8f0f10a8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1609,7 +1609,7 @@ void AwesomePlayer::onVideoEvent() {
                    mSeekTimeUs,
                    mSeeking == SEEK_VIDEO_ONLY
                        ? MediaSource::ReadOptions::SEEK_NEXT_SYNC
                        : MediaSource::ReadOptions::SEEK_CLOSEST_SYNC);
                        : MediaSource::ReadOptions::SEEK_CLOSEST);
        }
        for (;;) {
            status_t err = mVideoSource->read(&mVideoBuffer, &options);
+60 −11
Original line number Diff line number Diff line
@@ -93,7 +93,10 @@ struct BlockIterator {

    void advance();
    void reset();
    void seek(int64_t seekTimeUs, bool seekToKeyFrame);

    void seek(
            int64_t seekTimeUs, bool seekToKeyFrame,
            int64_t *actualFrameTimeUs);

    const mkvparser::Block *block() const;
    int64_t blockTimeUs() const;
@@ -303,22 +306,52 @@ void BlockIterator::reset() {
    } while (!eos() && block()->GetTrackNumber() != mTrackNum);
}

void BlockIterator::seek(int64_t seekTimeUs, bool seekToKeyFrame) {
void BlockIterator::seek(
        int64_t seekTimeUs, bool seekToKeyFrame,
        int64_t *actualFrameTimeUs) {
    Mutex::Autolock autoLock(mExtractor->mLock);

    mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll);
    *actualFrameTimeUs = -1ll;

    int64_t seekTimeNs = seekTimeUs * 1000ll;

    mCluster = mExtractor->mSegment->FindCluster(seekTimeNs);
    mBlockEntry = NULL;
    mBlockEntryIndex = 0;

    do {
    long prevKeyFrameBlockEntryIndex = -1;

    for (;;) {
        advance_l();

        if (eos()) {
            break;
        }
    while (!eos() && block()->GetTrackNumber() != mTrackNum);

    if (seekToKeyFrame) {
        while (!eos() && !mBlockEntry->GetBlock()->IsKey()) {
            advance_l();
        if (block()->GetTrackNumber() != mTrackNum) {
            continue;
        }

        if (block()->IsKey()) {
            prevKeyFrameBlockEntryIndex = mBlockEntryIndex - 1;
        }

        int64_t timeNs = block()->GetTime(mCluster);

        if (timeNs >= seekTimeNs) {
            *actualFrameTimeUs = (timeNs + 500ll) / 1000ll;
            break;
        }
    }

    if (eos()) {
        return;
    }

    if (seekToKeyFrame && !block()->IsKey()) {
        CHECK_GE(prevKeyFrameBlockEntryIndex, 0);
        mBlockEntryIndex = prevKeyFrameBlockEntryIndex;
        advance_l();
    }
}

@@ -397,6 +430,8 @@ status_t MatroskaSource::read(
        MediaBuffer **out, const ReadOptions *options) {
    *out = NULL;

    int64_t targetSampleTimeUs = -1ll;

    int64_t seekTimeUs;
    ReadOptions::SeekMode mode;
    if (options && options->getSeekTo(&seekTimeUs, &mode)
@@ -406,10 +441,14 @@ status_t MatroskaSource::read(
        // Apparently keyframe indication in audio tracks is unreliable,
        // fortunately in all our currently supported audio encodings every
        // frame is effectively a keyframe.
        mBlockIter.seek(seekTimeUs, !mIsAudio);
        int64_t actualFrameTimeUs;
        mBlockIter.seek(seekTimeUs, !mIsAudio, &actualFrameTimeUs);

        if (mode == ReadOptions::SEEK_CLOSEST) {
            targetSampleTimeUs = actualFrameTimeUs;
        }
    }

again:
    while (mPendingFrames.empty()) {
        status_t err = readBlock();

@@ -424,6 +463,11 @@ again:
    mPendingFrames.erase(mPendingFrames.begin());

    if (mType != AVC) {
        if (targetSampleTimeUs >= 0ll) {
            frame->meta_data()->setInt64(
                    kKeyTargetTime, targetSampleTimeUs);
        }

        *out = frame;

        return OK;
@@ -506,6 +550,11 @@ again:
    frame->release();
    frame = NULL;

    if (targetSampleTimeUs >= 0ll) {
        buffer->meta_data()->setInt64(
                kKeyTargetTime, targetSampleTimeUs);
    }

    *out = buffer;

    return OK;