summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/avc
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
commit6624c9fd0bc5e3858a22a04c05b5059445c1c367 (patch)
tree009c6806cadd4a6da28f3d497043b9665a16f134 /media/libstagefright/codecs/avc
parentd7514ec6eb17d262d6f9605a2c2f245b7ad7c0b9 (diff)
downloadframeworks_base-6624c9fd0bc5e3858a22a04c05b5059445c1c367.zip
frameworks_base-6624c9fd0bc5e3858a22a04c05b5059445c1c367.tar.gz
frameworks_base-6624c9fd0bc5e3858a22a04c05b5059445c1c367.tar.bz2
Support finer seek control on MediaSources.
related-to-bug: 2858448 Change-Id: Ifb4b13b990fd5889113e47e2c62249ac43391fa1
Diffstat (limited to 'media/libstagefright/codecs/avc')
-rw-r--r--media/libstagefright/codecs/avc/dec/AVCDecoder.cpp58
1 files changed, 52 insertions, 6 deletions
diff --git a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp b/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
index 24c361e..050e3da 100644
--- a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
+++ b/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
@@ -51,7 +51,9 @@ AVCDecoder::AVCDecoder(const sp<MediaSource> &source)
mInputBuffer(NULL),
mAnchorTimeUs(0),
mNumSamplesOutput(0),
- mPendingSeekTimeUs(-1) {
+ mPendingSeekTimeUs(-1),
+ mPendingSeekMode(MediaSource::ReadOptions::SEEK_CLOSEST_SYNC),
+ mTargetTimeUs(-1) {
memset(mHandle, 0, sizeof(tagAVCHandle));
mHandle->AVCObject = NULL;
mHandle->userData = this;
@@ -161,6 +163,8 @@ status_t AVCDecoder::start(MetaData *) {
mAnchorTimeUs = 0;
mNumSamplesOutput = 0;
mPendingSeekTimeUs = -1;
+ mPendingSeekMode = ReadOptions::SEEK_CLOSEST_SYNC;
+ mTargetTimeUs = -1;
mStarted = true;
return OK;
@@ -229,11 +233,13 @@ status_t AVCDecoder::read(
*out = NULL;
int64_t seekTimeUs;
- if (options && options->getSeekTo(&seekTimeUs)) {
+ ReadOptions::SeekMode mode;
+ if (options && options->getSeekTo(&seekTimeUs, &mode)) {
LOGV("seek requested to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
CHECK(seekTimeUs >= 0);
mPendingSeekTimeUs = seekTimeUs;
+ mPendingSeekMode = mode;
if (mInputBuffer) {
mInputBuffer->release();
@@ -246,6 +252,8 @@ status_t AVCDecoder::read(
if (mInputBuffer == NULL) {
LOGV("fetching new input buffer.");
+ bool seeking = false;
+
if (!mCodecSpecificData.isEmpty()) {
mInputBuffer = mCodecSpecificData.editItemAt(0);
mCodecSpecificData.removeAt(0);
@@ -258,7 +266,9 @@ status_t AVCDecoder::read(
ReadOptions seekOptions;
if (mPendingSeekTimeUs >= 0) {
- seekOptions.setSeekTo(mPendingSeekTimeUs);
+ seeking = true;
+
+ seekOptions.setSeekTo(mPendingSeekTimeUs, mPendingSeekMode);
mPendingSeekTimeUs = -1;
}
status_t err = mSource->read(&mInputBuffer, &seekOptions);
@@ -276,6 +286,16 @@ status_t AVCDecoder::read(
mInputBuffer = NULL;
}
}
+
+ if (seeking) {
+ int64_t targetTimeUs;
+ if (mInputBuffer->meta_data()->findInt64(kKeyTargetTime, &targetTimeUs)
+ && targetTimeUs >= 0) {
+ mTargetTimeUs = targetTimeUs;
+ } else {
+ mTargetTimeUs = -1;
+ }
+ }
}
const uint8_t *fragPtr;
@@ -394,9 +414,35 @@ status_t AVCDecoder::read(
CHECK(index >= 0);
CHECK(index < (int32_t)mFrames.size());
- *out = mFrames.editItemAt(index);
- (*out)->set_range(0, (*out)->size());
- (*out)->add_ref();
+ MediaBuffer *mbuf = mFrames.editItemAt(index);
+
+ bool skipFrame = false;
+
+ if (mTargetTimeUs >= 0) {
+ int64_t timeUs;
+ CHECK(mbuf->meta_data()->findInt64(kKeyTime, &timeUs));
+ CHECK(timeUs <= mTargetTimeUs);
+
+ if (timeUs < mTargetTimeUs) {
+ // We're still waiting for the frame with the matching
+ // timestamp and we won't return the current one.
+ skipFrame = true;
+
+ LOGV("skipping frame at %lld us", timeUs);
+ } else {
+ LOGV("found target frame at %lld us", timeUs);
+
+ mTargetTimeUs = -1;
+ }
+ }
+
+ if (!skipFrame) {
+ *out = mbuf;
+ (*out)->set_range(0, (*out)->size());
+ (*out)->add_ref();
+ } else {
+ *out = new MediaBuffer(0);
+ }
// Do _not_ release input buffer yet.