Commit message: None
CVE: CVE-2016-3878
CWE: CWE-284
Vulnerability description: decoder/ih264d_api.c in mediaserver in Android 6.x before 2016-09-01 mishandles the case of decoding zero MBs, which allows remote attackers to cause a denial of service (device hang or reboot) via a crafted media file, aka internal bug 29493002.

Project: Android

static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
 void *pv_api_ip,
 void *pv_api_op)
{
    IVD_API_COMMAND_TYPE_T e_cmd;
    UWORD32 *pu4_api_ip;
    UWORD32 *pu4_api_op;
    UWORD32 i, j;

 if(NULL == pv_api_op)
 return (IV_FAIL);

 if(NULL == pv_api_ip)
 return (IV_FAIL);

    pu4_api_ip = (UWORD32 *)pv_api_ip;
    pu4_api_op = (UWORD32 *)pv_api_op;
    e_cmd = *(pu4_api_ip + 1);

 /* error checks on handle */
 switch((WORD32)e_cmd)
 {
 case IVD_CMD_CREATE:
 break;

 case IVD_CMD_REL_DISPLAY_FRAME:
 case IVD_CMD_SET_DISPLAY_FRAME:
 case IVD_CMD_GET_DISPLAY_FRAME:
 case IVD_CMD_VIDEO_DECODE:
 case IVD_CMD_DELETE:
 case IVD_CMD_VIDEO_CTL:
 if(ps_handle == NULL)
 {
 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
 *(pu4_api_op + 1) |= IVD_HANDLE_NULL;
 return IV_FAIL;
 }

 if(ps_handle->u4_size != sizeof(iv_obj_t))
 {
 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
 *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT;
 return IV_FAIL;
 }

 if(ps_handle->pv_fxns != ih264d_api_function)
 {
 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
 *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
 return IV_FAIL;
 }

 if(ps_handle->pv_codec_handle == NULL)
 {
 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
 *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
 return IV_FAIL;
 }
 break;
 default:
 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
 *(pu4_api_op + 1) |= IVD_INVALID_API_CMD;
 return IV_FAIL;
 }

 switch((WORD32)e_cmd)
 {
 case IVD_CMD_CREATE:
 {
 ih264d_create_ip_t *ps_ip = (ih264d_create_ip_t *)pv_api_ip;
 ih264d_create_op_t *ps_op = (ih264d_create_op_t *)pv_api_op;


            ps_op->s_ivd_create_op_t.u4_error_code = 0;

 if((ps_ip->s_ivd_create_ip_t.u4_size > sizeof(ih264d_create_ip_t))
 || (ps_ip->s_ivd_create_ip_t.u4_size
 < sizeof(ivd_create_ip_t)))
 {
                ps_op->s_ivd_create_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_create_op_t.u4_error_code |=
                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
                H264_DEC_DEBUG_PRINT("\n");
 return (IV_FAIL);
 }

 if((ps_op->s_ivd_create_op_t.u4_size != sizeof(ih264d_create_op_t))
 && (ps_op->s_ivd_create_op_t.u4_size
 != sizeof(ivd_create_op_t)))
 {
                ps_op->s_ivd_create_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_create_op_t.u4_error_code |=
                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
                H264_DEC_DEBUG_PRINT("\n");
 return (IV_FAIL);
 }


 if((ps_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420P)
 && (ps_ip->s_ivd_create_ip_t.e_output_format
 != IV_YUV_422ILE)
 && (ps_ip->s_ivd_create_ip_t.e_output_format
 != IV_RGB_565)
 && (ps_ip->s_ivd_create_ip_t.e_output_format
 != IV_YUV_420SP_UV)
 && (ps_ip->s_ivd_create_ip_t.e_output_format
 != IV_YUV_420SP_VU))
 {
                ps_op->s_ivd_create_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_create_op_t.u4_error_code |=
                                IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED;
                H264_DEC_DEBUG_PRINT("\n");
 return (IV_FAIL);
 }

 }
 break;

 case IVD_CMD_GET_DISPLAY_FRAME:
 {
 ih264d_get_display_frame_ip_t *ps_ip =
 (ih264d_get_display_frame_ip_t *)pv_api_ip;
 ih264d_get_display_frame_op_t *ps_op =
 (ih264d_get_display_frame_op_t *)pv_api_op;

            ps_op->s_ivd_get_display_frame_op_t.u4_error_code = 0;

 if((ps_ip->s_ivd_get_display_frame_ip_t.u4_size
 != sizeof(ih264d_get_display_frame_ip_t))
 && (ps_ip->s_ivd_get_display_frame_ip_t.u4_size
 != sizeof(ivd_get_display_frame_ip_t)))
 {
                ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
 return (IV_FAIL);
 }

 if((ps_op->s_ivd_get_display_frame_op_t.u4_size
 != sizeof(ih264d_get_display_frame_op_t))
 && (ps_op->s_ivd_get_display_frame_op_t.u4_size
 != sizeof(ivd_get_display_frame_op_t)))
 {
                ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
 return (IV_FAIL);
 }
 }
 break;

 case IVD_CMD_REL_DISPLAY_FRAME:
 {
 ih264d_rel_display_frame_ip_t *ps_ip =
 (ih264d_rel_display_frame_ip_t *)pv_api_ip;
 ih264d_rel_display_frame_op_t *ps_op =
 (ih264d_rel_display_frame_op_t *)pv_api_op;

            ps_op->s_ivd_rel_display_frame_op_t.u4_error_code = 0;

 if((ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
 != sizeof(ih264d_rel_display_frame_ip_t))
 && (ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
 != sizeof(ivd_rel_display_frame_ip_t)))
 {
                ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
 return (IV_FAIL);
 }

 if((ps_op->s_ivd_rel_display_frame_op_t.u4_size
 != sizeof(ih264d_rel_display_frame_op_t))
 && (ps_op->s_ivd_rel_display_frame_op_t.u4_size
 != sizeof(ivd_rel_display_frame_op_t)))
 {
                ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
 return (IV_FAIL);
 }

 }
 break;

 case IVD_CMD_SET_DISPLAY_FRAME:
 {
 ih264d_set_display_frame_ip_t *ps_ip =
 (ih264d_set_display_frame_ip_t *)pv_api_ip;
 ih264d_set_display_frame_op_t *ps_op =
 (ih264d_set_display_frame_op_t *)pv_api_op;
            UWORD32 j;

            ps_op->s_ivd_set_display_frame_op_t.u4_error_code = 0;

 if((ps_ip->s_ivd_set_display_frame_ip_t.u4_size
 != sizeof(ih264d_set_display_frame_ip_t))
 && (ps_ip->s_ivd_set_display_frame_ip_t.u4_size
 != sizeof(ivd_set_display_frame_ip_t)))
 {
                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
 return (IV_FAIL);
 }

 if((ps_op->s_ivd_set_display_frame_op_t.u4_size
 != sizeof(ih264d_set_display_frame_op_t))
 && (ps_op->s_ivd_set_display_frame_op_t.u4_size
 != sizeof(ivd_set_display_frame_op_t)))
 {
                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
 return (IV_FAIL);
 }

 if(ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs == 0)
 {
                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
                                IVD_DISP_FRM_ZERO_OP_BUFS;
 return IV_FAIL;
 }

 for(j = 0; j < ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs;
                            j++)
 {
 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs
 == 0)
 {
                    ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                    ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
                                    IVD_DISP_FRM_ZERO_OP_BUFS;
 return IV_FAIL;
 }

 for(i = 0;
                                i
 < ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs;
                                i++)
 {
 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].pu1_bufs[i]
 == NULL)
 {
                        ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                        ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
                                        IVD_DISP_FRM_OP_BUF_NULL;
 return IV_FAIL;
 }

 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_min_out_buf_size[i]
 == 0)
 {
                        ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                        ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
                                        IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
 return IV_FAIL;
 }
 }
 }
 }
 break;

 case IVD_CMD_VIDEO_DECODE:
 {
 ih264d_video_decode_ip_t *ps_ip =
 (ih264d_video_decode_ip_t *)pv_api_ip;
 ih264d_video_decode_op_t *ps_op =
 (ih264d_video_decode_op_t *)pv_api_op;

            H264_DEC_DEBUG_PRINT("The input bytes is: %d",
                                 ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes);
            ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;

 if(ps_ip->s_ivd_video_decode_ip_t.u4_size
 != sizeof(ih264d_video_decode_ip_t)&&
                            ps_ip->s_ivd_video_decode_ip_t.u4_size != 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 IVD_CMD_DELETE:
 {
 ih264d_delete_ip_t *ps_ip =
 (ih264d_delete_ip_t *)pv_api_ip;
 ih264d_delete_op_t *ps_op =
 (ih264d_delete_op_t *)pv_api_op;

            ps_op->s_ivd_delete_op_t.u4_error_code = 0;

 if(ps_ip->s_ivd_delete_ip_t.u4_size
 != sizeof(ih264d_delete_ip_t))
 {
                ps_op->s_ivd_delete_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_delete_op_t.u4_error_code |=
                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
 return (IV_FAIL);
 }

 if(ps_op->s_ivd_delete_op_t.u4_size
 != sizeof(ih264d_delete_op_t))
 {
                ps_op->s_ivd_delete_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                ps_op->s_ivd_delete_op_t.u4_error_code |=
                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
 return (IV_FAIL);
 }

 }
 break;

 case IVD_CMD_VIDEO_CTL:
 {
            UWORD32 *pu4_ptr_cmd;
            UWORD32 sub_command;

            pu4_ptr_cmd = (UWORD32 *)pv_api_ip;
            pu4_ptr_cmd += 2;
            sub_command = *pu4_ptr_cmd;

 switch(sub_command)
 {
 case IVD_CMD_CTL_SETPARAMS:
 {
 ih264d_ctl_set_config_ip_t *ps_ip;
 ih264d_ctl_set_config_op_t *ps_op;
                    ps_ip = (ih264d_ctl_set_config_ip_t *)pv_api_ip;
                    ps_op = (ih264d_ctl_set_config_op_t *)pv_api_op;

 if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size
 != sizeof(ih264d_ctl_set_config_ip_t))
 {
                        ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
 << IVD_UNSUPPORTEDPARAM;
                        ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
 return IV_FAIL;
 }
 }
 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;
}

Project: Android

WORD32 ih264d_ctl(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
 ivd_ctl_set_config_ip_t *ps_ctl_ip;
 ivd_ctl_set_config_op_t *ps_ctl_op;
    WORD32 ret = IV_SUCCESS;
    UWORD32 subcommand;
 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;

 if(ps_dec->init_done != 1)
 {
 return IV_FAIL;
 }
    ps_ctl_ip = (ivd_ctl_set_config_ip_t*)pv_api_ip;
    ps_ctl_op = (ivd_ctl_set_config_op_t*)pv_api_op;
    ps_ctl_op->u4_error_code = 0;
    subcommand = ps_ctl_ip->e_sub_cmd;

 switch(subcommand)
 {
 case IVD_CMD_CTL_GETPARAMS:
            ret = ih264d_get_status(dec_hdl, (void *)pv_api_ip,
 (void *)pv_api_op);
 break;
 case IVD_CMD_CTL_SETPARAMS:
            ret = ih264d_set_params(dec_hdl, (void *)pv_api_ip,
 (void *)pv_api_op);
 break;
 case IVD_CMD_CTL_RESET:
            ret = ih264d_reset(dec_hdl, (void *)pv_api_ip, (void *)pv_api_op);
 break;
 case IVD_CMD_CTL_SETDEFAULT:
            ret = ih264d_set_default_params(dec_hdl, (void *)pv_api_ip,
 (void *)pv_api_op);
 break;
 case IVD_CMD_CTL_FLUSH:
            ret = ih264d_set_flush_mode(dec_hdl, (void *)pv_api_ip,
 (void *)pv_api_op);
 break;
 case IVD_CMD_CTL_GETBUFINFO:
            ret = ih264d_get_buf_info(dec_hdl, (void *)pv_api_ip,
 (void *)pv_api_op);
 break;
 case IVD_CMD_CTL_GETVERSION:
            ret = ih264d_get_version(dec_hdl, (void *)pv_api_ip,
 (void *)pv_api_op);
 break;
 case IH264D_CMD_CTL_DEGRADE:
            ret = ih264d_set_degrade(dec_hdl, (void *)pv_api_ip,
 (void *)pv_api_op);
 break;

 case IH264D_CMD_CTL_SET_NUM_CORES:
            ret = ih264d_set_num_cores(dec_hdl, (void *)pv_api_ip,
 (void *)pv_api_op);
 break;
 case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS:
            ret = ih264d_get_frame_dimensions(dec_hdl, (void *)pv_api_ip,
 (void *)pv_api_op);
 break;
 case IH264D_CMD_CTL_SET_PROCESSOR:
            ret = ih264d_set_processor(dec_hdl, (void *)pv_api_ip,
 (void *)pv_api_op);
 break;
 default:
            H264_DEC_DEBUG_PRINT("\ndo nothing\n")
 ;
 break;
 }

 return ret;
}

Project: Android

WORD32 ih264d_delete(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
 dec_struct_t *ps_dec;
 ih264d_delete_ip_t *ps_ip = (ih264d_delete_ip_t *)pv_api_ip;
 ih264d_delete_op_t *ps_op = (ih264d_delete_op_t *)pv_api_op;

    ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
    UNUSED(ps_ip);
    ps_op->s_ivd_delete_op_t.u4_error_code = 0;
    ih264d_free_dynamic_bufs(ps_dec);
    ih264d_free_static_bufs(dec_hdl);
 return IV_SUCCESS;
}

Project: Android

void ih264d_fill_output_struct_from_context(dec_struct_t *ps_dec,
 ivd_video_decode_op_t *ps_dec_op)
{
 if((ps_dec_op->u4_error_code & 0xff)
 != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
 {
        ps_dec_op->u4_pic_wd = (UWORD32)ps_dec->u2_disp_width;
        ps_dec_op->u4_pic_ht = (UWORD32)ps_dec->u2_disp_height;
 }
    ps_dec_op->e_pic_type = ps_dec->i4_frametype;

    ps_dec_op->u4_new_seq = 0;
    ps_dec_op->u4_output_present = ps_dec->u4_output_present;
    ps_dec_op->u4_progressive_frame_flag =
                    ps_dec->s_disp_op.u4_progressive_frame_flag;

    ps_dec_op->u4_is_ref_flag = 1;
 if(ps_dec_op->u4_frame_decoded_flag)
 {
 if(ps_dec->ps_cur_slice->u1_nal_ref_idc == 0)
            ps_dec_op->u4_is_ref_flag = 0;
 }

    ps_dec_op->e_output_format = ps_dec->s_disp_op.e_output_format;
    ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf;
    ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type;
    ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts;
    ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
}

Project: Android

WORD32 ih264d_free_static_bufs(iv_obj_t *dec_hdl)
{
 dec_struct_t *ps_dec;

 void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
 void *pv_mem_ctxt;

    ps_dec = (dec_struct_t *)dec_hdl->pv_codec_handle;
    pf_aligned_free = ps_dec->pf_aligned_free;
    pv_mem_ctxt = ps_dec->pv_mem_ctxt;

    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sps);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pps);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_dec_thread_handle);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_bs_deblk_thread_handle);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dpb_mgr);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pred);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_disp_buf_mgr);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_pic_buf_mgr);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pic_buf_base);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dec_err_status);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sei);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_dpb_cmds);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_bitstrm);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_cur_slice);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_scratch_sps_pps);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_bits_buf_static);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ppv_map_ref_idx_to_poc_base);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->p_cabac_ctxt_table_t);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_left_mb_ctxt_info);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_ref_buff_base);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pi2_pred1);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_temp_mc_buffer);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_init_dpb_base);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu4_mbaff_wt_mat);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu4_wts_ofsts_mat);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_left_mvpred_addr);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_mv_buf_mgr);
    PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_col_mv_base);
    PS_DEC_ALIGNED_FREE(ps_dec, dec_hdl->pv_codec_handle);

 if(dec_hdl)
 {
        pf_aligned_free(pv_mem_ctxt, dec_hdl);
 }
 return IV_SUCCESS;
}

