diff options
| author | Andreas Huber <andih@google.com> | 2009-10-07 13:36:52 -0700 |
|---|---|---|
| committer | Andreas Huber <andih@google.com> | 2009-10-07 13:53:24 -0700 |
| commit | 8b432b1d85259a463198db3efa5c50e59c254686 (patch) | |
| tree | c2fd1d75776013f29fcbc2b99c6e6dbb3585a0c7 /media/libstagefright | |
| parent | 5da9aeb4351ed02b05f15c11e34673ab38103dd8 (diff) | |
| download | frameworks_base-8b432b1d85259a463198db3efa5c50e59c254686.zip frameworks_base-8b432b1d85259a463198db3efa5c50e59c254686.tar.gz frameworks_base-8b432b1d85259a463198db3efa5c50e59c254686.tar.bz2 | |
Workaround for avc decoder misreporting output buffer size requirements if the content is not a multiple-16 width/height.
Diffstat (limited to 'media/libstagefright')
| -rw-r--r-- | media/libstagefright/OMXCodec.cpp | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index c4c6149..26c6a9e 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -39,6 +39,8 @@ namespace android { +static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; + struct CodecInfo { const char *mime; const char *codec; @@ -243,6 +245,15 @@ sp<OMXCodec> OMXCodec::Create( quirks |= kRequiresAllocateBufferOnOutputPorts; } + if (!strcmp(componentName, "OMX.qcom.video.decoder.avc")) { + // This decoder misreports the required output buffer size if + // the content in question is not a multiple-16 width/height. + + // XXX Not enabled by default to make the bug reproducible by + // the vendor. + // quirks |= kAlwaysAllocateOutputWithPadding; + } + sp<OMXCodec> codec = new OMXCodec( omx, node, quirks, createEncoder, mime, componentName, source); @@ -837,6 +848,25 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { return err; } + if ((portIndex == kPortIndexOutput) + && (mQuirks & kAlwaysAllocateOutputWithPadding)) { + CHECK_EQ(def.eDomain, OMX_PortDomainVideo); + const OMX_VIDEO_PORTDEFINITIONTYPE *videoDef = &def.format.video; + CHECK_EQ(videoDef->eColorFormat, OMX_QCOM_COLOR_FormatYVU420SemiPlanar); + + OMX_U32 width = (videoDef->nFrameWidth + 15) & ~0x0f; + OMX_U32 height = (videoDef->nFrameHeight + 15) & ~0x0f; + + size_t newBufferSize = (width * height * 3) / 2; + CHECK(newBufferSize >= def.nBufferSize); + if (newBufferSize > def.nBufferSize) { + CODEC_LOGV("Rounding up output buffersize from %ld to %ld " + "to accomodate multiple-of-16 alignment.", + def.nBufferSize, newBufferSize); + } + def.nBufferSize = newBufferSize; + } + size_t totalSize = def.nBufferCountActual * def.nBufferSize; mDealer[portIndex] = new MemoryDealer(totalSize); @@ -2017,8 +2047,6 @@ static const char *colorFormatString(OMX_COLOR_FORMATTYPE type) { size_t numNames = sizeof(kNames) / sizeof(kNames[0]); - static const int OMX_QCOM_COLOR_FormatYVU420SemiPlanar = 0x7FA30C00; - if (type == OMX_QCOM_COLOR_FormatYVU420SemiPlanar) { return "OMX_QCOM_COLOR_FormatYVU420SemiPlanar"; } else if (type < 0 || (size_t)type >= numNames) { |
