summaryrefslogtreecommitdiffstats
path: root/media
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
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')
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp91
-rw-r--r--media/libstagefright/SampleTable.cpp159
-rw-r--r--media/libstagefright/include/MPEG4Extractor.h2
-rw-r--r--media/libstagefright/include/SampleTable.h12
4 files changed, 128 insertions, 136 deletions
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 1ca2d6d..f9db1a1 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -377,7 +377,7 @@ status_t MPEG4Extractor::readMetaData() {
mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
}
- mInitCheck = verifyIfStreamable();
+ mInitCheck = OK;
} else {
mInitCheck = err;
}
@@ -1904,7 +1904,7 @@ status_t MPEG4Source::read(
off64_t offset;
size_t size;
- uint32_t dts;
+ uint32_t cts;
bool isSyncSample;
bool newBuffer = false;
if (mBuffer == NULL) {
@@ -1912,7 +1912,7 @@ status_t MPEG4Source::read(
status_t err =
mSampleTable->getMetaDataForSample(
- mCurrentSampleIndex, &offset, &size, &dts, &isSyncSample);
+ mCurrentSampleIndex, &offset, &size, &cts, &isSyncSample);
if (err != OK) {
return err;
@@ -1942,7 +1942,7 @@ status_t MPEG4Source::read(
mBuffer->set_range(0, size);
mBuffer->meta_data()->clear();
mBuffer->meta_data()->setInt64(
- kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
+ kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
mBuffer->meta_data()->setInt64(
@@ -2060,7 +2060,7 @@ status_t MPEG4Source::read(
mBuffer->meta_data()->clear();
mBuffer->meta_data()->setInt64(
- kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
+ kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
mBuffer->meta_data()->setInt64(
@@ -2094,87 +2094,6 @@ MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
return NULL;
}
-status_t MPEG4Extractor::verifyIfStreamable() {
- if (!(mDataSource->flags() & DataSource::kIsCachingDataSource)) {
- return OK;
- }
-
- Track *audio = findTrackByMimePrefix("audio/");
- Track *video = findTrackByMimePrefix("video/");
-
- if (audio == NULL || video == NULL) {
- return OK;
- }
-
- sp<SampleTable> audioSamples = audio->sampleTable;
- sp<SampleTable> videoSamples = video->sampleTable;
-
- off64_t maxOffsetDiff = 0;
- int64_t maxOffsetTimeUs = -1;
-
- for (uint32_t i = 0; i < videoSamples->countSamples(); ++i) {
- off64_t videoOffset;
- uint32_t videoTime;
- bool isSync;
- CHECK_EQ((status_t)OK, videoSamples->getMetaDataForSample(
- i, &videoOffset, NULL, &videoTime, &isSync));
-
- int64_t videoTimeUs = (int64_t)(videoTime * 1E6 / video->timescale);
-
- uint32_t reqAudioTime = (videoTimeUs * audio->timescale) / 1000000;
- uint32_t j;
- if (audioSamples->findSampleAtTime(
- reqAudioTime, &j, SampleTable::kFlagClosest) != OK) {
- continue;
- }
-
- off64_t audioOffset;
- uint32_t audioTime;
- CHECK_EQ((status_t)OK, audioSamples->getMetaDataForSample(
- j, &audioOffset, NULL, &audioTime));
-
- int64_t audioTimeUs = (int64_t)(audioTime * 1E6 / audio->timescale);
-
- off64_t offsetDiff = videoOffset - audioOffset;
- if (offsetDiff < 0) {
- offsetDiff = -offsetDiff;
- }
-
-#if 0
- printf("%s%d/%d videoTime %.2f secs audioTime %.2f secs "
- "videoOffset %lld audioOffset %lld offsetDiff %lld\n",
- isSync ? "*" : " ",
- i,
- j,
- videoTimeUs / 1E6,
- audioTimeUs / 1E6,
- videoOffset,
- audioOffset,
- offsetDiff);
-#endif
-
- if (offsetDiff > maxOffsetDiff) {
- maxOffsetDiff = offsetDiff;
- maxOffsetTimeUs = videoTimeUs;
- }
- }
-
-#if 0
- printf("max offset diff: %lld at video time: %.2f secs\n",
- maxOffsetDiff, maxOffsetTimeUs / 1E6);
-#endif
-
- if (maxOffsetDiff < 1024 * 1024) {
- return OK;
- }
-
- LOGE("This content is not streamable, "
- "max offset diff: %lld at video time: %.2f secs",
- maxOffsetDiff, maxOffsetTimeUs / 1E6);
-
- return ERROR_UNSUPPORTED;
-}
-
static bool LegacySniffMPEG4(
const sp<DataSource> &source, String8 *mimeType, float *confidence) {
uint8_t header[8];
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) {
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index d9ef208..3bd4c7e 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -92,8 +92,6 @@ private:
Track *findTrackByMimePrefix(const char *mimePrefix);
- status_t verifyIfStreamable();
-
MPEG4Extractor(const MPEG4Extractor &);
MPEG4Extractor &operator=(const MPEG4Extractor &);
};
diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h
index 2f95de9..f44e0a2 100644
--- a/media/libstagefright/include/SampleTable.h
+++ b/media/libstagefright/include/SampleTable.h
@@ -63,7 +63,7 @@ public:
uint32_t sampleIndex,
off64_t *offset,
size_t *size,
- uint32_t *decodingTime,
+ uint32_t *compositionTime,
bool *isSyncSample = NULL);
enum {
@@ -107,6 +107,12 @@ private:
uint32_t mTimeToSampleCount;
uint32_t *mTimeToSample;
+ struct SampleTimeEntry {
+ uint32_t mSampleIndex;
+ uint32_t mCompositionTime;
+ };
+ SampleTimeEntry *mSampleTimeEntries;
+
uint32_t *mCompositionTimeDeltaEntries;
size_t mNumCompositionTimeDeltaEntries;
@@ -130,6 +136,10 @@ private:
uint32_t getCompositionTimeOffset(uint32_t sampleIndex) const;
+ static int CompareIncreasingTime(const void *, const void *);
+
+ void buildSampleEntriesTable();
+
SampleTable(const SampleTable &);
SampleTable &operator=(const SampleTable &);
};