diff options
Diffstat (limited to 'media/libstagefright/codecs/on2')
-rw-r--r-- | media/libstagefright/codecs/on2/dec/SoftVPX.cpp | 256 | ||||
-rw-r--r-- | media/libstagefright/codecs/on2/dec/SoftVPX.h | 31 | ||||
-rw-r--r-- | media/libstagefright/codecs/on2/enc/Android.mk | 5 | ||||
-rw-r--r-- | media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp | 232 | ||||
-rw-r--r-- | media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h | 27 | ||||
-rw-r--r-- | media/libstagefright/codecs/on2/h264dec/Android.mk | 2 | ||||
-rw-r--r-- | media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp | 313 | ||||
-rw-r--r-- | media/libstagefright/codecs/on2/h264dec/SoftAVC.h | 31 |
8 files changed, 336 insertions, 561 deletions
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp index a400b4c..476e986 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp @@ -29,26 +29,23 @@ namespace android { -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; -} - SoftVPX::SoftVPX( const char *name, + const char *componentRole, + OMX_VIDEO_CODINGTYPE codingType, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component) - : SimpleSoftOMXComponent(name, callbacks, appData, component), - mCtx(NULL), - mWidth(320), - mHeight(240), - mOutputPortSettingsChange(NONE) { - initPorts(); + : SoftVideoDecoderOMXComponent( + name, componentRole, codingType, + NULL /* profileLevels */, 0 /* numProfileLevels */, + 320 /* width */, 240 /* height */, callbacks, appData, component), + mMode(codingType == OMX_VIDEO_CodingVP8 ? MODE_VP8 : MODE_VP9), + mCtx(NULL) { + initPorts(kNumBuffers, 768 * 1024 /* inputBufferSize */, + kNumBuffers, + codingType == OMX_VIDEO_CodingVP8 ? MEDIA_MIMETYPE_VIDEO_VP8 : MEDIA_MIMETYPE_VIDEO_VP9); + CHECK_EQ(initDecoder(), (status_t)OK); } @@ -58,65 +55,6 @@ SoftVPX::~SoftVPX() { mCtx = NULL; } -void SoftVPX::initPorts() { - OMX_PARAM_PORTDEFINITIONTYPE def; - InitOMXParams(&def); - - def.nPortIndex = 0; - def.eDir = OMX_DirInput; - def.nBufferCountMin = kNumBuffers; - def.nBufferCountActual = def.nBufferCountMin; - def.nBufferSize = 768 * 1024; - def.bEnabled = OMX_TRUE; - def.bPopulated = OMX_FALSE; - def.eDomain = OMX_PortDomainVideo; - def.bBuffersContiguous = OMX_FALSE; - def.nBufferAlignment = 1; - - def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_VPX); - 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; - def.format.video.xFramerate = 0; - def.format.video.bFlagErrorConcealment = OMX_FALSE; - def.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; - def.format.video.eColorFormat = OMX_COLOR_FormatUnused; - def.format.video.pNativeWindow = NULL; - - addPort(def); - - def.nPortIndex = 1; - def.eDir = OMX_DirOutput; - def.nBufferCountMin = kNumBuffers; - def.nBufferCountActual = def.nBufferCountMin; - def.bEnabled = OMX_TRUE; - def.bPopulated = OMX_FALSE; - def.eDomain = OMX_PortDomainVideo; - def.bBuffersContiguous = OMX_FALSE; - def.nBufferAlignment = 2; - - def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RAW); - 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; - def.format.video.xFramerate = 0; - def.format.video.bFlagErrorConcealment = OMX_FALSE; - def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; - def.format.video.pNativeWindow = NULL; - - def.nBufferSize = - (def.format.video.nFrameWidth * def.format.video.nFrameHeight * 3) / 2; - - addPort(def); -} - static int GetCPUCoreCount() { int cpuCoreCount = 1; #if defined(_SC_NPROCESSORS_ONLN) @@ -137,7 +75,9 @@ status_t SoftVPX::initDecoder() { memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t)); cfg.threads = GetCPUCoreCount(); if ((vpx_err = vpx_codec_dec_init( - (vpx_codec_ctx_t *)mCtx, &vpx_codec_vp8_dx_algo, &cfg, 0))) { + (vpx_codec_ctx_t *)mCtx, + mMode == MODE_VP8 ? &vpx_codec_vp8_dx_algo : &vpx_codec_vp9_dx_algo, + &cfg, 0))) { ALOGE("on2 decoder failed to initialize. (%d)", vpx_err); return UNKNOWN_ERROR; } @@ -145,80 +85,6 @@ status_t SoftVPX::initDecoder() { return OK; } -OMX_ERRORTYPE SoftVPX::internalGetParameter( - OMX_INDEXTYPE index, OMX_PTR params) { - switch (index) { - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; - - if (formatParams->nPortIndex > 1) { - return OMX_ErrorUndefined; - } - - if (formatParams->nIndex != 0) { - return OMX_ErrorNoMore; - } - - if (formatParams->nPortIndex == 0) { - formatParams->eCompressionFormat = OMX_VIDEO_CodingVPX; - formatParams->eColorFormat = OMX_COLOR_FormatUnused; - formatParams->xFramerate = 0; - } else { - CHECK_EQ(formatParams->nPortIndex, 1u); - - formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; - formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar; - formatParams->xFramerate = 0; - } - - return OMX_ErrorNone; - } - - default: - return SimpleSoftOMXComponent::internalGetParameter(index, params); - } -} - -OMX_ERRORTYPE SoftVPX::internalSetParameter( - OMX_INDEXTYPE index, const OMX_PTR params) { - switch (index) { - case OMX_IndexParamStandardComponentRole: - { - const OMX_PARAM_COMPONENTROLETYPE *roleParams = - (const OMX_PARAM_COMPONENTROLETYPE *)params; - - if (strncmp((const char *)roleParams->cRole, - "video_decoder.vpx", - OMX_MAX_STRINGNAME_SIZE - 1)) { - return OMX_ErrorUndefined; - } - - return OMX_ErrorNone; - } - - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; - - if (formatParams->nPortIndex > 1) { - return OMX_ErrorUndefined; - } - - if (formatParams->nIndex != 0) { - return OMX_ErrorNoMore; - } - - return OMX_ErrorNone; - } - - default: - return SimpleSoftOMXComponent::internalSetParameter(index, params); - } -} - void SoftVPX::onQueueFilled(OMX_U32 portIndex) { if (mOutputPortSettingsChange != NONE) { return; @@ -226,6 +92,7 @@ void SoftVPX::onQueueFilled(OMX_U32 portIndex) { List<BufferInfo *> &inQueue = getPortQueue(0); List<BufferInfo *> &outQueue = getPortQueue(1); + bool EOSseen = false; while (!inQueue.empty() && !outQueue.empty()) { BufferInfo *inInfo = *inQueue.begin(); @@ -235,17 +102,20 @@ void SoftVPX::onQueueFilled(OMX_U32 portIndex) { OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) { - inQueue.erase(inQueue.begin()); - inInfo->mOwnedByUs = false; - notifyEmptyBufferDone(inHeader); - - outHeader->nFilledLen = 0; - outHeader->nFlags = OMX_BUFFERFLAG_EOS; - - outQueue.erase(outQueue.begin()); - outInfo->mOwnedByUs = false; - notifyFillBufferDone(outHeader); - return; + EOSseen = true; + if (inHeader->nFilledLen == 0) { + inQueue.erase(inQueue.begin()); + inInfo->mOwnedByUs = false; + notifyEmptyBufferDone(inHeader); + + outHeader->nFilledLen = 0; + outHeader->nFlags = OMX_BUFFERFLAG_EOS; + + outQueue.erase(outQueue.begin()); + outInfo->mOwnedByUs = false; + notifyFillBufferDone(outHeader); + return; + } } if (vpx_codec_decode( @@ -266,8 +136,8 @@ void SoftVPX::onQueueFilled(OMX_U32 portIndex) { if (img != NULL) { CHECK_EQ(img->fmt, IMG_FMT_I420); - int32_t width = img->d_w; - int32_t height = img->d_h; + uint32_t width = img->d_w; + uint32_t height = img->d_h; if (width != mWidth || height != mHeight) { mWidth = width; @@ -282,7 +152,7 @@ void SoftVPX::onQueueFilled(OMX_U32 portIndex) { outHeader->nOffset = 0; outHeader->nFilledLen = (width * height * 3) / 2; - outHeader->nFlags = 0; + outHeader->nFlags = EOSseen ? OMX_BUFFERFLAG_EOS : 0; outHeader->nTimeStamp = inHeader->nTimeStamp; const uint8_t *srcLine = (const uint8_t *)img->planes[PLANE_Y]; @@ -325,58 +195,20 @@ void SoftVPX::onQueueFilled(OMX_U32 portIndex) { } } -void SoftVPX::onPortFlushCompleted(OMX_U32 portIndex) { -} - -void SoftVPX::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { - if (portIndex != 1) { - return; - } - - switch (mOutputPortSettingsChange) { - case NONE: - break; - - case AWAITING_DISABLED: - { - CHECK(!enabled); - mOutputPortSettingsChange = AWAITING_ENABLED; - break; - } - - default: - { - CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); - CHECK(enabled); - mOutputPortSettingsChange = NONE; - break; - } - } -} - -void SoftVPX::updatePortDefinitions() { - OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(0)->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 = &editPortInfo(1)->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; -} - } // namespace android android::SoftOMXComponent *createSoftOMXComponent( const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component) { - return new android::SoftVPX(name, callbacks, appData, component); + if (!strcmp(name, "OMX.google.vp8.decoder")) { + return new android::SoftVPX( + name, "video_decoder.vp8", OMX_VIDEO_CodingVP8, + callbacks, appData, component); + } else if (!strcmp(name, "OMX.google.vp9.decoder")) { + return new android::SoftVPX( + name, "video_decoder.vp9", OMX_VIDEO_CodingVP9, + callbacks, appData, component); + } else { + CHECK(!"Unknown component"); + } } - diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.h b/media/libstagefright/codecs/on2/dec/SoftVPX.h index 3e814a2..cd5eb28 100644 --- a/media/libstagefright/codecs/on2/dec/SoftVPX.h +++ b/media/libstagefright/codecs/on2/dec/SoftVPX.h @@ -18,12 +18,14 @@ #define SOFT_VPX_H_ -#include "SimpleSoftOMXComponent.h" +#include "SoftVideoDecoderOMXComponent.h" namespace android { -struct SoftVPX : public SimpleSoftOMXComponent { +struct SoftVPX : public SoftVideoDecoderOMXComponent { SoftVPX(const char *name, + const char *componentRole, + OMX_VIDEO_CODINGTYPE codingType, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component); @@ -31,36 +33,21 @@ struct SoftVPX : public SimpleSoftOMXComponent { protected: virtual ~SoftVPX(); - virtual OMX_ERRORTYPE internalGetParameter( - OMX_INDEXTYPE index, OMX_PTR params); - - virtual OMX_ERRORTYPE internalSetParameter( - OMX_INDEXTYPE index, const OMX_PTR params); - virtual void onQueueFilled(OMX_U32 portIndex); - virtual void onPortFlushCompleted(OMX_U32 portIndex); - virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled); private: enum { kNumBuffers = 4 }; - void *mCtx; - - int32_t mWidth; - int32_t mHeight; - enum { - NONE, - AWAITING_DISABLED, - AWAITING_ENABLED - } mOutputPortSettingsChange; + MODE_VP8, + MODE_VP9 + } mMode; - void initPorts(); - status_t initDecoder(); + void *mCtx; - void updatePortDefinitions(); + status_t initDecoder(); DISALLOW_EVIL_CONSTRUCTORS(SoftVPX); }; diff --git a/media/libstagefright/codecs/on2/enc/Android.mk b/media/libstagefright/codecs/on2/enc/Android.mk index a92d376..4060a0a 100644 --- a/media/libstagefright/codecs/on2/enc/Android.mk +++ b/media/libstagefright/codecs/on2/enc/Android.mk @@ -12,11 +12,16 @@ LOCAL_C_INCLUDES := \ frameworks/av/media/libstagefright/include \ frameworks/native/include/media/openmax \ +ifeq ($(TARGET_DEVICE), manta) + LOCAL_CFLAGS += -DSURFACE_IS_BGR32 +endif + LOCAL_STATIC_LIBRARIES := \ libvpx LOCAL_SHARED_LIBRARIES := \ libstagefright libstagefright_omx libstagefright_foundation libutils liblog \ + libhardware \ LOCAL_MODULE := libstagefright_soft_vpxenc LOCAL_MODULE_TAGS := optional diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp index e25637a..8375cac 100644 --- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp +++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp @@ -20,6 +20,8 @@ #include <utils/Log.h> +#include <media/hardware/HardwareAPI.h> +#include <media/hardware/MetadataBufferType.h> #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/MediaDefs.h> @@ -81,6 +83,52 @@ inline static void ConvertSemiPlanarToPlanar(uint8_t *inyuv, } } +static void ConvertRGB32ToPlanar( + const uint8_t *src, uint8_t *dstY, int32_t width, int32_t height) { + CHECK((width & 1) == 0); + CHECK((height & 1) == 0); + + uint8_t *dstU = dstY + width * height; + uint8_t *dstV = dstU + (width / 2) * (height / 2); + + for (int32_t y = 0; y < height; ++y) { + for (int32_t x = 0; x < width; ++x) { +#ifdef SURFACE_IS_BGR32 + unsigned blue = src[4 * x]; + unsigned green = src[4 * x + 1]; + unsigned red= src[4 * x + 2]; +#else + unsigned red= src[4 * x]; + unsigned green = src[4 * x + 1]; + unsigned blue = src[4 * x + 2]; +#endif + + unsigned luma = + ((red * 66 + green * 129 + blue * 25) >> 8) + 16; + + dstY[x] = luma; + + if ((x & 1) == 0 && (y & 1) == 0) { + unsigned U = + ((-red * 38 - green * 74 + blue * 112) >> 8) + 128; + + unsigned V = + ((red * 112 - green * 94 - blue * 18) >> 8) + 128; + + dstU[x / 2] = U; + dstV[x / 2] = V; + } + } + + if ((y & 1) == 0) { + dstU += width / 2; + dstV += width / 2; + } + + src += 4 * width; + dstY += width; + } +} SoftVPXEncoder::SoftVPXEncoder(const char *name, const OMX_CALLBACKTYPE *callbacks, @@ -93,14 +141,17 @@ SoftVPXEncoder::SoftVPXEncoder(const char *name, mWidth(176), mHeight(144), mBitrate(192000), // in bps + mBitrateUpdated(false), mBitrateControlMode(VPX_VBR), // variable bitrate mFrameDurationUs(33333), // Defaults to 30 fps mDCTPartitions(0), mErrorResilience(OMX_FALSE), mColorFormat(OMX_COLOR_FormatYUV420Planar), mLevel(OMX_VIDEO_VP8Level_Version0), - mConversionBuffer(NULL) { - + mConversionBuffer(NULL), + mInputDataIsMeta(false), + mGrallocModule(NULL), + mKeyFrameRequested(false) { initPorts(); } @@ -165,8 +216,8 @@ void SoftVPXEncoder::initPorts() { outputPort.eDir = OMX_DirOutput; outputPort.nBufferAlignment = kOutputBufferAlignment; outputPort.format.video.cMIMEType = - const_cast<char *>(MEDIA_MIMETYPE_VIDEO_VPX); - outputPort.format.video.eCompressionFormat = OMX_VIDEO_CodingVPX; + const_cast<char *>(MEDIA_MIMETYPE_VIDEO_VP8); + outputPort.format.video.eCompressionFormat = OMX_VIDEO_CodingVP8; outputPort.format.video.eColorFormat = OMX_COLOR_FormatUnused; outputPort.format.video.pNativeWindow = NULL; outputPort.nBufferSize = 256 * 1024; // arbitrary @@ -247,7 +298,7 @@ status_t SoftVPXEncoder::initEncoder() { return UNKNOWN_ERROR; } - if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { + if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar || mInputDataIsMeta) { if (mConversionBuffer == NULL) { mConversionBuffer = (uint8_t *)malloc(mWidth * mHeight * 3 / 2); if (mConversionBuffer == NULL) { @@ -315,7 +366,7 @@ OMX_ERRORTYPE SoftVPXEncoder::internalGetParameter(OMX_INDEXTYPE index, formatParams->xFramerate = (1000000/mFrameDurationUs) << 16; return OMX_ErrorNone; } else if (formatParams->nPortIndex == kOutputPortIndex) { - formatParams->eCompressionFormat = OMX_VIDEO_CodingVPX; + formatParams->eCompressionFormat = OMX_VIDEO_CodingVP8; formatParams->eColorFormat = OMX_COLOR_FormatUnused; formatParams->xFramerate = 0; return OMX_ErrorNone; @@ -427,9 +478,17 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetParameter(OMX_INDEXTYPE index, (const OMX_VIDEO_PARAM_BITRATETYPE *)param); case OMX_IndexParamPortDefinition: - return internalSetPortParams( + { + OMX_ERRORTYPE err = internalSetPortParams( (const OMX_PARAM_PORTDEFINITIONTYPE *)param); + if (err != OMX_ErrorNone) { + return err; + } + + return SimpleSoftOMXComponent::internalSetParameter(index, param); + } + case OMX_IndexParamVideoPortFormat: return internalSetFormatParams( (const OMX_VIDEO_PARAM_PORTFORMATTYPE *)param); @@ -442,11 +501,63 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetParameter(OMX_INDEXTYPE index, return internalSetProfileLevel( (const OMX_VIDEO_PARAM_PROFILELEVELTYPE *)param); + case OMX_IndexVendorStartUnused: + { + // storeMetaDataInBuffers + const StoreMetaDataInBuffersParams *storeParam = + (const StoreMetaDataInBuffersParams *)param; + + if (storeParam->nPortIndex != kInputPortIndex) { + return OMX_ErrorBadPortIndex; + } + + mInputDataIsMeta = (storeParam->bStoreMetaData == OMX_TRUE); + + return OMX_ErrorNone; + } + default: return SimpleSoftOMXComponent::internalSetParameter(index, param); } } +OMX_ERRORTYPE SoftVPXEncoder::setConfig( + OMX_INDEXTYPE index, const OMX_PTR _params) { + switch (index) { + case OMX_IndexConfigVideoIntraVOPRefresh: + { + OMX_CONFIG_INTRAREFRESHVOPTYPE *params = + (OMX_CONFIG_INTRAREFRESHVOPTYPE *)_params; + + if (params->nPortIndex != kOutputPortIndex) { + return OMX_ErrorBadPortIndex; + } + + mKeyFrameRequested = params->IntraRefreshVOP; + return OMX_ErrorNone; + } + + case OMX_IndexConfigVideoBitrate: + { + OMX_VIDEO_CONFIG_BITRATETYPE *params = + (OMX_VIDEO_CONFIG_BITRATETYPE *)_params; + + if (params->nPortIndex != kOutputPortIndex) { + return OMX_ErrorBadPortIndex; + } + + if (mBitrate != params->nEncodeBitrate) { + mBitrate = params->nEncodeBitrate; + mBitrateUpdated = true; + } + return OMX_ErrorNone; + } + + default: + return SimpleSoftOMXComponent::setConfig(index, _params); + } +} + OMX_ERRORTYPE SoftVPXEncoder::internalSetProfileLevel( const OMX_VIDEO_PARAM_PROFILELEVELTYPE* profileAndLevel) { if (profileAndLevel->nPortIndex != kOutputPortIndex) { @@ -507,13 +618,17 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetFormatParams( format->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar || format->eColorFormat == OMX_COLOR_FormatAndroidOpaque) { mColorFormat = format->eColorFormat; + + OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kInputPortIndex)->mDef; + def->format.video.eColorFormat = mColorFormat; + return OMX_ErrorNone; } else { ALOGE("Unsupported color format %i", format->eColorFormat); return OMX_ErrorUnsupportedSetting; } } else if (format->nPortIndex == kOutputPortIndex) { - if (format->eCompressionFormat == OMX_VIDEO_CodingVPX) { + if (format->eCompressionFormat == OMX_VIDEO_CodingVP8) { return OMX_ErrorNone; } else { return OMX_ErrorUnsupportedSetting; @@ -529,7 +644,7 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetRoleParams( const char* roleText = (const char*)role->cRole; const size_t roleTextMaxSize = OMX_MAX_STRINGNAME_SIZE - 1; - if (strncmp(roleText, "video_encoder.vpx", roleTextMaxSize)) { + if (strncmp(roleText, "video_encoder.vp8", roleTextMaxSize)) { ALOGE("Unsupported component role"); return OMX_ErrorBadParameter; } @@ -552,11 +667,17 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetPortParams( if (port->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar || port->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar || port->format.video.eColorFormat == OMX_COLOR_FormatAndroidOpaque) { - mColorFormat = port->format.video.eColorFormat; + mColorFormat = port->format.video.eColorFormat; } else { return OMX_ErrorUnsupportedSetting; } + OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kInputPortIndex)->mDef; + def->format.video.nFrameWidth = mWidth; + def->format.video.nFrameHeight = mHeight; + def->format.video.xFramerate = port->format.video.xFramerate; + def->format.video.eColorFormat = mColorFormat; + return OMX_ErrorNone; } else if (port->nPortIndex == kOutputPortIndex) { mBitrate = port->format.video.nBitrate; @@ -625,24 +746,78 @@ void SoftVPXEncoder::onQueueFilled(OMX_U32 portIndex) { return; } - uint8_t* source = inputBufferHeader->pBuffer + inputBufferHeader->nOffset; + uint8_t *source = + inputBufferHeader->pBuffer + inputBufferHeader->nOffset; + + if (mInputDataIsMeta) { + CHECK_GE(inputBufferHeader->nFilledLen, + 4 + sizeof(buffer_handle_t)); + + uint32_t bufferType = *(uint32_t *)source; + CHECK_EQ(bufferType, kMetadataBufferTypeGrallocSource); + + if (mGrallocModule == NULL) { + CHECK_EQ(0, hw_get_module( + GRALLOC_HARDWARE_MODULE_ID, &mGrallocModule)); + } + + const gralloc_module_t *grmodule = + (const gralloc_module_t *)mGrallocModule; + + buffer_handle_t handle = *(buffer_handle_t *)(source + 4); + + void *bits; + CHECK_EQ(0, + grmodule->lock( + grmodule, handle, + GRALLOC_USAGE_SW_READ_OFTEN + | GRALLOC_USAGE_SW_WRITE_NEVER, + 0, 0, mWidth, mHeight, &bits)); + + ConvertRGB32ToPlanar( + (const uint8_t *)bits, mConversionBuffer, mWidth, mHeight); + + source = mConversionBuffer; + + CHECK_EQ(0, grmodule->unlock(grmodule, handle)); + } else if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { + ConvertSemiPlanarToPlanar( + source, mConversionBuffer, mWidth, mHeight); - // NOTE: As much as nothing is known about color format - // when it is denoted as AndroidOpaque, it is at least - // assumed to be planar. - if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) { - ConvertSemiPlanarToPlanar(source, mConversionBuffer, mWidth, mHeight); source = mConversionBuffer; } vpx_image_t raw_frame; vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, mWidth, mHeight, kInputBufferAlignment, source); - codec_return = vpx_codec_encode(mCodecContext, - &raw_frame, - inputBufferHeader->nTimeStamp, // in timebase units - mFrameDurationUs, // frame duration in timebase units - 0, // frame flags - VPX_DL_REALTIME); // encoding deadline + + vpx_enc_frame_flags_t flags = 0; + if (mKeyFrameRequested) { + flags |= VPX_EFLAG_FORCE_KF; + mKeyFrameRequested = false; + } + + if (mBitrateUpdated) { + mCodecConfiguration->rc_target_bitrate = mBitrate/1000; + vpx_codec_err_t res = vpx_codec_enc_config_set(mCodecContext, + mCodecConfiguration); + if (res != VPX_CODEC_OK) { + ALOGE("vp8 encoder failed to update bitrate: %s", + vpx_codec_err_to_string(res)); + notify(OMX_EventError, + OMX_ErrorUndefined, + 0, // Extra notification data + NULL); // Notification data pointer + } + mBitrateUpdated = false; + } + + codec_return = vpx_codec_encode( + mCodecContext, + &raw_frame, + inputBufferHeader->nTimeStamp, // in timebase units + mFrameDurationUs, // frame duration in timebase units + flags, // frame flags + VPX_DL_REALTIME); // encoding deadline if (codec_return != VPX_CODEC_OK) { ALOGE("vpx encoder failed to encode frame"); notify(OMX_EventError, @@ -660,6 +835,8 @@ void SoftVPXEncoder::onQueueFilled(OMX_U32 portIndex) { if (encoded_packet->kind == VPX_CODEC_CX_FRAME_PKT) { outputBufferHeader->nTimeStamp = encoded_packet->data.frame.pts; outputBufferHeader->nFlags = 0; + if (encoded_packet->data.frame.flags & VPX_FRAME_IS_KEY) + outputBufferHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; outputBufferHeader->nOffset = 0; outputBufferHeader->nFilledLen = encoded_packet->data.frame.sz; memcpy(outputBufferHeader->pBuffer, @@ -676,6 +853,17 @@ void SoftVPXEncoder::onQueueFilled(OMX_U32 portIndex) { notifyEmptyBufferDone(inputBufferHeader); } } + +OMX_ERRORTYPE SoftVPXEncoder::getExtensionIndex( + const char *name, OMX_INDEXTYPE *index) { + if (!strcmp(name, "OMX.google.android.index.storeMetaDataInBuffers")) { + *index = OMX_IndexVendorStartUnused; + return OMX_ErrorNone; + } + + return SimpleSoftOMXComponent::getExtensionIndex(name, index); +} + } // namespace android diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h index 3bc05c0..076830f 100644 --- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h +++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h @@ -23,6 +23,8 @@ #include <OMX_VideoExt.h> #include <OMX_IndexExt.h> +#include <hardware/gralloc.h> + #include "vpx/vpx_encoder.h" #include "vpx/vpx_codec.h" #include "vpx/vp8cx.h" @@ -57,14 +59,13 @@ namespace android { // - OMX timestamps are in microseconds, therefore // encoder timebase is fixed to 1/1000000 -class SoftVPXEncoder : public SimpleSoftOMXComponent { - public: +struct SoftVPXEncoder : public SimpleSoftOMXComponent { SoftVPXEncoder(const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component); - protected: +protected: virtual ~SoftVPXEncoder(); // Returns current values for requested OMX @@ -77,13 +78,19 @@ class SoftVPXEncoder : public SimpleSoftOMXComponent { virtual OMX_ERRORTYPE internalSetParameter( OMX_INDEXTYPE index, const OMX_PTR param); + virtual OMX_ERRORTYPE setConfig( + OMX_INDEXTYPE index, const OMX_PTR params); + // OMX callback when buffers available // Note that both an input and output buffer // is expected to be available to carry out // encoding of the frame virtual void onQueueFilled(OMX_U32 portIndex); - private: + virtual OMX_ERRORTYPE getExtensionIndex( + const char *name, OMX_INDEXTYPE *index); + +private: // number of buffers allocated per port static const uint32_t kNumBuffers = 4; @@ -121,7 +128,10 @@ class SoftVPXEncoder : public SimpleSoftOMXComponent { int32_t mHeight; // Target bitrate set for the encoder, in bits per second. - int32_t mBitrate; + uint32_t mBitrate; + + // If a request for a change it bitrate has been received. + bool mBitrateUpdated; // Bitrate control mode, either constant or variable vpx_rc_mode mBitrateControlMode; @@ -156,6 +166,11 @@ class SoftVPXEncoder : public SimpleSoftOMXComponent { // indeed YUV420SemiPlanar. uint8_t* mConversionBuffer; + bool mInputDataIsMeta; + const hw_module_t *mGrallocModule; + + bool mKeyFrameRequested; + // Initializes input and output OMX ports with sensible // default values. void initPorts(); @@ -175,7 +190,7 @@ class SoftVPXEncoder : public SimpleSoftOMXComponent { const OMX_VIDEO_PARAM_PORTFORMATTYPE* format); // Verifies the component role tried to be set to this OMX component is - // strictly video_encoder.vpx + // strictly video_encoder.vp8 OMX_ERRORTYPE internalSetRoleParams( const OMX_PARAM_COMPONENTROLETYPE* role); diff --git a/media/libstagefright/codecs/on2/h264dec/Android.mk b/media/libstagefright/codecs/on2/h264dec/Android.mk index 2539f98..655b2ab 100644 --- a/media/libstagefright/codecs/on2/h264dec/Android.mk +++ b/media/libstagefright/codecs/on2/h264dec/Android.mk @@ -119,7 +119,7 @@ LOCAL_C_INCLUDES := $(LOCAL_PATH)/inc LOCAL_SHARED_LIBRARIES := libstagefright_soft_h264dec -LOCAL_MODULE_TAGS := debug +LOCAL_MODULE_TAGS := optional LOCAL_MODULE := decoder diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp index 6e36651..7ddb13c 100644 --- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp +++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp @@ -47,38 +47,28 @@ static const CodecProfileLevel kProfileLevels[] = { { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel51 }, }; -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; -} - SoftAVC::SoftAVC( const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, OMX_COMPONENTTYPE **component) - : SimpleSoftOMXComponent(name, callbacks, appData, component), + : SoftVideoDecoderOMXComponent( + name, "video_decoder.avc", OMX_VIDEO_CodingAVC, + kProfileLevels, ARRAY_SIZE(kProfileLevels), + 320 /* width */, 240 /* height */, callbacks, appData, component), mHandle(NULL), mInputBufferCount(0), - mWidth(320), - mHeight(240), mPictureSize(mWidth * mHeight * 3 / 2), - mCropLeft(0), - mCropTop(0), - mCropWidth(mWidth), - mCropHeight(mHeight), mFirstPicture(NULL), mFirstPictureId(-1), mPicId(0), mHeadersDecoded(false), mEOSStatus(INPUT_DATA_AVAILABLE), - mOutputPortSettingsChange(NONE), mSignalledError(false) { - initPorts(); + initPorts( + kNumInputBuffers, 8192 /* inputBufferSize */, + kNumOutputBuffers, MEDIA_MIMETYPE_VIDEO_AVC); + CHECK_EQ(initDecoder(), (status_t)OK); } @@ -100,65 +90,6 @@ SoftAVC::~SoftAVC() { delete[] mFirstPicture; } -void SoftAVC::initPorts() { - OMX_PARAM_PORTDEFINITIONTYPE def; - InitOMXParams(&def); - - def.nPortIndex = kInputPortIndex; - def.eDir = OMX_DirInput; - def.nBufferCountMin = kNumInputBuffers; - def.nBufferCountActual = def.nBufferCountMin; - def.nBufferSize = 8192; - def.bEnabled = OMX_TRUE; - def.bPopulated = OMX_FALSE; - def.eDomain = OMX_PortDomainVideo; - def.bBuffersContiguous = OMX_FALSE; - def.nBufferAlignment = 1; - - def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_AVC); - 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; - def.format.video.xFramerate = 0; - def.format.video.bFlagErrorConcealment = OMX_FALSE; - def.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; - def.format.video.eColorFormat = OMX_COLOR_FormatUnused; - def.format.video.pNativeWindow = NULL; - - addPort(def); - - def.nPortIndex = kOutputPortIndex; - def.eDir = OMX_DirOutput; - def.nBufferCountMin = kNumOutputBuffers; - def.nBufferCountActual = def.nBufferCountMin; - def.bEnabled = OMX_TRUE; - def.bPopulated = OMX_FALSE; - def.eDomain = OMX_PortDomainVideo; - def.bBuffersContiguous = OMX_FALSE; - def.nBufferAlignment = 2; - - def.format.video.cMIMEType = const_cast<char *>(MEDIA_MIMETYPE_VIDEO_RAW); - 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; - def.format.video.xFramerate = 0; - def.format.video.bFlagErrorConcealment = OMX_FALSE; - def.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; - def.format.video.eColorFormat = OMX_COLOR_FormatYUV420Planar; - def.format.video.pNativeWindow = NULL; - - def.nBufferSize = - (def.format.video.nFrameWidth * def.format.video.nFrameHeight * 3) / 2; - - addPort(def); -} - status_t SoftAVC::initDecoder() { // Force decoder to output buffers in display order. if (H264SwDecInit(&mHandle, 0) == H264SWDEC_OK) { @@ -167,126 +98,6 @@ status_t SoftAVC::initDecoder() { return UNKNOWN_ERROR; } -OMX_ERRORTYPE SoftAVC::internalGetParameter( - OMX_INDEXTYPE index, OMX_PTR params) { - switch (index) { - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; - - if (formatParams->nPortIndex > kOutputPortIndex) { - return OMX_ErrorUndefined; - } - - if (formatParams->nIndex != 0) { - return OMX_ErrorNoMore; - } - - if (formatParams->nPortIndex == kInputPortIndex) { - formatParams->eCompressionFormat = OMX_VIDEO_CodingAVC; - formatParams->eColorFormat = OMX_COLOR_FormatUnused; - formatParams->xFramerate = 0; - } else { - CHECK(formatParams->nPortIndex == kOutputPortIndex); - - formatParams->eCompressionFormat = OMX_VIDEO_CodingUnused; - formatParams->eColorFormat = OMX_COLOR_FormatYUV420Planar; - formatParams->xFramerate = 0; - } - - return OMX_ErrorNone; - } - - case OMX_IndexParamVideoProfileLevelQuerySupported: - { - OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel = - (OMX_VIDEO_PARAM_PROFILELEVELTYPE *) params; - - if (profileLevel->nPortIndex != kInputPortIndex) { - ALOGE("Invalid port index: %ld", profileLevel->nPortIndex); - return OMX_ErrorUnsupportedIndex; - } - - size_t index = profileLevel->nProfileIndex; - size_t nProfileLevels = - sizeof(kProfileLevels) / sizeof(kProfileLevels[0]); - if (index >= nProfileLevels) { - return OMX_ErrorNoMore; - } - - profileLevel->eProfile = kProfileLevels[index].mProfile; - profileLevel->eLevel = kProfileLevels[index].mLevel; - return OMX_ErrorNone; - } - - default: - return SimpleSoftOMXComponent::internalGetParameter(index, params); - } -} - -OMX_ERRORTYPE SoftAVC::internalSetParameter( - OMX_INDEXTYPE index, const OMX_PTR params) { - switch (index) { - case OMX_IndexParamStandardComponentRole: - { - const OMX_PARAM_COMPONENTROLETYPE *roleParams = - (const OMX_PARAM_COMPONENTROLETYPE *)params; - - if (strncmp((const char *)roleParams->cRole, - "video_decoder.avc", - OMX_MAX_STRINGNAME_SIZE - 1)) { - return OMX_ErrorUndefined; - } - - return OMX_ErrorNone; - } - - case OMX_IndexParamVideoPortFormat: - { - OMX_VIDEO_PARAM_PORTFORMATTYPE *formatParams = - (OMX_VIDEO_PARAM_PORTFORMATTYPE *)params; - - if (formatParams->nPortIndex > kOutputPortIndex) { - return OMX_ErrorUndefined; - } - - if (formatParams->nIndex != 0) { - return OMX_ErrorNoMore; - } - - return OMX_ErrorNone; - } - - default: - return SimpleSoftOMXComponent::internalSetParameter(index, params); - } -} - -OMX_ERRORTYPE SoftAVC::getConfig( - OMX_INDEXTYPE index, OMX_PTR params) { - switch (index) { - case OMX_IndexConfigCommonOutputCrop: - { - OMX_CONFIG_RECTTYPE *rectParams = (OMX_CONFIG_RECTTYPE *)params; - - if (rectParams->nPortIndex != 1) { - return OMX_ErrorUndefined; - } - - rectParams->nLeft = mCropLeft; - rectParams->nTop = mCropTop; - rectParams->nWidth = mCropWidth; - rectParams->nHeight = mCropHeight; - - return OMX_ErrorNone; - } - - default: - return OMX_ErrorUnsupportedIndex; - } -} - void SoftAVC::onQueueFilled(OMX_U32 portIndex) { if (mSignalledError || mOutputPortSettingsChange != NONE) { return; @@ -298,13 +109,21 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) { List<BufferInfo *> &inQueue = getPortQueue(kInputPortIndex); List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex); + + if (mHeadersDecoded) { + // Dequeue any already decoded output frames to free up space + // in the output queue. + + drainAllOutputBuffers(false /* eos */); + } + H264SwDecRet ret = H264SWDEC_PIC_RDY; bool portSettingsChanged = false; while ((mEOSStatus != INPUT_DATA_AVAILABLE || !inQueue.empty()) && outQueue.size() == kNumOutputBuffers) { if (mEOSStatus == INPUT_EOS_SEEN) { - drainAllOutputBuffers(); + drainAllOutputBuffers(true /* eos */); return; } @@ -392,15 +211,7 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) { mFirstPictureId = -1; } - while (!outQueue.empty() && - mHeadersDecoded && - H264SwDecNextPicture(mHandle, &decodedPicture, 0) - == H264SWDEC_PIC_RDY) { - - int32_t picId = decodedPicture.picId; - uint8_t *data = (uint8_t *) decodedPicture.pOutputPicture; - drainOneOutputBuffer(picId, data); - } + drainAllOutputBuffers(false /* eos */); } } @@ -409,8 +220,6 @@ bool SoftAVC::handlePortSettingChangeEvent(const H264SwDecInfo *info) { mWidth = info->picWidth; mHeight = info->picHeight; mPictureSize = mWidth * mHeight * 3 / 2; - mCropWidth = mWidth; - mCropHeight = mHeight; updatePortDefinitions(); notify(OMX_EventPortSettingsChanged, 1, 0, NULL); mOutputPortSettingsChange = AWAITING_DISABLED; @@ -463,43 +272,38 @@ void SoftAVC::drainOneOutputBuffer(int32_t picId, uint8_t* data) { notifyFillBufferDone(outHeader); } -bool SoftAVC::drainAllOutputBuffers() { +void SoftAVC::drainAllOutputBuffers(bool eos) { List<BufferInfo *> &outQueue = getPortQueue(kOutputPortIndex); H264SwDecPicture decodedPicture; + if (mHeadersDecoded) { + while (!outQueue.empty() + && H264SWDEC_PIC_RDY == H264SwDecNextPicture( + mHandle, &decodedPicture, eos /* flush */)) { + int32_t picId = decodedPicture.picId; + uint8_t *data = (uint8_t *) decodedPicture.pOutputPicture; + drainOneOutputBuffer(picId, data); + } + } + + if (!eos) { + return; + } + while (!outQueue.empty()) { BufferInfo *outInfo = *outQueue.begin(); outQueue.erase(outQueue.begin()); OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader; - if (mHeadersDecoded && - H264SWDEC_PIC_RDY == - H264SwDecNextPicture(mHandle, &decodedPicture, 1 /* flush */)) { - int32_t picId = decodedPicture.picId; - CHECK(mPicToHeaderMap.indexOfKey(picId) >= 0); - - memcpy(outHeader->pBuffer + outHeader->nOffset, - decodedPicture.pOutputPicture, - mPictureSize); - - OMX_BUFFERHEADERTYPE *header = mPicToHeaderMap.valueFor(picId); - outHeader->nTimeStamp = header->nTimeStamp; - outHeader->nFlags = header->nFlags; - outHeader->nFilledLen = mPictureSize; - mPicToHeaderMap.removeItem(picId); - delete header; - } else { - outHeader->nTimeStamp = 0; - outHeader->nFilledLen = 0; - outHeader->nFlags = OMX_BUFFERFLAG_EOS; - mEOSStatus = OUTPUT_FRAMES_FLUSHED; - } + outHeader->nTimeStamp = 0; + outHeader->nFilledLen = 0; + outHeader->nFlags = OMX_BUFFERFLAG_EOS; outInfo->mOwnedByUs = false; notifyFillBufferDone(outHeader); - } - return true; + mEOSStatus = OUTPUT_FRAMES_FLUSHED; + } } void SoftAVC::onPortFlushCompleted(OMX_U32 portIndex) { @@ -508,44 +312,9 @@ void SoftAVC::onPortFlushCompleted(OMX_U32 portIndex) { } } -void SoftAVC::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) { - switch (mOutputPortSettingsChange) { - case NONE: - break; - - case AWAITING_DISABLED: - { - CHECK(!enabled); - mOutputPortSettingsChange = AWAITING_ENABLED; - break; - } - - default: - { - CHECK_EQ((int)mOutputPortSettingsChange, (int)AWAITING_ENABLED); - CHECK(enabled); - mOutputPortSettingsChange = NONE; - break; - } - } -} - -void SoftAVC::updatePortDefinitions() { - OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(0)->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 = &editPortInfo(1)->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; +void SoftAVC::onReset() { + SoftVideoDecoderOMXComponent::onReset(); + mSignalledError = false; } } // namespace android diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h index 879b014..ee69926 100644 --- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.h +++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.h @@ -18,7 +18,7 @@ #define SOFT_AVC_H_ -#include "SimpleSoftOMXComponent.h" +#include "SoftVideoDecoderOMXComponent.h" #include <utils/KeyedVector.h> #include "H264SwDecApi.h" @@ -26,7 +26,7 @@ namespace android { -struct SoftAVC : public SimpleSoftOMXComponent { +struct SoftAVC : public SoftVideoDecoderOMXComponent { SoftAVC(const char *name, const OMX_CALLBACKTYPE *callbacks, OMX_PTR appData, @@ -35,22 +35,12 @@ struct SoftAVC : public SimpleSoftOMXComponent { protected: virtual ~SoftAVC(); - virtual OMX_ERRORTYPE internalGetParameter( - OMX_INDEXTYPE index, OMX_PTR params); - - virtual OMX_ERRORTYPE internalSetParameter( - OMX_INDEXTYPE index, const OMX_PTR params); - - virtual OMX_ERRORTYPE getConfig(OMX_INDEXTYPE index, OMX_PTR params); - virtual void onQueueFilled(OMX_U32 portIndex); virtual void onPortFlushCompleted(OMX_U32 portIndex); - virtual void onPortEnableCompleted(OMX_U32 portIndex, bool enabled); + virtual void onReset(); private: enum { - kInputPortIndex = 0, - kOutputPortIndex = 1, kNumInputBuffers = 8, kNumOutputBuffers = 2, }; @@ -65,9 +55,7 @@ private: size_t mInputBufferCount; - uint32_t mWidth, mHeight, mPictureSize; - uint32_t mCropLeft, mCropTop; - uint32_t mCropWidth, mCropHeight; + uint32_t mPictureSize; uint8_t *mFirstPicture; int32_t mFirstPictureId; @@ -81,19 +69,10 @@ private: EOSStatus mEOSStatus; - enum OutputPortSettingChange { - NONE, - AWAITING_DISABLED, - AWAITING_ENABLED - }; - OutputPortSettingChange mOutputPortSettingsChange; - bool mSignalledError; - void initPorts(); status_t initDecoder(); - void updatePortDefinitions(); - bool drainAllOutputBuffers(); + void drainAllOutputBuffers(bool eos); void drainOneOutputBuffer(int32_t picId, uint8_t *data); void saveFirstOutputBuffer(int32_t pidId, uint8_t *data); bool handleCropRectEvent(const CropParams* crop); |