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

Commit 1122fe90 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Make sure timestamps attached to encoded media are composition timestamps."

parents c33bf55c bd352c3c
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1074,6 +1074,20 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
            break;
        }

        case FOURCC('c', 't', 't', 's'):
        {
            status_t err =
                mLastTrack->sampleTable->setCompositionTimeToSampleParams(
                        data_offset, chunk_data_size);

            if (err != OK) {
                return err;
            }

            *offset += chunk_size;
            break;
        }

        case FOURCC('s', 't', 's', 's'):
        {
            status_t err =
+2 −0
Original line number Diff line number Diff line
@@ -307,6 +307,8 @@ status_t SampleIterator::findSampleTime(

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

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

    return OK;
}

+73 −0
Original line number Diff line number Diff line
@@ -53,6 +53,8 @@ SampleTable::SampleTable(const sp<DataSource> &source)
      mNumSampleSizes(0),
      mTimeToSampleCount(0),
      mTimeToSample(NULL),
      mCompositionTimeDeltaEntries(NULL),
      mNumCompositionTimeDeltaEntries(0),
      mSyncSampleOffset(-1),
      mNumSyncSamples(0),
      mSyncSamples(NULL),
@@ -68,6 +70,9 @@ SampleTable::~SampleTable() {
    delete[] mSyncSamples;
    mSyncSamples = NULL;

    delete[] mCompositionTimeDeltaEntries;
    mCompositionTimeDeltaEntries = NULL;

    delete[] mTimeToSample;
    mTimeToSample = NULL;

@@ -260,6 +265,51 @@ status_t SampleTable::setTimeToSampleParams(
    return OK;
}

status_t SampleTable::setCompositionTimeToSampleParams(
        off64_t data_offset, size_t data_size) {
    LOGI("There are reordered frames present.");

    if (mCompositionTimeDeltaEntries != NULL || data_size < 8) {
        return ERROR_MALFORMED;
    }

    uint8_t header[8];
    if (mDataSource->readAt(
                data_offset, header, sizeof(header))
            < (ssize_t)sizeof(header)) {
        return ERROR_IO;
    }

    if (U32_AT(header) != 0) {
        // Expected version = 0, flags = 0.
        return ERROR_MALFORMED;
    }

    size_t numEntries = U32_AT(&header[4]);

    if (data_size != (numEntries + 1) * 8) {
        return ERROR_MALFORMED;
    }

    mNumCompositionTimeDeltaEntries = numEntries;
    mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries];

    if (mDataSource->readAt(
                data_offset + 8, mCompositionTimeDeltaEntries, numEntries * 8)
            < (ssize_t)numEntries * 8) {
        delete[] mCompositionTimeDeltaEntries;
        mCompositionTimeDeltaEntries = NULL;

        return ERROR_IO;
    }

    for (size_t i = 0; i < 2 * numEntries; ++i) {
        mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
    }

    return OK;
}

status_t SampleTable::setSyncSampleParams(off64_t data_offset, size_t data_size) {
    if (mSyncSampleOffset >= 0 || data_size < 8) {
        return ERROR_MALFORMED;
@@ -333,6 +383,8 @@ uint32_t abs_difference(uint32_t time1, uint32_t time2) {

status_t SampleTable::findSampleAtTime(
        uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
    // XXX this currently uses decoding time, instead of composition time.

    *sample_index = 0;

    Mutex::Autolock autoLock(mLock);
@@ -607,5 +659,26 @@ status_t SampleTable::getMetaDataForSample(
    return OK;
}

uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) const {
    if (mCompositionTimeDeltaEntries == NULL) {
        return 0;
    }

    uint32_t curSample = 0;
    for (size_t i = 0; i < mNumCompositionTimeDeltaEntries; ++i) {
        uint32_t sampleCount = mCompositionTimeDeltaEntries[2 * i];

        if (sampleIndex < curSample + sampleCount) {
            uint32_t sampleDelta = mCompositionTimeDeltaEntries[2 * i + 1];

            return sampleDelta;
        }

        curSample += sampleCount;
    }

    return 0;
}

}  // namespace android
+8 −0
Original line number Diff line number Diff line
@@ -46,6 +46,9 @@ public:

    status_t setTimeToSampleParams(off64_t data_offset, size_t data_size);

    status_t setCompositionTimeToSampleParams(
            off64_t data_offset, size_t data_size);

    status_t setSyncSampleParams(off64_t data_offset, size_t data_size);

    ////////////////////////////////////////////////////////////////////////////
@@ -104,6 +107,9 @@ private:
    uint32_t mTimeToSampleCount;
    uint32_t *mTimeToSample;

    uint32_t *mCompositionTimeDeltaEntries;
    size_t mNumCompositionTimeDeltaEntries;

    off64_t mSyncSampleOffset;
    uint32_t mNumSyncSamples;
    uint32_t *mSyncSamples;
@@ -122,6 +128,8 @@ private:

    status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size);

    uint32_t getCompositionTimeOffset(uint32_t sampleIndex) const;

    SampleTable(const SampleTable &);
    SampleTable &operator=(const SampleTable &);
};