Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f64fa712 authored by Marco Nelissen's avatar Marco Nelissen Committed by android-build-merger
Browse files

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

am: c71583ee

Change-Id: I47e5508ba8abcf13fbabb63a8eab5344b69c4932
parents 0a083987 c71583ee
Loading
Loading
Loading
Loading
+71 −27
Original line number Diff line number Diff line
@@ -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;
@@ -995,6 +1055,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;
@@ -1061,6 +1122,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) {
@@ -1075,8 +1140,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;
@@ -1100,31 +1163,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;
        }
+3 −0
Original line number Diff line number Diff line
@@ -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;