diff options
author | Lajos Molnar <lajos@google.com> | 2014-12-11 11:17:51 -0800 |
---|---|---|
committer | Lajos Molnar <lajos@google.com> | 2014-12-11 11:17:51 -0800 |
commit | 3e08ca6709b5a75dc3b779cf3eba8196b08a0245 (patch) | |
tree | 0d91cba9d1c188d1898289f6b21826c6f6d316d3 /media/libstagefright/omx | |
parent | 2592184c976ef83aa9fdad7d63bfdb408c95aa7d (diff) | |
parent | 6571ed31d9c967faacd552be238b41088ae11e25 (diff) | |
download | frameworks_av-3e08ca6709b5a75dc3b779cf3eba8196b08a0245.zip frameworks_av-3e08ca6709b5a75dc3b779cf3eba8196b08a0245.tar.gz frameworks_av-3e08ca6709b5a75dc3b779cf3eba8196b08a0245.tar.bz2 |
resolved conflicts for merge of 6571ed31 to lmp-mr1-dev-plus-aosp
Change-Id: Ibaea3a0766f75a61964615482a9ef28651a42b37
Diffstat (limited to 'media/libstagefright/omx')
-rw-r--r-- | media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp | 86 | ||||
-rw-r--r-- | media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp | 307 |
2 files changed, 364 insertions, 29 deletions
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp index 2f83610..532cf2f 100644 --- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp +++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp @@ -26,6 +26,7 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> #include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/MediaDefs.h> namespace android { @@ -61,6 +62,8 @@ SoftVideoDecoderOMXComponent::SoftVideoDecoderOMXComponent( mCropWidth(width), mCropHeight(height), mOutputPortSettingsChange(NONE), + mMinInputBufferSize(384), // arbitrary, using one uncompressed macroblock + mMinCompressionRatio(1), // max input size is normally the output size mComponentRole(componentRole), mCodingType(codingType), mProfileLevels(profileLevels), @@ -71,7 +74,11 @@ void SoftVideoDecoderOMXComponent::initPorts( OMX_U32 numInputBuffers, OMX_U32 inputBufferSize, OMX_U32 numOutputBuffers, - const char *mimeType) { + const char *mimeType, + OMX_U32 minCompressionRatio) { + mMinInputBufferSize = inputBufferSize; + mMinCompressionRatio = minCompressionRatio; + OMX_PARAM_PORTDEFINITIONTYPE def; InitOMXParams(&def); @@ -120,27 +127,30 @@ void SoftVideoDecoderOMXComponent::initPorts( addPort(def); - updatePortDefinitions(); + updatePortDefinitions(true /* updateCrop */, true /* updateInputSize */); } -void SoftVideoDecoderOMXComponent::updatePortDefinitions(bool updateCrop) { - OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kInputPortIndex)->mDef; - def->format.video.nFrameWidth = mWidth; - def->format.video.nFrameHeight = mHeight; - def->format.video.nStride = def->format.video.nFrameWidth; - def->format.video.nSliceHeight = def->format.video.nFrameHeight; - - def->nBufferSize = def->format.video.nFrameWidth * def->format.video.nFrameHeight * 3 / 2; - - def = &editPortInfo(kOutputPortIndex)->mDef; - def->format.video.nFrameWidth = outputBufferWidth(); - def->format.video.nFrameHeight = outputBufferHeight(); - def->format.video.nStride = def->format.video.nFrameWidth; - def->format.video.nSliceHeight = def->format.video.nFrameHeight; - - def->nBufferSize = - (def->format.video.nFrameWidth * - def->format.video.nFrameHeight * 3) / 2; +void SoftVideoDecoderOMXComponent::updatePortDefinitions(bool updateCrop, bool updateInputSize) { + OMX_PARAM_PORTDEFINITIONTYPE *outDef = &editPortInfo(kOutputPortIndex)->mDef; + outDef->format.video.nFrameWidth = outputBufferWidth(); + outDef->format.video.nFrameHeight = outputBufferHeight(); + outDef->format.video.nStride = outDef->format.video.nFrameWidth; + outDef->format.video.nSliceHeight = outDef->format.video.nFrameHeight; + + outDef->nBufferSize = + (outDef->format.video.nStride * outDef->format.video.nSliceHeight * 3) / 2; + + OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef; + inDef->format.video.nFrameWidth = mWidth; + inDef->format.video.nFrameHeight = mHeight; + // input port is compressed, hence it has no stride + inDef->format.video.nStride = 0; + inDef->format.video.nSliceHeight = 0; + + // when output format changes, input buffer size does not actually change + if (updateInputSize) { + inDef->nBufferSize = max(outDef->nBufferSize / mMinCompressionRatio, mMinInputBufferSize); + } if (updateCrop) { mCropLeft = 0; @@ -169,7 +179,8 @@ void SoftVideoDecoderOMXComponent::handlePortSettingsChange( bool strideChanged = false; if (fakeStride) { OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kOutputPortIndex)->mDef; - if (def->format.video.nStride != width || def->format.video.nSliceHeight != height) { + if (def->format.video.nStride != (OMX_S32)width + || def->format.video.nSliceHeight != (OMX_U32)height) { strideChanged = true; } } @@ -252,7 +263,7 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalGetParameter( (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; if (formatParams->nPortIndex > kMaxPortIndex) { - return OMX_ErrorUndefined; + return OMX_ErrorBadPortIndex; } if (formatParams->nIndex != 0) { @@ -324,13 +335,25 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter( (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; if (formatParams->nPortIndex > kMaxPortIndex) { - return OMX_ErrorUndefined; + return OMX_ErrorBadPortIndex; } if (formatParams->nIndex != 0) { return OMX_ErrorNoMore; } + if (formatParams->nPortIndex == kInputPortIndex) { + if (formatParams->eCompressionFormat != mCodingType + || formatParams->eColorFormat != OMX_COLOR_FormatUnused) { + return OMX_ErrorUnsupportedSetting; + } + } else { + if (formatParams->eCompressionFormat != OMX_VIDEO_CodingUnused + || formatParams->eColorFormat != OMX_COLOR_FormatYUV420Planar) { + return OMX_ErrorUnsupportedSetting; + } + } + return OMX_ErrorNone; } @@ -348,7 +371,7 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter( mAdaptiveMaxWidth = 0; mAdaptiveMaxHeight = 0; } - updatePortDefinitions(); + updatePortDefinitions(true /* updateCrop */, true /* updateInputSize */); return OMX_ErrorNone; } @@ -369,11 +392,18 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetParameter( (mIsAdaptive && outputPort) ? mAdaptiveMaxWidth : newWidth; def->format.video.nFrameHeight = (mIsAdaptive && outputPort) ? mAdaptiveMaxHeight : newHeight; - def->format.video.nStride = def->format.video.nFrameWidth; - def->format.video.nSliceHeight = def->format.video.nFrameHeight; - def->nBufferSize = - def->format.video.nFrameWidth * def->format.video.nFrameHeight * 3 / 2; if (outputPort) { + def->format.video.nStride = def->format.video.nFrameWidth; + def->format.video.nSliceHeight = def->format.video.nFrameHeight; + def->nBufferSize = + def->format.video.nStride * def->format.video.nSliceHeight * 3 / 2; + + + OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef; + // increase input buffer size if required + inDef->nBufferSize = + max(def->nBufferSize / mMinCompressionRatio, inDef->nBufferSize); + mWidth = newWidth; mHeight = newHeight; mCropLeft = 0; diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp index 70ec6e4..d4d6217 100644 --- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp +++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp @@ -19,6 +19,7 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "SoftVideoEncoderOMXComponent" #include <utils/Log.h> +#include <utils/misc.h> #include "include/SoftVideoEncoderOMXComponent.h" @@ -27,6 +28,7 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/ALooper.h> #include <media/stagefright/foundation/AMessage.h> +#include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/MediaDefs.h> #include <ui/GraphicBuffer.h> @@ -34,13 +36,316 @@ namespace android { +const static OMX_COLOR_FORMATTYPE kSupportedColorFormats[] = { + OMX_COLOR_FormatYUV420Planar, + OMX_COLOR_FormatYUV420SemiPlanar, + OMX_COLOR_FormatAndroidOpaque +}; + +template<class T> +static void InitOMXParams(T *params) { + params->nSize = sizeof(T); + params->nVersion.s.nVersionMajor = 1; + params->nVersion.s.nVersionMinor = 0; + params->nVersion.s.nRevision = 0; + params->nVersion.s.nStep = 0; +} + SoftVideoEncoderOMXComponent::SoftVideoEncoderOMXComponent( const char *name, + const char *componentRole, + OMX_VIDEO_CODINGTYPE codingType, + const CodecProfileLevel *profileLevels, + size_t numProfileLevels, + int32_t width, + int32_t height, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component) : SimpleSoftOMXComponent(name, callbacks, appData, component), - mGrallocModule(NULL) { + mInputDataIsMeta(false), + mWidth(width), + mHeight(height), + mBitrate(192000), + mFramerate(30 << 16), // Q16 format + mColorFormat(OMX_COLOR_FormatYUV420Planar), + mGrallocModule(NULL), + mMinOutputBufferSize(384), // arbitrary, using one uncompressed macroblock + mMinCompressionRatio(1), // max output size is normally the input size + mComponentRole(componentRole), + mCodingType(codingType), + mProfileLevels(profileLevels), + mNumProfileLevels(numProfileLevels) { +} + +void SoftVideoEncoderOMXComponent::initPorts( + OMX_U32 numInputBuffers, OMX_U32 numOutputBuffers, OMX_U32 outputBufferSize, + const char *mime, OMX_U32 minCompressionRatio) { + OMX_PARAM_PORTDEFINITIONTYPE def; + + mMinOutputBufferSize = outputBufferSize; + mMinCompressionRatio = minCompressionRatio; + + InitOMXParams(&def); + + def.nPortIndex = kInputPortIndex; + def.eDir = OMX_DirInput; + def.nBufferCountMin = numInputBuffers; + def.nBufferCountActual = def.nBufferCountMin; + def.bEnabled = OMX_TRUE; + def.bPopulated = OMX_FALSE; + def.eDomain = OMX_PortDomainVideo; + def.bBuffersContiguous = OMX_FALSE; + def.format.video.pNativeRender = NULL; + def.format.video.nFrameWidth = mWidth; + def.format.video.nFrameHeight = mHeight; + def.format.video.nStride = def.format.video.nFrameWidth; + def.format.video.nSliceHeight = def.format.video.nFrameHeight; + def.format.video.nBitrate = 0; + // frameRate is in Q16 format. + def.format.video.xFramerate = mFramerate; + def.format.video.bFlagErrorConcealment = OMX_FALSE; + def.nBufferAlignment = kInputBufferAlignment; + def.format.video.cMIMEType = const_cast<char *>("video/raw"); + def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; + def.format.video.eColorFormat = mColorFormat; + def.format.video.pNativeWindow = NULL; + // buffersize set in updatePortParams + + addPort(def); + + InitOMXParams(&def); + + def.nPortIndex = kOutputPortIndex; + def.eDir = OMX_DirOutput; + def.nBufferCountMin = numOutputBuffers; + def.nBufferCountActual = def.nBufferCountMin; + def.bEnabled = OMX_TRUE; + def.bPopulated = OMX_FALSE; + def.eDomain = OMX_PortDomainVideo; + def.bBuffersContiguous = OMX_FALSE; + def.format.video.pNativeRender = NULL; + def.format.video.nFrameWidth = mWidth; + def.format.video.nFrameHeight = mHeight; + def.format.video.nStride = 0; + def.format.video.nSliceHeight = 0; + def.format.video.nBitrate = mBitrate; + def.format.video.xFramerate = 0 << 16; + def.format.video.bFlagErrorConcealment = OMX_FALSE; + def.nBufferAlignment = kOutputBufferAlignment; + def.format.video.cMIMEType = const_cast<char *>(mime); + def.format.video.eCompressionFormat = mCodingType; + def.format.video.eColorFormat = OMX_COLOR_FormatUnused; + def.format.video.pNativeWindow = NULL; + // buffersize set in updatePortParams + + addPort(def); + + updatePortParams(); +} + +void SoftVideoEncoderOMXComponent::updatePortParams() { + OMX_PARAM_PORTDEFINITIONTYPE *inDef = &editPortInfo(kInputPortIndex)->mDef; + inDef->format.video.nFrameWidth = mWidth; + inDef->format.video.nFrameHeight = mHeight; + inDef->format.video.nStride = inDef->format.video.nFrameWidth; + inDef->format.video.nSliceHeight = inDef->format.video.nFrameHeight; + inDef->format.video.xFramerate = mFramerate; + inDef->format.video.eColorFormat = mColorFormat; + uint32_t rawBufferSize = + inDef->format.video.nStride * inDef->format.video.nSliceHeight * 3 / 2; + if (inDef->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) { + inDef->nBufferSize = 4 + max(sizeof(buffer_handle_t), sizeof(GraphicBuffer *)); + } else { + inDef->nBufferSize = rawBufferSize; + } + + OMX_PARAM_PORTDEFINITIONTYPE *outDef = &editPortInfo(kOutputPortIndex)->mDef; + outDef->format.video.nFrameWidth = mWidth; + outDef->format.video.nFrameHeight = mHeight; + outDef->format.video.nBitrate = mBitrate; + + outDef->nBufferSize = max(mMinOutputBufferSize, rawBufferSize / mMinCompressionRatio); +} + +OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetPortParams( + const OMX_PARAM_PORTDEFINITIONTYPE *port) { + if (port->nPortIndex == kInputPortIndex) { + mWidth = port->format.video.nFrameWidth; + mHeight = port->format.video.nFrameHeight; + + // xFramerate comes in Q16 format, in frames per second unit + mFramerate = port->format.video.xFramerate; + + if (port->format.video.eCompressionFormat != OMX_VIDEO_CodingUnused + || (port->format.video.eColorFormat != OMX_COLOR_FormatYUV420Planar + && port->format.video.eColorFormat != OMX_COLOR_FormatYUV420SemiPlanar + && port->format.video.eColorFormat != OMX_COLOR_FormatAndroidOpaque)) { + return OMX_ErrorUnsupportedSetting; + } + + mColorFormat = port->format.video.eColorFormat; + } else if (port->nPortIndex == kOutputPortIndex) { + if (port->format.video.eCompressionFormat != mCodingType + || port->format.video.eColorFormat != OMX_COLOR_FormatUnused) { + return OMX_ErrorUnsupportedSetting; + } + + mBitrate = port->format.video.nBitrate; + } else { + return OMX_ErrorBadPortIndex; + } + + updatePortParams(); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalSetParameter( + OMX_INDEXTYPE index, const OMX_PTR param) { + // can include extension index OMX_INDEXEXTTYPE + const int32_t indexFull = index; + + switch (indexFull) { + case OMX_IndexParamVideoErrorCorrection: + { + return OMX_ErrorNotImplemented; + } + + case OMX_IndexParamStandardComponentRole: + { + const OMX_PARAM_COMPONENTROLETYPE *roleParams = + (const OMX_PARAM_COMPONENTROLETYPE *)param; + + if (strncmp((const char *)roleParams->cRole, + mComponentRole, + OMX_MAX_STRINGNAME_SIZE - 1)) { + return OMX_ErrorUnsupportedSetting; + } + + return OMX_ErrorNone; + } + + case OMX_IndexParamPortDefinition: + { + OMX_ERRORTYPE err = internalSetPortParams((const OMX_PARAM_PORTDEFINITIONTYPE *)param); + + if (err != OMX_ErrorNone) { + return err; + } + + return SimpleSoftOMXComponent::internalSetParameter(index, param); + } + + case OMX_IndexParamVideoPortFormat: + { + const OMX_VIDEO_PARAM_PORTFORMATTYPE* format = + (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)param; + + if (format->nPortIndex == kInputPortIndex) { + if (format->eColorFormat == OMX_COLOR_FormatYUV420Planar || + format->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar || + format->eColorFormat == OMX_COLOR_FormatAndroidOpaque) { + mColorFormat = format->eColorFormat; + + updatePortParams(); + return OMX_ErrorNone; + } else { + ALOGE("Unsupported color format %i", format->eColorFormat); + return OMX_ErrorUnsupportedSetting; + } + } else if (format->nPortIndex == kOutputPortIndex) { + if (format->eCompressionFormat == mCodingType) { + return OMX_ErrorNone; + } else { + return OMX_ErrorUnsupportedSetting; + } + } else { + return OMX_ErrorBadPortIndex; + } + } + + case kStoreMetaDataExtensionIndex: + { + // storeMetaDataInBuffers + const StoreMetaDataInBuffersParams *storeParam = + (const StoreMetaDataInBuffersParams *)param; + + if (storeParam->nPortIndex == kOutputPortIndex) { + return storeParam->bStoreMetaData ? OMX_ErrorUnsupportedSetting : OMX_ErrorNone; + } else if (storeParam->nPortIndex != kInputPortIndex) { + return OMX_ErrorBadPortIndex; + } + + mInputDataIsMeta = (storeParam->bStoreMetaData == OMX_TRUE); + if (mInputDataIsMeta) { + mColorFormat = OMX_COLOR_FormatAndroidOpaque; + } else if (mColorFormat == OMX_COLOR_FormatAndroidOpaque) { + mColorFormat = OMX_COLOR_FormatYUV420Planar; + } + updatePortParams(); + return OMX_ErrorNone; + } + + default: + return SimpleSoftOMXComponent::internalSetParameter(index, param); + } +} + +OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalGetParameter( + OMX_INDEXTYPE index, OMX_PTR param) { + switch (index) { + case OMX_IndexParamVideoErrorCorrection: + { + return OMX_ErrorNotImplemented; + } + + case OMX_IndexParamVideoPortFormat: + { + OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = + (OMX_VIDEO_PARAM_PORTFORMATTYPE *)param; + + if (formatParams->nPortIndex == kInputPortIndex) { + if (formatParams->nIndex >= NELEM(kSupportedColorFormats)) { + return OMX_ErrorNoMore; + } + + // Color formats, in order of preference + formatParams->eColorFormat = kSupportedColorFormats[formatParams->nIndex]; + formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; + formatParams->xFramerate = mFramerate; + return OMX_ErrorNone; + } else if (formatParams->nPortIndex == kOutputPortIndex) { + formatParams->eCompressionFormat = mCodingType; + formatParams->eColorFormat = OMX_COLOR_FormatUnused; + formatParams->xFramerate = 0; + return OMX_ErrorNone; + } else { + return OMX_ErrorBadPortIndex; + } + } + + case OMX_IndexParamVideoProfileLevelQuerySupported: + { + OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel = + (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) param; + + if (profileLevel->nPortIndex != kOutputPortIndex) { + ALOGE("Invalid port index: %u", profileLevel->nPortIndex); + return OMX_ErrorUnsupportedIndex; + } + + if (profileLevel->nProfileIndex >= mNumProfileLevels) { + return OMX_ErrorNoMore; + } + + profileLevel->eProfile = mProfileLevels[profileLevel->nProfileIndex].mProfile; + profileLevel->eLevel = mProfileLevels[profileLevel->nProfileIndex].mLevel; + return OMX_ErrorNone; + } + + default: + return SimpleSoftOMXComponent::internalGetParameter(index, param); + } } // static |