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

Commit c71583ee authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

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

parents d6a74eb9 96b48f71
Loading
Loading
Loading
Loading
+71 −27
Original line number Original line Diff line number Diff line
@@ -463,6 +463,66 @@ sp<MetaData> MPEG4Extractor::getTrackMetaData(
        return NULL;
        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)
    if ((flags & kIncludeExtensiveMetaData)
            && !track->includes_expensive_metadata) {
            && !track->includes_expensive_metadata) {
        track->includes_expensive_metadata = true;
        track->includes_expensive_metadata = true;
@@ -989,6 +1049,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                track->skipTrack = false;
                track->skipTrack = false;
                track->timescale = 0;
                track->timescale = 0;
                track->meta->setCString(kKeyMIMEType, "application/octet-stream");
                track->meta->setCString(kKeyMIMEType, "application/octet-stream");
                track->has_elst = false;
            }
            }


            off64_t stop_offset = *offset + chunk_size;
            off64_t stop_offset = *offset + chunk_size;
@@ -1055,6 +1116,10 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
        {
        {
            *offset += chunk_size;
            *offset += chunk_size;


            if (!mLastTrack) {
                return ERROR_MALFORMED;
            }

            // See 14496-12 8.6.6
            // See 14496-12 8.6.6
            uint8_t version;
            uint8_t version;
            if (mDataSource->readAt(data_offset, &version, 1) < 1) {
            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) {
            if (entry_count != 1) {
                // we only support a single entry at the moment, for gapless playback
                // we only support a single entry at the moment, for gapless playback
                ALOGW("ignoring edit list with %d entries", entry_count);
                ALOGW("ignoring edit list with %d entries", entry_count);
            } else if (mHeaderTimescale == 0) {
                ALOGW("ignoring edit list because timescale is 0");
            } else {
            } else {
                off64_t entriesoffset = data_offset + 8;
                off64_t entriesoffset = data_offset + 8;
                uint64_t segment_duration;
                uint64_t segment_duration;
@@ -1094,31 +1157,12 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                    return ERROR_IO;
                    return ERROR_IO;
                }
                }


                uint64_t halfscale = mHeaderTimescale / 2;
                // save these for later, because the elst atom might precede
                segment_duration = (segment_duration * 1000000 + halfscale)/ mHeaderTimescale;
                // the atoms that actually gives us the duration and sample rate
                media_time = (media_time * 1000000 + halfscale) / mHeaderTimescale;
                // needed to calculate the padding and delay values

                mLastTrack->has_elst = true;
                int64_t duration;
                mLastTrack->elst_media_time = media_time;
                int32_t samplerate;
                mLastTrack->elst_segment_duration = segment_duration;
                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);
                }
            }
            }
            break;
            break;
        }
        }
+3 −0
Original line number Original line Diff line number Diff line
@@ -82,6 +82,9 @@ private:
        sp<SampleTable> sampleTable;
        sp<SampleTable> sampleTable;
        bool includes_expensive_metadata;
        bool includes_expensive_metadata;
        bool skipTrack;
        bool skipTrack;
        bool has_elst;
        int64_t elst_media_time;
        uint64_t elst_segment_duration;
    };
    };


    Vector<SidxEntry> mSidxEntries;
    Vector<SidxEntry> mSidxEntries;