From 03c556ae1eb409ad088c49037e185946c54e1d25 Mon Sep 17 00:00:00 2001 From: Lajos Molnar Date: Fri, 25 Jul 2014 07:53:14 -0700 Subject: stagefright: add flexible YUV support Bug: 10706245 Change-Id: Icd246f22edfc67ed5240d59f5a5bde3e5f749465 --- media/libstagefright/ACodec.cpp | 104 ++++++++++++++++++++++++++++++++++++ media/libstagefright/MediaCodec.cpp | 12 +++++ 2 files changed, 116 insertions(+) (limited to 'media') diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index b6cc742..1b1d7a9 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -2709,6 +2709,83 @@ void ACodec::processDeferredMessages() { } } +// static +void ACodec::describeDefaultColorFormat(DescribeColorFormatParams ¶ms) { + MediaImage &image = params.sMediaImage; + memset(&image, 0, sizeof(image)); + + image.mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN; + image.mNumPlanes = 0; + + const OMX_COLOR_FORMATTYPE fmt = params.eColorFormat; + // we need stride and slice-height to be non-zero + if (params.nStride == 0 || params.nSliceHeight == 0) { + ALOGW("cannot describe color format 0x%x = %d with stride=%u and sliceHeight=%u", + fmt, fmt, params.nStride, params.nSliceHeight); + return; + } + + image.mWidth = params.nFrameWidth; + image.mHeight = params.nFrameHeight; + + // only supporting YUV420 + if (fmt != OMX_COLOR_FormatYUV420Planar && + fmt != OMX_COLOR_FormatYUV420PackedPlanar && + fmt != OMX_COLOR_FormatYUV420SemiPlanar && + fmt != OMX_COLOR_FormatYUV420PackedSemiPlanar) { + ALOGW("do not know color format 0x%x = %d", fmt, fmt); + return; + } + + // set-up YUV format + image.mType = MediaImage::MEDIA_IMAGE_TYPE_YUV; + image.mNumPlanes = 3; + image.mBitDepth = 8; + image.mPlane[image.Y].mOffset = 0; + image.mPlane[image.Y].mColInc = 1; + image.mPlane[image.Y].mRowInc = params.nStride; + image.mPlane[image.Y].mHorizSubsampling = 1; + image.mPlane[image.Y].mVertSubsampling = 1; + + switch (fmt) { + case OMX_COLOR_FormatYUV420Planar: // used for YV12 + case OMX_COLOR_FormatYUV420PackedPlanar: + image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight; + image.mPlane[image.U].mColInc = 1; + image.mPlane[image.U].mRowInc = params.nStride / 2; + image.mPlane[image.U].mHorizSubsampling = 2; + image.mPlane[image.U].mVertSubsampling = 2; + + image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + + (params.nStride * params.nSliceHeight / 4); + image.mPlane[image.V].mColInc = 1; + image.mPlane[image.V].mRowInc = params.nStride / 2; + image.mPlane[image.V].mHorizSubsampling = 2; + image.mPlane[image.V].mVertSubsampling = 2; + break; + + case OMX_COLOR_FormatYUV420SemiPlanar: + // FIXME: NV21 for sw-encoder, NV12 for decoder and hw-encoder + case OMX_COLOR_FormatYUV420PackedSemiPlanar: + // NV12 + image.mPlane[image.U].mOffset = params.nStride * params.nSliceHeight; + image.mPlane[image.U].mColInc = 2; + image.mPlane[image.U].mRowInc = params.nStride; + image.mPlane[image.U].mHorizSubsampling = 2; + image.mPlane[image.U].mVertSubsampling = 2; + + image.mPlane[image.V].mOffset = image.mPlane[image.U].mOffset + 1; + image.mPlane[image.V].mColInc = 2; + image.mPlane[image.V].mRowInc = params.nStride; + image.mPlane[image.V].mHorizSubsampling = 2; + image.mPlane[image.V].mVertSubsampling = 2; + break; + + default: + TRESPASS(); + } +} + status_t ACodec::getPortFormat(OMX_U32 portIndex, sp ¬ify) { // TODO: catch errors an return them instead of using CHECK OMX_PARAM_PORTDEFINITIONTYPE def; @@ -2736,6 +2813,33 @@ status_t ACodec::getPortFormat(OMX_U32 portIndex, sp ¬ify) { notify->setInt32("slice-height", videoDef->nSliceHeight); notify->setInt32("color-format", videoDef->eColorFormat); + + DescribeColorFormatParams describeParams; + InitOMXParams(&describeParams); + describeParams.eColorFormat = videoDef->eColorFormat; + describeParams.nFrameWidth = videoDef->nFrameWidth; + describeParams.nFrameHeight = videoDef->nFrameHeight; + describeParams.nStride = videoDef->nStride; + describeParams.nSliceHeight = videoDef->nSliceHeight; + + OMX_INDEXTYPE describeColorFormatIndex; + if (mOMX->getExtensionIndex( + mNode, "OMX.google.android.index.describeColorFormat", + &describeColorFormatIndex) || + mOMX->getParameter( + mNode, describeColorFormatIndex, + &describeParams, sizeof(describeParams))) { + describeDefaultColorFormat(describeParams); + } + + if (describeParams.sMediaImage.mType != MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN) { + notify->setBuffer( + "image-data", + ABuffer::CreateAsCopy( + &describeParams.sMediaImage, + sizeof(describeParams.sMediaImage))); + } + OMX_CONFIG_RECTTYPE rect; InitOMXParams(&rect); rect.nPortIndex = kPortIndexOutput; diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 15e062e..e944766 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -1948,6 +1948,18 @@ ssize_t MediaCodec::dequeuePortBuffer(int32_t portIndex) { Mutex::Autolock al(mBufferLock); info->mFormat = portIndex == kPortIndexInput ? mInputFormat : mOutputFormat; info->mOwnedByClient = true; + + // set image-data + if (info->mFormat != NULL) { + sp imageData; + if (info->mFormat->findBuffer("image-data", &imageData)) { + info->mData->meta()->setBuffer("image-data", imageData); + } + int32_t left, top, right, bottom; + if (info->mFormat->findRect("crop", &left, &top, &right, &bottom)) { + info->mData->meta()->setRect("crop-rect", left, top, right, bottom); + } + } } return index; -- cgit v1.1