aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShuduo Sang <shuduo.sang@intel.com>2011-09-13 17:41:41 +0800
committerPatrick Tjin <pattjin@google.com>2014-07-21 22:02:44 -0700
commit19b2ab9f325bdbf3afe530e943fa5a0c0020b308 (patch)
treed831e71b57586df696aa0d6d13763b7a6b6a9008
parent5a87cdf2139ee15c61aaae2988bbea3ae49e6235 (diff)
downloadandroid_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.mk96
-rw-r--r--videocodec/OMXComponentCodecBase.cpp7
-rw-r--r--videocodec/OMXComponentDefines.h24
-rw-r--r--videocodec/OMXVideoEncoderAVC.cpp391
-rw-r--r--videocodec/OMXVideoEncoderAVC.h27
-rw-r--r--videocodec/OMXVideoEncoderBase.cpp515
-rw-r--r--videocodec/OMXVideoEncoderBase.h56
-rw-r--r--videocodec/OMXVideoEncoderH263.cpp172
-rw-r--r--videocodec/OMXVideoEncoderH263.h6
-rw-r--r--videocodec/OMXVideoEncoderMPEG4.cpp174
-rw-r--r--videocodec/OMXVideoEncoderMPEG4.h6
-rw-r--r--videocodec/vabuffer.h3
-rw-r--r--wrs_omxil_components.list3
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(&paramPortDefinitionOutput, 0, sizeof(paramPortDefinitionOutput));
@@ -205,6 +230,7 @@ OMX_ERRORTYPE OMXVideoEncoderBase::InitOutputPort(void) {
InitOutputPortFormatSpecific(&paramPortDefinitionOutput);
port->SetPortDefinition(&paramPortDefinitionOutput, 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(&paramsUsrptrBuffer);
+ 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