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

Commit 943c94e7 authored by Marco Nelissen's avatar Marco Nelissen Committed by Android (Google) Code Review
Browse files

Merge "Handle mkv file without cue point"

parents f03cb213 2641ec2a
Loading
Loading
Loading
Loading
+86 −13
Original line number Diff line number Diff line
@@ -119,6 +119,9 @@ private:
    const mkvparser::BlockEntry *mBlockEntry;
    long mBlockEntryIndex;

    unsigned long mTrackType;
    void seekwithoutcue_l(int64_t seekTimeUs, int64_t *actualFrameTimeUs);

    void advance_l();

    BlockIterator(const BlockIterator &);
@@ -290,6 +293,7 @@ BlockIterator::BlockIterator(
      mCluster(NULL),
      mBlockEntry(NULL),
      mBlockEntryIndex(0) {
    mTrackType = mExtractor->mSegment->GetTracks()->GetTrackByNumber(trackNum)->GetType();
    reset();
}

@@ -442,12 +446,14 @@ void BlockIterator::seek(
        }

        if (!pCues) {
            ALOGE("No Cues in file");
            ALOGV("No Cues in file,seek without cue data");
            seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
            return;
        }
    }
    else if (!pSH) {
        ALOGE("No SeekHead");
        ALOGV("No SeekHead, seek without cue data");
        seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
        return;
    }

@@ -456,7 +462,9 @@ void BlockIterator::seek(
    while (!pCues->DoneParsing()) {
        pCues->LoadCuePoint();
        pCP = pCues->GetLast();
        CHECK(pCP);
        ALOGV("pCP = %s", pCP == NULL ? "NULL" : "not NULL");
        if (pCP == NULL)
            continue;

        size_t trackCount = mExtractor->mTracks.size();
        for (size_t index = 0; index < trackCount; ++index) {
@@ -494,6 +502,7 @@ void BlockIterator::seek(
    // Always *search* based on the video track, but finalize based on mTrackNum
    if (!pTP) {
        ALOGE("Did not locate the video track for seeking");
        seekwithoutcue_l(seekTimeUs, actualFrameTimeUs);
        return;
    }

@@ -537,6 +546,31 @@ int64_t BlockIterator::blockTimeUs() const {
    return (mBlockEntry->GetBlock()->GetTime(mCluster) + 500ll) / 1000ll;
}

void BlockIterator::seekwithoutcue_l(int64_t seekTimeUs, int64_t *actualFrameTimeUs) {
    mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll);
    const long status = mCluster->GetFirst(mBlockEntry);
    if (status < 0) {  // error
        ALOGE("get last blockenry failed!");
        mCluster = NULL;
        return;
    }
    mBlockEntryIndex = 0;
    while (!eos() && ((block()->GetTrackNumber() != mTrackNum) || (blockTimeUs() < seekTimeUs))) {
        advance_l();
    }

    // video track will seek to the next key frame.
    if (mTrackType == 1) {
        while (!eos() && ((block()->GetTrackNumber() != mTrackNum) ||
                      !mBlockEntry->GetBlock()->IsKey())) {
            advance_l();
        }
    }
    *actualFrameTimeUs = blockTimeUs();
     ALOGV("seekTimeUs:%lld, actualFrameTimeUs:%lld, tracknum:%lld",
              (long long)seekTimeUs, (long long)*actualFrameTimeUs, (long long)mTrackNum);
}

////////////////////////////////////////////////////////////////////////////////

static unsigned U24_AT(const uint8_t *ptr) {
@@ -956,6 +990,7 @@ MatroskaExtractor::MatroskaExtractor(DataSourceHelper *source)
        return;
    }

    if (mIsLiveStreaming) {
        // from mkvparser::Segment::Load(), but stop at first cluster
        ret = mSegment->ParseHeaders();
        if (ret == 0) {
@@ -968,6 +1003,44 @@ MatroskaExtractor::MatroskaExtractor(DataSourceHelper *source)
        } else if (ret > 0) {
            ret = mkvparser::E_BUFFER_NOT_FULL;
        }
    } else {
        ret = mSegment->ParseHeaders();
        if (ret < 0) {
            ALOGE("Segment parse header return fail %lld", ret);
            delete mSegment;
            mSegment = NULL;
            return;
        } else if (ret == 0) {
            const mkvparser::Cues* mCues = mSegment->GetCues();
            const mkvparser::SeekHead* mSH = mSegment->GetSeekHead();
            if ((mCues == NULL) && (mSH != NULL)) {
                size_t count = mSH->GetCount();
                const mkvparser::SeekHead::Entry* mEntry;
                for (size_t index = 0; index < count; index++) {
                    mEntry = mSH->GetEntry(index);
                    if (mEntry->id == 0x0C53BB6B) {  // Cues ID
                        long len;
                        long long pos;
                        mSegment->ParseCues(mEntry->pos, pos, len);
                        mCues = mSegment->GetCues();
                        ALOGV("find cue data by seekhead");
                        break;
                    }
                }
            }

            if (mCues) {
                long len;
                ret = mSegment->LoadCluster(pos, len);
                ALOGV("has Cue data, Cluster num=%ld", mSegment->GetCount());
            } else  {
                long status_Load = mSegment->Load();
                ALOGW("no Cue data,Segment Load status:%ld",status_Load);
            }
        } else if (ret > 0) {
            ret = mkvparser::E_BUFFER_NOT_FULL;
        }
    }

    if (ret < 0) {
        char uri[1024];