Bug 1020679 - Fix MP4 demuxer duration. r=cpearce

This commit is contained in:
Anthony Jones 2014-06-06 16:19:29 +12:00
parent 1d8a86d41b
commit 60c42c6d30
5 changed files with 41 additions and 1 deletions

View File

@ -2774,6 +2774,14 @@ status_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) {
mTrackFragmentHeaderInfo.mFlags = flags;
mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId;
mTrackFragmentHeaderInfo.mBaseDataOffset = 0;
mTrackFragmentHeaderInfo.mSampleDescriptionIndex = 0;
mTrackFragmentHeaderInfo.mDefaultSampleDuration = 0;
mTrackFragmentHeaderInfo.mDefaultSampleSize = 0;
mTrackFragmentHeaderInfo.mDefaultSampleFlags = 0;
mTrackFragmentHeaderInfo.mDataOffset = 0;
offset += 8;
size -= 8;
@ -3130,6 +3138,7 @@ status_t MPEG4Source::read(
off64_t offset;
size_t size;
uint32_t cts;
uint32_t duration;
bool isSyncSample;
bool newBuffer = false;
if (mBuffer == NULL) {
@ -3137,7 +3146,8 @@ status_t MPEG4Source::read(
status_t err =
mSampleTable->getMetaDataForSample(
mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample);
mCurrentSampleIndex, &offset, &size, &cts, &duration,
&isSyncSample);
if (err != OK) {
return err;
@ -3169,6 +3179,8 @@ status_t MPEG4Source::read(
mBuffer->meta_data()->setInt64(kKey64BitFileOffset, offset);
mBuffer->meta_data()->setInt64(
kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
mBuffer->meta_data()->setInt64(
kKeyDuration, ((int64_t)duration * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
mBuffer->meta_data()->setInt64(
@ -3292,6 +3304,8 @@ status_t MPEG4Source::read(
mBuffer->meta_data()->setInt64(kKey64BitFileOffset, offset);
mBuffer->meta_data()->setInt64(
kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
mBuffer->meta_data()->setInt64(
kKeyDuration, ((int64_t)duration * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
mBuffer->meta_data()->setInt64(
@ -3365,6 +3379,7 @@ status_t MPEG4Source::fragmentedRead(
off64_t offset = 0;
size_t size;
uint32_t cts = 0;
uint32_t duration = 0;
bool isSyncSample = false;
bool newBuffer = false;
if (mBuffer == NULL) {
@ -3399,6 +3414,7 @@ status_t MPEG4Source::fragmentedRead(
offset = smpl->offset;
size = smpl->size;
cts = mCurrentTime;
duration = smpl->duration;
mCurrentTime += smpl->duration;
isSyncSample = (mCurrentSampleIndex == 0); // XXX
@ -3443,6 +3459,8 @@ status_t MPEG4Source::fragmentedRead(
mBuffer->set_range(0, size);
mBuffer->meta_data()->setInt64(
kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
mBuffer->meta_data()->setInt64(
kKeyDuration, ((int64_t)duration * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
mBuffer->meta_data()->setInt64(
@ -3566,6 +3584,8 @@ status_t MPEG4Source::fragmentedRead(
mBuffer->meta_data()->setInt64(
kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
mBuffer->meta_data()->setInt64(
kKeyDuration, ((int64_t)duration * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
mBuffer->meta_data()->setInt64(

View File

@ -139,6 +139,18 @@ status_t SampleIterator::seekTo(uint32_t sampleIndex) {
return err;
}
if (sampleIndex + 1 == mTable->mNumSampleSizes) {
mCurrentSampleDuration = 0;
}
else {
uint32_t nextSampleTime;
if ((err = findSampleTime(sampleIndex + 1, &nextSampleTime)) != OK ) {
ALOGE("findSampleTime return error");
return err;
}
mCurrentSampleDuration = nextSampleTime - mCurrentSampleTime;
}
mCurrentSampleIndex = sampleIndex;
mInitialized = true;

View File

@ -779,6 +779,7 @@ status_t SampleTable::getMetaDataForSample(
off64_t *offset,
size_t *size,
uint32_t *compositionTime,
uint32_t *duration,
bool *isSyncSample) {
Mutex::Autolock autoLock(mLock);
@ -799,6 +800,10 @@ status_t SampleTable::getMetaDataForSample(
*compositionTime = mSampleIterator->getSampleTime();
}
if (duration) {
*duration = mSampleIterator->getSampleDuration();
}
if (isSyncSample) {
*isSyncSample = false;
if (mSyncSampleOffset < 0) {

View File

@ -33,6 +33,7 @@ struct SampleIterator {
off64_t getSampleOffset() const { return mCurrentSampleOffset; }
size_t getSampleSize() const { return mCurrentSampleSize; }
uint32_t getSampleTime() const { return mCurrentSampleTime; }
uint32_t getSampleDuration() const { return mCurrentSampleDuration; }
status_t getSampleSizeDirect(
uint32_t sampleIndex, size_t *size);
@ -64,6 +65,7 @@ private:
off64_t mCurrentSampleOffset;
size_t mCurrentSampleSize;
uint32_t mCurrentSampleTime;
uint32_t mCurrentSampleDuration;
void reset();
status_t findChunkRange(uint32_t sampleIndex);

View File

@ -66,6 +66,7 @@ public:
off64_t *offset,
size_t *size,
uint32_t *compositionTime,
uint32_t *duration = NULL,
bool *isSyncSample = NULL);
enum {