From 4678a6dc5f09008481524949a9667af5a6190374 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Fri, 15 Apr 2011 11:52:29 -0700 Subject: 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 --- media/libstagefright/SampleTable.cpp | 159 ++++++++++++++++++++++++----------- 1 file changed, 112 insertions(+), 47 deletions(-) (limited to 'media/libstagefright/SampleTable.cpp') 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 &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) { -- cgit v1.1