Project: Android

WORD32 ih264d_get_buf_info(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{

 dec_struct_t * ps_dec;
    UWORD8 i = 0; // Default for 420P format
    UWORD16 pic_wd, pic_ht;
 ivd_ctl_getbufinfo_op_t *ps_ctl_op =
 (ivd_ctl_getbufinfo_op_t*)pv_api_op;
    UNUSED(pv_api_ip);
    ps_ctl_op->u4_error_code = 0;

    ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);

    ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
 if(ps_dec->u1_chroma_format == IV_YUV_420P)
        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
 else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
 else if(ps_dec->u1_chroma_format == IV_RGB_565)
        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
 else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
 || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;

 else
 {
 return IV_FAIL;
 }

    ps_ctl_op->u4_num_disp_bufs = 1;


    pic_wd = 0;
    pic_ht = 0;

 if(ps_dec->i4_header_decoded == 3)
 {

 if(0 == ps_dec->u4_share_disp_buf)
 {
            pic_wd = ps_dec->u2_disp_width;
            pic_ht = ps_dec->u2_disp_height;

 }
 else
 {
            pic_wd = ps_dec->u2_frm_wd_y;
            pic_ht = ps_dec->u2_frm_ht_y;
 }

 }

 for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
 {
        ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2);
 }
 if((WORD32)ps_dec->u4_app_disp_width > pic_wd)
        pic_wd = ps_dec->u4_app_disp_width;

 if(0 == ps_dec->u4_share_disp_buf)
        ps_ctl_op->u4_num_disp_bufs = 1;
 else
 {
 if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
 {
 if((ps_dec->ps_cur_sps->u1_vui_parameters_present_flag == 1) &&
 (1 == ps_dec->ps_cur_sps->s_vui.u1_bitstream_restriction_flag))
 {
                ps_ctl_op->u4_num_disp_bufs =
                                ps_dec->ps_cur_sps->s_vui.u4_num_reorder_frames + 1;
 }
 else
 {
 /*if VUI is not present assume maximum possible refrence frames for the level,
                 * as max reorder frames*/
                ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size(ps_dec->ps_cur_sps);
 }

            ps_ctl_op->u4_num_disp_bufs +=
                            ps_dec->ps_cur_sps->u1_num_ref_frames + 1;

 }
 else
 {
            ps_ctl_op->u4_num_disp_bufs = 32;

 }

        ps_ctl_op->u4_num_disp_bufs = MAX(
                        ps_ctl_op->u4_num_disp_bufs, 6);
        ps_ctl_op->u4_num_disp_bufs = MIN(
                        ps_ctl_op->u4_num_disp_bufs, 32);
 }

 /*!*/
 if(ps_dec->u1_chroma_format == IV_YUV_420P)
 {
        ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
        ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht)
 >> 2;
        ps_ctl_op->u4_min_out_buf_size[2] = (pic_wd * pic_ht)
 >> 2;
 }
 else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
 {
        ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht)
 * 2;
        ps_ctl_op->u4_min_out_buf_size[1] =
                        ps_ctl_op->u4_min_out_buf_size[2] = 0;
 }
 else if(ps_dec->u1_chroma_format == IV_RGB_565)
 {
        ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht)
 * 2;
        ps_ctl_op->u4_min_out_buf_size[1] =
                        ps_ctl_op->u4_min_out_buf_size[2] = 0;
 }
 else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
 || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
 {
        ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
        ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht)
 >> 1;
        ps_ctl_op->u4_min_out_buf_size[2] = 0;
 }
    ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs;

 return IV_SUCCESS;
}

