Merge "Handle mkv file without cue point"

gugelfrei
Marco Nelissen 5 years ago committed by Android (Google) Code Review
commit 943c94e7fd

@ -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,17 +990,56 @@ MatroskaExtractor::MatroskaExtractor(DataSourceHelper *source)
return;
}
// from mkvparser::Segment::Load(), but stop at first cluster
ret = mSegment->ParseHeaders();
if (ret == 0) {
long len;
ret = mSegment->LoadCluster(pos, len);
if (ret >= 1) {
// no more clusters
ret = 0;
if (mIsLiveStreaming) {
// from mkvparser::Segment::Load(), but stop at first cluster
ret = mSegment->ParseHeaders();
if (ret == 0) {
long len;
ret = mSegment->LoadCluster(pos, len);
if (ret >= 1) {
// no more clusters
ret = 0;
}
} 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;
}
} else if (ret > 0) {
ret = mkvparser::E_BUFFER_NOT_FULL;
}
if (ret < 0) {

Loading…
Cancel
Save