diff options
author | Doney Alex <doney.alex@ittiam.com> | 2015-06-01 18:14:02 +0530 |
---|---|---|
committer | Marco Nelissen <marcone@google.com> | 2015-06-25 10:36:40 -0700 |
commit | 1ad56353aec03b0255d5cd5b67f9e6df780d9b65 (patch) | |
tree | db30f8486a228e63d364ddb72074166a8a00931b /media/libstagefright/codecs/avcenc | |
parent | defb2374a0e0adbd3714a2cd02be3c309cde4875 (diff) | |
download | frameworks_av-1ad56353aec03b0255d5cd5b67f9e6df780d9b65.zip frameworks_av-1ad56353aec03b0255d5cd5b67f9e6df780d9b65.tar.gz frameworks_av-1ad56353aec03b0255d5cd5b67f9e6df780d9b65.tar.bz2 |
SoftAVCEnc: Added support for Main Profile encoding.
Configured intra frame interval and deblock in setParams.
Change-Id: If501fa0ac42f2c4bf6604ea84715f7f13f707e74
Diffstat (limited to 'media/libstagefright/codecs/avcenc')
-rw-r--r-- | media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp | 290 | ||||
-rw-r--r-- | media/libstagefright/codecs/avcenc/SoftAVCEnc.h | 33 |
2 files changed, 203 insertions, 120 deletions
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp index a00f324..9ee3518 100644 --- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp +++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp @@ -49,10 +49,10 @@ static void InitOMXParams(T *params) { params->nVersion.s.nStep = 0; } -typedef struct LevelConversion { +struct LevelConversion { OMX_VIDEO_AVCLEVELTYPE omxLevel; WORD32 avcLevel; -} LevelConcersion; +}; static LevelConversion ConversionTable[] = { { OMX_VIDEO_AVCLevel1, 10 }, @@ -87,8 +87,21 @@ static const CodecProfileLevel kProfileLevels[] = { { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel32 }, { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel4 }, { OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel41 }, -}; + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1 }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel1b }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel11 }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel12 }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel13 }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel2 }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel21 }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel22 }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel3 }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel31 }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel32 }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel4 }, + { OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel41 }, +}; static size_t GetCPUCoreCount() { long cpuCoreCount = 1; @@ -99,7 +112,7 @@ static size_t GetCPUCoreCount() { cpuCoreCount = sysconf(_SC_NPROC_ONLN); #endif CHECK(cpuCoreCount >= 1); - ALOGD("Number of CPU cores: %ld", cpuCoreCount); + ALOGV("Number of CPU cores: %ld", cpuCoreCount); return (size_t)cpuCoreCount; } @@ -144,15 +157,15 @@ SoftAVC::SoftAVC( kProfileLevels, NELEM(kProfileLevels), 176 /* width */, 144 /* height */, callbacks, appData, component), + mBitrateUpdated(false), + mKeyFrameRequested(false), mIvVideoColorFormat(IV_YUV_420P), - mIDRFrameRefreshIntervalInSec(1), mAVCEncProfile(IV_PROFILE_BASE), - mAVCEncLevel(31), - mPrevTimestampUs(-1), + mAVCEncLevel(41), mStarted(false), mSawInputEOS(false), + mSawOutputEOS(false), mSignalledError(false), - mConversionBuffer(NULL), mCodecCtx(NULL) { initPorts(kNumBuffers, kNumBuffers, ((mWidth * mHeight * 3) >> 1), @@ -162,6 +175,10 @@ SoftAVC::SoftAVC( GENERATE_FILE_NAMES(); CREATE_DUMP_FILE(mInFile); CREATE_DUMP_FILE(mOutFile); + memset(mConversionBuffers, 0, sizeof(mConversionBuffers)); + memset(mInputBufferInfo, 0, sizeof(mInputBufferInfo)); + + initEncParams(); } @@ -173,7 +190,7 @@ SoftAVC::~SoftAVC() { CHECK(inQueue.empty()); } -OMX_ERRORTYPE SoftAVC::initEncParams() { +void SoftAVC::initEncParams() { mCodecCtx = NULL; mMemRecords = NULL; mNumMemRecords = DEFAULT_MEM_REC_CNT; @@ -186,7 +203,6 @@ OMX_ERRORTYPE SoftAVC::initEncParams() { mIInterval = DEFAULT_I_INTERVAL; mIDRInterval = DEFAULT_IDR_INTERVAL; mDisableDeblkLevel = DEFAULT_DISABLE_DEBLK_LEVEL; - mFrameRate = DEFAULT_SRC_FRAME_RATE; mEnableFastSad = DEFAULT_ENABLE_FAST_SAD; mEnableAltRef = DEFAULT_ENABLE_ALT_REF; mEncSpeed = DEFAULT_ENC_SPEED; @@ -195,11 +211,12 @@ OMX_ERRORTYPE SoftAVC::initEncParams() { mAIRRefreshPeriod = DEFAULT_AIR_REFRESH_PERIOD; mPSNREnable = DEFAULT_PSNR_ENABLE; mReconEnable = DEFAULT_RECON_ENABLE; + mEntropyMode = DEFAULT_ENTROPY_MODE; + mBframes = DEFAULT_B_FRAMES; gettimeofday(&mTimeStart, NULL); gettimeofday(&mTimeEnd, NULL); - return OMX_ErrorNone; } @@ -260,8 +277,8 @@ OMX_ERRORTYPE SoftAVC::setFrameRate() { s_frame_rate_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_frame_rate_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE; - s_frame_rate_ip.u4_src_frame_rate = mFrameRate; - s_frame_rate_ip.u4_tgt_frame_rate = mFrameRate; + s_frame_rate_ip.u4_src_frame_rate = mFramerate >> 16; + s_frame_rate_ip.u4_tgt_frame_rate = mFramerate >> 16; s_frame_rate_ip.u4_timestamp_high = -1; s_frame_rate_ip.u4_timestamp_low = -1; @@ -332,7 +349,6 @@ OMX_ERRORTYPE SoftAVC::setFrameType(IV_PICTURE_CODING_TYPE_T e_frame_type) { ive_ctl_set_frame_type_ip_t s_frame_type_ip; ive_ctl_set_frame_type_op_t s_frame_type_op; IV_STATUS_T status; - s_frame_type_ip.e_cmd = IVE_CMD_VIDEO_CTL; s_frame_type_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE; @@ -503,7 +519,6 @@ OMX_ERRORTYPE SoftAVC::setGopParams() { s_gop_params_ip.u4_i_frm_interval = mIInterval; s_gop_params_ip.u4_idr_frm_interval = mIDRInterval; - s_gop_params_ip.u4_num_b_frames = DEFAULT_B_FRAMES; s_gop_params_ip.u4_timestamp_high = -1; s_gop_params_ip.u4_timestamp_low = -1; @@ -529,7 +544,7 @@ OMX_ERRORTYPE SoftAVC::setProfileParams() { s_profile_params_ip.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS; s_profile_params_ip.e_profile = DEFAULT_EPROFILE; - + s_profile_params_ip.u4_entropy_coding_mode = mEntropyMode; s_profile_params_ip.u4_timestamp_high = -1; s_profile_params_ip.u4_timestamp_low = -1; @@ -595,7 +610,6 @@ void SoftAVC::logVersion() { OMX_ERRORTYPE SoftAVC::initEncoder() { IV_STATUS_T status; - size_t i; WORD32 level; uint32_t displaySizeY; CHECK(!mStarted); @@ -618,31 +632,26 @@ OMX_ERRORTYPE SoftAVC::initEncoder() { } mAVCEncLevel = MAX(level, mAVCEncLevel); - if (OMX_ErrorNone != (errType = initEncParams())) { - ALOGE("Failed to initialize encoder params"); - mSignalledError = true; - notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); - return errType; - } - mStride = mWidth; if (mInputDataIsMeta) { - if (mConversionBuffer) { - free(mConversionBuffer); - mConversionBuffer = NULL; - } + for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { + if (mConversionBuffers[i] != NULL) { + free(mConversionBuffers[i]); + } - if (mConversionBuffer == NULL) { if (((uint64_t)mStride * mHeight) > (((uint64_t)INT32_MAX / 3) * 2)) { ALOGE("Buffer size is too big."); return OMX_ErrorUndefined; } - mConversionBuffer = (uint8_t *)malloc(mStride * mHeight * 3 / 2); - if (mConversionBuffer == NULL) { + mConversionBuffers[i] = (uint8_t *)malloc(mStride * mHeight * 3 / 2); + + if (mConversionBuffers[i] == NULL) { ALOGE("Allocating conversion buffer failed."); return OMX_ErrorUndefined; } + + mConversionBuffersFree[i] = 1; } } @@ -658,7 +667,7 @@ OMX_ERRORTYPE SoftAVC::initEncoder() { break; } - ALOGV("Params width %d height %d level %d colorFormat %d", mWidth, + ALOGD("Params width %d height %d level %d colorFormat %d", mWidth, mHeight, mAVCEncLevel, mIvVideoColorFormat); /* Getting Number of MemRecords */ @@ -699,7 +708,7 @@ OMX_ERRORTYPE SoftAVC::initEncoder() { { iv_mem_rec_t *ps_mem_rec; ps_mem_rec = mMemRecords; - for (i = 0; i < mNumMemRecords; i++) { + for (size_t i = 0; i < mNumMemRecords; i++) { ps_mem_rec->u4_size = sizeof(iv_mem_rec_t); ps_mem_rec->pv_base = NULL; ps_mem_rec->u4_mem_size = 0; @@ -746,9 +755,9 @@ OMX_ERRORTYPE SoftAVC::initEncoder() { WORD32 total_size; iv_mem_rec_t *ps_mem_rec; total_size = 0; - ps_mem_rec = mMemRecords; - for (i = 0; i < mNumMemRecords; i++) { + + for (size_t i = 0; i < mNumMemRecords; i++) { ps_mem_rec->pv_base = ive_aligned_malloc( ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size); if (ps_mem_rec->pv_base == NULL) { @@ -763,7 +772,6 @@ OMX_ERRORTYPE SoftAVC::initEncoder() { ps_mem_rec++; } - printf("\nTotal memory for codec %d\n", total_size); } /* Codec Instance Creation */ @@ -797,7 +805,7 @@ OMX_ERRORTYPE SoftAVC::initEncoder() { s_init_ip.e_rc_mode = DEFAULT_RC_MODE; s_init_ip.u4_max_framerate = DEFAULT_MAX_FRAMERATE; s_init_ip.u4_max_bitrate = DEFAULT_MAX_BITRATE; - s_init_ip.u4_max_num_bframes = DEFAULT_B_FRAMES; + s_init_ip.u4_num_bframes = mBframes; s_init_ip.e_content_type = IV_PROGRESSIVE; s_init_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; s_init_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; @@ -872,7 +880,6 @@ OMX_ERRORTYPE SoftAVC::releaseEncoder() { iv_retrieve_mem_rec_ip_t s_retrieve_mem_ip; iv_retrieve_mem_rec_op_t s_retrieve_mem_op; iv_mem_rec_t *ps_mem_rec; - UWORD32 i; if (!mStarted) { return OMX_ErrorNone; @@ -893,16 +900,18 @@ OMX_ERRORTYPE SoftAVC::releaseEncoder() { /* Free memory records */ ps_mem_rec = mMemRecords; - for (i = 0; i < s_retrieve_mem_op.u4_num_mem_rec_filled; i++) { + for (size_t i = 0; i < s_retrieve_mem_op.u4_num_mem_rec_filled; i++) { ive_aligned_free(ps_mem_rec->pv_base); ps_mem_rec++; } free(mMemRecords); - if (mConversionBuffer != NULL) { - free(mConversionBuffer); - mConversionBuffer = NULL; + for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { + if (mConversionBuffers[i]) { + free(mConversionBuffers[i]); + mConversionBuffers[i] = NULL; + } } mStarted = false; @@ -934,23 +943,21 @@ OMX_ERRORTYPE SoftAVC::internalGetParameter(OMX_INDEXTYPE index, OMX_PTR params) return OMX_ErrorUndefined; } - avcParams->eProfile = OMX_VIDEO_AVCProfileBaseline; - OMX_VIDEO_AVCLEVELTYPE omxLevel = OMX_VIDEO_AVCLevel31; + OMX_VIDEO_AVCLEVELTYPE omxLevel = OMX_VIDEO_AVCLevel41; if (OMX_ErrorNone != ConvertAvcSpecLevelToOmxAvcLevel(mAVCEncLevel, &omxLevel)) { return OMX_ErrorUndefined; } + avcParams->eProfile = OMX_VIDEO_AVCProfileBaseline; avcParams->eLevel = omxLevel; avcParams->nRefFrames = 1; - avcParams->nBFrames = 0; avcParams->bUseHadamard = OMX_TRUE; avcParams->nAllowedPictureTypes = (OMX_VIDEO_PictureTypeI - | OMX_VIDEO_PictureTypeP); + | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB); avcParams->nRefIdx10ActiveMinus1 = 0; avcParams->nRefIdx11ActiveMinus1 = 0; avcParams->bWeightedPPrediction = OMX_FALSE; - avcParams->bEntropyCodingCABAC = OMX_FALSE; avcParams->bconstIpred = OMX_FALSE; avcParams->bDirect8x8Inference = OMX_FALSE; avcParams->bDirectSpatialTemporal = OMX_FALSE; @@ -981,14 +988,26 @@ OMX_ERRORTYPE SoftAVC::internalSetParameter(OMX_INDEXTYPE index, const OMX_PTR p return OMX_ErrorUndefined; } - if (avcType->eProfile != OMX_VIDEO_AVCProfileBaseline - || avcType->nRefFrames != 1 || avcType->nBFrames != 0 + mEntropyMode = 0; + + if (OMX_TRUE == avcType->bEntropyCodingCABAC) + mEntropyMode = 1; + + if ((avcType->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) && + avcType->nPFrames) { + mBframes = avcType->nBFrames / avcType->nPFrames; + } + + mIInterval = avcType->nPFrames + avcType->nBFrames; + + if (OMX_VIDEO_AVCLoopFilterDisable == avcType->eLoopFilterMode) + mDisableDeblkLevel = 4; + + if (avcType->nRefFrames != 1 || avcType->bUseHadamard != OMX_TRUE - || (avcType->nAllowedPictureTypes & OMX_VIDEO_PictureTypeB) != 0 || avcType->nRefIdx10ActiveMinus1 != 0 || avcType->nRefIdx11ActiveMinus1 != 0 || avcType->bWeightedPPrediction != OMX_FALSE - || avcType->bEntropyCodingCABAC != OMX_FALSE || avcType->bconstIpred != OMX_FALSE || avcType->bDirect8x8Inference != OMX_FALSE || avcType->bDirectSpatialTemporal != OMX_FALSE @@ -1083,14 +1102,27 @@ OMX_ERRORTYPE SoftAVC::setEncodeArgs( /* Initialize color formats */ ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat; - source = NULL; - if (inputBufferHeader) { + if ((inputBufferHeader != NULL) && inputBufferHeader->nFilledLen) { source = inputBufferHeader->pBuffer + inputBufferHeader->nOffset; if (mInputDataIsMeta) { + uint8_t *conversionBuffer = NULL; + for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { + if (mConversionBuffersFree[i]) { + mConversionBuffersFree[i] = 0; + conversionBuffer = mConversionBuffers[i]; + break; + } + } + + if (NULL == conversionBuffer) { + ALOGE("No free buffers to hold conversion data"); + return OMX_ErrorUndefined; + } + source = extractGraphicBuffer( - mConversionBuffer, (mWidth * mHeight * 3 / 2), source, + conversionBuffer, (mWidth * mHeight * 3 / 2), source, inputBufferHeader->nFilledLen, mWidth, mHeight); if (source == NULL) { @@ -1099,6 +1131,18 @@ OMX_ERRORTYPE SoftAVC::setEncodeArgs( return OMX_ErrorUndefined; } } + ps_encode_ip->u4_is_last = 0; + ps_encode_ip->u4_timestamp_high = (inputBufferHeader->nTimeStamp) >> 32; + ps_encode_ip->u4_timestamp_low = (inputBufferHeader->nTimeStamp) & 0xFFFFFFFF; + } + else { + if (mSawInputEOS){ + ps_encode_ip->u4_is_last = 1; + } + memset(ps_inp_raw_buf, 0, sizeof(iv_raw_buf_t)); + ps_inp_raw_buf->e_color_fmt = mIvVideoColorFormat; + ps_inp_raw_buf->u4_size = sizeof(iv_raw_buf_t); + return OMX_ErrorNone; } pu1_buf = (UWORD8 *)source; @@ -1153,14 +1197,6 @@ OMX_ERRORTYPE SoftAVC::setEncodeArgs( break; } } - - ps_encode_ip->u4_is_last = 0; - - if (inputBufferHeader) { - ps_encode_ip->u4_timestamp_high = (inputBufferHeader->nTimeStamp) >> 32; - ps_encode_ip->u4_timestamp_low = (inputBufferHeader->nTimeStamp) & 0xFFFFFFFF; - } - return OMX_ErrorNone; } @@ -1178,38 +1214,31 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) { return; } } - if (mSignalledError || mSawInputEOS) { + if (mSignalledError) { return; } List<BufferInfo *> &inQueue = getPortQueue(0); List<BufferInfo *> &outQueue = getPortQueue(1); - while (!mSawInputEOS && !inQueue.empty() && !outQueue.empty()) { + while (!mSawOutputEOS && !outQueue.empty()) { + OMX_ERRORTYPE error; ive_video_encode_ip_t s_encode_ip; ive_video_encode_op_t s_encode_op; - - BufferInfo *inputBufferInfo = *inQueue.begin(); - OMX_BUFFERHEADERTYPE *inputBufferHeader = inputBufferInfo->mHeader; - BufferInfo *outputBufferInfo = *outQueue.begin(); OMX_BUFFERHEADERTYPE *outputBufferHeader = outputBufferInfo->mHeader; - if (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS && - inputBufferHeader->nFilledLen == 0) { - mSawInputEOS = true; + BufferInfo *inputBufferInfo; + OMX_BUFFERHEADERTYPE *inputBufferHeader; - inQueue.erase(inQueue.begin()); - inputBufferInfo->mOwnedByUs = false; - notifyEmptyBufferDone(inputBufferHeader); - - outputBufferHeader->nFilledLen = 0; - outputBufferHeader->nFlags = OMX_BUFFERFLAG_EOS; - - outQueue.erase(outQueue.begin()); - outputBufferInfo->mOwnedByUs = false; - notifyFillBufferDone(outputBufferHeader); + if (mSawInputEOS) { + inputBufferHeader = NULL; + inputBufferInfo = NULL; + } else if (!inQueue.empty()) { + inputBufferInfo = *inQueue.begin(); + inputBufferHeader = inputBufferInfo->mHeader; + } else { return; } @@ -1219,6 +1248,10 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) { outputBufferHeader->nFilledLen = 0; outputBufferHeader->nOffset = 0; + if (inputBufferHeader != NULL) { + outputBufferHeader->nFlags = inputBufferHeader->nFlags; + } + uint8_t *outPtr = (uint8_t *)outputBufferHeader->pBuffer; if (!mSpsPpsHeaderReceived) { @@ -1242,10 +1275,13 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) { outputBufferHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG; outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes; - outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp; + if (inputBufferHeader != NULL) { + outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp; + } outQueue.erase(outQueue.begin()); outputBufferInfo->mOwnedByUs = false; + DUMP_TO_FILE( mOutFile, outputBufferHeader->pBuffer, outputBufferHeader->nFilledLen); @@ -1263,14 +1299,24 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) { setFrameType(IV_IDR_FRAME); } - mPrevTimestampUs = inputBufferHeader->nTimeStamp; - - if (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS) { + if ((inputBufferHeader != NULL) + && (inputBufferHeader->nFlags & OMX_BUFFERFLAG_EOS)) { mSawInputEOS = true; } + /* In normal mode, store inputBufferInfo and this will be returned + when encoder consumes this input */ + if (!mInputDataIsMeta && (inputBufferInfo != NULL)) { + for (size_t i = 0; i < MAX_INPUT_BUFFER_HEADERS; i++) { + if (NULL == mInputBufferInfo[i]) { + mInputBufferInfo[i] = inputBufferInfo; + break; + } + } + } error = setEncodeArgs( &s_encode_ip, &s_encode_op, inputBufferHeader, outputBufferHeader); + if (error != OMX_ErrorNone) { mSignalledError = true; notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); @@ -1280,14 +1326,11 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) { DUMP_TO_FILE( mInFile, s_encode_ip.s_inp_buf.apv_bufs[0], (mHeight * mStride * 3 / 2)); - //DUMP_TO_FILE(mInFile, inputBufferHeader->pBuffer + inputBufferHeader->nOffset, - // inputBufferHeader->nFilledLen); GETTIME(&mTimeStart, NULL); /* Compute time elapsed between end of previous decode() * to start of current decode() */ TIME_DIFF(mTimeEnd, mTimeStart, timeDelay); - status = ive_api_function(mCodecCtx, &s_encode_ip, &s_encode_op); if (IV_SUCCESS != status) { @@ -1305,38 +1348,77 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) { ALOGV("timeTaken=%6d delay=%6d numBytes=%6d", timeTaken, timeDelay, s_encode_op.s_out_buf.u4_bytes); + /* In encoder frees up an input buffer, mark it as free */ + if (s_encode_op.s_inp_buf.apv_bufs[0] != NULL) { + if (mInputDataIsMeta) { + for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { + if (mConversionBuffers[i] == s_encode_op.s_inp_buf.apv_bufs[0]) { + mConversionBuffersFree[i] = 1; + break; + } + } + } else { + /* In normal mode, call EBD on inBuffeHeader that is freed by the codec */ + for (size_t i = 0; i < MAX_INPUT_BUFFER_HEADERS; i++) { + uint8_t *buf = NULL; + OMX_BUFFERHEADERTYPE *bufHdr = NULL; + if (mInputBufferInfo[i] != NULL) { + bufHdr = mInputBufferInfo[i]->mHeader; + buf = bufHdr->pBuffer + bufHdr->nOffset; + } + if (s_encode_op.s_inp_buf.apv_bufs[0] == buf) { + mInputBufferInfo[i]->mOwnedByUs = false; + notifyEmptyBufferDone(bufHdr); + mInputBufferInfo[i] = NULL; + break; + } + } + } + } - outputBufferHeader->nFlags = inputBufferHeader->nFlags; outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes; - outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp; - if (IV_IDR_FRAME - == s_encode_op.u4_encoded_frame_type) { + if (IV_IDR_FRAME == s_encode_op.u4_encoded_frame_type) { outputBufferHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME; } - inQueue.erase(inQueue.begin()); - inputBufferInfo->mOwnedByUs = false; + if (inputBufferHeader != NULL) { + inQueue.erase(inQueue.begin()); - notifyEmptyBufferDone(inputBufferHeader); + /* If in meta data, call EBD on input */ + /* In case of normal mode, EBD will be done once encoder + releases the input buffer */ + if (mInputDataIsMeta) { + inputBufferInfo->mOwnedByUs = false; + notifyEmptyBufferDone(inputBufferHeader); + } + } - if (mSawInputEOS) { + if (s_encode_op.u4_is_last) { outputBufferHeader->nFlags |= OMX_BUFFERFLAG_EOS; + mSawOutputEOS = true; + } else { + outputBufferHeader->nFlags &= ~OMX_BUFFERFLAG_EOS; } - outputBufferInfo->mOwnedByUs = false; - outQueue.erase(outQueue.begin()); - - DUMP_TO_FILE( - mOutFile, outputBufferHeader->pBuffer, - outputBufferHeader->nFilledLen); - notifyFillBufferDone(outputBufferHeader); + if (outputBufferHeader->nFilledLen || s_encode_op.u4_is_last) { + outputBufferHeader->nTimeStamp = s_encode_op.u4_timestamp_high; + outputBufferHeader->nTimeStamp <<= 32; + outputBufferHeader->nTimeStamp |= s_encode_op.u4_timestamp_low; + outputBufferInfo->mOwnedByUs = false; + outQueue.erase(outQueue.begin()); + DUMP_TO_FILE(mOutFile, outputBufferHeader->pBuffer, + outputBufferHeader->nFilledLen); + notifyFillBufferDone(outputBufferHeader); + } + if (s_encode_op.u4_is_last == 1) { + return; + } } return; } - } // namespace android android::SoftOMXComponent *createSoftOMXComponent( diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h index 2b35d45..4418a7f 100644 --- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h +++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h @@ -17,7 +17,7 @@ #ifndef __SOFT_AVC_ENC_H__ #define __SOFT_AVC_ENC_H__ -#include <media/stagefright/MediaBuffer.h> + #include <media/stagefright/foundation/ABase.h> #include <utils/Vector.h> @@ -25,14 +25,14 @@ namespace android { -class MediaBuffer; - +#define MAX_INPUT_BUFFER_HEADERS 4 +#define MAX_CONVERSION_BUFFERS 4 #define CODEC_MAX_CORES 4 #define LEN_STATUS_BUFFER (10 * 1024) #define MAX_VBV_BUFF_SIZE (120 * 16384) #define MAX_NUM_IO_BUFS 3 -#define DEFAULT_MAX_REF_FRM 1 +#define DEFAULT_MAX_REF_FRM 2 #define DEFAULT_MAX_REORDER_FRM 0 #define DEFAULT_QP_MIN 10 #define DEFAULT_QP_MAX 40 @@ -57,7 +57,7 @@ class MediaBuffer; #define DEFAULT_TGT_FRAME_RATE 30 #define DEFAULT_MAX_WD 1920 #define DEFAULT_MAX_HT 1920 -#define DEFAULT_MAX_LEVEL 40 +#define DEFAULT_MAX_LEVEL 41 #define DEFAULT_STRIDE 0 #define DEFAULT_WD 1280 #define DEFAULT_HT 720 @@ -88,6 +88,7 @@ class MediaBuffer; #define DEFAULT_QPEL 1 #define DEFAULT_I4 1 #define DEFAULT_EPROFILE IV_PROFILE_BASE +#define DEFAULT_ENTROPY_MODE 0 #define DEFAULT_SLICE_MODE IVE_SLICE_MODE_NONE #define DEFAULT_SLICE_PARAM 256 #define DEFAULT_ARCH ARCH_ARM_A9Q @@ -149,8 +150,6 @@ private: int32_t mStride; - uint32_t mFrameRate; - struct timeval mTimeStart; // Time at the start of decode() struct timeval mTimeEnd; // Time at the end of decode() @@ -167,32 +166,32 @@ private: IV_COLOR_FORMAT_T mIvVideoColorFormat; - int32_t mIDRFrameRefreshIntervalInSec; IV_PROFILE_T mAVCEncProfile; WORD32 mAVCEncLevel; - int64_t mNumInputFrames; - int64_t mPrevTimestampUs; bool mStarted; bool mSpsPpsHeaderReceived; bool mSawInputEOS; + bool mSawOutputEOS; bool mSignalledError; bool mIntra4x4; bool mEnableFastSad; bool mEnableAltRef; - bool mReconEnable; - bool mPSNREnable; + bool mReconEnable; + bool mPSNREnable; + bool mEntropyMode; IVE_SPEED_CONFIG mEncSpeed; - uint8_t *mConversionBuffer; - + uint8_t *mConversionBuffers[MAX_CONVERSION_BUFFERS]; + bool mConversionBuffersFree[MAX_CONVERSION_BUFFERS]; + BufferInfo *mInputBufferInfo[MAX_INPUT_BUFFER_HEADERS]; iv_obj_t *mCodecCtx; // Codec context iv_mem_rec_t *mMemRecords; // Memory records requested by the codec size_t mNumMemRecords; // Number of memory records requested by codec size_t mNumCores; // Number of cores used by the codec UWORD32 mHeaderGenerated; - + UWORD32 mBframes; IV_ARCH_T mArch; IVE_SLICE_MODE_T mSliceMode; UWORD32 mSliceParam; @@ -203,7 +202,7 @@ private: IVE_AIR_MODE_T mAIRMode; UWORD32 mAIRRefreshPeriod; - OMX_ERRORTYPE initEncParams(); + void initEncParams(); OMX_ERRORTYPE initEncoder(); OMX_ERRORTYPE releaseEncoder(); @@ -292,6 +291,8 @@ private: fclose(fp); \ } else { \ ALOGD("Could not write to file %s", m_filename);\ + if (fp != NULL) \ + fclose(fp); \ } \ } #else /* FILE_DUMP_ENABLE */ |