| /****************************************************************************** |
| * |
| * 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_get_num_rec */ |
| /* ih264d_init_decoder */ |
| /* ih264d_init_video_decoder */ |
| /* ih264d_fill_num_mem_rec */ |
| /* ih264d_clr */ |
| /* 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 "04.00" |
| #define CODEC_VENDOR "ITTIAM" |
| #define MAXVERSION_STRLEN 511 |
| #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__) |
| |
| #define MAX_NAL_UNIT_SIZE MAX((H264_MAX_FRAME_HEIGHT * H264_MAX_FRAME_HEIGHT),MIN_NALUNIT_SIZE) |
| #define MIN_NALUNIT_SIZE 200000 |
| |
| |
| #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 MIN_IN_BUF_SIZE (2*1024*1024) // Currently, i4_size set to 500kb, CHECK LATER |
| |
| #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_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); |
| |
| 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 IV_CMD_GET_NUM_MEM_REC: |
| case IV_CMD_FILL_NUM_MEM_REC: |
| break; |
| case IV_CMD_INIT: |
| if(ps_handle == NULL) |
| { |
| *(pu4_api_op + 1) |= 1 << 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; |
| H264_DEC_DEBUG_PRINT( |
| "Sizes do not match. Expected: %d, Got: %d", |
| sizeof(iv_obj_t), ps_handle->u4_size); |
| return IV_FAIL; |
| } |
| 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 IV_CMD_RETRIEVE_MEMREC: |
| 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 IV_CMD_GET_NUM_MEM_REC: |
| { |
| ih264d_num_mem_rec_ip_t *ps_ip = |
| (ih264d_num_mem_rec_ip_t *)pv_api_ip; |
| ih264d_num_mem_rec_op_t *ps_op = |
| (ih264d_num_mem_rec_op_t *)pv_api_op; |
| ps_op->s_ivd_num_mem_rec_op_t.u4_error_code = 0; |
| |
| if(ps_ip->s_ivd_num_mem_rec_ip_t.u4_size |
| != sizeof(ih264d_num_mem_rec_ip_t)) |
| { |
| ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if(ps_op->s_ivd_num_mem_rec_op_t.u4_size |
| != sizeof(ih264d_num_mem_rec_op_t)) |
| { |
| ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| } |
| break; |
| case IV_CMD_FILL_NUM_MEM_REC: |
| { |
| ih264d_fill_mem_rec_ip_t *ps_ip = |
| (ih264d_fill_mem_rec_ip_t *)pv_api_ip; |
| ih264d_fill_mem_rec_op_t *ps_op = |
| (ih264d_fill_mem_rec_op_t *)pv_api_op; |
| iv_mem_rec_t *ps_mem_rec; |
| WORD32 max_wd = ps_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd; |
| WORD32 max_ht = ps_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht; |
| |
| max_wd = ALIGN16(max_wd); |
| max_ht = ALIGN32(max_ht); |
| |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code = 0; |
| |
| if((ps_ip->s_ivd_fill_mem_rec_ip_t.u4_size |
| > sizeof(ih264d_fill_mem_rec_ip_t)) |
| || (ps_ip->s_ivd_fill_mem_rec_ip_t.u4_size |
| < sizeof(iv_fill_mem_rec_ip_t))) |
| { |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if((ps_op->s_ivd_fill_mem_rec_op_t.u4_size |
| != sizeof(ih264d_fill_mem_rec_op_t)) |
| && (ps_op->s_ivd_fill_mem_rec_op_t.u4_size |
| != sizeof(iv_fill_mem_rec_op_t))) |
| { |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if(max_wd < H264_MIN_FRAME_WIDTH) |
| { |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= |
| IVD_REQUESTED_WIDTH_NOT_SUPPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if(max_wd > H264_MAX_FRAME_WIDTH) |
| { |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= |
| IVD_REQUESTED_WIDTH_NOT_SUPPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if(max_ht < H264_MIN_FRAME_HEIGHT) |
| { |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= |
| IVD_REQUESTED_HEIGHT_NOT_SUPPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if((max_ht * max_wd) |
| > (H264_MAX_FRAME_HEIGHT * H264_MAX_FRAME_WIDTH)) |
| |
| { |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= |
| IVD_REQUESTED_HEIGHT_NOT_SUPPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if(NULL == ps_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location) |
| { |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= |
| IVD_NUM_REC_NOT_SUFFICIENT; |
| return (IV_FAIL); |
| } |
| |
| /* check memrecords sizes are correct */ |
| ps_mem_rec = ps_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location; |
| for(i = 0; i < MEM_REC_CNT; i++) |
| { |
| if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) |
| { |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= |
| IVD_MEM_REC_STRUCT_SIZE_INCORRECT; |
| return IV_FAIL; |
| } |
| } |
| } |
| break; |
| |
| case IV_CMD_INIT: |
| { |
| ih264d_init_ip_t *ps_ip = (ih264d_init_ip_t *)pv_api_ip; |
| ih264d_init_op_t *ps_op = (ih264d_init_op_t *)pv_api_op; |
| iv_mem_rec_t *ps_mem_rec; |
| WORD32 max_wd = ps_ip->s_ivd_init_ip_t.u4_frm_max_wd; |
| WORD32 max_ht = ps_ip->s_ivd_init_ip_t.u4_frm_max_ht; |
| |
| max_wd = ALIGN16(max_wd); |
| max_ht = ALIGN32(max_ht); |
| |
| ps_op->s_ivd_init_op_t.u4_error_code = 0; |
| |
| if((ps_ip->s_ivd_init_ip_t.u4_size > sizeof(ih264d_init_ip_t)) |
| || (ps_ip->s_ivd_init_ip_t.u4_size |
| < sizeof(ivd_init_ip_t))) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; |
| H264_DEC_DEBUG_PRINT("\n"); |
| return (IV_FAIL); |
| } |
| |
| if((ps_op->s_ivd_init_op_t.u4_size != sizeof(ih264d_init_op_t)) |
| && (ps_op->s_ivd_init_op_t.u4_size |
| != sizeof(ivd_init_op_t))) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; |
| H264_DEC_DEBUG_PRINT("\n"); |
| return (IV_FAIL); |
| } |
| |
| if(ps_ip->s_ivd_init_ip_t.u4_num_mem_rec != MEM_REC_CNT) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_NOT_SUFFICIENT; |
| H264_DEC_DEBUG_PRINT("\n"); |
| return (IV_FAIL); |
| } |
| |
| if(max_wd < H264_MIN_FRAME_WIDTH) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_WIDTH_NOT_SUPPPORTED; |
| H264_DEC_DEBUG_PRINT("\n"); |
| return (IV_FAIL); |
| } |
| |
| if(max_wd > H264_MAX_FRAME_WIDTH) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_WIDTH_NOT_SUPPPORTED; |
| H264_DEC_DEBUG_PRINT("\n"); |
| return (IV_FAIL); |
| } |
| |
| if(max_ht < H264_MIN_FRAME_HEIGHT) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED; |
| H264_DEC_DEBUG_PRINT("\n"); |
| return (IV_FAIL); |
| } |
| |
| if((max_ht * max_wd) |
| > (H264_MAX_FRAME_HEIGHT * H264_MAX_FRAME_WIDTH)) |
| |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED; |
| H264_DEC_DEBUG_PRINT("\n"); |
| return (IV_FAIL); |
| } |
| |
| if(NULL == ps_ip->s_ivd_init_ip_t.pv_mem_rec_location) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_NUM_REC_NOT_SUFFICIENT; |
| H264_DEC_DEBUG_PRINT("\n"); |
| return (IV_FAIL); |
| } |
| |
| if((ps_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P) |
| && (ps_ip->s_ivd_init_ip_t.e_output_format |
| != IV_YUV_422ILE) |
| && (ps_ip->s_ivd_init_ip_t.e_output_format |
| != IV_RGB_565) |
| && (ps_ip->s_ivd_init_ip_t.e_output_format |
| != IV_YUV_420SP_UV) |
| && (ps_ip->s_ivd_init_ip_t.e_output_format |
| != IV_YUV_420SP_VU)) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED; |
| H264_DEC_DEBUG_PRINT("\n"); |
| return (IV_FAIL); |
| } |
| |
| /* verify number of mem records */ |
| if(ps_ip->s_ivd_init_ip_t.u4_num_mem_rec < MEM_REC_CNT) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_MEM_REC_NOT_SUFFICIENT; |
| H264_DEC_DEBUG_PRINT("\n"); |
| return IV_FAIL; |
| } |
| |
| ps_mem_rec = ps_ip->s_ivd_init_ip_t.pv_mem_rec_location; |
| /* check memrecords sizes are correct */ |
| for(i = 0; i < ps_ip->s_ivd_init_ip_t.u4_num_mem_rec; i++) |
| { |
| if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_MEM_REC_STRUCT_SIZE_INCORRECT; |
| H264_DEC_DEBUG_PRINT("i: %d\n", i); |
| return IV_FAIL; |
| } |
| /* check memrecords pointers are not NULL */ |
| |
| if(ps_mem_rec[i].pv_base == NULL) |
| { |
| |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_MEM_REC_BASE_NULL; |
| H264_DEC_DEBUG_PRINT("i: %d\n", i); |
| return IV_FAIL; |
| |
| } |
| |
| } |
| |
| /* verify memtabs for overlapping regions */ |
| { |
| void *start[MEM_REC_CNT]; |
| void *end[MEM_REC_CNT]; |
| |
| start[0] = (void *)(ps_mem_rec[0].pv_base); |
| end[0] = (void *)((UWORD8 *)ps_mem_rec[0].pv_base |
| + ps_mem_rec[0].u4_mem_size - 1); |
| for(i = 1; i < MEM_REC_CNT; i++) |
| { |
| /* This array is populated to check memtab overlapp */ |
| start[i] = (void *)(ps_mem_rec[i].pv_base); |
| end[i] = (void *)((UWORD8 *)ps_mem_rec[i].pv_base |
| + ps_mem_rec[i].u4_mem_size - 1); |
| |
| for(j = 0; j < i; j++) |
| { |
| if((start[i] >= start[j]) && (start[i] <= end[j])) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_MEM_REC_OVERLAP_ERR; |
| H264_DEC_DEBUG_PRINT("i: %d, j: %d\n", i, j); |
| return IV_FAIL; |
| } |
| |
| if((end[i] >= start[j]) && (end[i] <= end[j])) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_MEM_REC_OVERLAP_ERR; |
| H264_DEC_DEBUG_PRINT("i: %d, j: %d\n", i, j); |
| return IV_FAIL; |
| } |
| |
| if((start[i] < start[j]) && (end[i] > end[j])) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_MEM_REC_OVERLAP_ERR; |
| H264_DEC_DEBUG_PRINT("i: %d, j: %d\n", i, j); |
| return IV_FAIL; |
| } |
| } |
| |
| } |
| } |
| |
| { |
| iv_mem_rec_t mem_rec_ittiam_api[MEM_REC_CNT]; |
| ih264d_fill_mem_rec_ip_t s_fill_mem_rec_ip; |
| ih264d_fill_mem_rec_op_t s_fill_mem_rec_op; |
| IV_API_CALL_STATUS_T e_status; |
| |
| UWORD32 i; |
| s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = |
| IV_CMD_FILL_NUM_MEM_REC; |
| s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = |
| mem_rec_ittiam_api; |
| s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = |
| max_wd; |
| s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = |
| max_ht; |
| |
| if(ps_ip->s_ivd_init_ip_t.u4_size |
| > offsetof(ih264d_init_ip_t, i4_level)) |
| { |
| s_fill_mem_rec_ip.i4_level = ps_ip->i4_level; |
| } |
| else |
| { |
| s_fill_mem_rec_ip.i4_level = H264_LEVEL_3_1; |
| } |
| |
| if(ps_ip->s_ivd_init_ip_t.u4_size |
| > offsetof(ih264d_init_ip_t, u4_num_ref_frames)) |
| { |
| s_fill_mem_rec_ip.u4_num_ref_frames = |
| ps_ip->u4_num_ref_frames; |
| } |
| else |
| { |
| s_fill_mem_rec_ip.u4_num_ref_frames = |
| (H264_MAX_REF_PICS + 1); |
| } |
| |
| if(ps_ip->s_ivd_init_ip_t.u4_size |
| > offsetof(ih264d_init_ip_t, |
| u4_num_reorder_frames)) |
| { |
| s_fill_mem_rec_ip.u4_num_reorder_frames = |
| ps_ip->u4_num_reorder_frames; |
| } |
| else |
| { |
| s_fill_mem_rec_ip.u4_num_reorder_frames = (H264_MAX_REF_PICS |
| + 1); |
| } |
| |
| if(ps_ip->s_ivd_init_ip_t.u4_size |
| > offsetof(ih264d_init_ip_t, |
| u4_num_extra_disp_buf)) |
| { |
| s_fill_mem_rec_ip.u4_num_extra_disp_buf = |
| ps_ip->u4_num_extra_disp_buf; |
| } |
| else |
| { |
| s_fill_mem_rec_ip.u4_num_extra_disp_buf = 0; |
| } |
| |
| if(ps_ip->s_ivd_init_ip_t.u4_size |
| > offsetof(ih264d_init_ip_t, u4_share_disp_buf)) |
| { |
| #ifndef LOGO_EN |
| s_fill_mem_rec_ip.u4_share_disp_buf = |
| ps_ip->u4_share_disp_buf; |
| #else |
| s_fill_mem_rec_ip.u4_share_disp_buf = 0; |
| #endif |
| } |
| else |
| { |
| s_fill_mem_rec_ip.u4_share_disp_buf = 0; |
| } |
| |
| s_fill_mem_rec_ip.e_output_format = |
| ps_ip->s_ivd_init_ip_t.e_output_format; |
| |
| if((s_fill_mem_rec_ip.e_output_format != IV_YUV_420P) |
| && (s_fill_mem_rec_ip.e_output_format |
| != IV_YUV_420SP_UV) |
| && (s_fill_mem_rec_ip.e_output_format |
| != IV_YUV_420SP_VU)) |
| { |
| s_fill_mem_rec_ip.u4_share_disp_buf = 0; |
| } |
| |
| s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_size = |
| sizeof(ih264d_fill_mem_rec_ip_t); |
| s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size = |
| sizeof(ih264d_fill_mem_rec_op_t); |
| |
| for(i = 0; i < MEM_REC_CNT; i++) |
| mem_rec_ittiam_api[i].u4_size = sizeof(iv_mem_rec_t); |
| |
| e_status = ih264d_api_function(NULL, |
| (void *)&s_fill_mem_rec_ip, |
| (void *)&s_fill_mem_rec_op); |
| if(IV_FAIL == e_status) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code = |
| s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_error_code; |
| H264_DEC_DEBUG_PRINT("Fail\n"); |
| return (IV_FAIL); |
| } |
| |
| for(i = 0; i < MEM_REC_CNT; i++) |
| { |
| if(ps_mem_rec[i].u4_mem_size |
| < mem_rec_ittiam_api[i].u4_mem_size) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_MEM_REC_INSUFFICIENT_SIZE; |
| H264_DEC_DEBUG_PRINT("i: %d \n", i); |
| return IV_FAIL; |
| } |
| if(ps_mem_rec[i].u4_mem_alignment |
| != mem_rec_ittiam_api[i].u4_mem_alignment) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_MEM_REC_ALIGNMENT_ERR; |
| H264_DEC_DEBUG_PRINT("i: %d \n", i); |
| return IV_FAIL; |
| } |
| if(ps_mem_rec[i].e_mem_type |
| != mem_rec_ittiam_api[i].e_mem_type) |
| { |
| UWORD32 check = IV_SUCCESS; |
| UWORD32 diff = mem_rec_ittiam_api[i].e_mem_type |
| - ps_mem_rec[i].e_mem_type; |
| |
| if((ps_mem_rec[i].e_mem_type |
| <= IV_EXTERNAL_CACHEABLE_SCRATCH_MEM) |
| && (mem_rec_ittiam_api[i].e_mem_type |
| >= IV_INTERNAL_NONCACHEABLE_PERSISTENT_MEM)) |
| { |
| check = IV_FAIL; |
| } |
| if(3 != MOD(mem_rec_ittiam_api[i].e_mem_type, 4)) |
| { |
| /* |
| * It is not IV_EXTERNAL_NONCACHEABLE_PERSISTENT_MEM or IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM |
| */ |
| if((diff < 1) || (diff > 3)) |
| { |
| // Difference between 1 and 3 is okay for all cases other than the two filtered |
| // with the MOD condition above |
| check = IV_FAIL; |
| } |
| } |
| else |
| { |
| if(diff == 1) |
| { |
| /* |
| * This particular case is when codec asked for External Persistent, but got |
| * Internal Scratch. |
| */ |
| check = IV_FAIL; |
| } |
| if((diff != 2) && (diff != 3)) |
| { |
| check = IV_FAIL; |
| } |
| } |
| if(check == IV_FAIL) |
| { |
| ps_op->s_ivd_init_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_init_op_t.u4_error_code |= |
| IVD_INIT_DEC_MEM_REC_INCORRECT_TYPE; |
| H264_DEC_DEBUG_PRINT("i: %d \n", i); |
| 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 != 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 != 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); |
| } |
| |
| } |
| break; |
| |
| case IV_CMD_RETRIEVE_MEMREC: |
| { |
| ih264d_retrieve_mem_rec_ip_t *ps_ip = |
| (ih264d_retrieve_mem_rec_ip_t *)pv_api_ip; |
| ih264d_retrieve_mem_rec_op_t *ps_op = |
| (ih264d_retrieve_mem_rec_op_t *)pv_api_op; |
| iv_mem_rec_t *ps_mem_rec; |
| |
| ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code = 0; |
| |
| if(ps_ip->s_ivd_retrieve_mem_rec_ip_t.u4_size |
| != sizeof(ih264d_retrieve_mem_rec_ip_t)) |
| { |
| ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= |
| IVD_IP_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| if(ps_op->s_ivd_retrieve_mem_rec_op_t.u4_size |
| != sizeof(ih264d_retrieve_mem_rec_op_t)) |
| { |
| ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= |
| IVD_OP_API_STRUCT_SIZE_INCORRECT; |
| return (IV_FAIL); |
| } |
| |
| ps_mem_rec = ps_ip->s_ivd_retrieve_mem_rec_ip_t.pv_mem_rec_location; |
| /* check memrecords sizes are correct */ |
| for(i = 0; i < MEM_REC_CNT; i++) |
| { |
| if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) |
| { |
| ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1 |
| << IVD_UNSUPPORTEDPARAM; |
| ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= |
| IVD_MEM_REC_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_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; |
| } |
| /*****************************************************************************/ |
| /* */ |
| /* Function Name : ih264d_get_num_rec */ |
| /* */ |
| /* Description : returns number of mem records required */ |
| /* */ |
| /* Inputs : pv_api_ip input api structure */ |
| /* : pv_api_op output api structure */ |
| /* Outputs : */ |
| /* 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_num_rec(void *pv_api_ip, void *pv_api_op) |
| { |
| iv_num_mem_rec_ip_t *ps_mem_q_ip; |
| iv_num_mem_rec_op_t *ps_mem_q_op; |
| ps_mem_q_ip = (iv_num_mem_rec_ip_t *)pv_api_ip; |
| ps_mem_q_op = (iv_num_mem_rec_op_t *)pv_api_op; |
| UNUSED(ps_mem_q_ip); |
| ps_mem_q_op->u4_num_mem_rec = MEM_REC_CNT; |
| |
| 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(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(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); |
| |
| |
| |
| /* Set pic_parameter_set_id to -1 */ |
| |
| |
| |
| 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; |
| |
| ps_dec->i4_app_skip_mode = IVD_SKIP_NONE; |
| ps_dec->i4_dec_skip_mode = IVD_SKIP_NONE; |
| |
| 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_first_pb_nal_in_pic = 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 = -1; |
| 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; |
| |
| /* 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 = -1; |
| ps_dec->i4_frametype = -1; |
| ps_dec->i4_content_type = -1; |
| |
| 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); |
| |
| #if VERT_SCALE_UP_AND_422 |
| ps_dec->u1_vert_up_scale_flag = 1; |
| #else |
| ps_dec->u1_vert_up_scale_flag = 0; |
| #endif |
| |
| 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->init_done = 1; |
| ps_dec->process_called = 1; |
| |
| ps_dec->pv_pic_buf_mgr = NULL; |
| ps_dec->pv_mv_buf_mgr = NULL; |
| } |
| |
| /************************************************************************** |
| * \if Function name : ih264d_init_video_decoder \endif |
| * |
| * \brief |
| * Wrapper for the decoder init |
| * |
| * \param p_NALBufAPI: Pointer to NAL Buffer API. |
| * \param ih264d_dec_mem_manager :Pointer to the function that will be called by decoder |
| * for memory allocation and freeing. |
| * |
| * \return |
| * pointer to the decparams |
| * |
| ************************************************************************** |
| */ |
| |
| WORD32 ih264d_init_video_decoder(iv_obj_t *dec_hdl, |
| ih264d_init_ip_t *ps_init_ip, |
| ih264d_init_op_t *ps_init_op) |
| { |
| dec_struct_t * ps_dec; |
| iv_mem_rec_t *memtab; |
| UWORD8 *pu1_extra_mem_base,*pu1_mem_base; |
| |
| memtab = ps_init_ip->s_ivd_init_ip_t.pv_mem_rec_location; |
| |
| dec_hdl->pv_codec_handle = memtab[MEM_REC_CODEC].pv_base; |
| ps_dec = dec_hdl->pv_codec_handle; |
| |
| memset(ps_dec, 0, sizeof(dec_struct_t)); |
| |
| if(ps_init_ip->s_ivd_init_ip_t.u4_size |
| > offsetof(ih264d_init_ip_t, i4_level)) |
| { |
| ps_dec->u4_level_at_init = ps_init_ip->i4_level; |
| } |
| else |
| { |
| ps_dec->u4_level_at_init = H264_LEVEL_3_1; |
| } |
| |
| if(ps_init_ip->s_ivd_init_ip_t.u4_size |
| > offsetof(ih264d_init_ip_t, u4_num_ref_frames)) |
| { |
| ps_dec->u4_num_ref_frames_at_init = ps_init_ip->u4_num_ref_frames; |
| } |
| else |
| { |
| ps_dec->u4_num_ref_frames_at_init = H264_MAX_REF_PICS; |
| } |
| |
| if(ps_init_ip->s_ivd_init_ip_t.u4_size |
| > offsetof(ih264d_init_ip_t, u4_num_reorder_frames)) |
| { |
| ps_dec->u4_num_reorder_frames_at_init = |
| ps_init_ip->u4_num_reorder_frames; |
| } |
| else |
| { |
| ps_dec->u4_num_reorder_frames_at_init = H264_MAX_REF_PICS; |
| } |
| |
| if(ps_init_ip->s_ivd_init_ip_t.u4_size |
| > offsetof(ih264d_init_ip_t, u4_num_extra_disp_buf)) |
| { |
| ps_dec->u4_num_extra_disp_bufs_at_init = |
| ps_init_ip->u4_num_extra_disp_buf; |
| } |
| else |
| { |
| ps_dec->u4_num_extra_disp_bufs_at_init = 0; |
| } |
| |
| if(ps_init_ip->s_ivd_init_ip_t.u4_size |
| > offsetof(ih264d_init_ip_t, u4_share_disp_buf)) |
| { |
| #ifndef LOGO_EN |
| ps_dec->u4_share_disp_buf = ps_init_ip->u4_share_disp_buf; |
| #else |
| ps_dec->u4_share_disp_buf = 0; |
| #endif |
| } |
| else |
| { |
| ps_dec->u4_share_disp_buf = 0; |
| } |
| |
| if((ps_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P) |
| && (ps_init_ip->s_ivd_init_ip_t.e_output_format |
| != IV_YUV_420SP_UV) |
| && (ps_init_ip->s_ivd_init_ip_t.e_output_format |
| != IV_YUV_420SP_VU)) |
| { |
| ps_dec->u4_share_disp_buf = 0; |
| } |
| |
| if((ps_dec->u4_level_at_init < MIN_LEVEL_SUPPORTED) |
| || (ps_dec->u4_level_at_init > MAX_LEVEL_SUPPORTED)) |
| { |
| ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_LEVEL_UNSUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if(ps_dec->u4_num_ref_frames_at_init > H264_MAX_REF_PICS) |
| { |
| ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_NUM_REF; |
| ps_dec->u4_num_ref_frames_at_init = H264_MAX_REF_PICS; |
| } |
| |
| if(ps_dec->u4_num_reorder_frames_at_init > H264_MAX_REF_PICS) |
| { |
| ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_NUM_REF; |
| ps_dec->u4_num_reorder_frames_at_init = H264_MAX_REF_PICS; |
| } |
| |
| if(ps_dec->u4_num_extra_disp_bufs_at_init > H264_MAX_REF_PICS) |
| { |
| ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_NUM_REF; |
| ps_dec->u4_num_extra_disp_bufs_at_init = 0; |
| } |
| |
| if(0 == ps_dec->u4_share_disp_buf) |
| ps_dec->u4_num_extra_disp_bufs_at_init = 0; |
| |
| ps_dec->u4_num_disp_bufs_requested = 1; |
| |
| ps_dec->u4_width_at_init = ps_init_ip->s_ivd_init_ip_t.u4_frm_max_wd; |
| ps_dec->u4_height_at_init = ps_init_ip->s_ivd_init_ip_t.u4_frm_max_ht; |
| |
| ps_dec->u4_width_at_init = ALIGN16(ps_dec->u4_width_at_init); |
| ps_dec->u4_height_at_init = ALIGN32(ps_dec->u4_height_at_init); |
| |
| ps_dec->pv_dec_thread_handle = memtab[MEM_REC_THREAD_HANDLE].pv_base; |
| |
| pu1_mem_base = memtab[MEM_REC_THREAD_HANDLE].pv_base; |
| ps_dec->pv_bs_deblk_thread_handle = pu1_mem_base |
| + ithread_get_handle_size(); |
| |
| ps_dec->u4_extra_mem_used = 0; |
| |
| pu1_extra_mem_base = memtab[MEM_REC_EXTRA_MEM].pv_base; |
| |
| ps_dec->ps_dec_err_status = (dec_err_status_t *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used); |
| ps_dec->u4_extra_mem_used += (((sizeof(dec_err_status_t) + 127) >> 7) << 7); |
| |
| ps_dec->ps_mem_tab = memtab[MEM_REC_BACKUP].pv_base; |
| |
| memcpy(ps_dec->ps_mem_tab, memtab, sizeof(iv_mem_rec_t) * MEM_REC_CNT); |
| |
| ps_dec->ps_pps = memtab[MEM_REC_PPS].pv_base; |
| |
| ps_dec->ps_sps = memtab[MEM_REC_SPS].pv_base; |
| |
| ps_dec->ps_sei = (sei *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used); |
| ps_dec->u4_extra_mem_used += sizeof(sei); |
| |
| ps_dec->ps_dpb_mgr = memtab[MEM_REC_DPB_MGR].pv_base; |
| |
| ps_dec->ps_dpb_cmds = (dpb_commands_t *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used); |
| ps_dec->u4_extra_mem_used += sizeof(dpb_commands_t); |
| |
| ps_dec->ps_bitstrm = (dec_bit_stream_t *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used); |
| ps_dec->u4_extra_mem_used += sizeof(dec_bit_stream_t); |
| |
| ps_dec->ps_cur_slice =(dec_slice_params_t *) (pu1_extra_mem_base + ps_dec->u4_extra_mem_used); |
| ps_dec->u4_extra_mem_used += sizeof(dec_slice_params_t); |
| |
| ps_dec->pv_scratch_sps_pps = (void *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used); |
| |
| |
| ps_dec->u4_extra_mem_used += MAX(sizeof(dec_seq_params_t), |
| sizeof(dec_pic_params_t)); |
| ps_dec->ps_pred_pkd = memtab[MEM_REC_PRED_INFO_PKD].pv_base; |
| |
| |
| ps_dec->ps_dpb_mgr->pv_codec_handle = ps_dec; |
| |
| ps_dec->pv_dec_out = (void *)ps_init_op; |
| ps_dec->pv_dec_in = (void *)ps_init_ip; |
| |
| ps_dec->u1_chroma_format = |
| (UWORD8)(ps_init_ip->s_ivd_init_ip_t.e_output_format); |
| |
| |
| |
| ih264d_init_decoder(ps_dec); |
| |
| return (IV_SUCCESS); |
| |
| } |
| |
| |
| /*****************************************************************************/ |
| /* */ |
| /* Function Name : ih264d_fill_num_mem_rec */ |
| /* */ |
| /* Description : fills memory records */ |
| /* */ |
| /* Inputs : pv_api_ip input api structure */ |
| /* : pv_api_op output api 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_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op) |
| { |
| |
| ih264d_fill_mem_rec_ip_t *ps_mem_q_ip; |
| ih264d_fill_mem_rec_op_t *ps_mem_q_op; |
| WORD32 level; |
| UWORD32 num_reorder_frames; |
| UWORD32 num_ref_frames; |
| UWORD32 num_extra_disp_bufs; |
| UWORD32 u4_dpb_size_num_frames; |
| iv_mem_rec_t *memTab; |
| |
| UWORD32 chroma_format, u4_share_disp_buf; |
| UWORD32 u4_total_num_mbs; |
| UWORD32 luma_width, luma_width_in_mbs; |
| UWORD32 luma_height, luma_height_in_mbs; |
| UWORD32 max_dpb_size; |
| |
| ps_mem_q_ip = (ih264d_fill_mem_rec_ip_t *)pv_api_ip; |
| ps_mem_q_op = (ih264d_fill_mem_rec_op_t *)pv_api_op; |
| |
| if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size |
| > offsetof(ih264d_fill_mem_rec_ip_t, i4_level)) |
| { |
| level = ps_mem_q_ip->i4_level; |
| } |
| else |
| { |
| level = H264_LEVEL_3_1; |
| } |
| |
| if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size |
| > offsetof(ih264d_fill_mem_rec_ip_t, u4_num_reorder_frames)) |
| { |
| num_reorder_frames = ps_mem_q_ip->u4_num_reorder_frames; |
| } |
| else |
| { |
| num_reorder_frames = H264_MAX_REF_PICS; |
| } |
| |
| if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size |
| > offsetof(ih264d_fill_mem_rec_ip_t, u4_num_ref_frames)) |
| { |
| num_ref_frames = ps_mem_q_ip->u4_num_ref_frames; |
| } |
| else |
| { |
| num_ref_frames = H264_MAX_REF_PICS; |
| } |
| |
| if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size |
| > offsetof(ih264d_fill_mem_rec_ip_t, u4_num_extra_disp_buf)) |
| { |
| num_extra_disp_bufs = ps_mem_q_ip->u4_num_extra_disp_buf; |
| } |
| else |
| { |
| num_extra_disp_bufs = 0; |
| } |
| |
| if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size |
| > offsetof(ih264d_fill_mem_rec_ip_t, u4_share_disp_buf)) |
| { |
| #ifndef LOGO_EN |
| u4_share_disp_buf = ps_mem_q_ip->u4_share_disp_buf; |
| #else |
| u4_share_disp_buf = 0; |
| #endif |
| } |
| else |
| { |
| u4_share_disp_buf = 0; |
| } |
| |
| if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size |
| > offsetof(ih264d_fill_mem_rec_ip_t, e_output_format)) |
| { |
| chroma_format = ps_mem_q_ip->e_output_format; |
| } |
| else |
| { |
| chroma_format = -1; |
| } |
| |
| if((chroma_format != IV_YUV_420P) && (chroma_format != IV_YUV_420SP_UV) |
| && (chroma_format != IV_YUV_420SP_VU)) |
| { |
| u4_share_disp_buf = 0; |
| } |
| if(0 == u4_share_disp_buf) |
| num_extra_disp_bufs = 0; |
| |
| { |
| |
| luma_height = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht; |
| luma_width = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd; |
| |
| luma_height = ALIGN32(luma_height); |
| luma_width = ALIGN16(luma_width); |
| luma_width_in_mbs = luma_width >> 4; |
| luma_height_in_mbs = luma_height >> 4; |
| u4_total_num_mbs = (luma_height * luma_width) >> 8; |
| } |
| /* |
| * If level is lesser than 31 and the resolution required is higher, |
| * then make the level at least 31. |
| */ |
| if(u4_total_num_mbs > MAX_MBS_LEVEL_30 && level < H264_LEVEL_3_1) |
| { |
| level = H264_LEVEL_3_1; |
| } |
| |
| if((level < MIN_LEVEL_SUPPORTED) || (level > MAX_LEVEL_SUPPORTED)) |
| { |
| ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= |
| ERROR_LEVEL_UNSUPPORTED; |
| return (IV_FAIL); |
| } |
| |
| if(num_ref_frames > H264_MAX_REF_PICS) |
| { |
| ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= ERROR_NUM_REF; |
| num_ref_frames = H264_MAX_REF_PICS; |
| } |
| |
| if(num_reorder_frames > H264_MAX_REF_PICS) |
| { |
| ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= ERROR_NUM_REF; |
| num_reorder_frames = H264_MAX_REF_PICS; |
| } |
| memTab = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location; |
| |
| memTab[MEM_REC_IV_OBJ].u4_mem_size = sizeof(iv_obj_t); |
| memTab[MEM_REC_IV_OBJ].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_IV_OBJ].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| H264_DEC_DEBUG_PRINT("MEM_REC_IV_OBJ MEM Size = %d\n", |
| memTab[MEM_REC_IV_OBJ].u4_mem_size); |
| |
| memTab[MEM_REC_CODEC].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_CODEC].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_CODEC].u4_mem_size = sizeof(dec_struct_t); |
| |
| { |
| UWORD32 mvinfo_size, mv_info_size_pad; |
| UWORD32 MVbank, MVbank_pad; |
| UWORD32 Ysize; |
| UWORD32 UVsize; |
| UWORD32 one_frm_size; |
| |
| UWORD32 extra_mem = 0; |
| |
| UWORD32 pad_len_h, pad_len_v; |
| |
| /* |
| * For low_delay, use num_buf as 2 - |
| * num_buf = (num_buf_ref) + 1; |
| * where num_buf_ref is 1. |
| */ |
| UWORD32 num_buf; |
| |
| { |
| UWORD32 num_bufs_app, num_bufs_level; |
| |
| num_bufs_app = num_ref_frames + num_reorder_frames + 1; |
| |
| if(num_bufs_app <= 1) |
| num_bufs_app = 2; |
| |
| num_bufs_level = ih264d_get_dpb_size_new(level, (luma_width >> 4), |
| (luma_height >> 4)); |
| |
| max_dpb_size = num_bufs_level; |
| |
| num_bufs_level = num_bufs_level * 2 + 1; |
| |
| num_buf = MIN(num_bufs_level, num_bufs_app); |
| |
| num_buf += num_extra_disp_bufs; |
| |
| } |
| |
| mvinfo_size = ((luma_width * (luma_height)) >> 4); |
| |
| mv_info_size_pad = ((luma_width * (PAD_MV_BANK_ROW)) >> 4); |
| |
| Ysize = ALIGN32((luma_width + (PAD_LEN_Y_H << 1))) |
| * (luma_height + (PAD_LEN_Y_V << 2)); |
| |
| |
| UVsize = Ysize >> 2; |
| if(u4_share_disp_buf == 1) |
| { |
| /* In case of buffers getting shared between application and library |
| there is no need of reference memtabs. Instead of setting the i4_size |
| to zero, it is reduced to a small i4_size to ensure that changes |
| in the code are minimal */ |
| |
| if((chroma_format == IV_YUV_420P) |
| || (chroma_format == IV_YUV_420SP_UV) |
| || (chroma_format == IV_YUV_420SP_VU)) |
| { |
| Ysize = 64; |
| } |
| if(chroma_format == IV_YUV_420SP_UV) |
| { |
| UVsize = 64; |
| } |
| } |
| |
| one_frm_size = (((Ysize + 127) >> 7) << 7) |
| + ((((UVsize << 1) + 127) >> 7) << 7); |
| |
| //Note that for ARM RVDS WS the sizeof(mv_pred_t) is 16 |
| |
| /*Add memory for colocated MB*/ |
| MVbank = sizeof(mv_pred_t) * mvinfo_size; |
| MVbank_pad = sizeof(mv_pred_t) * mv_info_size_pad; |
| |
| MVbank = (((MVbank + 127) >> 7) << 7); |
| |
| MVbank_pad = (((MVbank_pad + 127) >> 7) << 7); |
| |
| memTab[MEM_REC_MVBANK].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_MVBANK].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_MVBANK].u4_mem_size = (MVbank + MVbank_pad) |
| * (MIN(max_dpb_size, num_ref_frames) + 1); |
| |
| |
| memTab[MEM_REC_REF_PIC].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_REF_PIC].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_REF_PIC].u4_mem_size = one_frm_size * num_buf; |
| |
| } |
| |
| memTab[MEM_REC_DEBLK_MB_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_DEBLK_MB_INFO].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_DEBLK_MB_INFO].u4_mem_size = (((((u4_total_num_mbs |
| + (luma_width >> 4)) * sizeof(deblk_mb_t)) + 127) >> 7) << 7); |
| |
| memTab[MEM_REC_NEIGHBOR_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_NEIGHBOR_INFO].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_NEIGHBOR_INFO].u4_mem_size = sizeof(mb_neigbour_params_t) |
| * ((luma_width + 16) >> 4) * 2 * 2; |
| { |
| WORD32 size; |
| WORD32 num_entries; |
| |
| num_entries = MIN(MAX_FRAMES, num_ref_frames); |
| num_entries = 2 * ((2 * num_entries) + 1); |
| |
| size = num_entries * sizeof(void *); |
| size += PAD_MAP_IDX_POC * sizeof(void *); |
| size *= u4_total_num_mbs; |
| size += sizeof(dec_slice_struct_t) * u4_total_num_mbs; |
| memTab[MEM_REC_SLICE_HDR].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_SLICE_HDR].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_SLICE_HDR].u4_mem_size = size; |
| } |
| { |
| |
| UWORD32 u4_num_entries; |
| |
| u4_num_entries = u4_total_num_mbs; |
| |
| memTab[MEM_REC_MB_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_MB_INFO].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_MB_INFO].u4_mem_size = sizeof(dec_mb_info_t) |
| * u4_num_entries; |
| |
| memTab[MEM_REC_PRED_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_PRED_INFO].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| |
| memTab[MEM_REC_PRED_INFO].u4_mem_size = sizeof(pred_info_t) * 2*32; |
| |
| memTab[MEM_REC_COEFF_DATA].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_COEFF_DATA].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_COEFF_DATA].u4_mem_size = MB_LUM_SIZE * sizeof(WORD16); |
| /*For I16x16 MBs, 16 4x4 AC coeffs and 1 4x4 DC coeff TU blocks will be sent |
| For all MBs along with 8 4x4 AC coeffs 2 2x2 DC coeff TU blocks will be sent |
| So use 17 4x4 TU blocks for luma and 9 4x4 TU blocks for chroma */ |
| memTab[MEM_REC_COEFF_DATA].u4_mem_size += u4_num_entries |
| * (MAX(17 * sizeof(tu_sblk4x4_coeff_data_t),4 * sizeof(tu_blk8x8_coeff_data_t)) |
| + 9 * sizeof(tu_sblk4x4_coeff_data_t)); |
| //32 bytes for each mb to store u1_prev_intra4x4_pred_mode and u1_rem_intra4x4_pred_mode data |
| memTab[MEM_REC_COEFF_DATA].u4_mem_size += u4_num_entries * 32; |
| |
| } |
| |
| memTab[MEM_REC_SPS].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_SPS].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_SPS].u4_mem_size = ((sizeof(dec_seq_params_t)) |
| * MAX_NUM_SEQ_PARAMS); |
| |
| memTab[MEM_REC_PPS].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_PPS].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_PPS].u4_mem_size = (sizeof(dec_pic_params_t)) |
| * MAX_NUM_PIC_PARAMS; |
| |
| { |
| UWORD32 u4_mem_size; |
| |
| u4_mem_size = 0; |
| u4_mem_size += (((sizeof(dec_err_status_t) + 127) >> 7) << 7); |
| u4_mem_size += sizeof(sei); |
| u4_mem_size += sizeof(dpb_commands_t); |
| u4_mem_size += sizeof(dec_bit_stream_t); |
| u4_mem_size += sizeof(dec_slice_params_t); |
| u4_mem_size += MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t)); |
| |
| memTab[MEM_REC_EXTRA_MEM].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_EXTRA_MEM].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_EXTRA_MEM].u4_mem_size = u4_mem_size; |
| } |
| |
| { |
| |
| UWORD32 u4_mem_size; |
| |
| u4_mem_size = 0; |
| u4_mem_size += ((TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC) * sizeof(void *)); |
| u4_mem_size = ALIGN64(u4_mem_size); |
| u4_mem_size += (sizeof(bin_ctxt_model_t) * NUM_CABAC_CTXTS); |
| u4_mem_size = ALIGN64(u4_mem_size); |
| u4_mem_size += sizeof(ctxt_inc_mb_info_t); |
| u4_mem_size = ALIGN64(u4_mem_size); |
| u4_mem_size += sizeof(UWORD32) * (MAX_REF_BUFS * MAX_REF_BUFS); |
| u4_mem_size = ALIGN64(u4_mem_size); |
| |
| u4_mem_size += MAX_REF_BUF_SIZE * 2; |
| u4_mem_size = ALIGN64(u4_mem_size); |
| u4_mem_size += ((sizeof(WORD16)) * PRED_BUFFER_WIDTH |
| * PRED_BUFFER_HEIGHT * 2); |
| u4_mem_size = ALIGN64(u4_mem_size); |
| u4_mem_size += sizeof(UWORD8) * (MB_LUM_SIZE); |
| u4_mem_size = ALIGN64(u4_mem_size); |
| u4_mem_size += sizeof(parse_pmbarams_t) * luma_width_in_mbs; //Max recon mb group*/ |
| u4_mem_size = ALIGN64(u4_mem_size); |
| u4_mem_size += (sizeof(parse_part_params_t) * luma_width_in_mbs) << 4; //Max recon mb group*/ |
| u4_mem_size = ALIGN64(u4_mem_size); |
| |
| u4_mem_size += 2 * MAX_REF_BUFS * sizeof(struct pic_buffer_t); |
| u4_mem_size = ALIGN64(u4_mem_size); |
| u4_mem_size += 2 * MAX_REF_BUFS * sizeof(struct pic_buffer_t); |
| u4_mem_size = ALIGN64(u4_mem_size); |
| u4_mem_size += (sizeof(UWORD32) * 3 * (MAX_REF_BUFS * MAX_REF_BUFS)) << 3; |
| u4_mem_size = ALIGN64(u4_mem_size); |
| |
| u4_mem_size += sizeof(UWORD32) * 2 * 3 |
| * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1)); |
| u4_mem_size = ALIGN64(u4_mem_size); |
| |
| memTab[MEM_REC_INTERNAL_SCRATCH].u4_mem_alignment = |
| (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_INTERNAL_SCRATCH].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_SCRATCH_MEM; |
| memTab[MEM_REC_INTERNAL_SCRATCH].u4_mem_size = u4_mem_size; |
| } |
| |
| { |
| |
| UWORD32 u4_mem_used; |
| UWORD32 u4_numRows = MB_SIZE << 1; |
| UWORD32 u4_blk_wd = ((luma_width_in_mbs << 4) >> 1) + 8; |
| |
| u4_mem_used = 0; |
| u4_mem_used += ((luma_width_in_mbs * sizeof(deblkmb_neighbour_t)) << 1); |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += (sizeof(neighbouradd_t) << 2); |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += ((sizeof(ctxt_inc_mb_info_t)) |
| * (((luma_width_in_mbs + 1) << 1) + 1)); |
| u4_mem_used = ALIGN64(u4_mem_used); |
| |
| u4_mem_used += (sizeof(mv_pred_t) * luma_width_in_mbs * 16); |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += (sizeof(mv_pred_t) * luma_width_in_mbs * 16); |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += (sizeof(mv_pred_t) * luma_width_in_mbs * 4 |
| * MV_SCRATCH_BUFS); |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_numRows = BLK8x8SIZE << 1; |
| |
| u4_blk_wd = ((luma_width_in_mbs << 3) >> 1) + 8; |
| |
| u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd; |
| u4_mem_used += 32; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += sizeof(UWORD8) * (luma_width + 16) * 2; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += sizeof(UWORD8) * (luma_width + 16) * 2; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += sizeof(UWORD8) * (luma_width + 16) * 2; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += sizeof(mb_neigbour_params_t) * (luma_width_in_mbs + 1) |
| * luma_height_in_mbs; |
| u4_mem_used += luma_width; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += luma_width; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += luma_width; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| |
| u4_mem_used += ((MB_SIZE + 4) << 1) * PAD_LEN_Y_H; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += ((BLK8x8SIZE + 2) << 1) * PAD_LEN_UV_H; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| u4_mem_used += ((BLK8x8SIZE + 2) << 1) * PAD_LEN_UV_H; |
| u4_mem_used = ALIGN64(u4_mem_used); |
| memTab[MEM_REC_INTERNAL_PERSIST].u4_mem_alignment = |
| (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_INTERNAL_PERSIST].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_INTERNAL_PERSIST].u4_mem_size = u4_mem_used; |
| } |
| |
| memTab[MEM_REC_BITSBUF].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_BITSBUF].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_BITSBUF].u4_mem_size = MAX(256000, (luma_width * luma_height * 3 / 2)); |
| |
| { |
| |
| UWORD32 u4_thread_struct_size = ithread_get_handle_size(); |
| |
| memTab[MEM_REC_THREAD_HANDLE].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_THREAD_HANDLE].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_THREAD_HANDLE].u4_mem_size = u4_thread_struct_size * 2; |
| |
| } |
| |
| memTab[MEM_REC_PARSE_MAP].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_PARSE_MAP].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_PARSE_MAP].u4_mem_size = u4_total_num_mbs; |
| |
| memTab[MEM_REC_PROC_MAP].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_PROC_MAP].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_PROC_MAP].u4_mem_size = u4_total_num_mbs; |
| |
| memTab[MEM_REC_SLICE_NUM_MAP].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_SLICE_NUM_MAP].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_SLICE_NUM_MAP].u4_mem_size = u4_total_num_mbs |
| * sizeof(UWORD16); |
| |
| memTab[MEM_REC_DPB_MGR].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_DPB_MGR].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_DPB_MGR].u4_mem_size = sizeof(dpb_manager_t); |
| |
| memTab[MEM_REC_BACKUP].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_BACKUP].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_BACKUP].u4_mem_size = sizeof(iv_mem_rec_t) * MEM_REC_CNT; |
| |
| { |
| |
| UWORD32 u4_mem_size; |
| |
| u4_mem_size = sizeof(disp_mgr_t); |
| u4_mem_size += sizeof(buf_mgr_t) + ithread_get_mutex_lock_size(); |
| u4_mem_size += sizeof(struct pic_buffer_t) * (H264_MAX_REF_PICS * 2); |
| |
| memTab[MEM_REC_PIC_BUF_MGR].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_PIC_BUF_MGR].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_PIC_BUF_MGR].u4_mem_size = u4_mem_size; |
| } |
| |
| { |
| UWORD32 u4_mem_size; |
| |
| u4_mem_size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size(); |
| u4_mem_size += sizeof(col_mv_buf_t) * (H264_MAX_REF_PICS * 2); |
| u4_mem_size = ALIGN128(u4_mem_size); |
| u4_mem_size += ((luma_width * luma_height) >> 4) |
| * (MIN(max_dpb_size, num_ref_frames) + 1); |
| memTab[MEM_REC_MV_BUF_MGR].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_MV_BUF_MGR].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| memTab[MEM_REC_MV_BUF_MGR].u4_mem_size = u4_mem_size; |
| } |
| |
| memTab[MEM_REC_PRED_INFO_PKD].u4_mem_alignment = (128 * 8) / CHAR_BIT; |
| memTab[MEM_REC_PRED_INFO_PKD].e_mem_type = |
| IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; |
| |
| { |
| UWORD32 u4_num_entries; |
| u4_num_entries = u4_total_num_mbs; |
| |
| if(1 == num_ref_frames) |
| u4_num_entries *= 16; |
| else |
| u4_num_entries *= 16 * 2; |
| |
| memTab[MEM_REC_PRED_INFO_PKD].u4_mem_size = sizeof(pred_info_pkd_t) |
| * u4_num_entries; |
| } |
| |
| ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled = MEM_REC_CNT; |
| |
| |
| return IV_SUCCESS; |
| } |
| /*****************************************************************************/ |
| /* */ |
| /* Function Name : ih264d_clr */ |
| /* */ |
| /* Description : returns memory records to app */ |
| /* */ |
| /* 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_clr(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) |
| { |
| |
| dec_struct_t * ps_dec; |
| iv_retrieve_mem_rec_ip_t *dec_clr_ip; |
| iv_retrieve_mem_rec_op_t *dec_clr_op; |
| |
| dec_clr_ip = (iv_retrieve_mem_rec_ip_t *)pv_api_ip; |
| dec_clr_op = (iv_retrieve_mem_rec_op_t *)pv_api_op; |
| ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle); |
| |
| if(ps_dec->init_done != 1) |
| { |
| //return a proper Error Code |
| return IV_FAIL; |
| } |
| |
| if(ps_dec->pv_pic_buf_mgr) |
| ih264_buf_mgr_free((buf_mgr_t *)ps_dec->pv_pic_buf_mgr); |
| if(ps_dec->pv_mv_buf_mgr) |
| ih264_buf_mgr_free((buf_mgr_t *)ps_dec->pv_mv_buf_mgr); |
| |
| memcpy(dec_clr_ip->pv_mem_rec_location, ps_dec->ps_mem_tab, |
| MEM_REC_CNT * (sizeof(iv_mem_rec_t))); |
| dec_clr_op->u4_num_mem_rec_filled = MEM_REC_CNT; |
| |
| H264_DEC_DEBUG_PRINT("The clear non-conceal num mem recs: %d\n", |
| dec_clr_op->u4_num_mem_rec_filled); |
| |
| return IV_SUCCESS; |
| |
| } |
| |
| /*****************************************************************************/ |
| /* */ |
| /* Function Name : ih264d_init */ |
| /* */ |
| /* Description : initializes 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_init(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) |
| { |
| ih264d_init_ip_t *ps_init_ip; |
| ih264d_init_op_t *ps_init_op; |
| WORD32 init_status = IV_SUCCESS; |
| ps_init_ip = (ih264d_init_ip_t *)pv_api_ip; |
| ps_init_op = (ih264d_init_op_t *)pv_api_op; |
| |
| init_status = ih264d_init_video_decoder(dec_hdl, ps_init_ip, ps_init_op); |
| |
| if(IV_SUCCESS != init_status) |
| { |
| return init_status; |
| } |
| |
| return init_status; |
| } |
| /*****************************************************************************/ |
| /* */ |
| /* 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: |
| 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_FEATURE_UNAVAIL: |
| 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: |
| 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; |
| |
| } |
| |
| /*****************************************************************************/ |
| /* */ |
| /* 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; |
| ivd_video_decode_ip_t *ps_dec_ip; |
| ivd_video_decode_op_t *ps_dec_op; |
| |
| ithread_set_name((void*)"Parse_thread"); |
| |
| ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip; |
| ps_dec_op = (ivd_video_decode_op_t *)pv_api_op; |
| |
| { |
| UWORD32 u4_size; |
| u4_size = ps_dec_op->u4_size; |
| memset(ps_dec_op, 0, sizeof(ivd_video_decode_op_t)); |
| ps_dec_op->u4_size = u4_size; |
| } |
| |
| ps_dec->pv_dec_out = ps_dec_op; |
| ps_dec->process_called = 1; |
| 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; |
| |
| ps_dec_op->u4_num_bytes_consumed = 0; |
| |
| 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; |
| ps_dec->u4_stop_threads = 0; |
| 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_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 = -1; |
| ps_dec_op->u4_output_present = 0; |
| ps_dec_op->u4_frame_decoded_flag = 0; |
| |
| ps_dec->i4_frametype = -1; |
| ps_dec->i4_content_type = -1; |
| /* |
| * For field pictures, set the bottom and top picture decoded u4_flag correctly. |
| */ |
| { |
| if((TOP_FIELD_ONLY | BOT_FIELD_ONLY) == ps_dec->u1_top_bottom_decoded) |
| { |
| ps_dec->u1_top_bottom_decoded = 0; |
| } |
| } |
| ps_dec->u4_slice_start_code_found = 0; |
| |
| /* In case the deocder 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 i, 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_flushfrm && 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_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; |
| |
| } |
| 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->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->u4_prev_nal_skipped = 0; |
| |
| 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 = 2; |
| ps_dec->u1_first_pb_nal_in_pic = 1; |
| ps_dec->u1_slice_header_done = 0; |
| ps_dec->u1_dangling_field = 0; |
| |
| ps_dec->u4_dec_thread_created = 0; |
| ps_dec->u4_bs_deblk_thread_created = 0; |
| ps_dec->u4_cur_bs_mb_num = 0; |
| ps_dec->u4_start_recon_deblk = 0; |
| |
| DEBUG_THREADS_PRINTF(" Starting process call\n"); |
| |
| ps_dec->u4_pic_buf_got = 0; |
| |
| do |
| { |
| |
| 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; |
| pu1_bitstrm_buf = ps_dec->ps_mem_tab[MEM_REC_BITSBUF].pv_base; |
| |
| 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 */ |
| buflen = MIN(buflen, (WORD32)ps_dec->ps_mem_tab[MEM_REC_BITSBUF].u4_mem_size); |
| |
| bytes_consumed = buflen + u4_length_of_start_code; |
| ps_dec_op->u4_num_bytes_consumed += bytes_consumed; |
| |
| if(buflen >= MAX_NAL_UNIT_SIZE) |
| { |
| |
| ih264d_fill_output_struct_from_context(ps_dec, ps_dec_op); |
| H264_DEC_DEBUG_PRINT( |
| "\nNal Size exceeded %d, Processing Stopped..\n", |
| MAX_NAL_UNIT_SIZE); |
| ps_dec->i4_error_code = 1 << IVD_CORRUPTEDDATA; |
| |
| ps_dec_op->e_pic_type = -1; |
| /*signal the decode thread*/ |
| ih264d_signal_decode_thread(ps_dec); |
| /*signal end of frame decode for curren frame*/ |
| |
| if(ps_dec->u4_pic_buf_got == 0) |
| { |
| if(ps_dec->i4_header_decoded == 3) |
| { |
| ps_dec->u2_total_mbs_coded = |
| ps_dec->ps_cur_sps->u2_max_mb_addr + 1; |
| } |
| |
| /* close deblock thread if it is not closed yet*/ |
| if(ps_dec->u4_num_cores == 3) |
| { |
| ih264d_signal_bs_deblk_thread(ps_dec); |
| } |
| return IV_FAIL; |
| } |
| else |
| { |
| ps_dec->u1_pic_decode_done = 1; |
| continue; |
| } |
| } |
| |
| { |
| UWORD8 u1_firstbyte, u1_nal_ref_idc; |
| |
| if(ps_dec->i4_app_skip_mode == IVD_SKIP_B) |
| { |
| u1_firstbyte = *(pu1_buf + u4_length_of_start_code); |
| u1_nal_ref_idc = (UWORD8)(NAL_REF_IDC(u1_firstbyte)); |
| if(u1_nal_ref_idc == 0) |
| { |
| /*skip non reference frames*/ |
| cur_slice_is_nonref = 1; |
| continue; |
| } |
| else |
| { |
| if(1 == cur_slice_is_nonref) |
| { |
| /*We have encountered a referenced frame,return to app*/ |
| ps_dec_op->u4_num_bytes_consumed -= |
| bytes_consumed; |
| ps_dec_op->e_pic_type = IV_B_FRAME; |
| ps_dec_op->u4_error_code = |
| IVD_DEC_FRM_SKIPPED; |
| ps_dec_op->u4_error_code |= (1 |
| << IVD_UNSUPPORTEDPARAM); |
| ps_dec_op->u4_frame_decoded_flag = 0; |
| ps_dec_op->u4_size = |
| sizeof(ivd_video_decode_op_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); |
| } |
| |
| return (IV_FAIL); |
| } |
| } |
| |
| } |
| |
| } |
| |
| |
| if(buflen) |
| { |
| memcpy(pu1_bitstrm_buf, pu1_buf + u4_length_of_start_code, |
| buflen); |
| 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; |
| } |
| |
| } |
| |
| ps_dec->u4_return_to_app = 0; |
| 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 == |