diff options
| author | Shuduo Sang <shuduo.sang@intel.com> | 2011-09-13 17:41:41 +0800 |
|---|---|---|
| committer | Patrick Tjin <pattjin@google.com> | 2014-07-21 22:02:44 -0700 |
| commit | 19b2ab9f325bdbf3afe530e943fa5a0c0020b308 (patch) | |
| tree | d831e71b57586df696aa0d6d13763b7a6b6a9008 | |
| parent | 5a87cdf2139ee15c61aaae2988bbea3ae49e6235 (diff) | |
| download | android_hardware_intel_common_omx-components-19b2ab9f325bdbf3afe530e943fa5a0c0020b308.tar.gz android_hardware_intel_common_omx-components-19b2ab9f325bdbf3afe530e943fa5a0c0020b308.tar.bz2 android_hardware_intel_common_omx-components-19b2ab9f325bdbf3afe530e943fa5a0c0020b308.zip | |
[PORT FROM R1][omx-components] New OMX IL wrapper based on new encoder library
BZ: 5809
New OMX IL wrapper based on new encoder library
Change-Id: Idd5c9d30eca102d9516504f8be52bbbb8e664ddb
Orig-Change-Id: I7edf2ff47fb27ad0a63586328b765110ef32ddba
Signed-off-by: Weian Chen <weian.chen@intel.com>
Reviewed-on: http://android.intel.com:8080/18324
Tested-by: Sang, Shuduo <shuduo.sang@intel.com>
Reviewed-by: Monnier, OlivierX <olivierx.monnier@intel.com>
Reviewed-by: buildbot <buildbot@intel.com>
Tested-by: buildbot <buildbot@intel.com>
| -rw-r--r-- | videocodec/Android.mk | 96 | ||||
| -rw-r--r-- | videocodec/OMXComponentCodecBase.cpp | 7 | ||||
| -rw-r--r-- | videocodec/OMXComponentDefines.h | 24 | ||||
| -rw-r--r-- | videocodec/OMXVideoEncoderAVC.cpp | 391 | ||||
| -rw-r--r-- | videocodec/OMXVideoEncoderAVC.h | 27 | ||||
| -rw-r--r-- | videocodec/OMXVideoEncoderBase.cpp | 515 | ||||
| -rw-r--r-- | videocodec/OMXVideoEncoderBase.h | 56 | ||||
| -rw-r--r-- | videocodec/OMXVideoEncoderH263.cpp | 172 | ||||
| -rw-r--r-- | videocodec/OMXVideoEncoderH263.h | 6 | ||||
| -rw-r--r-- | videocodec/OMXVideoEncoderMPEG4.cpp | 174 | ||||
| -rw-r--r-- | videocodec/OMXVideoEncoderMPEG4.h | 6 | ||||
| -rw-r--r-- | videocodec/vabuffer.h | 3 | ||||
| -rw-r--r-- | wrs_omxil_components.list | 3 |
13 files changed, 1272 insertions, 208 deletions
diff --git a/videocodec/Android.mk b/videocodec/Android.mk index 11d1764..4b934ab 100644 --- a/videocodec/Android.mk +++ b/videocodec/Android.mk @@ -112,5 +112,101 @@ LOCAL_MODULE_TAGS := optional LOCAL_MODULE := libOMXVideoDecoderWMV include $(BUILD_SHARED_LIBRARY) +include $(CLEAR_VARS) + +LOCAL_CPPFLAGS := +LOCAL_LDFLAGS := + +LOCAL_SHARED_LIBRARIES := \ + libwrs_omxil_common \ + liblog \ + libva_videoencoder \ + libva \ + libva-android \ + libva-tpi \ + libutils \ + libsharedbuffer + +LOCAL_C_INCLUDES := \ + $(WRS_OMXIL_CORE_ROOT)/utils/inc \ + $(WRS_OMXIL_CORE_ROOT)/base/inc \ + $(WRS_OMXIL_CORE_ROOT)/core/inc/khronos/openmax/include \ + $(TARGET_OUT_HEADERS)/libmix_videoencoder \ + $(TARGET_OUT_HEADERS)/libva \ + $(TARGET_OUT_HEADERS)/libsharedbuffer + +LOCAL_SRC_FILES := \ + OMXComponentCodecBase.cpp \ + OMXVideoEncoderBase.cpp \ + OMXVideoEncoderAVC.cpp + +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := libOMXVideoEncoderAVC +include $(BUILD_SHARED_LIBRARY) + + +include $(CLEAR_VARS) + +LOCAL_CPPFLAGS := +LOCAL_LDFLAGS := + +LOCAL_SHARED_LIBRARIES := \ + libwrs_omxil_common \ + liblog \ + libva_videoencoder \ + libva \ + libva-android \ + libva-tpi \ + libutils \ + libsharedbuffer + +LOCAL_C_INCLUDES := \ + $(WRS_OMXIL_CORE_ROOT)/utils/inc \ + $(WRS_OMXIL_CORE_ROOT)/base/inc \ + $(WRS_OMXIL_CORE_ROOT)/core/inc/khronos/openmax/include \ + $(TARGET_OUT_HEADERS)/libmix_videoencoder \ + $(TARGET_OUT_HEADERS)/libva \ + $(TARGET_OUT_HEADERS)/libsharedbuffer + +LOCAL_SRC_FILES := \ + OMXComponentCodecBase.cpp \ + OMXVideoEncoderBase.cpp \ + OMXVideoEncoderH263.cpp + +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := libOMXVideoEncoderH263 +include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) + +LOCAL_CPPFLAGS := +LOCAL_LDFLAGS := + +LOCAL_SHARED_LIBRARIES := \ + libwrs_omxil_common \ + liblog \ + libva_videoencoder \ + libva \ + libva-android \ + libva-tpi \ + libutils \ + libsharedbuffer + +LOCAL_C_INCLUDES := \ + $(WRS_OMXIL_CORE_ROOT)/utils/inc \ + $(WRS_OMXIL_CORE_ROOT)/base/inc \ + $(WRS_OMXIL_CORE_ROOT)/core/inc/khronos/openmax/include \ + $(TARGET_OUT_HEADERS)/libmix_videoencoder \ + $(TARGET_OUT_HEADERS)/libva \ + $(TARGET_OUT_HEADERS)/libsharedbuffer + +LOCAL_SRC_FILES := \ + OMXComponentCodecBase.cpp \ + OMXVideoEncoderBase.cpp \ + OMXVideoEncoderMPEG4.cpp + +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE := libOMXVideoEncoderMPEG4 +include $(BUILD_SHARED_LIBRARY) endif diff --git a/videocodec/OMXComponentCodecBase.cpp b/videocodec/OMXComponentCodecBase.cpp index e119a5e..29a4beb 100644 --- a/videocodec/OMXComponentCodecBase.cpp +++ b/videocodec/OMXComponentCodecBase.cpp @@ -115,6 +115,8 @@ OMX_ERRORTYPE OMXComponentCodecBase::ComponentSetConfig( OMX_INDEXTYPE nIndex, OMX_PTR pComponentConfigStructure) { + OMX_ERRORTYPE ret = OMX_ErrorNone; + OMXHANDLER handler = FindHandler(nIndex, false); if (handler == NULL) { LOGE("ComponentSetConfig: No handler for index %d", nIndex); @@ -122,7 +124,10 @@ OMX_ERRORTYPE OMXComponentCodecBase::ComponentSetConfig( } LOGV("ComponentSetConfig: Index = 0x%x", nIndex); - return (*handler)(this, pComponentConfigStructure); + pthread_mutex_lock(&mSerializationLock); + ret = (*handler)(this, pComponentConfigStructure); + pthread_mutex_unlock(&mSerializationLock); + return ret; } OMX_ERRORTYPE OMXComponentCodecBase::ProcessorInit(void) { diff --git a/videocodec/OMXComponentDefines.h b/videocodec/OMXComponentDefines.h index 7ee9f57..e697d45 100644 --- a/videocodec/OMXComponentDefines.h +++ b/videocodec/OMXComponentDefines.h @@ -76,6 +76,30 @@ return OMX_ErrorNone;\ } +#define CHECK_BS_STATE() \ + if (mBsState == BS_STATE_EXECUTING) { \ + LOGE("Wrong state"); \ + return OMX_ErrorUndefined; \ + } + +#define CHECK_BS_STATUS(FUNC) \ + if (ret != BS_SUCCESS) { \ + LOGE(FUNC" Failed. ret = 0x%08x\n", ret); \ + return OMX_ErrorUndefined; \ + } + +#define CHECK_STATUS(FUNC) \ + if (ret != OMX_ErrorNone) { \ + LOGE(FUNC" Failed. ret = 0x%08x\n", ret); \ + return ret; \ + } + +#define CHECK_ENCODE_STATUS(FUNC)\ + if (ret < ENCODE_SUCCESS) { \ + LOGE(FUNC" Failed. ret = 0x%08x\n", ret); \ + return OMX_ErrorUndefined; \ + } + #define DECLARE_OMX_COMPONENT(NAME, ROLE, CLASS) \ static const char *gName = (const char *)(NAME);\ static const char *gRole = (const char *)(ROLE);\ diff --git a/videocodec/OMXVideoEncoderAVC.cpp b/videocodec/OMXVideoEncoderAVC.cpp index 3ba1cf2..4fd90de 100644 --- a/videocodec/OMXVideoEncoderAVC.cpp +++ b/videocodec/OMXVideoEncoderAVC.cpp @@ -15,21 +15,27 @@ */ -// #define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 #define LOG_TAG "OMXVideoEncoderAVC" #include <utils/Log.h> #include "OMXVideoEncoderAVC.h" -static const char* AVC_MIME_TYPE = "video/h264"; - +static const char *AVC_MIME_TYPE = "video/h264"; OMXVideoEncoderAVC::OMXVideoEncoderAVC() { - LOGV("OMXVideoEncoderAVC is constructed."); BuildHandlerList(); + mVideoEncoder = createVideoEncoder(AVC_MIME_TYPE); + if (!mVideoEncoder) LOGE("OMX_ErrorInsufficientResources"); + + mAVCParams = new VideoParamsAVC(); + if (!mAVCParams) LOGE("OMX_ErrorInsufficientResources"); } OMXVideoEncoderAVC::~OMXVideoEncoderAVC() { - LOGV("OMXVideoEncoderAVC is destructed."); + if(mAVCParams) { + delete mAVCParams; + mAVCParams = NULL; + } } OMX_ERRORTYPE OMXVideoEncoderAVC::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput) { @@ -52,7 +58,7 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEF SetTypeHeader(&mConfigAvcIntraPeriod, sizeof(mConfigAvcIntraPeriod)); mConfigAvcIntraPeriod.nPortIndex = OUTPORT_INDEX; // TODO: need to be populated from Video Encoder - mConfigAvcIntraPeriod.nIDRPeriod = 0; + mConfigAvcIntraPeriod.nIDRPeriod = 1; mConfigAvcIntraPeriod.nPFrames = 0; // OMX_VIDEO_CONFIG_NALSIZE @@ -62,33 +68,75 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEF mConfigNalSize.nNaluBytes = 0; // OMX_VIDEO_PARAM_INTEL_AVCVUI -#if 0 memset(&mParamIntelAvcVui, 0, sizeof(mParamIntelAvcVui)); SetTypeHeader(&mParamIntelAvcVui, sizeof(mParamIntelAvcVui)); mParamIntelAvcVui.nPortIndex = OUTPORT_INDEX; mParamIntelAvcVui.bVuiGeneration = OMX_FALSE; -#endif - // override OMX_PARAM_PORTDEFINITIONTYPE + // OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS + memset(&mConfigIntelSliceNumbers, 0, sizeof(mConfigIntelSliceNumbers)); + SetTypeHeader(&mConfigIntelSliceNumbers, sizeof(mConfigIntelSliceNumbers)); + mConfigIntelSliceNumbers.nPortIndex = OUTPORT_INDEX; + mConfigIntelSliceNumbers.nISliceNumber = 2; + mConfigIntelSliceNumbers.nPSliceNumber = 2; + + // Override OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput->nBufferCountActual = OUTPORT_ACTUAL_BUFFER_COUNT; paramPortDefinitionOutput->nBufferCountMin = OUTPORT_MIN_BUFFER_COUNT; paramPortDefinitionOutput->nBufferSize = OUTPORT_BUFFER_SIZE; paramPortDefinitionOutput->format.video.cMIMEType = (OMX_STRING)AVC_MIME_TYPE; paramPortDefinitionOutput->format.video.eCompressionFormat = OMX_VIDEO_CodingAVC; - // override OMX_VIDEO_PARAM_PROFILELEVELTYPE + // Override OMX_VIDEO_PARAM_PROFILELEVELTYPE // TODO: check if profile/level supported is correct mParamProfileLevel.eProfile = mParamAvc.eProfile; mParamProfileLevel.eLevel = mParamAvc.eLevel; - // override OMX_VIDEO_PARAM_BITRATETYPE + // Override OMX_VIDEO_PARAM_BITRATETYPE mParamBitrate.nTargetBitrate = 192000; + // Override OMX_VIDEO_CONFIG_INTEL_BITRATETYPE + mConfigIntelBitrate.nInitialQP = 24; // Initial QP for I frames + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::SetVideoEncoderParam(void) { + + Encode_Status ret = ENCODE_SUCCESS; + LOGV("OMXVideoEncoderAVC::SetVideoEncoderParam"); + + if (!mEncoderParams) { + LOGE("NULL pointer: mEncoderParams"); + return OMX_ErrorBadParameter; + } + + mVideoEncoder->getParameters(mEncoderParams); + mEncoderParams->profile = (VAProfile)VAProfileH264Baseline; + OMXVideoEncoderBase::SetVideoEncoderParam(); + + mVideoEncoder->getParameters(mAVCParams); + if(mParamIntelAvcVui.bVuiGeneration == OMX_TRUE) { + mAVCParams->VUIFlag = 1; + } + mAVCParams->sliceNum.iSliceNum = mConfigIntelSliceNumbers.nISliceNumber; + mAVCParams->sliceNum.pSliceNum = mConfigIntelSliceNumbers.nPSliceNumber; + mAVCParams->idrInterval = mConfigAvcIntraPeriod.nIDRPeriod; + mAVCParams->maxSliceSize = mConfigNalSize.nNaluBytes * 8; + ret = mVideoEncoder ->setParameters(mAVCParams); + CHECK_ENCODE_STATUS("setParameters"); + + LOGV("VUIFlag = %d\n", mAVCParams->VUIFlag); + LOGV("sliceNum.iSliceNum = %d\n", mAVCParams->sliceNum.iSliceNum); + LOGV("sliceNum.pSliceNum = %d\n", mAVCParams->sliceNum.pSliceNum); + LOGV("idrInterval = %d\n ", mAVCParams->idrInterval); + LOGV("maxSliceSize = %d\n ", mAVCParams->maxSliceSize); return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorInit(void) { - return OMXVideoEncoderBase::ProcessorInit(); + mFirstFrame = OMX_TRUE; + return OMXVideoEncoderBase::ProcessorInit(); } OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorDeinit(void) { @@ -96,11 +144,222 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorDeinit(void) { } OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorProcess( - OMX_BUFFERHEADERTYPE **buffers, - buffer_retain_t *retains, - OMX_U32 numberBuffers) { + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + OMX_U32 outfilledlen = 0; + OMX_S64 outtimestamp = 0; + OMX_U32 outflags = 0; + + OMX_ERRORTYPE oret = OMX_ErrorNone; + Encode_Status ret = ENCODE_SUCCESS; + + VideoEncOutputBuffer outBuf; + VideoEncRawBuffer inBuf; + + LOGV_IF(buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS, + "%s(),%d: got OMX_BUFFERFLAG_EOS\n", __func__, __LINE__); + + if (!buffers[INPORT_INDEX]->nFilledLen) { + LOGE("%s(),%d: input buffer's nFilledLen is zero\n", __func__, __LINE__); + goto out; + } + + if (mBsState != BS_STATE_INVALID) { + LOGV(" Share buffer mode\n"); + inBuf.size = mSharedBufArray[0].dataSize; + inBuf.data = + *(reinterpret_cast<uint8_t **>(buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset)); + } else { + inBuf.data = buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset; + inBuf.size = buffers[INPORT_INDEX]->nFilledLen; + } + + LOGV("inBuf.data=%x, size=%d",(unsigned)inBuf.data, inBuf.size); + + outBuf.data = buffers[OUTPORT_INDEX]->pBuffer + buffers[OUTPORT_INDEX]->nOffset; + outBuf.dataSize = 0; + outBuf.bufferSize = buffers[OUTPORT_INDEX]->nAllocLen - buffers[OUTPORT_INDEX]->nOffset; + + if(inBuf.size<=0) { + LOGE("The Input buf size is 0\n"); + return OMX_ErrorBadParameter; + } + + LOGV("in buffer = 0x%x ts = %lld", + buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset, + buffers[INPORT_INDEX]->nTimeStamp); + + if(mFrameRetrieved) { + // encode and setConfig need to be thread safe + pthread_mutex_lock(&mSerializationLock); + ret = mVideoEncoder->encode(&inBuf); + pthread_mutex_unlock(&mSerializationLock); + CHECK_ENCODE_STATUS("encode"); + mFrameRetrieved = OMX_FALSE; + + // This is for buffer contention, we won't release current buffer + // but the last input buffer + ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); + } + + switch (mNalStreamFormat.eNaluFormat) { + case OMX_NaluFormatStartCodes: + + outBuf.format = OUTPUT_EVERYTHING; + ret = mVideoEncoder->getOutput(&outBuf); + CHECK_ENCODE_STATUS("encode"); + + LOGV("output data size = %d", outBuf.dataSize); + outfilledlen = outBuf.dataSize; + outtimestamp = buffers[INPORT_INDEX]->nTimeStamp; + + + if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) { + outflags |= OMX_BUFFERFLAG_SYNCFRAME; + } + + if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) { + outflags |= OMX_BUFFERFLAG_ENDOFFRAME; + mFrameRetrieved = OMX_TRUE; + retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE; + + } else { + retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again + + } + + if (outfilledlen > 0) { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; + } else { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + } + + break; + case OMX_NaluFormatOneNaluPerBuffer: + + outBuf.format = OUTPUT_ONE_NAL; + ret = mVideoEncoder->getOutput(&outBuf); + CHECK_ENCODE_STATUS("getOutput"); + // Return code could not be ENCODE_BUFFER_TOO_SMALL + // If we don't return error, we will have dead lock issue + if (ret == ENCODE_BUFFER_TOO_SMALL) { + return OMX_ErrorUndefined; + } + + LOGV("output codec data size = %d", outBuf.dataSize); + + outfilledlen = outBuf.dataSize; + outtimestamp = buffers[INPORT_INDEX]->nTimeStamp; + + if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) { + outflags |= OMX_BUFFERFLAG_SYNCFRAME; + } + + if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) { + outflags |= OMX_BUFFERFLAG_ENDOFFRAME; + mFrameRetrieved = OMX_TRUE; + retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE; + + } else { + retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again + } + + if (outfilledlen > 0) { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; + } else { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + } + + break; + case OMX_NaluFormatStartCodesSeparateFirstHeader: + + if(mFirstFrame) { + LOGV("mFirstFrame\n"); + outBuf.format = OUTPUT_CODEC_DATA; + ret = mVideoEncoder->getOutput(&outBuf); + CHECK_ENCODE_STATUS("getOutput"); + // Return code could not be ENCODE_BUFFER_TOO_SMALL + // If we don't return error, we will have dead lock issue + if (ret == ENCODE_BUFFER_TOO_SMALL) { + return OMX_ErrorUndefined; + } + + LOGV("output codec data size = %d", outBuf.dataSize); + + outflags |= OMX_BUFFERFLAG_CODECCONFIG; + outflags |= OMX_BUFFERFLAG_ENDOFFRAME; + outflags |= OMX_BUFFERFLAG_SYNCFRAME; + + // This input buffer need to be gotten again + retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + outfilledlen = outBuf.dataSize; + mFirstFrame = OMX_FALSE; + } else { + outBuf.format = OUTPUT_EVERYTHING; + mVideoEncoder->getOutput(&outBuf); + CHECK_ENCODE_STATUS("getOutput"); + + LOGV("output data size = %d", outBuf.dataSize); + + + outfilledlen = outBuf.dataSize; + outtimestamp = buffers[INPORT_INDEX]->nTimeStamp; + + if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) { + outflags |= OMX_BUFFERFLAG_SYNCFRAME; + } + if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) { + LOGV("Get buffer done\n"); + outflags |= OMX_BUFFERFLAG_ENDOFFRAME; + mFrameRetrieved = OMX_TRUE; + retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE; + + } else { + retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again + + } + + } + + if (outfilledlen > 0) { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; + } else { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + } + + break; + } + + +out: + LOGV("output buffers = %p:%d, flag = %x", buffers[OUTPORT_INDEX]->pBuffer, outfilledlen, outflags); + + if(retains[OUTPORT_INDEX] != BUFFER_RETAIN_GETAGAIN) { + buffers[OUTPORT_INDEX]->nFilledLen = outfilledlen; + buffers[OUTPORT_INDEX]->nTimeStamp = outtimestamp; + buffers[OUTPORT_INDEX]->nFlags = outflags; + } + + if (retains[INPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN || + retains[INPORT_INDEX] == BUFFER_RETAIN_ACCUMULATE ) { + mFrameInputCount ++; + } + + if (retains[OUTPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN) mFrameOutputCount ++; + +#if 0 + if (avcEncParamIntelBitrateType.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) { + if (oret == (OMX_ERRORTYPE) OMX_ErrorIntelExtSliceSizeOverflow) { + oret = OMX_ErrorNone; + } + } +#endif + LOGV_IF(oret == OMX_ErrorNone, "%s(),%d: exit, encode is done\n", __func__, __LINE__); + + return oret; - return OMXVideoEncoderBase::ProcessorProcess(buffers, retains, numberBuffers); } OMX_ERRORTYPE OMXVideoEncoderAVC::BuildHandlerList(void) { @@ -111,7 +370,8 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::BuildHandlerList(void) { AddHandler((OMX_INDEXTYPE)OMX_IndexParamNalStreamFormatSelect, GetParamNalStreamFormatSelect, SetParamNalStreamFormatSelect); AddHandler(OMX_IndexConfigVideoAVCIntraPeriod, GetConfigVideoAVCIntraPeriod, SetConfigVideoAVCIntraPeriod); AddHandler(OMX_IndexConfigVideoNalSize, GetConfigVideoNalSize, SetConfigVideoNalSize); - //AddHandler(OMX_IndexParamIntelAVCVUI, GetParamIntelAVCVUI, SetParamIntelAVCVUI); + AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelSliceNumbers, GetConfigIntelSliceNumbers, SetConfigIntelSliceNumbers); + AddHandler((OMX_INDEXTYPE)OMX_IndexParamIntelAVCVUI, GetParamIntelAVCVUI, SetParamIntelAVCVUI); AddHandler((OMX_INDEXTYPE)OMX_IndexParamVideoBytestream, GetParamVideoBytestream, SetParamVideoBytestream); return OMX_ErrorNone; } @@ -146,13 +406,26 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormat(OMX_PTR pStructure) { CHECK_TYPE_HEADER(p); CHECK_PORT_INDEX(p, OUTPORT_INDEX); // TODO: check if this is desired format - p->eNaluFormat = OMX_NaluFormatStartCodesSeparateFirstHeader; //OMX_NaluFormatStartCodes; + p->eNaluFormat = mNalStreamFormat.eNaluFormat; //OMX_NaluFormatStartCodes; return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamNalStreamFormat(OMX_PTR pStructure) { - LOGW("SetParamNalStreamFormat is not supported."); - return OMX_ErrorUnsupportedSetting; + OMX_ERRORTYPE ret; + OMX_NALSTREAMFORMATTYPE *p = (OMX_NALSTREAMFORMATTYPE *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + LOGV("p->eNaluFormat =%d\n",p->eNaluFormat); + if(p->eNaluFormat != OMX_NaluFormatStartCodes && + p->eNaluFormat != OMX_NaluFormatStartCodesSeparateFirstHeader && + p->eNaluFormat != OMX_NaluFormatOneNaluPerBuffer) { + LOGE("Format not support\n"); + return OMX_ErrorUnsupportedSetting; + } + mNalStreamFormat.eNaluFormat = p->eNaluFormat; + return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormatSupported(OMX_PTR pStructure) { @@ -162,12 +435,13 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamNalStreamFormatSupported(OMX_PTR pStru CHECK_TYPE_HEADER(p); CHECK_PORT_INDEX(p, OUTPORT_INDEX); p->eNaluFormat = (OMX_NALUFORMATSTYPE) - (OMX_NaluFormatStartCodes | - OMX_NaluFormatStartCodesSeparateFirstHeader); + (OMX_NaluFormatStartCodes | + OMX_NaluFormatStartCodesSeparateFirstHeader | + OMX_NaluFormatOneNaluPerBuffer); // TODO: check if this is desired format - // OMX_NaluFormatFourByteInterleaveLength | - //OMX_NaluFormatZeroByteInterleaveLength); + // OMX_NaluFormatFourByteInterleaveLength | + //OMX_NaluFormatZeroByteInterleaveLength); return OMX_ErrorNone; } @@ -191,7 +465,8 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamNalStreamFormatSelect(OMX_PTR pStructu CHECK_SET_PARAM_STATE(); if (p->eNaluFormat != OMX_NaluFormatStartCodes && - p->eNaluFormat != OMX_NaluFormatStartCodesSeparateFirstHeader) { + p->eNaluFormat != OMX_NaluFormatStartCodesSeparateFirstHeader && + p->eNaluFormat != OMX_NaluFormatOneNaluPerBuffer) { //p->eNaluFormat != OMX_NaluFormatFourByteInterleaveLength && //p->eNaluFormat != OMX_NaluFormatZeroByteInterleaveLength) { // TODO: check if this is desried @@ -216,6 +491,7 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::GetConfigVideoAVCIntraPeriod(OMX_PTR pStructur OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigVideoAVCIntraPeriod(OMX_PTR pStructure) { OMX_ERRORTYPE ret; + Encode_Status retStatus = ENCODE_SUCCESS; OMX_VIDEO_CONFIG_AVCINTRAPERIOD *p = (OMX_VIDEO_CONFIG_AVCINTRAPERIOD *)pStructure; CHECK_TYPE_HEADER(p); CHECK_PORT_INDEX(p, OUTPORT_INDEX); @@ -228,6 +504,13 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigVideoAVCIntraPeriod(OMX_PTR pStructur CHECK_SET_CONFIG_STATE(); // TODO: apply AVC Intra Period configuration in Executing state + VideoConfigAVCIntraPeriod avcIntraPreriod; + avcIntraPreriod.idrInterval = mConfigAvcIntraPeriod.nIDRPeriod; + avcIntraPreriod.intraPeriod = mConfigAvcIntraPeriod.nPFrames; + retStatus = mVideoEncoder->setConfig(&avcIntraPreriod); + if(retStatus != ENCODE_SUCCESS) { + LOGW("set avc intra prerod config failed"); + } return OMX_ErrorNone; } @@ -243,6 +526,7 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::GetConfigVideoNalSize(OMX_PTR pStructure) { OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigVideoNalSize(OMX_PTR pStructure) { OMX_ERRORTYPE ret; + Encode_Status retStatus = ENCODE_SUCCESS; if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { LOGE("SetConfigVideoNalSize failed. Feature is disabled."); return OMX_ErrorUnsupportedIndex; @@ -262,25 +546,71 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigVideoNalSize(OMX_PTR pStructure) { LOGE("SetConfigVideoNalSize failed. Feature is supported only in VCM."); return OMX_ErrorUnsupportedSetting; } - // TODO: apply NAL Size configuration in Executing state + VideoConfigNALSize configNalSize; + configNalSize.maxSliceSize = mConfigNalSize.nNaluBytes * 8; + retStatus = mVideoEncoder->setConfig(&configNalSize); + if(retStatus != ENCODE_SUCCESS) { + LOGW("set NAL size config failed"); + } return OMX_ErrorNone; } +OMX_ERRORTYPE OMXVideoEncoderAVC::GetConfigIntelSliceNumbers(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *p = (OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *)pStructure; + + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + memcpy(p, &mConfigIntelSliceNumbers, sizeof(*p)); + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigIntelSliceNumbers(OMX_PTR pStructure) { + OMX_ERRORTYPE ret; + Encode_Status retStatus = ENCODE_SUCCESS; + if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { + LOGE("SetConfigIntelSliceNumbers failed. Feature is disabled."); + return OMX_ErrorUnsupportedIndex; + } + OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *p = (OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *)pStructure; + CHECK_TYPE_HEADER(p); + CHECK_PORT_INDEX(p, OUTPORT_INDEX); + + // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) + mConfigIntelSliceNumbers = *p; + + // return OMX_ErrorNone if not in Executing state + // TODO: return OMX_ErrorIncorrectStateOperation? + CHECK_SET_CONFIG_STATE(); + + if (mParamIntelBitrate.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) { + LOGE("SetConfigIntelSliceNumbers failed. Feature is supported only in VCM."); + return OMX_ErrorUnsupportedSetting; + } + VideoConfigSliceNum sliceNum; + sliceNum.sliceNum.iSliceNum = mConfigIntelSliceNumbers.nISliceNumber; + sliceNum.sliceNum.pSliceNum = mConfigIntelSliceNumbers.nPSliceNumber; + retStatus = mVideoEncoder->setConfig(&sliceNum); + if(retStatus != ENCODE_SUCCESS) { + LOGW("set silce num config failed!\n"); + } + return OMX_ErrorNone; +} OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamIntelAVCVUI(OMX_PTR pStructure) { -#if 0 + OMX_ERRORTYPE ret; OMX_VIDEO_PARAM_INTEL_AVCVUI *p = (OMX_VIDEO_PARAM_INTEL_AVCVUI *)pStructure; CHECK_TYPE_HEADER(p); CHECK_PORT_INDEX(p, OUTPORT_INDEX); - memcpy(p, mParamIntelAvcVui, sizeof(*p)); -#endif + memcpy(p, &mParamIntelAvcVui, sizeof(*p)); + return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamIntelAVCVUI(OMX_PTR pStructure) { -#if 0 + OMX_ERRORTYPE ret; OMX_VIDEO_PARAM_INTEL_AVCVUI *p = (OMX_VIDEO_PARAM_INTEL_AVCVUI *)pStructure; CHECK_TYPE_HEADER(p); @@ -290,7 +620,6 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamIntelAVCVUI(OMX_PTR pStructure) { CHECK_SET_PARAM_STATE(); mParamIntelAvcVui = *p; -#endif return OMX_ErrorNone; } diff --git a/videocodec/OMXVideoEncoderAVC.h b/videocodec/OMXVideoEncoderAVC.h index 509f604..e0de2f2 100644 --- a/videocodec/OMXVideoEncoderAVC.h +++ b/videocodec/OMXVideoEncoderAVC.h @@ -35,16 +35,17 @@ protected: buffer_retain_t *retains, OMX_U32 numberBuffers); - virtual OMX_ERRORTYPE BuildHandlerList(void); - - DECLARE_HANDLER(OMXVideoEncoderAVC, ParamVideoAvc); - DECLARE_HANDLER(OMXVideoEncoderAVC, ParamNalStreamFormat); - DECLARE_HANDLER(OMXVideoEncoderAVC, ParamNalStreamFormatSupported); - DECLARE_HANDLER(OMXVideoEncoderAVC, ParamNalStreamFormatSelect); - DECLARE_HANDLER(OMXVideoEncoderAVC, ConfigVideoAVCIntraPeriod); - DECLARE_HANDLER(OMXVideoEncoderAVC, ConfigVideoNalSize); - DECLARE_HANDLER(OMXVideoEncoderAVC, ParamIntelAVCVUI); - DECLARE_HANDLER(OMXVideoEncoderAVC, ParamVideoBytestream); + virtual OMX_ERRORTYPE BuildHandlerList(void); + virtual OMX_ERRORTYPE SetVideoEncoderParam(); + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamVideoAvc); + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamNalStreamFormat); + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamNalStreamFormatSupported); + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamNalStreamFormatSelect); + DECLARE_HANDLER(OMXVideoEncoderAVC, ConfigVideoAVCIntraPeriod); + DECLARE_HANDLER(OMXVideoEncoderAVC, ConfigVideoNalSize); + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamIntelAVCVUI); + DECLARE_HANDLER(OMXVideoEncoderAVC, ParamVideoBytestream); + DECLARE_HANDLER(OMXVideoEncoderAVC, ConfigIntelSliceNumbers); private: @@ -53,7 +54,6 @@ private: OUTPORT_MIN_BUFFER_COUNT = 1, OUTPORT_ACTUAL_BUFFER_COUNT = 10, OUTPORT_BUFFER_SIZE = 1382400, - // for OMX_VIDEO_PARAM_INTEL_AVC_DECODE_SETTINGS NUM_REFERENCE_FRAME = 4, }; @@ -61,7 +61,10 @@ private: OMX_NALSTREAMFORMATTYPE mNalStreamFormat; OMX_VIDEO_CONFIG_AVCINTRAPERIOD mConfigAvcIntraPeriod; OMX_VIDEO_CONFIG_NALSIZE mConfigNalSize; - //OMX_VIDEO_PARAM_INTEL_AVCVUI mParamIntelAvcVui; + OMX_VIDEO_PARAM_INTEL_BITRATETYPE avcEncParamIntelBitrateType; + OMX_VIDEO_PARAM_INTEL_AVCVUI mParamIntelAvcVui; + OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS mConfigIntelSliceNumbers; + VideoParamsAVC *mAVCParams; }; #endif /* OMX_VIDEO_ENCODER_AVC_H_ */ diff --git a/videocodec/OMXVideoEncoderBase.cpp b/videocodec/OMXVideoEncoderBase.cpp index 4535b4a..c30ee0a 100644 --- a/videocodec/OMXVideoEncoderBase.cpp +++ b/videocodec/OMXVideoEncoderBase.cpp @@ -20,12 +20,31 @@ #include <utils/Log.h> #include "OMXVideoEncoderBase.h" -static const char* RAW_MIME_TYPE = "video/raw"; - -OMXVideoEncoderBase::OMXVideoEncoderBase() { +static const char *RAW_MIME_TYPE = "video/raw"; + +OMXVideoEncoderBase::OMXVideoEncoderBase() + :mVideoEncoder(NULL) + ,mEncoderParams(NULL) + ,mFrameInputCount(0) + ,mFrameOutputCount(0) + ,mPFrames(0) + ,mFrameRetrieved(OMX_TRUE) + ,mFirstFrame(OMX_TRUE) { + + mEncoderParams = new VideoParamsCommon(); + if (!mEncoderParams) LOGE("OMX_ErrorInsufficientResources"); + + mBsState = BS_STATE_INVALID; + OMX_ERRORTYPE ret = InitBSMode(); + if(ret != OMX_ErrorNone) { + LOGE("InitBSMode failed in Constructor "); + DeinitBSMode(); + } } OMXVideoEncoderBase::~OMXVideoEncoderBase() { + + // destroy ports if (this->ports) { if (this->ports[INPORT_INDEX]) { delete this->ports[INPORT_INDEX]; @@ -37,6 +56,22 @@ OMXVideoEncoderBase::~OMXVideoEncoderBase() { this->ports[OUTPORT_INDEX] = NULL; } } + + // Release video encoder object + if(mVideoEncoder) { + releaseVideoEncoder(mVideoEncoder); + mVideoEncoder = NULL; + } + + if(mEncoderParams) { + delete mEncoderParams; + mEncoderParams = NULL; + } + + OMX_ERRORTYPE oret = DeinitBSMode(); + if (oret != OMX_ErrorNone) { + LOGE("DeinitBSMode in destructor"); + } } OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPort(void) { @@ -130,16 +165,9 @@ OMX_ERRORTYPE OMXVideoEncoderBase::InitOutputPort(void) { mConfigIntelBitrate.nPortIndex = OUTPORT_INDEX; mConfigIntelBitrate.nMaxEncodeBitrate = 4000 * 1024; // Maximum bitrate mConfigIntelBitrate.nTargetPercentage = 95; // Target bitrate as percentage of maximum bitrate; e.g. 95 is 95% - mConfigIntelBitrate.nWindowSize = 1000; // Window size in milliseconds allowed for bitrate to reach target - mConfigIntelBitrate.nInitialQP = 36; // Initial QP for I frames - mConfigIntelBitrate.nMinQP = 18; - - // OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS - memset(&mConfigIntelSliceNumbers, 0, sizeof(mConfigIntelSliceNumbers)); - SetTypeHeader(&mConfigIntelSliceNumbers, sizeof(mConfigIntelSliceNumbers)); - mConfigIntelSliceNumbers.nPortIndex = OUTPORT_INDEX; - mConfigIntelSliceNumbers.nISliceNumber = 1; - mConfigIntelSliceNumbers.nPSliceNumber = 1; + mConfigIntelBitrate.nWindowSize = 500; // Window size in milliseconds allowed for bitrate to reach target + mConfigIntelBitrate.nInitialQP = 24; // Initial QP for I frames + mConfigIntelBitrate.nMinQP = 1; // OMX_VIDEO_CONFIG_INTEL_AIR memset(&mConfigIntelAir, 0, sizeof(mConfigIntelAir)); @@ -156,7 +184,6 @@ OMX_ERRORTYPE OMXVideoEncoderBase::InitOutputPort(void) { mConfigFramerate.nPortIndex = OUTPORT_INDEX; mConfigFramerate.xEncodeFramerate = 0; // Q16 format -#if 0 // OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL memset(&mParamIntelAdaptiveSliceControl, 0, sizeof(mParamIntelAdaptiveSliceControl)); SetTypeHeader(&mParamIntelAdaptiveSliceControl, sizeof(mParamIntelAdaptiveSliceControl)); @@ -165,7 +192,6 @@ OMX_ERRORTYPE OMXVideoEncoderBase::InitOutputPort(void) { mParamIntelAdaptiveSliceControl.nMinPSliceNumber = 5; mParamIntelAdaptiveSliceControl.nNumPFramesToSkip = 8; mParamIntelAdaptiveSliceControl.nSliceSizeThreshold = 1200; -#endif // OMX_VIDEO_PARAM_PROFILELEVELTYPE memset(&mParamProfileLevel, 0, sizeof(mParamProfileLevel)); @@ -174,7 +200,6 @@ OMX_ERRORTYPE OMXVideoEncoderBase::InitOutputPort(void) { mParamProfileLevel.eProfile = 0; // undefined profile, to be overridden mParamProfileLevel.eLevel = 0; // undefined level, to be overridden - // OMX_PARAM_PORTDEFINITIONTYPE OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionOutput; memset(¶mPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput)); @@ -205,6 +230,7 @@ OMX_ERRORTYPE OMXVideoEncoderBase::InitOutputPort(void) { InitOutputPortFormatSpecific(¶mPortDefinitionOutput); port->SetPortDefinition(¶mPortDefinitionOutput, true); + port->SetPortBitrateParam(&mParamBitrate, true); // OMX_VIDEO_PARAM_PORTFORMATTYPE OMX_VIDEO_PARAM_PORTFORMATTYPE paramPortFormat; @@ -225,127 +251,362 @@ OMX_ERRORTYPE OMXVideoEncoderBase::InitInputPortFormatSpecific(OMX_PARAM_PORTDEF return OMX_ErrorNone; } +OMX_ERRORTYPE OMXVideoEncoderBase::SetVideoEncoderParam() { + + Encode_Status ret = ENCODE_SUCCESS; + PortVideo *port_in = NULL; + PortVideo *port_out = NULL; + OMX_VIDEO_CONTROLRATETYPE controlrate; + const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionInput = NULL; + LOGV("OMXVideoEncoderBase::SetVideoEncoderParam called\n"); + + port_in = static_cast<PortVideo *>(ports[INPORT_INDEX]); + port_out = static_cast<PortVideo *>(ports[OUTPORT_INDEX]); + paramPortDefinitionInput = port_in->GetPortDefinition(); + mEncoderParams->resolution.height = paramPortDefinitionInput->format.video.nFrameHeight; + mEncoderParams->resolution.width = paramPortDefinitionInput->format.video.nFrameWidth; + const OMX_VIDEO_PARAM_BITRATETYPE *bitrate = port_out->GetPortBitrateParam(); + + mEncoderParams->frameRate.frameRateDenom = 1; + if(mConfigFramerate.xEncodeFramerate != 0) { + mEncoderParams->frameRate.frameRateNum = mConfigFramerate.xEncodeFramerate; + } else { + mEncoderParams->frameRate.frameRateNum = paramPortDefinitionInput->format.video.xFramerate >> 16; + mConfigFramerate.xEncodeFramerate = paramPortDefinitionInput->format.video.xFramerate >> 16; + } + + if(mPFrames == 0) { + mPFrames = mEncoderParams->frameRate.frameRateNum / 2; + } + mEncoderParams->intraPeriod = mPFrames; + mEncoderParams->rawFormat = RAW_FORMAT_NV12; + + LOGV("frameRate.frameRateDenom = %d\n", mEncoderParams->frameRate.frameRateDenom); + LOGV("frameRate.frameRateNum = %d\n", mEncoderParams->frameRate.frameRateNum); + LOGV("intraPeriod = %d\n ", mEncoderParams->intraPeriod); + mEncoderParams->rcParams.initQP = mConfigIntelBitrate.nInitialQP; + mEncoderParams->rcParams.minQP = mConfigIntelBitrate.nMinQP; + mEncoderParams->rcParams.windowSize = mConfigIntelBitrate.nWindowSize; + mEncoderParams->rcParams.targetPercentage = mConfigIntelBitrate.nTargetPercentage; + + if(mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { + + mEncoderParams->rcParams.bitRate = mParamBitrate.nTargetBitrate;//bitrate->nTargetBitrate; + LOGV("rcParams.bitRate = %d\n", mEncoderParams->rcParams.bitRate); + + if (mEncoderParams->rcMode == RATE_CONTROL_CBR) { + controlrate = OMX_Video_ControlRateConstant; + } else if (mEncoderParams->rcMode == RATE_CONTROL_VBR) { + controlrate = OMX_Video_ControlRateVariable; + } else { + controlrate = OMX_Video_ControlRateDisable; + } + + if (controlrate != bitrate->eControlRate) { + + if ((bitrate->eControlRate == OMX_Video_ControlRateVariable) || + (bitrate->eControlRate == OMX_Video_ControlRateVariableSkipFrames)) { + mEncoderParams->rcMode = RATE_CONTROL_VBR; + } else if ((bitrate->eControlRate == OMX_Video_ControlRateConstant) || + (bitrate->eControlRate == OMX_Video_ControlRateConstantSkipFrames)) { + mEncoderParams->rcMode = RATE_CONTROL_CBR; + } else { + mEncoderParams->rcMode = RATE_CONTROL_NONE; + } + LOGV("rcMode = %d\n", mEncoderParams->rcMode); + } + } else { + mEncoderParams->rcMode = RATE_CONTROL_VCM; + if(mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateConstant || + mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateVariable) { + LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateConstant || OMX_Video_Intel_ControlRateVariable", __func__); + mEncoderParams->rcParams.bitRate = mParamIntelBitrate.nTargetBitrate; + } else if(mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateVideoConferencingMode) { + LOGV("%s(), eControlRate == OMX_Video_Intel_ControlRateVideoConferencingMode ", __func__); + mEncoderParams->rcParams.bitRate = mConfigIntelBitrate.nMaxEncodeBitrate; + if(mConfigIntelAir.bAirEnable == OMX_TRUE) { + mEncoderParams->airParams.airAuto = mConfigIntelAir.bAirAuto; + mEncoderParams->airParams.airMBs = mConfigIntelAir.nAirMBs; + mEncoderParams->airParams.airThreshold = mConfigIntelAir.nAirThreshold; + mEncoderParams->refreshType = VIDEO_ENC_AIR; + } else { + mEncoderParams->refreshType = VIDEO_ENC_NONIR; + } + LOGV("refreshType = %d\n", mEncoderParams->refreshType); + } + } + + ret = mVideoEncoder->setParameters(mEncoderParams); + CHECK_ENCODE_STATUS("setParameters"); + return OMX_ErrorNone; +} + OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorInit(void) { - OMX_ERRORTYPE ret; - ret = OMXComponentCodecBase::ProcessorInit(); - CHECK_RETURN_VALUE("OMXComponentCodecBase::ProcessorInit"); + OMX_ERRORTYPE ret = OMX_ErrorNone; + ret = SetVideoEncoderParam(); + CHECK_STATUS("SetVideoEncoderParam"); + + ret = StartBufferSharing(); + CHECK_STATUS("StartBufferSharing"); + + if (mVideoEncoder->start() != ENCODE_SUCCESS) { + LOGE("Start failed, ret = 0x%08x\n", ret); + return OMX_ErrorUndefined; + } return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorDeinit(void) { OMX_ERRORTYPE ret; - return OMXComponentCodecBase::ProcessorDeinit(); + if (mBsState == BS_STATE_EXECUTING) { + ret = StopBufferSharing(); + if (ret != OMX_ErrorNone) { + LOGE("StopBufferSharing failed, ret = 0x%08x\n", ret); + } + } + + if(mVideoEncoder) { + mVideoEncoder->stop(); + } + return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorStop(void) { - OMX_ERRORTYPE ret; + this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); - return OMXComponentCodecBase::ProcessorStop(); + return OMX_ErrorNone; +} +OMX_ERRORTYPE OMXVideoEncoderBase:: ProcessorProcess( + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + LOGV("OMXVideoEncoderBase:: ProcessorProcess \n"); + return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorFlush(OMX_U32 portIndex) { + LOGV("OMXVideoEncoderBase::ProcessorFlush\n"); if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) { this->ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); + mVideoEncoder->flush(); + } + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::AllocateSharedBuffers(int width, int height) { + + int index = 0; + int bufSize = 0; + Encode_Status ret = ENCODE_SUCCESS; + + if (width <= 0 || height <= 0) { + LOGE("width <= 0 || height <= 0"); + return OMX_ErrorBadParameter; + } + + CHECK_BS_STATE(); + + if (mBsState == BS_STATE_INVALID) { + LOGW("buffer sharing not enabled, do nothing"); + return OMX_ErrorNone; + } + + if (mSharedBufArray != NULL) { + delete [] mSharedBufArray; + mSharedBufArray = NULL; + } + + mSharedBufArray = new SharedBufferType[mSharedBufCnt]; + VideoParamsUsrptrBuffer paramsUsrptrBuffer; + + bufSize = SHARE_PTR_ALIGN(width) * height * 3 / 2; + + for (index = 0; index < mSharedBufCnt; index++) { + + paramsUsrptrBuffer.type = VideoParamsTypeUsrptrBuffer; + paramsUsrptrBuffer.size = sizeof(VideoParamsUsrptrBuffer); + paramsUsrptrBuffer.expectedSize = bufSize; + paramsUsrptrBuffer.format = STRING_TO_FOURCC("NV12"); + paramsUsrptrBuffer.width = width; + paramsUsrptrBuffer.height = height; + + mVideoEncoder->getParameters(¶msUsrptrBuffer); + if (ret != ENCODE_SUCCESS) { + LOGE("Get usrptr failed"); + if (mSharedBufArray) { + delete []mSharedBufArray; + mSharedBufArray = NULL; + } + return OMX_ErrorUndefined; + } + + mSharedBufArray[index].pointer = paramsUsrptrBuffer.usrPtr; + mSharedBufArray[index].stride = paramsUsrptrBuffer.stride; + mSharedBufArray[index].allocatedSize = paramsUsrptrBuffer.actualSize; + mSharedBufArray[index].width = width; + mSharedBufArray[index].height = height; + mSharedBufArray[index].dataSize = mSharedBufArray[index].stride * height * 3 / 2; + + LOGV("width:%d, Height:%d, stride:%d, pointer:%p", mSharedBufArray[index].width, + mSharedBufArray[index].height, mSharedBufArray[index].stride, + mSharedBufArray[index].pointer); } return OMX_ErrorNone; } -OMX_ERRORTYPE OMXVideoEncoderBase::ProcessorProcess( - OMX_BUFFERHEADERTYPE **buffers, - buffer_retain_t *retains, - OMX_U32 numberBuffers) { +OMX_ERRORTYPE OMXVideoEncoderBase::UploadSharedBuffers() { + CHECK_BS_STATE(); - return OMX_ErrorNotImplemented; + if (mBsState == BS_STATE_INVALID) { + LOGW("buffer sharing not enabled, do nothing."); + return OMX_ErrorNone; + } + + BufferShareStatus ret = mBsInstance->encoderSetSharedBuffer(mSharedBufArray, mSharedBufCnt); + CHECK_BS_STATUS ("encoderSetSharedBuffer"); + + return OMX_ErrorNone; } -OMX_ERRORTYPE OMXVideoEncoderBase::EnableBufferSharing(void) -{ - BufferShareStatus ret; +OMX_ERRORTYPE OMXVideoEncoderBase::SetBSInfoToPort() { + CHECK_BS_STATE(); - if (mBufferSharingState != BUFFER_SHARING_INVALID) { - LOGE("EnableBufferSharing: Invalid buffer sharing state: %d", mBufferSharingState); - return OMX_ErrorUndefined; + OMX_VIDEO_CONFIG_PRI_INFOTYPE privateinfoparam; + memset(&privateinfoparam, 0, sizeof(privateinfoparam)); + SetTypeHeader(&privateinfoparam, sizeof(privateinfoparam)); + + //caution: buffer-sharing info stored in INPORT (raw port) + privateinfoparam.nPortIndex = INPORT_INDEX; + if (mBsState == BS_STATE_INVALID) { + privateinfoparam.nCapacity = 0; + privateinfoparam.nHolder = NULL; + } else { + privateinfoparam.nCapacity = mSharedBufCnt; + privateinfoparam.nHolder = mSharedBufArray; + } + OMX_ERRORTYPE ret = static_cast<PortVideo *>(ports[privateinfoparam.nPortIndex])->SetPortPrivateInfoParam(&privateinfoparam, false); + + return ret; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::TriggerBSMode() { + CHECK_BS_STATE(); + + if (mBsState == BS_STATE_INVALID) { + LOGW("buffer sharing not enabled."); + return OMX_ErrorNone; } - mBufferSharingCount = 4; - mBufferSharingInfo = NULL; - mBufferSharingLib = BufferShareRegistry::getInstance(); + BufferShareStatus ret = mBsInstance->encoderEnterSharingMode(); + if (ret == BS_PEER_DOWN) { + LOGE("upstream component down during buffer sharing state transition."); + } + CHECK_BS_STATUS ("encoderEnterSharingMode"); - ret = mBufferSharingLib->encoderRequestToEnableSharingMode(); - if (ret != BS_SUCCESS) { - LOGE("encoderRequestToEnableSharingMode failed. Error = %d", ret); + mBsState = BS_STATE_EXECUTING; + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::CheckAndEnableBSMode() { + BufferShareStatus bsret; + + if (mBsState != BS_STATE_INVALID) { + LOGE("failed (incorrect state)."); return OMX_ErrorUndefined; } + if (mBsInstance->isBufferSharingModeEnabled()) { + LOGV("Buffer sharing is enabled"); + mBsState = BS_STATE_LOADED; + } else { + LOGV("Buffer sharing is disabled"); + mBsState = BS_STATE_INVALID; + } + return OMX_ErrorNone; } -OMX_ERRORTYPE OMXVideoEncoderBase::DisableBufferSharing(void) -{ + +OMX_ERRORTYPE OMXVideoEncoderBase::InitBSMode(void) { BufferShareStatus ret; - if ((mBufferSharingState != BUFFER_SHARING_INVALID) && - (mBufferSharingState != BUFFER_SHARING_LOADED)) { - LOGE("DisableBufferSharing: Invalid buffer sharing state: %d", mBufferSharingState); + if (mBsState != BS_STATE_INVALID) { + LOGE("InitBSMode: Invalid buffer sharing state: %d", mBsState); return OMX_ErrorUndefined; } - if (mBufferSharingState == BUFFER_SHARING_INVALID) { + mSharedBufCnt = SHARED_BUFFER_CNT; + mSharedBufArray = NULL; + mBsInstance = BufferShareRegistry::getInstance(); + + ret = mBsInstance->encoderRequestToEnableSharingMode(); + CHECK_BS_STATUS ("encoderRequestToEnableSharingMode"); + + return OMX_ErrorNone; +} + +OMX_ERRORTYPE OMXVideoEncoderBase::DeinitBSMode(void) { + BufferShareStatus ret; + + CHECK_BS_STATE(); + + if (mBsState == BS_STATE_INVALID) { return OMX_ErrorNone; } - if (mBufferSharingInfo) { - delete [] mBufferSharingInfo; + if (mBsState) { + delete [] mSharedBufArray; + mSharedBufArray = NULL; } - mBufferSharingInfo = NULL; - ret = mBufferSharingLib->encoderRequestToDisableSharingMode(); - if (ret != BS_SUCCESS) { - LOGE("encoderRequestToDisableSharingMode failed. Error = %d", ret); - return OMX_ErrorUndefined; - } + ret = mBsInstance->encoderRequestToDisableSharingMode(); + CHECK_BS_STATUS ("encoderRequestToDisableSharingMode"); - mBufferSharingState = BUFFER_SHARING_INVALID; + + mBsState = BS_STATE_INVALID; return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoEncoderBase::StartBufferSharing(void) { // TODO: consolidate the following APIs - /* - CheckAndEnableBufferSharingMode - RequestShareBuffers - RegisterShareBuffersToPort - RegisterShareBuffersToLib - EnterBufferSharingMode - */ + OMX_ERRORTYPE ret = OMX_ErrorNone; + + ret = CheckAndEnableBSMode(); + CHECK_STATUS("CheckAndEnableBSMode"); + + ret = AllocateSharedBuffers(mEncoderParams->resolution.width, mEncoderParams->resolution.height); + CHECK_STATUS("AllocateSharedBuffers"); + + ret = SetBSInfoToPort(); + CHECK_STATUS("SetBSInfoToPort"); + + ret = UploadSharedBuffers(); + CHECK_STATUS("UploadSharedBuffers"); + + ret = TriggerBSMode(); + CHECK_STATUS("UploadSharedBuffers"); + return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoEncoderBase::StopBufferSharing(void) { - if ((mBufferSharingState != BUFFER_SHARING_INVALID) && - (mBufferSharingState != BUFFER_SHARING_EXECUTING)) { - LOGE("StopBufferSharing: Invalid buffer sharing state: %d", mBufferSharingState); - return OMX_ErrorUndefined; - } - if (mBufferSharingState == BUFFER_SHARING_INVALID) { + if (mBsState == BS_STATE_INVALID) { return OMX_ErrorNone; } - BufferShareStatus ret = mBufferSharingLib->encoderExitSharingMode(); - if (ret != BS_SUCCESS) { - LOGE("encoderExitSharingMode failed. Error = %d", ret); - return OMX_ErrorUndefined; - } + BufferShareStatus ret = mBsInstance->encoderExitSharingMode(); + CHECK_BS_STATUS ("encoderExitSharingMode"); + - mBufferSharingState = BUFFER_SHARING_LOADED; + mBsState = BS_STATE_LOADED; return OMX_ErrorNone; } - OMX_ERRORTYPE OMXVideoEncoderBase::BuildHandlerList(void) { OMXComponentCodecBase::BuildHandlerList(); AddHandler(OMX_IndexParamVideoPortFormat, GetParamVideoPortFormat, SetParamVideoPortFormat); @@ -353,7 +614,6 @@ OMX_ERRORTYPE OMXVideoEncoderBase::BuildHandlerList(void) { AddHandler((OMX_INDEXTYPE)OMX_IndexIntelPrivateInfo, GetIntelPrivateInfo, SetIntelPrivateInfo); AddHandler((OMX_INDEXTYPE)OMX_IndexParamIntelBitrate, GetParamIntelBitrate, SetParamIntelBitrate); AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelBitrate, GetConfigIntelBitrate, SetConfigIntelBitrate); - AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelSliceNumbers, GetConfigIntelSliceNumbers, SetConfigIntelSliceNumbers); AddHandler((OMX_INDEXTYPE)OMX_IndexConfigIntelAIR, GetConfigIntelAIR, SetConfigIntelAIR); AddHandler(OMX_IndexConfigVideoFramerate, GetConfigVideoFramerate, SetConfigVideoFramerate); AddHandler(OMX_IndexConfigVideoIntraVOPRefresh, GetConfigVideoIntraVOPRefresh, SetConfigVideoIntraVOPRefresh); @@ -408,7 +668,8 @@ OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoBitrate(OMX_PTR pStructure) { CHECK_TYPE_HEADER(p); CHECK_PORT_INDEX(p, OUTPORT_INDEX); CHECK_SET_PARAM_STATE(); - + OMX_U32 index = p->nPortIndex; + PortVideo *port = NULL; // This disables other type of bitrate control mechanism // TODO: check if it is desired mParamIntelBitrate.eControlRate = OMX_Video_Intel_ControlRateMax; @@ -417,6 +678,8 @@ OMX_ERRORTYPE OMXVideoEncoderBase::SetParamVideoBitrate(OMX_PTR pStructure) { mParamBitrate.eControlRate = p->eControlRate; mParamBitrate.nTargetBitrate = p->nTargetBitrate; + port = static_cast<PortVideo *>(ports[index]); + ret = port->SetPortBitrateParam(p, false); return OMX_ErrorNone; } @@ -492,6 +755,7 @@ OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelBitrate(OMX_PTR pStructure) { OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelBitrate(OMX_PTR pStructure) { OMX_ERRORTYPE ret; + Encode_Status retStatus = ENCODE_SUCCESS; if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { LOGE("SetConfigIntelBitrate failed. Feature is disabled."); return OMX_ErrorUnsupportedIndex; @@ -511,47 +775,19 @@ OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelBitrate(OMX_PTR pStructure) { LOGE("SetConfigIntelBitrate failed. Feature is supported only in VCM."); return OMX_ErrorUnsupportedSetting; } - // TODO: apply Bitrate configuration in Executing state - return OMX_ErrorNone; -} - - -OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelSliceNumbers(OMX_PTR pStructure) { - OMX_ERRORTYPE ret; - OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *p = (OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *)pStructure; - - CHECK_TYPE_HEADER(p); - CHECK_PORT_INDEX(p, OUTPORT_INDEX); - memcpy(p, &mConfigIntelSliceNumbers, sizeof(*p)); - return OMX_ErrorNone; -} - -OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelSliceNumbers(OMX_PTR pStructure) { - OMX_ERRORTYPE ret; - if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { - LOGE("SetConfigIntelSliceNumbers failed. Feature is disabled."); - return OMX_ErrorUnsupportedIndex; - } - OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *p = (OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS *)pStructure; - CHECK_TYPE_HEADER(p); - CHECK_PORT_INDEX(p, OUTPORT_INDEX); - - // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig) - mConfigIntelSliceNumbers = *p; - - // return OMX_ErrorNone if not in Executing state - // TODO: return OMX_ErrorIncorrectStateOperation? - CHECK_SET_CONFIG_STATE(); - - if (mParamIntelBitrate.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) { - LOGE("SetConfigIntelSliceNumbers failed. Feature is supported only in VCM."); - return OMX_ErrorUnsupportedSetting; + VideoConfigBitRate configBitRate; + configBitRate.rcParams.bitRate = mConfigIntelBitrate.nMaxEncodeBitrate; + configBitRate.rcParams.initQP = mConfigIntelBitrate.nInitialQP; + configBitRate.rcParams.minQP = mConfigIntelBitrate.nMinQP; + configBitRate.rcParams.windowSize = mConfigIntelBitrate.nWindowSize; + configBitRate.rcParams.targetPercentage = mConfigIntelBitrate.nTargetPercentage; + retStatus = mVideoEncoder->setConfig(&configBitRate); + if(retStatus != ENCODE_SUCCESS) { + LOGW("failed to set IntelBitrate"); } - // TODO: apply Slice numbers configuration in Executing state return OMX_ErrorNone; } - OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelAIR(OMX_PTR pStructure) { OMX_ERRORTYPE ret; OMX_VIDEO_CONFIG_INTEL_AIR *p = (OMX_VIDEO_CONFIG_INTEL_AIR *)pStructure; @@ -564,6 +800,7 @@ OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigIntelAIR(OMX_PTR pStructure) { OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelAIR(OMX_PTR pStructure) { OMX_ERRORTYPE ret; + Encode_Status retStatus = ENCODE_SUCCESS; if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { LOGE("SetConfigIntelAIR failed. Feature is disabled."); return OMX_ErrorUnsupportedIndex; @@ -583,7 +820,27 @@ OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigIntelAIR(OMX_PTR pStructure) { LOGE("SetConfigIntelAIR failed. Feature is supported only in VCM."); return OMX_ErrorUnsupportedSetting; } - // TODO: apply AIR configuration in Executing state + + VideoConfigAIR configAIR; + VideoConfigIntraRefreshType configIntraRefreshType; + if(mConfigIntelAir.bAirEnable == OMX_TRUE) { + configAIR.airParams.airAuto = mConfigIntelAir.bAirAuto; + configAIR.airParams.airMBs = mConfigIntelAir.nAirMBs; + configAIR.airParams.airThreshold = mConfigIntelAir.nAirThreshold; + configIntraRefreshType.refreshType = VIDEO_ENC_AIR; + } else { + configIntraRefreshType.refreshType = VIDEO_ENC_NONIR; + } + + retStatus = mVideoEncoder->setConfig(&configAIR); + if(retStatus != ENCODE_SUCCESS) { + LOGW("Failed to set AIR config"); + } + + retStatus = mVideoEncoder->setConfig(&configIntraRefreshType); + if(retStatus != ENCODE_SUCCESS) { + LOGW("Failed to set refresh config"); + } return OMX_ErrorNone; } @@ -599,6 +856,7 @@ OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoFramerate(OMX_PTR pStructure) { OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoFramerate(OMX_PTR pStructure) { OMX_ERRORTYPE ret; + Encode_Status retStatus = ENCODE_SUCCESS; if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { LOGE("SetConfigVideoFramerate failed. Feature is disabled."); return OMX_ErrorUnsupportedIndex; @@ -618,7 +876,13 @@ OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoFramerate(OMX_PTR pStructure) { LOGE("SetConfigIntelAIR failed. Feature is supported only in VCM."); return OMX_ErrorUnsupportedSetting; } - // TODO: apply Framerate configuration in Executing state + VideoConfigFrameRate framerate; + framerate.frameRate.frameRateDenom = 1; + framerate.frameRate.frameRateNum = mConfigFramerate.xEncodeFramerate >> 16; + retStatus = mVideoEncoder->setConfig(&framerate); + if(retStatus != ENCODE_SUCCESS) { + LOGW("Failed to set frame rate config"); + } return OMX_ErrorNone; } @@ -629,6 +893,7 @@ OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoIntraVOPRefresh(OMX_PTR pStruct OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoIntraVOPRefresh(OMX_PTR pStructure) { OMX_ERRORTYPE ret; + Encode_Status retStatus = ENCODE_SUCCESS; OMX_CONFIG_INTRAREFRESHVOPTYPE *p = (OMX_CONFIG_INTRAREFRESHVOPTYPE *)pStructure; CHECK_TYPE_HEADER(p); CHECK_PORT_INDEX(p, OUTPORT_INDEX); @@ -638,23 +903,33 @@ OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoIntraVOPRefresh(OMX_PTR pStruct CHECK_SET_CONFIG_STATE(); // TODO: apply VOP refresh configuration in Executing state + VideoConfigIntraRefreshType configIntraRefreshType; + if(mConfigIntelAir.bAirEnable) { + configIntraRefreshType.refreshType = VIDEO_ENC_AIR; + } else { + configIntraRefreshType.refreshType = VIDEO_ENC_NONIR; + } + retStatus = mVideoEncoder->setConfig(&configIntraRefreshType); + if(retStatus != ENCODE_SUCCESS) { + LOGW("Failed to set refresh config"); + } return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoEncoderBase::GetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) { -#if 0 + OMX_ERRORTYPE ret; OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *p = (OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL *)pStructure; CHECK_TYPE_HEADER(p); CHECK_PORT_INDEX(p, OUTPORT_INDEX); - memcpy(p, mParamIntelAdaptiveSliceControl, sizeof(*p)); -#endif + memcpy(p, &mParamIntelAdaptiveSliceControl, sizeof(*p)); + return OMX_ErrorNone; } OMX_ERRORTYPE OMXVideoEncoderBase::SetParamIntelAdaptiveSliceControl(OMX_PTR pStructure) { -#if 0 + OMX_ERRORTYPE ret; if (mParamIntelBitrate.eControlRate == OMX_Video_Intel_ControlRateMax) { LOGE("SetParamIntelAdaptiveSliceControl failed. Feature is disabled."); @@ -668,7 +943,7 @@ OMX_ERRORTYPE OMXVideoEncoderBase::SetParamIntelAdaptiveSliceControl(OMX_PTR pSt CHECK_SET_PARAM_STATE(); mParamIntelAdaptiveSliceControl = *p; -#endif + return OMX_ErrorNone; } diff --git a/videocodec/OMXVideoEncoderBase.h b/videocodec/OMXVideoEncoderBase.h index 341bb44..705b339 100644 --- a/videocodec/OMXVideoEncoderBase.h +++ b/videocodec/OMXVideoEncoderBase.h @@ -19,14 +19,17 @@ #ifndef OMX_VIDEO_ENCODER_BASE_H_ #define OMX_VIDEO_ENCODER_BASE_H_ - #include "OMXComponentCodecBase.h" #include <IntelBufferSharing.h> -//#include "VideoEncoderInterface.h" +#include <va/va_tpi.h> +#include <va/va_android.h> +#include<VideoEncoderHost.h> using android::sp; using android::BufferShareRegistry; +#define SHARED_BUFFER_CNT 7 + class OMXVideoEncoderBase : public OMXComponentCodecBase { public: OMXVideoEncoderBase(); @@ -57,7 +60,6 @@ protected: DECLARE_HANDLER(OMXVideoEncoderBase, IntelPrivateInfo); DECLARE_HANDLER(OMXVideoEncoderBase, ParamIntelBitrate); DECLARE_HANDLER(OMXVideoEncoderBase, ConfigIntelBitrate); - DECLARE_HANDLER(OMXVideoEncoderBase, ConfigIntelSliceNumbers); DECLARE_HANDLER(OMXVideoEncoderBase, ConfigIntelAIR); DECLARE_HANDLER(OMXVideoEncoderBase, ConfigVideoFramerate); DECLARE_HANDLER(OMXVideoEncoderBase, ConfigVideoIntraVOPRefresh); @@ -65,46 +67,60 @@ protected: DECLARE_HANDLER(OMXVideoEncoderBase, ParamVideoProfileLevelQuerySupported); protected: - virtual OMX_ERRORTYPE EnableBufferSharing(void); - virtual OMX_ERRORTYPE DisableBufferSharing(void); + virtual OMX_ERRORTYPE InitBSMode(void); + virtual OMX_ERRORTYPE DeinitBSMode(void); virtual OMX_ERRORTYPE StartBufferSharing(void); virtual OMX_ERRORTYPE StopBufferSharing(void); - - + virtual OMX_ERRORTYPE SetVideoEncoderParam(); +private: + OMX_ERRORTYPE CheckAndEnableBSMode(); + OMX_ERRORTYPE AllocateSharedBuffers(int width, int height); + OMX_ERRORTYPE UploadSharedBuffers(); + OMX_ERRORTYPE SetBSInfoToPort(); + OMX_ERRORTYPE TriggerBSMode(); protected: - //IVideoEncoder *mVideoEncoder; OMX_VIDEO_PARAM_BITRATETYPE mParamBitrate; OMX_VIDEO_CONFIG_PRI_INFOTYPE mConfigPriInfo; OMX_VIDEO_PARAM_INTEL_BITRATETYPE mParamIntelBitrate; OMX_VIDEO_CONFIG_INTEL_BITRATETYPE mConfigIntelBitrate; - OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS mConfigIntelSliceNumbers; OMX_VIDEO_CONFIG_INTEL_AIR mConfigIntelAir; OMX_CONFIG_FRAMERATETYPE mConfigFramerate; -// OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL mParamIntelAdaptiveSliceControl; + OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL mParamIntelAdaptiveSliceControl; OMX_VIDEO_PARAM_PROFILELEVELTYPE mParamProfileLevel; + IVideoEncoder *mVideoEncoder; + VideoParamsCommon *mEncoderParams; + OMX_U32 mFrameInputCount; + OMX_U32 mFrameOutputCount; + OMX_BOOL mFirstFrame; + OMX_BOOL mFrameRetrieved; + + enum { + BS_STATE_INVALID, + BS_STATE_LOADED, + BS_STATE_EXECUTING + } mBsState; + + SharedBufferType *mSharedBufArray; + private: + enum { // OMX_PARAM_PORTDEFINITIONTYPE INPORT_MIN_BUFFER_COUNT = 1, - INPORT_ACTUAL_BUFFER_COUNT = 5, + INPORT_ACTUAL_BUFFER_COUNT = 2, INPORT_BUFFER_SIZE = 1382400, - // OMX_PARAM_PORTDEFINITIONTYPE + // OMX_PARAM_PORTDEFINITIONTYPE OUTPORT_MIN_BUFFER_COUNT = 1, OUTPORT_ACTUAL_BUFFER_COUNT = 2, OUTPORT_BUFFER_SIZE = 1382400, }; - sp<BufferShareRegistry> mBufferSharingLib; - int mBufferSharingCount; - SharedBufferType* mBufferSharingInfo; + sp<BufferShareRegistry> mBsInstance; + OMX_U32 mSharedBufCnt; + OMX_U32 mPFrames; - enum { - BUFFER_SHARING_INVALID, - BUFFER_SHARING_LOADED, - BUFFER_SHARING_EXECUTING - } mBufferSharingState; }; #endif /* OMX_VIDEO_ENCODER_BASE_H_ */ diff --git a/videocodec/OMXVideoEncoderH263.cpp b/videocodec/OMXVideoEncoderH263.cpp index eb213cd..3bb5998 100644 --- a/videocodec/OMXVideoEncoderH263.cpp +++ b/videocodec/OMXVideoEncoderH263.cpp @@ -15,20 +15,22 @@ */ -// #define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 #define LOG_TAG "OMXVideoEncoderH263" #include <utils/Log.h> #include "OMXVideoEncoderH263.h" -static const char* H263_MIME_TYPE = "video/h263"; +static const char *H263_MIME_TYPE = "video/h263"; OMXVideoEncoderH263::OMXVideoEncoderH263() { - LOGV("OMXVideoEncoderH263 is constructed."); + LOGV("Constructer for OMXVideoEncoderH263."); BuildHandlerList(); + mVideoEncoder = createVideoEncoder(H263_MIME_TYPE); + if (!mVideoEncoder) LOGE("OMX_ErrorInsufficientResources"); } OMXVideoEncoderH263::~OMXVideoEncoderH263() { - LOGV("OMXVideoEncoderH263 is destructed."); + LOGV("Destructer for OMXVideoEncoderH263."); } OMX_ERRORTYPE OMXVideoEncoderH263::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput) { @@ -37,7 +39,7 @@ OMX_ERRORTYPE OMXVideoEncoderH263::InitOutputPortFormatSpecific(OMX_PARAM_PORTDE SetTypeHeader(&mParamH263, sizeof(mParamH263)); mParamH263.nPortIndex = OUTPORT_INDEX; mParamH263.eProfile = OMX_VIDEO_H263ProfileBaseline; - // TODO: check eLevel, 10 in Froyo + // TODO: check eLevel, 10 mParamH263.eLevel = OMX_VIDEO_H263Level70; //OMX_VIDEO_H263Level10; // override OMX_PARAM_PORTDEFINITIONTYPE @@ -55,10 +57,25 @@ OMX_ERRORTYPE OMXVideoEncoderH263::InitOutputPortFormatSpecific(OMX_PARAM_PORTDE // override OMX_VIDEO_PARAM_BITRATETYPE mParamBitrate.nTargetBitrate = 64000; + // override OMX_VIDEO_CONFIG_INTEL_BITRATETYPE + mConfigIntelBitrate.nInitialQP = 15; // Initial QP for I frames return OMX_ErrorNone; } +OMX_ERRORTYPE OMXVideoEncoderH263::SetVideoEncoderParam(void) { + + if (!mEncoderParams) { + LOGE("NULL pointer: mEncoderParams"); + return OMX_ErrorBadParameter; + } + + mVideoEncoder->getParameters(mEncoderParams); + mEncoderParams->profile = (VAProfile)PROFILE_H263BASELINE; + return OMXVideoEncoderBase::SetVideoEncoderParam(); +} + OMX_ERRORTYPE OMXVideoEncoderH263::ProcessorInit(void) { + LOGV("OMXVideoEncoderH263::ProcessorInit\n"); return OMXVideoEncoderBase::ProcessorInit(); } @@ -67,11 +84,148 @@ OMX_ERRORTYPE OMXVideoEncoderH263::ProcessorDeinit(void) { } OMX_ERRORTYPE OMXVideoEncoderH263::ProcessorProcess( - OMX_BUFFERHEADERTYPE **buffers, - buffer_retain_t *retains, - OMX_U32 numberBuffers) { + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + LOGV("OMXVideoEncoderH263::ProcessorProcess \n"); + + VideoEncOutputBuffer outBuf; + VideoEncRawBuffer inBuf; + OMX_U32 outfilledlen = 0; + OMX_S64 outtimestamp = 0; + OMX_U32 outflags = 0; + + OMX_ERRORTYPE oret = OMX_ErrorNone; + Encode_Status ret = ENCODE_SUCCESS; + + LOGV("%s(): enter encode\n", __func__); + + LOGV_IF(buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS, + "%s(),%d: got OMX_BUFFERFLAG_EOS\n", __func__, __LINE__); + + if (!buffers[INPORT_INDEX]->nFilledLen) { + LOGE("%s(),%d: input buffer's nFilledLen is zero\n", __func__, __LINE__); + goto out; + } + + if (mBsState != BS_STATE_INVALID) { + // Here is shared buffer mode + inBuf.size = mSharedBufArray[0].dataSize; + inBuf.data = + *(reinterpret_cast<uint8_t **>(buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset)); + } else { + inBuf.data = buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset; + inBuf.size = buffers[INPORT_INDEX]->nFilledLen; + } + + LOGV("buffer_in.data=%x, data_size=%d", + (unsigned)inBuf.data, inBuf.size); + + outBuf.data = buffers[OUTPORT_INDEX]->pBuffer + buffers[OUTPORT_INDEX]->nOffset; + outBuf.bufferSize = buffers[OUTPORT_INDEX]->nAllocLen - buffers[OUTPORT_INDEX]->nOffset; + outBuf.dataSize = 0; + + if(mFrameRetrieved) { + // encode and setConfig need to be thread safe + pthread_mutex_unlock(&mSerializationLock); + ret = mVideoEncoder->encode(&inBuf); + pthread_mutex_unlock(&mSerializationLock); + + CHECK_ENCODE_STATUS("encode"); + mFrameRetrieved = OMX_FALSE; + + // This is for buffer contention, we won't release current buffer + // but the last input buffer + ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); + } + + outBuf.format = OUTPUT_EVERYTHING; + ret = mVideoEncoder->getOutput(&outBuf); + // CHECK_ENCODE_STATUS("encode"); + if(ret == ENCODE_NO_REQUEST_DATA) { + mFrameRetrieved = OMX_TRUE; + retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE; + goto out; + } + + LOGV("output data size = %d", outBuf.dataSize); + outfilledlen = outBuf.dataSize; + outtimestamp = buffers[INPORT_INDEX]->nTimeStamp; + + + if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) { + outflags |= OMX_BUFFERFLAG_SYNCFRAME; + } + + if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) { + outflags |= OMX_BUFFERFLAG_ENDOFFRAME; + mFrameRetrieved = OMX_TRUE; + retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE; + + } else { + retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again + + } + + if (outfilledlen > 0) { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; + } else { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + } + + + if(ret == ENCODE_SLICESIZE_OVERFLOW) { + LOGV("%s(), mix_video_encode returns MIX_RESULT_VIDEO_ENC_SLICESIZE_OVERFLOW" + , __func__); + oret = (OMX_ERRORTYPE)OMX_ErrorIntelExtSliceSizeOverflow; + } +#if SHOW_FPS + { + struct timeval t; + OMX_TICKS current_ts, interval_ts; + float current_fps, average_fps; + + t.tv_sec = t.tv_usec = 0; + gettimeofday(&t, NULL); + + current_ts =(nsecs_t)t.tv_sec * 1000000000 + (nsecs_t)t.tv_usec * 1000; + interval_ts = current_ts - lastTs; + lastTs = current_ts; + + current_fps = (float)1000000000 / (float)interval_ts; + average_fps = (current_fps + lastFps) / 2; + lastFps = current_fps; + + LOGD("FPS = %2.1f\n", average_fps); + } +#endif + +out: + + if(retains[OUTPORT_INDEX] != BUFFER_RETAIN_GETAGAIN) { + buffers[OUTPORT_INDEX]->nFilledLen = outfilledlen; + buffers[OUTPORT_INDEX]->nTimeStamp = outtimestamp; + buffers[OUTPORT_INDEX]->nFlags = outflags; + + LOGV("********** output buffer: len=%d, ts=%ld, flags=%x", + outfilledlen, + outtimestamp, + outflags); + } + + if (retains[INPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN || + retains[INPORT_INDEX] == BUFFER_RETAIN_ACCUMULATE ) { + mFrameInputCount ++; + } + + if (retains[OUTPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN) + mFrameOutputCount ++; + + LOGV_IF(oret == OMX_ErrorNone, "%s(),%d: exit, encode is done\n", __func__, __LINE__); + + return oret; - return OMXVideoEncoderBase::ProcessorProcess(buffers, retains, numberBuffers); } OMX_ERRORTYPE OMXVideoEncoderH263::BuildHandlerList(void) { diff --git a/videocodec/OMXVideoEncoderH263.h b/videocodec/OMXVideoEncoderH263.h index f0d156b..44f5fbc 100644 --- a/videocodec/OMXVideoEncoderH263.h +++ b/videocodec/OMXVideoEncoderH263.h @@ -35,9 +35,9 @@ protected: buffer_retain_t *retains, OMX_U32 numberBuffers); - virtual OMX_ERRORTYPE BuildHandlerList(void); - - DECLARE_HANDLER(OMXVideoEncoderH263, ParamVideoH263); + virtual OMX_ERRORTYPE BuildHandlerList(void); + virtual OMX_ERRORTYPE SetVideoEncoderParam(); + DECLARE_HANDLER(OMXVideoEncoderH263, ParamVideoH263); private: enum { diff --git a/videocodec/OMXVideoEncoderMPEG4.cpp b/videocodec/OMXVideoEncoderMPEG4.cpp index da58e74..b84f0fc 100644 --- a/videocodec/OMXVideoEncoderMPEG4.cpp +++ b/videocodec/OMXVideoEncoderMPEG4.cpp @@ -15,16 +15,18 @@ */ -// #define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 #define LOG_TAG "OMXVideoEncoderMPEG4" #include <utils/Log.h> #include "OMXVideoEncoderMPEG4.h" -static const char* MPEG4_MIME_TYPE = "video/mpeg4"; +static const char *MPEG4_MIME_TYPE = "video/mpeg4"; OMXVideoEncoderMPEG4::OMXVideoEncoderMPEG4() { LOGV("OMXVideoEncoderMPEG4 is constructed."); BuildHandlerList(); + mVideoEncoder = createVideoEncoder(MPEG4_MIME_TYPE); + if (!mVideoEncoder) LOGE("OMX_ErrorInsufficientResources"); } OMXVideoEncoderMPEG4::~OMXVideoEncoderMPEG4() { @@ -37,7 +39,7 @@ OMX_ERRORTYPE OMXVideoEncoderMPEG4::InitOutputPortFormatSpecific(OMX_PARAM_PORTD SetTypeHeader(&mParamMpeg4, sizeof(mParamMpeg4)); mParamMpeg4.nPortIndex = OUTPORT_INDEX; mParamMpeg4.eProfile = OMX_VIDEO_MPEG4ProfileSimple; - // TODO: Check eLevel (Level3 in Froyo) + // TODO: Check eLevel (Level3) mParamMpeg4.eLevel = OMX_VIDEO_MPEG4Level5; //OMX_VIDEO_MPEG4Level3; // override OMX_PARAM_PORTDEFINITIONTYPE @@ -52,9 +54,23 @@ OMX_ERRORTYPE OMXVideoEncoderMPEG4::InitOutputPortFormatSpecific(OMX_PARAM_PORTD mParamProfileLevel.eProfile = mParamMpeg4.eProfile; mParamProfileLevel.eLevel = mParamMpeg4.eLevel; //OMX_VIDEO_MPEG4Level5; + // override OMX_VIDEO_CONFIG_INTEL_BITRATETYPE + mConfigIntelBitrate.nInitialQP = 15; // Initial QP for I frames return OMX_ErrorNone; } +OMX_ERRORTYPE OMXVideoEncoderMPEG4::SetVideoEncoderParam(void) { + + if (!mEncoderParams) { + LOGE("NULL pointer: mEncoderParams"); + return OMX_ErrorBadParameter; + } + + mVideoEncoder->getParameters(mEncoderParams); + mEncoderParams->profile = (VAProfile)PROFILE_MPEG4SIMPLE; + return OMXVideoEncoderBase::SetVideoEncoderParam(); +} + OMX_ERRORTYPE OMXVideoEncoderMPEG4::ProcessorInit(void) { return OMXVideoEncoderBase::ProcessorInit(); } @@ -64,11 +80,155 @@ OMX_ERRORTYPE OMXVideoEncoderMPEG4::ProcessorDeinit(void) { } OMX_ERRORTYPE OMXVideoEncoderMPEG4::ProcessorProcess( - OMX_BUFFERHEADERTYPE **buffers, - buffer_retain_t *retains, - OMX_U32 numberBuffers) { + OMX_BUFFERHEADERTYPE **buffers, + buffer_retain_t *retains, + OMX_U32 numberBuffers) { + + VideoEncOutputBuffer outBuf; + VideoEncRawBuffer inBuf; + Encode_Status ret = ENCODE_SUCCESS; + + OMX_U32 outfilledlen = 0; + OMX_S64 outtimestamp = 0; + OMX_U32 outflags = 0; + OMX_ERRORTYPE oret = OMX_ErrorNone; + + + LOGV_IF(buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS, + "%s(),%d: got OMX_BUFFERFLAG_EOS\n", __func__, __LINE__); + + if (!buffers[INPORT_INDEX]->nFilledLen) { + LOGV("%s(),%d: input buffer's nFilledLen is zero\n", __func__, __LINE__); + goto out; + } + + if (mBsState != BS_STATE_INVALID) { + inBuf.size = mSharedBufArray[0].dataSize; + inBuf.data = + *(reinterpret_cast<uint8_t **>(buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset)); + } else { + inBuf.data = + buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset; + inBuf.size = buffers[INPORT_INDEX]->nFilledLen; + } + + LOGV("inBuf.data=%x, size=%d", (unsigned)inBuf.data, inBuf.size); + + outBuf.data = + buffers[OUTPORT_INDEX]->pBuffer + buffers[OUTPORT_INDEX]->nOffset; + outBuf.dataSize = 0; + outBuf.bufferSize = buffers[OUTPORT_INDEX]->nAllocLen - buffers[OUTPORT_INDEX]->nOffset; + + + if (mFrameRetrieved) { + // encode and setConfig need to be thread safe + pthread_mutex_unlock(&mSerializationLock); + ret = mVideoEncoder->encode(&inBuf); + pthread_mutex_unlock(&mSerializationLock); + + CHECK_ENCODE_STATUS("encode"); + mFrameRetrieved = OMX_FALSE; + + // This is for buffer contention, we won't release current buffer + // but the last input buffer + ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); + } + + if (mFirstFrame) { + LOGV("mFirstFrame\n"); + outBuf.format = OUTPUT_CODEC_DATA; + ret = mVideoEncoder->getOutput(&outBuf); + CHECK_ENCODE_STATUS("getOutput"); + // Return code could not be ENCODE_BUFFER_TOO_SMALL + // If we don't return error, we will have dead lock issue + if (ret == ENCODE_BUFFER_TOO_SMALL) { + return OMX_ErrorUndefined; + } + + LOGV("output codec data size = %d", outBuf.dataSize); + + outflags |= OMX_BUFFERFLAG_CODECCONFIG; + outflags |= OMX_BUFFERFLAG_ENDOFFRAME; + outflags |= OMX_BUFFERFLAG_SYNCFRAME; + + outfilledlen = outBuf.dataSize; + mFirstFrame = OMX_FALSE; + } else { + outBuf.format = OUTPUT_EVERYTHING; + mVideoEncoder->getOutput(&outBuf); + CHECK_ENCODE_STATUS("getOutput"); + + LOGV("output data size = %d", outBuf.dataSize); + + + outfilledlen = outBuf.dataSize; + outtimestamp = buffers[INPORT_INDEX]->nTimeStamp; + + if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) { + outflags |= OMX_BUFFERFLAG_SYNCFRAME; + } + + if (outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) { + LOGV("Get buffer done\n"); + outflags |= OMX_BUFFERFLAG_ENDOFFRAME; + mFrameRetrieved = OMX_TRUE; + retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE; + + } else { + retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again + + } + + } + + if (outfilledlen > 0) { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN; + } else { + retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; + } + + + +#if SHOW_FPS + { + struct timeval t; + OMX_TICKS current_ts, interval_ts; + float current_fps, average_fps; + + t.tv_sec = t.tv_usec = 0; + gettimeofday(&t, NULL); + + current_ts = + (nsecs_t)t.tv_sec * 1000000000 + (nsecs_t)t.tv_usec * 1000; + interval_ts = current_ts - lastTs; + lastTs = current_ts; + + current_fps = (float)1000000000 / (float)interval_ts; + average_fps = (current_fps + lastFps) / 2; + lastFps = current_fps; + + LOGV("FPS = %2.1f\n", average_fps); + } +#endif + +out: + + if (retains[OUTPORT_INDEX] != BUFFER_RETAIN_GETAGAIN) { + buffers[OUTPORT_INDEX]->nFilledLen = outfilledlen; + buffers[OUTPORT_INDEX]->nTimeStamp = outtimestamp; + buffers[OUTPORT_INDEX]->nFlags = outflags; + } + + if (retains[INPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN || + retains[INPORT_INDEX] == BUFFER_RETAIN_ACCUMULATE ) { + mFrameInputCount ++; + } + + if (retains[OUTPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN) + mFrameOutputCount ++; + + return oret; - return OMXVideoEncoderBase::ProcessorProcess(buffers, retains, numberBuffers); } OMX_ERRORTYPE OMXVideoEncoderMPEG4::BuildHandlerList(void) { diff --git a/videocodec/OMXVideoEncoderMPEG4.h b/videocodec/OMXVideoEncoderMPEG4.h index 6ad4e7c..33b93a2 100644 --- a/videocodec/OMXVideoEncoderMPEG4.h +++ b/videocodec/OMXVideoEncoderMPEG4.h @@ -36,9 +36,9 @@ protected: buffer_retain_t *retains, OMX_U32 numberBuffers); - virtual OMX_ERRORTYPE BuildHandlerList(void); - - DECLARE_HANDLER(OMXVideoEncoderMPEG4, ParamVideoMpeg4); + virtual OMX_ERRORTYPE BuildHandlerList(void); + virtual OMX_ERRORTYPE SetVideoEncoderParam(); + DECLARE_HANDLER(OMXVideoEncoderMPEG4, ParamVideoMpeg4); private: enum { diff --git a/videocodec/vabuffer.h b/videocodec/vabuffer.h index 3bfa624..f3fab72 100644 --- a/videocodec/vabuffer.h +++ b/videocodec/vabuffer.h @@ -17,8 +17,7 @@ #ifndef __VA_BUFFER_H__ #define __VA_BUFFER_H__ -struct VABuffer -{ +struct VABuffer { VASurfaceID surface; VADisplay display; unsigned int frame_structure; diff --git a/wrs_omxil_components.list b/wrs_omxil_components.list index 5aa98ea..6511c07 100644 --- a/wrs_omxil_components.list +++ b/wrs_omxil_components.list @@ -14,3 +14,6 @@ libOMXVideoDecoderAVC.so libOMXVideoDecoderH263.so libOMXVideoDecoderWMV.so libOMXVideoDecoderMPEG4.so +libOMXVideoEncoderAVC.so +libOMXVideoEncoderH263.so +libOMXVideoEncoderMPEG4.so |
