status_t SoftAVC::resetDecoder() { ivd_ctl_reset_ip_t s_ctl_ip; ivd_ctl_reset_op_t s_ctl_op; IV_API_CALL_STATUS_T status; s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET; s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t); s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t); status = ivdec_api_function(mCodecCtx, (void *)&s_ctl_ip, (void *)&s_ctl_op); if (IV_SUCCESS != status) { ALOGE("Error in reset: 0x%x", s_ctl_op.u4_error_code); return UNKNOWN_ERROR; } mSignalledError = false; /* Set the run-time (dynamic) parameters */ setParams(outputBufferWidth()); /* Set number of cores/threads to be used by the codec */ setNumCores(); return OK; }
status_t SoftHEVC::initDecoder() { IV_API_CALL_STATUS_T status; mNumCores = GetCPUCoreCount(); mCodecCtx = NULL; mStride = outputBufferWidth(); /* Initialize the decoder */ { ivdext_create_ip_t s_create_ip; ivdext_create_op_t s_create_op; void *dec_fxns = (void *)ivdec_api_function; s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ivdext_create_ip_t); s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE; s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0; s_create_op.s_ivd_create_op_t.u4_size = sizeof(ivdext_create_op_t); s_create_ip.s_ivd_create_ip_t.e_output_format = mIvColorFormat; s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ivd_aligned_malloc; s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ivd_aligned_free; s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL; status = ivdec_api_function(mCodecCtx, (void *)&s_create_ip, (void *)&s_create_op); mCodecCtx = (iv_obj_t*)s_create_op.s_ivd_create_op_t.pv_handle; mCodecCtx->pv_fxns = dec_fxns; mCodecCtx->u4_size = sizeof(iv_obj_t); if (status != IV_SUCCESS) { ALOGE("Error in create: 0x%x", s_create_op.s_ivd_create_op_t.u4_error_code); deInitDecoder(); mCodecCtx = NULL; return UNKNOWN_ERROR; } } /* Reset the plugin state */ resetPlugin(); /* Set the run time (dynamic) parameters */ setParams(mStride); /* Set number of cores/threads to be used by the codec */ setNumCores(); /* Get codec version */ logVersion(); mFlushNeeded = false; return OK; }
status_t SoftAVC::initDecoder(uint32_t width, uint32_t height) { IV_API_CALL_STATUS_T status; UWORD32 u4_num_reorder_frames; UWORD32 u4_num_ref_frames; UWORD32 u4_share_disp_buf; WORD32 i4_level; mNumCores = GetCPUCoreCount(); mCodecCtx = NULL; /* Initialize number of ref and reorder modes (for H264) */ u4_num_reorder_frames = 16; u4_num_ref_frames = 16; u4_share_disp_buf = 0; uint32_t displayStride = mIsAdaptive ? mAdaptiveMaxWidth : width; uint32_t displayHeight = mIsAdaptive ? mAdaptiveMaxHeight : height; uint32_t displaySizeY = displayStride * displayHeight; if(mNewLevel == 0){ if (displaySizeY > (1920 * 1088)) { i4_level = 50; } else if (displaySizeY > (1280 * 720)) { i4_level = 40; } else if (displaySizeY > (720 * 576)) { i4_level = 31; } else if (displaySizeY > (624 * 320)) { i4_level = 30; } else if (displaySizeY > (352 * 288)) { i4_level = 21; } else { i4_level = 20; } } else { i4_level = mNewLevel; } { iv_num_mem_rec_ip_t s_num_mem_rec_ip; iv_num_mem_rec_op_t s_num_mem_rec_op; s_num_mem_rec_ip.u4_size = sizeof(s_num_mem_rec_ip); s_num_mem_rec_op.u4_size = sizeof(s_num_mem_rec_op); s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC; ALOGV("Get number of mem records"); status = ivdec_api_function( mCodecCtx, (void *)&s_num_mem_rec_ip, (void *)&s_num_mem_rec_op); if (IV_SUCCESS != status) { ALOGE("Error in getting mem records: 0x%x", s_num_mem_rec_op.u4_error_code); return UNKNOWN_ERROR; } mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec; } mMemRecords = (iv_mem_rec_t *)ivd_aligned_malloc( 128, mNumMemRecords * sizeof(iv_mem_rec_t)); if (mMemRecords == NULL) { ALOGE("Allocation failure"); return NO_MEMORY; } memset(mMemRecords, 0, mNumMemRecords * sizeof(iv_mem_rec_t)); { size_t i; ivdext_fill_mem_rec_ip_t s_fill_mem_ip; ivdext_fill_mem_rec_op_t s_fill_mem_op; iv_mem_rec_t *ps_mem_rec; s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_size = sizeof(ivdext_fill_mem_rec_ip_t); s_fill_mem_ip.i4_level = i4_level; s_fill_mem_ip.u4_num_reorder_frames = u4_num_reorder_frames; s_fill_mem_ip.u4_num_ref_frames = u4_num_ref_frames; s_fill_mem_ip.u4_share_disp_buf = u4_share_disp_buf; s_fill_mem_ip.u4_num_extra_disp_buf = 0; s_fill_mem_ip.e_output_format = mIvColorFormat; s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC; s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = mMemRecords; s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = displayStride; s_fill_mem_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = displayHeight; s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_size = sizeof(ivdext_fill_mem_rec_op_t); ps_mem_rec = mMemRecords; for (i = 0; i < mNumMemRecords; i++) { ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t); } status = ivdec_api_function( mCodecCtx, (void *)&s_fill_mem_ip, (void *)&s_fill_mem_op); if (IV_SUCCESS != status) { ALOGE("Error in filling mem records: 0x%x", s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_error_code); return UNKNOWN_ERROR; } mNumMemRecords = s_fill_mem_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled; ps_mem_rec = mMemRecords; for (i = 0; i < mNumMemRecords; i++) { ps_mem_rec->pv_base = ivd_aligned_malloc( ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size); if (ps_mem_rec->pv_base == NULL) { ALOGE("Allocation failure for memory record #%zu of size %u", i, ps_mem_rec->u4_mem_size); status = IV_FAIL; return NO_MEMORY; } ps_mem_rec++; } } /* Initialize the decoder */ { ivdext_init_ip_t s_init_ip; ivdext_init_op_t s_init_op; void *dec_fxns = (void *)ivdec_api_function; s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ivdext_init_ip_t); s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT; s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mMemRecords; s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd = displayStride; s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = displayHeight; s_init_ip.i4_level = i4_level; s_init_ip.u4_num_reorder_frames = u4_num_reorder_frames; s_init_ip.u4_num_ref_frames = u4_num_ref_frames; s_init_ip.u4_share_disp_buf = u4_share_disp_buf; s_init_ip.u4_num_extra_disp_buf = 0; s_init_op.s_ivd_init_op_t.u4_size = sizeof(s_init_op); s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = mNumMemRecords; s_init_ip.s_ivd_init_ip_t.e_output_format = mIvColorFormat; mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base; mCodecCtx->pv_fxns = dec_fxns; mCodecCtx->u4_size = sizeof(iv_obj_t); status = ivdec_api_function(mCodecCtx, (void *)&s_init_ip, (void *)&s_init_op); if (status != IV_SUCCESS) { mCodecCtx = NULL; ALOGE("Error in init: 0x%x", s_init_op.s_ivd_init_op_t.u4_error_code); return UNKNOWN_ERROR; } } /* Reset the plugin state */ resetPlugin(); /* Set the run time (dynamic) parameters */ setParams(displayStride); /* Set number of cores/threads to be used by the codec */ setNumCores(); /* Get codec version */ logVersion(); /* Allocate internal picture buffer */ uint32_t bufferSize = displaySizeY * 3 / 2; mFlushOutBuffer = (uint8_t *)ivd_aligned_malloc(128, bufferSize); if (NULL == mFlushOutBuffer) { ALOGE("Could not allocate flushOutputBuffer of size %u", bufferSize); return NO_MEMORY; } mInitNeeded = false; mFlushNeeded = false; return OK; }
OMX_ERRORTYPE SoftAVC::initEncoder() { IV_STATUS_T status; WORD32 level; uint32_t displaySizeY; CHECK(!mStarted); OMX_ERRORTYPE errType = OMX_ErrorNone; displaySizeY = mWidth * mHeight; if (displaySizeY > (1920 * 1088)) { level = 50; } else if (displaySizeY > (1280 * 720)) { level = 40; } else if (displaySizeY > (720 * 576)) { level = 31; } else if (displaySizeY > (624 * 320)) { level = 30; } else if (displaySizeY > (352 * 288)) { level = 21; } else { level = 20; } mAVCEncLevel = MAX(level, mAVCEncLevel); mStride = mWidth; if (mInputDataIsMeta) { for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) { if (mConversionBuffers[i] != NULL) { free(mConversionBuffers[i]); mConversionBuffers[i] = 0; } if (((uint64_t)mStride * mHeight) > ((uint64_t)INT32_MAX / 3)) { ALOGE("Buffer size is too big."); return OMX_ErrorUndefined; } mConversionBuffers[i] = (uint8_t *)malloc(mStride * mHeight * 3 / 2); if (mConversionBuffers[i] == NULL) { ALOGE("Allocating conversion buffer failed."); return OMX_ErrorUndefined; } mConversionBuffersFree[i] = 1; } } switch (mColorFormat) { case OMX_COLOR_FormatYUV420SemiPlanar: mIvVideoColorFormat = IV_YUV_420SP_UV; ALOGV("colorFormat YUV_420SP"); break; default: case OMX_COLOR_FormatYUV420Planar: mIvVideoColorFormat = IV_YUV_420P; ALOGV("colorFormat YUV_420P"); break; } ALOGD("Params width %d height %d level %d colorFormat %d", mWidth, mHeight, mAVCEncLevel, mIvVideoColorFormat); /* Getting Number of MemRecords */ { iv_num_mem_rec_ip_t s_num_mem_rec_ip; iv_num_mem_rec_op_t s_num_mem_rec_op; s_num_mem_rec_ip.u4_size = sizeof(iv_num_mem_rec_ip_t); s_num_mem_rec_op.u4_size = sizeof(iv_num_mem_rec_op_t); s_num_mem_rec_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC; status = ive_api_function(0, &s_num_mem_rec_ip, &s_num_mem_rec_op); if (status != IV_SUCCESS) { ALOGE("Get number of memory records failed = 0x%x\n", s_num_mem_rec_op.u4_error_code); return OMX_ErrorUndefined; } mNumMemRecords = s_num_mem_rec_op.u4_num_mem_rec; } /* Allocate array to hold memory records */ if (mNumMemRecords > SIZE_MAX / sizeof(iv_mem_rec_t)) { ALOGE("requested memory size is too big."); return OMX_ErrorUndefined; } mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t)); if (NULL == mMemRecords) { ALOGE("Unable to allocate memory for hold memory records: Size %zu", mNumMemRecords * sizeof(iv_mem_rec_t)); mSignalledError = true; notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); return OMX_ErrorUndefined; } { iv_mem_rec_t *ps_mem_rec; ps_mem_rec = mMemRecords; 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; ps_mem_rec->u4_mem_alignment = 0; ps_mem_rec->e_mem_type = IV_NA_MEM_TYPE; ps_mem_rec++; } } /* Getting MemRecords Attributes */ { iv_fill_mem_rec_ip_t s_fill_mem_rec_ip; iv_fill_mem_rec_op_t s_fill_mem_rec_op; s_fill_mem_rec_ip.u4_size = sizeof(iv_fill_mem_rec_ip_t); s_fill_mem_rec_op.u4_size = sizeof(iv_fill_mem_rec_op_t); s_fill_mem_rec_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC; s_fill_mem_rec_ip.ps_mem_rec = mMemRecords; s_fill_mem_rec_ip.u4_num_mem_rec = mNumMemRecords; s_fill_mem_rec_ip.u4_max_wd = mWidth; s_fill_mem_rec_ip.u4_max_ht = mHeight; s_fill_mem_rec_ip.u4_max_level = mAVCEncLevel; s_fill_mem_rec_ip.e_color_format = DEFAULT_INP_COLOR_FORMAT; s_fill_mem_rec_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM; s_fill_mem_rec_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM; s_fill_mem_rec_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; s_fill_mem_rec_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; status = ive_api_function(0, &s_fill_mem_rec_ip, &s_fill_mem_rec_op); if (status != IV_SUCCESS) { ALOGE("Fill memory records failed = 0x%x\n", s_fill_mem_rec_op.u4_error_code); mSignalledError = true; notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); return OMX_ErrorUndefined; } } /* Allocating Memory for Mem Records */ { WORD32 total_size; iv_mem_rec_t *ps_mem_rec; total_size = 0; ps_mem_rec = mMemRecords; 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) { ALOGE("Allocation failure for mem record id %zu size %u\n", i, ps_mem_rec->u4_mem_size); mSignalledError = true; notify(OMX_EventError, OMX_ErrorUndefined, 0, 0); return OMX_ErrorUndefined; } total_size += ps_mem_rec->u4_mem_size; ps_mem_rec++; } } /* Codec Instance Creation */ { ive_init_ip_t s_init_ip; ive_init_op_t s_init_op; mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base; mCodecCtx->u4_size = sizeof(iv_obj_t); mCodecCtx->pv_fxns = (void *)ive_api_function; s_init_ip.u4_size = sizeof(ive_init_ip_t); s_init_op.u4_size = sizeof(ive_init_op_t); s_init_ip.e_cmd = IV_CMD_INIT; s_init_ip.u4_num_mem_rec = mNumMemRecords; s_init_ip.ps_mem_rec = mMemRecords; s_init_ip.u4_max_wd = mWidth; s_init_ip.u4_max_ht = mHeight; s_init_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM; s_init_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM; s_init_ip.u4_max_level = mAVCEncLevel; s_init_ip.e_inp_color_fmt = mIvVideoColorFormat; if (mReconEnable || mPSNREnable) { s_init_ip.u4_enable_recon = 1; } else { s_init_ip.u4_enable_recon = 0; } s_init_ip.e_recon_color_fmt = DEFAULT_RECON_COLOR_FORMAT; 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_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; s_init_ip.e_slice_mode = mSliceMode; s_init_ip.u4_slice_param = mSliceParam; s_init_ip.e_arch = mArch; s_init_ip.e_soc = DEFAULT_SOC; status = ive_api_function(mCodecCtx, &s_init_ip, &s_init_op); if (status != IV_SUCCESS) { ALOGE("Init memory records failed = 0x%x\n", s_init_op.u4_error_code); mSignalledError = true; notify(OMX_EventError, OMX_ErrorUndefined, 0 /* arg2 */, NULL /* data */); return OMX_ErrorUndefined; } } /* Get Codec Version */ logVersion(); /* set processor details */ setNumCores(); /* Video control Set Frame dimensions */ setDimensions(); /* Video control Set Frame rates */ setFrameRate(); /* Video control Set IPE Params */ setIpeParams(); /* Video control Set Bitrate */ setBitRate(); /* Video control Set QP */ setQp(); /* Video control Set AIR params */ setAirParams(); /* Video control Set VBV params */ setVbvParams(); /* Video control Set Motion estimation params */ setMeParams(); /* Video control Set GOP params */ setGopParams(); /* Video control Set Deblock params */ setDeblockParams(); /* Video control Set Profile params */ setProfileParams(); /* Video control Set in Encode header mode */ setEncMode(IVE_ENC_MODE_HEADER); ALOGV("init_codec successfull"); mSpsPpsHeaderReceived = false; mStarted = true; return OMX_ErrorNone; }