summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/SampleTable.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2011-04-15 11:52:29 -0700
committerAndreas Huber <andih@google.com>2011-04-15 11:52:29 -0700
commit4678a6dc5f09008481524949a9667af5a6190374 (patch)
treed11859556aca985b86bc89605bc2e4535f77ce7e /media/libstagefright/SampleTable.cpp
parente2e3f479fe160e8ba00321ada2c61d4bcaf5be4d (diff)
downloadframeworks_av-4678a6dc5f09008481524949a9667af5a6190374.zip
frameworks_av-4678a6dc5f09008481524949a9667af5a6190374.tar.gz
frameworks_av-4678a6dc5f09008481524949a9667af5a6190374.tar.bz2
Remove streamability verification, it's taking too long. Also...
make sure that findSampleAtTime uses composition time instead of decoding time, at the expense of extra memory. Change-Id: I67d09389b3df7ed265f614bdd0b142ca7f19f86a related-to-bug: 4294536
Diffstat (limited to 'media/libstagefright/SampleTable.cpp')
-rw-r--r--media/libstagefright/SampleTable.cpp159
1 files changed, 112 insertions, 47 deletions
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index 423df70..08db902 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -53,6 +53,7 @@ SampleTable::SampleTable(const sp<DataSource> &source)
mNumSampleSizes(0),
mTimeToSampleCount(0),
mTimeToSample(NULL),
+ mSampleTimeEntries(NULL),
mCompositionTimeDeltaEntries(NULL),
mNumCompositionTimeDeltaEntries(0),
mSyncSampleOffset(-1),
@@ -73,6 +74,9 @@ SampleTable::~SampleTable() {
delete[] mCompositionTimeDeltaEntries;
mCompositionTimeDeltaEntries = NULL;
+ delete[] mSampleTimeEntries;
+ mSampleTimeEntries = NULL;
+
delete[] mTimeToSample;
mTimeToSample = NULL;
@@ -381,67 +385,128 @@ uint32_t abs_difference(uint32_t time1, uint32_t time2) {
return time1 > time2 ? time1 - time2 : time2 - time1;
}
-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.
+// static
+int SampleTable::CompareIncreasingTime(const void *_a, const void *_b) {
+ const SampleTimeEntry *a = (const SampleTimeEntry *)_a;
+ const SampleTimeEntry *b = (const SampleTimeEntry *)_b;
- *sample_index = 0;
+ if (a->mCompositionTime < b->mCompositionTime) {
+ return -1;
+ } else if (a->mCompositionTime > b->mCompositionTime) {
+ return 1;
+ }
+
+ return 0;
+}
+void SampleTable::buildSampleEntriesTable() {
Mutex::Autolock autoLock(mLock);
- uint32_t cur_sample = 0;
- uint32_t time = 0;
+ if (mSampleTimeEntries != NULL) {
+ return;
+ }
+
+ mSampleTimeEntries = new SampleTimeEntry[mNumSampleSizes];
+
+ uint32_t sampleIndex = 0;
+ uint32_t sampleTime = 0;
+
for (uint32_t i = 0; i < mTimeToSampleCount; ++i) {
uint32_t n = mTimeToSample[2 * i];
uint32_t delta = mTimeToSample[2 * i + 1];
- if (req_time < time + n * delta) {
- int j = (req_time - time) / delta;
-
- uint32_t time1 = time + j * delta;
- uint32_t time2 = time1 + delta;
-
- uint32_t sampleTime;
- if (i+1 == mTimeToSampleCount
- || (abs_difference(req_time, time1)
- < abs_difference(req_time, time2))) {
- *sample_index = cur_sample + j;
- sampleTime = time1;
- } else {
- *sample_index = cur_sample + j + 1;
- sampleTime = time2;
- }
+ for (uint32_t j = 0; j < n; ++j) {
+ CHECK(sampleIndex < mNumSampleSizes);
- switch (flags) {
- case kFlagBefore:
- {
- if (sampleTime > req_time && *sample_index > 0) {
- --*sample_index;
- }
- break;
- }
+ mSampleTimeEntries[sampleIndex].mSampleIndex = sampleIndex;
- case kFlagAfter:
- {
- if (sampleTime < req_time
- && *sample_index + 1 < mNumSampleSizes) {
- ++*sample_index;
- }
- break;
- }
+ mSampleTimeEntries[sampleIndex].mCompositionTime =
+ sampleTime + getCompositionTimeOffset(sampleIndex);
+
+ ++sampleIndex;
+ sampleTime += delta;
+ }
+ }
+
+ qsort(mSampleTimeEntries, mNumSampleSizes, sizeof(SampleTimeEntry),
+ CompareIncreasingTime);
+}
- default:
- break;
+status_t SampleTable::findSampleAtTime(
+ uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
+ buildSampleEntriesTable();
+
+ uint32_t left = 0;
+ uint32_t right = mNumSampleSizes;
+ while (left < right) {
+ uint32_t center = (left + right) / 2;
+ uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime;
+
+ if (req_time < centerTime) {
+ right = center;
+ } else if (req_time > centerTime) {
+ left = center + 1;
+ } else {
+ left = center;
+ break;
+ }
+ }
+
+ if (left == mNumSampleSizes) {
+ --left;
+ }
+
+ uint32_t closestIndex = left;
+
+ switch (flags) {
+ case kFlagBefore:
+ {
+ while (closestIndex > 0
+ && mSampleTimeEntries[closestIndex].mCompositionTime
+ > req_time) {
+ --closestIndex;
}
+ break;
+ }
- return OK;
+ case kFlagAfter:
+ {
+ while (closestIndex + 1 < mNumSampleSizes
+ && mSampleTimeEntries[closestIndex].mCompositionTime
+ < req_time) {
+ ++closestIndex;
+ }
+ break;
}
- time += delta * n;
- cur_sample += n;
+ default:
+ {
+ CHECK(flags == kFlagClosest);
+
+ if (closestIndex > 0) {
+ // Check left neighbour and pick closest.
+ uint32_t absdiff1 =
+ abs_difference(
+ mSampleTimeEntries[closestIndex].mCompositionTime,
+ req_time);
+
+ uint32_t absdiff2 =
+ abs_difference(
+ mSampleTimeEntries[closestIndex - 1].mCompositionTime,
+ req_time);
+
+ if (absdiff1 > absdiff2) {
+ closestIndex = closestIndex - 1;
+ }
+ }
+
+ break;
+ }
}
- return ERROR_OUT_OF_RANGE;
+ *sample_index = mSampleTimeEntries[closestIndex].mSampleIndex;
+
+ return OK;
}
status_t SampleTable::findSyncSampleNear(
@@ -613,7 +678,7 @@ status_t SampleTable::getMetaDataForSample(
uint32_t sampleIndex,
off64_t *offset,
size_t *size,
- uint32_t *decodingTime,
+ uint32_t *compositionTime,
bool *isSyncSample) {
Mutex::Autolock autoLock(mLock);
@@ -630,8 +695,8 @@ status_t SampleTable::getMetaDataForSample(
*size = mSampleIterator->getSampleSize();
}
- if (decodingTime) {
- *decodingTime = mSampleIterator->getSampleTime();
+ if (compositionTime) {
+ *compositionTime = mSampleIterator->getSampleTime();
}
if (isSyncSample) {