summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs
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
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')
-rw-r--r--media/libstagefright/codecs/aacdec/AACDecoder.cpp3
-rw-r--r--media/libstagefright/codecs/aacenc/AACEncoder.cpp3
-rw-r--r--media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp3
-rw-r--r--media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp3
-rw-r--r--media/libstagefright/codecs/amrwb/AMRWBDecoder.cpp3
-rw-r--r--media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp3
-rw-r--r--media/libstagefright/codecs/avc/dec/AVCDecoder.cpp58
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp52
-rw-r--r--media/libstagefright/codecs/mp3dec/MP3Decoder.cpp3
-rw-r--r--media/libstagefright/codecs/on2/dec/VPXDecoder.cpp45
-rw-r--r--media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp3
11 files changed, 157 insertions, 22 deletions
diff --git a/media/libstagefright/codecs/aacdec/AACDecoder.cpp b/media/libstagefright/codecs/aacdec/AACDecoder.cpp
index 8ae1135..c5b51c0 100644
--- a/media/libstagefright/codecs/aacdec/AACDecoder.cpp
+++ b/media/libstagefright/codecs/aacdec/AACDecoder.cpp
@@ -159,7 +159,8 @@ status_t AACDecoder::read(
*out = NULL;
int64_t seekTimeUs;
- if (options && options->getSeekTo(&seekTimeUs)) {
+ ReadOptions::SeekMode mode;
+ if (options && options->getSeekTo(&seekTimeUs, &mode)) {
CHECK(seekTimeUs >= 0);
mNumSamplesOutput = 0;
diff --git a/media/libstagefright/codecs/aacenc/AACEncoder.cpp b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
index 2317de6..e8235c2 100644
--- a/media/libstagefright/codecs/aacenc/AACEncoder.cpp
+++ b/media/libstagefright/codecs/aacenc/AACEncoder.cpp
@@ -202,7 +202,8 @@ status_t AACEncoder::read(
*out = NULL;
int64_t seekTimeUs;
- CHECK(options == NULL || !options->getSeekTo(&seekTimeUs));
+ ReadOptions::SeekMode mode;
+ CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode));
MediaBuffer *buffer;
CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), OK);
diff --git a/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp b/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp
index 7728597..fb300da 100644
--- a/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp
@@ -117,7 +117,8 @@ status_t AMRNBDecoder::read(
*out = NULL;
int64_t seekTimeUs;
- if (options && options->getSeekTo(&seekTimeUs)) {
+ ReadOptions::SeekMode mode;
+ if (options && options->getSeekTo(&seekTimeUs, &mode)) {
CHECK(seekTimeUs >= 0);
mNumSamplesOutput = 0;
diff --git a/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp
index 4c02fe9..c875426 100644
--- a/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/AMRNBEncoder.cpp
@@ -145,7 +145,8 @@ status_t AMRNBEncoder::read(
*out = NULL;
int64_t seekTimeUs;
- CHECK(options == NULL || !options->getSeekTo(&seekTimeUs));
+ ReadOptions::SeekMode mode;
+ CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode));
while (mNumInputSamples < kNumSamplesPerFrame) {
if (mInputBuffer == NULL) {
diff --git a/media/libstagefright/codecs/amrwb/AMRWBDecoder.cpp b/media/libstagefright/codecs/amrwb/AMRWBDecoder.cpp
index c17c100..2a21472 100644
--- a/media/libstagefright/codecs/amrwb/AMRWBDecoder.cpp
+++ b/media/libstagefright/codecs/amrwb/AMRWBDecoder.cpp
@@ -135,7 +135,8 @@ status_t AMRWBDecoder::read(
*out = NULL;
int64_t seekTimeUs;
- if (options && options->getSeekTo(&seekTimeUs)) {
+ ReadOptions::SeekMode seekMode;
+ if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
CHECK(seekTimeUs >= 0);
mNumSamplesOutput = 0;
diff --git a/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp
index 4257c6a..93304d0 100644
--- a/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp
+++ b/media/libstagefright/codecs/amrwbenc/AMRWBEncoder.cpp
@@ -196,7 +196,8 @@ status_t AMRWBEncoder::read(
*out = NULL;
int64_t seekTimeUs;
- CHECK(options == NULL || !options->getSeekTo(&seekTimeUs));
+ ReadOptions::SeekMode mode;
+ CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &mode));
while (mNumInputSamples < kNumSamplesPerFrame) {
if (mInputBuffer == NULL) {
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.
diff --git a/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp b/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
index 8350f7a..0f08f6e 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
@@ -37,7 +37,8 @@ M4vH263Decoder::M4vH263Decoder(const sp<MediaSource> &source)
mStarted(false),
mHandle(new tagvideoDecControls),
mInputBuffer(NULL),
- mNumSamplesOutput(0) {
+ mNumSamplesOutput(0),
+ mTargetTimeUs(-1) {
LOGV("M4vH263Decoder");
memset(mHandle, 0, sizeof(tagvideoDecControls));
@@ -146,6 +147,7 @@ status_t M4vH263Decoder::start(MetaData *) {
mSource->start();
mNumSamplesOutput = 0;
+ mTargetTimeUs = -1;
mStarted = true;
return OK;
@@ -175,8 +177,11 @@ status_t M4vH263Decoder::read(
MediaBuffer **out, const ReadOptions *options) {
*out = NULL;
+ bool seeking = false;
int64_t seekTimeUs;
- if (options && options->getSeekTo(&seekTimeUs)) {
+ ReadOptions::SeekMode mode;
+ if (options && options->getSeekTo(&seekTimeUs, &mode)) {
+ seeking = true;
CHECK_EQ(PVResetVideoDecoder(mHandle), PV_TRUE);
}
@@ -186,6 +191,16 @@ status_t M4vH263Decoder::read(
return err;
}
+ if (seeking) {
+ int64_t targetTimeUs;
+ if (inputBuffer->meta_data()->findInt64(kKeyTargetTime, &targetTimeUs)
+ && targetTimeUs >= 0) {
+ mTargetTimeUs = targetTimeUs;
+ } else {
+ mTargetTimeUs = -1;
+ }
+ }
+
uint8_t *bitstream =
(uint8_t *) inputBuffer->data() + inputBuffer->range_offset();
@@ -221,17 +236,40 @@ status_t M4vH263Decoder::read(
return INFO_FORMAT_CHANGED;
}
- *out = mFrames[mNumSamplesOutput & 0x01];
- (*out)->add_ref();
-
int64_t timeUs;
CHECK(inputBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
- (*out)->meta_data()->setInt64(kKeyTime, timeUs);
- ++mNumSamplesOutput;
inputBuffer->release();
inputBuffer = NULL;
+ bool skipFrame = false;
+
+ if (mTargetTimeUs >= 0) {
+ 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 = new MediaBuffer(0);
+ } else {
+ *out = mFrames[mNumSamplesOutput & 0x01];
+ (*out)->add_ref();
+ (*out)->meta_data()->setInt64(kKeyTime, timeUs);
+ }
+
+ ++mNumSamplesOutput;
+
return OK;
}
diff --git a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
index f40bd11..c4a8280 100644
--- a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
+++ b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
@@ -122,7 +122,8 @@ status_t MP3Decoder::read(
*out = NULL;
int64_t seekTimeUs;
- if (options && options->getSeekTo(&seekTimeUs)) {
+ ReadOptions::SeekMode mode;
+ if (options && options->getSeekTo(&seekTimeUs, &mode)) {
CHECK(seekTimeUs >= 0);
mNumFramesOutput = 0;
diff --git a/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp b/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp
index bad8956..fbc97f4 100644
--- a/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp
+++ b/media/libstagefright/codecs/on2/dec/VPXDecoder.cpp
@@ -39,7 +39,8 @@ VPXDecoder::VPXDecoder(const sp<MediaSource> &source)
mStarted(false),
mBufferSize(0),
mCtx(NULL),
- mBufferGroup(NULL) {
+ mBufferGroup(NULL),
+ mTargetTimeUs(-1) {
sp<MetaData> inputFormat = source->getFormat();
const char *mime;
CHECK(inputFormat->findCString(kKeyMIMEType, &mime));
@@ -94,6 +95,8 @@ status_t VPXDecoder::start(MetaData *) {
mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
mBufferGroup->add_buffer(new MediaBuffer(mBufferSize));
+ mTargetTimeUs = -1;
+
mStarted = true;
return OK;
@@ -126,6 +129,13 @@ status_t VPXDecoder::read(
MediaBuffer **out, const ReadOptions *options) {
*out = NULL;
+ bool seeking = false;
+ int64_t seekTimeUs;
+ ReadOptions::SeekMode seekMode;
+ if (options && options->getSeekTo(&seekTimeUs, &seekMode)) {
+ seeking = true;
+ }
+
MediaBuffer *input;
status_t err = mSource->read(&input, options);
@@ -135,6 +145,16 @@ status_t VPXDecoder::read(
LOGV("read %d bytes from source\n", input->range_length());
+ if (seeking) {
+ int64_t targetTimeUs;
+ if (input->meta_data()->findInt64(kKeyTargetTime, &targetTimeUs)
+ && targetTimeUs >= 0) {
+ mTargetTimeUs = targetTimeUs;
+ } else {
+ mTargetTimeUs = -1;
+ }
+ }
+
if (vpx_codec_decode(
(vpx_codec_ctx_t *)mCtx,
(uint8_t *)input->data() + input->range_offset(),
@@ -156,6 +176,29 @@ status_t VPXDecoder::read(
input->release();
input = NULL;
+ bool skipFrame = false;
+
+ if (mTargetTimeUs >= 0) {
+ 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 = new MediaBuffer(0);
+ return OK;
+ }
+
vpx_codec_iter_t iter = NULL;
vpx_image_t *img = vpx_codec_get_frame((vpx_codec_ctx_t *)mCtx, &iter);
diff --git a/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp b/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
index df3f16a..53f0638 100644
--- a/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/VorbisDecoder.cpp
@@ -200,7 +200,8 @@ status_t VorbisDecoder::read(
*out = NULL;
int64_t seekTimeUs;
- if (options && options->getSeekTo(&seekTimeUs)) {
+ ReadOptions::SeekMode mode;
+ if (options && options->getSeekTo(&seekTimeUs, &mode)) {
CHECK(seekTimeUs >= 0);
mNumFramesOutput = 0;