Bug 1120075 - Use Movie Extend Header's duration as fallback when available. r=kentuckyfriedtakahe, a=sledru
--- a/media/libstagefright/binding/mp4_demuxer.cpp
+++ b/media/libstagefright/binding/mp4_demuxer.cpp
@@ -139,16 +139,23 @@ MP4Demuxer::Init()
if (index->IsFragmented() && !mVideoConfig.crypto.valid) {
mPrivate->mVideoIterator = new SampleIterator(index);
}
}
}
sp<MetaData> metaData = e->getMetaData();
mCrypto.Update(metaData);
+ int64_t movieDuration;
+ if (!mVideoConfig.duration && !mAudioConfig.duration &&
+ metaData->findInt64(kKeyMovieDuration, &movieDuration)) {
+ // No duration were found in either tracks, use movie extend header box one.
+ mVideoConfig.duration = mAudioConfig.duration = movieDuration;
+ }
+
return mPrivate->mAudio.get() || mPrivate->mVideo.get();
}
bool
MP4Demuxer::HasValidAudio()
{
mMonitor->AssertCurrentThreadOwns();
return mPrivate->mAudio.get() && mAudioConfig.IsValid();
--- a/media/libstagefright/frameworks/av/include/media/stagefright/MetaData.h
+++ b/media/libstagefright/frameworks/av/include/media/stagefright/MetaData.h
@@ -62,16 +62,17 @@ enum {
kKeyIsCodecConfig = 'conf', // int32_t (bool)
kKeyTime = 'time', // int64_t (usecs)
kKeyDecodingTime = 'decT', // int64_t (decoding timestamp in usecs)
kKeyNTPTime = 'ntpT', // uint64_t (ntp-timestamp)
kKeyTargetTime = 'tarT', // int64_t (usecs)
kKeyDriftTime = 'dftT', // int64_t (usecs)
kKeyAnchorTime = 'ancT', // int64_t (usecs)
kKeyDuration = 'dura', // int64_t (usecs)
+ kKeyMovieDuration = 'mdur', // int64_t (usecs)
kKeyColorFormat = 'colf',
kKeyPlatformPrivate = 'priv', // pointer
kKeyDecoderComponent = 'decC', // cstring
kKeyBufferID = 'bfID',
kKeyMaxInputSize = 'inpS',
kKeyThumbnailTime = 'thbT', // int64_t (usecs)
kKeyTrackID = 'trID',
kKeyIsDRM = 'idrm', // int32_t (bool)
--- a/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/frameworks/av/media/libstagefright/MPEG4Extractor.cpp
@@ -1692,16 +1692,56 @@ status_t MPEG4Extractor::parseChunk(off6
if (s.length()) {
mFileMetaData->setCString(kKeyDate, s.string());
}
*offset += chunk_size;
break;
}
+ case FOURCC('m', 'e', 'h', 'd'):
+ {
+ if (chunk_data_size < 8) {
+ return ERROR_MALFORMED;
+ }
+
+ uint8_t version;
+ if (mDataSource->readAt(
+ data_offset, &version, sizeof(version))
+ < (ssize_t)sizeof(version)) {
+ return ERROR_IO;
+ }
+ if (version > 1) {
+ break;
+ }
+ int64_t duration = 0;
+ if (version == 1) {
+ if (mDataSource->readAt(
+ data_offset + 4, &duration, sizeof(duration))
+ < (ssize_t)sizeof(duration)) {
+ return ERROR_IO;
+ }
+ duration = ntoh64(duration);
+ } else {
+ uint32_t duration32;
+ if (mDataSource->readAt(
+ data_offset + 4, &duration32, sizeof(duration32))
+ < (ssize_t)sizeof(duration32)) {
+ return ERROR_IO;
+ }
+ duration = ntohl(duration32);
+ }
+ if (duration) {
+ mFileMetaData->setInt64(kKeyMovieDuration, duration * 1000LL);
+ }
+
+ *offset += chunk_size;
+ break;
+ }
+
case FOURCC('m', 'd', 'a', 't'):
{
ALOGV("mdat chunk, drm: %d", mIsDrm);
if (!mIsDrm) {
*offset += chunk_size;
break;
}