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

Commit 2e880916 authored by Eric (Quic) Ho's avatar Eric (Quic) Ho Committed by Ricardo Cerqueira
Browse files

libstagefright - Fix timestamp overflow

 - change time related variables to 64 bit to avoid overflow
 - composition time calculations were having overflow in
   SampleIterator and it propagates to the rest of the time
   related information for the frames

Change-Id: I035cbfaced1215eb1afd2c6cb900116e46006994
parent 395b6a12
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -443,14 +443,14 @@ sp<MetaData> MPEG4Extractor::getTrackMetaData(
                }
            } else {
                uint32_t sampleIndex;
                uint32_t sampleTime;
                uint64_t sampleTime;
                if (track->sampleTable->findThumbnailSample(&sampleIndex) == OK
                        && track->sampleTable->getMetaDataForSample(
                            sampleIndex, NULL /* offset */, NULL /* size */,
                            &sampleTime) == OK) {
                    track->meta->setInt64(
                            kKeyThumbnailTime,
                            ((int64_t)sampleTime * 1000000) / track->timescale);
                            (sampleTime * 1000000) / track->timescale);
                }
            }
        }
@@ -3071,7 +3071,7 @@ status_t MPEG4Source::read(
                    sampleIndex, &syncSampleIndex, findFlags);
        }

        uint32_t sampleTime;
        uint64_t sampleTime;
        if (err == OK) {
            err = mSampleTable->getMetaDataForSample(
                    sampleIndex, NULL, NULL, &sampleTime);
@@ -3095,7 +3095,7 @@ status_t MPEG4Source::read(
        }

#if 0
        uint32_t syncSampleTime;
        uint64_t syncSampleTime;
        CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
                    syncSampleIndex, NULL, NULL, &syncSampleTime));