Project: Android

WORD32 ih264d_get_display_frame(iv_obj_t *dec_hdl,
 void *pv_api_ip,
 void *pv_api_op)
{

    UNUSED(dec_hdl);
    UNUSED(pv_api_ip);
    UNUSED(pv_api_op);
 return IV_FAIL;
}

Project: Android

WORD32 ih264d_get_status(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{

    UWORD32 i;
 dec_struct_t * ps_dec;
    UWORD32 pic_wd, pic_ht;
 ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t*)pv_api_op;
    UNUSED(pv_api_ip);
    ps_ctl_op->u4_error_code = 0;

    ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);


 if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
 {
        ps_ctl_op->u4_pic_ht = ps_dec->u2_disp_height;
        ps_ctl_op->u4_pic_wd = ps_dec->u2_disp_width;

 if(0 == ps_dec->u4_share_disp_buf)
 {
            pic_wd = ps_dec->u2_disp_width;
            pic_ht = ps_dec->u2_disp_height;

 }
 else
 {
            pic_wd = ps_dec->u2_frm_wd_y;
            pic_ht = ps_dec->u2_frm_ht_y;
 }
 }
 else
 {
        pic_wd = 0;
        pic_ht = 0;

        ps_ctl_op->u4_pic_ht = pic_wd;
        ps_ctl_op->u4_pic_wd = pic_ht;

 if(1 == ps_dec->u4_share_disp_buf)
 {
            pic_wd += (PAD_LEN_Y_H << 1);
            pic_ht += (PAD_LEN_Y_V << 2);

 }

 }

 if(ps_dec->u4_app_disp_width > pic_wd)
        pic_wd = ps_dec->u4_app_disp_width;
 if(0 == ps_dec->u4_share_disp_buf)
        ps_ctl_op->u4_num_disp_bufs = 1;
 else
 {
 if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
 {
 if((ps_dec->ps_cur_sps->u1_vui_parameters_present_flag == 1) &&
 (1 == ps_dec->ps_cur_sps->s_vui.u1_bitstream_restriction_flag))
 {
                ps_ctl_op->u4_num_disp_bufs =
                                ps_dec->ps_cur_sps->s_vui.u4_num_reorder_frames + 1;
 }
 else
 {
 /*if VUI is not present assume maximum possible refrence frames for the level,
                 * as max reorder frames*/
                ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size(ps_dec->ps_cur_sps);
 }

            ps_ctl_op->u4_num_disp_bufs +=
                            ps_dec->ps_cur_sps->u1_num_ref_frames + 1;
 }
 else
 {
            ps_ctl_op->u4_num_disp_bufs = 32;
 }
        ps_ctl_op->u4_num_disp_bufs = MAX(
                        ps_ctl_op->u4_num_disp_bufs, 6);
        ps_ctl_op->u4_num_disp_bufs = MIN(
                        ps_ctl_op->u4_num_disp_bufs, 32);
 }

    ps_ctl_op->u4_error_code = ps_dec->i4_error_code;

    ps_ctl_op->u4_frame_rate = 0; //make it proper
    ps_ctl_op->u4_bit_rate = 0; //make it proper
    ps_ctl_op->e_content_type = ps_dec->i4_content_type;
    ps_ctl_op->e_output_chroma_format = ps_dec->u1_chroma_format;
    ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;

 if(ps_dec->u1_chroma_format == IV_YUV_420P)
 {
        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
 }
 else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
 {
        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
 }
 else if(ps_dec->u1_chroma_format == IV_RGB_565)
 {
        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
 }
 else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
 || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
 {
        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
 }

 else
 {
        ps_ctl_op->u4_error_code = ERROR_FEATURE_UNAVAIL;
 return IV_FAIL;
 }

 for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
 {
        ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2);
 }

 /*!*/
 if(ps_dec->u1_chroma_format == IV_YUV_420P)
 {
        ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
        ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht)
 >> 2;
        ps_ctl_op->u4_min_out_buf_size[2] = (pic_wd * pic_ht)
 >> 2;
 }
 else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
 {
        ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht)
 * 2;
        ps_ctl_op->u4_min_out_buf_size[1] =
                        ps_ctl_op->u4_min_out_buf_size[2] = 0;
 }
 else if(ps_dec->u1_chroma_format == IV_RGB_565)
 {
        ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht)
 * 2;
        ps_ctl_op->u4_min_out_buf_size[1] =
                        ps_ctl_op->u4_min_out_buf_size[2] = 0;
 }
 else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV)
 || (ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
 {
        ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
        ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht)
 >> 1;
        ps_ctl_op->u4_min_out_buf_size[2] = 0;
 }

    ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs;
 return IV_SUCCESS;
}

