aboutsummaryrefslogtreecommitdiffstats
path: root/videocodec
diff options
context:
space:
mode:
authorJuan Antonio Gozalvez Herrero <jgozalvx>2013-01-15 11:17:57 +0100
committerPatrick Tjin <pattjin@google.com>2014-07-21 22:02:49 -0700
commite4876b874be60356322ca55b467fd0ee096ee7ab (patch)
tree49909fa7c449bd300c7a11c2a06fc970cccf4115 /videocodec
parent0d275ff362298b443c828f09f593bfb674112bbd (diff)
downloadandroid_hardware_intel_common_omx-components-e4876b874be60356322ca55b467fd0ee096ee7ab.tar.gz
android_hardware_intel_common_omx-components-e4876b874be60356322ca55b467fd0ee096ee7ab.tar.bz2
android_hardware_intel_common_omx-components-e4876b874be60356322ca55b467fd0ee096ee7ab.zip
Revert "MRFLD highprofile encoding support"
BZ: 76824 This reverts commit fbf1cd362697bbb3b12162408e03f87f9b122ab1. This reverts patch http://android.intel.com:8080/#/c/67485/ Change-Id: Id1b04d3ad21f5b340b04daac24a8e8ec548a779d Orig-Change-Id: I8cc469dd7ea37b1c9989a55adec3b1834c4aa905 Reviewed-on: http://android.intel.com:8080/86741 Reviewed-by: Gozalvez Herrero, Juan AntonioX <juan.antoniox.gozalvez.herrero@intel.com> Tested-by: Gozalvez Herrero, Juan AntonioX <juan.antoniox.gozalvez.herrero@intel.com> Reviewed-by: cactus <cactus@intel.com> Tested-by: cactus <cactus@intel.com>
Diffstat (limited to 'videocodec')
-rw-r--r--videocodec/OMXVideoEncoderAVC.cpp600
-rw-r--r--videocodec/OMXVideoEncoderAVC.h64
-rw-r--r--videocodec/OMXVideoEncoderBase.cpp9
-rw-r--r--videocodec/OMXVideoEncoderBase.h2
-rw-r--r--videocodec/OMXVideoEncoderH263.cpp5
-rw-r--r--videocodec/OMXVideoEncoderMPEG4.cpp5
6 files changed, 247 insertions, 438 deletions
diff --git a/videocodec/OMXVideoEncoderAVC.cpp b/videocodec/OMXVideoEncoderAVC.cpp
index 3d43526..9a59485 100644
--- a/videocodec/OMXVideoEncoderAVC.cpp
+++ b/videocodec/OMXVideoEncoderAVC.cpp
@@ -14,7 +14,8 @@
* limitations under the License.
*/
-#define LOG_NDEBUG 0
+
+//#define LOG_NDEBUG 0
#define LOG_TAG "OMXVideoEncoderAVC"
#include <utils/Log.h>
#include "OMXVideoEncoderAVC.h"
@@ -45,8 +46,6 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEF
mParamAvc.nPortIndex = OUTPORT_INDEX;
mParamAvc.eProfile = OMX_VIDEO_AVCProfileBaseline;
mParamAvc.eLevel = OMX_VIDEO_AVCLevel41;
- mParamAvc.nPFrames = 30;
- mParamAvc.nBFrames = 0;
// OMX_NALSTREAMFORMATTYPE
memset(&mNalStreamFormat, 0, sizeof(mNalStreamFormat));
@@ -61,7 +60,7 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::InitOutputPortFormatSpecific(OMX_PARAM_PORTDEF
mConfigAvcIntraPeriod.nPortIndex = OUTPORT_INDEX;
// TODO: need to be populated from Video Encoder
mConfigAvcIntraPeriod.nIDRPeriod = 1;
- mConfigAvcIntraPeriod.nPFrames = 30;
+ mConfigAvcIntraPeriod.nPFrames = 0;
// OMX_VIDEO_CONFIG_NALSIZE
memset(&mConfigNalSize, 0, sizeof(mConfigNalSize));
@@ -114,20 +113,12 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::SetVideoEncoderParam(void) {
}
mVideoEncoder->getParameters(mEncoderParams);
- if (mParamAvc.eProfile == OMX_VIDEO_AVCProfileBaseline) {
- mEncoderParams->profile = (VAProfile)VAProfileH264Baseline;
- mEncoderParams->intraPeriod = mParamAvc.nPFrames; //intraperiod
- } else if (mParamAvc.eProfile == OMX_VIDEO_AVCProfileHigh) {
- mEncoderParams->profile = (VAProfile)VAProfileH264High;
- mEncoderParams->intraPeriod = mParamAvc.nPFrames + mParamAvc.nBFrames; //intraperiod
- }
+ mEncoderParams->profile = (VAProfile)VAProfileH264Baseline;
// 0 - all luma and chroma block edges of the slice are filtered
// 1 - deblocking is disabled for all block edges of the slice
// 2 - all luma and chroma block edges of the slice are filtered
// with exception of the block edges that coincide with slice boundaries
mEncoderParams->disableDeblocking = 0;
-
-
OMXVideoEncoderBase::SetVideoEncoderParam();
mVideoEncoder->getParameters(mAVCParams);
@@ -141,35 +132,33 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::SetVideoEncoderParam(void) {
}
mAVCParams->sliceNum.iSliceNum = mConfigIntelSliceNumbers.nISliceNumber;
mAVCParams->sliceNum.pSliceNum = mConfigIntelSliceNumbers.nPSliceNumber;
+ mAVCParams->idrInterval = mConfigAvcIntraPeriod.nIDRPeriod;
mAVCParams->maxSliceSize = mConfigNalSize.nNaluBytes * 8;
- if (mEncoderParams->intraPeriod == 0) {
- mAVCParams->idrInterval = 0;
- mAVCParams->ipPeriod = 0;
- } else {
- mAVCParams->idrInterval = mConfigAvcIntraPeriod.nIDRPeriod; //idrinterval
- if (mParamAvc.eProfile == OMX_VIDEO_AVCProfileBaseline) {
- mAVCParams->ipPeriod = 1; //ipperiod
- } else if (mParamAvc.eProfile == OMX_VIDEO_AVCProfileHigh) {
- mAVCParams->ipPeriod = mEncoderParams->intraPeriod / mParamAvc.nPFrames; //ipperiod
- }
- }
ret = mVideoEncoder ->setParameters(mAVCParams);
CHECK_ENCODE_STATUS("setParameters");
+ VideoConfigAVCIntraPeriod avcIntraPreriod;
+ avcIntraPreriod.idrInterval = mConfigAvcIntraPeriod.nIDRPeriod;
+ // hardcode intra period for AVC encoder, get value from OMX_VIDEO_PARAM_AVCTYPE.nPFrames or
+ // OMX_VIDEO_CONFIG_AVCINTRAPERIOD.nPFrames is a more flexible method
+ if (mParamAvc.nPFrames == 0) {
+ avcIntraPreriod.intraPeriod = 0;
+ } else {
+ avcIntraPreriod.intraPeriod = 30;
+ }
+ ret = mVideoEncoder->setConfig(&avcIntraPreriod);
+ CHECK_ENCODE_STATUS("setConfig");
+
LOGV("VUIFlag = %d\n", mAVCParams->VUIFlag);
LOGV("sliceNum.iSliceNum = %d\n", mAVCParams->sliceNum.iSliceNum);
LOGV("sliceNum.pSliceNum = %d\n", mAVCParams->sliceNum.pSliceNum);
- LOGV("maxSliceSize = %d\n ", mAVCParams->maxSliceSize);
- LOGV("intraPeriod = %d\n ", mEncoderParams->intraPeriod);
LOGV("idrInterval = %d\n ", mAVCParams->idrInterval);
- LOGV("ipPeriod = %d\n ", mAVCParams->ipPeriod);
+ LOGV("maxSliceSize = %d\n ", mAVCParams->maxSliceSize);
return OMX_ErrorNone;
}
OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorInit(void) {
mFirstFrame = OMX_TRUE;
- mInputPictureCount = 0;
- mFrameEncodedCount = 0;
return OMXVideoEncoderBase::ProcessorInit();
}
@@ -177,376 +166,290 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorDeinit(void) {
return OMXVideoEncoderBase::ProcessorDeinit();
}
-OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorStop(void) {
- OMX_BUFFERHEADERTYPE *omxbuf = NULL;
+OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorProcess(
+ OMX_BUFFERHEADERTYPE **buffers,
+ buffer_retain_t *retains,
+ OMX_U32 numberBuffers) {
- while(!mBFrameList.empty()) {
- omxbuf = * mBFrameList.begin();
- this->ports[INPORT_INDEX]->ReturnThisBuffer(omxbuf);
- mBFrameList.erase(mBFrameList.begin());
+ 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;
+
+ OMX_NALUFORMATSTYPE NaluFormat = mNalStreamFormat.eNaluFormat;
+
+ 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;
}
- return OMXVideoEncoderBase::ProcessorStop();
-}
+ if (bAndroidOpaqueFormat) {
+ mCurHandle = rgba2nv12conversion(buffers[INPORT_INDEX]);
+ }
+
+ inBuf.data = buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset;
+ inBuf.size = buffers[INPORT_INDEX]->nFilledLen;
-OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorPreEmptyBuffer(OMX_BUFFERHEADERTYPE* buffer) {
- OMX_U32 EncodeInfo = 0;
- OMX_U32 EncodeFrameType = 0;
-
- uint32_t poc = 0;
- uint32_t idrPeriod = mAVCParams->idrInterval;
- uint32_t IntraPeriod = mEncoderParams->intraPeriod; /*6*/
- uint32_t IpPeriod = mAVCParams->ipPeriod; /*3 */
- bool BFrameEnabled = IpPeriod > 1;
-
- LOGV("ProcessorPreEmptyBuffer idrPeriod=%d, IntraPeriod=%d, IpPeriod=%d, BFrameEnabled=%d\n", idrPeriod, IntraPeriod, IpPeriod, BFrameEnabled);
-
- //decide frame type, refer Merrifield Video Encoder Driver HLD Chapter 3.15
- if (idrPeriod == 0)
- poc = mInputPictureCount;
- else if (BFrameEnabled)
- poc = mInputPictureCount % (IntraPeriod*idrPeriod + 1);
- else
- poc = mInputPictureCount % (IntraPeriod*idrPeriod);
-
- if (poc == 0 /*IDR*/) {
- EncodeFrameType = F_IDR;
- } else if (IntraPeriod == 0) {
- EncodeFrameType = F_I;
- }else if ((poc > IpPeriod) && ((poc - IpPeriod) % IntraPeriod == 0))/*I*/{
- EncodeFrameType = F_I;
- if (BFrameEnabled)
- SET_CO(EncodeInfo, CACHE_POP);
- } else if ((poc % IpPeriod == 0) /*P*/ || (buffer->nFlags & OMX_BUFFERFLAG_EOS)/*EOS,always P*/) {
- EncodeFrameType = F_P;
- if (BFrameEnabled)
- SET_CO(EncodeInfo, CACHE_POP);
- } else { /*B*/
- EncodeFrameType = F_B;
- SET_CO(EncodeInfo, CACHE_PUSH);
+ 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;
}
- SET_FT(EncodeInfo, EncodeFrameType);
- SET_FC(EncodeInfo, mInputPictureCount);
+ LOGV("in buffer = 0x%x ts = %lld",
+ buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset,
+ buffers[INPORT_INDEX]->nTimeStamp);
- buffer->pPlatformPrivate = (OMX_PTR) EncodeInfo;
+ if(inBuf.data == NULL) {
+ LOGE("The Input buf is NULL\n");
+ return OMX_ErrorBadParameter;
+ }
- LOGV("ProcessorPreEmptyBuffer Frame %d, Type %s, EncodeInfo %x\n", mInputPictureCount, FrameTypeStr[EncodeFrameType], EncodeInfo);
+ 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;
- mInputPictureCount ++;
- return OMX_ErrorNone;
-}
+ // This is for buffer contention, we won't release current buffer
+ // but the last input buffer
+ ports[INPORT_INDEX]->ReturnAllRetainedBuffers();
+ }
-OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessCacheOperation(
- OMX_BUFFERHEADERTYPE **buffers,
- buffer_retain_t *retains,
- Encode_Info *pInfo) {
+ if (mStoreMetaDataInBuffers)
+ NaluFormat = OMX_NaluFormatLengthPrefixedSeparateFirstHeader;
- /* Check and do cache operation
- */
- if (pInfo->CacheOperation == CACHE_NONE) {
- if (buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS)
- pInfo->EndOfEncode = true;
+ switch (NaluFormat) {
+ case OMX_NaluFormatStartCodes:
- } else if (pInfo->CacheOperation == CACHE_PUSH) {
- mBFrameList.push_front(buffers[INPORT_INDEX]);
- retains[INPORT_INDEX] = BUFFER_RETAIN_CACHE;
- retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+ outBuf.format = OUTPUT_EVERYTHING;
+ ret = mVideoEncoder->getOutput(&outBuf);
+ CHECK_ENCODE_STATUS("encode");
- } else if (pInfo->CacheOperation == CACHE_POP) {
- pInfo->NotStopFrame = true; //it is also a nstop frame
+ LOGV("output data size = %d", outBuf.dataSize);
+ outfilledlen = outBuf.dataSize;
+ outtimestamp = buffers[INPORT_INDEX]->nTimeStamp;
- OMX_BUFFERHEADERTYPE *omxbuf = NULL;
- uint32_t i = 0;
- LOGV("BFrameList size = %d\n", mBFrameList.size());
+ if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) {
+ outflags |= OMX_BUFFERFLAG_SYNCFRAME;
+ }
- while(!mBFrameList.empty()) {
- omxbuf = *mBFrameList.begin();
+ if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) {
+ outflags |= OMX_BUFFERFLAG_ENDOFFRAME;
+ mFrameRetrieved = OMX_TRUE;
+ retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE;
- if (buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS && i == 0 ) {
- //this is final encode frame, make EOE
- uint32_t tmp = (uint32_t) omxbuf->pPlatformPrivate;
- tmp |= ENC_EOE;
- omxbuf->pPlatformPrivate = (OMX_PTR) tmp;
} else {
- //all these frames except final B frame in miniGOP can't be stopped at any time
- //to avoid not breaking miniGOP integrity
- if (i > 0) {
- uint32_t tmp = (uint32_t) omxbuf->pPlatformPrivate;
- tmp |= ENC_NSTOP;
- omxbuf->pPlatformPrivate = (OMX_PTR) tmp;
- }
+ retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again
+
}
- ports[INPORT_INDEX]->RetainThisBuffer(omxbuf, false); //push bufferq head
- mBFrameList.erase(mBFrameList.begin()); //clear it from internal queue
- i++;
- }
+ if (outfilledlen > 0) {
+ retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN;
+ } else {
+ retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+ }
- } else if (pInfo->CacheOperation == CACHE_RESET) {
-// mBFrameList.clear();
- }
+ break;
+ case OMX_NaluFormatOneNaluPerBuffer:
- pInfo->CacheOperation = CACHE_NONE;
+ 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("ProcessCacheOperation OK\n");
- return OMX_ErrorNone;
-}
+ LOGV("output codec data size = %d", outBuf.dataSize);
-OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessDataRetrieve(
- OMX_BUFFERHEADERTYPE **buffers,
- buffer_retain_t *retains,
- Encode_Info *pInfo) {
+ outfilledlen = outBuf.dataSize;
+ outtimestamp = buffers[INPORT_INDEX]->nTimeStamp;
- OMX_NALUFORMATSTYPE NaluFormat = mNalStreamFormat.eNaluFormat;
+ if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) {
+ outflags |= OMX_BUFFERFLAG_SYNCFRAME;
+ }
- if (mStoreMetaDataInBuffers)
- NaluFormat = OMX_NaluFormatLengthPrefixedSeparateFirstHeader;
+ if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) {
+ outflags |= OMX_BUFFERFLAG_ENDOFFRAME;
+ mFrameRetrieved = OMX_TRUE;
+ retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE;
- VideoEncOutputBuffer outBuf;
- outBuf.data = buffers[OUTPORT_INDEX]->pBuffer + buffers[OUTPORT_INDEX]->nOffset;
- outBuf.bufferSize = buffers[OUTPORT_INDEX]->nAllocLen - buffers[OUTPORT_INDEX]->nOffset;
- outBuf.dataSize = 0;
- outBuf.remainingSize = 0;
- outBuf.flag = 0;
- outBuf.timeStamp = 0;
+ } else {
+ retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again
+ }
- switch (NaluFormat) {
- case OMX_NaluFormatStartCodes:
- outBuf.format = OUTPUT_EVERYTHING;
- break;
+ if (outfilledlen > 0) {
+ retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN;
+ } else {
+ retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+ }
- case OMX_NaluFormatOneNaluPerBuffer:
- outBuf.format = OUTPUT_ONE_NAL;
break;
-
case OMX_NaluFormatStartCodesSeparateFirstHeader:
- case OMX_NaluFormatLengthPrefixedSeparateFirstHeader:
+
if(mFirstFrame) {
- LOGV("FirstFrame to output codec data\n");
+ LOGV("mFirstFrame\n");
outBuf.format = OUTPUT_CODEC_DATA;
- } else {
- if (NaluFormat == OMX_NaluFormatStartCodesSeparateFirstHeader)
- outBuf.format = OUTPUT_EVERYTHING;
- else
- outBuf.format = OUTPUT_LENGTH_PREFIXED;
- }
- break;
+ ret = mVideoEncoder->getOutput(&outBuf);
+ CHECK_ENCODE_STATUS("getOutput");
- default:
- return OMX_ErrorUndefined;
- }
+ // 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;
+ }
- //start getOutput
- Encode_Status ret = mVideoEncoder->getOutput(&outBuf);
+ LOGV("output codec data size = %d", outBuf.dataSize);
- if (ret < ENCODE_SUCCESS) {
- LOGE("libMIX getOutput Failed. ret = 0x%08x, drop this frame\n", ret);
- outBuf.dataSize = 0;
- outBuf.flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
-// return OMX_ErrorUndefined;
+ outflags |= OMX_BUFFERFLAG_CODECCONFIG;
+ outflags |= OMX_BUFFERFLAG_ENDOFFRAME;
+ outflags |= OMX_BUFFERFLAG_SYNCFRAME;
- } else if (ret == ENCODE_BUFFER_TOO_SMALL)
- return OMX_ErrorUndefined; // Return code could not be ENCODE_BUFFER_TOO_SMALL, or we will have dead lock issue
+ // 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;
+ ret = mVideoEncoder->getOutput(&outBuf);
+ CHECK_ENCODE_STATUS("getOutput");
- LOGV("libMIX getOutput data size= %d, flag=0x%08x", outBuf.dataSize, outBuf.flag);
- OMX_U32 outfilledlen = outBuf.dataSize;
- OMX_S64 outtimestamp = outBuf.timeStamp;
- OMX_U32 outflags = 0;
+ LOGV("output data size = %d", outBuf.dataSize);
- //if codecconfig
- if (outBuf.flag & ENCODE_BUFFERFLAG_CODECCONFIG)
- outflags |= OMX_BUFFERFLAG_CODECCONFIG;
-
- //if syncframe
- if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME)
- outflags |= OMX_BUFFERFLAG_SYNCFRAME;
-
- //if eos
- if (outBuf.flag & ENCODE_BUFFERFLAG_ENDOFSTREAM)
- outflags |= OMX_BUFFERFLAG_EOS;
-
- //if full encoded data retrieved
- if(outBuf.flag & ENCODE_BUFFERFLAG_ENDOFFRAME) {
- LOGV("Output a complete Frame done\n");
- outflags |= OMX_BUFFERFLAG_ENDOFFRAME;
-
- if ((NaluFormat == OMX_NaluFormatStartCodesSeparateFirstHeader
- || NaluFormat == OMX_NaluFormatLengthPrefixedSeparateFirstHeader ) && mFirstFrame ) {
- // This input buffer need to be gotten again
- retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
- mFirstFrame = OMX_FALSE;
-
- } else {
- pInfo->DataRetrieved = true;
- ports[INPORT_INDEX]->ReturnAllRetainedBuffers(); //return last all retained frames
- if (outBuf.flag & ENCODE_BUFFERFLAG_ENDOFSTREAM)
- retains[INPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN;
- else
- retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE; //retain current frame
-
- mFrameOutputCount ++;
- }
- } else //not complete output all encoded data, push again to continue output
- retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+ outfilledlen = outBuf.dataSize;
+ outtimestamp = buffers[INPORT_INDEX]->nTimeStamp;
- LOGV("OMX output buffer = %p:%d, flag = %x, ts=%lld", buffers[OUTPORT_INDEX]->pBuffer, outfilledlen, outflags, outtimestamp);
+ 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;
- if (outfilledlen > 0) {
- retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN;
- buffers[OUTPORT_INDEX]->nFilledLen = outfilledlen;
- buffers[OUTPORT_INDEX]->nTimeStamp = outtimestamp;
- buffers[OUTPORT_INDEX]->nFlags = outflags;
- if (outBuf.flag & ENCODE_BUFFERFLAG_NSTOPFRAME)
- buffers[OUTPORT_INDEX]->pPlatformPrivate = (OMX_PTR) 0x00000001; //indicate it is nstop frame
- }
- else
- retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+ } else {
+ retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN; //get again
- LOGV("ProcessDataRetrieve OK\n");
- return OMX_ErrorNone;
-}
+ }
+ }
-OMX_ERRORTYPE OMXVideoEncoderAVC::ProcessorProcess(
- OMX_BUFFERHEADERTYPE **buffers,
- buffer_retain_t *retains,
- OMX_U32 numberBuffers) {
+ if (outfilledlen > 0) {
+ retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN;
+ } else {
+ retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+ }
+ break;
+ case OMX_NaluFormatLengthPrefixedSeparateFirstHeader:
- OMX_ERRORTYPE oret = OMX_ErrorNone;
- Encode_Status ret = ENCODE_SUCCESS;
+ 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;
+ }
- VideoEncRawBuffer inBuf;
+ LOGV("output codec data size = %d", outBuf.dataSize);
- inBuf.data = buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset;
- inBuf.size = buffers[INPORT_INDEX]->nFilledLen;
- inBuf.flag = 0;
- inBuf.timeStamp = buffers[INPORT_INDEX]->nTimeStamp;
-
- if (buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS) {
- LOGV("%s(),%d: got OMX_BUFFERFLAG_EOS\n", __func__, __LINE__);
- if(inBuf.size<=0 || inBuf.data == NULL) {
- LOGE("The Input buf size is 0 or buf is NULL, return with no error\n");
- retains[INPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN;
- return OMX_ErrorNone;
- }
- }
+ outflags |= OMX_BUFFERFLAG_CODECCONFIG;
+ outflags |= OMX_BUFFERFLAG_ENDOFFRAME;
+ outflags |= OMX_BUFFERFLAG_SYNCFRAME;
- if(inBuf.size<=0 || inBuf.data == NULL) {
- LOGE("The Input buf size is 0 or buf is NULL, return with error\n");
- return OMX_ErrorBadParameter;
- }
+ // This input buffer need to be gotten again
+ retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+ outfilledlen = outBuf.dataSize;
+ mFirstFrame = OMX_FALSE;
+ } else {
+ outBuf.format = OUTPUT_LENGTH_PREFIXED;
+ ret = mVideoEncoder->getOutput(&outBuf);
- LOGV("Input OMX Buffer = 0x%x, size=%d, ts = %lld", inBuf.data, inBuf.size, buffers[INPORT_INDEX]->nTimeStamp);
-
- //get frame encode info
- Encode_Info eInfo;
- uint32_t encodeInfo = (uint32_t) buffers[INPORT_INDEX]->pPlatformPrivate;
- eInfo.FrameType = GET_FT(encodeInfo);
- eInfo.EncodeComplete = encodeInfo & ENC_EC;
- eInfo.DataRetrieved = encodeInfo & ENC_DR;
- eInfo.CacheOperation = GET_CO(encodeInfo);
- eInfo.EndOfEncode = encodeInfo & ENC_EOE;
- eInfo.NotStopFrame = encodeInfo & ENC_NSTOP;
- eInfo.FrameCount = GET_FC(encodeInfo);
-
- LOGV("ProcessorProcess Frame %d, type:%s, EC:%d, DR:%d, CO:%s, EOE=%d\n",
- eInfo.FrameCount , FrameTypeStr[eInfo.FrameType], eInfo.EncodeComplete,
- eInfo.DataRetrieved, CacheOperationStr[eInfo.CacheOperation], eInfo.EndOfEncode );
-
- //for live effect
- if (bAndroidOpaqueFormat)
- mCurHandle = rgba2nv12conversion(buffers[INPORT_INDEX]);
+ if (ret < ENCODE_SUCCESS) { \
+ LOGE("getOutput Failed. ret = 0x%08x, drop this frame\n", ret);
+ outBuf.dataSize = 0;
+ outBuf.flag |= ENCODE_BUFFERFLAG_ENDOFFRAME;
+ }
- if (eInfo.CacheOperation == CACHE_PUSH) {
- ProcessCacheOperation(buffers, retains, &eInfo);
- //nothing should be done in this case, just store status and return
- goto exit;
- }else
- ProcessCacheOperation(buffers, retains, &eInfo);
+ LOGV("output data size = %d", outBuf.dataSize);
- /* Check encode state, if not, call libMIX encode()
- */
- if(!eInfo.EncodeComplete) {
- // encode and setConfig need to be thread safe
- if (eInfo.EndOfEncode)
- inBuf.flag |= ENCODE_BUFFERFLAG_ENDOFSTREAM;
- if (eInfo.NotStopFrame)
- inBuf.flag |= ENCODE_BUFFERFLAG_NSTOPFRAME;
- inBuf.type = (FrameType) eInfo.FrameType;
+ outfilledlen = outBuf.dataSize;
+ outtimestamp = buffers[INPORT_INDEX]->nTimeStamp;
- pthread_mutex_lock(&mSerializationLock);
- ret = mVideoEncoder->encode(&inBuf);
- pthread_mutex_unlock(&mSerializationLock);
- CHECK_ENCODE_STATUS("encode");
- eInfo.EncodeComplete = true;
+ 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
+ }
+ }
- mFrameEncodedCount ++;
- if (mFrameEncodedCount == 2) {//not getoutput for second encode frame to keep in async mode
- eInfo.DataRetrieved = true;
- retains[INPORT_INDEX] = BUFFER_RETAIN_ACCUMULATE;
- retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
- }
+ if (outfilledlen > 0) {
+ retains[OUTPORT_INDEX] = BUFFER_RETAIN_NOT_RETAIN;
+ } else {
+ retains[OUTPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+ }
+ break;
}
- /* Check encode data retrieve state, if not complete output, continue call libMIX getOutput()
- */
- if (!eInfo.DataRetrieved)
- oret = ProcessDataRetrieve(buffers, retains, &eInfo);
-
- /* Check EOE state, if yes, this is final encode frame, need to push this buffer again
- to call getOutput again for final output
- */
- if (eInfo.EndOfEncode && eInfo.EncodeComplete && eInfo.DataRetrieved) {
- eInfo.DataRetrieved = false;
- eInfo.EndOfEncode = false;
- retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+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 0
- if (avcEncParamIntelBitrateType.eControlRate != OMX_Video_Intel_ControlRateVideoConferencingMode) {
- if (oret == (OMX_ERRORTYPE) OMX_ErrorIntelExtSliceSizeOverflow) {
- oret = OMX_ErrorNone;
- }
+ if (retains[INPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN ||
+ retains[INPORT_INDEX] == BUFFER_RETAIN_ACCUMULATE ) {
+ mFrameInputCount ++;
}
-#endif
-exit:
+ if (retains[OUTPORT_INDEX] == BUFFER_RETAIN_NOT_RETAIN) mFrameOutputCount ++;
if (bAndroidOpaqueFormat && buffers[INPORT_INDEX]->nFilledLen != 0) {
// Restore input buffer's content
- if (mCurHandle < 0)
- return OMX_ErrorUndefined;
-
buffers[INPORT_INDEX]->nFilledLen = 4 + sizeof(buffer_handle_t);
memcpy(buffers[INPORT_INDEX]->pBuffer, mBufferHandleMaps[mCurHandle].backBuffer,
buffers[INPORT_INDEX]->nFilledLen);
- }
-
- /* restore all states into input OMX buffer
- */
- if (eInfo.EncodeComplete)
- encodeInfo |= ENC_EC;
- else
- encodeInfo &= ~ENC_EC;
- if (eInfo.DataRetrieved)
- encodeInfo |= ENC_DR;
- else
- encodeInfo &= ~ENC_DR;
-
- if (eInfo.EndOfEncode)
- encodeInfo |= ENC_EOE;
- else
- encodeInfo &= ~ENC_EOE;
-
- if (eInfo.NotStopFrame)
- encodeInfo |= ENC_NSTOP;
- else
- encodeInfo &= ~ENC_NSTOP;
+ }
- SET_CO(encodeInfo, eInfo.CacheOperation);
- buffers[INPORT_INDEX]->pPlatformPrivate = (OMX_PTR) encodeInfo;
+#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;
@@ -578,7 +481,6 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::GetParamVideoProfileLevelQuerySupported(OMX_PT
OMX_U32 level;
} plTable[] = {
{OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41},
-// {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel41},
};
OMX_U32 count = sizeof(plTable)/sizeof(ProfileLevelTable);
@@ -612,18 +514,6 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::SetParamVideoAvc(OMX_PTR pStructure) {
CHECK_PORT_INDEX(p, OUTPORT_INDEX);
CHECK_SET_PARAM_STATE();
- if(p->bEnableASO == OMX_TRUE)
- return OMX_ErrorUnsupportedSetting;
-
- if(p->bEnableFMO == OMX_TRUE)
- return OMX_ErrorUnsupportedSetting;
-
- if(p->bEnableUEP == OMX_TRUE)
- return OMX_ErrorUnsupportedSetting;
-
- if(p->bEnableRS == OMX_TRUE)
- return OMX_ErrorUnsupportedSetting;
-
// TODO: do we need to check if port is enabled?
// TODO: see SetPortAvcParam implementation - Can we make simple copy????
memcpy(&mParamAvc, p, sizeof(mParamAvc));
@@ -738,26 +628,12 @@ OMX_ERRORTYPE OMXVideoEncoderAVC::SetConfigVideoAVCIntraPeriod(OMX_PTR pStructur
// TODO: apply AVC Intra Period configuration in Executing state
VideoConfigAVCIntraPeriod avcIntraPreriod;
+ avcIntraPreriod.idrInterval = mConfigAvcIntraPeriod.nIDRPeriod;
avcIntraPreriod.intraPeriod = mConfigAvcIntraPeriod.nPFrames;
- if (avcIntraPreriod.intraPeriod == 0) {
- avcIntraPreriod.idrInterval = 0;
- avcIntraPreriod.ipPeriod = 0;
- } else {
- avcIntraPreriod.idrInterval = mConfigAvcIntraPeriod.nIDRPeriod;
- if (mParamAvc.eProfile == OMX_VIDEO_AVCProfileBaseline) {
- avcIntraPreriod.ipPeriod = 1;
- } else if (mParamAvc.eProfile == OMX_VIDEO_AVCProfileHigh) {
- avcIntraPreriod.ipPeriod = avcIntraPreriod.intraPeriod / mParamAvc.nPFrames;
- }
- }
retStatus = mVideoEncoder->setConfig(&avcIntraPreriod);
if(retStatus != ENCODE_SUCCESS) {
- LOGW("set avc intra period config failed");
+ LOGW("set avc intra prerod config failed");
}
-
- mEncoderParams->intraPeriod = avcIntraPreriod.intraPeriod;
- mAVCParams->idrInterval = avcIntraPreriod.idrInterval;
- mAVCParams->ipPeriod = avcIntraPreriod.ipPeriod;
return OMX_ErrorNone;
}
diff --git a/videocodec/OMXVideoEncoderAVC.h b/videocodec/OMXVideoEncoderAVC.h
index 28a2d62..1f32118 100644
--- a/videocodec/OMXVideoEncoderAVC.h
+++ b/videocodec/OMXVideoEncoderAVC.h
@@ -20,53 +20,6 @@
#include "OMXVideoEncoderBase.h"
-#include <utils/List.h>
-
-enum {
- F_UNKNOWN = 0x00, // Unknown
- F_I = 0x01, // General I-frame type
- F_P = 0x02, // General P-frame type
- F_B = 0x03, // General B-frame type
- F_SI = 0x04, // H.263 SI-frame type
- F_SP = 0x05, // H.263 SP-frame type
- F_EI = 0x06, // H.264 EI-frame type
- F_EP = 0x07, // H.264 EP-frame type
- F_S = 0x08, // MPEG-4 S-frame type
- F_IDR = 0x09, // IDR-frame type
-};
-
-enum {
- CACHE_NONE = 0x00, //nothing to be done
- CACHE_PUSH = 0x01, //push this frame into cache
- CACHE_POP = 0x02, //pop all from cache into queue head by STACK rule
- CACHE_RESET = 0x03, //reset cache, clear all cached frames
-};
-
-#define ENC_EC 0x08000000
-#define ENC_DR 0x04000000
-#define ENC_EOE 0x00800000
-#define ENC_NSTOP 0x00400000
-
-#define GET_FT(x) ( (x & 0xF0000000 ) >> 28 ) //get frame type
-#define GET_CO(x) ( (x & 0x03000000 ) >> 24 ) //get cache operation
-#define GET_FC(x) ( (x & 0x003FFFFF ) ) //get frame count
-
-#define SET_FT(x, y) { x = ((x & ~0xF0000000) | (y << 28)); }
-#define SET_CO(x, y) { x = ((x & ~0x03000000) | (y << 24 )); }
-#define SET_FC(x, y) { x = ((x & ~0x003FFFFF) | (y & 0x003FFFFF )); }
-
-const char* FrameTypeStr[10] = {"UNKNOWN", "I", "P", "B", "SI", "SP", "EI", "EP", "S", "IDR"};
-const char* CacheOperationStr[4]= {"NONE", "PUSH", "POP", "RESET"};
-
-typedef struct {
- uint32_t FrameType;
- bool EncodeComplete;
- bool DataRetrieved;
- uint32_t CacheOperation;
- bool EndOfEncode;
- bool NotStopFrame;
- uint32_t FrameCount;
-}Encode_Info;
class OMXVideoEncoderAVC : public OMXVideoEncoderBase {
public:
@@ -77,12 +30,10 @@ protected:
virtual OMX_ERRORTYPE InitOutputPortFormatSpecific(OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput);
virtual OMX_ERRORTYPE ProcessorInit(void);
virtual OMX_ERRORTYPE ProcessorDeinit(void);
- virtual OMX_ERRORTYPE ProcessorStop(void);
virtual OMX_ERRORTYPE ProcessorProcess(
OMX_BUFFERHEADERTYPE **buffers,
buffer_retain_t *retains,
OMX_U32 numberBuffers);
- virtual OMX_ERRORTYPE ProcessorPreEmptyBuffer(OMX_BUFFERHEADERTYPE* buffer);
virtual OMX_ERRORTYPE BuildHandlerList(void);
virtual OMX_ERRORTYPE SetVideoEncoderParam();
@@ -114,21 +65,6 @@ private:
OMX_VIDEO_PARAM_INTEL_AVCVUI mParamIntelAvcVui;
OMX_VIDEO_CONFIG_INTEL_SLICE_NUMBERS mConfigIntelSliceNumbers;
VideoParamsAVC *mAVCParams;
-
- OMX_U32 mInputPictureCount;
- OMX_U32 mFrameEncodedCount;
-
- List<OMX_BUFFERHEADERTYPE*> mBFrameList;
-
- OMX_ERRORTYPE ProcessCacheOperation(
- OMX_BUFFERHEADERTYPE **buffers,
- buffer_retain_t *retains,
- Encode_Info *pInfo);
- OMX_ERRORTYPE ProcessDataRetrieve(
- OMX_BUFFERHEADERTYPE **buffers,
- buffer_retain_t *retains,
- Encode_Info *pInfo);
-
};
#endif /* OMX_VIDEO_ENCODER_AVC_H_ */
diff --git a/videocodec/OMXVideoEncoderBase.cpp b/videocodec/OMXVideoEncoderBase.cpp
index 70d6b60..63ab076 100644
--- a/videocodec/OMXVideoEncoderBase.cpp
+++ b/videocodec/OMXVideoEncoderBase.cpp
@@ -28,6 +28,7 @@ OMXVideoEncoderBase::OMXVideoEncoderBase()
,mEncoderParams(NULL)
,mFrameInputCount(0)
,mFrameOutputCount(0)
+ ,mPFrames(0)
,mFrameRetrieved(OMX_TRUE)
,mFirstFrame(OMX_TRUE)
,mStoreMetaDataInBuffers(OMX_FALSE) {
@@ -270,11 +271,11 @@ OMX_ERRORTYPE OMXVideoEncoderBase::SetVideoEncoderParam() {
mConfigFramerate.xEncodeFramerate = paramPortDefinitionInput->format.video.xFramerate >> 16;
}
- if(mEncoderParams->intraPeriod == 0) {
- OMX_U32 intraPeriod = mEncoderParams->frameRate.frameRateNum / 2;
- mEncoderParams->intraPeriod = (intraPeriod < 15) ? 15 : intraPeriod; // Limit intra frame period to ensure video quality for low bitrate application.
+ if(mPFrames == 0) {
+ mPFrames = mEncoderParams->frameRate.frameRateNum / 2;
+ mPFrames = (mPFrames < 15) ? 15 : mPFrames; // Limit intra frame period to ensure video quality for low bitrate application.
}
-
+ mEncoderParams->intraPeriod = mPFrames;
mEncoderParams->rawFormat = RAW_FORMAT_NV12;
LOGV("frameRate.frameRateDenom = %d\n", mEncoderParams->frameRate.frameRateDenom);
diff --git a/videocodec/OMXVideoEncoderBase.h b/videocodec/OMXVideoEncoderBase.h
index 45bce8f..bb8cb1e 100644
--- a/videocodec/OMXVideoEncoderBase.h
+++ b/videocodec/OMXVideoEncoderBase.h
@@ -103,6 +103,8 @@ private:
OUTPORT_BUFFER_SIZE = 1382400,
};
+ OMX_U32 mPFrames;
+
public:
struct {
OMX_BUFFERHEADERTYPE* mHeader;
diff --git a/videocodec/OMXVideoEncoderH263.cpp b/videocodec/OMXVideoEncoderH263.cpp
index 8bbe4b6..00d66e7 100644
--- a/videocodec/OMXVideoEncoderH263.cpp
+++ b/videocodec/OMXVideoEncoderH263.cpp
@@ -114,9 +114,6 @@ OMX_ERRORTYPE OMXVideoEncoderH263::ProcessorProcess(
inBuf.data = buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset;
inBuf.size = buffers[INPORT_INDEX]->nFilledLen;
- inBuf.type = FTYPE_UNKNOWN;
- inBuf.flag = 0;
- inBuf.timeStamp = buffers[INPORT_INDEX]->nTimeStamp;
LOGV("buffer_in.data=%x, data_size=%d",
(unsigned)inBuf.data, inBuf.size);
@@ -151,7 +148,7 @@ OMX_ERRORTYPE OMXVideoEncoderH263::ProcessorProcess(
LOGV("output data size = %d", outBuf.dataSize);
outfilledlen = outBuf.dataSize;
- outtimestamp = outBuf.timeStamp;
+ outtimestamp = buffers[INPORT_INDEX]->nTimeStamp;
if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) {
diff --git a/videocodec/OMXVideoEncoderMPEG4.cpp b/videocodec/OMXVideoEncoderMPEG4.cpp
index c2df1fd..918b391 100644
--- a/videocodec/OMXVideoEncoderMPEG4.cpp
+++ b/videocodec/OMXVideoEncoderMPEG4.cpp
@@ -104,9 +104,6 @@ OMX_ERRORTYPE OMXVideoEncoderMPEG4::ProcessorProcess(
inBuf.data = buffers[INPORT_INDEX]->pBuffer + buffers[INPORT_INDEX]->nOffset;
inBuf.size = buffers[INPORT_INDEX]->nFilledLen;
- inBuf.type = FTYPE_UNKNOWN;
- inBuf.flag = 0;
- inBuf.timeStamp = buffers[INPORT_INDEX]->nTimeStamp;
if (bAndroidOpaqueFormat) {
mCurHandle = rgba2nv12conversion(buffers[INPORT_INDEX]);
@@ -163,7 +160,7 @@ OMX_ERRORTYPE OMXVideoEncoderMPEG4::ProcessorProcess(
outfilledlen = outBuf.dataSize;
- outtimestamp = outBuf.timeStamp;
+ outtimestamp = buffers[INPORT_INDEX]->nTimeStamp;
if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) {
outflags |= OMX_BUFFERFLAG_SYNCFRAME;