| /****************************************************************************** |
| * |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at: |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| ***************************************************************************** |
| * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
| */ |
| |
| /** |
| ******************************************************************************* |
| * @file |
| * ih264e_api.c |
| * |
| * @brief |
| * Contains api function definitions for H264 encoder |
| * |
| * @author |
| * ittiam |
| * |
| * @par List of Functions: |
| * - api_check_struct_sanity() |
| * - ih264e_codec_update_config() |
| * - ih264e_set_default_params() |
| * - ih264e_init() |
| * - ih264e_get_num_rec() |
| * - ih264e_fill_num_mem_rec() |
| * - ih264e_init_mem_rec() |
| * - ih264e_retrieve_memrec() |
| * - ih264e_set_flush_mode() |
| * - ih264e_get_buf_info() |
| * - ih264e_set_dimensions() |
| * - ih264e_set_frame_rate() |
| * - ih264e_set_bit_rate() |
| * - ih264e_set_frame_type() |
| * - ih264e_set_qp() |
| * - ih264e_set_enc_mode() |
| * - ih264e_set_vbv_params() |
| * - ih264_set_air_params() |
| * - ih264_set_me_params() |
| * - ih264_set_ipe_params() |
| * - ih264_set_gop_params() |
| * - ih264_set_profile_params() |
| * - ih264_set_deblock_params() |
| * - ih264e_set_num_cores() |
| * - ih264e_reset() |
| * - ih264e_ctl() |
| * - ih264e_api_function() |
| * |
| * @remarks |
| * None |
| * |
| ******************************************************************************* |
| */ |
| |
| /*****************************************************************************/ |
| /* File Includes */ |
| /*****************************************************************************/ |
| |
| /* System Include Files */ |
| #include <stdio.h> |
| #include <stddef.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <assert.h> |
| |
| /* User Include Files */ |
| #include "ih264e_config.h" |
| #include "ih264_typedefs.h" |
| #include "ih264_size_defs.h" |
| #include "iv2.h" |
| #include "ive2.h" |
| #include "ih264e.h" |
| #include "ithread.h" |
| #include "ih264_debug.h" |
| #include "ih264_defs.h" |
| #include "ih264_error.h" |
| #include "ih264_structs.h" |
| #include "ih264_trans_quant_itrans_iquant.h" |
| #include "ih264_inter_pred_filters.h" |
| #include "ih264_mem_fns.h" |
| #include "ih264_padding.h" |
| #include "ih264_intra_pred_filters.h" |
| #include "ih264_deblk_edge_filters.h" |
| #include "ih264_cabac_tables.h" |
| #include "ih264_macros.h" |
| #include "ih264e_defs.h" |
| #include "ih264e_globals.h" |
| #include "ih264_buf_mgr.h" |
| #include "irc_mem_req_and_acq.h" |
| #include "irc_cntrl_param.h" |
| #include "irc_frame_info_collector.h" |
| #include "irc_rate_control_api.h" |
| #include "ih264e_time_stamp.h" |
| #include "ih264e_modify_frm_rate.h" |
| #include "ih264e_rate_control.h" |
| #include "ih264e_error.h" |
| #include "ih264e_bitstream.h" |
| #include "ime_defs.h" |
| #include "ime_distortion_metrics.h" |
| #include "ime_structs.h" |
| #include "ih264e_cabac_structs.h" |
| #include "ih264e_structs.h" |
| #include "ih264e_utils.h" |
| #include "ih264e_core_coding.h" |
| #include "ih264_platform_macros.h" |
| #include "ih264e_platform_macros.h" |
| #include "ih264_list.h" |
| #include "ih264_dpb_mgr.h" |
| #include "ih264_cavlc_tables.h" |
| #include "ih264e_cavlc.h" |
| #include "ih264_common_tables.h" |
| #include "ih264e_master.h" |
| #include "ih264e_fmt_conv.h" |
| #include "ih264e_version.h" |
| |
| |
| /*****************************************************************************/ |
| /* Function Declarations */ |
| /*****************************************************************************/ |
| WORD32 ih264e_get_rate_control_mem_tab(void *pv_rate_control, |
| iv_mem_rec_t *ps_mem, |
| ITT_FUNC_TYPE_E e_func_type); |
| |
| |
| /*****************************************************************************/ |
| /* Function Definitions */ |
| /*****************************************************************************/ |
| |
| /** |
| ******************************************************************************* |
| * |
| * @brief |
| * Used to test arguments for corresponding API call |
| * |
| * @par Description: |
| * For each command the arguments are validated |
| * |
| * @param[in] ps_handle |
| * Codec handle at API level |
| * |
| * @param[in] pv_api_ip |
| * Pointer to input structure |
| * |
| * @param[out] pv_api_op |
| * Pointer to output structure |
| * |
| * @returns error status |
| * |
| * @remarks none |
| * |
| ******************************************************************************* |
| */ |
| static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, |
| void *pv_api_ip, |
| void *pv_api_op) |
| { |
| /* api call */ |
| WORD32 command = IV_CMD_NA; |
| |
| /* input structure expected by the api call */ |
| UWORD32 *pu4_api_ip = pv_api_ip; |
| |
| /* output structure expected by the api call */ |
| UWORD32 *pu4_api_op = pv_api_op; |
| |
| /* temp var */ |
| WORD32 i, j; |
| |
| if (NULL == pv_api_op || NULL == pv_api_ip) |
| { |
| return (IV_FAIL); |
| } |
| |
| /* get command */ |
| command = pu4_api_ip[1]; |
| |
| /* set error code */ |
| pu4_api_op[1] = 0; |
| |
| /* error checks on handle */ |
| switch (command) |
| { |
| case IV_CMD_GET_NUM_MEM_REC: |
| case IV_CMD_FILL_NUM_MEM_REC: |
| break; |
| |
| case IV_CMD_INIT: |
| if (ps_handle == NULL) |
| { |
| *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; |
| *(pu4_api_op + 1) |= IVE_ERR_HANDLE_NULL; |
| return IV_FAIL; |
| } |
| |
| if (ps_handle->u4_size != sizeof(iv_obj_t)) |
| { |
| *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; |
| *(pu4_api_op + 1) |= IVE_ERR_HANDLE_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| break; |
| |
| case IVE_CMD_QUEUE_INPUT: |
| case IVE_CMD_QUEUE_OUTPUT: |
| case IVE_CMD_DEQUEUE_OUTPUT: |
| case IVE_CMD_GET_RECON: |
| case IV_CMD_RETRIEVE_MEMREC: |
| case IVE_CMD_VIDEO_CTL: |
| case IVE_CMD_VIDEO_ENCODE: |
| |
| if (ps_handle == NULL) |
| { |
| *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; |
| *(pu4_api_op + 1) |= IVE_ERR_HANDLE_NULL; |
| return IV_FAIL; |
| } |
| |
| if (ps_handle->u4_size != sizeof(iv_obj_t)) |
| { |
| *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; |
| *(pu4_api_op + 1) |= IVE_ERR_HANDLE_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_handle->pv_fxns != ih264e_api_function) |
| { |
| *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; |
| *(pu4_api_op + 1) |= IVE_ERR_API_FUNCTION_PTR_NULL; |
| return IV_FAIL; |
| } |
| |
| if (ps_handle->pv_codec_handle == NULL) |
| { |
| *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; |
| *(pu4_api_op + 1) |= IVE_ERR_INVALID_CODEC_HANDLE; |
| return IV_FAIL; |
| } |
| break; |
| |
| default: |
| *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; |
| *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_CMD; |
| return IV_FAIL; |
| } |
| |
| /* error checks on input output structures */ |
| switch (command) |
| { |
| case IV_CMD_GET_NUM_MEM_REC: |
| { |
| ih264e_num_mem_rec_ip_t *ps_ip = pv_api_ip; |
| ih264e_num_mem_rec_op_t *ps_op = pv_api_op; |
| |
| ps_op->s_ive_op.u4_error_code = 0; |
| |
| if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_num_mem_rec_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_GET_MEM_REC_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if (ps_op->s_ive_op.u4_size != sizeof(ih264e_num_mem_rec_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_GET_MEM_REC_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| break; |
| } |
| |
| case IV_CMD_FILL_NUM_MEM_REC: |
| { |
| ih264e_fill_mem_rec_ip_t *ps_ip = pv_api_ip; |
| ih264e_fill_mem_rec_op_t *ps_op = pv_api_op; |
| |
| iv_mem_rec_t *ps_mem_rec = NULL; |
| |
| WORD32 max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); |
| WORD32 max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); |
| |
| ps_op->s_ive_op.u4_error_code = 0; |
| |
| if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_fill_mem_rec_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_FILL_MEM_REC_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if (ps_op->s_ive_op.u4_size != sizeof(ih264e_fill_mem_rec_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_FILL_MEM_REC_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if (max_wd < MIN_WD || max_wd > MAX_WD) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (max_ht < MIN_HT || max_ht > MAX_HT) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| /* verify number of mem rec ptr */ |
| if (NULL == ps_ip->s_ive_ip.ps_mem_rec) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL; |
| return (IV_FAIL); |
| } |
| |
| /* verify number of mem records */ |
| if (ps_ip->s_ive_ip.u4_num_mem_rec != MEM_REC_CNT) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_NUM_MEM_REC_NOT_SUFFICIENT; |
| return IV_FAIL; |
| } |
| |
| /* check mem records sizes are correct */ |
| ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec; |
| for (i = 0; i < MEM_REC_CNT; i++) |
| { |
| if (ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| } |
| break; |
| } |
| |
| case IV_CMD_INIT: |
| { |
| ih264e_init_ip_t *ps_ip = pv_api_ip; |
| ih264e_init_op_t *ps_op = pv_api_op; |
| |
| iv_mem_rec_t *ps_mem_rec = NULL; |
| |
| WORD32 max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); |
| WORD32 max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); |
| |
| ps_op->s_ive_op.u4_error_code = 0; |
| |
| if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_init_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_INIT_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if (ps_op->s_ive_op.u4_size != sizeof(ih264e_init_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_INIT_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if (max_wd < MIN_WD || max_wd > MAX_WD) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (max_ht < MIN_HT || max_ht > MAX_HT) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_max_ref_cnt > MAX_REF_PIC_CNT || |
| ps_ip->s_ive_ip.u4_max_ref_cnt < MIN_REF_PIC_CNT) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_max_reorder_cnt != 0) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_10) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_1B) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_11) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_12) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_13) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_20) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_21) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_22) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_30) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_31) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_32) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_40) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_41) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_42) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_50) |
| && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_51)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_CODEC_LEVEL_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if ((ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420P) |
| && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_422ILE) |
| && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_UV) |
| && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_VU)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if ((ps_ip->s_ive_ip.e_recon_color_fmt != IV_YUV_420P) |
| && (ps_ip->s_ive_ip.e_recon_color_fmt != IV_YUV_420SP_UV) |
| && (ps_ip->s_ive_ip.e_recon_color_fmt != IV_YUV_420SP_VU)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_RECON_CHROMA_FORMAT_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if ((ps_ip->s_ive_ip.e_rc_mode != IVE_RC_NONE) |
| && (ps_ip->s_ive_ip.e_rc_mode != IVE_RC_STORAGE) |
| && (ps_ip->s_ive_ip.e_rc_mode != IVE_RC_CBR_NON_LOW_DELAY)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_RATE_CONTROL_MODE_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_max_framerate > DEFAULT_MAX_FRAMERATE) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_FRAME_RATE_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_max_bitrate > DEFAULT_MAX_BITRATE) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= IH264E_BITRATE_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_num_bframes > MAX_NUM_BFRAMES) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= IH264E_BFRAMES_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_num_bframes |
| && (ps_ip->s_ive_ip.u4_max_ref_cnt < 2)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= IH264E_BFRAMES_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.e_content_type != IV_PROGRESSIVE) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_CONTENT_TYPE_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_max_srch_rng_x > DEFAULT_MAX_SRCH_RANGE_X) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_HORIZONTAL_SEARCH_RANGE_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_max_srch_rng_y > DEFAULT_MAX_SRCH_RANGE_Y) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_VERTICAL_SEARCH_RANGE_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if ((ps_ip->s_ive_ip.e_slice_mode != IVE_SLICE_MODE_NONE) |
| && (ps_ip->s_ive_ip.e_slice_mode != IVE_SLICE_MODE_BLOCKS)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_SLICE_TYPE_INPUT_INVALID; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.e_slice_mode == IVE_SLICE_MODE_BLOCKS) |
| { |
| if (ps_ip->s_ive_ip.u4_slice_param == 0 |
| || ps_ip->s_ive_ip.u4_slice_param > ((UWORD32)max_ht >> 4)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_SLICE_PARAM_INPUT_INVALID; |
| return (IV_FAIL); |
| } |
| } |
| |
| if (NULL == ps_ip->s_ive_ip.ps_mem_rec) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL; |
| return (IV_FAIL); |
| } |
| |
| /* verify number of mem records */ |
| if (ps_ip->s_ive_ip.u4_num_mem_rec != MEM_REC_CNT) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_NUM_MEM_REC_NOT_SUFFICIENT; |
| return (IV_FAIL); |
| } |
| |
| ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec; |
| |
| /* check memrecords sizes are correct */ |
| for (i = 0; i <((WORD32)ps_ip->s_ive_ip.u4_num_mem_rec); i++) |
| { |
| if (ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| /* check memrecords pointers are not NULL */ |
| if (ps_mem_rec[i].pv_base == NULL) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_MEM_REC_BASE_POINTER_NULL; |
| return IV_FAIL; |
| } |
| } |
| |
| /* verify memtabs for overlapping regions */ |
| { |
| void *start[MEM_REC_CNT]; |
| void *end[MEM_REC_CNT]; |
| |
| start[0] = (ps_mem_rec[0].pv_base); |
| end[0] = ((UWORD8 *) ps_mem_rec[0].pv_base) |
| + ps_mem_rec[0].u4_mem_size - 1; |
| |
| for (i = 1; i < MEM_REC_CNT; i++) |
| { |
| /* This array is populated to check memtab overlap */ |
| start[i] = (ps_mem_rec[i].pv_base); |
| end[i] = ((UWORD8 *) ps_mem_rec[i].pv_base) |
| + ps_mem_rec[i].u4_mem_size - 1; |
| |
| for (j = 0; j < i; j++) |
| { |
| if ((start[i] >= start[j]) && (start[i] <= end[j])) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_MEM_REC_OVERLAP_ERR; |
| return IV_FAIL; |
| } |
| |
| if ((end[i] >= start[j]) && (end[i] <= end[j])) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_MEM_REC_OVERLAP_ERR; |
| return IV_FAIL; |
| } |
| |
| if ((start[i] < start[j]) && (end[i] > end[j])) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_MEM_REC_OVERLAP_ERR; |
| return IV_FAIL; |
| } |
| } |
| } |
| } |
| |
| /* re-validate mem records with init config */ |
| { |
| /* mem records */ |
| iv_mem_rec_t s_mem_rec_ittiam_api[MEM_REC_CNT]; |
| |
| /* api interface structs */ |
| ih264e_fill_mem_rec_ip_t s_ip; |
| ih264e_fill_mem_rec_op_t s_op; |
| |
| /* error status */ |
| IV_STATUS_T e_status; |
| |
| /* temp var */ |
| WORD32 i; |
| |
| s_ip.s_ive_ip.u4_size = sizeof(ih264e_fill_mem_rec_ip_t); |
| s_op.s_ive_op.u4_size = sizeof(ih264e_fill_mem_rec_op_t); |
| |
| s_ip.s_ive_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC; |
| s_ip.s_ive_ip.ps_mem_rec = s_mem_rec_ittiam_api; |
| s_ip.s_ive_ip.u4_max_wd = max_wd; |
| s_ip.s_ive_ip.u4_max_ht = max_ht; |
| s_ip.s_ive_ip.u4_num_mem_rec = ps_ip->s_ive_ip.u4_num_mem_rec; |
| s_ip.s_ive_ip.u4_max_level = ps_ip->s_ive_ip.u4_max_level; |
| s_ip.s_ive_ip.u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt; |
| s_ip.s_ive_ip.u4_max_reorder_cnt = |
| ps_ip->s_ive_ip.u4_max_reorder_cnt; |
| s_ip.s_ive_ip.e_color_format = ps_ip->s_ive_ip.e_inp_color_fmt; |
| s_ip.s_ive_ip.u4_max_srch_rng_x = |
| ps_ip->s_ive_ip.u4_max_srch_rng_x; |
| s_ip.s_ive_ip.u4_max_srch_rng_y = |
| ps_ip->s_ive_ip.u4_max_srch_rng_y; |
| |
| for (i = 0; i < MEM_REC_CNT; i++) |
| { |
| s_mem_rec_ittiam_api[i].u4_size = sizeof(iv_mem_rec_t); |
| } |
| |
| /* fill mem records */ |
| e_status = ih264e_api_function(NULL, (void *) &s_ip, |
| (void *) &s_op); |
| |
| if (IV_FAIL == e_status) |
| { |
| ps_op->s_ive_op.u4_error_code = s_op.s_ive_op.u4_error_code; |
| return (IV_FAIL); |
| } |
| |
| /* verify mem records */ |
| for (i = 0; i < MEM_REC_CNT; i++) |
| { |
| if (ps_mem_rec[i].u4_mem_size |
| < s_mem_rec_ittiam_api[i].u4_mem_size) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_MEM_REC_INSUFFICIENT_SIZE; |
| |
| return IV_FAIL; |
| } |
| |
| if (ps_mem_rec[i].u4_mem_alignment |
| != s_mem_rec_ittiam_api[i].u4_mem_alignment) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_MEM_REC_ALIGNMENT_ERR; |
| |
| return IV_FAIL; |
| } |
| |
| if (ps_mem_rec[i].e_mem_type |
| != s_mem_rec_ittiam_api[i].e_mem_type) |
| { |
| UWORD32 check = IV_SUCCESS; |
| UWORD32 diff = s_mem_rec_ittiam_api[i].e_mem_type |
| - ps_mem_rec[i].e_mem_type; |
| |
| if ((ps_mem_rec[i].e_mem_type |
| <= IV_EXTERNAL_CACHEABLE_SCRATCH_MEM) |
| && (s_mem_rec_ittiam_api[i].e_mem_type |
| >= IV_INTERNAL_NONCACHEABLE_PERSISTENT_MEM)) |
| { |
| check = IV_FAIL; |
| } |
| |
| if (3 != (s_mem_rec_ittiam_api[i].e_mem_type % 4)) |
| { |
| /* It is not IV_EXTERNAL_NONCACHEABLE_PERSISTENT_MEM or |
| * IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM */ |
| |
| if ((diff < 1) || (diff > 3)) |
| { |
| /* Difference between 1 and 3 is okay for all cases other than the |
| * two filtered with the MOD condition above */ |
| check = IV_FAIL; |
| } |
| } |
| else |
| { |
| if (diff == 1) |
| { |
| /* This particular case is when codec asked for External Persistent, |
| * but got Internal Scratch */ |
| check = IV_FAIL; |
| } |
| if ((diff != 2) && (diff != 3)) |
| { |
| check = IV_FAIL; |
| } |
| } |
| |
| if (check == IV_FAIL) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_MEM_REC_INCORRECT_TYPE; |
| |
| return IV_FAIL; |
| } |
| } |
| } |
| } |
| break; |
| } |
| |
| case IVE_CMD_QUEUE_INPUT: |
| case IVE_CMD_QUEUE_OUTPUT: |
| case IVE_CMD_DEQUEUE_OUTPUT: |
| case IVE_CMD_GET_RECON: |
| break; |
| |
| case IV_CMD_RETRIEVE_MEMREC: |
| { |
| ih264e_retrieve_mem_rec_ip_t *ps_ip = pv_api_ip; |
| ih264e_retrieve_mem_rec_op_t *ps_op = pv_api_op; |
| |
| iv_mem_rec_t *ps_mem_rec = NULL; |
| |
| ps_op->s_ive_op.u4_error_code = 0; |
| |
| if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_retrieve_mem_rec_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_RETRIEVE_MEM_REC_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if (ps_op->s_ive_op.u4_size != sizeof(ih264e_retrieve_mem_rec_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_RETRIEVE_MEM_REC_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if (NULL == ps_ip->s_ive_ip.ps_mem_rec) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL; |
| return (IV_FAIL); |
| } |
| |
| ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec; |
| |
| /* check memrecords sizes are correct */ |
| for (i = 0; i < MEM_REC_CNT; i++) |
| { |
| if (ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| } |
| break; |
| } |
| |
| case IVE_CMD_VIDEO_ENCODE: |
| { |
| ih264e_video_encode_ip_t *ps_ip = pv_api_ip; |
| ih264e_video_encode_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_video_encode_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_ENCODE_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if (ps_op->s_ive_op.u4_size != sizeof(ih264e_video_encode_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| break; |
| } |
| |
| case IVE_CMD_VIDEO_CTL: |
| { |
| /* ptr to input structure */ |
| WORD32 *pu4_ptr_cmd = pv_api_ip; |
| |
| /* sub command */ |
| WORD32 sub_command = pu4_ptr_cmd[2]; |
| |
| switch (sub_command) |
| { |
| case IVE_CMD_CTL_SETDEFAULT: |
| { |
| ih264e_ctl_setdefault_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_setdefault_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_setdefault_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETDEF_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_setdefault_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETDEF_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| break; |
| } |
| |
| case IVE_CMD_CTL_GETBUFINFO: |
| { |
| codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle); |
| |
| ih264e_ctl_getbufinfo_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_getbufinfo_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_getbufinfo_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_GETBUFINFO_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_getbufinfo_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_GETBUFINFO_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_ip->s_ive_ip.u4_max_wd < MIN_WD) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_WIDTH_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_max_wd > ps_codec->s_cfg.u4_max_wd) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_WIDTH_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_max_ht < MIN_HT) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_HEIGHT_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_max_ht > ps_codec->s_cfg.u4_max_ht) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_HEIGHT_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if ((ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420P) |
| && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_422ILE) |
| && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_UV) |
| && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_VU)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| break; |
| } |
| |
| case IVE_CMD_CTL_GETVERSION: |
| { |
| ih264e_ctl_getversioninfo_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_getversioninfo_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_getversioninfo_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_GETVERSION_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_getversioninfo_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_GETVERSION_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_ip->s_ive_ip.pu1_version == NULL) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_CTL_GET_VERSION_BUFFER_IS_NULL; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_FLUSH: |
| { |
| ih264e_ctl_flush_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_flush_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_flush_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_FLUSH_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_flush_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_FLUSH_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_RESET: |
| { |
| ih264e_ctl_reset_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_reset_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_reset_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_RESET_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_reset_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_RESET_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_NUM_CORES: |
| { |
| ih264e_ctl_set_num_cores_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_num_cores_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_num_cores_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETCORES_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_num_cores_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETCORES_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_num_cores < 1) |
| || (ps_ip->s_ive_ip.u4_num_cores > MAX_NUM_CORES)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_NUM_CORES; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_DIMENSIONS: |
| { |
| codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle); |
| |
| ih264e_ctl_set_dimensions_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_dimensions_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_dimensions_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETDIM_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_dimensions_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETDIM_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_ip->s_ive_ip.u4_wd < MIN_WD) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_WIDTH_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_wd > ps_codec->s_cfg.u4_max_wd) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_WIDTH_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_ht < MIN_HT) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_HEIGHT_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_ht > ps_codec->s_cfg.u4_max_ht) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_HEIGHT_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_FRAMERATE: |
| { |
| ih264e_ctl_set_frame_rate_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_frame_rate_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_frame_rate_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETFRAMERATE_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_frame_rate_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETFRAMERATE_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (((ps_ip->s_ive_ip.u4_src_frame_rate * 1000) > DEFAULT_MAX_FRAMERATE) |
| || ((ps_ip->s_ive_ip.u4_tgt_frame_rate * 1000) > DEFAULT_MAX_FRAMERATE)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_FRAME_RATE_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_src_frame_rate == 0) |
| || (ps_ip->s_ive_ip.u4_tgt_frame_rate == 0)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_FRAME_RATE_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_tgt_frame_rate |
| > ps_ip->s_ive_ip.u4_src_frame_rate) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_TGT_FRAME_RATE_EXCEEDS_SRC_FRAME_RATE; |
| return (IV_FAIL); |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_BITRATE: |
| { |
| ih264e_ctl_set_bitrate_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_bitrate_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_bitrate_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETBITRATE_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_bitrate_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETBITRATE_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_target_bitrate > DEFAULT_MAX_BITRATE) |
| || (ps_ip->s_ive_ip.u4_target_bitrate == 0)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_BITRATE_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_FRAMETYPE: |
| { |
| ih264e_ctl_set_frame_type_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_frame_type_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_frame_type_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETFRAMETYPE_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_frame_type_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETFRAMETYPE_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.e_frame_type != IV_NA_FRAME) |
| && (ps_ip->s_ive_ip.e_frame_type != IV_I_FRAME) |
| && (ps_ip->s_ive_ip.e_frame_type != IV_P_FRAME) |
| && (ps_ip->s_ive_ip.e_frame_type != IV_IDR_FRAME)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_FORCE_FRAME_INPUT; |
| return IV_FAIL; |
| } |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_ME_PARAMS: |
| { |
| codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle); |
| |
| ih264e_ctl_set_me_params_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_me_params_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_me_params_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETMEPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_me_params_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETMEPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_me_speed_preset != FULL_SRCH) |
| && (ps_ip->s_ive_ip.u4_me_speed_preset != DMND_SRCH) |
| && (ps_ip->s_ive_ip.u4_me_speed_preset != HEX_SRCH)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_ME_SPEED_PRESET; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_enable_hpel != 0) |
| && (ps_ip->s_ive_ip.u4_enable_hpel != 1)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_HALFPEL_OPTION; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_enable_qpel != 0) |
| && (ps_ip->s_ive_ip.u4_enable_qpel != 1)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_QPEL_OPTION; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_enable_fast_sad != 0) |
| && (ps_ip->s_ive_ip.u4_enable_fast_sad != 1)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_FAST_SAD_OPTION; |
| return IV_FAIL; |
| } |
| |
| if (ps_ip->s_ive_ip.u4_enable_alt_ref > 255) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_ALT_REF_OPTION; |
| return IV_FAIL; |
| } |
| |
| if (ps_ip->s_ive_ip.u4_srch_rng_x |
| > ps_codec->s_cfg.u4_max_srch_rng_x) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_HORIZONTAL_SEARCH_RANGE_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if (ps_ip->s_ive_ip.u4_srch_rng_y |
| > ps_codec->s_cfg.u4_max_srch_rng_y) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_VERTICAL_SEARCH_RANGE_NOT_SUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_IPE_PARAMS: |
| { |
| ih264e_ctl_set_ipe_params_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_ipe_params_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_ipe_params_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETIPEPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_ipe_params_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETIPEPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_enable_intra_4x4 != 0) |
| && (ps_ip->s_ive_ip.u4_enable_intra_4x4 != 1)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_INTRA4x4_OPTION; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_CONFIG) |
| && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_SLOWEST) |
| && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_NORMAL) |
| && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_FAST) |
| && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_HIGH_SPEED) |
| && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_FASTEST)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_ENC_SPEED_PRESET; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_GOP_PARAMS: |
| { |
| ih264e_ctl_set_gop_params_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_gop_params_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_gop_params_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETGOPPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_gop_params_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETGOPPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_i_frm_interval < DEFAULT_MIN_INTRA_FRAME_RATE) |
| || (ps_ip->s_ive_ip.u4_i_frm_interval > DEFAULT_MAX_INTRA_FRAME_RATE)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_INTRA_FRAME_INTERVAL; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_idr_frm_interval < DEFAULT_MIN_INTRA_FRAME_RATE) |
| || (ps_ip->s_ive_ip.u4_idr_frm_interval > DEFAULT_MAX_INTRA_FRAME_RATE)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_IDR_FRAME_INTERVAL; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_DEBLOCK_PARAMS: |
| { |
| ih264e_ctl_set_deblock_params_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_deblock_params_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_deblock_params_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETDEBLKPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_deblock_params_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETDEBLKPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_0) |
| && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_2) |
| && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_3) |
| && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_4)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_DEBLOCKING_TYPE_INPUT; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_QP: |
| { |
| ih264e_ctl_set_qp_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_qp_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_qp_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETQPPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_qp_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETQPPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_i_qp_max > MAX_H264_QP) |
| || (ps_ip->s_ive_ip.u4_p_qp_max > MAX_H264_QP) |
| || (ps_ip->s_ive_ip.u4_b_qp_max > MAX_H264_QP)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_MAX_FRAME_QP; |
| return IV_FAIL; |
| } |
| |
| /* We donot support QP < 4 */ |
| if ((ps_ip->s_ive_ip.u4_i_qp_min < 4) |
| || (ps_ip->s_ive_ip.u4_p_qp_min < 4) |
| || (ps_ip->s_ive_ip.u4_b_qp_min < 4) |
| || (ps_ip->s_ive_ip.u4_i_qp_min > ps_ip->s_ive_ip.u4_i_qp_max) |
| || (ps_ip->s_ive_ip.u4_p_qp_min > ps_ip->s_ive_ip.u4_p_qp_max) |
| || (ps_ip->s_ive_ip.u4_b_qp_min > ps_ip->s_ive_ip.u4_b_qp_max)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_MIN_FRAME_QP; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_i_qp > ps_ip->s_ive_ip.u4_i_qp_max) |
| || (ps_ip->s_ive_ip.u4_p_qp > ps_ip->s_ive_ip.u4_p_qp_max) |
| || (ps_ip->s_ive_ip.u4_b_qp > ps_ip->s_ive_ip.u4_b_qp_max)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INIT_QP; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_i_qp < ps_ip->s_ive_ip.u4_i_qp_min) |
| || (ps_ip->s_ive_ip.u4_p_qp < ps_ip->s_ive_ip.u4_p_qp_min) |
| || (ps_ip->s_ive_ip.u4_b_qp < ps_ip->s_ive_ip.u4_b_qp_min)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INIT_QP; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_ENC_MODE: |
| { |
| ih264e_ctl_set_enc_mode_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_enc_mode_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_enc_mode_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETENCMODE_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_enc_mode_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETENCMODE_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.e_enc_mode != IVE_ENC_MODE_HEADER) |
| && (ps_ip->s_ive_ip.e_enc_mode != IVE_ENC_MODE_PICTURE)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_ENC_OPERATION_MODE; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_VBV_PARAMS: |
| { |
| ih264e_ctl_set_vbv_params_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_vbv_params_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_vbv_params_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETVBVPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_vbv_params_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETVBVPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.u4_vbv_buffer_delay < DEFAULT_MIN_BUFFER_DELAY) |
| || (ps_ip->s_ive_ip.u4_vbv_buffer_delay > DEFAULT_MAX_BUFFER_DELAY)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_BUFFER_DELAY; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_AIR_PARAMS: |
| { |
| ih264e_ctl_set_air_params_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_air_params_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_air_params_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETAIRPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_air_params_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETAIRPARAMS_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if ((ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_NONE) |
| && (ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_CYCLIC) |
| && (ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_RANDOM)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_AIR_MODE; |
| return IV_FAIL; |
| } |
| |
| if (ps_ip->s_ive_ip.u4_air_refresh_period == 0) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_AIR_REFRESH_PERIOD; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| case IVE_CMD_CTL_SET_PROFILE_PARAMS: |
| { |
| ih264e_ctl_set_profile_params_ip_t *ps_ip = pv_api_ip; |
| ih264e_ctl_set_profile_params_op_t *ps_op = pv_api_op; |
| |
| if (ps_ip->s_ive_ip.u4_size |
| != sizeof(ih264e_ctl_set_profile_params_ip_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_IP_CTL_SETPROFILE_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_op->s_ive_op.u4_size |
| != sizeof(ih264e_ctl_set_profile_params_op_t)) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IVE_ERR_OP_CTL_SETPROFILE_API_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| |
| if (ps_ip->s_ive_ip.e_profile != IV_PROFILE_BASE && |
| ps_ip->s_ive_ip.e_profile != IV_PROFILE_MAIN) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_PROFILE_NOT_SUPPORTED; |
| return IV_FAIL; |
| } |
| |
| if (ps_ip->s_ive_ip.u4_entropy_coding_mode > 1) |
| { |
| ps_op->s_ive_op.u4_error_code |= 1 |
| << IVE_UNSUPPORTEDPARAM; |
| ps_op->s_ive_op.u4_error_code |= |
| IH264E_INVALID_ENTROPY_CODING_MODE; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| default: |
| *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; |
| *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_SUB_CMD; |
| return IV_FAIL; |
| } |
| |
| break; |
| } |
| |
| default: |
| *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; |
| *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_CMD; |
| return IV_FAIL; |
| } |
| |
| return IV_SUCCESS; |
| } |
| |
| /** |
| ******************************************************************************* |
| * |
| * @brief update encoder configuration parameters |
| * |
| * @par Description: |
| * updates encoder configuration parameters from the given config set. |
| * Initialize/reinitialize codec parameters according to new configurations. |
| * |
| * @param[in] ps_codec |
| * Pointer to codec context |
| * |
| * @param[in] ps_cfg |
| * Pointer to config param set |
| * |
| * @remarks none |
| * |
| ******************************************************************************* |
| */ |
| IH264E_ERROR_T ih264e_codec_update_config(codec_t *ps_codec, |
| cfg_params_t *ps_cfg) |
| { |
| /* config params */ |
| cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg; |
| |
| /* error status */ |
| IH264E_ERROR_T err = IH264E_SUCCESS; |
| |
| /* temp var */ |
| UWORD32 u4_init_rc = 0; |
| |
| /***********************/ |
| /* UPDATE CODEC CONFIG */ |
| /***********************/ |
| if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_DIMENSIONS) |
| { |
| UWORD32 wd_aln = ALIGN16(ps_cfg->u4_wd); |
| UWORD32 ht_aln = ALIGN16(ps_cfg->u4_ht); |
| |
| if (ps_curr_cfg->u4_wd != wd_aln || ps_curr_cfg->u4_ht != ht_aln |
| || ps_curr_cfg->u4_disp_wd != ps_cfg->u4_disp_wd |
| || ps_curr_cfg->u4_disp_ht != ps_cfg->u4_disp_ht) |
| { |
| ps_curr_cfg->u4_wd = wd_aln; |
| ps_curr_cfg->u4_ht = ht_aln; |
| |
| ps_curr_cfg->u4_disp_wd = ps_cfg->u4_disp_wd; |
| ps_curr_cfg->u4_disp_ht = ps_cfg->u4_disp_ht; |
| |
| ps_curr_cfg->i4_wd_mbs = ps_curr_cfg->u4_wd >> 4; |
| ps_curr_cfg->i4_ht_mbs = ps_curr_cfg->u4_ht >> 4; |
| |
| ps_codec->i4_rec_strd = ALIGN16(ps_cfg->u4_wd) + PAD_WD; |
| |
| /* If number of MBs in a frame changes the air map also changes. |
| * Hence recompute air map also reset air pic cnt */ |
| if (ps_codec->s_cfg.e_air_mode != IVE_AIR_MODE_NONE) |
| { |
| /* re-init the air map */ |
| ih264e_init_air_map(ps_codec); |
| |
| /* reset air counter */ |
| ps_codec->i4_air_pic_cnt = -1; |
| } |
| |
| /* initialize mv bank buffer manager */ |
| err = ih264e_mv_buf_mgr_add_bufs(ps_codec); |
| if (err != IH264E_SUCCESS) |
| return err; |
| |
| /* initialize ref bank buffer manager */ |
| err = ih264e_pic_buf_mgr_add_bufs(ps_codec); |
| if (err != IH264E_SUCCESS) |
| return err; |
| |
| /* since dimension changed, start new sequence by forcing IDR */ |
| ps_codec->force_curr_frame_type = IV_IDR_FRAME; |
| |
| /* in case dimension changes, we need to reinitialize RC as the |
| * old model shall not fit further */ |
| u4_init_rc = 1; |
| |
| /* when the dimension changes, the header needs to be regenerated */ |
| ps_codec->i4_gen_header = 1; |
| } |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_FRAMERATE) |
| { |
| /* temp var */ |
| UWORD32 u4_src_ticks, u4_tgt_ticks; |
| |
| u4_src_ticks = ih264e_frame_time_get_src_ticks( |
| ps_codec->s_rate_control.pps_frame_time); |
| |
| u4_tgt_ticks = ih264e_frame_time_get_tgt_ticks( |
| ps_codec->s_rate_control.pps_frame_time); |
| |
| /* Change frame rate */ |
| if (ps_codec->s_cfg.u4_src_frame_rate |
| != ps_cfg->u4_src_frame_rate * 1000) |
| { |
| ps_codec->s_cfg.u4_src_frame_rate = ps_cfg->u4_src_frame_rate |
| * 1000; |
| |
| ih264e_frame_time_update_src_frame_rate( |
| ps_codec->s_rate_control.pps_frame_time, |
| ps_codec->s_cfg.u4_src_frame_rate); |
| |
| ih264_time_stamp_update_frame_rate( |
| ps_codec->s_rate_control.pps_time_stamp, |
| ps_codec->s_cfg.u4_src_frame_rate); |
| |
| irc_change_frame_rate(ps_codec->s_rate_control.pps_rate_control_api, |
| ps_codec->s_cfg.u4_src_frame_rate, |
| u4_src_ticks, u4_tgt_ticks); |
| } |
| |
| if (ps_codec->s_cfg.u4_tgt_frame_rate |
| != ps_cfg->u4_tgt_frame_rate * 1000) |
| { |
| ps_codec->s_cfg.u4_tgt_frame_rate = ps_cfg->u4_tgt_frame_rate |
| * 1000; |
| |
| ih264e_frame_time_update_tgt_frame_rate( |
| ps_codec->s_rate_control.pps_frame_time, |
| ps_codec->s_cfg.u4_tgt_frame_rate); |
| |
| irc_change_frame_rate(ps_codec->s_rate_control.pps_rate_control_api, |
| ps_codec->s_cfg.u4_src_frame_rate, |
| u4_src_ticks, u4_tgt_ticks); |
| |
| irc_change_frm_rate_for_bit_alloc( |
| ps_codec->s_rate_control.pps_rate_control_api, |
| ps_codec->s_cfg.u4_tgt_frame_rate); |
| } |
| |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_BITRATE) |
| { |
| if (ps_curr_cfg->u4_target_bitrate != ps_cfg->u4_target_bitrate) |
| { |
| if (IVE_RC_NONE != ps_curr_cfg->e_rc_mode) |
| irc_change_avg_bit_rate( |
| ps_codec->s_rate_control.pps_rate_control_api, |
| ps_cfg->u4_target_bitrate); |
| |
| ps_curr_cfg->u4_target_bitrate = ps_cfg->u4_target_bitrate; |
| } |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_FRAMETYPE) |
| { |
| switch (ps_cfg->e_frame_type) |
| { |
| case IV_I_FRAME: |
| ps_codec->force_curr_frame_type = IV_I_FRAME; |
| break; |
| |
| case IV_IDR_FRAME: |
| ps_codec->force_curr_frame_type = IV_IDR_FRAME; |
| break; |
| |
| case IV_P_FRAME: |
| default: |
| break; |
| } |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_ME_PARAMS) |
| { |
| if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG) |
| { |
| ps_codec->s_cfg.u4_enable_hpel = ps_cfg->u4_enable_hpel; |
| ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad; |
| ps_codec->s_cfg.u4_me_speed_preset = ps_cfg->u4_me_speed_preset; |
| ps_codec->s_cfg.u4_enable_qpel = ps_cfg->u4_enable_qpel; |
| } |
| else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST) |
| { |
| ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad; |
| } |
| ps_codec->s_cfg.u4_srch_rng_x = ps_cfg->u4_srch_rng_x; |
| ps_codec->s_cfg.u4_srch_rng_y = ps_cfg->u4_srch_rng_y; |
| |
| if (ps_codec->s_cfg.u4_enable_alt_ref != ps_cfg->u4_enable_alt_ref) |
| { |
| ps_codec->s_cfg.u4_enable_alt_ref = ps_cfg->u4_enable_alt_ref; |
| ps_codec->u4_is_curr_frm_ref = 1; |
| } |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_IPE_PARAMS) |
| { |
| ps_curr_cfg->u4_enc_speed_preset = ps_cfg->u4_enc_speed_preset; |
| |
| if (ps_curr_cfg->u4_enc_speed_preset == IVE_SLOWEST) |
| {/* high quality */ |
| /* enable diamond search */ |
| ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; |
| ps_curr_cfg->u4_enable_fast_sad = 0; |
| |
| /* disable intra 4x4 */ |
| ps_curr_cfg->u4_enable_intra_4x4 = 1; |
| ps_codec->luma_energy_compaction[1] = |
| ih264e_code_luma_intra_macroblock_4x4_rdopt_on; |
| |
| /* sub pel off */ |
| ps_curr_cfg->u4_enable_hpel = 1; |
| |
| /* deblocking off */ |
| ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; |
| |
| /* disabled intra inter gating in Inter slices */ |
| ps_codec->u4_inter_gate = 0; |
| } |
| else if (ps_curr_cfg->u4_enc_speed_preset == IVE_NORMAL) |
| {/* normal */ |
| /* enable diamond search */ |
| ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; |
| ps_curr_cfg->u4_enable_fast_sad = 0; |
| |
| /* disable intra 4x4 */ |
| ps_curr_cfg->u4_enable_intra_4x4 = 1; |
| |
| /* sub pel off */ |
| ps_curr_cfg->u4_enable_hpel = 1; |
| |
| /* deblocking off */ |
| ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; |
| |
| /* disabled intra inter gating in Inter slices */ |
| ps_codec->u4_inter_gate = 0; |
| } |
| else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FAST) |
| {/* normal */ |
| /* enable diamond search */ |
| ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; |
| ps_curr_cfg->u4_enable_fast_sad = 0; |
| |
| /* disable intra 4x4 */ |
| ps_curr_cfg->u4_enable_intra_4x4 = 0; |
| |
| /* sub pel off */ |
| ps_curr_cfg->u4_enable_hpel = 1; |
| |
| /* deblocking off */ |
| ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; |
| |
| /* disabled intra inter gating in Inter slices */ |
| ps_codec->u4_inter_gate = 1; |
| } |
| else if (ps_curr_cfg->u4_enc_speed_preset == IVE_HIGH_SPEED) |
| {/* fast */ |
| /* enable diamond search */ |
| ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; |
| ps_curr_cfg->u4_enable_fast_sad = 0; |
| |
| /* disable intra 4x4 */ |
| ps_curr_cfg->u4_enable_intra_4x4 = 0; |
| |
| /* sub pel off */ |
| ps_curr_cfg->u4_enable_hpel = 0; |
| |
| /* deblocking off */ |
| ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4; |
| |
| /* disabled intra inter gating in Inter slices */ |
| ps_codec->u4_inter_gate = 0; |
| } |
| else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST) |
| {/* fastest */ |
| /* enable diamond search */ |
| ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; |
| //u4_num_layers = 4; |
| |
| /* disable intra 4x4 */ |
| ps_curr_cfg->u4_enable_intra_4x4 = 0; |
| |
| /* sub pel off */ |
| ps_curr_cfg->u4_enable_hpel = 0; |
| |
| /* deblocking off */ |
| ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4; |
| |
| /* disabled intra inter gating in Inter slices */ |
| ps_codec->u4_inter_gate = 1; |
| } |
| else if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG) |
| { |
| ps_curr_cfg->u4_enable_intra_4x4 = ps_cfg->u4_enable_intra_4x4; |
| } |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_GOP_PARAMS) |
| { |
| if (ps_curr_cfg->u4_i_frm_interval != ps_cfg->u4_i_frm_interval) |
| { |
| ps_curr_cfg->u4_i_frm_interval = ps_cfg->u4_i_frm_interval; |
| |
| /* reset air counter */ |
| ps_codec->i4_air_pic_cnt = -1; |
| |
| /* re-init air map */ |
| ih264e_init_air_map(ps_codec); |
| |
| /*Effect intra frame interval change*/ |
| |
| irc_change_intra_frm_int_call( |
| ps_codec->s_rate_control.pps_rate_control_api, |
| ps_curr_cfg->u4_i_frm_interval); |
| } |
| |
| ps_curr_cfg->u4_idr_frm_interval = ps_cfg->u4_idr_frm_interval; |
| |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_DEBLOCK_PARAMS) |
| { |
| if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG) |
| { |
| ps_curr_cfg->u4_disable_deblock_level = |
| ps_cfg->u4_disable_deblock_level; |
| } |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_QP) |
| { |
| UWORD8 au1_init_qp[MAX_PIC_TYPE]; |
| UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE]; |
| |
| ps_codec->s_cfg.u4_i_qp_max = ps_cfg->u4_i_qp_max; |
| ps_codec->s_cfg.u4_i_qp_min = ps_cfg->u4_i_qp_min; |
| ps_codec->s_cfg.u4_i_qp = ps_cfg->u4_i_qp; |
| |
| ps_codec->s_cfg.u4_p_qp_max = ps_cfg->u4_p_qp_max; |
| ps_codec->s_cfg.u4_p_qp_min = ps_cfg->u4_p_qp_min; |
| ps_codec->s_cfg.u4_p_qp = ps_cfg->u4_p_qp; |
| |
| ps_codec->s_cfg.u4_b_qp_max = ps_cfg->u4_b_qp_max; |
| ps_codec->s_cfg.u4_b_qp_min = ps_cfg->u4_b_qp_min; |
| ps_codec->s_cfg.u4_b_qp = ps_cfg->u4_b_qp; |
| |
| /* update rc lib with modified qp */ |
| au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp]; |
| au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp]; |
| au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp]; |
| |
| irc_change_init_qp(ps_codec->s_rate_control.pps_rate_control_api, |
| au1_init_qp); |
| |
| au1_min_max_qp[2 * I_PIC] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_min]; |
| au1_min_max_qp[2 * I_PIC + 1] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_max]; |
| |
| au1_min_max_qp[2 * P_PIC] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_min]; |
| au1_min_max_qp[2 * P_PIC + 1] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_max]; |
| |
| au1_min_max_qp[2 * B_PIC] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_min]; |
| au1_min_max_qp[2 * B_PIC + 1] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_max]; |
| |
| irc_change_min_max_qp(ps_codec->s_rate_control.pps_rate_control_api, |
| au1_min_max_qp); |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_ENC_MODE) |
| { |
| ps_codec->s_cfg.e_enc_mode = ps_cfg->e_enc_mode; |
| |
| if (ps_codec->s_cfg.e_enc_mode == IVE_ENC_MODE_HEADER) |
| { |
| ps_codec->i4_header_mode = 1; |
| ps_codec->s_cfg.e_enc_mode = IVE_ENC_MODE_PICTURE; |
| } |
| else |
| { |
| ps_codec->i4_header_mode = 0; |
| } |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_VBV_PARAMS |
| && IVE_RC_NONE != ps_codec->s_cfg.e_rc_mode) |
| { |
| ps_codec->s_cfg.u4_vbv_buf_size = ps_cfg->u4_vbv_buf_size; |
| ps_codec->s_cfg.u4_vbv_buffer_delay = ps_cfg->u4_vbv_buffer_delay; |
| |
| // irc_change_buffer_delay(ps_codec->s_rate_control.pps_rate_control_api, ps_codec->s_cfg.u4_vbv_buffer_delay); |
| |
| // TODO: remove this when the support for changing buffer dynamically |
| // is yet to be added. |
| u4_init_rc = 1; |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_AIR_PARAMS) |
| { |
| if (ps_curr_cfg->e_air_mode != ps_cfg->e_air_mode |
| || ps_curr_cfg->u4_air_refresh_period |
| != ps_cfg->u4_air_refresh_period) |
| { |
| ps_curr_cfg->e_air_mode = ps_cfg->e_air_mode; |
| ps_curr_cfg->u4_air_refresh_period = ps_cfg->u4_air_refresh_period; |
| |
| ih264e_init_air_map(ps_codec); |
| |
| /* reset air counter */ |
| ps_codec->i4_air_pic_cnt = -1; |
| } |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_PROFILE_PARAMS) |
| { |
| ps_codec->s_cfg.e_profile = ps_cfg->e_profile; |
| ps_codec->s_cfg.u4_entropy_coding_mode = ps_cfg->u4_entropy_coding_mode; |
| } |
| else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_NUM_CORES) |
| { |
| ps_codec->s_cfg.u4_num_cores = ps_cfg->u4_num_cores; |
| } |
| |
| /* reset RC model */ |
| if (u4_init_rc) |
| { |
| /* init qp */ |
| UWORD8 au1_init_qp[MAX_PIC_TYPE]; |
| |
| /* min max qp */ |
| UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE]; |
| |
| /* init i,p,b qp */ |
| au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp]; |
| au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp]; |
| au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp]; |
| |
| /* init min max qp */ |
| au1_min_max_qp[2 * I_PIC] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_min]; |
| au1_min_max_qp[2 * I_PIC + 1] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_max]; |
| |
| au1_min_max_qp[2 * P_PIC] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_min]; |
| au1_min_max_qp[2 * P_PIC + 1] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_max]; |
| |
| au1_min_max_qp[2 * B_PIC] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_min]; |
| au1_min_max_qp[2 * B_PIC + 1] = |
| gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_max]; |
| |
| /* get rc mode */ |
| switch (ps_codec->s_cfg.e_rc_mode) |
| { |
| case IVE_RC_STORAGE: |
| ps_codec->s_rate_control.e_rc_type = VBR_STORAGE; |
| break; |
| |
| case IVE_RC_CBR_NON_LOW_DELAY: |
| ps_codec->s_rate_control.e_rc_type = CBR_NLDRC; |
| break; |
| |
| case IVE_RC_CBR_LOW_DELAY: |
| ps_codec->s_rate_control.e_rc_type = CBR_LDRC; |
| break; |
| |
| case IVE_RC_NONE: |
| ps_codec->s_rate_control.e_rc_type = CONST_QP; |
| break; |
| |
| default: |
| break; |
| } |
| |
| /* init rate control */ |
| ih264e_rc_init(ps_codec->s_rate_control.pps_rate_control_api, |
| ps_codec->s_rate_control.pps_frame_time, |
| ps_codec->s_rate_control.pps_time_stamp, |
| ps_codec->s_rate_control.pps_pd_frm_rate, |
| ps_codec->s_cfg.u4_max_framerate, |
| ps_codec->s_cfg.u4_src_frame_rate, |
| ps_codec->s_cfg.u4_tgt_frame_rate, |
| ps_codec->s_rate_control.e_rc_type, |
| ps_codec->s_cfg.u4_target_bitrate, |
| ps_codec->s_cfg.u4_max_bitrate, |
| ps_codec->s_cfg.u4_vbv_buffer_delay, |
| ps_codec->s_cfg.u4_i_frm_interval, |
| ps_codec->s_cfg.u4_num_bframes + 1, au1_init_qp, |
| ps_codec->s_cfg.u4_num_bframes + 2, au1_min_max_qp, |
| ps_codec->s_cfg.u4_max_level); |
| } |
| |
| return err; |
| } |
| |
| /** |
| ******************************************************************************* |
| * |
| * @brief |
| * Sets default encoder config parameters |
| * |
| * @par Description: |
| * Sets default dynamic parameters. Will be called in ih264e_init() to ensure |
| * that even if set_params is not called, codec continues to work |
| * |
| * @param[in] ps_cfg |
| * Pointer to encoder config params |
| * |
| * @returns error status |
| * |
| * @remarks none |
| * |
| ******************************************************************************* |
| */ |
| static WORD32 ih264e_set_default_params(cfg_params_t *ps_cfg) |
| { |
| WORD32 ret = IV_SUCCESS; |
| |
| ps_cfg->u4_max_wd = MAX_WD; |
| ps_cfg->u4_max_ht = MAX_HT; |
| ps_cfg->u4_max_ref_cnt = MAX_REF_CNT; |
| ps_cfg->u4_max_reorder_cnt = MAX_REF_CNT; |
| ps_cfg->u4_max_level = DEFAULT_MAX_LEVEL; |
| ps_cfg->e_inp_color_fmt = IV_YUV_420SP_UV; |
| ps_cfg->u4_enable_recon = DEFAULT_RECON_ENABLE; |
| ps_cfg->e_recon_color_fmt = IV_YUV_420P; |
| ps_cfg->u4_enc_speed_preset = IVE_FASTEST; |
| ps_cfg->e_rc_mode = DEFAULT_RC; |
| ps_cfg->u4_max_framerate = DEFAULT_MAX_FRAMERATE; |
| ps_cfg->u4_max_bitrate = DEFAULT_MAX_BITRATE; |
| ps_cfg->u4_num_bframes = DEFAULT_MAX_NUM_BFRAMES; |
| ps_cfg->e_content_type = IV_PROGRESSIVE; |
| ps_cfg->u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; |
| ps_cfg->u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; |
| ps_cfg->e_slice_mode = IVE_SLICE_MODE_NONE; |
| ps_cfg->u4_slice_param = DEFAULT_SLICE_PARAM; |
| ps_cfg->e_arch = ih264e_default_arch(); |
| ps_cfg->e_soc = SOC_GENERIC; |
| ps_cfg->u4_disp_wd = MAX_WD; |
| ps_cfg->u4_disp_ht = MAX_HT; |
| ps_cfg->u4_wd = MAX_WD; |
| ps_cfg->u4_ht = MAX_HT; |
| ps_cfg->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE; |
| ps_cfg->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE; |
| ps_cfg->u4_target_bitrate = DEFAULT_BITRATE; |
| ps_cfg->e_frame_type = IV_NA_FRAME; |
| ps_cfg->e_enc_mode = IVE_ENC_MODE_DEFAULT; |
| ps_cfg->u4_i_qp = DEFAULT_I_QP; |
| ps_cfg->u4_p_qp = DEFAULT_P_QP; |
| ps_cfg->u4_b_qp = DEFAULT_B_QP; |
| ps_cfg->u4_i_qp_min = DEFAULT_QP_MIN; |
| ps_cfg->u4_i_qp_max = DEFAULT_QP_MAX; |
| ps_cfg->u4_p_qp_min = DEFAULT_QP_MIN; |
| ps_cfg->u4_p_qp_max = DEFAULT_QP_MAX; |
| ps_cfg->u4_b_qp_min = DEFAULT_QP_MIN; |
| ps_cfg->u4_b_qp_max = DEFAULT_QP_MAX; |
| ps_cfg->e_air_mode = DEFAULT_AIR_MODE; |
| ps_cfg->u4_air_refresh_period = DEFAULT_AIR_REFRESH_PERIOD; |
| ps_cfg->u4_vbv_buffer_delay = DEFAULT_VBV_DELAY; |
| ps_cfg->u4_vbv_buf_size = DEFAULT_VBV_SIZE; |
| ps_cfg->u4_num_cores = DEFAULT_NUM_CORES; |
| ps_cfg->u4_me_speed_preset = DEFAULT_ME_SPEED_PRESET; |
| ps_cfg->u4_enable_hpel = DEFAULT_HPEL; |
| ps_cfg->u4_enable_qpel = DEFAULT_QPEL; |
| ps_cfg->u4_enable_intra_4x4 = DEFAULT_I4; |
| ps_cfg->u4_enable_intra_8x8 = DEFAULT_I8; |
| ps_cfg->u4_enable_intra_16x16 = DEFAULT_I16; |
| ps_cfg->u4_enable_fast_sad = DEFAULT_ENABLE_FAST_SAD; |
| ps_cfg->u4_enable_satqd = DEFAULT_ENABLE_SATQD; |
| ps_cfg->i4_min_sad = |
| (ps_cfg->u4_enable_satqd == DEFAULT_ENABLE_SATQD) ? |
| DEFAULT_MIN_SAD_ENABLE : |
| DEFAULT_MIN_SAD_DISABLE; |
| ps_cfg->u4_srch_rng_x = DEFAULT_SRCH_RNG_X; |
| ps_cfg->u4_srch_rng_y = DEFAULT_SRCH_RNG_Y; |
| ps_cfg->u4_i_frm_interval = DEFAULT_I_INTERVAL; |
| ps_cfg->u4_idr_frm_interval = DEFAULT_IDR_INTERVAL; |
| ps_cfg->u4_disable_deblock_level = DEFAULT_DISABLE_DEBLK_LEVEL; |
| ps_cfg->e_profile = DEFAULT_PROFILE; |
| ps_cfg->u4_timestamp_low = 0; |
| ps_cfg->u4_timestamp_high = 0; |
| ps_cfg->u4_is_valid = 1; |
| ps_cfg->e_cmd = IVE_CMD_CT_NA; |
| ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4; |
| ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4; |
| ps_cfg->u4_entropy_coding_mode = CAVLC; |
| ps_cfg->u4_weighted_prediction = 0; |
| ps_cfg->u4_constrained_intra_pred = 0; |
| ps_cfg->u4_pic_info_type = 0; |
| ps_cfg->u4_mb_info_type = 0; |
| |
| return ret; |
| } |
| |
| /** |
| ******************************************************************************* |
| * |
| * @brief |
| * Initialize encoder context. This will be called by init_mem_rec and during |
| * codec reset |
| * |
| * @par Description: |
| * Initializes the context |
| * |
| * @param[in] ps_codec |
| * Codec context pointer |
| * |
| * @returns error status |
| * |
| * @remarks none |
| * |
| ******************************************************************************* |
| */ |
| static WORD32 ih264e_init(codec_t *ps_codec) |
| { |
| /* enc config param set */ |
| cfg_params_t *ps_cfg = &(ps_codec->s_cfg); |
| |
| /* temp var */ |
| WORD32 i; |
| |
| /* coded pic count */ |
| ps_codec->i4_poc = 0; |
| |
| /* Number of API calls to encode are made */ |
| ps_codec->i4_encode_api_call_cnt = -1; |
| |
| /* Indicates no header has been generated yet */ |
| ps_codec->u4_header_generated = 0; |
| |
| /* Number of pictures encoded */ |
| ps_codec->i4_pic_cnt = -1; |
| |
| /* Number of threads created */ |
| ps_codec->i4_proc_thread_cnt = 0; |
| |
| /* ctl mutex init */ |
| ithread_mutex_init(ps_codec->pv_ctl_mutex); |
| |
| /* Set encoder chroma format */ |
| ps_codec->e_codec_color_format = |
| (ps_cfg->e_inp_color_fmt == IV_YUV_420SP_VU) ? |
| IV_YUV_420SP_VU : IV_YUV_420SP_UV; |
| |
| /* Number of continuous frames where deblocking was disabled */ |
| ps_codec->i4_disable_deblk_pic_cnt = 0; |
| |
| /* frame num */ |
| ps_codec->i4_frame_num = 0; |
| |
| /* set the current frame type to I frame, since we are going to start encoding*/ |
| ps_codec->force_curr_frame_type = IV_NA_FRAME; |
| |
| /* idr_pic_id */ |
| ps_codec->i4_idr_pic_id = -1; |
| |
| /* Flush mode */ |
| ps_codec->i4_flush_mode = 0; |
| |
| /* Encode header mode */ |
| ps_codec->i4_header_mode = 0; |
| |
| /* Encode generate header */ |
| ps_codec->i4_gen_header = 0; |
| |
| /* To signal successful completion of init */ |
| ps_codec->i4_init_done = 1; |
| |
| /* To signal that at least one picture was decoded */ |
| ps_codec->i4_first_pic_done = 0; |
| |
| /* Reset Codec */ |
| ps_codec->i4_reset_flag = 0; |
| |
| /* Current error code */ |
| ps_codec->i4_error_code = IH264E_SUCCESS; |
| |
| /* threshold residue */ |
| ps_codec->u4_thres_resi = 1; |
| |
| /* inter gating enable */ |
| ps_codec->u4_inter_gate = 0; |
| |
| /* entropy mutex init */ |
| ithread_mutex_init(ps_codec->pv_entropy_mutex); |
| |
| /* sps id */ |
| ps_codec->i4_sps_id = 0; |
| |
| /* sps id */ |
| ps_codec->i4_pps_id = 0; |
| |
| /* Process thread created status */ |
| memset(ps_codec->ai4_process_thread_created, 0, MAX_PROCESS_THREADS); |
| |
| /* Number of MBs processed together */ |
| ps_codec->i4_proc_nmb = 8; |
| |
| /* Previous POC msb */ |
| ps_codec->i4_prev_poc_msb = 0; |
| |
| /* Previous POC lsb */ |
| ps_codec->i4_prev_poc_lsb = -1; |
| |
| /* max Previous POC lsb */ |
| ps_codec->i4_max_prev_poc_lsb = -1; |
| |
| /* sps, pps status */ |
| { |
| sps_t *ps_sps = ps_codec->ps_sps_base; |
| pps_t *ps_pps = ps_codec->ps_pps_base; |
| |
| for (i = 0; i < MAX_SPS_CNT; i++) |
| { |
| ps_sps->i1_sps_valid = 0; |
| ps_sps++; |
| } |
| |
| for (i = 0; i < MAX_PPS_CNT; i++) |
| { |
| ps_pps->i1_pps_valid = 0; |
| ps_pps++; |
| } |
| } |
| |
| { |
| WORD32 max_mb_rows = ps_cfg->i4_ht_mbs; |
| |
| WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS; |
| WORD32 clz; |
| |
| /* Use next power of two number of entries*/ |
| clz = CLZ(num_jobs); |
| num_jobs = 1 << (32 - clz); |
| |
| /* init process jobq */ |
| ps_codec->pv_proc_jobq = ih264_list_init( |
| ps_codec->pv_proc_jobq_buf, |
| ps_codec->i4_proc_jobq_buf_size, num_jobs, |
| sizeof(job_t), 10); |
| RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL); |
| ih264_list_reset(ps_codec->pv_proc_jobq); |
| |
| /* init entropy jobq */ |
| ps_codec->pv_entropy_jobq = ih264_list_init( |
| ps_codec->pv_entropy_jobq_buf, |
| ps_codec->i4_entropy_jobq_buf_size, num_jobs, |
| sizeof(job_t), 10); |
| RETURN_IF((ps_codec->pv_entropy_jobq == NULL), IV_FAIL); |
| ih264_list_reset(ps_codec->pv_entropy_jobq); |
| } |
| |
| /* Update the jobq context to all the threads */ |
| for (i = 0; i < MAX_PROCESS_CTXT; i++) |
| { |
| ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq; |
| ps_codec->as_process[i].pv_entropy_jobq = ps_codec->pv_entropy_jobq; |
| |
| /* i4_id always stays between 0 and MAX_PROCESS_THREADS */ |
| ps_codec->as_process[i].i4_id = |
| (i >= MAX_PROCESS_THREADS) ? |
| (i - MAX_PROCESS_THREADS) : i; |
| ps_codec->as_process[i].ps_codec = ps_codec; |
| |
| ps_codec->as_process[i].s_entropy.pv_proc_jobq = ps_codec->pv_proc_jobq; |
| ps_codec->as_process[i].s_entropy.pv_entropy_jobq = |
| ps_codec->pv_entropy_jobq; |
| ps_codec->as_process[i].s_entropy.i4_abs_pic_order_cnt = -1; |
| } |
| |
| /* Initialize MV Bank buffer manager */ |
| ps_codec->pv_mv_buf_mgr = ih264_buf_mgr_init(ps_codec->pv_mv_buf_mgr_base); |
| |
| /* Initialize Picture buffer manager for reference buffers*/ |
| ps_codec->pv_ref_buf_mgr = ih264_buf_mgr_init( |
| ps_codec->pv_ref_buf_mgr_base); |
| |
| /* Initialize Picture buffer manager for input buffers*/ |
| ps_codec->pv_inp_buf_mgr = ih264_buf_mgr_init( |
| ps_codec->pv_inp_buf_mgr_base); |
| |
| /* Initialize buffer manager for output buffers*/ |
| ps_codec->pv_out_buf_mgr = ih264_buf_mgr_init( |
| ps_codec->pv_out_buf_mgr_base); |
| |
| /* buffer cnt in buffer manager */ |
| ps_codec->i4_inp_buf_cnt = 0; |
| ps_codec->i4_out_buf_cnt = 0; |
| ps_codec->i4_ref_buf_cnt = 0; |
| |
| ps_codec->ps_pic_buf = (pic_buf_t *) ps_codec->pv_pic_buf_base; |
| memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT * sizeof(pic_buf_t)); |
| |
| /* Initialize dpb manager */ |
| ih264_dpb_mgr_init((dpb_mgr_t*) ps_codec->pv_dpb_mgr); |
| |
| memset(ps_codec->as_ref_set, 0, |
| sizeof(ref_set_t) * (MAX_DPB_SIZE + MAX_CTXT_SETS)); |
| for (i = 0; i < (MAX_DPB_SIZE + MAX_CTXT_SETS); i++) |
| { |
| ps_codec->as_ref_set[i].i4_pic_cnt = -1; |
| } |
| |
| /* fn ptr init */ |
| ih264e_init_function_ptr(ps_codec); |
| |
| /* reset status flags */ |
| for (i = 0; i < MAX_CTXT_SETS; i++) |
| { |
| ps_codec->au4_entropy_thread_active[i] = 0; |
| ps_codec->ai4_pic_cnt[i] = -1; |
| |
| ps_codec->s_rate_control.pre_encode_skip[i] = 0; |
| ps_codec->s_rate_control.post_encode_skip[i] = 0; |
| } |
| |
| ps_codec->s_rate_control.num_intra_in_prev_frame = 0; |
| ps_codec->s_rate_control.i4_avg_activity = 0; |
| |
| return IV_SUCCESS; |
| } |
| |
| /** |
| ******************************************************************************* |
| * |
| * @brief |
| * Gets number of memory records required by the codec |
| * |
| * @par Description: |
| * Gets codec memory requirements |
| * |
| * @param[in] pv_api_ip |
| * Pointer to input argument structure |
| * |
| * @param[out] pv_api_op |
| * Pointer to output argument structure |
| * |
| * @returns status |
| * |
| * @remarks |
| * |
| ******************************************************************************* |
| */ |
| static WORD32 ih264e_get_num_rec(void *pv_api_ip, void *pv_api_op) |
| { |
| /* api call I/O structures */ |
| ih264e_num_mem_rec_op_t *ps_op = pv_api_op; |
| |
| UNUSED(pv_api_ip); |
| |
| ps_op->s_ive_op.u4_num_mem_rec = MEM_REC_CNT; |
| |
| return IV_SUCCESS; |
| } |
| |
| /** |
| ******************************************************************************* |
| * |
| * @brief |
| * Fills memory records of the codec |
| * |
| * @par Description: |
| * Fills codec memory requirements |
| * |
| * @param[in] pv_api_ip |
| * Pointer to input argument structure |
| * |
| * @param[out] pv_api_op |
| * Pointer to output argument structure |
| * |
| * @returns error status |
| * |
| * @remarks none |
| * |
| ******************************************************************************* |
| */ |
| static WORD32 ih264e_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op) |
| { |
| /* api call I/O structures */ |
| ih264e_fill_mem_rec_ip_t *ps_ip = pv_api_ip; |
| ih264e_fill_mem_rec_op_t *ps_op = pv_api_op; |
| |
| /* profile / level info */ |
| WORD32 level; |
| WORD32 num_reorder_frames; |
| WORD32 num_ref_frames; |
| |
| /* mem records */ |
| WORD32 no_of_mem_rec; |
| iv_mem_rec_t *ps_mem_rec_base, *ps_mem_rec; |
| |
| /* frame dimensions */ |
| WORD32 max_wd_luma, max_ht_luma; |
| WORD32 max_mb_rows, max_mb_cols, max_mb_cnt; |
| |
| /* temp var */ |
| WORD32 i; |
| |
| /* error status */ |
| IV_STATUS_T status = IV_SUCCESS; |
| |
| num_reorder_frames = ps_ip->s_ive_ip.u4_max_reorder_cnt; |
| num_ref_frames = ps_ip->s_ive_ip.u4_max_ref_cnt; |
| |
| /* mem records */ |
| ps_mem_rec_base = ps_ip->s_ive_ip.ps_mem_rec; |
| no_of_mem_rec = ps_ip->s_ive_ip.u4_num_mem_rec; |
| |
| /* frame dimensions */ |
| max_ht_luma = ps_ip->s_ive_ip.u4_max_ht; |
| max_wd_luma = ps_ip->s_ive_ip.u4_max_wd; |
| max_ht_luma = ALIGN16(max_ht_luma); |
| max_wd_luma = ALIGN16(max_wd_luma); |
| max_mb_rows = max_ht_luma / MB_SIZE; |
| max_mb_cols = max_wd_luma / MB_SIZE; |
| max_mb_cnt = max_mb_rows * max_mb_cols; |
| |
| /* profile / level info */ |
| level = ih264e_get_min_level(max_ht_luma, max_wd_luma); |
| |
| /* validate params */ |
| if ((level < MIN_LEVEL) || (level > MAX_LEVEL)) |
| { |
| ps_op->s_ive_op.u4_error_code |= IH264E_CODEC_LEVEL_NOT_SUPPORTED; |
| level = MAX_LEVEL; |
| } |
| |
| if (num_ref_frames > MAX_REF_CNT) |
| { |
| ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED; |
| num_ref_frames = MAX_REF_CNT; |
| } |
| |
| if (num_reorder_frames > MAX_REF_CNT) |
| { |
| ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED; |
| num_reorder_frames = MAX_REF_CNT; |
| } |
| |
| /* Set all memory records as persistent and alignment as 128 by default */ |
| ps_mem_rec = ps_mem_rec_base; |
| for (i = 0; i < no_of_mem_rec; i++) |
| { |
| ps_mem_rec->u4_mem_alignment = 128; |
| ps_mem_rec->e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| ps_mem_rec++; |
| } |
| |
| /************************************************************************ |
| * Request memory for h264 encoder handle * |
| ***********************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_IV_OBJ]; |
| { |
| ps_mem_rec->u4_mem_size = sizeof(iv_obj_t); |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_IV_OBJ, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory for h264 encoder context * |
| ***********************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC]; |
| { |
| ps_mem_rec->u4_mem_size = sizeof(codec_t); |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CODEC, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory for CABAC context * |
| ***********************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC]; |
| { |
| ps_mem_rec->u4_mem_size = sizeof(cabac_ctxt_t); |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CABAC, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory for CABAC MB info * |
| ***********************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC_MB_INFO]; |
| { |
| ps_mem_rec->u4_mem_size = ((max_mb_cols + 1) + 1) |
| * sizeof(mb_info_ctxt_t); |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CABAC_MB_INFO, ps_mem_rec->u4_mem_size); |
| |
| |
| /************************************************************************ |
| * Request memory for entropy context * |
| * In multi core encoding, each row is assumed to be launched on a * |
| * thread. The rows below can only start after its neighbors are coded * |
| * The status of an mb coded/uncoded is signaled via entropy map. * |
| * 1. One word32 to store skip run cnt * |
| * 2. mb entropy map (mb status entropy coded/uncoded). The size* |
| * of the entropy map is max mb cols. Further allocate one * |
| * more additional row to evade checking for row -1. * |
| * 3. size of bit stream buffer to store bit stream ctxt. * |
| * 4. Entropy coding is dependent on nnz coefficient count for * |
| * the neighbor blocks. It is sufficient to maintain one row * |
| * worth of nnz as entropy for lower row waits on entropy map* |
| ************************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY]; |
| { |
| /* total size of the mem record */ |
| WORD32 total_size = 0; |
| |
| /* size of skip mb run */ |
| total_size += sizeof(WORD32); |
| total_size = ALIGN8(total_size); |
| |
| /* size in bytes to store entropy status of an entire frame */ |
| total_size += (max_mb_cols * max_mb_rows); |
| /* add an additional 1 row of bytes to evade the special case of row 0 */ |
| total_size += max_mb_cols; |
| total_size = ALIGN128(total_size); |
| |
| /* size of bit stream buffer */ |
| total_size += sizeof(bitstrm_t); |
| total_size = ALIGN128(total_size); |
| |
| /* top nnz luma */ |
| total_size += (max_mb_cols * 4 * sizeof(UWORD8)); |
| total_size = ALIGN128(total_size); |
| |
| /* top nnz cbcr */ |
| total_size += (max_mb_cols * 4 * sizeof(UWORD8)); |
| total_size = ALIGN128(total_size); |
| |
| /* total size per each proc ctxt */ |
| total_size *= MAX_CTXT_SETS; |
| |
| ps_mem_rec->u4_mem_size = total_size; |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTROPY, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * The residue coefficients that needs to be entropy coded are packed * |
| * at a buffer space by the proc threads. The entropy thread shall * |
| * read from the buffer space, unpack them and encode the same. The * |
| * buffer space required to pack a row of mbs are as follows. * |
| * Assuming transform_8x8_flag is disabled, * |
| * In the worst case, 1 mb contains 1 dc 4x4 luma sub block, followed * |
| * by 16 ac 4x4 luma sub blocks, 2 dc chroma 2x2 sub blocks, followed * |
| * by 8 ac 4x4 chroma sub blocks. * |
| * For the sake of simplicity we assume that all sub blocks are of * |
| * type 4x4. The packing of each 4x4 is depicted by the structure * |
| * tu_sblk_coeff_data_t * |
| ************************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_COEFF_DATA]; |
| { |
| /* temp var */ |
| WORD32 size = 0; |
| |
| /* size of coeff data of 1 mb */ |
| size += sizeof(tu_sblk_coeff_data_t) * MAX_4x4_SUBBLKS; |
| |
| /* size of coeff data of 1 row of mb's */ |
| size *= max_mb_cols; |
| |
| /* align to avoid any false sharing across threads */ |
| size = ALIGN64(size); |
| |
| /* size for one full frame */ |
| size *= max_mb_rows; |
| |
| /* size of each proc buffer set (ping, pong) */ |
| size *= MAX_CTXT_SETS; |
| |
| ps_mem_rec->u4_mem_size = size; |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MB_COEFF_DATA, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * while encoding an mb, the mb header data is signaled to the entropy* |
| * thread by writing to a buffer space. the size of header data per mb * |
| * is assumed to be 40 bytes * |
| * TODO: revisit this inference * |
| ************************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_HEADER_DATA]; |
| { |
| /* temp var */ |
| WORD32 size; |
| |
| /* size per MB */ |
| size = 40; |
| |
| /* size for 1 row of mbs */ |
| size = size * max_mb_cols; |
| |
| /* align to avoid any false sharing across threads */ |
| size = ALIGN64(size); |
| |
| /* size for one full frame */ |
| size *= max_mb_rows; |
| |
| /* size of each proc buffer set (ping, pong) */ |
| size *= MAX_CTXT_SETS; |
| |
| ps_mem_rec->u4_mem_size = size; |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MB_HEADER_DATA, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Size for holding mv_buf_t for each MV Bank. * |
| * Note this allocation is done for BUF_MGR_MAX_CNT instead of * |
| * MAX_DPB_SIZE or max_dpb_size for following reasons * |
| * max_dpb_size will be based on max_wd and max_ht * |
| * For higher max_wd and max_ht this number will be smaller than * |
| * MAX_DPB_SIZE But during actual initialization number of buffers * |
| * allocated can be more. * |
| * * |
| * One extra MV Bank is needed to hold current pics MV bank. * |
| * Since this is only a structure allocation and not actual buffer * |
| * allocation, it is allocated for BUF_MGR_MAX_CNT entries * |
| ************************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK]; |
| { |
| /* max luma samples */ |
| WORD32 max_luma_samples = 0; |
| |
| /* determine max luma samples */ |
| for (i = 0; i < 16; i++) |
| if (level ==(WORD32)gas_ih264_lvl_tbl[i].u4_level_idc) |
| max_luma_samples = gas_ih264_lvl_tbl[i].u4_max_fs |
| << (BLK_SIZE + BLK_SIZE); |
| |
| ps_mem_rec->u4_mem_size = ih264_buf_mgr_size(); |
| |
| /************************************************************************ |
| * Allocate for pu_map, enc_pu_t and pic_pu_idx for each MV bank * |
| * Note: Number of luma samples is not max_wd * max_ht here, instead it * |
| * is set to maximum number of luma samples allowed at the given level. * |
| * This is done to ensure that any stream with width and height lesser * |
| * than max_wd and max_ht is supported. Number of buffers required can * |
| * be greater for lower width and heights at a given level and this * |
| * increased number of buffers might require more memory than what * |
| * max_wd and max_ht buffer would have required Also note one extra * |
| * buffer is allocated to store current pictures MV bank. * |
| ***********************************************************************/ |
| |
| ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(mv_buf_t); |
| |
| ps_mem_rec->u4_mem_size += (num_ref_frames + num_reorder_frames |
| + MAX_CTXT_SETS) |
| * ih264e_get_pic_mv_bank_size(max_luma_samples); |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBANK, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * While encoding inter slices, to compute the cost of encoding an mb * |
| * with the mv's at hand, we employ the expression cost = sad + lambda * |
| * x mv_bits. Here mv_bits is the total number of bits taken to represe* |
| * nt the mv in the stream. The mv bits for all the possible mv are * |
| * stored in the look up table. The mem record for this look up table * |
| * is given below. * |
| ************************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBITS]; |
| { |
| /* max srch range x */ |
| UWORD32 u4_srch_range_x = ps_ip->s_ive_ip.u4_max_srch_rng_x; |
| |
| /* max srch range y */ |
| UWORD32 u4_srch_range_y = ps_ip->s_ive_ip.u4_max_srch_rng_y; |
| |
| /* max srch range */ |
| UWORD32 u4_max_srch_range = MAX(u4_srch_range_x, u4_srch_range_y); |
| |
| /* due to subpel */ |
| u4_max_srch_range <<= 2; |
| |
| /* due to mv on either direction */ |
| u4_max_srch_range = (u4_max_srch_range << 1); |
| |
| /* due to pred mv + zero */ |
| u4_max_srch_range = (u4_max_srch_range << 1) + 1; |
| |
| u4_max_srch_range = ALIGN128(u4_max_srch_range); |
| |
| ps_mem_rec->u4_mem_size = u4_max_srch_range; |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBITS, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory for SPS * |
| ***********************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS]; |
| { |
| ps_mem_rec->u4_mem_size = MAX_SPS_CNT * sizeof(sps_t); |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SPS, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory for PPS * |
| ***********************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS]; |
| { |
| ps_mem_rec->u4_mem_size = MAX_PPS_CNT * sizeof(pps_t); |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PPS, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory for Slice Header * |
| ***********************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR]; |
| { |
| ps_mem_rec->u4_mem_size = MAX_CTXT_SETS * MAX_SLICE_HDR_CNT |
| * sizeof(slice_header_t); |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_HDR, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory for Adaptive Intra Refresh * |
| ***********************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_AIR_MAP]; |
| { |
| /* total size of the mem record */ |
| WORD32 total_size = 0; |
| |
| /* intra coded map */ |
| total_size += max_mb_cnt; |
| total_size *= MAX_CTXT_SETS; |
| |
| /* mb refresh map */ |
| total_size += sizeof(UWORD16) * max_mb_cnt; |
| |
| /* alignment */ |
| total_size = ALIGN128(total_size); |
| |
| ps_mem_rec->u4_mem_size = total_size; |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_AIR_MAP, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * In multi slice encoding, this memory record helps tracking the start* |
| * of slice with reference to mb. * |
| * MEM RECORD for holding * |
| * 1. mb slice map * |
| ************************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_MAP]; |
| { |
| /* total size of the mem record */ |
| WORD32 total_size = 0; |
| |
| /* size in bytes to slice index of all mbs of a frame */ |
| total_size = ALIGN64(max_mb_cnt); |
| |
| /* ih264e_update_proc_ctxt can overread by 1 at the end */ |
| total_size += 1; |
| |
| /* total size per each proc ctxt */ |
| total_size *= MAX_CTXT_SETS; |
| ps_mem_rec->u4_mem_size = total_size; |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_MAP, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory to hold thread handles for each processing thread * |
| ************************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE]; |
| { |
| WORD32 handle_size = ithread_get_handle_size(); |
| |
| ps_mem_rec->u4_mem_size = MAX_PROCESS_THREADS * handle_size; |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_THREAD_HANDLE, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory to hold mutex for control calls * |
| ************************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_CTL_MUTEX]; |
| { |
| ps_mem_rec->u4_mem_size = ithread_get_mutex_lock_size(); |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CTL_MUTEX, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory to hold mutex for entropy calls * |
| ************************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_MUTEX]; |
| { |
| ps_mem_rec->u4_mem_size = ithread_get_mutex_lock_size(); |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTROPY_MUTEX, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory to hold process jobs * |
| ***********************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ]; |
| { |
| /* One process job per row of MBs */ |
| /* Allocate for two pictures, so that wrap around can be handled easily */ |
| WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS; |
| |
| WORD32 job_queue_size = ih264_list_size(num_jobs, sizeof(job_t)); |
| |
| ps_mem_rec->u4_mem_size = job_queue_size; |
| } |
| DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_JOBQ, ps_mem_rec->u4_mem_size); |
| |
| /************************************************************************ |
| * Request memory to hold entropy jobs * |
| ***********************************************************************/ |
| ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_JOBQ]; |
| { |
| /* One process job per row of MBs */ |
| /* Allocate for two pictures, so that wrap around can be handled easily */ |
| WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS; |
| |
|