Project: Android

WORD32 ih264d_get_version(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
 char version_string[MAXVERSION_STRLEN + 1];
    UWORD32 version_string_len;

 ivd_ctl_getversioninfo_ip_t *ps_ip;
 ivd_ctl_getversioninfo_op_t *ps_op;

    ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip;
    ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op;
    UNUSED(dec_hdl);
    ps_op->u4_error_code = IV_SUCCESS;

    VERSION(version_string, CODEC_NAME, CODEC_RELEASE_TYPE, CODEC_RELEASE_VER,
            CODEC_VENDOR);

 if((WORD32)ps_ip->u4_version_buffer_size <= 0)
 {
        ps_op->u4_error_code = IH264D_VERS_BUF_INSUFFICIENT;
 return (IV_FAIL);
 }

    version_string_len = strnlen(version_string, MAXVERSION_STRLEN) + 1;

 if(ps_ip->u4_version_buffer_size >= version_string_len) //(WORD32)sizeof(sizeof(version_string)))
 {
        memcpy(ps_ip->pv_version_buffer, version_string, version_string_len);
        ps_op->u4_error_code = IV_SUCCESS;
 }
 else
 {
        ps_op->u4_error_code = IH264D_VERS_BUF_INSUFFICIENT;
 return IV_FAIL;
 }
 return (IV_SUCCESS);
}

