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

Commit b1dc9e07 authored by Marco Nelissen's avatar Marco Nelissen
Browse files

Always treat composition time offsets as signed

even for version 0 ctts atoms that technically should contain only
unsigned values.

Bug: 27174229
Change-Id: I7309222f5fe646c25c45ff5351bfc310759ef542
parent cf1bbf3a
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -320,7 +320,18 @@ status_t SampleIterator::findSampleTimeAndDuration(

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

    *time += mTable->getCompositionTimeOffset(sampleIndex);
    int32_t offset = mTable->getCompositionTimeOffset(sampleIndex);
    if ((offset < 0 && *time < (offset == INT32_MIN ?
            INT32_MAX : uint32_t(-offset))) ||
            (offset > 0 && *time > UINT32_MAX - offset)) {
        ALOGE("%u + %d would overflow", *time, offset);
        return ERROR_OUT_OF_RANGE;
    }
    if (offset > 0) {
        *time += offset;
    } else {
        *time -= (offset == INT32_MIN ? INT32_MAX : (-offset));
    }

    *duration = mTTSDuration;

+35 −11
Original line number Diff line number Diff line
@@ -49,14 +49,14 @@ struct SampleTable::CompositionDeltaLookup {
    CompositionDeltaLookup();

    void setEntries(
            const uint32_t *deltaEntries, size_t numDeltaEntries);
            const int32_t *deltaEntries, size_t numDeltaEntries);

    uint32_t getCompositionTimeOffset(uint32_t sampleIndex);
    int32_t getCompositionTimeOffset(uint32_t sampleIndex);

private:
    Mutex mLock;

    const uint32_t *mDeltaEntries;
    const int32_t *mDeltaEntries;
    size_t mNumDeltaEntries;

    size_t mCurrentDeltaEntry;
@@ -73,7 +73,7 @@ SampleTable::CompositionDeltaLookup::CompositionDeltaLookup()
}

void SampleTable::CompositionDeltaLookup::setEntries(
        const uint32_t *deltaEntries, size_t numDeltaEntries) {
        const int32_t *deltaEntries, size_t numDeltaEntries) {
    Mutex::Autolock autolock(mLock);

    mDeltaEntries = deltaEntries;
@@ -82,7 +82,7 @@ void SampleTable::CompositionDeltaLookup::setEntries(
    mCurrentEntrySampleIndex = 0;
}

uint32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset(
int32_t SampleTable::CompositionDeltaLookup::getCompositionTimeOffset(
        uint32_t sampleIndex) {
    Mutex::Autolock autolock(mLock);

@@ -372,6 +372,10 @@ status_t SampleTable::setTimeToSampleParams(
    return OK;
}

// NOTE: per 14996-12, version 0 ctts contains unsigned values, while version 1
// contains signed values, however some software creates version 0 files that
// contain signed values, so we're always treating the values as signed,
// regardless of version.
status_t SampleTable::setCompositionTimeToSampleParams(
        off64_t data_offset, size_t data_size) {
    ALOGI("There are reordered frames present.");
@@ -387,8 +391,12 @@ status_t SampleTable::setCompositionTimeToSampleParams(
        return ERROR_IO;
    }

    if (U32_AT(header) != 0) {
        // Expected version = 0, flags = 0.
    uint32_t flags = U32_AT(header);
    uint32_t version = flags >> 24;
    flags &= 0xffffff;

    if ((version != 0 && version != 1) || flags != 0) {
        // Expected version = 0 or 1, flags = 0.
        return ERROR_MALFORMED;
    }

@@ -404,7 +412,7 @@ status_t SampleTable::setCompositionTimeToSampleParams(
        return ERROR_OUT_OF_RANGE;
    }

    mCompositionTimeDeltaEntries = new (std::nothrow) uint32_t[2 * numEntries];
    mCompositionTimeDeltaEntries = new (std::nothrow) int32_t[2 * numEntries];
    if (!mCompositionTimeDeltaEntries)
        return ERROR_OUT_OF_RANGE;

@@ -546,12 +554,28 @@ void SampleTable::buildSampleEntriesTable() {

                mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;

                uint32_t compTimeDelta =
                int32_t compTimeDelta =
                    mCompositionDeltaLookup->getCompositionTimeOffset(
                            sampleIndex);

                if ((compTimeDelta < 0 && sampleTime <
                        (compTimeDelta == INT32_MIN ?
                                INT32_MAX : uint32_t(-compTimeDelta)))
                        || (compTimeDelta > 0 &&
                                sampleTime > UINT32_MAX - compTimeDelta)) {
                    ALOGE("%u + %d would overflow, clamping",
                            sampleTime, compTimeDelta);
                    if (compTimeDelta < 0) {
                        sampleTime = 0;
                    } else {
                        sampleTime = UINT32_MAX;
                    }
                    compTimeDelta = 0;
                }

                mSampleTimeEntries[sampleIndex].mCompositionTime =
                    sampleTime + compTimeDelta;
                        compTimeDelta > 0 ? sampleTime + compTimeDelta:
                                sampleTime - (-compTimeDelta);
            }

            ++sampleIndex;
@@ -841,7 +865,7 @@ status_t SampleTable::getMetaDataForSample(
    return OK;
}

uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
int32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
    return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex);
}

+2 −2
Original line number Diff line number Diff line
@@ -119,7 +119,7 @@ private:
    };
    SampleTimeEntry *mSampleTimeEntries;

    uint32_t *mCompositionTimeDeltaEntries;
    int32_t *mCompositionTimeDeltaEntries;
    size_t mNumCompositionTimeDeltaEntries;
    CompositionDeltaLookup *mCompositionDeltaLookup;

@@ -148,7 +148,7 @@ private:
    }

    status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size);
    uint32_t getCompositionTimeOffset(uint32_t sampleIndex);
    int32_t getCompositionTimeOffset(uint32_t sampleIndex);

    static int CompareIncreasingTime(const void *, const void *);