diff options
| author | Juan Antonio Gozalvez Herrero <jgozalvx> | 2013-01-15 11:17:57 +0100 |
|---|---|---|
| committer | Patrick Tjin <pattjin@google.com> | 2014-07-21 22:02:49 -0700 |
| commit | e4876b874be60356322ca55b467fd0ee096ee7ab (patch) | |
| tree | 49909fa7c449bd300c7a11c2a06fc970cccf4115 /videocodec/OMXVideoEncoderAVC.cpp | |
| parent | 0d275ff362298b443c828f09f593bfb674112bbd (diff) | |
| download | android_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/OMXVideoEncoderAVC.cpp')
| -rw-r--r-- | videocodec/OMXVideoEncoderAVC.cpp | 600 |
1 files changed, 238 insertions, 362 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; } |