Project: Android

UWORD32 ih264d_map_error(UWORD32 i4_err_status)
{
    UWORD32 temp = 0;

 switch(i4_err_status)
 {
 case ERROR_MEM_ALLOC_ISRAM_T:
 case ERROR_MEM_ALLOC_SDRAM_T:
 case ERROR_BUF_MGR:
 case ERROR_MB_GROUP_ASSGN_T:
 case ERROR_FRAME_LIMIT_OVER:
 case ERROR_ACTUAL_RESOLUTION_GREATER_THAN_INIT:
 case ERROR_PROFILE_NOT_SUPPORTED:
 case ERROR_INIT_NOT_DONE:
 case IVD_MEM_ALLOC_FAILED:
            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;

}

Project: Android

WORD32 ih264d_rel_display_frame(iv_obj_t *dec_hdl,
 void *pv_api_ip,
 void *pv_api_op)
{

 ivd_rel_display_frame_ip_t *ps_rel_ip;
 ivd_rel_display_frame_op_t *ps_rel_op;
    UWORD32 buf_released = 0;

    UWORD32 u4_ts = -1;
 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;

    ps_rel_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip;
    ps_rel_op = (ivd_rel_display_frame_op_t *)pv_api_op;
    ps_rel_op->u4_error_code = 0;
    u4_ts = ps_rel_ip->u4_disp_buf_id;

 if(0 == ps_dec->u4_share_disp_buf)
 {
        ps_dec->u4_disp_buf_mapping[u4_ts] = 0;
        ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 0;
 return IV_SUCCESS;
 }

 if(ps_dec->pv_pic_buf_mgr != NULL)
 {
 if(1 == ps_dec->u4_disp_buf_mapping[u4_ts])
 {
            ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr,
                                  ps_rel_ip->u4_disp_buf_id,
                                  BUF_MGR_IO);
            ps_dec->u4_disp_buf_mapping[u4_ts] = 0;
            buf_released = 1;
 }
 }

 if((1 == ps_dec->u4_share_disp_buf) && (0 == buf_released))
        ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 1;

 return IV_SUCCESS;
}

