From 8fa80e3be63ffde5ef029afa713877440856b663 Mon Sep 17 00:00:00 2001 From: James Dong Date: Fri, 7 Sep 2012 17:27:50 -0700 Subject: Allow OMXCodec to specify an output color format for OMX decoder component The output color format is specified via the meta argument in OMXCodec::Create() o related-to-bug: 7122195 Change-Id: Id3247686b893af25cc190685201e53ad34b0399c --- media/libstagefright/OMXCodec.cpp | 34 ++++++++++++++++---- .../StagefrightMetadataRetriever.cpp | 37 +++++++++++++++++++++- 2 files changed, 64 insertions(+), 7 deletions(-) (limited to 'media/libstagefright') diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index d0e306c..233a733 100755 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -546,12 +546,8 @@ status_t OMXCodec::configureCodec(const sp &meta) { if (mIsEncoder) { setVideoInputFormat(mMIME, meta); } else { - int32_t width, height; - bool success = meta->findInt32(kKeyWidth, &width); - success = success && meta->findInt32(kKeyHeight, &height); - CHECK(success); status_t err = setVideoOutputFormat( - mMIME, width, height); + mMIME, meta); if (err != OK) { return err; @@ -1172,7 +1168,13 @@ status_t OMXCodec::setupAVCEncoderParameters(const sp& meta) { } status_t OMXCodec::setVideoOutputFormat( - const char *mime, OMX_U32 width, OMX_U32 height) { + const char *mime, const sp& meta) { + + int32_t width, height; + bool success = meta->findInt32(kKeyWidth, &width); + success = success && meta->findInt32(kKeyHeight, &height); + CHECK(success); + CODEC_LOGV("setVideoOutputFormat width=%ld, height=%ld", width, height); OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; @@ -1218,6 +1220,26 @@ status_t OMXCodec::setVideoOutputFormat( || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar || format.eColorFormat == OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka); + int32_t colorFormat; + if (meta->findInt32(kKeyColorFormat, &colorFormat) + && colorFormat != OMX_COLOR_FormatUnused + && colorFormat != format.eColorFormat) { + + while (OMX_ErrorNoMore != err) { + format.nIndex++; + err = mOMX->getParameter( + mNode, OMX_IndexParamVideoPortFormat, + &format, sizeof(format)); + if (format.eColorFormat == colorFormat) { + break; + } + } + if (format.eColorFormat != colorFormat) { + CODEC_LOGE("Color format %d is not supported", colorFormat); + return ERROR_UNSUPPORTED; + } + } + err = mOMX->setParameter( mNode, OMX_IndexParamVideoPortFormat, &format, sizeof(format)); diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp index c9ef4d9..a2f3f13 100644 --- a/media/libstagefright/StagefrightMetadataRetriever.cpp +++ b/media/libstagefright/StagefrightMetadataRetriever.cpp @@ -110,6 +110,31 @@ status_t StagefrightMetadataRetriever::setDataSource( return OK; } +static bool isYUV420PlanarSupported( + OMXClient *client, + const sp &trackMeta) { + + const char *mime; + CHECK(trackMeta->findCString(kKeyMIMEType, &mime)); + + Vector caps; + if (QueryCodecs(client->interface(), mime, + true, /* queryDecoders */ + true, /* hwCodecOnly */ + &caps) == OK) { + + for (size_t j = 0; j < caps.size(); ++j) { + CodecCapabilities cap = caps[j]; + for (size_t i = 0; i < cap.mColorFormats.size(); ++i) { + if (cap.mColorFormats[i] == OMX_COLOR_FormatYUV420Planar) { + return true; + } + } + } + } + return false; +} + static VideoFrame *extractVideoFrameWithCodecFlags( OMXClient *client, const sp &trackMeta, @@ -117,9 +142,19 @@ static VideoFrame *extractVideoFrameWithCodecFlags( uint32_t flags, int64_t frameTimeUs, int seekMode) { + + sp format = source->getFormat(); + + // XXX: + // Once all vendors support OMX_COLOR_FormatYUV420Planar, we can + // remove this check and always set the decoder output color format + if (isYUV420PlanarSupported(client, trackMeta)) { + format->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar); + } + sp decoder = OMXCodec::Create( - client->interface(), source->getFormat(), false, source, + client->interface(), format, false, source, NULL, flags | OMXCodec::kClientNeedsFramebuffer); if (decoder.get() == NULL) { -- cgit v1.1