diff options
author | Andreas Huber <andih@google.com> | 2010-01-04 14:49:56 -0800 |
---|---|---|
committer | Andreas Huber <andih@google.com> | 2010-01-04 14:51:49 -0800 |
commit | cb110ccbe4c275eba0857d9af341a75113243fa0 (patch) | |
tree | 4f540f015b08a3f6c81da6bab40c0f9719cb08bb /media/libstagefright/codecs/m4v_h263 | |
parent | 3e9549e47e2ccc0e37637854f673654750db289f (diff) | |
download | frameworks_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.cpp | 78 |
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, ×tamp, &bufferSize, - &useExtTimestamp, (uint8_t *)mFrames[mNumSamplesOutput & 0x01]->data())); + if (PVDecodeVideoFrame( + mHandle, &bitstream, ×tamp, &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; } |