Bug 1054144 - Support 'tfdt' in MP4 parser; r=edwin

This commit is contained in:
Anthony Jones 2014-08-18 13:02:22 +12:00
Родитель 280c36f93f
Коммит 0d6ac1003c
1 изменённых файлов: 62 добавлений и 3 удалений

Просмотреть файл

@ -106,11 +106,20 @@ private:
size_t parseNALSize(const uint8_t *data) const;
status_t parseChunk(off64_t *offset);
status_t parseTrackFragmentData(off64_t offset, off64_t size);
status_t parseTrackFragmentHeader(off64_t offset, off64_t size);
status_t parseTrackFragmentRun(off64_t offset, off64_t size);
status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size);
status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size);
struct TrackFragmentData {
TrackFragmentData(): mPresent(false), mFlags(0), mBaseMediaDecodeTime(0) {}
bool mPresent;
uint32_t mFlags;
uint64_t mBaseMediaDecodeTime;
};
TrackFragmentData mTrackFragmentData;
struct TrackFragmentHeaderInfo {
enum Flags {
kBaseDataOffsetPresent = 0x01,
@ -2572,6 +2581,16 @@ status_t MPEG4Source::parseChunk(off64_t *offset) {
break;
}
case FOURCC('t', 'f', 'd', 't'):
{
status_t err;
if ((err = parseTrackFragmentData(data_offset, chunk_data_size)) != OK) {
return err;
}
*offset += chunk_size;
break;
}
case FOURCC('t', 'f', 'h', 'd'): {
status_t err;
if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) {
@ -2786,6 +2805,41 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(off64_t offset, off
return OK;
}
status_t MPEG4Source::parseTrackFragmentData(off64_t offset, off64_t size) {
if (size < 8) {
return -EINVAL;
}
uint32_t flags;
if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags
return ERROR_MALFORMED;
}
uint8_t version = flags >> 24;
mTrackFragmentData.mFlags = flags;
if (version == 0) {
uint32_t time;
if (mDataSource->getUInt32(offset + 4, &time)) {
mTrackFragmentData.mBaseMediaDecodeTime = time;
mTrackFragmentData.mPresent = true;
return OK;
}
} else if (version == 1) {
if (size < 12) {
return -EINVAL;
}
if (mDataSource->getUInt64(offset + 4,
&mTrackFragmentData.mBaseMediaDecodeTime)) {
mTrackFragmentData.mPresent = true;
return OK;
}
}
return ERROR_MALFORMED;
}
status_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) {
if (size < 8) {
@ -3448,10 +3502,15 @@ status_t MPEG4Source::fragmentedRead(
mCurrentMoofOffset = nextMoof;
mCurrentSamples.clear();
mCurrentSampleIndex = 0;
mTrackFragmentData.mPresent = false;
parseChunk(&nextMoof);
if (mCurrentSampleIndex >= mCurrentSamples.size()) {
return ERROR_END_OF_STREAM;
}
if (mCurrentSampleIndex >= mCurrentSamples.size()) {
return ERROR_END_OF_STREAM;
}
if (mTrackFragmentData.mPresent) {
mCurrentTime = mTrackFragmentData.mBaseMediaDecodeTime;
}
}
const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];