Project: Android

WORD32 ih264d_reset(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
 dec_struct_t * ps_dec;
 ivd_ctl_reset_op_t *ps_ctl_op = (ivd_ctl_reset_op_t *)pv_api_op;
    UNUSED(pv_api_ip);
    ps_ctl_op->u4_error_code = 0;

    ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);

 if(ps_dec != NULL)
 {
        ih264d_init_decoder(ps_dec);
 }
 else
 {
        H264_DEC_DEBUG_PRINT(
 "\nReset called without Initializing the decoder\n");
        ps_ctl_op->u4_error_code = ERROR_INIT_NOT_DONE;
 }

 return IV_SUCCESS;
}

Project: Android

WORD32 ih264d_set_default_params(iv_obj_t *dec_hdl,
 void *pv_api_ip,
 void *pv_api_op)
{

 dec_struct_t * ps_dec;
    WORD32 ret = IV_SUCCESS;

 ivd_ctl_set_config_op_t *ps_ctl_op =
 (ivd_ctl_set_config_op_t *)pv_api_op;
    ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
    UNUSED(pv_api_ip);


 {
        ps_dec->u4_app_disp_width = 0;
        ps_dec->u4_skip_frm_mask = 0;
        ps_dec->i4_decode_header = 1;

        ps_ctl_op->u4_error_code = 0;
 }


 return ret;
}

