summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/SampleTable.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-09-19 12:18:47 -0700
committerAndreas Huber <andih@google.com>2011-09-19 12:21:33 -0700
commit89aa8fe4cb00d2f24260005b008602232d678684 (patch)
tree06d871b702884809f45f70ed71b19917cc93fd3d /media/libstagefright/SampleTable.cpp
parent84ada693b87f4d9344578e750a506b7789c13eb9 (diff)
downloadframeworks_av-89aa8fe4cb00d2f24260005b008602232d678684.zip
frameworks_av-89aa8fe4cb00d2f24260005b008602232d678684.tar.gz
frameworks_av-89aa8fe4cb00d2f24260005b008602232d678684.tar.bz2
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
Diffstat (limited to 'media/libstagefright/SampleTable.cpp')
-rw-r--r--media/libstagefright/SampleTable.cpp101
1 files changed, 80 insertions, 21 deletions
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index 2b9d99b..ebad321 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -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