diff options
-rw-r--r-- | include/media/stagefright/OMXCodec.h | 2 | ||||
-rwxr-xr-x | media/libstagefright/OMXCodec.cpp | 34 | ||||
-rw-r--r-- | media/libstagefright/StagefrightMetadataRetriever.cpp | 37 |
3 files changed, 65 insertions, 8 deletions
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index e6739ae..583c3b3 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -276,7 +276,7 @@ private: CodecProfileLevel& profileLevel); status_t setVideoOutputFormat( - const char *mime, OMX_U32 width, OMX_U32 height); + const char *mime, const sp<MetaData>& meta); void setImageOutputFormat( OMX_COLOR_FORMATTYPE format, OMX_U32 width, OMX_U32 height); 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<MetaData> &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<MetaData>& meta) { } status_t OMXCodec::setVideoOutputFormat( - const char *mime, OMX_U32 width, OMX_U32 height) { + const char *mime, const sp<MetaData>& 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<MetaData> &trackMeta) { + + const char *mime; + CHECK(trackMeta->findCString(kKeyMIMEType, &mime)); + + Vector<CodecCapabilities> 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<MetaData> &trackMeta, @@ -117,9 +142,19 @@ static VideoFrame *extractVideoFrameWithCodecFlags( uint32_t flags, int64_t frameTimeUs, int seekMode) { + + sp<MetaData> 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<MediaSource> decoder = OMXCodec::Create( - client->interface(), source->getFormat(), false, source, + client->interface(), format, false, source, NULL, flags | OMXCodec::kClientNeedsFramebuffer); if (decoder.get() == NULL) { |