Project: Android

WORD32 ih264d_set_degrade(iv_obj_t *ps_codec_obj,
 void *pv_api_ip,
 void *pv_api_op)
{
 ih264d_ctl_degrade_ip_t *ps_ip;
 ih264d_ctl_degrade_op_t *ps_op;
 dec_struct_t *ps_codec = (dec_struct_t *)ps_codec_obj->pv_codec_handle;

    ps_ip = (ih264d_ctl_degrade_ip_t *)pv_api_ip;
    ps_op = (ih264d_ctl_degrade_op_t *)pv_api_op;

    ps_codec->i4_degrade_type = ps_ip->i4_degrade_type;
    ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval;
    ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics;

    ps_op->u4_error_code = 0;
    ps_codec->i4_degrade_pic_cnt = 0;

 return IV_SUCCESS;
}

Project: Android

WORD32 ih264d_set_display_frame(iv_obj_t *dec_hdl,
 void *pv_api_ip,
 void *pv_api_op)
{

 ivd_set_display_frame_ip_t *dec_disp_ip;
 ivd_set_display_frame_op_t *dec_disp_op;

    UWORD32 i;
 dec_struct_t * ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);

    dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip;
    dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op;
    dec_disp_op->u4_error_code = 0;


    ps_dec->u4_num_disp_bufs = 0;
 if(ps_dec->u4_share_disp_buf)
 {
        UWORD32 u4_num_bufs = dec_disp_ip->num_disp_bufs;

        u4_num_bufs = MIN(u4_num_bufs, MAX_DISP_BUFS_NEW);

        ps_dec->u4_num_disp_bufs = u4_num_bufs;
 for(i = 0; i < u4_num_bufs; i++)
 {
            ps_dec->disp_bufs[i].u4_num_bufs =
                            dec_disp_ip->s_disp_buffer[i].u4_num_bufs;

            ps_dec->disp_bufs[i].buf[0] =
                            dec_disp_ip->s_disp_buffer[i].pu1_bufs[0];
            ps_dec->disp_bufs[i].buf[1] =
                            dec_disp_ip->s_disp_buffer[i].pu1_bufs[1];
            ps_dec->disp_bufs[i].buf[2] =
                            dec_disp_ip->s_disp_buffer[i].pu1_bufs[2];

            ps_dec->disp_bufs[i].u4_bufsize[0] =
                            dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0];
            ps_dec->disp_bufs[i].u4_bufsize[1] =
                            dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1];
            ps_dec->disp_bufs[i].u4_bufsize[2] =
                            dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2];

 }
 }
 return IV_SUCCESS;

}

Project: Android