@@ -3117,7 +3117,7 @@ status_t MPEG4Source::read(

    off64_t offset;
    size_t size;
    uint32_t cts;
    uint64_t cts;
    bool isSyncSample;
    bool newBuffer = false;
    if (mBuffer == NULL) {
@@ -3155,7 +3155,7 @@ status_t MPEG4Source::read(
            mBuffer->set_range(0, size);
            mBuffer->meta_data()->clear();
            mBuffer->meta_data()->setInt64(
                    kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
                    kKeyTime, (cts * 1000000) / mTimescale);

            if (targetSampleTimeUs >= 0) {
                mBuffer->meta_data()->setInt64(
@@ -3277,7 +3277,7 @@ status_t MPEG4Source::read(

        mBuffer->meta_data()->clear();
        mBuffer->meta_data()->setInt64(
                kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
                kKeyTime, (cts * 1000000) / mTimescale);

        if (targetSampleTimeUs >= 0) {
            mBuffer->meta_data()->setInt64(
+3 −3
Original line number Diff line number Diff line
@@ -286,7 +286,7 @@ status_t SampleIterator::getSampleSizeDirect(
}

status_t SampleIterator::findSampleTime(
        uint32_t sampleIndex, uint32_t *time) {
        uint32_t sampleIndex, uint64_t *time) {
    if (sampleIndex >= mTable->mNumSampleSizes) {
        return ERROR_OUT_OF_RANGE;
    }
@@ -305,9 +305,9 @@ status_t SampleIterator::findSampleTime(
        ++mTimeToSampleIndex;
    }

    *time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
    *time = mTTSSampleTime + (uint64_t)mTTSDuration * ((uint64_t)sampleIndex - (uint64_t)mTTSSampleIndex);

    *time += mTable->getCompositionTimeOffset(sampleIndex);
    *time += (int32_t)mTable->getCompositionTimeOffset(sampleIndex);

    return OK;
}
+10 −10
Original line number Diff line number Diff line
@@ -460,7 +460,7 @@ status_t SampleTable::getMaxSampleSize(size_t *max_size) {
    return OK;
}

uint32_t abs_difference(uint32_t time1, uint32_t time2) {
uint64_t abs_difference(uint64_t time1, uint64_t time2) {
    return time1 > time2 ? time1 - time2 : time2 - time1;
}

@@ -488,7 +488,7 @@ void SampleTable::buildSampleEntriesTable() {
    mSampleTimeEntries = new SampleTimeEntry[mNumSampleSizes];

    uint32_t sampleIndex = 0;
    uint32_t sampleTime = 0;
    uint64_t sampleTime = 0;

    for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
        uint32_t n = mTimeToSample[2 * i];
@@ -520,14 +520,14 @@ void SampleTable::buildSampleEntriesTable() {
}

status_t SampleTable::findSampleAtTime(
        uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
        uint64_t req_time, uint32_t *sample_index, uint32_t flags) {
    buildSampleEntriesTable();

    uint32_t left = 0;
    uint32_t right = mNumSampleSizes;
    while (left < right) {
        uint32_t center = (left + right) / 2;
        uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime;
        uint64_t centerTime = mSampleTimeEntries[center].mCompositionTime;

        if (req_time < centerTime) {
            right = center;
@@ -576,12 +576,12 @@ status_t SampleTable::findSampleAtTime(

            if (closestIndex > 0) {
                // Check left neighbour and pick closest.
                uint32_t absdiff1 =
                uint64_t absdiff1 =
                    abs_difference(
                            mSampleTimeEntries[closestIndex].mCompositionTime,
                            req_time);

                uint32_t absdiff2 =
                uint64_t absdiff2 =
                    abs_difference(
                            mSampleTimeEntries[closestIndex - 1].mCompositionTime,
                            req_time);
@@ -656,20 +656,20 @@ status_t SampleTable::findSyncSampleNear(
            return err;
        }

        uint32_t sample_time = mSampleIterator->getSampleTime();
        uint64_t sample_time = mSampleIterator->getSampleTime();

        err = mSampleIterator->seekTo(x);
        if (err != OK) {
            return err;
        }
        uint32_t x_time = mSampleIterator->getSampleTime();
        uint64_t x_time = mSampleIterator->getSampleTime();

        err = mSampleIterator->seekTo(y);
        if (err != OK) {
            return err;
        }

        uint32_t y_time = mSampleIterator->getSampleTime();
        uint64_t y_time = mSampleIterator->getSampleTime();

        if (abs_difference(x_time, sample_time)
                > abs_difference(y_time, sample_time)) {
@@ -777,7 +777,7 @@ status_t SampleTable::getMetaDataForSample(
        uint32_t sampleIndex,
        off64_t *offset,
        size_t *size,
        uint32_t *compositionTime,
        uint64_t *compositionTime,
        bool *isSyncSample) {
    Mutex::Autolock autoLock(mLock);

+4 −4
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ struct SampleIterator {
    uint32_t getDescIndex() const { return mChunkDesc; }
    off64_t getSampleOffset() const { return mCurrentSampleOffset; }
    size_t getSampleSize() const { return mCurrentSampleSize; }
    uint32_t getSampleTime() const { return mCurrentSampleTime; }
    uint64_t getSampleTime() const { return mCurrentSampleTime; }

    status_t getSampleSizeDirect(
            uint32_t sampleIndex, size_t *size);
@@ -53,19 +53,19 @@ private:

    uint32_t mTimeToSampleIndex;
    uint32_t mTTSSampleIndex;
    uint32_t mTTSSampleTime;
    uint64_t mTTSSampleTime;
    uint32_t mTTSCount;
    uint32_t mTTSDuration;

    uint32_t mCurrentSampleIndex;
    off64_t mCurrentSampleOffset;
    size_t mCurrentSampleSize;
    uint32_t mCurrentSampleTime;
    uint64_t mCurrentSampleTime;

    void reset();
    status_t findChunkRange(uint32_t sampleIndex);
    status_t getChunkOffset(uint32_t chunk, off64_t *offset);
    status_t findSampleTime(uint32_t sampleIndex, uint32_t *time);
    status_t findSampleTime(uint32_t sampleIndex, uint64_t *time);

    SampleIterator(const SampleIterator &);
    SampleIterator &operator=(const SampleIterator &);
+3 −3
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ public:
            uint32_t sampleIndex,
            off64_t *offset,
            size_t *size,
            uint32_t *compositionTime,
            uint64_t *compositionTime,
            bool *isSyncSample = NULL);

    enum {
@@ -74,7 +74,7 @@ public:
        kFlagClosest
    };
    status_t findSampleAtTime(
            uint32_t req_time, uint32_t *sample_index, uint32_t flags);
            uint64_t req_time, uint32_t *sample_index, uint32_t flags);

    status_t findSyncSampleNear(
            uint32_t start_sample_index, uint32_t *sample_index,
@@ -113,7 +113,7 @@ private:

    struct SampleTimeEntry {
        uint32_t mSampleIndex;
        uint32_t mCompositionTime;
        uint64_t mCompositionTime;
    };
    SampleTimeEntry *mSampleTimeEntries;