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

Commit 89aa8fe4 authored by Andreas Huber's avatar Andreas Huber
Browse files

Remove an O(n^2) algorithm in MPEG4Extractor.cpp to speed up seeks in long streams

containing B-frames.

Change-Id: Ie4dc734d2c2d5a5ce84674bb883f4b27e2278642
related-to-bug: 5336497
parent 84ada693
Loading
Loading
Loading
Loading
+80 −21
Original line number Diff line number Diff line
@@ -23,8 +23,8 @@

#include <arpa/inet.h>

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaDebug.h>
#include <media/stagefright/Utils.h>

namespace android {
@@ -40,6 +40,71 @@ const uint32_t SampleTable::kSampleSizeTypeCompact = FOURCC('s', 't', 'z', '2');

////////////////////////////////////////////////////////////////////////////////

struct SampleTable::CompositionDeltaLookup {
    CompositionDeltaLookup();

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

    uint32_t getCompositionTimeOffset(uint32_t sampleIndex);

private:
    Mutex mLock;

    const uint32_t *mDeltaEntries;
    size_t mNumDeltaEntries;

    size_t mCurrentDeltaEntry;
    size_t mCurrentEntrySampleIndex;

    DISALLOW_EVIL_CONSTRUCTORS(CompositionDeltaLookup);
};

SampleTable::CompositionDeltaLookup::CompositionDeltaLookup()
    : mDeltaEntries(NULL),
      mNumDeltaEntries(0),
      mCurrentDeltaEntry(0),
      mCurrentEntrySampleIndex(0) {
}

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

    mDeltaEntries = deltaEntries;
    mNumDeltaEntries = numDeltaEntries;
    mCurrentDeltaEntry = 0;
    mCurrentEntrySampleIndex = 0;
}

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

    if (mDeltaEntries == NULL) {
        return 0;
    }

    if (sampleIndex < mCurrentEntrySampleIndex) {
        mCurrentDeltaEntry = 0;
        mCurrentEntrySampleIndex = 0;
    }

    while (mCurrentDeltaEntry < mNumDeltaEntries) {
        uint32_t sampleCount = mDeltaEntries[2 * mCurrentDeltaEntry];
        if (sampleIndex < mCurrentEntrySampleIndex + sampleCount) {
            return mDeltaEntries[2 * mCurrentDeltaEntry + 1];
        }

        mCurrentEntrySampleIndex += sampleCount;
        ++mCurrentDeltaEntry;
    }

    return 0;
}

////////////////////////////////////////////////////////////////////////////////

SampleTable::SampleTable(const sp<DataSource> &source)
    : mDataSource(source),
      mChunkOffsetOffset(-1),
@@ -56,6 +121,7 @@ SampleTable::SampleTable(const sp<DataSource> &source)
      mSampleTimeEntries(NULL),
      mCompositionTimeDeltaEntries(NULL),
      mNumCompositionTimeDeltaEntries(0),
      mCompositionDeltaLookup(new CompositionDeltaLookup),
      mSyncSampleOffset(-1),
      mNumSyncSamples(0),
      mSyncSamples(NULL),
@@ -71,6 +137,9 @@ SampleTable::~SampleTable() {
    delete[] mSyncSamples;
    mSyncSamples = NULL;

    delete mCompositionDeltaLookup;
    mCompositionDeltaLookup = NULL;

    delete[] mCompositionTimeDeltaEntries;
    mCompositionTimeDeltaEntries = NULL;

@@ -318,6 +387,9 @@ status_t SampleTable::setCompositionTimeToSampleParams(
        mCompositionTimeDeltaEntries[i] = ntohl(mCompositionTimeDeltaEntries[i]);
    }

    mCompositionDeltaLookup->setEntries(
            mCompositionTimeDeltaEntries, mNumCompositionTimeDeltaEntries);

    return OK;
}

@@ -430,8 +502,12 @@ void SampleTable::buildSampleEntriesTable() {

                mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;

                uint32_t compTimeDelta =
                    mCompositionDeltaLookup->getCompositionTimeOffset(
                            sampleIndex);

                mSampleTimeEntries[sampleIndex].mCompositionTime =
                    sampleTime + getCompositionTimeOffset(sampleIndex);
                    sampleTime + compTimeDelta;
            }

            ++sampleIndex;
@@ -739,25 +815,8 @@ 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;
uint32_t SampleTable::getCompositionTimeOffset(uint32_t sampleIndex) {
    return mCompositionDeltaLookup->getCompositionTimeOffset(sampleIndex);
}

}  // namespace android
+4 −2
Original line number Diff line number Diff line
@@ -86,6 +86,8 @@ protected:
    ~SampleTable();

private:
    struct CompositionDeltaLookup;

    static const uint32_t kChunkOffsetType32;
    static const uint32_t kChunkOffsetType64;
    static const uint32_t kSampleSizeType32;
@@ -117,6 +119,7 @@ private:

    uint32_t *mCompositionTimeDeltaEntries;
    size_t mNumCompositionTimeDeltaEntries;
    CompositionDeltaLookup *mCompositionDeltaLookup;

    off64_t mSyncSampleOffset;
    uint32_t mNumSyncSamples;
@@ -135,8 +138,7 @@ private:
    friend struct SampleIterator;

    status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size);

    uint32_t getCompositionTimeOffset(uint32_t sampleIndex) const;
    uint32_t getCompositionTimeOffset(uint32_t sampleIndex);

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