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
This commit is contained in:
Andreas Huber
2011-09-19 12:18:47 -07:00
parent c7342fbf99
commit abc63e7f46
2 changed files with 84 additions and 23 deletions

View File

@@ -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

View File

@@ -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 *);