|
|
|
@ -459,6 +459,7 @@ status_t MPEG4Extractor::getTrackMetaData(
|
|
|
|
|
track->meta.findInt64(kKeyDuration, &duration) &&
|
|
|
|
|
track->meta.findInt32(kKeySampleRate, &samplerate)) {
|
|
|
|
|
|
|
|
|
|
// elst has to be processed only the first time this function is called
|
|
|
|
|
track->has_elst = false;
|
|
|
|
|
|
|
|
|
|
if (track->elst_segment_duration > INT64_MAX) {
|
|
|
|
@ -466,16 +467,19 @@ status_t MPEG4Extractor::getTrackMetaData(
|
|
|
|
|
}
|
|
|
|
|
int64_t segment_duration = track->elst_segment_duration;
|
|
|
|
|
int64_t media_time = track->elst_media_time;
|
|
|
|
|
int64_t halfscale = mHeaderTimescale / 2;
|
|
|
|
|
int64_t halfscale = track->timescale / 2;
|
|
|
|
|
|
|
|
|
|
ALOGV("segment_duration = %" PRId64 ", media_time = %" PRId64
|
|
|
|
|
", halfscale = %" PRId64 ", timescale = %d",
|
|
|
|
|
segment_duration,
|
|
|
|
|
media_time,
|
|
|
|
|
halfscale,
|
|
|
|
|
mHeaderTimescale);
|
|
|
|
|
", halfscale = %" PRId64 ", mdhd_timescale = %d, track_timescale = %u",
|
|
|
|
|
segment_duration, media_time,
|
|
|
|
|
halfscale, mHeaderTimescale, track->timescale);
|
|
|
|
|
|
|
|
|
|
if ((uint32_t)samplerate != track->timescale){
|
|
|
|
|
ALOGV("samplerate:%" PRId32 ", track->timescale and samplerate are different!", samplerate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int64_t delay;
|
|
|
|
|
// delay = ((media_time * samplerate) + halfscale) / mHeaderTimescale;
|
|
|
|
|
// delay = ((media_time * samplerate) + halfscale) / track->timescale;
|
|
|
|
|
if (__builtin_mul_overflow(media_time, samplerate, &delay) ||
|
|
|
|
|
__builtin_add_overflow(delay, halfscale, &delay) ||
|
|
|
|
|
(delay /= mHeaderTimescale, false) ||
|
|
|
|
@ -502,33 +506,43 @@ status_t MPEG4Extractor::getTrackMetaData(
|
|
|
|
|
|
|
|
|
|
int64_t segment_end;
|
|
|
|
|
int64_t padding;
|
|
|
|
|
// padding = scaled_duration - ((segment_duration + media_time) * 1000000);
|
|
|
|
|
if (__builtin_add_overflow(segment_duration, media_time, &segment_end) ||
|
|
|
|
|
__builtin_mul_overflow(segment_end, 1000000, &segment_end) ||
|
|
|
|
|
__builtin_sub_overflow(scaled_duration, segment_end, &padding)) {
|
|
|
|
|
int64_t segment_duration_e6;
|
|
|
|
|
int64_t media_time_scaled_e6;
|
|
|
|
|
int64_t media_time_scaled;
|
|
|
|
|
// padding = scaled_duration - ((segment_duration * 1000000) +
|
|
|
|
|
// ((media_time * mHeaderTimeScale * 1000000)/track->timescale) )
|
|
|
|
|
// segment_duration is based on timescale in movie header box(mdhd)
|
|
|
|
|
// media_time is based on timescale track header/media timescale
|
|
|
|
|
if (__builtin_mul_overflow(segment_duration, 1000000, &segment_duration_e6) ||
|
|
|
|
|
__builtin_mul_overflow(media_time, mHeaderTimescale, &media_time_scaled) ||
|
|
|
|
|
__builtin_mul_overflow(media_time_scaled, 1000000, &media_time_scaled_e6)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
media_time_scaled_e6 /= track->timescale;
|
|
|
|
|
if(__builtin_add_overflow(segment_duration_e6, media_time_scaled_e6, &segment_end) ||
|
|
|
|
|
__builtin_sub_overflow(scaled_duration, segment_end, &padding)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ALOGV("segment_end = %" PRId64 ", padding = %" PRId64, segment_end, padding);
|
|
|
|
|
|
|
|
|
|
int64_t paddingsamples = 0;
|
|
|
|
|
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;
|
|
|
|
|
int64_t halfscale_e6;
|
|
|
|
|
int64_t timescale_e6;
|
|
|
|
|
// paddingsamples = ((padding * samplerate) + (halfscale * 1000000))
|
|
|
|
|
// / (mHeaderTimescale * 1000000);
|
|
|
|
|
if (__builtin_mul_overflow(padding, samplerate, &paddingsamples) ||
|
|
|
|
|
__builtin_mul_overflow(halfscale, 1000000, &halfscale_e6) ||
|
|
|
|
|
__builtin_mul_overflow(mHeaderTimescale, 1000000, ×cale_e6) ||
|
|
|
|
|
__builtin_add_overflow(paddingsamples, halfscale_e6, &paddingsamples) ||
|
|
|
|
|
(paddingsamples /= timescale_e6, false) ||
|
|
|
|
|
paddingsamples > INT32_MAX) {
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
int64_t halfscale_e6;
|
|
|
|
|
int64_t timescale_e6;
|
|
|
|
|
// paddingsamples = ((padding * samplerate) + (halfscale * 1000000))
|
|
|
|
|
// / (mHeaderTimescale * 1000000);
|
|
|
|
|
if (__builtin_mul_overflow(padding, samplerate, &paddingsamples) ||
|
|
|
|
|
__builtin_mul_overflow(halfscale, 1000000, &halfscale_e6) ||
|
|
|
|
|
__builtin_mul_overflow(mHeaderTimescale, 1000000, ×cale_e6) ||
|
|
|
|
|
__builtin_add_overflow(paddingsamples, halfscale_e6, &paddingsamples) ||
|
|
|
|
|
(paddingsamples /= timescale_e6, false) ||
|
|
|
|
|
paddingsamples > INT32_MAX) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ALOGV("paddingsamples = %" PRId64, paddingsamples);
|
|
|
|
|
track->meta.setInt32(kKeyEncoderPadding, paddingsamples);
|
|
|
|
|