aboutsummaryrefslogtreecommitdiffstats
path: root/videocodec/OMXVideoEncoderMPEG4.cpp
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 /videocodec/OMXVideoEncoderMPEG4.cpp
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>
Diffstat (limited to 'videocodec/OMXVideoEncoderMPEG4.cpp')
-rw-r--r--videocodec/OMXVideoEncoderMPEG4.cpp174
1 files changed, 167 insertions, 7 deletions
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) {