summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/m4v_h263
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2010-01-04 14:49:56 -0800
committerAndreas Huber <andih@google.com>2010-01-04 14:51:49 -0800
commitcb110ccbe4c275eba0857d9af341a75113243fa0 (patch)
tree4f540f015b08a3f6c81da6bab40c0f9719cb08bb /media/libstagefright/codecs/m4v_h263
parent3e9549e47e2ccc0e37637854f673654750db289f (diff)
downloadframeworks_av-cb110ccbe4c275eba0857d9af341a75113243fa0.zip
frameworks_av-cb110ccbe4c275eba0857d9af341a75113243fa0.tar.gz
frameworks_av-cb110ccbe4c275eba0857d9af341a75113243fa0.tar.bz2
Fix mpeg4/h.263 software decoder.
Diffstat (limited to 'media/libstagefright/codecs/m4v_h263')
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp78
1 files changed, 61 insertions, 17 deletions
diff --git a/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp b/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
index c3ef0d2..ec3ad47 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/M4vH263Decoder.cpp
@@ -43,8 +43,17 @@ M4vH263Decoder::M4vH263Decoder(const sp<MediaSource> &source)
memset(mHandle, 0, sizeof(tagvideoDecControls));
mFormat = new MetaData;
mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_RAW);
- CHECK(mSource->getFormat()->findInt32(kKeyWidth, &mWidth));
- CHECK(mSource->getFormat()->findInt32(kKeyHeight, &mHeight));
+
+ // CHECK(mSource->getFormat()->findInt32(kKeyWidth, &mWidth));
+ // CHECK(mSource->getFormat()->findInt32(kKeyHeight, &mHeight));
+
+ // We'll ignore the dimension advertised by the source, the decoder
+ // appears to require us to always start with the default dimensions
+ // of 352 x 288 to operate correctly and later react to changes in
+ // the dimensions as needed.
+ mWidth = 352;
+ mHeight = 288;
+
mFormat->setInt32(kKeyWidth, mWidth);
mFormat->setInt32(kKeyHeight, mHeight);
mFormat->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
@@ -60,6 +69,20 @@ M4vH263Decoder::~M4vH263Decoder() {
mHandle = NULL;
}
+void M4vH263Decoder::allocateFrames(int32_t width, int32_t height) {
+ size_t frameSize =
+ (((width + 15) & - 16) * ((height + 15) & - 16) * 3) / 2;
+
+ for (uint32_t i = 0; i < 2; ++i) {
+ mFrames[i] = new MediaBuffer(frameSize);
+ mFrames[i]->setObserver(this);
+ }
+
+ PVSetReferenceYUV(
+ mHandle,
+ (uint8_t *)mFrames[1]->data());
+}
+
status_t M4vH263Decoder::start(MetaData *) {
CHECK(!mStarted);
@@ -85,7 +108,8 @@ status_t M4vH263Decoder::start(MetaData *) {
const void *codec_specific_data;
size_t codec_specific_data_size;
- esds.getCodecSpecificInfo(&codec_specific_data, &codec_specific_data_size);
+ esds.getCodecSpecificInfo(
+ &codec_specific_data, &codec_specific_data_size);
vol_data[0] = (uint8_t *) malloc(codec_specific_data_size);
memcpy(vol_data[0], codec_specific_data, codec_specific_data_size);
@@ -102,12 +126,14 @@ status_t M4vH263Decoder::start(MetaData *) {
CHECK_EQ(mode, actualMode);
PVSetPostProcType((VideoDecControls *) mHandle, 0);
- size_t frameSize = (((mWidth + 15) & - 16) * ((mHeight + 15) & - 16) * 3) / 2;
- for (uint32_t i = 0; i < 2; ++i) {
- mFrames[i] = new MediaBuffer(frameSize);
- mFrames[i]->setObserver(this);
+
+ int32_t width, height;
+ PVGetVideoDimensions(mHandle, &width, &height);
+ if (mode == H263_MODE && (width == 0 || height == 0)) {
+ width = 352;
+ height = 288;
}
- PVSetReferenceYUV(mHandle, (uint8_t *)mFrames[1]->data());
+ allocateFrames(width, height);
mSource->start();
@@ -152,24 +178,41 @@ status_t M4vH263Decoder::read(
return err;
}
- uint8_t *bitstream = (uint8_t *) inputBuffer->data() + inputBuffer->range_offset();
+ uint8_t *bitstream =
+ (uint8_t *) inputBuffer->data() + inputBuffer->range_offset();
+
uint32_t timestamp = 0xFFFFFFFF;
int32_t bufferSize = inputBuffer->range_length();
uint32_t useExtTimestamp = 0;
- CHECK_EQ(PV_TRUE, PVDecodeVideoFrame(mHandle, &bitstream, &timestamp, &bufferSize,
- &useExtTimestamp, (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data()));
+ if (PVDecodeVideoFrame(
+ mHandle, &bitstream, &timestamp, &bufferSize,
+ &useExtTimestamp,
+ (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data())
+ != PV_TRUE) {
+ LOGE("failed to decode video frame.");
+
+ inputBuffer->release();
+ inputBuffer = NULL;
+
+ return UNKNOWN_ERROR;
+ }
- // Check whether video dimension is changed.
- // If so, notify the client about the change.
int32_t width, height;
PVGetVideoDimensions(mHandle, &width, &height);
- if (mWidth != width || mHeight != height) {
- mFormat->setInt32(kKeyWidth, width);
- mFormat->setInt32(kKeyHeight, height);
+ if (width != mWidth || height != mHeight) {
+ ++mNumSamplesOutput; // The client will never get to see this frame.
+
+ inputBuffer->release();
+ inputBuffer = NULL;
+
+ mWidth = width;
+ mHeight = height;
+ mFormat->setInt32(kKeyWidth, mWidth);
+ mFormat->setInt32(kKeyHeight, mHeight);
+
return INFO_FORMAT_CHANGED;
}
- PVSetReferenceYUV(mHandle, (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data());
*out = mFrames[mNumSamplesOutput & 0x01];
(*out)->add_ref();
@@ -179,6 +222,7 @@ status_t M4vH263Decoder::read(
++mNumSamplesOutput;
inputBuffer->release();
+ inputBuffer = NULL;
return OK;
}