| /****************************************************************************** | |
| * | |
| * 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 Name : ih264d_api.c */ | |
| /* */ | |
| /* Description : Has all API related functions */ | |
| /* */ | |
| /* */ | |
| /* List of Functions : api_check_struct_sanity */ | |
| /* ih264d_set_processor */ | |
| /* ih264d_create */ | |
| /* ih264d_delete */ | |
| /* ih264d_init */ | |
| /* ih264d_map_error */ | |
| /* ih264d_video_decode */ | |
| /* ih264d_get_version */ | |
| /* ih264d_get_display_frame */ | |
| /* ih264d_set_display_frame */ | |
| /* ih264d_set_flush_mode */ | |
| /* ih264d_get_status */ | |
| /* ih264d_get_buf_info */ | |
| /* ih264d_set_params */ | |
| /* ih264d_set_default_params */ | |
| /* ih264d_reset */ | |
| /* ih264d_ctl */ | |
| /* ih264d_rel_display_frame */ | |
| /* ih264d_set_degrade */ | |
| /* ih264d_get_frame_dimensions */ | |
| /* ih264d_set_num_cores */ | |
| /* ih264d_fill_output_struct_from_context */ | |
| /* ih264d_api_function */ | |
| /* */ | |
| /* Issues / Problems : None */ | |
| /* */ | |
| /* Revision History : */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 14 10 2008 100356(SKV) Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| #include "ih264_typedefs.h" | |
| #include "ih264_macros.h" | |
| #include "ih264_platform_macros.h" | |
| #include "ih264d_tables.h" | |
| #include "iv.h" | |
| #include "ivd.h" | |
| #include "ih264d.h" | |
| #include "ih264d_defs.h" | |
| #include <string.h> | |
| #include <limits.h> | |
| #include <stddef.h> | |
| #include "ih264d_inter_pred.h" | |
| #include "ih264d_structs.h" | |
| #include "ih264d_nal.h" | |
| #include "ih264d_error_handler.h" | |
| #include "ih264d_defs.h" | |
| #include "ithread.h" | |
| #include "ih264d_parse_slice.h" | |
| #include "ih264d_function_selector.h" | |
| #include "ih264_error.h" | |
| #include "ih264_disp_mgr.h" | |
| #include "ih264_buf_mgr.h" | |
| #include "ih264d_deblocking.h" | |
| #include "ih264d_parse_cavlc.h" | |
| #include "ih264d_parse_cabac.h" | |
| #include "ih264d_utils.h" | |
| #include "ih264d_format_conv.h" | |
| #include "ih264d_parse_headers.h" | |
| #include "ih264d_thread_compute_bs.h" | |
| #include <assert.h> | |
| /*********************/ | |
| /* Codec Versioning */ | |
| /*********************/ | |
| //Move this to where it is used | |
| #define CODEC_NAME "H264VDEC" | |
| #define CODEC_RELEASE_TYPE "production" | |
| #define CODEC_RELEASE_VER "05.00" | |
| #define CODEC_VENDOR "ITTIAM" | |
| #define MAXVERSION_STRLEN 511 | |
| #ifdef ANDROID | |
| #define VERSION(version_string, codec_name, codec_release_type, codec_release_ver, codec_vendor) \ | |
| snprintf(version_string, MAXVERSION_STRLEN, \ | |
| "@(#)Id:%s_%s Ver:%s Released by %s", \ | |
| codec_name, codec_release_type, codec_release_ver, codec_vendor) | |
| #else | |
| #define VERSION(version_string, codec_name, codec_release_type, codec_release_ver, codec_vendor) \ | |
| snprintf(version_string, MAXVERSION_STRLEN, \ | |
| "@(#)Id:%s_%s Ver:%s Released by %s Build: %s @ %s", \ | |
| codec_name, codec_release_type, codec_release_ver, codec_vendor, __DATE__, __TIME__) | |
| #endif | |
| #define MIN_IN_BUFS 1 | |
| #define MIN_OUT_BUFS_420 3 | |
| #define MIN_OUT_BUFS_422ILE 1 | |
| #define MIN_OUT_BUFS_RGB565 1 | |
| #define MIN_OUT_BUFS_420SP 2 | |
| #define NUM_FRAMES_LIMIT_ENABLED 0 | |
| #if NUM_FRAMES_LIMIT_ENABLED | |
| #define NUM_FRAMES_LIMIT 10000 | |
| #else | |
| #define NUM_FRAMES_LIMIT 0x7FFFFFFF | |
| #endif | |
| UWORD32 ih264d_get_extra_mem_external(UWORD32 width, UWORD32 height); | |
| WORD32 ih264d_get_frame_dimensions(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op); | |
| WORD32 ih264d_get_vui_params(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op); | |
| WORD32 ih264d_get_sei_mdcv_params(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op); | |
| WORD32 ih264d_get_sei_cll_params(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op); | |
| WORD32 ih264d_get_sei_ave_params(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op); | |
| WORD32 ih264d_get_sei_ccv_params(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op); | |
| WORD32 ih264d_get_sei_sii_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op); | |
| WORD32 ih264d_get_sei_fgc_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op); | |
| WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op); | |
| WORD32 ih264d_deblock_display(dec_struct_t *ps_dec); | |
| void ih264d_signal_decode_thread(dec_struct_t *ps_dec); | |
| void ih264d_signal_bs_deblk_thread(dec_struct_t *ps_dec); | |
| void ih264d_decode_picture_thread(dec_struct_t *ps_dec); | |
| WORD32 ih264d_set_degrade(iv_obj_t *ps_codec_obj, | |
| void *pv_api_ip, | |
| void *pv_api_op); | |
| void ih264d_fill_output_struct_from_context(dec_struct_t *ps_dec, | |
| ivd_video_decode_op_t *ps_dec_op); | |
| /*! | |
| ************************************************************************** | |
| * \if Function name : ih264d_export_sei_params \endif | |
| * | |
| * \brief | |
| * Exports sei params from decoder to application. | |
| * | |
| * \return | |
| * 0 on Success and error code otherwise | |
| ************************************************************************** | |
| */ | |
| void ih264d_export_sei_params(ivd_sei_decode_op_t *ps_sei_decode_op, dec_struct_t *ps_dec) | |
| { | |
| WORD32 i4_status = IV_SUCCESS; | |
| sei *ps_sei = (sei *)ps_dec->pv_disp_sei_params; | |
| i4_status = ih264d_export_sei_mdcv_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export); | |
| i4_status = ih264d_export_sei_cll_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export); | |
| i4_status = ih264d_export_sei_ave_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export); | |
| i4_status = ih264d_export_sei_ccv_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export); | |
| i4_status = ih264d_export_sei_sii_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export); | |
| i4_status = ih264d_export_sei_fgc_params(ps_sei_decode_op, ps_sei, &ps_dec->s_sei_export); | |
| UNUSED(i4_status); | |
| } | |
| static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| IVD_API_COMMAND_TYPE_T e_cmd; | |
| UWORD32 *pu4_api_ip; | |
| UWORD32 *pu4_api_op; | |
| UWORD32 i, j; | |
| if(NULL == pv_api_op) | |
| return (IV_FAIL); | |
| if(NULL == pv_api_ip) | |
| return (IV_FAIL); | |
| pu4_api_ip = (UWORD32 *)pv_api_ip; | |
| pu4_api_op = (UWORD32 *)pv_api_op; | |
| e_cmd = *(pu4_api_ip + 1); | |
| /* error checks on handle */ | |
| switch((WORD32)e_cmd) | |
| { | |
| case IVD_CMD_CREATE: | |
| break; | |
| case IVD_CMD_REL_DISPLAY_FRAME: | |
| case IVD_CMD_SET_DISPLAY_FRAME: | |
| case IVD_CMD_GET_DISPLAY_FRAME: | |
| case IVD_CMD_VIDEO_DECODE: | |
| case IVD_CMD_DELETE: | |
| case IVD_CMD_VIDEO_CTL: | |
| if(ps_handle == NULL) | |
| { | |
| *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; | |
| *(pu4_api_op + 1) |= IVD_HANDLE_NULL; | |
| return IV_FAIL; | |
| } | |
| if(ps_handle->u4_size != sizeof(iv_obj_t)) | |
| { | |
| *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; | |
| *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_handle->pv_fxns != ih264d_api_function) | |
| { | |
| *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; | |
| *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL; | |
| return IV_FAIL; | |
| } | |
| if(ps_handle->pv_codec_handle == NULL) | |
| { | |
| *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; | |
| *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL; | |
| return IV_FAIL; | |
| } | |
| break; | |
| default: | |
| *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; | |
| *(pu4_api_op + 1) |= IVD_INVALID_API_CMD; | |
| return IV_FAIL; | |
| } | |
| switch((WORD32)e_cmd) | |
| { | |
| case IVD_CMD_CREATE: | |
| { | |
| ih264d_create_ip_t *ps_ip = (ih264d_create_ip_t *)pv_api_ip; | |
| ih264d_create_op_t *ps_op = (ih264d_create_op_t *)pv_api_op; | |
| ps_op->s_ivd_create_op_t.u4_error_code = 0; | |
| if((ps_ip->s_ivd_create_ip_t.u4_size > sizeof(ih264d_create_ip_t)) | |
| || (ps_ip->s_ivd_create_ip_t.u4_size | |
| < sizeof(ivd_create_ip_t))) | |
| { | |
| ps_op->s_ivd_create_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_create_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| H264_DEC_DEBUG_PRINT("\n"); | |
| return (IV_FAIL); | |
| } | |
| if((ps_op->s_ivd_create_op_t.u4_size != sizeof(ih264d_create_op_t)) | |
| && (ps_op->s_ivd_create_op_t.u4_size | |
| != sizeof(ivd_create_op_t))) | |
| { | |
| ps_op->s_ivd_create_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_create_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| H264_DEC_DEBUG_PRINT("\n"); | |
| return (IV_FAIL); | |
| } | |
| if((ps_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420P) | |
| && (ps_ip->s_ivd_create_ip_t.e_output_format | |
| != IV_YUV_422ILE) | |
| && (ps_ip->s_ivd_create_ip_t.e_output_format | |
| != IV_RGB_565) | |
| && (ps_ip->s_ivd_create_ip_t.e_output_format | |
| != IV_YUV_420SP_UV) | |
| && (ps_ip->s_ivd_create_ip_t.e_output_format | |
| != IV_YUV_420SP_VU)) | |
| { | |
| ps_op->s_ivd_create_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_create_op_t.u4_error_code |= | |
| IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED; | |
| H264_DEC_DEBUG_PRINT("\n"); | |
| return (IV_FAIL); | |
| } | |
| } | |
| break; | |
| case IVD_CMD_GET_DISPLAY_FRAME: | |
| { | |
| ih264d_get_display_frame_ip_t *ps_ip = | |
| (ih264d_get_display_frame_ip_t *)pv_api_ip; | |
| ih264d_get_display_frame_op_t *ps_op = | |
| (ih264d_get_display_frame_op_t *)pv_api_op; | |
| ps_op->s_ivd_get_display_frame_op_t.u4_error_code = 0; | |
| if((ps_ip->s_ivd_get_display_frame_ip_t.u4_size | |
| != sizeof(ih264d_get_display_frame_ip_t)) | |
| && (ps_ip->s_ivd_get_display_frame_ip_t.u4_size | |
| != sizeof(ivd_get_display_frame_ip_t))) | |
| { | |
| ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return (IV_FAIL); | |
| } | |
| if((ps_op->s_ivd_get_display_frame_op_t.u4_size | |
| != sizeof(ih264d_get_display_frame_op_t)) | |
| && (ps_op->s_ivd_get_display_frame_op_t.u4_size | |
| != sizeof(ivd_get_display_frame_op_t))) | |
| { | |
| ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return (IV_FAIL); | |
| } | |
| } | |
| break; | |
| case IVD_CMD_REL_DISPLAY_FRAME: | |
| { | |
| ih264d_rel_display_frame_ip_t *ps_ip = | |
| (ih264d_rel_display_frame_ip_t *)pv_api_ip; | |
| ih264d_rel_display_frame_op_t *ps_op = | |
| (ih264d_rel_display_frame_op_t *)pv_api_op; | |
| ps_op->s_ivd_rel_display_frame_op_t.u4_error_code = 0; | |
| if((ps_ip->s_ivd_rel_display_frame_ip_t.u4_size | |
| != sizeof(ih264d_rel_display_frame_ip_t)) | |
| && (ps_ip->s_ivd_rel_display_frame_ip_t.u4_size | |
| != sizeof(ivd_rel_display_frame_ip_t))) | |
| { | |
| ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return (IV_FAIL); | |
| } | |
| if((ps_op->s_ivd_rel_display_frame_op_t.u4_size | |
| != sizeof(ih264d_rel_display_frame_op_t)) | |
| && (ps_op->s_ivd_rel_display_frame_op_t.u4_size | |
| != sizeof(ivd_rel_display_frame_op_t))) | |
| { | |
| ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return (IV_FAIL); | |
| } | |
| } | |
| break; | |
| case IVD_CMD_SET_DISPLAY_FRAME: | |
| { | |
| ih264d_set_display_frame_ip_t *ps_ip = | |
| (ih264d_set_display_frame_ip_t *)pv_api_ip; | |
| ih264d_set_display_frame_op_t *ps_op = | |
| (ih264d_set_display_frame_op_t *)pv_api_op; | |
| UWORD32 j; | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code = 0; | |
| if((ps_ip->s_ivd_set_display_frame_ip_t.u4_size | |
| != sizeof(ih264d_set_display_frame_ip_t)) | |
| && (ps_ip->s_ivd_set_display_frame_ip_t.u4_size | |
| != sizeof(ivd_set_display_frame_ip_t))) | |
| { | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return (IV_FAIL); | |
| } | |
| if((ps_op->s_ivd_set_display_frame_op_t.u4_size | |
| != sizeof(ih264d_set_display_frame_op_t)) | |
| && (ps_op->s_ivd_set_display_frame_op_t.u4_size | |
| != sizeof(ivd_set_display_frame_op_t))) | |
| { | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return (IV_FAIL); | |
| } | |
| if(ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs == 0) | |
| { | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= | |
| IVD_DISP_FRM_ZERO_OP_BUFS; | |
| return IV_FAIL; | |
| } | |
| for(j = 0; j < ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs; | |
| j++) | |
| { | |
| if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs | |
| == 0) | |
| { | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= | |
| IVD_DISP_FRM_ZERO_OP_BUFS; | |
| return IV_FAIL; | |
| } | |
| for(i = 0; | |
| i | |
| < ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs; | |
| i++) | |
| { | |
| if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].pu1_bufs[i] | |
| == NULL) | |
| { | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= | |
| IVD_DISP_FRM_OP_BUF_NULL; | |
| return IV_FAIL; | |
| } | |
| if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_min_out_buf_size[i] | |
| == 0) | |
| { | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= | |
| IVD_DISP_FRM_ZERO_OP_BUF_SIZE; | |
| return IV_FAIL; | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case IVD_CMD_VIDEO_DECODE: | |
| { | |
| ih264d_video_decode_ip_t *ps_ip = | |
| (ih264d_video_decode_ip_t *)pv_api_ip; | |
| ih264d_video_decode_op_t *ps_op = | |
| (ih264d_video_decode_op_t *)pv_api_op; | |
| H264_DEC_DEBUG_PRINT("The input bytes is: %d", | |
| ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes); | |
| ps_op->s_ivd_video_decode_op_t.u4_error_code = 0; | |
| if(ps_ip->s_ivd_video_decode_ip_t.u4_size != sizeof(ih264d_video_decode_ip_t) && | |
| ps_ip->s_ivd_video_decode_ip_t.u4_size != sizeof(ivd_video_decode_ip_t) && | |
| ps_ip->s_ivd_video_decode_ip_t.u4_size != | |
| offsetof(ivd_video_decode_ip_t, s_out_buffer)) | |
| { | |
| ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_video_decode_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return (IV_FAIL); | |
| } | |
| if(ps_op->s_ivd_video_decode_op_t.u4_size != sizeof(ih264d_video_decode_op_t) && | |
| ps_op->s_ivd_video_decode_op_t.u4_size != sizeof(ivd_video_decode_op_t) && | |
| ps_op->s_ivd_video_decode_op_t.u4_size != | |
| offsetof(ivd_video_decode_op_t, u4_output_present)) | |
| { | |
| ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_video_decode_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return (IV_FAIL); | |
| } | |
| { | |
| dec_struct_t *ps_dec = (dec_struct_t *)(ps_handle->pv_codec_handle); | |
| if(ps_dec->u1_enable_mb_info) | |
| { | |
| if(!ps_ip->pu1_8x8_blk_qp_map && !ps_ip->pu1_8x8_blk_type_map) | |
| { | |
| ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_video_decode_op_t.u4_error_code |= | |
| IH264D_FRAME_INFO_OP_BUF_NULL; | |
| return IV_FAIL; | |
| } | |
| } | |
| } | |
| } | |
| break; | |
| case IVD_CMD_DELETE: | |
| { | |
| ih264d_delete_ip_t *ps_ip = | |
| (ih264d_delete_ip_t *)pv_api_ip; | |
| ih264d_delete_op_t *ps_op = | |
| (ih264d_delete_op_t *)pv_api_op; | |
| ps_op->s_ivd_delete_op_t.u4_error_code = 0; | |
| if(ps_ip->s_ivd_delete_ip_t.u4_size | |
| != sizeof(ih264d_delete_ip_t)) | |
| { | |
| ps_op->s_ivd_delete_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_delete_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return (IV_FAIL); | |
| } | |
| if(ps_op->s_ivd_delete_op_t.u4_size | |
| != sizeof(ih264d_delete_op_t)) | |
| { | |
| ps_op->s_ivd_delete_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_delete_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return (IV_FAIL); | |
| } | |
| } | |
| break; | |
| case IVD_CMD_VIDEO_CTL: | |
| { | |
| UWORD32 *pu4_ptr_cmd; | |
| UWORD32 sub_command; | |
| pu4_ptr_cmd = (UWORD32 *)pv_api_ip; | |
| pu4_ptr_cmd += 2; | |
| sub_command = *pu4_ptr_cmd; | |
| switch(sub_command) | |
| { | |
| case IVD_CMD_CTL_SETPARAMS: | |
| { | |
| ih264d_ctl_set_config_ip_t *ps_ip; | |
| ih264d_ctl_set_config_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_set_config_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_set_config_op_t *)pv_api_op; | |
| if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size | |
| != sizeof(ih264d_ctl_set_config_ip_t)) | |
| { | |
| ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| } | |
| //no break; is needed here | |
| case IVD_CMD_CTL_SETDEFAULT: | |
| { | |
| ih264d_ctl_set_config_op_t *ps_op; | |
| ps_op = (ih264d_ctl_set_config_op_t *)pv_api_op; | |
| if(ps_op->s_ivd_ctl_set_config_op_t.u4_size | |
| != sizeof(ih264d_ctl_set_config_op_t)) | |
| { | |
| ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| } | |
| break; | |
| case IVD_CMD_CTL_GETPARAMS: | |
| { | |
| ih264d_ctl_getstatus_ip_t *ps_ip; | |
| ih264d_ctl_getstatus_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_getstatus_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_getstatus_op_t *)pv_api_op; | |
| if(ps_ip->s_ivd_ctl_getstatus_ip_t.u4_size | |
| != sizeof(ih264d_ctl_getstatus_ip_t)) | |
| { | |
| ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->s_ivd_ctl_getstatus_op_t.u4_size | |
| != sizeof(ih264d_ctl_getstatus_op_t)) | |
| { | |
| ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| } | |
| break; | |
| case IVD_CMD_CTL_GETBUFINFO: | |
| { | |
| ih264d_ctl_getbufinfo_ip_t *ps_ip; | |
| ih264d_ctl_getbufinfo_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_getbufinfo_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_getbufinfo_op_t *)pv_api_op; | |
| if(ps_ip->s_ivd_ctl_getbufinfo_ip_t.u4_size | |
| != sizeof(ih264d_ctl_getbufinfo_ip_t)) | |
| { | |
| ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->s_ivd_ctl_getbufinfo_op_t.u4_size | |
| != sizeof(ih264d_ctl_getbufinfo_op_t)) | |
| { | |
| ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| } | |
| break; | |
| case IVD_CMD_CTL_GETVERSION: | |
| { | |
| ih264d_ctl_getversioninfo_ip_t *ps_ip; | |
| ih264d_ctl_getversioninfo_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_getversioninfo_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_getversioninfo_op_t *)pv_api_op; | |
| if(ps_ip->s_ivd_ctl_getversioninfo_ip_t.u4_size | |
| != sizeof(ih264d_ctl_getversioninfo_ip_t)) | |
| { | |
| ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->s_ivd_ctl_getversioninfo_op_t.u4_size | |
| != sizeof(ih264d_ctl_getversioninfo_op_t)) | |
| { | |
| ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| } | |
| break; | |
| case IVD_CMD_CTL_FLUSH: | |
| { | |
| ih264d_ctl_flush_ip_t *ps_ip; | |
| ih264d_ctl_flush_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_flush_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_flush_op_t *)pv_api_op; | |
| if(ps_ip->s_ivd_ctl_flush_ip_t.u4_size | |
| != sizeof(ih264d_ctl_flush_ip_t)) | |
| { | |
| ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->s_ivd_ctl_flush_op_t.u4_size | |
| != sizeof(ih264d_ctl_flush_op_t)) | |
| { | |
| ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| } | |
| break; | |
| case IVD_CMD_CTL_RESET: | |
| { | |
| ih264d_ctl_reset_ip_t *ps_ip; | |
| ih264d_ctl_reset_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_reset_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_reset_op_t *)pv_api_op; | |
| if(ps_ip->s_ivd_ctl_reset_ip_t.u4_size | |
| != sizeof(ih264d_ctl_reset_ip_t)) | |
| { | |
| ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->s_ivd_ctl_reset_op_t.u4_size | |
| != sizeof(ih264d_ctl_reset_op_t)) | |
| { | |
| ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1 | |
| << IVD_UNSUPPORTEDPARAM; | |
| ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| } | |
| break; | |
| case IH264D_CMD_CTL_DEGRADE: | |
| { | |
| ih264d_ctl_degrade_ip_t *ps_ip; | |
| ih264d_ctl_degrade_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_degrade_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_degrade_op_t *)pv_api_op; | |
| if(ps_ip->u4_size != sizeof(ih264d_ctl_degrade_ip_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->u4_size != sizeof(ih264d_ctl_degrade_op_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if((ps_ip->i4_degrade_pics < 0) | |
| || (ps_ip->i4_degrade_pics > 4) | |
| || (ps_ip->i4_nondegrade_interval < 0) | |
| || (ps_ip->i4_degrade_type < 0) | |
| || (ps_ip->i4_degrade_type > 15)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| return IV_FAIL; | |
| } | |
| break; | |
| } | |
| case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS: | |
| { | |
| ih264d_ctl_get_frame_dimensions_ip_t *ps_ip; | |
| ih264d_ctl_get_frame_dimensions_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_get_frame_dimensions_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_get_frame_dimensions_op_t *)pv_api_op; | |
| if(ps_ip->u4_size | |
| != sizeof(ih264d_ctl_get_frame_dimensions_ip_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->u4_size | |
| != sizeof(ih264d_ctl_get_frame_dimensions_op_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| break; | |
| } | |
| case IH264D_CMD_CTL_GET_VUI_PARAMS: | |
| { | |
| ih264d_ctl_get_vui_params_ip_t *ps_ip; | |
| ih264d_ctl_get_vui_params_op_t *ps_op; | |
| ps_ip = | |
| (ih264d_ctl_get_vui_params_ip_t *)pv_api_ip; | |
| ps_op = | |
| (ih264d_ctl_get_vui_params_op_t *)pv_api_op; | |
| if(ps_ip->u4_size | |
| != sizeof(ih264d_ctl_get_vui_params_ip_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->u4_size | |
| != sizeof(ih264d_ctl_get_vui_params_op_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| break; | |
| } | |
| case IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS: | |
| { | |
| ih264d_ctl_get_sei_mdcv_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_mdcv_params_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_get_sei_mdcv_params_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_mdcv_params_op_t *)pv_api_op; | |
| if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_mdcv_params_ip_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_mdcv_params_op_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| break; | |
| } | |
| case IH264D_CMD_CTL_GET_SEI_CLL_PARAMS: | |
| { | |
| ih264d_ctl_get_sei_cll_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_cll_params_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_get_sei_cll_params_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_cll_params_op_t *)pv_api_op; | |
| if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_cll_params_ip_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_cll_params_op_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| break; | |
| } | |
| case IH264D_CMD_CTL_GET_SEI_AVE_PARAMS: | |
| { | |
| ih264d_ctl_get_sei_ave_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_ave_params_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_get_sei_ave_params_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_ave_params_op_t *)pv_api_op; | |
| if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_ave_params_ip_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_ave_params_op_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| break; | |
| } | |
| case IH264D_CMD_CTL_GET_SEI_CCV_PARAMS: | |
| { | |
| ih264d_ctl_get_sei_ccv_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_ccv_params_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_get_sei_ccv_params_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_ccv_params_op_t *)pv_api_op; | |
| if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_ccv_params_ip_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_ccv_params_op_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| break; | |
| } | |
| case IH264D_CMD_CTL_GET_SEI_SII_PARAMS: | |
| { | |
| ih264d_ctl_get_sei_sii_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_sii_params_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_get_sei_sii_params_ip_t *) pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_sii_params_op_t *) pv_api_op; | |
| if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_sii_params_ip_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_sii_params_op_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| break; | |
| } | |
| case IH264D_CMD_CTL_GET_SEI_FGC_PARAMS: | |
| { | |
| ih264d_ctl_get_sei_fgc_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_fgc_params_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_get_sei_fgc_params_ip_t *) pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_fgc_params_op_t *) pv_api_op; | |
| if(ps_ip->u4_size != sizeof(ih264d_ctl_get_sei_fgc_params_ip_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->u4_size != sizeof(ih264d_ctl_get_sei_fgc_params_op_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| break; | |
| } | |
| case IH264D_CMD_CTL_SET_NUM_CORES: | |
| { | |
| ih264d_ctl_set_num_cores_ip_t *ps_ip; | |
| ih264d_ctl_set_num_cores_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_set_num_cores_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_set_num_cores_op_t *)pv_api_op; | |
| if(ps_ip->u4_size != sizeof(ih264d_ctl_set_num_cores_ip_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->u4_size != sizeof(ih264d_ctl_set_num_cores_op_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if((ps_ip->u4_num_cores != 1) && (ps_ip->u4_num_cores != 2) | |
| && (ps_ip->u4_num_cores != 3) | |
| && (ps_ip->u4_num_cores != 4)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| return IV_FAIL; | |
| } | |
| break; | |
| } | |
| case IH264D_CMD_CTL_SET_PROCESSOR: | |
| { | |
| ih264d_ctl_set_processor_ip_t *ps_ip; | |
| ih264d_ctl_set_processor_op_t *ps_op; | |
| ps_ip = (ih264d_ctl_set_processor_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_set_processor_op_t *)pv_api_op; | |
| if(ps_ip->u4_size != sizeof(ih264d_ctl_set_processor_ip_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| if(ps_op->u4_size != sizeof(ih264d_ctl_set_processor_op_t)) | |
| { | |
| ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_op->u4_error_code |= | |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; | |
| return IV_FAIL; | |
| } | |
| break; | |
| } | |
| default: | |
| *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; | |
| *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD; | |
| return IV_FAIL; | |
| break; | |
| } | |
| } | |
| break; | |
| } | |
| return IV_SUCCESS; | |
| } | |
| /** | |
| ******************************************************************************* | |
| * | |
| * @brief | |
| * Sets Processor type | |
| * | |
| * @par Description: | |
| * Sets Processor type | |
| * | |
| * @param[in] ps_codec_obj | |
| * Pointer to codec object at API level | |
| * | |
| * @param[in] pv_api_ip | |
| * Pointer to input argument structure | |
| * | |
| * @param[out] pv_api_op | |
| * Pointer to output argument structure | |
| * | |
| * @returns Status | |
| * | |
| * @remarks | |
| * | |
| * | |
| ******************************************************************************* | |
| */ | |
| WORD32 ih264d_set_processor(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| ih264d_ctl_set_processor_ip_t *ps_ip; | |
| ih264d_ctl_set_processor_op_t *ps_op; | |
| dec_struct_t *ps_codec = (dec_struct_t *)dec_hdl->pv_codec_handle; | |
| ps_ip = (ih264d_ctl_set_processor_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_set_processor_op_t *)pv_api_op; | |
| ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch; | |
| ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc; | |
| ih264d_init_function_ptr(ps_codec); | |
| ps_op->u4_error_code = 0; | |
| return IV_SUCCESS; | |
| } | |
| /************************************************************************** | |
| * \if Function name : ih264d_init_decoder \endif | |
| * | |
| * | |
| * \brief | |
| * Initializes the decoder | |
| * | |
| * \param apiVersion : Version of the api being used. | |
| * \param errorHandlingMechanism : Mechanism to be used for errror handling. | |
| * \param postFilteringType: Type of post filtering operation to be used. | |
| * \param uc_outputFormat: Format of the decoded picture [default 4:2:0]. | |
| * \param uc_dispBufs: Number of Display Buffers. | |
| * \param p_NALBufAPI: Pointer to NAL Buffer API. | |
| * \param p_DispBufAPI: Pointer to Display Buffer API. | |
| * \param ih264d_dec_mem_manager :Pointer to the function that will be called by decoder | |
| * for memory allocation and freeing. | |
| * | |
| * \return | |
| * 0 on Success and -1 on error | |
| * | |
| ************************************************************************** | |
| */ | |
| void ih264d_init_decoder(void * ps_dec_params) | |
| { | |
| dec_struct_t * ps_dec = (dec_struct_t *)ps_dec_params; | |
| dec_slice_params_t *ps_cur_slice; | |
| pocstruct_t *ps_prev_poc, *ps_cur_poc; | |
| WORD32 size; | |
| size = sizeof(pred_info_t) * 2 * 32; | |
| memset(ps_dec->ps_pred, 0 , size); | |
| size = sizeof(disp_mgr_t); | |
| memset(ps_dec->pv_disp_buf_mgr, 0 , size); | |
| size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size(); | |
| memset(ps_dec->pv_pic_buf_mgr, 0, size); | |
| size = sizeof(dec_err_status_t); | |
| memset(ps_dec->ps_dec_err_status, 0, size); | |
| size = sizeof(sei); | |
| memset(ps_dec->ps_sei, 0, size); | |
| size = sizeof(sei); | |
| memset(ps_dec->ps_sei_parse, 0, size); | |
| size = sizeof(dpb_commands_t); | |
| memset(ps_dec->ps_dpb_cmds, 0, size); | |
| size = sizeof(dec_bit_stream_t); | |
| memset(ps_dec->ps_bitstrm, 0, size); | |
| size = sizeof(dec_slice_params_t); | |
| memset(ps_dec->ps_cur_slice, 0, size); | |
| size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t)); | |
| memset(ps_dec->pv_scratch_sps_pps, 0, size); | |
| size = sizeof(ctxt_inc_mb_info_t); | |
| memset(ps_dec->ps_left_mb_ctxt_info, 0, size); | |
| size = (sizeof(neighbouradd_t) << 2); | |
| memset(ps_dec->ps_left_mvpred_addr, 0 ,size); | |
| size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size(); | |
| memset(ps_dec->pv_mv_buf_mgr, 0, size); | |
| /* Free any dynamic buffers that are allocated */ | |
| ih264d_free_dynamic_bufs(ps_dec); | |
| { | |
| UWORD8 i; | |
| struct pic_buffer_t *ps_init_dpb; | |
| ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[0][0]; | |
| for(i = 0; i < 2 * MAX_REF_BUFS; i++) | |
| { | |
| ps_init_dpb->pu1_buf1 = NULL; | |
| ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1; | |
| ps_dec->ps_dpb_mgr->ps_init_dpb[0][i] = ps_init_dpb; | |
| ps_dec->ps_dpb_mgr->ps_mod_dpb[0][i] = ps_init_dpb; | |
| ps_init_dpb++; | |
| } | |
| ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[1][0]; | |
| for(i = 0; i < 2 * MAX_REF_BUFS; i++) | |
| { | |
| ps_init_dpb->pu1_buf1 = NULL; | |
| ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1; | |
| ps_dec->ps_dpb_mgr->ps_init_dpb[1][i] = ps_init_dpb; | |
| ps_dec->ps_dpb_mgr->ps_mod_dpb[1][i] = ps_init_dpb; | |
| ps_init_dpb++; | |
| } | |
| } | |
| ps_cur_slice = ps_dec->ps_cur_slice; | |
| ps_dec->init_done = 0; | |
| ps_dec->u4_num_cores = 1; | |
| ps_dec->u2_pic_ht = ps_dec->u2_pic_wd = 0; | |
| ps_dec->u1_separate_parse = DEFAULT_SEPARATE_PARSE; | |
| ps_dec->u4_app_disable_deblk_frm = 0; | |
| ps_dec->i4_degrade_type = 0; | |
| ps_dec->i4_degrade_pics = 0; | |
| memset(ps_dec->ps_pps, 0, | |
| ((sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS)); | |
| memset(ps_dec->ps_sps, 0, | |
| ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS)); | |
| /* Initialization of function pointers ih264d_deblock_picture function*/ | |
| ps_dec->p_DeblockPicture[0] = ih264d_deblock_picture_non_mbaff; | |
| ps_dec->p_DeblockPicture[1] = ih264d_deblock_picture_mbaff; | |
| ps_dec->s_cab_dec_env.pv_codec_handle = ps_dec; | |
| ps_dec->u4_num_fld_in_frm = 0; | |
| ps_dec->ps_dpb_mgr->pv_codec_handle = ps_dec; | |
| /* Initialize the sei validity u4_flag with zero indiacting sei is not valid*/ | |
| ps_dec->ps_sei->u1_is_valid = 0; | |
| /* decParams Initializations */ | |
| ps_dec->ps_cur_pps = NULL; | |
| ps_dec->ps_cur_sps = NULL; | |
| ps_dec->u1_init_dec_flag = 0; | |
| ps_dec->u1_first_slice_in_stream = 1; | |
| ps_dec->u1_last_pic_not_decoded = 0; | |
| ps_dec->u4_app_disp_width = 0; | |
| ps_dec->i4_header_decoded = 0; | |
| ps_dec->u4_total_frames_decoded = 0; | |
| ps_dec->i4_error_code = 0; | |
| ps_dec->i4_content_type = IV_CONTENTTYPE_NA; | |
| ps_dec->ps_cur_slice->u1_mbaff_frame_flag = 0; | |
| ps_dec->ps_dec_err_status->u1_err_flag = ACCEPT_ALL_PICS; //REJECT_PB_PICS; | |
| ps_dec->ps_dec_err_status->u1_cur_pic_type = PIC_TYPE_UNKNOWN; | |
| ps_dec->ps_dec_err_status->u4_frm_sei_sync = SYNC_FRM_DEFAULT; | |
| ps_dec->ps_dec_err_status->u4_cur_frm = INIT_FRAME; | |
| ps_dec->ps_dec_err_status->u1_pic_aud_i = PIC_TYPE_UNKNOWN; | |
| ps_dec->u1_pr_sl_type = 0xFF; | |
| ps_dec->u2_mbx = 0xffff; | |
| ps_dec->u2_mby = 0; | |
| ps_dec->u2_total_mbs_coded = 0; | |
| /* POC initializations */ | |
| ps_prev_poc = &ps_dec->s_prev_pic_poc; | |
| ps_cur_poc = &ps_dec->s_cur_pic_poc; | |
| ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb = 0; | |
| ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb = 0; | |
| ps_prev_poc->i4_delta_pic_order_cnt_bottom = | |
| ps_cur_poc->i4_delta_pic_order_cnt_bottom = 0; | |
| ps_prev_poc->i4_delta_pic_order_cnt[0] = | |
| ps_cur_poc->i4_delta_pic_order_cnt[0] = 0; | |
| ps_prev_poc->i4_delta_pic_order_cnt[1] = | |
| ps_cur_poc->i4_delta_pic_order_cnt[1] = 0; | |
| ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0; | |
| ps_prev_poc->i4_top_field_order_count = ps_cur_poc->i4_top_field_order_count = | |
| 0; | |
| ps_prev_poc->i4_bottom_field_order_count = | |
| ps_cur_poc->i4_bottom_field_order_count = 0; | |
| ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field = 0; | |
| ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0; | |
| ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst = 0; | |
| ps_cur_slice->u1_mmco_equalto5 = 0; | |
| ps_cur_slice->u2_frame_num = 0; | |
| ps_dec->i4_max_poc = 0; | |
| ps_dec->i4_prev_max_display_seq = 0; | |
| ps_dec->u1_recon_mb_grp = 4; | |
| ps_dec->i4_reorder_depth = -1; | |
| /* Field PIC initializations */ | |
| ps_dec->u1_second_field = 0; | |
| ps_dec->s_prev_seq_params.u1_eoseq_pending = 0; | |
| /* Set the cropping parameters as zero */ | |
| ps_dec->u2_crop_offset_y = 0; | |
| ps_dec->u2_crop_offset_uv = 0; | |
| /* The Initial Frame Rate Info is not Present */ | |
| ps_dec->i4_vui_frame_rate = -1; | |
| ps_dec->i4_pic_type = NA_SLICE; | |
| ps_dec->i4_frametype = IV_NA_FRAME; | |
| ps_dec->i4_content_type = IV_CONTENTTYPE_NA; | |
| ps_dec->u1_res_changed = 0; | |
| ps_dec->u1_frame_decoded_flag = 0; | |
| /* Set the default frame seek mask mode */ | |
| ps_dec->u4_skip_frm_mask = SKIP_NONE; | |
| /********************************************************/ | |
| /* Initialize CAVLC residual decoding function pointers */ | |
| /********************************************************/ | |
| ps_dec->pf_cavlc_4x4res_block[0] = ih264d_cavlc_4x4res_block_totalcoeff_1; | |
| ps_dec->pf_cavlc_4x4res_block[1] = | |
| ih264d_cavlc_4x4res_block_totalcoeff_2to10; | |
| ps_dec->pf_cavlc_4x4res_block[2] = | |
| ih264d_cavlc_4x4res_block_totalcoeff_11to16; | |
| ps_dec->pf_cavlc_parse4x4coeff[0] = ih264d_cavlc_parse4x4coeff_n0to7; | |
| ps_dec->pf_cavlc_parse4x4coeff[1] = ih264d_cavlc_parse4x4coeff_n8; | |
| ps_dec->pf_cavlc_parse_8x8block[0] = | |
| ih264d_cavlc_parse_8x8block_none_available; | |
| ps_dec->pf_cavlc_parse_8x8block[1] = | |
| ih264d_cavlc_parse_8x8block_left_available; | |
| ps_dec->pf_cavlc_parse_8x8block[2] = | |
| ih264d_cavlc_parse_8x8block_top_available; | |
| ps_dec->pf_cavlc_parse_8x8block[3] = | |
| ih264d_cavlc_parse_8x8block_both_available; | |
| /***************************************************************************/ | |
| /* Initialize Bs calculation function pointers for P and B, 16x16/non16x16 */ | |
| /***************************************************************************/ | |
| ps_dec->pf_fill_bs1[0][0] = ih264d_fill_bs1_16x16mb_pslice; | |
| ps_dec->pf_fill_bs1[0][1] = ih264d_fill_bs1_non16x16mb_pslice; | |
| ps_dec->pf_fill_bs1[1][0] = ih264d_fill_bs1_16x16mb_bslice; | |
| ps_dec->pf_fill_bs1[1][1] = ih264d_fill_bs1_non16x16mb_bslice; | |
| ps_dec->pf_fill_bs_xtra_left_edge[0] = | |
| ih264d_fill_bs_xtra_left_edge_cur_frm; | |
| ps_dec->pf_fill_bs_xtra_left_edge[1] = | |
| ih264d_fill_bs_xtra_left_edge_cur_fld; | |
| /* Initialize Reference Pic Buffers */ | |
| ih264d_init_ref_bufs(ps_dec->ps_dpb_mgr); | |
| ps_dec->u2_prv_frame_num = 0; | |
| ps_dec->u1_top_bottom_decoded = 0; | |
| ps_dec->u1_dangling_field = 0; | |
| ps_dec->s_cab_dec_env.cabac_table = gau4_ih264d_cabac_table; | |
| ps_dec->pu1_left_mv_ctxt_inc = ps_dec->u1_left_mv_ctxt_inc_arr[0]; | |
| ps_dec->pi1_left_ref_idx_ctxt_inc = | |
| &ps_dec->i1_left_ref_idx_ctx_inc_arr[0][0]; | |
| ps_dec->pu1_left_yuv_dc_csbp = &ps_dec->u1_yuv_dc_csbp_topmb; | |
| /* ! */ | |
| /* Initializing flush frame u4_flag */ | |
| ps_dec->u1_flushfrm = 0; | |
| { | |
| ps_dec->s_cab_dec_env.pv_codec_handle = (void*)ps_dec; | |
| ps_dec->ps_bitstrm->pv_codec_handle = (void*)ps_dec; | |
| ps_dec->ps_cur_slice->pv_codec_handle = (void*)ps_dec; | |
| ps_dec->ps_dpb_mgr->pv_codec_handle = (void*)ps_dec; | |
| } | |
| memset(ps_dec->disp_bufs, 0, (MAX_DISP_BUFS_NEW) * sizeof(disp_buf_t)); | |
| memset(ps_dec->u4_disp_buf_mapping, 0, | |
| (MAX_DISP_BUFS_NEW) * sizeof(UWORD32)); | |
| memset(ps_dec->u4_disp_buf_to_be_freed, 0, | |
| (MAX_DISP_BUFS_NEW) * sizeof(UWORD32)); | |
| memset(ps_dec->ps_cur_slice, 0, sizeof(dec_slice_params_t)); | |
| ih264d_init_arch(ps_dec); | |
| ih264d_init_function_ptr(ps_dec); | |
| ps_dec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; | |
| ps_dec->init_done = 1; | |
| } | |
| WORD32 ih264d_join_threads(dec_struct_t *ps_dec) | |
| { | |
| if(ps_dec->i4_threads_active) | |
| { | |
| /* Wait for threads */ | |
| ps_dec->i4_break_threads = 1; | |
| if(ps_dec->u4_dec_thread_created) | |
| { | |
| ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]); | |
| ps_dec->ai4_process_start[0] = PROC_START; | |
| ithread_cond_signal(ps_dec->apv_proc_start_condition[0]); | |
| ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]); | |
| ithread_join(ps_dec->pv_dec_thread_handle, NULL); | |
| ps_dec->u4_dec_thread_created = 0; | |
| } | |
| if(ps_dec->u4_bs_deblk_thread_created) | |
| { | |
| ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]); | |
| ps_dec->ai4_process_start[1] = PROC_START; | |
| ithread_cond_signal(ps_dec->apv_proc_start_condition[1]); | |
| ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]); | |
| ithread_join(ps_dec->pv_bs_deblk_thread_handle, NULL); | |
| ps_dec->u4_bs_deblk_thread_created = 0; | |
| } | |
| } | |
| return IV_SUCCESS; | |
| } | |
| WORD32 ih264d_free_static_bufs(iv_obj_t *dec_hdl) | |
| { | |
| dec_struct_t *ps_dec; | |
| void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf); | |
| void *pv_mem_ctxt; | |
| ps_dec = (dec_struct_t *)dec_hdl->pv_codec_handle; | |
| pf_aligned_free = ps_dec->pf_aligned_free; | |
| pv_mem_ctxt = ps_dec->pv_mem_ctxt; | |
| if(ps_dec->i4_threads_active) | |
| { | |
| ih264d_join_threads(ps_dec); | |
| // destroy mutex and condition variable for both the threads | |
| // 1. ih264d_decode_picture_thread | |
| // 2. ih264d_recon_deblk_thread | |
| { | |
| UWORD32 i; | |
| for(i = 0; i < 2; i++) | |
| { | |
| ithread_cond_destroy(ps_dec->apv_proc_start_condition[i]); | |
| ithread_cond_destroy(ps_dec->apv_proc_done_condition[i]); | |
| ithread_mutex_destroy(ps_dec->apv_proc_start_mutex[i]); | |
| ithread_mutex_destroy(ps_dec->apv_proc_done_mutex[i]); | |
| } | |
| } | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_mutex[0]); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_condition[0]); | |
| } | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sps); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pps); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_dec_thread_handle); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_bs_deblk_thread_handle); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dpb_mgr); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pred); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_disp_buf_mgr); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_pic_buf_mgr); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pic_buf_base); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dec_err_status); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sei); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sei_parse); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dpb_cmds); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_bitstrm); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_cur_slice); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_scratch_sps_pps); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_bits_buf_static); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ppv_map_ref_idx_to_poc_base); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->p_cabac_ctxt_table_t); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_left_mb_ctxt_info); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_ref_buff_base); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pi2_pred1); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_temp_mc_buffer); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_init_dpb_base); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu4_mbaff_wt_mat); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu4_wts_ofsts_mat); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_left_mvpred_addr); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_mv_buf_mgr); | |
| PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_col_mv_base); | |
| PS_DEC_ALIGNED_FREE(ps_dec, dec_hdl->pv_codec_handle); | |
| if(dec_hdl) | |
| { | |
| pf_aligned_free(pv_mem_ctxt, dec_hdl); | |
| } | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_create */ | |
| /* */ | |
| /* Description : creates decoder */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_allocate_static_bufs(iv_obj_t **dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| ih264d_create_ip_t *ps_create_ip; | |
| ih264d_create_op_t *ps_create_op; | |
| void *pv_buf; | |
| UWORD8 *pu1_buf; | |
| dec_struct_t *ps_dec; | |
| void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size); | |
| void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf); | |
| void *pv_mem_ctxt; | |
| WORD32 size; | |
| ps_create_ip = (ih264d_create_ip_t *)pv_api_ip; | |
| ps_create_op = (ih264d_create_op_t *)pv_api_op; | |
| ps_create_op->s_ivd_create_op_t.u4_error_code = 0; | |
| pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc; | |
| pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free; | |
| pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt; | |
| /* Initialize return handle to NULL */ | |
| ps_create_op->s_ivd_create_op_t.pv_handle = NULL; | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(iv_obj_t)); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, sizeof(iv_obj_t)); | |
| *dec_hdl = (iv_obj_t *)pv_buf; | |
| ps_create_op->s_ivd_create_op_t.pv_handle = *dec_hdl; | |
| (*dec_hdl)->pv_codec_handle = NULL; | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(dec_struct_t)); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| (*dec_hdl)->pv_codec_handle = (dec_struct_t *)pv_buf; | |
| ps_dec = (dec_struct_t *)pv_buf; | |
| memset(ps_dec, 0, sizeof(dec_struct_t)); | |
| #ifndef LOGO_EN | |
| ps_dec->u4_share_disp_buf = ps_create_ip->s_ivd_create_ip_t.u4_share_disp_buf; | |
| #else | |
| ps_dec->u4_share_disp_buf = 0; | |
| #endif | |
| ps_dec->u1_chroma_format = | |
| (UWORD8)(ps_create_ip->s_ivd_create_ip_t.e_output_format); | |
| if((ps_dec->u1_chroma_format != IV_YUV_420P) | |
| && (ps_dec->u1_chroma_format | |
| != IV_YUV_420SP_UV) | |
| && (ps_dec->u1_chroma_format | |
| != IV_YUV_420SP_VU)) | |
| { | |
| ps_dec->u4_share_disp_buf = 0; | |
| } | |
| ps_dec->u1_enable_mb_info = ps_create_ip->u4_enable_frame_info; | |
| ps_dec->pf_aligned_alloc = pf_aligned_alloc; | |
| ps_dec->pf_aligned_free = pf_aligned_free; | |
| ps_dec->pv_mem_ctxt = pv_mem_ctxt; | |
| ps_dec->i4_threads_active = ps_create_ip->u4_keep_threads_active; | |
| size = ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_sps = pv_buf; | |
| size = (sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS; | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_pps = pv_buf; | |
| size = ithread_get_handle_size(); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pv_dec_thread_handle = pv_buf; | |
| size = ithread_get_handle_size(); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pv_bs_deblk_thread_handle = pv_buf; | |
| if(ps_dec->i4_threads_active) | |
| { | |
| UWORD32 i; | |
| /* Request memory to hold mutex (start/done) for both threads */ | |
| size = ithread_get_mutex_lock_size() << 2; | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 8, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| // init mutex variable for both the threads | |
| // 1. ih264d_decode_picture_thread | |
| // 2. ih264d_recon_deblk_thread | |
| for(i = 0; i < 2; i++) | |
| { | |
| WORD32 ret; | |
| WORD32 mutex_size = ithread_get_mutex_lock_size(); | |
| ps_dec->apv_proc_start_mutex[i] = | |
| (UWORD8 *)pv_buf + (2 * i * mutex_size); | |
| ps_dec->apv_proc_done_mutex[i] = | |
| (UWORD8 *)pv_buf + ((2 * i + 1) * mutex_size); | |
| ret = ithread_mutex_init(ps_dec->apv_proc_start_mutex[0]); | |
| RETURN_IF((ret != IV_SUCCESS), ret); | |
| ret = ithread_mutex_init(ps_dec->apv_proc_done_mutex[i]); | |
| RETURN_IF((ret != IV_SUCCESS), ret); | |
| } | |
| size = ithread_get_cond_struct_size() << 2; | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 8, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| // init condition variable for both the threads | |
| for(i = 0; i < 2; i++) | |
| { | |
| WORD32 ret; | |
| WORD32 cond_size = ithread_get_cond_struct_size(); | |
| ps_dec->apv_proc_start_condition[i] = | |
| (UWORD8 *)pv_buf + (2 * i * cond_size); | |
| ps_dec->apv_proc_done_condition[i] = | |
| (UWORD8 *)pv_buf + ((2 * i + 1) * cond_size); | |
| ret = ithread_cond_init(ps_dec->apv_proc_start_condition[i]); | |
| RETURN_IF((ret != IV_SUCCESS), ret); | |
| ret = ithread_cond_init(ps_dec->apv_proc_done_condition[i]); | |
| RETURN_IF((ret != IV_SUCCESS), ret); | |
| } | |
| } | |
| size = sizeof(dpb_manager_t); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_dpb_mgr = pv_buf; | |
| size = sizeof(pred_info_t) * 2 * 32; | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_pred = pv_buf; | |
| size = sizeof(disp_mgr_t); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pv_disp_buf_mgr = pv_buf; | |
| size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size(); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pv_pic_buf_mgr = pv_buf; | |
| size = sizeof(struct pic_buffer_t) * (H264_MAX_REF_PICS * 2); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_pic_buf_base = pv_buf; | |
| size = sizeof(dec_err_status_t); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_dec_err_status = (dec_err_status_t *)pv_buf; | |
| size = sizeof(sei); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_sei = (sei *)pv_buf; | |
| size = sizeof(sei); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_sei_parse = (sei *)pv_buf; | |
| size = sizeof(dpb_commands_t); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_dpb_cmds = (dpb_commands_t *)pv_buf; | |
| size = sizeof(dec_bit_stream_t); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_bitstrm = (dec_bit_stream_t *)pv_buf; | |
| size = sizeof(dec_slice_params_t); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_cur_slice = (dec_slice_params_t *)pv_buf; | |
| size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t)); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pv_scratch_sps_pps = pv_buf; | |
| ps_dec->u4_static_bits_buf_size = 256000; | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, ps_dec->u4_static_bits_buf_size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, ps_dec->u4_static_bits_buf_size); | |
| ps_dec->pu1_bits_buf_static = pv_buf; | |
| size = ((TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC) | |
| * sizeof(void *)); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| ps_dec->ppv_map_ref_idx_to_poc_base = pv_buf; | |
| memset(ps_dec->ppv_map_ref_idx_to_poc_base, 0, size); | |
| ps_dec->ppv_map_ref_idx_to_poc = ps_dec->ppv_map_ref_idx_to_poc_base + OFFSET_MAP_IDX_POC; | |
| size = (sizeof(bin_ctxt_model_t) * NUM_CABAC_CTXTS); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->p_cabac_ctxt_table_t = pv_buf; | |
| size = sizeof(ctxt_inc_mb_info_t); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_left_mb_ctxt_info = pv_buf; | |
| size = MAX_REF_BUF_SIZE * 2; | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pu1_ref_buff_base = pv_buf; | |
| ps_dec->pu1_ref_buff = ps_dec->pu1_ref_buff_base + MAX_REF_BUF_SIZE; | |
| size = ((sizeof(WORD16)) * PRED_BUFFER_WIDTH | |
| * PRED_BUFFER_HEIGHT * 2); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pi2_pred1 = pv_buf; | |
| size = sizeof(UWORD8) * (MB_LUM_SIZE); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pu1_temp_mc_buffer = pv_buf; | |
| size = 8 * MAX_REF_BUFS * sizeof(struct pic_buffer_t); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pu1_init_dpb_base = pv_buf; | |
| pu1_buf = pv_buf; | |
| ps_dec->ps_dpb_mgr->ps_init_dpb[0][0] = (struct pic_buffer_t *)pu1_buf; | |
| pu1_buf += size / 2; | |
| ps_dec->ps_dpb_mgr->ps_init_dpb[1][0] = (struct pic_buffer_t *)pu1_buf; | |
| size = (sizeof(UWORD32) * 2 * 3 | |
| * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1)) * 2); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pu4_mbaff_wt_mat = pv_buf; | |
| size = sizeof(UWORD32) * 2 * 3 | |
| * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1)); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pu4_wts_ofsts_mat = pv_buf; | |
| size = (sizeof(neighbouradd_t) << 2); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->ps_left_mvpred_addr = pv_buf; | |
| size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size(); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size); | |
| ps_dec->pv_mv_buf_mgr = pv_buf; | |
| size = sizeof(col_mv_buf_t) * (H264_MAX_REF_PICS * 2); | |
| pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| ps_dec->ps_col_mv_base = pv_buf; | |
| memset(ps_dec->ps_col_mv_base, 0, size); | |
| ih264d_init_decoder(ps_dec); | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_create */ | |
| /* */ | |
| /* Description : creates decoder */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_create(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| ih264d_create_ip_t *ps_create_ip; | |
| ih264d_create_op_t *ps_create_op; | |
| WORD32 ret; | |
| ps_create_ip = (ih264d_create_ip_t *)pv_api_ip; | |
| ps_create_op = (ih264d_create_op_t *)pv_api_op; | |
| ps_create_op->s_ivd_create_op_t.u4_error_code = 0; | |
| dec_hdl = NULL; | |
| ret = ih264d_allocate_static_bufs(&dec_hdl, pv_api_ip, pv_api_op); | |
| /* If allocation of some buffer fails, then free buffers allocated till then */ | |
| if(IV_FAIL == ret) | |
| { | |
| if(dec_hdl) | |
| { | |
| if(dec_hdl->pv_codec_handle) | |
| { | |
| ih264d_free_static_bufs(dec_hdl); | |
| } | |
| else | |
| { | |
| void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf); | |
| void *pv_mem_ctxt; | |
| pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free; | |
| pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt; | |
| pf_aligned_free(pv_mem_ctxt, dec_hdl); | |
| } | |
| } | |
| ps_create_op->s_ivd_create_op_t.u4_error_code = IVD_MEM_ALLOC_FAILED; | |
| ps_create_op->s_ivd_create_op_t.u4_error_code |= 1 << IVD_FATALERROR; | |
| return IV_FAIL; | |
| } | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_map_error */ | |
| /* */ | |
| /* Description : Maps error codes to IVD error groups */ | |
| /* */ | |
| /* Inputs : */ | |
| /* Globals : <Does it use any global variables?> */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| UWORD32 ih264d_map_error(UWORD32 i4_err_status) | |
| { | |
| UWORD32 temp = 0; | |
| switch(i4_err_status) | |
| { | |
| case ERROR_MEM_ALLOC_ISRAM_T: | |
| case ERROR_MEM_ALLOC_SDRAM_T: | |
| case ERROR_BUF_MGR: | |
| case ERROR_MB_GROUP_ASSGN_T: | |
| case ERROR_FRAME_LIMIT_OVER: | |
| case ERROR_ACTUAL_RESOLUTION_GREATER_THAN_INIT: | |
| case ERROR_PROFILE_NOT_SUPPORTED: | |
| case ERROR_INIT_NOT_DONE: | |
| case IVD_MEM_ALLOC_FAILED: | |
| case ERROR_FEATURE_UNAVAIL: | |
| case IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED: | |
| temp = 1 << IVD_FATALERROR; | |
| H264_DEC_DEBUG_PRINT("\nFatal Error\n"); | |
| break; | |
| case ERROR_DBP_MANAGER_T: | |
| case ERROR_GAPS_IN_FRM_NUM: | |
| case ERROR_UNKNOWN_NAL: | |
| case ERROR_INV_MB_SLC_GRP_T: | |
| case ERROR_MULTIPLE_SLC_GRP_T: | |
| case ERROR_UNKNOWN_LEVEL: | |
| case ERROR_UNAVAIL_PICBUF_T: | |
| case ERROR_UNAVAIL_MVBUF_T: | |
| case ERROR_UNAVAIL_DISPBUF_T: | |
| case ERROR_NUM_REF: | |
| case ERROR_REFIDX_ORDER_T: | |
| case ERROR_PIC0_NOT_FOUND_T: | |
| case ERROR_MB_TYPE: | |
| case ERROR_SUB_MB_TYPE: | |
| case ERROR_CBP: | |
| case ERROR_REF_IDX: | |
| case ERROR_NUM_MV: | |
| case ERROR_CHROMA_PRED_MODE: | |
| case ERROR_INTRAPRED: | |
| case ERROR_NEXT_MB_ADDRESS_T: | |
| case ERROR_MB_ADDRESS_T: | |
| case ERROR_PIC1_NOT_FOUND_T: | |
| case ERROR_CAVLC_NUM_COEFF_T: | |
| case ERROR_CAVLC_SCAN_POS_T: | |
| case ERROR_PRED_WEIGHT_TABLE_T: | |
| case ERROR_CORRUPTED_SLICE: | |
| temp = 1 << IVD_CORRUPTEDDATA; | |
| break; | |
| case ERROR_NOT_SUPP_RESOLUTION: | |
| case ERROR_ACTUAL_LEVEL_GREATER_THAN_INIT: | |
| temp = 1 << IVD_UNSUPPORTEDINPUT; | |
| break; | |
| case ERROR_INVALID_PIC_PARAM: | |
| case ERROR_INVALID_SEQ_PARAM: | |
| case ERROR_EGC_EXCEED_32_1_T: | |
| case ERROR_EGC_EXCEED_32_2_T: | |
| case ERROR_INV_RANGE_TEV_T: | |
| case ERROR_INV_SLC_TYPE_T: | |
| case ERROR_INV_POC_TYPE_T: | |
| case ERROR_INV_RANGE_QP_T: | |
| case ERROR_INV_SPS_PPS_T: | |
| case ERROR_INV_SLICE_HDR_T: | |
| case ERROR_INV_SEI_MDCV_PARAMS: | |
| case ERROR_INV_SEI_CLL_PARAMS: | |
| case ERROR_INV_SEI_AVE_PARAMS: | |
| case ERROR_INV_SEI_CCV_PARAMS: | |
| case ERROR_INV_SEI_SII_PARAMS: | |
| temp = 1 << IVD_CORRUPTEDHEADER; | |
| break; | |
| case ERROR_EOB_FLUSHBITS_T: | |
| case ERROR_EOB_GETBITS_T: | |
| case ERROR_EOB_GETBIT_T: | |
| case ERROR_EOB_BYPASS_T: | |
| case ERROR_EOB_DECISION_T: | |
| case ERROR_EOB_TERMINATE_T: | |
| case ERROR_EOB_READCOEFF4X4CAB_T: | |
| temp = 1 << IVD_INSUFFICIENTDATA; | |
| break; | |
| case ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED: | |
| case ERROR_DISP_WIDTH_RESET_TO_PIC_WIDTH: | |
| temp = 1 << IVD_UNSUPPORTEDPARAM | 1 << IVD_FATALERROR; | |
| break; | |
| case ERROR_DANGLING_FIELD_IN_PIC: | |
| temp = 1 << IVD_APPLIEDCONCEALMENT; | |
| break; | |
| } | |
| return temp; | |
| } | |
| UWORD32 ih264d_get_outbuf_size(WORD32 pic_wd, | |
| UWORD32 pic_ht, | |
| UWORD8 u1_chroma_format, | |
| UWORD32 *p_buf_size) | |
| { | |
| UWORD32 u4_min_num_out_bufs = 0; | |
| if(u1_chroma_format == IV_YUV_420P) | |
| u4_min_num_out_bufs = MIN_OUT_BUFS_420; | |
| else if(u1_chroma_format == IV_YUV_422ILE) | |
| u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; | |
| else if(u1_chroma_format == IV_RGB_565) | |
| u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; | |
| else if((u1_chroma_format == IV_YUV_420SP_UV) | |
| || (u1_chroma_format == IV_YUV_420SP_VU)) | |
| u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; | |
| if(u1_chroma_format == IV_YUV_420P) | |
| { | |
| p_buf_size[0] = (pic_wd * pic_ht); | |
| p_buf_size[1] = (pic_wd * pic_ht) >> 2; | |
| p_buf_size[2] = (pic_wd * pic_ht) >> 2; | |
| } | |
| else if(u1_chroma_format == IV_YUV_422ILE) | |
| { | |
| p_buf_size[0] = (pic_wd * pic_ht) * 2; | |
| p_buf_size[1] = p_buf_size[2] = 0; | |
| } | |
| else if(u1_chroma_format == IV_RGB_565) | |
| { | |
| p_buf_size[0] = (pic_wd * pic_ht) * 2; | |
| p_buf_size[1] = p_buf_size[2] = 0; | |
| } | |
| else if((u1_chroma_format == IV_YUV_420SP_UV) | |
| || (u1_chroma_format == IV_YUV_420SP_VU)) | |
| { | |
| p_buf_size[0] = (pic_wd * pic_ht); | |
| p_buf_size[1] = (pic_wd * pic_ht) >> 1; | |
| p_buf_size[2] = 0; | |
| } | |
| return u4_min_num_out_bufs; | |
| } | |
| WORD32 check_app_out_buf_size(dec_struct_t *ps_dec) | |
| { | |
| UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS]; | |
| UWORD32 u4_min_num_out_bufs, i; | |
| UWORD32 pic_wd, pic_ht; | |
| if(0 == ps_dec->u4_share_disp_buf) | |
| { | |
| pic_wd = ps_dec->u2_disp_width; | |
| pic_ht = ps_dec->u2_disp_height; | |
| } | |
| else | |
| { | |
| pic_wd = ps_dec->u2_frm_wd_y; | |
| pic_ht = ps_dec->u2_frm_ht_y; | |
| } | |
| if(ps_dec->u4_app_disp_width > pic_wd) | |
| pic_wd = ps_dec->u4_app_disp_width; | |
| u4_min_num_out_bufs = ih264d_get_outbuf_size(pic_wd, pic_ht, | |
| ps_dec->u1_chroma_format, | |
| &au4_min_out_buf_size[0]); | |
| if(0 == ps_dec->u4_share_disp_buf) | |
| { | |
| if(ps_dec->ps_out_buffer->u4_num_bufs < u4_min_num_out_bufs) | |
| return IV_FAIL; | |
| for(i = 0; i < u4_min_num_out_bufs; i++) | |
| { | |
| if(ps_dec->ps_out_buffer->u4_min_out_buf_size[i] | |
| < au4_min_out_buf_size[i]) | |
| return (IV_FAIL); | |
| } | |
| } | |
| else | |
| { | |
| if(ps_dec->disp_bufs[0].u4_num_bufs < u4_min_num_out_bufs) | |
| return IV_FAIL; | |
| for(i = 0; i < u4_min_num_out_bufs; i++) | |
| { | |
| /* We need to check only with the disp_buffer[0], because we have | |
| * already ensured that all the buffers are of the same size in | |
| * ih264d_set_display_frame. | |
| */ | |
| if(ps_dec->disp_bufs[0].u4_bufsize[i] < au4_min_out_buf_size[i]) | |
| return (IV_FAIL); | |
| } | |
| } | |
| return (IV_SUCCESS); | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_video_decode */ | |
| /* */ | |
| /* Description : handle video decode API command */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| /* ! */ | |
| dec_struct_t * ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); | |
| WORD32 i4_err_status = 0; | |
| UWORD8 *pu1_buf = NULL; | |
| WORD32 buflen; | |
| UWORD32 u4_max_ofst, u4_length_of_start_code = 0; | |
| UWORD32 bytes_consumed = 0; | |
| UWORD32 cur_slice_is_nonref = 0; | |
| UWORD32 u4_next_is_aud; | |
| UWORD32 u4_first_start_code_found = 0; | |
| WORD32 ret = 0,api_ret_value = IV_SUCCESS; | |
| WORD32 header_data_left = 0,frame_data_left = 0; | |
| UWORD8 *pu1_bitstrm_buf; | |
| ih264d_video_decode_ip_t *ps_h264d_dec_ip; | |
| ih264d_video_decode_op_t *ps_h264d_dec_op; | |
| ivd_video_decode_ip_t *ps_dec_ip; | |
| ivd_video_decode_op_t *ps_dec_op; | |
| ithread_set_name((void*)"Parse_thread"); | |
| ps_h264d_dec_ip = (ih264d_video_decode_ip_t *)pv_api_ip; | |
| ps_h264d_dec_op = (ih264d_video_decode_op_t *)pv_api_op; | |
| ps_dec_ip = &ps_h264d_dec_ip->s_ivd_video_decode_ip_t; | |
| ps_dec_op = &ps_h264d_dec_op->s_ivd_video_decode_op_t; | |
| { | |
| UWORD32 u4_size; | |
| u4_size = ps_dec_op->u4_size; | |
| memset(ps_h264d_dec_op, 0, ps_dec_op->u4_size); | |
| ps_dec_op->u4_size = u4_size; | |
| } | |
| ps_dec->pv_dec_out = ps_dec_op; | |
| if(ps_dec->init_done != 1) | |
| { | |
| return IV_FAIL; | |
| } | |
| /*Data memory barries instruction,so that bitstream write by the application is complete*/ | |
| DATA_SYNC(); | |
| if(0 == ps_dec->u1_flushfrm) | |
| { | |
| if(ps_dec_ip->pv_stream_buffer == NULL) | |
| { | |
| ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL; | |
| return IV_FAIL; | |
| } | |
| if(ps_dec_ip->u4_num_Bytes <= 0) | |
| { | |
| ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV; | |
| return IV_FAIL; | |
| } | |
| } | |
| ps_dec->u1_pic_decode_done = 0; | |
| if(ps_dec->i4_threads_active) | |
| { | |
| UWORD32 i; | |
| ps_dec->i4_break_threads = 0; | |
| for (i = 0; i < 2; i++) | |
| { | |
| ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[i]); | |
| RETURN_IF((ret != IV_SUCCESS), ret); | |
| ps_dec->ai4_process_start[i] = PROC_INIT; | |
| ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[i]); | |
| RETURN_IF((ret != IV_SUCCESS), ret); | |
| } | |
| } | |
| else { | |
| ps_dec->u4_dec_thread_created = 0; | |
| ps_dec->u4_bs_deblk_thread_created = 0; | |
| } | |
| ps_dec_op->u4_num_bytes_consumed = 0; | |
| ps_dec_op->i4_reorder_depth = -1; | |
| ps_dec_op->i4_display_index = DEFAULT_POC; | |
| ps_dec->ps_out_buffer = NULL; | |
| if(ps_dec_ip->u4_size | |
| >= offsetof(ivd_video_decode_ip_t, s_out_buffer)) | |
| ps_dec->ps_out_buffer = &ps_dec_ip->s_out_buffer; | |
| ps_dec->u4_fmt_conv_cur_row = 0; | |
| ps_dec->u4_output_present = 0; | |
| ps_dec->s_disp_op.u4_error_code = 1; | |
| ps_dec->u4_fmt_conv_num_rows = FMT_CONV_NUM_ROWS; | |
| if(0 == ps_dec->u4_share_disp_buf | |
| && ps_dec->i4_decode_header == 0) | |
| { | |
| UWORD32 i; | |
| if((ps_dec->ps_out_buffer->u4_num_bufs == 0) || | |
| (ps_dec->ps_out_buffer->u4_num_bufs > IVD_VIDDEC_MAX_IO_BUFFERS)) | |
| { | |
| ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS; | |
| return IV_FAIL; | |
| } | |
| for(i = 0; i < ps_dec->ps_out_buffer->u4_num_bufs; i++) | |
| { | |
| if(ps_dec->ps_out_buffer->pu1_bufs[i] == NULL) | |
| { | |
| ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL; | |
| return IV_FAIL; | |
| } | |
| if(ps_dec->ps_out_buffer->u4_min_out_buf_size[i] == 0) | |
| { | |
| ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_dec_op->u4_error_code |= | |
| IVD_DISP_FRM_ZERO_OP_BUF_SIZE; | |
| return IV_FAIL; | |
| } | |
| } | |
| } | |
| if(ps_dec->u4_total_frames_decoded >= NUM_FRAMES_LIMIT) | |
| { | |
| ps_dec_op->u4_error_code = ERROR_FRAME_LIMIT_OVER; | |
| return IV_FAIL; | |
| } | |
| /* ! */ | |
| ps_dec->u4_ts = ps_dec_ip->u4_ts; | |
| ps_dec_op->u4_error_code = 0; | |
| ps_dec_op->e_pic_type = IV_NA_FRAME; | |
| ps_dec_op->u4_output_present = 0; | |
| ps_dec_op->u4_frame_decoded_flag = 0; | |
| ps_dec->i4_frametype = IV_NA_FRAME; | |
| ps_dec->i4_content_type = IV_CONTENTTYPE_NA; | |
| ps_dec->u4_slice_start_code_found = 0; | |
| /* In case the decoder is not in flush mode(in shared mode), | |
| then decoder has to pick up a buffer to write current frame. | |
| Check if a frame is available in such cases */ | |
| if(ps_dec->u1_init_dec_flag == 1 && ps_dec->u4_share_disp_buf == 1 | |
| && ps_dec->u1_flushfrm == 0) | |
| { | |
| UWORD32 i; | |
| WORD32 disp_avail = 0, free_id; | |
| /* Check if at least one buffer is available with the codec */ | |
| /* If not then return to application with error */ | |
| for(i = 0; i < ps_dec->u1_pic_bufs; i++) | |
| { | |
| if(0 == ps_dec->u4_disp_buf_mapping[i] | |
| || 1 == ps_dec->u4_disp_buf_to_be_freed[i]) | |
| { | |
| disp_avail = 1; | |
| break; | |
| } | |
| } | |
| if(0 == disp_avail) | |
| { | |
| /* If something is queued for display wait for that buffer to be returned */ | |
| ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL; | |
| ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); | |
| return (IV_FAIL); | |
| } | |
| while(1) | |
| { | |
| pic_buffer_t *ps_pic_buf; | |
| ps_pic_buf = (pic_buffer_t *)ih264_buf_mgr_get_next_free( | |
| (buf_mgr_t *)ps_dec->pv_pic_buf_mgr, &free_id); | |
| if(ps_pic_buf == NULL) | |
| { | |
| UWORD32 display_queued = 0; | |
| /* check if any buffer was given for display which is not returned yet */ | |
| for(i = 0; i < (MAX_DISP_BUFS_NEW); i++) | |
| { | |
| if(0 != ps_dec->u4_disp_buf_mapping[i]) | |
| { | |
| display_queued = 1; | |
| break; | |
| } | |
| } | |
| /* If some buffer is queued for display, then codec has to singal an error and wait | |
| for that buffer to be returned. | |
| If nothing is queued for display then codec has ownership of all display buffers | |
| and it can reuse any of the existing buffers and continue decoding */ | |
| if(1 == display_queued) | |
| { | |
| /* If something is queued for display wait for that buffer to be returned */ | |
| ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL; | |
| ps_dec_op->u4_error_code |= (1 | |
| << IVD_UNSUPPORTEDPARAM); | |
| return (IV_FAIL); | |
| } | |
| } | |
| else | |
| { | |
| /* If the buffer is with display, then mark it as in use and then look for a buffer again */ | |
| if(1 == ps_dec->u4_disp_buf_mapping[free_id]) | |
| { | |
| ih264_buf_mgr_set_status( | |
| (buf_mgr_t *)ps_dec->pv_pic_buf_mgr, | |
| free_id, | |
| BUF_MGR_IO); | |
| } | |
| else | |
| { | |
| /** | |
| * Found a free buffer for present call. Release it now. | |
| * Will be again obtained later. | |
| */ | |
| ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, | |
| free_id, | |
| BUF_MGR_IO); | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| if(ps_dec->u1_enable_mb_info && (ps_dec->i4_header_decoded & DECODED_SPS_MASK)) | |
| { | |
| UWORD32 blk_qp_map_size = ps_h264d_dec_ip->u4_8x8_blk_qp_map_size; | |
| UWORD32 blk_type_map_size = ps_h264d_dec_ip->u4_8x8_blk_type_map_size; | |
| UWORD32 blk_8x8_map_size = ps_dec->u4_total_mbs << 2; | |
| if ((ps_h264d_dec_ip->pu1_8x8_blk_qp_map && blk_qp_map_size < blk_8x8_map_size) || | |
| (ps_h264d_dec_ip->pu1_8x8_blk_type_map && blk_type_map_size < blk_8x8_map_size)) | |
| { | |
| ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; | |
| ps_dec_op->u4_error_code |= IH264D_INSUFFICIENT_METADATA_BUFFER; | |
| return IV_FAIL; | |
| } | |
| } | |
| if(ps_dec->u1_flushfrm) | |
| { | |
| if(ps_dec->u1_init_dec_flag == 0) | |
| { | |
| /*Come out of flush mode and return*/ | |
| ps_dec->u1_flushfrm = 0; | |
| return (IV_FAIL); | |
| } | |
| ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer, | |
| &(ps_dec->s_disp_op)); | |
| if(0 == ps_dec->s_disp_op.u4_error_code) | |
| { | |
| /* check output buffer size given by the application */ | |
| if(check_app_out_buf_size(ps_dec) != IV_SUCCESS) | |
| { | |
| ps_dec_op->u4_error_code= IVD_DISP_FRM_ZERO_OP_BUF_SIZE; | |
| return (IV_FAIL); | |
| } | |
| ps_dec->u4_fmt_conv_cur_row = 0; | |
| ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht; | |
| ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), | |
| ps_dec->u4_fmt_conv_cur_row, | |
| ps_dec->u4_fmt_conv_num_rows); | |
| ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; | |
| ps_dec->u4_output_present = 1; | |
| if(ps_dec->u1_enable_mb_info) | |
| { | |
| UWORD32 disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id; | |
| if(ps_h264d_dec_ip->pu1_8x8_blk_qp_map) | |
| { | |
| ps_h264d_dec_op->pu1_8x8_blk_qp_map = ps_h264d_dec_ip->pu1_8x8_blk_qp_map; | |
| ps_h264d_dec_op->u4_8x8_blk_qp_map_size = ps_dec->u4_total_mbs << 2; | |
| ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_qp_map, | |
| ps_dec->as_buf_id_info_map[disp_buf_id].pu1_qp_map, | |
| ps_dec->u4_total_mbs << 2); | |
| } | |
| if(ps_h264d_dec_ip->pu1_8x8_blk_type_map) | |
| { | |
| ps_h264d_dec_op->pu1_8x8_blk_type_map = ps_h264d_dec_ip->pu1_8x8_blk_type_map; | |
| ps_h264d_dec_op->u4_8x8_blk_type_map_size = ps_dec->u4_total_mbs << 2; | |
| ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_type_map, | |
| ps_dec->as_buf_id_info_map[disp_buf_id].pu1_mb_type_map, | |
| ps_dec->u4_total_mbs << 2); | |
| } | |
| } | |
| } | |
| ih264d_export_sei_params(&ps_dec_op->s_sei_decode_op, ps_dec); | |
| ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op)); | |
| ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width; | |
| ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height; | |
| ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth; | |
| ps_dec_op->i4_display_index = ps_dec->i4_display_index; | |
| ps_dec_op->u4_new_seq = 0; | |
| ps_dec_op->u4_output_present = ps_dec->u4_output_present; | |
| ps_dec_op->u4_progressive_frame_flag = | |
| ps_dec->s_disp_op.u4_progressive_frame_flag; | |
| ps_dec_op->e_output_format = | |
| ps_dec->s_disp_op.e_output_format; | |
| ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf; | |
| ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type; | |
| ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts; | |
| ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id; | |
| /*In the case of flush ,since no frame is decoded set pic type as invalid*/ | |
| ps_dec_op->u4_is_ref_flag = -1; | |
| ps_dec_op->e_pic_type = IV_NA_FRAME; | |
| ps_dec_op->u4_frame_decoded_flag = 0; | |
| if(0 == ps_dec->s_disp_op.u4_error_code) | |
| { | |
| return (IV_SUCCESS); | |
| } | |
| else | |
| return (IV_FAIL); | |
| } | |
| if(ps_dec->u1_res_changed == 1) | |
| { | |
| /*if resolution has changed and all buffers have been flushed, reset decoder*/ | |
| ih264d_init_decoder(ps_dec); | |
| } | |
| ps_dec->u2_cur_mb_addr = 0; | |
| ps_dec->u2_total_mbs_coded = 0; | |
| ps_dec->u2_cur_slice_num = 0; | |
| ps_dec->cur_dec_mb_num = 0; | |
| ps_dec->cur_recon_mb_num = 0; | |
| ps_dec->u4_first_slice_in_pic = 1; | |
| ps_dec->u1_slice_header_done = 0; | |
| ps_dec->u1_dangling_field = 0; | |
| ps_dec->u4_cur_bs_mb_num = 0; | |
| ps_dec->u4_start_recon_deblk = 0; | |
| ps_dec->u4_sps_cnt_in_process = 0; | |
| DEBUG_THREADS_PRINTF(" Starting process call\n"); | |
| ps_dec->u4_pic_buf_got = 0; | |
| do | |
| { | |
| WORD32 buf_size; | |
| pu1_buf = (UWORD8*)ps_dec_ip->pv_stream_buffer | |
| + ps_dec_op->u4_num_bytes_consumed; | |
| u4_max_ofst = ps_dec_ip->u4_num_Bytes | |
| - ps_dec_op->u4_num_bytes_consumed; | |
| /* If dynamic bitstream buffer is not allocated and | |
| * header decode is done, then allocate dynamic bitstream buffer | |
| */ | |
| if((NULL == ps_dec->pu1_bits_buf_dynamic) && | |
| (ps_dec->i4_header_decoded & 1)) | |
| { | |
| WORD32 size; | |
| void *pv_buf; | |
| void *pv_mem_ctxt = ps_dec->pv_mem_ctxt; | |
| size = MAX(256000, ps_dec->u2_pic_wd * ps_dec->u2_pic_ht * 3 / 2); | |
| pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, | |
| size + EXTRA_BS_OFFSET); | |
| RETURN_IF((NULL == pv_buf), IV_FAIL); | |
| memset(pv_buf, 0, size + EXTRA_BS_OFFSET); | |
| ps_dec->pu1_bits_buf_dynamic = pv_buf; | |
| ps_dec->u4_dynamic_bits_buf_size = size; | |
| } | |
| if(ps_dec->pu1_bits_buf_dynamic) | |
| { | |
| pu1_bitstrm_buf = ps_dec->pu1_bits_buf_dynamic; | |
| buf_size = ps_dec->u4_dynamic_bits_buf_size; | |
| } | |
| else | |
| { | |
| pu1_bitstrm_buf = ps_dec->pu1_bits_buf_static; | |
| buf_size = ps_dec->u4_static_bits_buf_size; | |
| } | |
| u4_next_is_aud = 0; | |
| buflen = ih264d_find_start_code(pu1_buf, 0, u4_max_ofst, | |
| &u4_length_of_start_code, | |
| &u4_next_is_aud); | |
| if(buflen == -1) | |
| buflen = 0; | |
| /* Ignore bytes beyond the allocated size of intermediate buffer */ | |
| /* Since 8 bytes are read ahead, ensure 8 bytes are free at the | |
| end of the buffer, which will be memset to 0 after emulation prevention */ | |
| buflen = MIN(buflen, buf_size - 8); | |
| bytes_consumed = buflen + u4_length_of_start_code; | |
| ps_dec_op->u4_num_bytes_consumed += bytes_consumed; | |
| if(buflen) | |
| { | |
| memcpy(pu1_bitstrm_buf, pu1_buf + u4_length_of_start_code, | |
| buflen); | |
| /* Decoder may read extra 8 bytes near end of the frame */ | |
| if((buflen + 8) < buf_size) | |
| { | |
| memset(pu1_bitstrm_buf + buflen, 0, 8); | |
| } | |
| u4_first_start_code_found = 1; | |
| } | |
| else | |
| { | |
| /*start code not found*/ | |
| if(u4_first_start_code_found == 0) | |
| { | |
| /*no start codes found in current process call*/ | |
| ps_dec->i4_error_code = ERROR_START_CODE_NOT_FOUND; | |
| ps_dec_op->u4_error_code |= 1 << IVD_INSUFFICIENTDATA; | |
| if(ps_dec->u4_pic_buf_got == 0) | |
| { | |
| ih264d_fill_output_struct_from_context(ps_dec, | |
| ps_dec_op); | |
| ps_dec_op->u4_error_code = ps_dec->i4_error_code; | |
| ps_dec_op->u4_frame_decoded_flag = 0; | |
| return (IV_FAIL); | |
| } | |
| else | |
| { | |
| ps_dec->u1_pic_decode_done = 1; | |
| continue; | |
| } | |
| } | |
| else | |
| { | |
| /* a start code has already been found earlier in the same process call*/ | |
| frame_data_left = 0; | |
| header_data_left = 0; | |
| continue; | |
| } | |
| } | |
| ret = ih264d_parse_nal_unit(dec_hdl, ps_dec_op, | |
| pu1_bitstrm_buf, buflen); | |
| if(ret != OK) | |
| { | |
| UWORD32 error = ih264d_map_error(ret); | |
| ps_dec_op->u4_error_code = error | ret; | |
| api_ret_value = IV_FAIL; | |
| if((ret == IVD_RES_CHANGED) | |
| || (ret == IVD_MEM_ALLOC_FAILED) | |
| || (ret == ERROR_UNAVAIL_PICBUF_T) | |
| || (ret == ERROR_UNAVAIL_MVBUF_T) | |
| || (ret == ERROR_INV_SPS_PPS_T) | |
| || (ret == ERROR_FEATURE_UNAVAIL) | |
| || (ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED) | |
| || (ret == IVD_DISP_FRM_ZERO_OP_BUF_SIZE)) | |
| { | |
| ps_dec->u4_slice_start_code_found = 0; | |
| break; | |
| } | |
| if((ret == ERROR_INCOMPLETE_FRAME) || (ret == ERROR_DANGLING_FIELD_IN_PIC)) | |
| { | |
| ps_dec_op->u4_num_bytes_consumed -= bytes_consumed; | |
| api_ret_value = IV_FAIL; | |
| break; | |
| } | |
| if(ret == ERROR_IN_LAST_SLICE_OF_PIC) | |
| { | |
| api_ret_value = IV_FAIL; | |
| break; | |
| } | |
| } | |
| header_data_left = ((ps_dec->i4_decode_header == 1) | |
| && (ps_dec->i4_header_decoded != 3) | |
| && (ps_dec_op->u4_num_bytes_consumed | |
| < ps_dec_ip->u4_num_Bytes)); | |
| frame_data_left = (((ps_dec->i4_decode_header == 0) | |
| && ((ps_dec->u1_pic_decode_done == 0) | |
| || (u4_next_is_aud == 1))) | |
| && (ps_dec_op->u4_num_bytes_consumed | |
| < ps_dec_ip->u4_num_Bytes)); | |
| } | |
| while(( header_data_left == 1)||(frame_data_left == 1)); | |
| if((ps_dec->u4_pic_buf_got == 1) | |
| && (ret != IVD_MEM_ALLOC_FAILED) | |
| && ps_dec->u2_total_mbs_coded < ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs) | |
| { | |
| // last slice - missing/corruption | |
| WORD32 num_mb_skipped; | |
| WORD32 prev_slice_err; | |
| pocstruct_t temp_poc; | |
| WORD32 ret1; | |
| WORD32 ht_in_mbs; | |
| ht_in_mbs = ps_dec->u2_pic_ht >> (4 + ps_dec->ps_cur_slice->u1_field_pic_flag); | |
| num_mb_skipped = (ht_in_mbs * ps_dec->u2_frm_wd_in_mbs) | |
| - ps_dec->u2_total_mbs_coded; | |
| if(ps_dec->u4_first_slice_in_pic && (ps_dec->u4_pic_buf_got == 0)) | |
| prev_slice_err = 1; | |
| else | |
| prev_slice_err = 2; | |
| if(ps_dec->u4_first_slice_in_pic && (ps_dec->u2_total_mbs_coded == 0)) | |
| prev_slice_err = 1; | |
| ret1 = ih264d_mark_err_slice_skip(ps_dec, num_mb_skipped, ps_dec->u1_nal_unit_type == IDR_SLICE_NAL, ps_dec->ps_cur_slice->u2_frame_num, | |
| &temp_poc, prev_slice_err); | |
| if((ret1 == ERROR_UNAVAIL_PICBUF_T) || (ret1 == ERROR_UNAVAIL_MVBUF_T) || | |
| (ret1 == ERROR_INV_SPS_PPS_T)) | |
| { | |
| ret = ret1; | |
| } | |
| } | |
| if((ret == IVD_RES_CHANGED) | |
| || (ret == IVD_MEM_ALLOC_FAILED) | |
| || (ret == ERROR_UNAVAIL_PICBUF_T) | |
| || (ret == ERROR_UNAVAIL_MVBUF_T) | |
| || (ret == ERROR_INV_SPS_PPS_T)) | |
| { | |
| /* signal the decode thread */ | |
| ih264d_signal_decode_thread(ps_dec); | |
| /* close deblock thread if it is not closed yet */ | |
| if(ps_dec->u4_num_cores == 3) | |
| { | |
| ih264d_signal_bs_deblk_thread(ps_dec); | |
| } | |
| /* dont consume bitstream for change in resolution case */ | |
| if(ret == IVD_RES_CHANGED) | |
| { | |
| ps_dec_op->u4_num_bytes_consumed -= bytes_consumed; | |
| } | |
| return IV_FAIL; | |
| } | |
| if(ps_dec->u1_separate_parse) | |
| { | |
| /* If Format conversion is not complete, | |
| complete it here */ | |
| if(ps_dec->u4_num_cores == 2) | |
| { | |
| /*do deblocking of all mbs*/ | |
| if((ps_dec->u4_nmb_deblk == 0) &&(ps_dec->u4_start_recon_deblk == 1) && (ps_dec->ps_cur_sps->u1_mb_aff_flag == 0)) | |
| { | |
| UWORD32 u4_num_mbs,u4_max_addr; | |
| tfr_ctxt_t s_tfr_ctxt; | |
| tfr_ctxt_t *ps_tfr_cxt = &s_tfr_ctxt; | |
| pad_mgr_t *ps_pad_mgr = &ps_dec->s_pad_mgr; | |
| /*BS is done for all mbs while parsing*/ | |
| u4_max_addr = (ps_dec->u2_frm_wd_in_mbs * ps_dec->u2_frm_ht_in_mbs) - 1; | |
| ps_dec->u4_cur_bs_mb_num = u4_max_addr + 1; | |
| ih264d_init_deblk_tfr_ctxt(ps_dec, ps_pad_mgr, ps_tfr_cxt, | |
| ps_dec->u2_frm_wd_in_mbs, 0); | |
| u4_num_mbs = u4_max_addr | |
| - ps_dec->u4_cur_deblk_mb_num + 1; | |
| DEBUG_PERF_PRINTF("mbs left for deblocking= %d \n",u4_num_mbs); | |
| if(u4_num_mbs != 0) | |
| ih264d_check_mb_map_deblk(ps_dec, u4_num_mbs, | |
| ps_tfr_cxt,1); | |
| ps_dec->u4_start_recon_deblk = 0; | |
| } | |
| } | |
| /*signal the decode thread*/ | |
| ih264d_signal_decode_thread(ps_dec); | |
| /* close deblock thread if it is not closed yet*/ | |
| if(ps_dec->u4_num_cores == 3) | |
| { | |
| ih264d_signal_bs_deblk_thread(ps_dec); | |
| } | |
| } | |
| DATA_SYNC(); | |
| if((ps_dec_op->u4_error_code & 0xff) | |
| != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED) | |
| { | |
| ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width; | |
| ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height; | |
| ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth; | |
| } | |
| //Report if header (sps and pps) has not been decoded yet | |
| if(ps_dec->i4_decode_header == 1 && ps_dec->i4_header_decoded != 3) | |
| { | |
| ps_dec_op->u4_error_code |= (1 << IVD_INSUFFICIENTDATA); | |
| api_ret_value = IV_FAIL; | |
| } | |
| if((ps_dec->u4_pic_buf_got == 1) | |
| && (ERROR_DANGLING_FIELD_IN_PIC != i4_err_status)) | |
| { | |
| /* | |
| * For field pictures, set the bottom and top picture decoded u4_flag correctly. | |
| */ | |
| if(ps_dec->ps_cur_slice->u1_field_pic_flag) | |
| { | |
| if(1 == ps_dec->ps_cur_slice->u1_bottom_field_flag) | |
| { | |
| ps_dec->u1_top_bottom_decoded |= BOT_FIELD_ONLY; | |
| } | |
| else | |
| { | |
| ps_dec->u1_top_bottom_decoded |= TOP_FIELD_ONLY; | |
| } | |
| } | |
| else | |
| { | |
| ps_dec->u1_top_bottom_decoded = TOP_FIELD_ONLY | BOT_FIELD_ONLY; | |
| } | |
| /* if new frame in not found (if we are still getting slices from previous frame) | |
| * ih264d_deblock_display is not called. Such frames will not be added to reference /display | |
| */ | |
| if ((ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) == 0) | |
| { | |
| /* Calling Function to deblock Picture and Display */ | |
| ret = ih264d_deblock_display(ps_dec); | |
| } | |
| /*set to complete ,as we dont support partial frame decode*/ | |
| if(ps_dec->i4_header_decoded == 3) | |
| { | |
| ps_dec->u2_total_mbs_coded = ps_dec->ps_cur_sps->u2_max_mb_addr + 1; | |
| } | |
| /*Update the i4_frametype at the end of picture*/ | |
| if(ps_dec->ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL) | |
| { | |
| ps_dec->i4_frametype = IV_IDR_FRAME; | |
| } | |
| else if(ps_dec->i4_pic_type == B_SLICE) | |
| { | |
| ps_dec->i4_frametype = IV_B_FRAME; | |
| } | |
| else if(ps_dec->i4_pic_type == P_SLICE) | |
| { | |
| ps_dec->i4_frametype = IV_P_FRAME; | |
| } | |
| else if(ps_dec->i4_pic_type == I_SLICE) | |
| { | |
| ps_dec->i4_frametype = IV_I_FRAME; | |
| } | |
| else | |
| { | |
| H264_DEC_DEBUG_PRINT("Shouldn't come here\n"); | |
| } | |
| //Update the content type | |
| ps_dec->i4_content_type = ps_dec->ps_cur_slice->u1_field_pic_flag; | |
| ps_dec->u4_total_frames_decoded = ps_dec->u4_total_frames_decoded + 2; | |
| ps_dec->u4_total_frames_decoded = ps_dec->u4_total_frames_decoded | |
| - ps_dec->ps_cur_slice->u1_field_pic_flag; | |
| } | |
| /* close deblock thread if it is not closed yet*/ | |
| if(!ps_dec->i4_threads_active) | |
| { | |
| if(ps_dec->u4_num_cores == 3) | |
| { | |
| ih264d_signal_bs_deblk_thread(ps_dec); | |
| } | |
| } | |
| { | |
| /* In case the decoder is configured to run in low delay mode, | |
| * then get display buffer and then format convert. | |
| * Note in this mode, format conversion does not run paralelly in a thread and adds to the codec cycles | |
| */ | |
| if((IVD_DECODE_FRAME_OUT == ps_dec->e_frm_out_mode) | |
| && ps_dec->u1_init_dec_flag) | |
| { | |
| ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer, | |
| &(ps_dec->s_disp_op)); | |
| if(0 == ps_dec->s_disp_op.u4_error_code) | |
| { | |
| ps_dec->u4_fmt_conv_cur_row = 0; | |
| ps_dec->u4_output_present = 1; | |
| } | |
| } | |
| ih264d_fill_output_struct_from_context(ps_dec, ps_dec_op); | |
| /* If Format conversion is not complete, | |
| complete it here */ | |
| if(ps_dec->u4_output_present && | |
| (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht)) | |
| { | |
| ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht | |
| - ps_dec->u4_fmt_conv_cur_row; | |
| ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), | |
| ps_dec->u4_fmt_conv_cur_row, | |
| ps_dec->u4_fmt_conv_num_rows); | |
| ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; | |
| } | |
| ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op)); | |
| } | |
| if(ps_dec->i4_decode_header == 1 && (ps_dec->i4_header_decoded & 1) == 1) | |
| { | |
| ps_dec_op->u4_progressive_frame_flag = 1; | |
| if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid))) | |
| { | |
| if((0 == ps_dec->ps_sps->u1_frame_mbs_only_flag) | |
| && (0 == ps_dec->ps_sps->u1_mb_aff_flag)) | |
| ps_dec_op->u4_progressive_frame_flag = 0; | |
| } | |
| } | |
| if((TOP_FIELD_ONLY | BOT_FIELD_ONLY) == ps_dec->u1_top_bottom_decoded) | |
| { | |
| ps_dec->u1_top_bottom_decoded = 0; | |
| } | |
| /*--------------------------------------------------------------------*/ | |
| /* Do End of Pic processing. */ | |
| /* Should be called only if frame was decoded in previous process call*/ | |
| /*--------------------------------------------------------------------*/ | |
| if(ps_dec->u4_pic_buf_got == 1) | |
| { | |
| if(1 == ps_dec->u1_last_pic_not_decoded) | |
| { | |
| ret = ih264d_end_of_pic_dispbuf_mgr(ps_dec); | |
| if(ret != OK) | |
| return ret; | |
| ret = ih264d_end_of_pic(ps_dec); | |
| if(ret != OK) | |
| return ret; | |
| } | |
| else | |
| { | |
| ret = ih264d_end_of_pic(ps_dec); | |
| if(ret != OK) | |
| return ret; | |
| } | |
| } | |
| if(ps_dec->u1_enable_mb_info && ps_dec->u4_output_present) | |
| { | |
| UWORD32 disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id; | |
| if(ps_h264d_dec_ip->pu1_8x8_blk_qp_map) | |
| { | |
| ps_h264d_dec_op->pu1_8x8_blk_qp_map = ps_h264d_dec_ip->pu1_8x8_blk_qp_map; | |
| ps_h264d_dec_op->u4_8x8_blk_qp_map_size = ps_dec->u4_total_mbs << 2; | |
| ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_qp_map, | |
| ps_dec->as_buf_id_info_map[disp_buf_id].pu1_qp_map, | |
| ps_dec->u4_total_mbs << 2); | |
| } | |
| if(ps_h264d_dec_ip->pu1_8x8_blk_type_map) | |
| { | |
| ps_h264d_dec_op->pu1_8x8_blk_type_map = ps_h264d_dec_ip->pu1_8x8_blk_type_map; | |
| ps_h264d_dec_op->u4_8x8_blk_type_map_size = ps_dec->u4_total_mbs << 2; | |
| ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_type_map, | |
| ps_dec->as_buf_id_info_map[disp_buf_id].pu1_mb_type_map, | |
| ps_dec->u4_total_mbs << 2); | |
| } | |
| } | |
| /*Data memory barrier instruction,so that yuv write by the library is complete*/ | |
| DATA_SYNC(); | |
| H264_DEC_DEBUG_PRINT("The num bytes consumed: %d\n", | |
| ps_dec_op->u4_num_bytes_consumed); | |
| return api_ret_value; | |
| } | |
| WORD32 ih264d_get_version(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| char version_string[MAXVERSION_STRLEN + 1]; | |
| UWORD32 version_string_len; | |
| ivd_ctl_getversioninfo_ip_t *ps_ip; | |
| ivd_ctl_getversioninfo_op_t *ps_op; | |
| ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip; | |
| ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op; | |
| UNUSED(dec_hdl); | |
| ps_op->u4_error_code = IV_SUCCESS; | |
| VERSION(version_string, CODEC_NAME, CODEC_RELEASE_TYPE, CODEC_RELEASE_VER, | |
| CODEC_VENDOR); | |
| if((WORD32)ps_ip->u4_version_buffer_size <= 0) | |
| { | |
| ps_op->u4_error_code = IH264D_VERS_BUF_INSUFFICIENT; | |
| return (IV_FAIL); | |
| } | |
| version_string_len = strnlen(version_string, MAXVERSION_STRLEN) + 1; | |
| if(ps_ip->u4_version_buffer_size >= version_string_len) //(WORD32)sizeof(sizeof(version_string))) | |
| { | |
| memcpy(ps_ip->pv_version_buffer, version_string, version_string_len); | |
| ps_op->u4_error_code = IV_SUCCESS; | |
| } | |
| else | |
| { | |
| ps_op->u4_error_code = IH264D_VERS_BUF_INSUFFICIENT; | |
| return IV_FAIL; | |
| } | |
| return (IV_SUCCESS); | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_get_display_frame */ | |
| /* */ | |
| /* Description : */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_get_display_frame(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| UNUSED(dec_hdl); | |
| UNUSED(pv_api_ip); | |
| UNUSED(pv_api_op); | |
| // This function is no longer needed, output is returned in the process() | |
| return IV_FAIL; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_set_display_frame */ | |
| /* */ | |
| /* Description : */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_set_display_frame(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| UWORD32 u4_disp_buf_size[3], u4_num_disp_bufs; | |
| ivd_set_display_frame_ip_t *dec_disp_ip; | |
| ivd_set_display_frame_op_t *dec_disp_op; | |
| UWORD32 i; | |
| dec_struct_t * ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); | |
| dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip; | |
| dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op; | |
| dec_disp_op->u4_error_code = 0; | |
| ps_dec->u4_num_disp_bufs = 0; | |
| if(ps_dec->u4_share_disp_buf) | |
| { | |
| UWORD32 u4_num_bufs = dec_disp_ip->num_disp_bufs; | |
| u4_num_bufs = MIN(u4_num_bufs, MAX_DISP_BUFS_NEW); | |
| ps_dec->u4_num_disp_bufs = u4_num_bufs; | |
| /* Get the number and sizes of the first buffer. Compare this with the | |
| * rest to make sure all the buffers are of the same size. | |
| */ | |
| u4_num_disp_bufs = dec_disp_ip->s_disp_buffer[0].u4_num_bufs; | |
| u4_disp_buf_size[0] = | |
| dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[0]; | |
| u4_disp_buf_size[1] = | |
| dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1]; | |
| u4_disp_buf_size[2] = | |
| dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[2]; | |
| for(i = 0; i < u4_num_bufs; i++) | |
| { | |
| if(dec_disp_ip->s_disp_buffer[i].u4_num_bufs != u4_num_disp_bufs) | |
| { | |
| return IV_FAIL; | |
| } | |
| if((dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0] | |
| != u4_disp_buf_size[0]) | |
| || (dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1] | |
| != u4_disp_buf_size[1]) | |
| || (dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2] | |
| != u4_disp_buf_size[2])) | |
| { | |
| return IV_FAIL; | |
| } | |
| ps_dec->disp_bufs[i].u4_num_bufs = | |
| dec_disp_ip->s_disp_buffer[i].u4_num_bufs; | |
| ps_dec->disp_bufs[i].buf[0] = | |
| dec_disp_ip->s_disp_buffer[i].pu1_bufs[0]; | |
| ps_dec->disp_bufs[i].buf[1] = | |
| dec_disp_ip->s_disp_buffer[i].pu1_bufs[1]; | |
| ps_dec->disp_bufs[i].buf[2] = | |
| dec_disp_ip->s_disp_buffer[i].pu1_bufs[2]; | |
| ps_dec->disp_bufs[i].u4_bufsize[0] = | |
| dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0]; | |
| ps_dec->disp_bufs[i].u4_bufsize[1] = | |
| dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1]; | |
| ps_dec->disp_bufs[i].u4_bufsize[2] = | |
| dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2]; | |
| } | |
| } | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_set_flush_mode */ | |
| /* */ | |
| /* Description : */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Globals : <Does it use any global variables?> */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_set_flush_mode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| dec_struct_t * ps_dec; | |
| ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t*)pv_api_op; | |
| ps_ctl_op->u4_error_code = 0; | |
| ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); | |
| UNUSED(pv_api_ip); | |
| /* ! */ | |
| /* Signal flush frame control call */ | |
| ps_dec->u1_flushfrm = 1; | |
| if(ps_dec->u1_init_dec_flag == 1) | |
| { | |
| ih264d_release_pics_in_dpb((void *)ps_dec, ps_dec->u1_pic_bufs); | |
| ih264d_release_display_bufs(ps_dec); | |
| } | |
| ps_ctl_op->u4_error_code = 0; | |
| /* Ignore dangling fields during flush */ | |
| ps_dec->u1_top_bottom_decoded = 0; | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_get_status */ | |
| /* */ | |
| /* Description : */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Globals : <Does it use any global variables?> */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_get_status(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| UWORD32 i; | |
| dec_struct_t * ps_dec; | |
| UWORD32 pic_wd, pic_ht; | |
| ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t*)pv_api_op; | |
| UNUSED(pv_api_ip); | |
| ps_ctl_op->u4_error_code = 0; | |
| ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); | |
| if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid))) | |
| { | |
| ps_ctl_op->u4_pic_ht = ps_dec->u2_disp_height; | |
| ps_ctl_op->u4_pic_wd = ps_dec->u2_disp_width; | |
| if(0 == ps_dec->u4_share_disp_buf) | |
| { | |
| pic_wd = ps_dec->u2_disp_width; | |
| pic_ht = ps_dec->u2_disp_height; | |
| } | |
| else | |
| { | |
| pic_wd = ps_dec->u2_frm_wd_y; | |
| pic_ht = ps_dec->u2_frm_ht_y; | |
| } | |
| } | |
| else | |
| { | |
| pic_wd = 0; | |
| pic_ht = 0; | |
| ps_ctl_op->u4_pic_ht = pic_wd; | |
| ps_ctl_op->u4_pic_wd = pic_ht; | |
| if(1 == ps_dec->u4_share_disp_buf) | |
| { | |
| pic_wd += (PAD_LEN_Y_H << 1); | |
| pic_ht += (PAD_LEN_Y_V << 2); | |
| } | |
| } | |
| if(ps_dec->u4_app_disp_width > pic_wd) | |
| pic_wd = ps_dec->u4_app_disp_width; | |
| if(0 == ps_dec->u4_share_disp_buf) | |
| ps_ctl_op->u4_num_disp_bufs = 1; | |
| else | |
| { | |
| if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid))) | |
| { | |
| if((ps_dec->ps_cur_sps->u1_vui_parameters_present_flag == 1) && | |
| (1 == ps_dec->ps_cur_sps->s_vui.u1_bitstream_restriction_flag)) | |
| { | |
| ps_ctl_op->u4_num_disp_bufs = | |
| ps_dec->ps_cur_sps->s_vui.u4_num_reorder_frames + 1; | |
| } | |
| else | |
| { | |
| /*if VUI is not present assume maximum possible refrence frames for the level, | |
| * as max reorder frames*/ | |
| ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size(ps_dec->ps_cur_sps); | |
| } | |
| ps_ctl_op->u4_num_disp_bufs += | |
| ps_dec->ps_cur_sps->u1_num_ref_frames + 1; | |
| } | |
| else | |
| { | |
| ps_ctl_op->u4_num_disp_bufs = 32; | |
| } | |
| ps_ctl_op->u4_num_disp_bufs = MAX( | |
| ps_ctl_op->u4_num_disp_bufs, 6); | |
| ps_ctl_op->u4_num_disp_bufs = MIN( | |
| ps_ctl_op->u4_num_disp_bufs, 32); | |
| } | |
| ps_ctl_op->u4_error_code = ps_dec->i4_error_code; | |
| ps_ctl_op->u4_frame_rate = 0; //make it proper | |
| ps_ctl_op->u4_bit_rate = 0; //make it proper | |
| ps_ctl_op->e_content_type = ps_dec->i4_content_type; | |
| ps_ctl_op->e_output_chroma_format = ps_dec->u1_chroma_format; | |
| ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS; | |
| if(ps_dec->u1_chroma_format == IV_YUV_420P) | |
| { | |
| ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420; | |
| } | |
| else if(ps_dec->u1_chroma_format == IV_YUV_422ILE) | |
| { | |
| ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; | |
| } | |
| else if(ps_dec->u1_chroma_format == IV_RGB_565) | |
| { | |
| ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; | |
| } | |
| else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) | |
| || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU)) | |
| { | |
| ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; | |
| } | |
| else | |
| { | |
| //Invalid chroma format; Error code may be updated, verify in testing if needed | |
| ps_ctl_op->u4_error_code = ERROR_FEATURE_UNAVAIL; | |
| return IV_FAIL; | |
| } | |
| for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++) | |
| { | |
| ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2); | |
| } | |
| /*!*/ | |
| if(ps_dec->u1_chroma_format == IV_YUV_420P) | |
| { | |
| ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht); | |
| ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht) | |
| >> 2; | |
| ps_ctl_op->u4_min_out_buf_size[2] = (pic_wd * pic_ht) | |
| >> 2; | |
| } | |
| else if(ps_dec->u1_chroma_format == IV_YUV_422ILE) | |
| { | |
| ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht) | |
| * 2; | |
| ps_ctl_op->u4_min_out_buf_size[1] = | |
| ps_ctl_op->u4_min_out_buf_size[2] = 0; | |
| } | |
| else if(ps_dec->u1_chroma_format == IV_RGB_565) | |
| { | |
| ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht) | |
| * 2; | |
| ps_ctl_op->u4_min_out_buf_size[1] = | |
| ps_ctl_op->u4_min_out_buf_size[2] = 0; | |
| } | |
| else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) | |
| || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU)) | |
| { | |
| ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht); | |
| ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht) | |
| >> 1; | |
| ps_ctl_op->u4_min_out_buf_size[2] = 0; | |
| } | |
| ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs; | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_get_buf_info */ | |
| /* */ | |
| /* Description : */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Globals : <Does it use any global variables?> */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_get_buf_info(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| dec_struct_t * ps_dec; | |
| UWORD8 i = 0; // Default for 420P format | |
| UWORD16 pic_wd, pic_ht; | |
| ivd_ctl_getbufinfo_op_t *ps_ctl_op = | |
| (ivd_ctl_getbufinfo_op_t*)pv_api_op; | |
| UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS]; | |
| UNUSED(pv_api_ip); | |
| ps_ctl_op->u4_error_code = 0; | |
| ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); | |
| ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS; | |
| ps_ctl_op->u4_num_disp_bufs = 1; | |
| pic_wd = 0; | |
| pic_ht = 0; | |
| if(ps_dec->i4_header_decoded == 3) | |
| { | |
| if(0 == ps_dec->u4_share_disp_buf) | |
| { | |
| pic_wd = ps_dec->u2_disp_width; | |
| pic_ht = ps_dec->u2_disp_height; | |
| } | |
| else | |
| { | |
| pic_wd = ps_dec->u2_frm_wd_y; | |
| pic_ht = ps_dec->u2_frm_ht_y; | |
| } | |
| } | |
| for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++) | |
| { | |
| ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2); | |
| } | |
| if((WORD32)ps_dec->u4_app_disp_width > pic_wd) | |
| pic_wd = ps_dec->u4_app_disp_width; | |
| if(0 == ps_dec->u4_share_disp_buf) | |
| ps_ctl_op->u4_num_disp_bufs = 1; | |
| else | |
| { | |
| if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid))) | |
| { | |
| if((ps_dec->ps_cur_sps->u1_vui_parameters_present_flag == 1) && | |
| (1 == ps_dec->ps_cur_sps->s_vui.u1_bitstream_restriction_flag)) | |
| { | |
| ps_ctl_op->u4_num_disp_bufs = | |
| ps_dec->ps_cur_sps->s_vui.u4_num_reorder_frames + 1; | |
| } | |
| else | |
| { | |
| /*if VUI is not present assume maximum possible refrence frames for the level, | |
| * as max reorder frames*/ | |
| ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size(ps_dec->ps_cur_sps); | |
| } | |
| ps_ctl_op->u4_num_disp_bufs += | |
| ps_dec->ps_cur_sps->u1_num_ref_frames + 1; | |
| } | |
| else | |
| { | |
| ps_ctl_op->u4_num_disp_bufs = 32; | |
| } | |
| ps_ctl_op->u4_num_disp_bufs = MAX( | |
| ps_ctl_op->u4_num_disp_bufs, 6); | |
| ps_ctl_op->u4_num_disp_bufs = MIN( | |
| ps_ctl_op->u4_num_disp_bufs, 32); | |
| } | |
| ps_ctl_op->u4_min_num_out_bufs = ih264d_get_outbuf_size( | |
| pic_wd, pic_ht, ps_dec->u1_chroma_format, | |
| &au4_min_out_buf_size[0]); | |
| for(i = 0; i < ps_ctl_op->u4_min_num_out_bufs; i++) | |
| { | |
| ps_ctl_op->u4_min_out_buf_size[i] = au4_min_out_buf_size[i]; | |
| } | |
| ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs; | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_set_params */ | |
| /* */ | |
| /* Description : */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| dec_struct_t * ps_dec; | |
| WORD32 ret = IV_SUCCESS; | |
| ih264d_ctl_set_config_ip_t *ps_h264d_ctl_ip = | |
| (ih264d_ctl_set_config_ip_t *)pv_api_ip; | |
| ih264d_ctl_set_config_op_t *ps_h264d_ctl_op = | |
| (ih264d_ctl_set_config_op_t *)pv_api_op; | |
| ivd_ctl_set_config_ip_t *ps_ctl_ip = | |
| &ps_h264d_ctl_ip->s_ivd_ctl_set_config_ip_t; | |
| ivd_ctl_set_config_op_t *ps_ctl_op = | |
| &ps_h264d_ctl_op->s_ivd_ctl_set_config_op_t; | |
| ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); | |
| ps_dec->u4_skip_frm_mask = 0; | |
| ps_ctl_op->u4_error_code = 0; | |
| if(ps_ctl_ip->e_frm_skip_mode != IVD_SKIP_NONE) | |
| { | |
| ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); | |
| ret = IV_FAIL; | |
| } | |
| if(ps_ctl_ip->u4_disp_wd >= ps_dec->u2_disp_width) | |
| { | |
| ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd; | |
| } | |
| else if(0 == ps_dec->i4_header_decoded) | |
| { | |
| ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd; | |
| } | |
| else if(ps_ctl_ip->u4_disp_wd == 0) | |
| { | |
| ps_dec->u4_app_disp_width = 0; | |
| } | |
| else | |
| { | |
| /* | |
| * Set the display width to zero. This will ensure that the wrong value we had stored (0xFFFFFFFF) | |
| * does not propogate. | |
| */ | |
| ps_dec->u4_app_disp_width = 0; | |
| ps_ctl_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); | |
| ps_ctl_op->u4_error_code |= ERROR_DISP_WIDTH_INVALID; | |
| ret = IV_FAIL; | |
| } | |
| if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_FRAME) | |
| ps_dec->i4_decode_header = 0; | |
| else if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_HEADER) | |
| ps_dec->i4_decode_header = 1; | |
| else | |
| { | |
| ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); | |
| ps_dec->i4_decode_header = 1; | |
| ret = IV_FAIL; | |
| } | |
| ps_dec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; | |
| if((ps_ctl_ip->e_frm_out_mode != IVD_DECODE_FRAME_OUT) && | |
| (ps_ctl_ip->e_frm_out_mode != IVD_DISPLAY_FRAME_OUT)) | |
| { | |
| ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); | |
| ret = IV_FAIL; | |
| } | |
| ps_dec->e_frm_out_mode = ps_ctl_ip->e_frm_out_mode; | |
| return ret; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_set_default_params */ | |
| /* */ | |
| /* Description : */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 08 08 2011 100421 Copied from set_params */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_set_default_params(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| dec_struct_t * ps_dec; | |
| WORD32 ret = IV_SUCCESS; | |
| ivd_ctl_set_config_op_t *ps_ctl_op = | |
| (ivd_ctl_set_config_op_t *)pv_api_op; | |
| ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); | |
| UNUSED(pv_api_ip); | |
| { | |
| ps_dec->u4_app_disp_width = 0; | |
| ps_dec->u4_skip_frm_mask = 0; | |
| ps_dec->i4_decode_header = 1; | |
| ps_ctl_op->u4_error_code = 0; | |
| } | |
| return ret; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_reset */ | |
| /* */ | |
| /* Description : */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Globals : <Does it use any global variables?> */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_delete(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| dec_struct_t *ps_dec; | |
| ih264d_delete_ip_t *ps_ip = (ih264d_delete_ip_t *)pv_api_ip; | |
| ih264d_delete_op_t *ps_op = (ih264d_delete_op_t *)pv_api_op; | |
| ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); | |
| UNUSED(ps_ip); | |
| ps_op->s_ivd_delete_op_t.u4_error_code = 0; | |
| ih264d_free_dynamic_bufs(ps_dec); | |
| ih264d_free_static_bufs(dec_hdl); | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_reset */ | |
| /* */ | |
| /* Description : */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Globals : <Does it use any global variables?> */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_reset(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| dec_struct_t * ps_dec; | |
| ivd_ctl_reset_op_t *ps_ctl_op = (ivd_ctl_reset_op_t *)pv_api_op; | |
| UNUSED(pv_api_ip); | |
| ps_ctl_op->u4_error_code = 0; | |
| ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); | |
| if(ps_dec != NULL) | |
| { | |
| ih264d_join_threads(ps_dec); | |
| ih264d_init_decoder(ps_dec); | |
| } | |
| else | |
| { | |
| H264_DEC_DEBUG_PRINT( | |
| "\nReset called without Initializing the decoder\n"); | |
| ps_ctl_op->u4_error_code = ERROR_INIT_NOT_DONE; | |
| } | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_ctl */ | |
| /* */ | |
| /* Description : */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_ctl(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| ivd_ctl_set_config_ip_t *ps_ctl_ip; | |
| ivd_ctl_set_config_op_t *ps_ctl_op; | |
| WORD32 ret = IV_SUCCESS; | |
| UWORD32 subcommand; | |
| dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; | |
| if(ps_dec->init_done != 1) | |
| { | |
| //Return proper Error Code | |
| return IV_FAIL; | |
| } | |
| ps_ctl_ip = (ivd_ctl_set_config_ip_t*)pv_api_ip; | |
| ps_ctl_op = (ivd_ctl_set_config_op_t*)pv_api_op; | |
| ps_ctl_op->u4_error_code = 0; | |
| subcommand = ps_ctl_ip->e_sub_cmd; | |
| switch(subcommand) | |
| { | |
| case IVD_CMD_CTL_GETPARAMS: | |
| ret = ih264d_get_status(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_CTL_SETPARAMS: | |
| ret = ih264d_set_params(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_CTL_RESET: | |
| ret = ih264d_reset(dec_hdl, (void *)pv_api_ip, (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_CTL_SETDEFAULT: | |
| ret = ih264d_set_default_params(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_CTL_FLUSH: | |
| ret = ih264d_set_flush_mode(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_CTL_GETBUFINFO: | |
| ret = ih264d_get_buf_info(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_CTL_GETVERSION: | |
| ret = ih264d_get_version(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IH264D_CMD_CTL_DEGRADE: | |
| ret = ih264d_set_degrade(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IH264D_CMD_CTL_SET_NUM_CORES: | |
| ret = ih264d_set_num_cores(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS: | |
| ret = ih264d_get_frame_dimensions(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IH264D_CMD_CTL_GET_VUI_PARAMS: | |
| ret = ih264d_get_vui_params(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS: | |
| ret = ih264d_get_sei_mdcv_params(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IH264D_CMD_CTL_GET_SEI_CLL_PARAMS: | |
| ret = ih264d_get_sei_cll_params(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IH264D_CMD_CTL_GET_SEI_AVE_PARAMS: | |
| ret = ih264d_get_sei_ave_params(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IH264D_CMD_CTL_GET_SEI_CCV_PARAMS: | |
| ret = ih264d_get_sei_ccv_params(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IH264D_CMD_CTL_GET_SEI_SII_PARAMS: | |
| ret = ih264d_get_sei_sii_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op); | |
| break; | |
| case IH264D_CMD_CTL_GET_SEI_FGC_PARAMS: | |
| ret = ih264d_get_sei_fgc_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op); | |
| break; | |
| case IH264D_CMD_CTL_SET_PROCESSOR: | |
| ret = ih264d_set_processor(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| default: | |
| H264_DEC_DEBUG_PRINT("\ndo nothing\n") | |
| ; | |
| break; | |
| } | |
| return ret; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_rel_display_frame */ | |
| /* */ | |
| /* Description : */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_rel_display_frame(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| ivd_rel_display_frame_ip_t *ps_rel_ip; | |
| ivd_rel_display_frame_op_t *ps_rel_op; | |
| UWORD32 buf_released = 0; | |
| UWORD32 u4_ts = 0; | |
| dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; | |
| ps_rel_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip; | |
| ps_rel_op = (ivd_rel_display_frame_op_t *)pv_api_op; | |
| ps_rel_op->u4_error_code = 0; | |
| u4_ts = ps_rel_ip->u4_disp_buf_id; | |
| if(0 == ps_dec->u4_share_disp_buf) | |
| { | |
| ps_dec->u4_disp_buf_mapping[u4_ts] = 0; | |
| ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 0; | |
| return IV_SUCCESS; | |
| } | |
| if(ps_dec->pv_pic_buf_mgr != NULL) | |
| { | |
| if(1 == ps_dec->u4_disp_buf_mapping[u4_ts]) | |
| { | |
| ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, | |
| ps_rel_ip->u4_disp_buf_id, | |
| BUF_MGR_IO); | |
| ps_dec->u4_disp_buf_mapping[u4_ts] = 0; | |
| buf_released = 1; | |
| } | |
| } | |
| if((1 == ps_dec->u4_share_disp_buf) && (0 == buf_released)) | |
| ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 1; | |
| return IV_SUCCESS; | |
| } | |
| /** | |
| ******************************************************************************* | |
| * | |
| * @brief | |
| * Sets degrade params | |
| * | |
| * @par Description: | |
| * Sets degrade params. | |
| * Refer to ih264d_ctl_degrade_ip_t definition for details | |
| * | |
| * @param[in] ps_codec_obj | |
| * Pointer to codec object at API level | |
| * | |
| * @param[in] pv_api_ip | |
| * Pointer to input argument structure | |
| * | |
| * @param[out] pv_api_op | |
| * Pointer to output argument structure | |
| * | |
| * @returns Status | |
| * | |
| * @remarks | |
| * | |
| * | |
| ******************************************************************************* | |
| */ | |
| WORD32 ih264d_set_degrade(iv_obj_t *ps_codec_obj, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| ih264d_ctl_degrade_ip_t *ps_ip; | |
| ih264d_ctl_degrade_op_t *ps_op; | |
| dec_struct_t *ps_codec = (dec_struct_t *)ps_codec_obj->pv_codec_handle; | |
| ps_ip = (ih264d_ctl_degrade_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_degrade_op_t *)pv_api_op; | |
| ps_codec->i4_degrade_type = ps_ip->i4_degrade_type; | |
| ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval; | |
| ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics; | |
| ps_op->u4_error_code = 0; | |
| ps_codec->i4_degrade_pic_cnt = 0; | |
| return IV_SUCCESS; | |
| } | |
| WORD32 ih264d_get_frame_dimensions(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| ih264d_ctl_get_frame_dimensions_ip_t *ps_ip; | |
| ih264d_ctl_get_frame_dimensions_op_t *ps_op; | |
| dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; | |
| UWORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset; | |
| ps_ip = (ih264d_ctl_get_frame_dimensions_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_get_frame_dimensions_op_t *)pv_api_op; | |
| UNUSED(ps_ip); | |
| if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid))) | |
| { | |
| disp_wd = ps_dec->u2_disp_width; | |
| disp_ht = ps_dec->u2_disp_height; | |
| if(0 == ps_dec->u4_share_disp_buf) | |
| { | |
| buffer_wd = disp_wd; | |
| buffer_ht = disp_ht; | |
| } | |
| else | |
| { | |
| buffer_wd = ps_dec->u2_frm_wd_y; | |
| buffer_ht = ps_dec->u2_frm_ht_y; | |
| } | |
| } | |
| else | |
| { | |
| disp_wd = 0; | |
| disp_ht = 0; | |
| if(0 == ps_dec->u4_share_disp_buf) | |
| { | |
| buffer_wd = disp_wd; | |
| buffer_ht = disp_ht; | |
| } | |
| else | |
| { | |
| buffer_wd = ALIGN16(disp_wd) + (PAD_LEN_Y_H << 1); | |
| buffer_ht = ALIGN16(disp_ht) + (PAD_LEN_Y_V << 2); | |
| } | |
| } | |
| if(ps_dec->u4_app_disp_width > buffer_wd) | |
| buffer_wd = ps_dec->u4_app_disp_width; | |
| if(0 == ps_dec->u4_share_disp_buf) | |
| { | |
| x_offset = 0; | |
| y_offset = 0; | |
| } | |
| else | |
| { | |
| y_offset = (PAD_LEN_Y_V << 1); | |
| x_offset = PAD_LEN_Y_H; | |
| if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid)) | |
| && (0 != ps_dec->u2_crop_offset_y)) | |
| { | |
| y_offset += ps_dec->u2_crop_offset_y / ps_dec->u2_frm_wd_y; | |
| x_offset += ps_dec->u2_crop_offset_y % ps_dec->u2_frm_wd_y; | |
| } | |
| } | |
| ps_op->u4_disp_wd[0] = disp_wd; | |
| ps_op->u4_disp_ht[0] = disp_ht; | |
| ps_op->u4_buffer_wd[0] = buffer_wd; | |
| ps_op->u4_buffer_ht[0] = buffer_ht; | |
| ps_op->u4_x_offset[0] = x_offset; | |
| ps_op->u4_y_offset[0] = y_offset; | |
| ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1) | |
| >> 1); | |
| ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1) | |
| >> 1); | |
| ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0] | |
| >> 1); | |
| ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0] | |
| >> 1); | |
| ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = | |
| (ps_op->u4_x_offset[0] >> 1); | |
| ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] = | |
| (ps_op->u4_y_offset[0] >> 1); | |
| if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) | |
| || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU)) | |
| { | |
| ps_op->u4_disp_wd[2] = 0; | |
| ps_op->u4_disp_ht[2] = 0; | |
| ps_op->u4_buffer_wd[2] = 0; | |
| ps_op->u4_buffer_ht[2] = 0; | |
| ps_op->u4_x_offset[2] = 0; | |
| ps_op->u4_y_offset[2] = 0; | |
| ps_op->u4_disp_wd[1] <<= 1; | |
| ps_op->u4_buffer_wd[1] <<= 1; | |
| ps_op->u4_x_offset[1] <<= 1; | |
| } | |
| return IV_SUCCESS; | |
| } | |
| WORD32 ih264d_get_vui_params(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| ih264d_ctl_get_vui_params_ip_t *ps_ip; | |
| ih264d_ctl_get_vui_params_op_t *ps_op; | |
| dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; | |
| dec_seq_params_t *ps_sps; | |
| vui_t *ps_vui; | |
| WORD32 i; | |
| UWORD32 u4_size; | |
| ps_ip = (ih264d_ctl_get_vui_params_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_get_vui_params_op_t *)pv_api_op; | |
| UNUSED(ps_ip); | |
| u4_size = ps_op->u4_size; | |
| memset(ps_op, 0, sizeof(ih264d_ctl_get_vui_params_op_t)); | |
| ps_op->u4_size = u4_size; | |
| if(NULL == ps_dec->ps_cur_sps) | |
| { | |
| ps_op->u4_error_code = ERROR_VUI_PARAMS_NOT_FOUND; | |
| return IV_FAIL; | |
| } | |
| ps_sps = ps_dec->ps_cur_sps; | |
| if((0 == ps_sps->u1_is_valid) | |
| || (0 == ps_sps->u1_vui_parameters_present_flag)) | |
| { | |
| ps_op->u4_error_code = ERROR_VUI_PARAMS_NOT_FOUND; | |
| return IV_FAIL; | |
| } | |
| ps_vui = &ps_sps->s_vui; | |
| ps_op->u1_aspect_ratio_idc = ps_vui->u1_aspect_ratio_idc; | |
| ps_op->u2_sar_width = ps_vui->u2_sar_width; | |
| ps_op->u2_sar_height = ps_vui->u2_sar_height; | |
| ps_op->u1_overscan_appropriate_flag = ps_vui->u1_overscan_appropriate_flag; | |
| ps_op->u1_video_format = ps_vui->u1_video_format; | |
| ps_op->u1_video_full_range_flag = ps_vui->u1_video_full_range_flag; | |
| ps_op->u1_colour_primaries = ps_vui->u1_colour_primaries; | |
| ps_op->u1_tfr_chars = ps_vui->u1_tfr_chars; | |
| ps_op->u1_matrix_coeffs = ps_vui->u1_matrix_coeffs; | |
| ps_op->u1_cr_top_field = ps_vui->u1_cr_top_field; | |
| ps_op->u1_cr_bottom_field = ps_vui->u1_cr_bottom_field; | |
| ps_op->u4_num_units_in_tick = ps_vui->u4_num_units_in_tick; | |
| ps_op->u4_time_scale = ps_vui->u4_time_scale; | |
| ps_op->u1_fixed_frame_rate_flag = ps_vui->u1_fixed_frame_rate_flag; | |
| ps_op->u1_nal_hrd_params_present = ps_vui->u1_nal_hrd_params_present; | |
| ps_op->u1_vcl_hrd_params_present = ps_vui->u1_vcl_hrd_params_present; | |
| ps_op->u1_low_delay_hrd_flag = ps_vui->u1_low_delay_hrd_flag; | |
| ps_op->u1_pic_struct_present_flag = ps_vui->u1_pic_struct_present_flag; | |
| ps_op->u1_bitstream_restriction_flag = ps_vui->u1_bitstream_restriction_flag; | |
| ps_op->u1_mv_over_pic_boundaries_flag = ps_vui->u1_mv_over_pic_boundaries_flag; | |
| ps_op->u4_max_bytes_per_pic_denom = ps_vui->u4_max_bytes_per_pic_denom; | |
| ps_op->u4_max_bits_per_mb_denom = ps_vui->u4_max_bits_per_mb_denom; | |
| ps_op->u4_log2_max_mv_length_horz = ps_vui->u4_log2_max_mv_length_horz; | |
| ps_op->u4_log2_max_mv_length_vert = ps_vui->u4_log2_max_mv_length_vert; | |
| ps_op->u4_num_reorder_frames = ps_vui->u4_num_reorder_frames; | |
| ps_op->u4_max_dec_frame_buffering = ps_vui->u4_max_dec_frame_buffering; | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_get_sei_mdcv_params */ | |
| /* */ | |
| /* Description : This function populates SEI mdcv message in */ | |
| /* output structure */ | |
| /* Inputs : iv_obj_t decoder handle */ | |
| /* : pv_api_ip pointer to input structure */ | |
| /* : pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : returns 0; 1 with error code when MDCV is not present */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_get_sei_mdcv_params(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| ih264d_ctl_get_sei_mdcv_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_mdcv_params_op_t *ps_op; | |
| dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; | |
| sei_mdcv_params_t *ps_sei_mdcv; | |
| WORD32 i4_count; | |
| ps_ip = (ih264d_ctl_get_sei_mdcv_params_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_mdcv_params_op_t *)pv_api_op; | |
| UNUSED(ps_ip); | |
| if(0 == ps_dec->s_sei_export.u1_sei_mdcv_params_present_flag) | |
| { | |
| ps_op->u4_error_code = ERROR_SEI_MDCV_PARAMS_NOT_FOUND; | |
| return IV_FAIL; | |
| } | |
| ps_sei_mdcv = &ps_dec->s_sei_export.s_sei_mdcv_params; | |
| for(i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; i4_count++) | |
| { | |
| ps_op->au2_display_primaries_x[i4_count] = ps_sei_mdcv->au2_display_primaries_x[i4_count]; | |
| ps_op->au2_display_primaries_y[i4_count] = ps_sei_mdcv->au2_display_primaries_y[i4_count]; | |
| } | |
| ps_op->u2_white_point_x = ps_sei_mdcv->u2_white_point_x; | |
| ps_op->u2_white_point_y = ps_sei_mdcv->u2_white_point_y; | |
| ps_op->u4_max_display_mastering_luminance = ps_sei_mdcv->u4_max_display_mastering_luminance; | |
| ps_op->u4_min_display_mastering_luminance = ps_sei_mdcv->u4_min_display_mastering_luminance; | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_get_sei_cll_params */ | |
| /* */ | |
| /* Description : This function populates SEI cll message in */ | |
| /* output structure */ | |
| /* Inputs : iv_obj_t decoder handle */ | |
| /* : pv_api_ip pointer to input structure */ | |
| /* : pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : returns 0; 1 with error code when CLL is not present */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_get_sei_cll_params(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| ih264d_ctl_get_sei_cll_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_cll_params_op_t *ps_op; | |
| dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; | |
| sei_cll_params_t *ps_sei_cll; | |
| ps_ip = (ih264d_ctl_get_sei_cll_params_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_cll_params_op_t *)pv_api_op; | |
| UNUSED(ps_ip); | |
| if(0 == ps_dec->s_sei_export.u1_sei_cll_params_present_flag) | |
| { | |
| ps_op->u4_error_code = ERROR_SEI_CLL_PARAMS_NOT_FOUND; | |
| return IV_FAIL; | |
| } | |
| ps_sei_cll = &ps_dec->s_sei_export.s_sei_cll_params; | |
| ps_op->u2_max_content_light_level = ps_sei_cll->u2_max_content_light_level; | |
| ps_op->u2_max_pic_average_light_level = ps_sei_cll->u2_max_pic_average_light_level; | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_get_sei_ave_params */ | |
| /* */ | |
| /* Description : This function populates SEI ave message in */ | |
| /* output structure */ | |
| /* Inputs : iv_obj_t decoder handle */ | |
| /* : pv_api_ip pointer to input structure */ | |
| /* : pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : returns 0; 1 with error code when AVE is not present */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_get_sei_ave_params(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| ih264d_ctl_get_sei_ave_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_ave_params_op_t *ps_op; | |
| dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; | |
| sei_ave_params_t *ps_sei_ave; | |
| ps_ip = (ih264d_ctl_get_sei_ave_params_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_ave_params_op_t *)pv_api_op; | |
| UNUSED(ps_ip); | |
| if(0 == ps_dec->s_sei_export.u1_sei_ave_params_present_flag) | |
| { | |
| ps_op->u4_error_code = ERROR_SEI_AVE_PARAMS_NOT_FOUND; | |
| return IV_FAIL; | |
| } | |
| ps_sei_ave = &ps_dec->s_sei_export.s_sei_ave_params; | |
| ps_op->u4_ambient_illuminance = ps_sei_ave->u4_ambient_illuminance; | |
| ps_op->u2_ambient_light_x = ps_sei_ave->u2_ambient_light_x; | |
| ps_op->u2_ambient_light_y = ps_sei_ave->u2_ambient_light_y; | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_get_sei_ccv_params */ | |
| /* */ | |
| /* Description : This function populates SEI mdcv message in */ | |
| /* output structure */ | |
| /* Inputs : iv_obj_t decoder handle */ | |
| /* : pv_api_ip pointer to input structure */ | |
| /* : pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : returns 0; 1 with error code when CCV is not present */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_get_sei_ccv_params(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| ih264d_ctl_get_sei_ccv_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_ccv_params_op_t *ps_op; | |
| dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; | |
| sei_ccv_params_t *ps_sei_ccv; | |
| WORD32 i4_count; | |
| ps_ip = (ih264d_ctl_get_sei_ccv_params_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_ccv_params_op_t *)pv_api_op; | |
| UNUSED(ps_ip); | |
| if(0 == ps_dec->s_sei_export.u1_sei_ccv_params_present_flag) | |
| { | |
| ps_op->u4_error_code = ERROR_SEI_CCV_PARAMS_NOT_FOUND; | |
| return IV_FAIL; | |
| } | |
| ps_sei_ccv = &ps_dec->s_sei_export.s_sei_ccv_params; | |
| ps_op->u1_ccv_cancel_flag = ps_sei_ccv->u1_ccv_cancel_flag; | |
| if(0 == ps_op->u1_ccv_cancel_flag) | |
| { | |
| ps_op->u1_ccv_persistence_flag = ps_sei_ccv->u1_ccv_persistence_flag; | |
| ps_op->u1_ccv_primaries_present_flag = ps_sei_ccv->u1_ccv_primaries_present_flag; | |
| ps_op->u1_ccv_min_luminance_value_present_flag = | |
| ps_sei_ccv->u1_ccv_min_luminance_value_present_flag; | |
| ps_op->u1_ccv_max_luminance_value_present_flag = | |
| ps_sei_ccv->u1_ccv_max_luminance_value_present_flag; | |
| ps_op->u1_ccv_avg_luminance_value_present_flag = | |
| ps_sei_ccv->u1_ccv_avg_luminance_value_present_flag; | |
| ps_op->u1_ccv_reserved_zero_2bits = ps_sei_ccv->u1_ccv_reserved_zero_2bits; | |
| if(1 == ps_sei_ccv->u1_ccv_primaries_present_flag) | |
| { | |
| for(i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; i4_count++) | |
| { | |
| ps_op->ai4_ccv_primaries_x[i4_count] = ps_sei_ccv->ai4_ccv_primaries_x[i4_count]; | |
| ps_op->ai4_ccv_primaries_y[i4_count] = ps_sei_ccv->ai4_ccv_primaries_y[i4_count]; | |
| } | |
| } | |
| if(1 == ps_sei_ccv->u1_ccv_min_luminance_value_present_flag) | |
| { | |
| ps_op->u4_ccv_min_luminance_value = ps_sei_ccv->u4_ccv_min_luminance_value; | |
| } | |
| if(1 == ps_sei_ccv->u1_ccv_max_luminance_value_present_flag) | |
| { | |
| ps_op->u4_ccv_max_luminance_value = ps_sei_ccv->u4_ccv_max_luminance_value; | |
| } | |
| if(1 == ps_sei_ccv->u1_ccv_avg_luminance_value_present_flag) | |
| { | |
| ps_op->u4_ccv_avg_luminance_value = ps_sei_ccv->u4_ccv_avg_luminance_value; | |
| } | |
| } | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_get_sei_sii_params */ | |
| /* */ | |
| /* Description : This function populates SEI sii message in */ | |
| /* output structure */ | |
| /* Inputs : iv_obj_t decoder handle */ | |
| /* : pv_api_ip pointer to input structure */ | |
| /* : pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : returns 0; 1 with error code when SII is not present */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_get_sei_sii_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| ih264d_ctl_get_sei_sii_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_sii_params_op_t *ps_op; | |
| dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; | |
| sei_sii_params_t *ps_sei_sii; | |
| int i; | |
| ps_ip = (ih264d_ctl_get_sei_sii_params_ip_t *) pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_sii_params_op_t *) pv_api_op; | |
| UNUSED(ps_ip); | |
| if(0 == ps_dec->s_sei_export.u1_sei_sii_params_present_flag) | |
| { | |
| ps_op->u4_error_code = ERROR_SEI_SII_PARAMS_NOT_FOUND; | |
| return IV_FAIL; | |
| } | |
| ps_sei_sii = &ps_dec->s_sei_export.s_sei_sii_params; | |
| if((ps_sei_sii->u4_sii_sub_layer_idx > 0) && | |
| (ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag == 1)) | |
| { | |
| ps_op->u4_error_code = ERROR_INV_SEI_SII_PARAMS; | |
| return IV_FAIL; | |
| } | |
| if((ps_sei_sii->u4_sii_sub_layer_idx > ps_sei_sii->u1_sii_max_sub_layers_minus1) && | |
| (ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag == 0)) | |
| { | |
| ps_op->u4_error_code = ERROR_INV_SEI_SII_PARAMS; | |
| return IV_FAIL; | |
| } | |
| ps_op->u4_sii_sub_layer_idx = ps_sei_sii->u4_sii_sub_layer_idx; | |
| if(0 == ps_op->u4_sii_sub_layer_idx) | |
| { | |
| ps_op->u1_shutter_interval_info_present_flag = | |
| ps_sei_sii->u1_shutter_interval_info_present_flag; | |
| if(1 == ps_sei_sii->u1_shutter_interval_info_present_flag) | |
| { | |
| ps_op->u4_sii_time_scale = ps_sei_sii->u4_sii_time_scale; | |
| ps_op->u1_fixed_shutter_interval_within_cvs_flag = | |
| ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag; | |
| if(1 == ps_sei_sii->u1_fixed_shutter_interval_within_cvs_flag) | |
| { | |
| ps_op->u4_sii_num_units_in_shutter_interval = | |
| ps_sei_sii->u4_sii_num_units_in_shutter_interval; | |
| } | |
| else | |
| { | |
| ps_op->u1_sii_max_sub_layers_minus1 = ps_sei_sii->u1_sii_max_sub_layers_minus1; | |
| for(i = 0; i <= ps_sei_sii->u1_sii_max_sub_layers_minus1; i++) | |
| { | |
| ps_op->au4_sub_layer_num_units_in_shutter_interval[i] = | |
| ps_sei_sii->au4_sub_layer_num_units_in_shutter_interval[i]; | |
| } | |
| } | |
| } | |
| } | |
| return IV_SUCCESS; | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_get_sei_fgc_params */ | |
| /* */ | |
| /* Description : This function populates SEI FGC message in */ | |
| /* output structure */ | |
| /* Inputs : iv_obj_t decoder handle */ | |
| /* : pv_api_ip pointer to input structure */ | |
| /* : pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : returns 0; 1 with error code when FGC is not present */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* */ | |
| /* */ | |
| /*****************************************************************************/ | |
| WORD32 ih264d_get_sei_fgc_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| ih264d_ctl_get_sei_fgc_params_ip_t *ps_ip; | |
| ih264d_ctl_get_sei_fgc_params_op_t *ps_op; | |
| dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; | |
| sei_fgc_params_t *ps_sei_fgc; | |
| WORD32 i4_count; | |
| UWORD32 c, i, j; | |
| ps_ip = (ih264d_ctl_get_sei_fgc_params_ip_t *) pv_api_ip; | |
| ps_op = (ih264d_ctl_get_sei_fgc_params_op_t *) pv_api_op; | |
| UNUSED(ps_ip); | |
| if(0 == ps_dec->s_sei_export.u1_sei_fgc_params_present_flag) | |
| { | |
| ps_op->u4_error_code = ERROR_SEI_FGC_PARAMS_NOT_FOUND; | |
| return IV_FAIL; | |
| } | |
| ps_sei_fgc = &ps_dec->s_sei_export.s_sei_fgc_params; | |
| ps_op->u1_film_grain_characteristics_cancel_flag = | |
| ps_sei_fgc->u1_film_grain_characteristics_cancel_flag; | |
| if(0 == ps_op->u1_film_grain_characteristics_cancel_flag) | |
| { | |
| ps_op->i4_poc = ps_sei_fgc->i4_poc; | |
| ps_op->u4_idr_pic_id = ps_sei_fgc->u4_idr_pic_id; | |
| ps_op->u1_film_grain_model_id = ps_sei_fgc->u1_film_grain_model_id; | |
| ps_op->u1_separate_colour_description_present_flag = | |
| ps_sei_fgc->u1_separate_colour_description_present_flag; | |
| if(ps_op->u1_separate_colour_description_present_flag) | |
| { | |
| ps_op->u1_film_grain_bit_depth_luma_minus8 = | |
| ps_sei_fgc->u1_film_grain_bit_depth_luma_minus8; | |
| ps_op->u1_film_grain_bit_depth_chroma_minus8 = | |
| ps_sei_fgc->u1_film_grain_bit_depth_chroma_minus8; | |
| ps_op->u1_film_grain_full_range_flag = ps_sei_fgc->u1_film_grain_full_range_flag; | |
| ps_op->u1_film_grain_colour_primaries = ps_sei_fgc->u1_film_grain_colour_primaries; | |
| ps_op->u1_film_grain_transfer_characteristics = | |
| ps_sei_fgc->u1_film_grain_transfer_characteristics; | |
| ps_op->u1_film_grain_matrix_coefficients = | |
| ps_sei_fgc->u1_film_grain_matrix_coefficients; | |
| } | |
| ps_op->u1_blending_mode_id = ps_sei_fgc->u1_blending_mode_id; | |
| ps_op->u1_log2_scale_factor = ps_sei_fgc->u1_log2_scale_factor; | |
| for(c = 0; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++) | |
| { | |
| ps_op->au1_comp_model_present_flag[c] = ps_sei_fgc->au1_comp_model_present_flag[c]; | |
| } | |
| for(c = 0; c < SEI_FGC_NUM_COLOUR_COMPONENTS; c++) | |
| { | |
| if(ps_op->au1_comp_model_present_flag[c]) | |
| { | |
| ps_op->au1_num_intensity_intervals_minus1[c] = | |
| ps_sei_fgc->au1_num_intensity_intervals_minus1[c]; | |
| ps_op->au1_num_model_values_minus1[c] = ps_sei_fgc->au1_num_model_values_minus1[c]; | |
| for(i = 0; i <= ps_op->au1_num_intensity_intervals_minus1[c]; i++) | |
| { | |
| ps_op->au1_intensity_interval_lower_bound[c][i] = | |
| ps_sei_fgc->au1_intensity_interval_lower_bound[c][i]; | |
| ps_op->au1_intensity_interval_upper_bound[c][i] = | |
| ps_sei_fgc->au1_intensity_interval_upper_bound[c][i]; | |
| for(j = 0; j <= ps_op->au1_num_model_values_minus1[c]; j++) | |
| { | |
| ps_op->ai4_comp_model_value[c][i][j] = | |
| ps_sei_fgc->ai4_comp_model_value[c][i][j]; | |
| } | |
| } | |
| } | |
| } | |
| ps_op->u4_film_grain_characteristics_repetition_period = | |
| ps_sei_fgc->u4_film_grain_characteristics_repetition_period; | |
| } | |
| return IV_SUCCESS; | |
| } | |
| WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) | |
| { | |
| ih264d_ctl_set_num_cores_ip_t *ps_ip; | |
| ih264d_ctl_set_num_cores_op_t *ps_op; | |
| dec_struct_t *ps_dec = dec_hdl->pv_codec_handle; | |
| ps_ip = (ih264d_ctl_set_num_cores_ip_t *)pv_api_ip; | |
| ps_op = (ih264d_ctl_set_num_cores_op_t *)pv_api_op; | |
| ps_op->u4_error_code = 0; | |
| ps_dec->u4_num_cores = ps_ip->u4_num_cores; | |
| if(ps_dec->u4_num_cores == 1) | |
| { | |
| ps_dec->u1_separate_parse = 0; | |
| } | |
| else | |
| { | |
| ps_dec->u1_separate_parse = 1; | |
| } | |
| /*using only upto three threads currently*/ | |
| if(ps_dec->u4_num_cores > 3) | |
| ps_dec->u4_num_cores = 3; | |
| return IV_SUCCESS; | |
| } | |
| void ih264d_fill_output_struct_from_context(dec_struct_t *ps_dec, | |
| ivd_video_decode_op_t *ps_dec_op) | |
| { | |
| if((ps_dec_op->u4_error_code & 0xff) | |
| != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED) | |
| { | |
| ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width; | |
| ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height; | |
| } | |
| ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth; | |
| ps_dec_op->i4_display_index = ps_dec->i4_display_index; | |
| ps_dec_op->e_pic_type = ps_dec->i4_frametype; | |
| ps_dec_op->u4_new_seq = 0; | |
| ps_dec_op->u4_output_present = ps_dec->u4_output_present; | |
| ps_dec_op->u4_progressive_frame_flag = | |
| ps_dec->s_disp_op.u4_progressive_frame_flag; | |
| ps_dec_op->u4_is_ref_flag = 1; | |
| if(ps_dec_op->u4_frame_decoded_flag) | |
| { | |
| if(ps_dec->ps_cur_slice->u1_nal_ref_idc == 0) | |
| ps_dec_op->u4_is_ref_flag = 0; | |
| } | |
| ps_dec_op->e_output_format = ps_dec->s_disp_op.e_output_format; | |
| ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf; | |
| ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type; | |
| ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts; | |
| ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id; | |
| ih264d_export_sei_params(&ps_dec_op->s_sei_decode_op, ps_dec); | |
| } | |
| /*****************************************************************************/ | |
| /* */ | |
| /* Function Name : ih264d_api_function */ | |
| /* */ | |
| /* Description : */ | |
| /* */ | |
| /* Inputs :iv_obj_t decoder handle */ | |
| /* :pv_api_ip pointer to input structure */ | |
| /* :pv_api_op pointer to output structure */ | |
| /* Outputs : */ | |
| /* Returns : void */ | |
| /* */ | |
| /* Issues : none */ | |
| /* */ | |
| /* Revision History: */ | |
| /* */ | |
| /* DD MM YYYY Author(s) Changes (Describe the changes made) */ | |
| /* 22 10 2008 100356 Draft */ | |
| /* */ | |
| /*****************************************************************************/ | |
| IV_API_CALL_STATUS_T ih264d_api_function(iv_obj_t *dec_hdl, | |
| void *pv_api_ip, | |
| void *pv_api_op) | |
| { | |
| UWORD32 command; | |
| UWORD32 *pu2_ptr_cmd; | |
| UWORD32 u4_api_ret; | |
| IV_API_CALL_STATUS_T e_status; | |
| e_status = api_check_struct_sanity(dec_hdl, pv_api_ip, pv_api_op); | |
| if(e_status != IV_SUCCESS) | |
| { | |
| UWORD32 *ptr_err; | |
| ptr_err = (UWORD32 *)pv_api_op; | |
| UNUSED(ptr_err); | |
| H264_DEC_DEBUG_PRINT("error code = %d\n", *(ptr_err + 1)); | |
| return IV_FAIL; | |
| } | |
| pu2_ptr_cmd = (UWORD32 *)pv_api_ip; | |
| pu2_ptr_cmd++; | |
| command = *pu2_ptr_cmd; | |
| // H264_DEC_DEBUG_PRINT("inside lib = %d\n",command); | |
| switch(command) | |
| { | |
| case IVD_CMD_CREATE: | |
| u4_api_ret = ih264d_create(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_DELETE: | |
| u4_api_ret = ih264d_delete(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_VIDEO_DECODE: | |
| u4_api_ret = ih264d_video_decode(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_GET_DISPLAY_FRAME: | |
| u4_api_ret = ih264d_get_display_frame(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_SET_DISPLAY_FRAME: | |
| u4_api_ret = ih264d_set_display_frame(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_REL_DISPLAY_FRAME: | |
| u4_api_ret = ih264d_rel_display_frame(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| case IVD_CMD_VIDEO_CTL: | |
| u4_api_ret = ih264d_ctl(dec_hdl, (void *)pv_api_ip, | |
| (void *)pv_api_op); | |
| break; | |
| default: | |
| u4_api_ret = IV_FAIL; | |
| break; | |
| } | |
| return u4_api_ret; | |
| } |