summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/media/stagefright/OMXCodec.h2
-rwxr-xr-xmedia/libstagefright/OMXCodec.cpp34
-rw-r--r--media/libstagefright/StagefrightMetadataRetriever.cpp37
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) {