Merge "Allow edit list atom to appear earlier in the file"

gugelfrei
Treehugger Robot 7 years ago committed by Gerrit Code Review
commit c71583ee52

@ -463,6 +463,66 @@ sp<MetaData> MPEG4Extractor::getTrackMetaData(
return NULL;
}
int64_t duration;
int32_t samplerate;
if (track->has_elst && mHeaderTimescale != 0 &&
track->meta->findInt64(kKeyDuration, &duration) &&
track->meta->findInt32(kKeySampleRate, &samplerate)) {
track->has_elst = false;
if (track->elst_segment_duration > INT64_MAX) {
goto editlistoverflow;
}
int64_t segment_duration = track->elst_segment_duration;
int64_t media_time = track->elst_media_time;
int64_t halfscale = mHeaderTimescale / 2;
int64_t delay;
// delay = ((media_time * samplerate) + halfscale) / mHeaderTimescale;
if (__builtin_mul_overflow(media_time, samplerate, &delay) ||
__builtin_add_overflow(delay, halfscale, &delay) ||
(delay /= mHeaderTimescale, false) ||
delay > INT32_MAX ||
delay < INT32_MIN) {
goto editlistoverflow;
}
track->meta->setInt32(kKeyEncoderDelay, delay);
int64_t scaled_duration;
// scaled_duration = ((duration * mHeaderTimescale) + 500000) / 1000000;
if (__builtin_mul_overflow(duration, mHeaderTimescale, &scaled_duration) ||
__builtin_add_overflow(scaled_duration, 500000, &scaled_duration)) {
goto editlistoverflow;
}
scaled_duration /= 1000000;
int64_t segment_end;
int64_t padding;
if (__builtin_add_overflow(segment_duration, media_time, &segment_end) ||
__builtin_sub_overflow(scaled_duration, segment_end, &padding)) {
goto editlistoverflow;
}
if (padding < 0) {
// track duration from media header (which is what kKeyDuration is) might
// be slightly shorter than the segment duration, which would make the
// padding negative. Clamp to zero.
padding = 0;
}
int64_t paddingsamples;
// paddingsamples = ((padding * samplerate) + halfscale) / mHeaderTimescale;
if (__builtin_mul_overflow(padding, samplerate, &paddingsamples) ||
__builtin_add_overflow(paddingsamples, halfscale, &paddingsamples) ||
(paddingsamples /= mHeaderTimescale, false) ||
paddingsamples > INT32_MAX) {
goto editlistoverflow;
}
track->meta->setInt32(kKeyEncoderPadding, paddingsamples);
}
editlistoverflow:
if ((flags & kIncludeExtensiveMetaData)
&& !track->includes_expensive_metadata) {
track->includes_expensive_metadata = true;
@ -989,6 +1049,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
track->skipTrack = false;
track->timescale = 0;
track->meta->setCString(kKeyMIMEType, "application/octet-stream");
track->has_elst = false;
}
off64_t stop_offset = *offset + chunk_size;
@ -1055,6 +1116,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
{
*offset += chunk_size;
if (!mLastTrack) {
return ERROR_MALFORMED;
}
// See 14496-12 8.6.6
uint8_t version;
if (mDataSource->readAt(data_offset, &version, 1) < 1) {
@ -1069,8 +1134,6 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
if (entry_count != 1) {
// we only support a single entry at the moment, for gapless playback
ALOGW("ignoring edit list with %d entries", entry_count);
} else if (mHeaderTimescale == 0) {
ALOGW("ignoring edit list because timescale is 0");
} else {
off64_t entriesoffset = data_offset + 8;
uint64_t segment_duration;
@ -1094,31 +1157,12 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
return ERROR_IO;
}
uint64_t halfscale = mHeaderTimescale / 2;
segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale;
media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale;
int64_t duration;
int32_t samplerate;
if (!mLastTrack) {
return ERROR_MALFORMED;
}
if (mLastTrack->meta->findInt64(kKeyDuration, &duration) &&
mLastTrack->meta->findInt32(kKeySampleRate, &samplerate)) {
int64_t delay = (media_time * samplerate + 500000) / 1000000;
mLastTrack->meta->setInt32(kKeyEncoderDelay, delay);
int64_t paddingus = duration - (int64_t)(segment_duration + media_time);
if (paddingus < 0) {
// track duration from media header (which is what kKeyDuration is) might
// be slightly shorter than the segment duration, which would make the
// padding negative. Clamp to zero.
paddingus = 0;
}
int64_t paddingsamples = (paddingus * samplerate + 500000) / 1000000;
mLastTrack->meta->setInt32(kKeyEncoderPadding, paddingsamples);
}
// save these for later, because the elst atom might precede
// the atoms that actually gives us the duration and sample rate
// needed to calculate the padding and delay values
mLastTrack->has_elst = true;
mLastTrack->elst_media_time = media_time;
mLastTrack->elst_segment_duration = segment_duration;
}
break;
}

@ -82,6 +82,9 @@ private:
sp<SampleTable> sampleTable;
bool includes_expensive_metadata;
bool skipTrack;
bool has_elst;
int64_t elst_media_time;
uint64_t elst_segment_duration;
};
Vector<SidxEntry> mSidxEntries;

Loading…
Cancel
Save