Loading media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp +186 −101 Original line number Diff line number Diff line Loading @@ -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 }, Loading Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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), Loading @@ -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(); } Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); Loading @@ -618,27 +632,22 @@ 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) { 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; } } Loading @@ -654,7 +663,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 */ Loading Loading @@ -691,7 +700,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; Loading Loading @@ -738,9 +747,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) { Loading @@ -755,7 +764,6 @@ OMX_ERRORTYPE SoftAVC::initEncoder() { ps_mem_rec++; } printf("\nTotal memory for codec %d\n", total_size); } /* Codec Instance Creation */ Loading Loading @@ -789,7 +797,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; Loading Loading @@ -864,7 +872,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; Loading @@ -885,16 +892,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; Loading Loading @@ -926,23 +935,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; Loading Loading @@ -973,14 +980,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 Loading Loading @@ -1075,14 +1094,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) { Loading @@ -1091,6 +1123,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; Loading Loading @@ -1145,14 +1189,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; } Loading @@ -1170,35 +1206,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) { inQueue.erase(inQueue.begin()); inputBufferInfo->mOwnedByUs = false; notifyEmptyBufferDone(inputBufferHeader); BufferInfo *inputBufferInfo; OMX_BUFFERHEADERTYPE *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; } Loading @@ -1208,6 +1240,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) { Loading @@ -1231,10 +1267,13 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) { outputBufferHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG; outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes; if (inputBufferHeader != NULL) { outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp; } outQueue.erase(outQueue.begin()); outputBufferInfo->mOwnedByUs = false; DUMP_TO_FILE( mOutFile, outputBufferHeader->pBuffer, outputBufferHeader->nFilledLen); Loading @@ -1252,14 +1291,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); Loading @@ -1269,14 +1318,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) { Loading @@ -1294,38 +1340,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; } if (inputBufferHeader != NULL) { inQueue.erase(inQueue.begin()); inputBufferInfo->mOwnedByUs = false; /* 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; } 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, 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( Loading media/libstagefright/codecs/avcenc/SoftAVCEnc.h +17 −16 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -25,14 +25,14 @@ namespace android { struct 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 Loading @@ -57,7 +57,7 @@ struct 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 Loading Loading @@ -88,6 +88,7 @@ struct 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 Loading Loading @@ -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() Loading @@ -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 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; Loading @@ -203,7 +202,7 @@ private: IVE_AIR_MODE_T mAIRMode; UWORD32 mAIRRefreshPeriod; OMX_ERRORTYPE initEncParams(); void initEncParams(); OMX_ERRORTYPE initEncoder(); OMX_ERRORTYPE releaseEncoder(); Loading Loading @@ -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 */ Loading Loading
media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp +186 −101 Original line number Diff line number Diff line Loading @@ -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 }, Loading Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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), Loading @@ -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(); } Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); Loading @@ -618,27 +632,22 @@ 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) { 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; } } Loading @@ -654,7 +663,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 */ Loading Loading @@ -691,7 +700,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; Loading Loading @@ -738,9 +747,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) { Loading @@ -755,7 +764,6 @@ OMX_ERRORTYPE SoftAVC::initEncoder() { ps_mem_rec++; } printf("\nTotal memory for codec %d\n", total_size); } /* Codec Instance Creation */ Loading Loading @@ -789,7 +797,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; Loading Loading @@ -864,7 +872,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; Loading @@ -885,16 +892,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; Loading Loading @@ -926,23 +935,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; Loading Loading @@ -973,14 +980,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 Loading Loading @@ -1075,14 +1094,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) { Loading @@ -1091,6 +1123,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; Loading Loading @@ -1145,14 +1189,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; } Loading @@ -1170,35 +1206,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) { inQueue.erase(inQueue.begin()); inputBufferInfo->mOwnedByUs = false; notifyEmptyBufferDone(inputBufferHeader); BufferInfo *inputBufferInfo; OMX_BUFFERHEADERTYPE *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; } Loading @@ -1208,6 +1240,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) { Loading @@ -1231,10 +1267,13 @@ void SoftAVC::onQueueFilled(OMX_U32 portIndex) { outputBufferHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG; outputBufferHeader->nFilledLen = s_encode_op.s_out_buf.u4_bytes; if (inputBufferHeader != NULL) { outputBufferHeader->nTimeStamp = inputBufferHeader->nTimeStamp; } outQueue.erase(outQueue.begin()); outputBufferInfo->mOwnedByUs = false; DUMP_TO_FILE( mOutFile, outputBufferHeader->pBuffer, outputBufferHeader->nFilledLen); Loading @@ -1252,14 +1291,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); Loading @@ -1269,14 +1318,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) { Loading @@ -1294,38 +1340,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; } if (inputBufferHeader != NULL) { inQueue.erase(inQueue.begin()); inputBufferInfo->mOwnedByUs = false; /* 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; } 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, 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( Loading
media/libstagefright/codecs/avcenc/SoftAVCEnc.h +17 −16 Original line number Diff line number Diff line Loading @@ -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> Loading @@ -25,14 +25,14 @@ namespace android { struct 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 Loading @@ -57,7 +57,7 @@ struct 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 Loading Loading @@ -88,6 +88,7 @@ struct 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 Loading Loading @@ -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() Loading @@ -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 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; Loading @@ -203,7 +202,7 @@ private: IVE_AIR_MODE_T mAIRMode; UWORD32 mAIRRefreshPeriod; OMX_ERRORTYPE initEncParams(); void initEncParams(); OMX_ERRORTYPE initEncoder(); OMX_ERRORTYPE releaseEncoder(); Loading Loading @@ -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 */ Loading