WORD32 ih264d_set_flush_mode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
 dec_struct_t * ps_dec;
 ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t*)pv_api_op;
    ps_ctl_op->u4_error_code = 0;

    ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
    UNUSED(pv_api_ip);
 /* ! */
 /* Signal flush frame control call */
    ps_dec->u1_flushfrm = 1;

 if(ps_dec->u1_init_dec_flag == 1)
 {
        ih264d_release_pics_in_dpb((void *)ps_dec, ps_dec->u1_pic_bufs);
        ih264d_release_display_bufs(ps_dec);
 }

    ps_ctl_op->u4_error_code = 0;

 return IV_SUCCESS;
}

Project: Android

WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
 ih264d_ctl_set_num_cores_ip_t *ps_ip;
 ih264d_ctl_set_num_cores_op_t *ps_op;
 dec_struct_t *ps_dec = dec_hdl->pv_codec_handle;

    ps_ip = (ih264d_ctl_set_num_cores_ip_t *)pv_api_ip;
    ps_op = (ih264d_ctl_set_num_cores_op_t *)pv_api_op;
    ps_op->u4_error_code = 0;
    ps_dec->u4_num_cores = ps_ip->u4_num_cores;
 if(ps_dec->u4_num_cores == 1)
 {
        ps_dec->u1_separate_parse = 0;
 }
 else
 {
        ps_dec->u1_separate_parse = 1;
 }

 /*using only upto three threads currently*/
 if(ps_dec->u4_num_cores > 3)
        ps_dec->u4_num_cores = 3;

 return IV_SUCCESS;
}

Project: Android

WORD32 ih264d_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{

 dec_struct_t * ps_dec;
    WORD32 ret = IV_SUCCESS;

 ivd_ctl_set_config_ip_t *ps_ctl_ip =
 (ivd_ctl_set_config_ip_t *)pv_api_ip;
 ivd_ctl_set_config_op_t *ps_ctl_op =
 (ivd_ctl_set_config_op_t *)pv_api_op;

    ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);

    ps_dec->u4_skip_frm_mask = 0;

    ps_ctl_op->u4_error_code = 0;

    ps_dec->i4_app_skip_mode = ps_ctl_ip->e_frm_skip_mode;

 /*Is it really supported test it when you so the corner testing using test app*/

 if(ps_ctl_ip->e_frm_skip_mode != IVD_SKIP_NONE)
 {

 if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_P)
            ps_dec->u4_skip_frm_mask |= 1 << P_SLC_BIT;
 else if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_B)
            ps_dec->u4_skip_frm_mask |= 1 << B_SLC_BIT;
 else if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_PB)
 {
            ps_dec->u4_skip_frm_mask |= 1 << B_SLC_BIT;
            ps_dec->u4_skip_frm_mask |= 1 << P_SLC_BIT;
 }
 else if(ps_ctl_ip->e_frm_skip_mode == IVD_SKIP_I)
            ps_dec->u4_skip_frm_mask |= 1 << I_SLC_BIT;
 else
 {
            ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
            ret = IV_FAIL;
 }
 }

 if((0 != ps_dec->u4_app_disp_width)
 && (ps_ctl_ip->u4_disp_wd
 != ps_dec->u4_app_disp_width))
 {
        ps_ctl_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
        ps_ctl_op->u4_error_code |= ERROR_DISP_WIDTH_INVALID;
        ret = IV_FAIL;
 }
 else
 {
 if(ps_ctl_ip->u4_disp_wd >= ps_dec->u2_pic_wd)
 {
            ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd;
 }
 else if(0 == ps_dec->i4_header_decoded)
 {
            ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd;
 }
 else if(ps_ctl_ip->u4_disp_wd == 0)
 {
            ps_dec->u4_app_disp_width = 0;
 }
 else
 {
 /*
             * Set the display width to zero. This will ensure that the wrong value we had stored (0xFFFFFFFF)
             * does not propogate.
             */
            ps_dec->u4_app_disp_width = 0;
            ps_ctl_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
            ps_ctl_op->u4_error_code |= ERROR_DISP_WIDTH_INVALID;
            ret = IV_FAIL;
 }
 }
 if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_FRAME)
        ps_dec->i4_decode_header = 0;
 else if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_HEADER)
        ps_dec->i4_decode_header = 1;
 else
 {
        ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
        ps_dec->i4_decode_header = 1;
        ret = IV_FAIL;
 }
    ps_dec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;

 if((ps_ctl_ip->e_frm_out_mode != IVD_DECODE_FRAME_OUT) &&
 (ps_ctl_ip->e_frm_out_mode != IVD_DISPLAY_FRAME_OUT))
 {
        ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
        ret = IV_FAIL;
 }
    ps_dec->e_frm_out_mode = ps_ctl_ip->e_frm_out_mode;
 return ret;

}