Loading media/extractors/mkv/MatroskaExtractor.cpp +86 −13 Original line number Diff line number Diff line Loading @@ -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 &); Loading Loading @@ -290,6 +293,7 @@ BlockIterator::BlockIterator( mCluster(NULL), mBlockEntry(NULL), mBlockEntryIndex(0) { mTrackType = mExtractor->mSegment->GetTracks()->GetTrackByNumber(trackNum)->GetType(); reset(); } Loading Loading @@ -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; } Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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]; Loading Loading
media/extractors/mkv/MatroskaExtractor.cpp +86 −13 Original line number Diff line number Diff line Loading @@ -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 &); Loading Loading @@ -290,6 +293,7 @@ BlockIterator::BlockIterator( mCluster(NULL), mBlockEntry(NULL), mBlockEntryIndex(0) { mTrackType = mExtractor->mSegment->GetTracks()->GetTrackByNumber(trackNum)->GetType(); reset(); } Loading Loading @@ -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; } Loading @@ -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) { Loading Loading @@ -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; } Loading Loading @@ -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) { Loading Loading @@ -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) { Loading @@ -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]; Loading