summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/MPEG4Extractor.cpp
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-07-20 15:04:28 -0700
committerAndreas Huber <andih@google.com>2010-07-21 08:51:29 -0700
commitabd1f4f870925d6776dbe4b930b759a1ab6595ca (patch)
tree1b86ec19a16a2a340afecfd6207b1fd8236228b9 /media/libstagefright/MPEG4Extractor.cpp
parent3108231d90e8aa324923fd8864ca2477948c5d25 (diff)
downloadframeworks_av-abd1f4f870925d6776dbe4b930b759a1ab6595ca.zip
frameworks_av-abd1f4f870925d6776dbe4b930b759a1ab6595ca.tar.gz
frameworks_av-abd1f4f870925d6776dbe4b930b759a1ab6595ca.tar.bz2
Support finer seek control on MediaSources.
related-to-bug: 2858448 Change-Id: Ifb4b13b990fd5889113e47e2c62249ac43391fa1
Diffstat (limited to 'media/libstagefright/MPEG4Extractor.cpp')
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp73
1 files changed, 69 insertions, 4 deletions
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 0c2f1e6..7cea629 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -1468,12 +1468,45 @@ status_t MPEG4Source::read(
*out = NULL;
+ int64_t targetSampleTimeUs = -1;
+
int64_t seekTimeUs;
- if (options && options->getSeekTo(&seekTimeUs)) {
+ ReadOptions::SeekMode mode;
+ if (options && options->getSeekTo(&seekTimeUs, &mode)) {
+ uint32_t findFlags = 0;
+ switch (mode) {
+ case ReadOptions::SEEK_PREVIOUS_SYNC:
+ findFlags = SampleTable::kFlagBefore;
+ break;
+ case ReadOptions::SEEK_NEXT_SYNC:
+ findFlags = SampleTable::kFlagAfter;
+ break;
+ case ReadOptions::SEEK_CLOSEST_SYNC:
+ case ReadOptions::SEEK_CLOSEST:
+ findFlags = SampleTable::kFlagClosest;
+ break;
+ default:
+ CHECK(!"Should not be here.");
+ break;
+ }
+
uint32_t sampleIndex;
- status_t err = mSampleTable->findClosestSample(
+ status_t err = mSampleTable->findSampleAtTime(
seekTimeUs * mTimescale / 1000000,
- &sampleIndex, SampleTable::kSyncSample_Flag);
+ &sampleIndex, findFlags);
+
+ if (mode == ReadOptions::SEEK_CLOSEST) {
+ // We found the closest sample already, now we want the sync
+ // sample preceding it (or the sample itself of course), even
+ // if the subsequent sync sample is closer.
+ findFlags = SampleTable::kFlagBefore;
+ }
+
+ uint32_t syncSampleIndex;
+ if (err == OK) {
+ err = mSampleTable->findSyncSampleNear(
+ sampleIndex, &syncSampleIndex, findFlags);
+ }
if (err != OK) {
if (err == ERROR_OUT_OF_RANGE) {
@@ -1487,7 +1520,27 @@ status_t MPEG4Source::read(
return err;
}
- mCurrentSampleIndex = sampleIndex;
+ uint32_t sampleTime;
+ CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
+ sampleIndex, NULL, NULL, &sampleTime));
+
+ if (mode == ReadOptions::SEEK_CLOSEST) {
+ targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
+ }
+
+#if 0
+ uint32_t syncSampleTime;
+ CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
+ syncSampleIndex, NULL, NULL, &syncSampleTime));
+
+ LOGI("seek to time %lld us => sample at time %lld us, "
+ "sync sample at time %lld us",
+ seekTimeUs,
+ sampleTime * 1000000ll / mTimescale,
+ syncSampleTime * 1000000ll / mTimescale);
+#endif
+
+ mCurrentSampleIndex = syncSampleIndex;
if (mBuffer != NULL) {
mBuffer->release();
mBuffer = NULL;
@@ -1536,6 +1589,12 @@ status_t MPEG4Source::read(
mBuffer->meta_data()->clear();
mBuffer->meta_data()->setInt64(
kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
+
+ if (targetSampleTimeUs >= 0) {
+ mBuffer->meta_data()->setInt64(
+ kKeyTargetTime, targetSampleTimeUs);
+ }
+
++mCurrentSampleIndex;
}
@@ -1632,6 +1691,12 @@ status_t MPEG4Source::read(
mBuffer->meta_data()->clear();
mBuffer->meta_data()->setInt64(
kKeyTime, ((int64_t)dts * 1000000) / mTimescale);
+
+ if (targetSampleTimeUs >= 0) {
+ mBuffer->meta_data()->setInt64(
+ kKeyTargetTime, targetSampleTimeUs);
+ }
+
++mCurrentSampleIndex;
*out = mBuffer;