summaryrefslogtreecommitdiffstats
path: root/media/libstagefright
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2009-10-07 13:36:52 -0700
committerAndreas Huber <andih@google.com>2009-10-07 13:53:24 -0700
commit8b432b1d85259a463198db3efa5c50e59c254686 (patch)
treec2fd1d75776013f29fcbc2b99c6e6dbb3585a0c7 /media/libstagefright
parent5da9aeb4351ed02b05f15c11e34673ab38103dd8 (diff)
downloadframeworks_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.cpp32
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) {