blob: c449fba63868a8212f8da87046b86e4f85e546a2 [file] [log] [blame]
/******************************************************************************
*
* Copyright (C) 2022 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
* isvcd_api.c
*
* @brief
* Contains all the API related functions
*
* @author
* Kishore
*
* @par List of Functions:
* - api_check_struct_sanity()
* - isvcd_set_processor()
* - isvcd_init_decoder()
* - isvcd_nal_parse_ctxt_free()
* - isvcd_residual_resample_ctxt_free()
* - isvcd_intra_resample_ctxt_free()
* - isvcd_mode_mv_resample_ctxt_free()
* - isvcd_free_static_bufs()
* - isvcd_nal_parse_ctxt_create()
* - isvcd_intra_resample_ctxt_create()
* - isvcd_residual_resample_ctxt_create()
* - isvcd_mode_mv_resample_ctxt_create()
* - isvcd_allocate_static_bufs()
* - isvcd_create()
* - isvcd_update_dqid()
* - isvcd_detect_res_change()
* - isvcd_parse_ref_pic_list_modify()
* - isvcd_parse_slice_hdr_refdq_id()
* - isvcd_get_ref_lyr_dqid()
* - isvcd_conceal_node_params()
* - isvcd_refine_dep_list()
* - isvcd_dec_non_vcl()
* - isvcd_seq_hdr_dec()
* - isvcd_pre_parse_refine_au()
* - isvcd_video_decode()
* - isvcd_set_display_frame()
* - isvcd_set_flush_mode()
* - isvcd_get_status()
* - isvcd_get_buf_info()
* - isvcd_set_params()
* - isvcd_set_target_layer()
* - isvcd_set_default_params()
* - isvcd_delete()
* - isvcd_reset()
* - isvcd_ctl()
* - isvcd_rel_display_frame()
* - isvcd_set_degrade()
* - isvcd_get_frame_dimensions()
* - isvcd_get_vui_params()
* - isvcd_get_sei_mdcv_params()
* - isvcd_get_sei_cll_params()
* - isvcd_get_sei_ave_params()
* - isvcd_get_sei_ccv_params()
* - isvcd_set_num_cores()
* - isvcd_fill_output_struct_from_context()
* - isvcd_api_function()
*
* @remarks
* None
*
*******************************************************************************
*/
#include <string.h>
#include <limits.h>
#include <stddef.h>
#include <assert.h>
#include "ih264_defs.h"
#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_defs.h"
#include "ih264d_debug.h"
#include "ih264_debug.h"
#include "ih264d_inter_pred.h"
#include "isvcd_structs.h"
#include "ih264d_nal.h"
#include "ih264d_error_handler.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_process_pslice.h"
#include "isvcd_process_epslice.h"
#include "ih264d_utils.h"
#include "ih264d_api_utils.h"
#include "ih264d_format_conv.h"
#include "ih264d_parse_headers.h"
#include "ih264d_thread_compute_bs.h"
#include "isvcd_utils.h"
#include "isvcd.h"
#include "isvcd_mode_mv_resamp.h"
#include "isvcd_parse_headers.h"
#include "isvcd_thread_compute_bs.h"
#include "isvcd_function_selector.h"
/*********************/
/* Codec Versioning */
/*********************/
// Move this to where it is used
#define CODEC_NAME "H264VDEC"
#define CODEC_RELEASE_TYPE "production"
#define CODEC_RELEASE_VER "05.00"
#define CODEC_VENDOR "ITTIAM"
#define MAXVERSION_STRLEN 511
#ifdef ANDROID
#define VERSION(version_string, codec_name, codec_release_type, codec_release_ver, codec_vendor) \
snprintf(version_string, MAXVERSION_STRLEN, "@(#)Id:%s_%s Ver:%s Released by %s", codec_name, \
codec_release_type, codec_release_ver, codec_vendor)
#else
#define VERSION(version_string, codec_name, codec_release_type, codec_release_ver, codec_vendor) \
snprintf(version_string, MAXVERSION_STRLEN, \
"@(#)Id:%s_%s Ver:%s Released by %s Build: %s @ %s", codec_name, codec_release_type, \
codec_release_ver, codec_vendor, __DATE__, __TIME__)
#endif
#define MIN_IN_BUFS 1
#define MIN_OUT_BUFS_420 3
#define MIN_OUT_BUFS_422ILE 1
#define MIN_OUT_BUFS_RGB565 1
#define MIN_OUT_BUFS_420SP 2
#define NUM_FRAMES_LIMIT_ENABLED 0
#if NUM_FRAMES_LIMIT_ENABLED
#define NUM_FRAMES_LIMIT 10000
#else
#define NUM_FRAMES_LIMIT 0x7FFFFFFF
#endif
WORD32 ih264d_get_version(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
WORD32 ih264d_parse_sei(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm);
WORD32 check_app_out_buf_size(dec_struct_t *ps_dec);
UWORD32 ih264d_get_extra_mem_external(UWORD32 width, UWORD32 height);
WORD32 isvcd_get_frame_dimensions(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
WORD32 isvcd_get_vui_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
WORD32 isvcd_get_sei_mdcv_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
WORD32 isvcd_get_sei_cll_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
WORD32 isvcd_get_sei_ave_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
WORD32 isvcd_get_sei_ccv_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
WORD32 isvcd_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);
WORD32 ih264d_get_display_frame(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
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);
void isvcd_decode_picture_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec);
WORD32 isvcd_set_degrade(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op);
void isvcd_fill_output_struct_from_context(svc_dec_lyr_struct_t *ps_svc_lyr_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;
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 != isvcd_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:
{
isvcd_create_ip_t *ps_ip = (isvcd_create_ip_t *) pv_api_ip;
isvcd_create_op_t *ps_op = (isvcd_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(isvcd_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(isvcd_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:
{
isvcd_get_display_frame_ip_t *ps_ip = (isvcd_get_display_frame_ip_t *) pv_api_ip;
isvcd_get_display_frame_op_t *ps_op = (isvcd_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(isvcd_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(isvcd_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:
{
isvcd_rel_display_frame_ip_t *ps_ip = (isvcd_rel_display_frame_ip_t *) pv_api_ip;
isvcd_rel_display_frame_op_t *ps_op = (isvcd_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(isvcd_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(isvcd_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:
{
isvcd_set_display_frame_ip_t *ps_ip = (isvcd_set_display_frame_ip_t *) pv_api_ip;
isvcd_set_display_frame_op_t *ps_op = (isvcd_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(isvcd_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(isvcd_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:
{
isvcd_video_decode_ip_t *ps_ip = (isvcd_video_decode_ip_t *) pv_api_ip;
isvcd_video_decode_op_t *ps_op = (isvcd_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(isvcd_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(isvcd_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);
}
{
svc_dec_ctxt_t *ps_svcd_ctxt;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
dec_struct_t *ps_dec;
ps_svcd_ctxt = (svc_dec_ctxt_t *) (ps_handle->pv_codec_handle);
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
ps_dec = &ps_svc_lyr_dec->s_dec;
if(ps_dec->u1_enable_mb_info)
{
if(!ps_ip->pu1_8x8_blk_qp_map && !ps_ip->pu1_8x8_blk_type_map)
{
ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_video_decode_op_t.u4_error_code |=
IH264D_FRAME_INFO_OP_BUF_NULL;
return IV_FAIL;
}
}
}
}
break;
case IVD_CMD_DELETE:
{
isvcd_delete_ip_t *ps_ip = (isvcd_delete_ip_t *) pv_api_ip;
isvcd_delete_op_t *ps_op = (isvcd_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(isvcd_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(isvcd_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:
{
isvcd_ctl_set_config_ip_t *ps_ip;
isvcd_ctl_set_config_op_t *ps_op;
ps_ip = (isvcd_ctl_set_config_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_set_config_op_t *) pv_api_op;
if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size !=
sizeof(isvcd_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;
}
}
break;
case IVD_CMD_CTL_SETDEFAULT:
{
isvcd_ctl_set_config_op_t *ps_op;
ps_op = (isvcd_ctl_set_config_op_t *) pv_api_op;
if(ps_op->s_ivd_ctl_set_config_op_t.u4_size !=
sizeof(isvcd_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:
{
isvcd_ctl_getstatus_ip_t *ps_ip;
isvcd_ctl_getstatus_op_t *ps_op;
ps_ip = (isvcd_ctl_getstatus_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_getstatus_op_t *) pv_api_op;
if(ps_ip->s_ivd_ctl_getstatus_ip_t.u4_size != sizeof(isvcd_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(isvcd_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:
{
isvcd_ctl_getbufinfo_ip_t *ps_ip;
isvcd_ctl_getbufinfo_op_t *ps_op;
ps_ip = (isvcd_ctl_getbufinfo_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_getbufinfo_op_t *) pv_api_op;
if(ps_ip->s_ivd_ctl_getbufinfo_ip_t.u4_size !=
sizeof(isvcd_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(isvcd_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:
{
isvcd_ctl_getversioninfo_ip_t *ps_ip;
isvcd_ctl_getversioninfo_op_t *ps_op;
ps_ip = (isvcd_ctl_getversioninfo_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_getversioninfo_op_t *) pv_api_op;
if(ps_ip->s_ivd_ctl_getversioninfo_ip_t.u4_size !=
sizeof(isvcd_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(isvcd_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:
{
isvcd_ctl_flush_ip_t *ps_ip;
isvcd_ctl_flush_op_t *ps_op;
ps_ip = (isvcd_ctl_flush_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_flush_op_t *) pv_api_op;
if(ps_ip->s_ivd_ctl_flush_ip_t.u4_size != sizeof(isvcd_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(isvcd_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:
{
isvcd_ctl_reset_ip_t *ps_ip;
isvcd_ctl_reset_op_t *ps_op;
ps_ip = (isvcd_ctl_reset_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_reset_op_t *) pv_api_op;
if(ps_ip->s_ivd_ctl_reset_ip_t.u4_size != sizeof(isvcd_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(isvcd_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:
{
isvcd_ctl_degrade_ip_t *ps_ip;
isvcd_ctl_degrade_op_t *ps_op;
ps_ip = (isvcd_ctl_degrade_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_degrade_op_t *) pv_api_op;
if(ps_ip->u4_size != sizeof(isvcd_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(isvcd_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:
{
isvcd_ctl_get_frame_dimensions_ip_t *ps_ip;
isvcd_ctl_get_frame_dimensions_op_t *ps_op;
ps_ip = (isvcd_ctl_get_frame_dimensions_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_frame_dimensions_op_t *) pv_api_op;
if(ps_ip->u4_size != sizeof(isvcd_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(isvcd_ctl_get_frame_dimensions_op_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
break;
}
case IH264D_CMD_CTL_GET_VUI_PARAMS:
{
isvcd_ctl_get_vui_params_ip_t *ps_ip;
isvcd_ctl_get_vui_params_op_t *ps_op;
ps_ip = (isvcd_ctl_get_vui_params_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_vui_params_op_t *) pv_api_op;
if(ps_ip->u4_size != sizeof(isvcd_ctl_get_vui_params_ip_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->u4_size != sizeof(isvcd_ctl_get_vui_params_op_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
break;
}
case IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS:
{
isvcd_ctl_get_sei_mdcv_params_ip_t *ps_ip;
isvcd_ctl_get_sei_mdcv_params_op_t *ps_op;
ps_ip = (isvcd_ctl_get_sei_mdcv_params_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_sei_mdcv_params_op_t *) pv_api_op;
if(ps_ip->u4_size != sizeof(isvcd_ctl_get_sei_mdcv_params_ip_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->u4_size != sizeof(isvcd_ctl_get_sei_mdcv_params_op_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
break;
}
case IH264D_CMD_CTL_GET_SEI_CLL_PARAMS:
{
isvcd_ctl_get_sei_cll_params_ip_t *ps_ip;
isvcd_ctl_get_sei_cll_params_op_t *ps_op;
ps_ip = (isvcd_ctl_get_sei_cll_params_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_sei_cll_params_op_t *) pv_api_op;
if(ps_ip->u4_size != sizeof(isvcd_ctl_get_sei_cll_params_ip_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->u4_size != sizeof(isvcd_ctl_get_sei_cll_params_op_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
break;
}
case IH264D_CMD_CTL_GET_SEI_AVE_PARAMS:
{
isvcd_ctl_get_sei_ave_params_ip_t *ps_ip;
isvcd_ctl_get_sei_ave_params_op_t *ps_op;
ps_ip = (isvcd_ctl_get_sei_ave_params_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_sei_ave_params_op_t *) pv_api_op;
if(ps_ip->u4_size != sizeof(isvcd_ctl_get_sei_ave_params_ip_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->u4_size != sizeof(isvcd_ctl_get_sei_ave_params_op_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
break;
}
case IH264D_CMD_CTL_GET_SEI_CCV_PARAMS:
{
isvcd_ctl_get_sei_ccv_params_ip_t *ps_ip;
isvcd_ctl_get_sei_ccv_params_op_t *ps_op;
ps_ip = (isvcd_ctl_get_sei_ccv_params_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_sei_ccv_params_op_t *) pv_api_op;
if(ps_ip->u4_size != sizeof(isvcd_ctl_get_sei_ccv_params_ip_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |= IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->u4_size != sizeof(isvcd_ctl_get_sei_ccv_params_op_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |= IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
break;
}
case IH264D_CMD_CTL_SET_NUM_CORES:
{
isvcd_ctl_set_num_cores_ip_t *ps_ip;
isvcd_ctl_set_num_cores_op_t *ps_op;
ps_ip = (isvcd_ctl_set_num_cores_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_set_num_cores_op_t *) pv_api_op;
if(ps_ip->u4_size != sizeof(isvcd_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(isvcd_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:
{
isvcd_ctl_set_processor_ip_t *ps_ip;
isvcd_ctl_set_processor_op_t *ps_op;
ps_ip = (isvcd_ctl_set_processor_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_set_processor_op_t *) pv_api_op;
if(ps_ip->u4_size != sizeof(isvcd_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(isvcd_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;
}
case ISVCD_CMD_CTL_SET_TGT_LAYER:
{
isvcd_set_target_layer_ip_t *ps_ip;
isvcd_set_target_layer_op_t *ps_op;
ps_ip = (isvcd_set_target_layer_ip_t *) pv_api_ip;
ps_op = (isvcd_set_target_layer_op_t *) pv_api_op;
if(ps_ip->u4_size != sizeof(isvcd_set_target_layer_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_ip->u1_tgt_dep_id > MAX_DEPENDENCY_ID)
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
return IV_FAIL;
}
if(ps_ip->u1_tgt_temp_id > MAX_TEMPORAL_ID)
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
return IV_FAIL;
}
if(ps_ip->u1_tgt_quality_id > MAX_QUALITY_ID)
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
return IV_FAIL;
}
if(ps_ip->u1_tgt_priority_id > MAX_PRIORITY_ID)
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
return IV_FAIL;
}
if(ps_op->u4_size != sizeof(isvcd_set_target_layer_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 isvcd_set_processor(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
isvcd_ctl_set_processor_ip_t *ps_ip;
isvcd_ctl_set_processor_op_t *ps_op;
UWORD8 u1_layer_id;
svc_dec_lyr_struct_t *ps_codec;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_ip = (isvcd_ctl_set_processor_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_set_processor_op_t *) pv_api_op;
ps_svcd_ctxt->e_processor_arch = (IVD_ARCH_T) ps_ip->u4_arch;
ps_svcd_ctxt->e_processor_soc = (IVD_SOC_T) ps_ip->u4_soc;
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_codec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_codec->s_dec.e_processor_arch = (IVD_ARCH_T) ps_ip->u4_arch;
ps_codec->s_dec.e_processor_soc = (IVD_SOC_T) ps_ip->u4_soc;
isvcd_init_function_ptr(ps_codec);
}
ps_op->u4_error_code = 0;
return IV_SUCCESS;
}
/**************************************************************************
* \if Function name : isvcd_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 isvcd_init_decoder(svc_dec_lyr_struct_t *ps_dec_svc_lyr_params)
{
svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) ps_dec_svc_lyr_params;
dec_struct_t *ps_dec;
dec_slice_params_t *ps_cur_slice;
pocstruct_t *ps_prev_poc, *ps_cur_poc;
size_t size;
ps_dec = &ps_svc_lyr_dec->s_dec;
size = sizeof(pred_info_t) * 2 * 32;
memset(ps_dec->ps_pred, 0, size);
size = sizeof(disp_mgr_t);
memset(ps_dec->pv_disp_buf_mgr, 0, size);
size = ih264_buf_mgr_size();
memset(ps_dec->pv_pic_buf_mgr, 0, size);
size = sizeof(dec_err_status_t);
memset(ps_dec->ps_dec_err_status, 0, size);
size = sizeof(sei);
memset(ps_dec->ps_sei, 0, size);
size = sizeof(sei);
memset(ps_dec->ps_sei_parse, 0, size);
size = sizeof(dpb_commands_t);
memset(ps_dec->ps_dpb_cmds, 0, size);
size = sizeof(dec_bit_stream_t);
memset(ps_dec->ps_bitstrm, 0, size);
size = sizeof(dec_slice_params_t);
memset(ps_dec->ps_cur_slice, 0, size);
size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t));
memset(ps_dec->pv_scratch_sps_pps, 0, size);
size = sizeof(dec_svc_seq_params_t);
memset(ps_svc_lyr_dec->pv_scratch_subset_sps, 0, size);
size = sizeof(ctxt_inc_mb_info_t);
memset(ps_dec->ps_left_mb_ctxt_info, 0, size);
size = (sizeof(neighbouradd_t) << 2);
memset(ps_dec->ps_left_mvpred_addr, 0, size);
size = ih264_buf_mgr_size();
memset(ps_dec->pv_mv_buf_mgr, 0, size);
/* Free any dynamic buffers that are allocated */
isvcd_free_dynamic_bufs(ps_svc_lyr_dec);
{
UWORD8 i;
struct pic_buffer_t *ps_init_dpb;
ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[0][0];
for(i = 0; i < 2 * MAX_REF_BUFS; i++)
{
ps_init_dpb->pu1_buf1 = NULL;
ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1;
ps_dec->ps_dpb_mgr->ps_init_dpb[0][i] = ps_init_dpb;
ps_dec->ps_dpb_mgr->ps_mod_dpb[0][i] = ps_init_dpb;
ps_init_dpb++;
}
ps_init_dpb = ps_dec->ps_dpb_mgr->ps_init_dpb[1][0];
for(i = 0; i < 2 * MAX_REF_BUFS; i++)
{
ps_init_dpb->pu1_buf1 = NULL;
ps_init_dpb->u1_long_term_frm_idx = MAX_REF_BUFS + 1;
ps_dec->ps_dpb_mgr->ps_init_dpb[1][i] = ps_init_dpb;
ps_dec->ps_dpb_mgr->ps_mod_dpb[1][i] = ps_init_dpb;
ps_init_dpb++;
}
}
ps_cur_slice = ps_dec->ps_cur_slice;
ps_dec->init_done = 0;
ps_dec->u4_num_cores = 1;
ps_dec->u2_pic_ht = ps_dec->u2_pic_wd = 0;
ps_dec->u1_separate_parse = DEFAULT_SEPARATE_PARSE;
ps_dec->u4_app_disable_deblk_frm = 0;
ps_dec->i4_degrade_type = 0;
ps_dec->i4_degrade_pics = 0;
/* Initialization of function pointers ih264d_deblock_picture function*/
ps_dec->p_DeblockPicture[0] = ih264d_deblock_picture_non_mbaff;
ps_dec->p_DeblockPicture[1] = ih264d_deblock_picture_mbaff;
ps_dec->s_cab_dec_env.pv_codec_handle = ps_dec;
ps_dec->u4_num_fld_in_frm = 0;
ps_dec->ps_dpb_mgr->pv_codec_handle = ps_dec;
/* Initialize the sei validity u4_flag with zero indiacting sei is not valid*/
ps_dec->ps_sei->u1_is_valid = 0;
/* decParams Initializations */
ps_dec->ps_cur_pps = NULL;
ps_dec->ps_cur_sps = NULL;
ps_dec->u1_init_dec_flag = 0;
ps_dec->u1_first_slice_in_stream = 1;
ps_dec->u1_last_pic_not_decoded = 0;
ps_dec->u4_app_disp_width = 0;
ps_dec->i4_header_decoded = 0;
ps_dec->u4_total_frames_decoded = 0;
ps_dec->i4_error_code = 0;
ps_dec->i4_content_type = IV_CONTENTTYPE_NA;
ps_dec->ps_cur_slice->u1_mbaff_frame_flag = 0;
ps_dec->ps_dec_err_status->u1_err_flag = ACCEPT_ALL_PICS;
ps_dec->ps_dec_err_status->u1_cur_pic_type = PIC_TYPE_UNKNOWN;
ps_dec->ps_dec_err_status->u4_frm_sei_sync = SYNC_FRM_DEFAULT;
ps_dec->ps_dec_err_status->u4_cur_frm = INIT_FRAME;
ps_dec->ps_dec_err_status->u1_pic_aud_i = PIC_TYPE_UNKNOWN;
ps_dec->u1_pr_sl_type = 0xFF;
ps_dec->u2_mbx = 0xffff;
ps_dec->u2_mby = 0;
ps_dec->u2_total_mbs_coded = 0;
/* POC initializations */
ps_prev_poc = &ps_dec->s_prev_pic_poc;
ps_cur_poc = &ps_dec->s_cur_pic_poc;
ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb = 0;
ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb = 0;
ps_prev_poc->i4_delta_pic_order_cnt_bottom = ps_cur_poc->i4_delta_pic_order_cnt_bottom = 0;
ps_prev_poc->i4_delta_pic_order_cnt[0] = ps_cur_poc->i4_delta_pic_order_cnt[0] = 0;
ps_prev_poc->i4_delta_pic_order_cnt[1] = ps_cur_poc->i4_delta_pic_order_cnt[1] = 0;
ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
ps_prev_poc->i4_top_field_order_count = ps_cur_poc->i4_top_field_order_count = 0;
ps_prev_poc->i4_bottom_field_order_count = ps_cur_poc->i4_bottom_field_order_count = 0;
ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field = 0;
ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst = 0;
ps_cur_slice->u1_mmco_equalto5 = 0;
ps_cur_slice->u2_frame_num = 0;
ps_dec->i4_max_poc = 0;
ps_dec->i4_prev_max_display_seq = 0;
ps_dec->u1_recon_mb_grp = 4;
ps_dec->i4_reorder_depth = -1;
/* Field PIC initializations */
ps_dec->u1_second_field = 0;
ps_dec->s_prev_seq_params.u1_eoseq_pending = 0;
/* Set the cropping parameters as zero */
ps_dec->u2_crop_offset_y = 0;
ps_dec->u2_crop_offset_uv = 0;
/* The Initial Frame Rate Info is not Present */
ps_dec->i4_vui_frame_rate = -1;
ps_dec->i4_pic_type = NA_SLICE;
ps_dec->i4_frametype = IV_NA_FRAME;
ps_dec->i4_content_type = IV_CONTENTTYPE_NA;
ps_dec->u1_res_changed = 0;
ps_dec->u1_frame_decoded_flag = 0;
/* Set the default frame seek mask mode */
ps_dec->u4_skip_frm_mask = SKIP_NONE;
/********************************************************/
/* Initialize CAVLC residual decoding function pointers */
/********************************************************/
ps_dec->pf_cavlc_4x4res_block[0] = ih264d_cavlc_4x4res_block_totalcoeff_1;
ps_dec->pf_cavlc_4x4res_block[1] = ih264d_cavlc_4x4res_block_totalcoeff_2to10;
ps_dec->pf_cavlc_4x4res_block[2] = ih264d_cavlc_4x4res_block_totalcoeff_11to16;
ps_dec->pf_cavlc_parse4x4coeff[0] = ih264d_cavlc_parse4x4coeff_n0to7;
ps_dec->pf_cavlc_parse4x4coeff[1] = ih264d_cavlc_parse4x4coeff_n8;
ps_dec->pf_cavlc_parse_8x8block[0] = ih264d_cavlc_parse_8x8block_none_available;
ps_dec->pf_cavlc_parse_8x8block[1] = ih264d_cavlc_parse_8x8block_left_available;
ps_dec->pf_cavlc_parse_8x8block[2] = ih264d_cavlc_parse_8x8block_top_available;
ps_dec->pf_cavlc_parse_8x8block[3] = ih264d_cavlc_parse_8x8block_both_available;
/***************************************************************************/
/* Initialize Bs calculation function pointers for P and B, 16x16/non16x16 */
/***************************************************************************/
ps_dec->pf_fill_bs1[0][0] = ih264d_fill_bs1_16x16mb_pslice;
ps_dec->pf_fill_bs1[0][1] = ih264d_fill_bs1_non16x16mb_pslice;
ps_dec->pf_fill_bs1[1][0] = ih264d_fill_bs1_16x16mb_bslice;
ps_dec->pf_fill_bs1[1][1] = ih264d_fill_bs1_non16x16mb_bslice;
ps_dec->pf_fill_bs_xtra_left_edge[0] = ih264d_fill_bs_xtra_left_edge_cur_frm;
ps_dec->pf_fill_bs_xtra_left_edge[1] = ih264d_fill_bs_xtra_left_edge_cur_fld;
/* Initialize Reference Pic Buffers */
ih264d_init_ref_bufs(ps_dec->ps_dpb_mgr);
ps_dec->u2_prv_frame_num = 0;
ps_dec->u1_top_bottom_decoded = 0;
ps_dec->u1_dangling_field = 0;
ps_dec->s_cab_dec_env.cabac_table = gau4_ih264d_cabac_table;
ps_dec->pu1_left_mv_ctxt_inc = ps_dec->u1_left_mv_ctxt_inc_arr[0];
ps_dec->pi1_left_ref_idx_ctxt_inc = &ps_dec->i1_left_ref_idx_ctx_inc_arr[0][0];
ps_dec->pu1_left_yuv_dc_csbp = &ps_dec->u1_yuv_dc_csbp_topmb;
/* ! */
/* Initializing flush frame u4_flag */
ps_dec->u1_flushfrm = 0;
ps_dec->s_cab_dec_env.pv_codec_handle = (void *) ps_dec;
ps_dec->ps_bitstrm->pv_codec_handle = (void *) ps_dec;
ps_dec->ps_cur_slice->pv_codec_handle = (void *) ps_dec;
ps_dec->ps_dpb_mgr->pv_codec_handle = (void *) ps_dec;
memset(ps_dec->disp_bufs, 0, (MAX_DISP_BUFS_NEW) * sizeof(disp_buf_t));
memset(ps_dec->u4_disp_buf_mapping, 0, (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
memset(ps_dec->u4_disp_buf_to_be_freed, 0, (MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
memset(ps_dec->ps_cur_slice, 0, sizeof(dec_slice_params_t));
ih264d_init_arch(ps_dec);
isvcd_init_function_ptr(ps_svc_lyr_dec);
ps_dec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
ps_dec->init_done = 1;
ps_svc_lyr_dec->u1_layer_identifier = BASE_LAYER;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_nal_parse_ctxt_free */
/* */
/* Description :this function is used to free the nal parse context */
/* Inputs : */
/* Globals : none */
/* Processing : */
/* */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 25 11 2021 Kishore creation */
/* */
/*****************************************************************************/
void isvcd_nal_parse_ctxt_free(svc_dec_ctxt_t *ps_svcd_ctxt)
{
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
void *pv_mem_ctxt;
nal_parse_ctxt_t *ps_ctxt;
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
ps_dec = &ps_svc_lyr_dec->s_dec;
pf_aligned_free = ps_dec->pf_aligned_free;
pv_mem_ctxt = ps_dec->pv_mem_ctxt;
ps_ctxt = (nal_parse_ctxt_t *) ps_svcd_ctxt->pv_nal_parse_ctxt;
pf_aligned_free(pv_mem_ctxt, ps_ctxt->s_dqid_ctxt.ps_dqid_node);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->pv_nal_header_buf);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->pv_nal_unit);
pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_vcl_nal_buff);
pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_non_vcl_nal_buff);
pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_nal_parse_ctxt);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_residual_resample_ctxt_free */
/* */
/* Description :this function is used to free the resd_resamp context */
/* Inputs : */
/* Globals : none */
/* Processing : */
/* */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 25 11 2021 Kishore creation */
/* */
/*****************************************************************************/
void isvcd_residual_resample_ctxt_free(svc_dec_ctxt_t *ps_svcd_ctxt)
{
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
void *pv_mem_ctxt;
residual_sampling_ctxt_t *ps_ctxt;
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
ps_dec = &ps_svc_lyr_dec->s_dec;
pf_aligned_free = ps_dec->pf_aligned_free;
pv_mem_ctxt = ps_dec->pv_mem_ctxt;
ps_ctxt = (residual_sampling_ctxt_t *) ps_svcd_ctxt->pv_residual_sample_ctxt;
pf_aligned_free(pv_mem_ctxt, ps_ctxt->pi2_refarray_buffer);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->pu1_ref_x_ptr_incr);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_x_offset_length);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_y_offset_length);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_x_pos_phase);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_y_pos_phase);
pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_residual_sample_ctxt);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_intra_resample_ctxt_free */
/* */
/* Description :this function is used to free the intra_resamp context */
/* Inputs : */
/* Globals : none */
/* Processing : */
/* */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 25 11 2021 Kishore creation */
/* */
/*****************************************************************************/
void isvcd_intra_resample_ctxt_free(svc_dec_ctxt_t *ps_svcd_ctxt)
{
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
void *pv_mem_ctxt;
intra_sampling_ctxt_t *ps_ctxt;
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
ps_dec = &ps_svc_lyr_dec->s_dec;
pf_aligned_free = ps_dec->pf_aligned_free;
pv_mem_ctxt = ps_dec->pv_mem_ctxt;
ps_ctxt = (intra_sampling_ctxt_t *) ps_svcd_ctxt->pv_intra_sample_ctxt;
pf_aligned_free(pv_mem_ctxt, ps_ctxt->pu1_refarray_buffer);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->pu1_refarray_cb);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->pu1_refarray_cr);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->pi4_temp_interpolation_buffer);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_x_offset_length);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_y_offset_length);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_x_min_max);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_y_min_max);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_x_pos_phase);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_y_pos_phase);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.pi2_xd_index);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.pi2_yd_index);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.pi2_ya_index);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_seg_lookup_horz);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.ps_seg_lookup_vert);
pf_aligned_free(pv_mem_ctxt, ps_ctxt->as_res_lyrs[0].s_luma_map_ctxt.pu1_refarray_x_idx);
pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_intra_sample_ctxt);
pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_ii_pred_ctxt);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_mode_mv_resample_ctxt_free */
/* */
/* Description :this function is used to free the mv resamp context */
/* Inputs : */
/* Globals : none */
/* Processing : */
/* */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 25 11 2021 Kishore creation */
/* */
/*****************************************************************************/
void isvcd_mode_mv_resample_ctxt_free(svc_dec_ctxt_t *ps_svcd_ctxt)
{
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
void *pv_mem_ctxt;
mode_motion_ctxt_t *ps_mode_motion;
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
ps_dec = &ps_svc_lyr_dec->s_dec;
pf_aligned_free = ps_dec->pf_aligned_free;
pv_mem_ctxt = ps_dec->pv_mem_ctxt;
ps_mode_motion = (mode_motion_ctxt_t *) ps_svcd_ctxt->pv_mode_mv_sample_ctxt;
pf_aligned_free(pv_mem_ctxt, ps_mode_motion->ps_motion_pred_struct);
pf_aligned_free(pv_mem_ctxt, ps_mode_motion->as_res_lyr_mem[0].pi2_ref_loc_x);
pf_aligned_free(pv_mem_ctxt, ps_mode_motion->as_res_lyr_mem[0].pi2_ref_loc_y);
pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_ref_lyr_offset);
pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->pv_mode_mv_sample_ctxt);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_free_static_bufs */
/* */
/* Description :this function is used to free the static buffers */
/* Inputs : */
/* Globals : none */
/* Processing : */
/* */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 25 11 2021 Kishore creation */
/* */
/*****************************************************************************/
WORD32 isvcd_free_static_bufs(iv_obj_t *dec_hdl)
{
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
UWORD8 u1_layer_id;
svc_dec_ctxt_t *ps_svcd_ctxt;
void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
void *pv_mem_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
isvcd_intra_resample_ctxt_free(ps_svcd_ctxt);
isvcd_residual_resample_ctxt_free(ps_svcd_ctxt);
isvcd_mode_mv_resample_ctxt_free(ps_svcd_ctxt);
isvcd_nal_parse_ctxt_free(ps_svcd_ctxt);
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
pf_aligned_free = ps_dec->pf_aligned_free;
pv_mem_ctxt = ps_dec->pv_mem_ctxt;
#ifdef KEEP_THREADS_ACTIVE
/* Wait for threads */
ps_dec->i4_break_threads = 1;
if(ps_dec->u4_dec_thread_created)
{
ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]);
ps_dec->ai4_process_start[0] = PROC_START;
ithread_cond_signal(ps_dec->apv_proc_start_condition[0]);
ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]);
ithread_join(ps_dec->pv_dec_thread_handle, NULL);
ps_dec->u4_dec_thread_created = 0;
}
if(ps_dec->u4_bs_deblk_thread_created)
{
ithread_mutex_lock(ps_dec->apv_proc_start_mutex[1]);
ps_dec->ai4_process_start[1] = PROC_START;
ithread_cond_signal(ps_dec->apv_proc_start_condition[1]);
ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[1]);
ithread_join(ps_dec->pv_bs_deblk_thread_handle, NULL);
ps_dec->u4_bs_deblk_thread_created = 0;
}
// destroy mutex and condition variable for both the threads
// 1. ih264d_decode_picture_thread
// 2. ih264d_recon_deblk_thread
{
UWORD32 i;
for(i = 0; i < 2; i++)
{
ithread_cond_destroy(ps_dec->apv_proc_start_condition[i]);
ithread_cond_destroy(ps_dec->apv_proc_done_condition[i]);
ithread_mutex_destroy(ps_dec->apv_proc_start_mutex[i]);
ithread_mutex_destroy(ps_dec->apv_proc_done_mutex[i]);
}
}
PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_mutex[0]);
PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->apv_proc_start_condition[0]);
#endif
if(0 == u1_layer_id)
{
UWORD8 u1_sps_ctr;
PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sps);
for(u1_sps_ctr = 0; u1_sps_ctr < (2 * MAX_NUM_SEQ_PARAMS); u1_sps_ctr++)
{
if(NULL != ps_svcd_ctxt->ps_subset_sps[u1_sps_ctr].s_sps_svc_ext.ps_svc_vui_ext)
{
PS_DEC_ALIGNED_FREE(
ps_dec,
ps_svcd_ctxt->ps_subset_sps[u1_sps_ctr].s_sps_svc_ext.ps_svc_vui_ext);
}
}
PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->ps_subset_sps);
PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_pps);
PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sei);
PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_sei_parse);
}
PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->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->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_dpb_cmds);
PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_bitstrm);
PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->ps_nal_svc_ext);
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_svc_lyr_dec->pv_scratch_subset_sps);
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->ps_col_mv_base);
PS_DEC_ALIGNED_FREE(ps_dec, ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma);
if(NULL != ps_dec->pv_pic_buf_mgr)
{
if(u1_layer_id < ps_svcd_ctxt->u1_prev_num_res_layers)
{
if(((buf_mgr_t *) ps_dec->pv_pic_buf_mgr)->pv_mutex != NULL)
ih264_buf_mgr_free(ps_dec->pv_pic_buf_mgr);
}
PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_pic_buf_mgr);
}
if(NULL != ps_dec->pv_mv_buf_mgr)
{
if(u1_layer_id < ps_svcd_ctxt->u1_prev_num_res_layers)
{
if(((buf_mgr_t *) ps_dec->pv_mv_buf_mgr)->pv_mutex != NULL)
ih264_buf_mgr_free(ps_dec->pv_mv_buf_mgr);
}
PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pv_mv_buf_mgr);
}
}
pf_aligned_free(pv_mem_ctxt, ps_svcd_ctxt->ps_svc_dec_lyr);
pf_aligned_free(pv_mem_ctxt, dec_hdl->pv_codec_handle);
if(dec_hdl)
{
pf_aligned_free(pv_mem_ctxt, dec_hdl);
}
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_nal_parse_init */
/* */
/* Description : Initiaization of allocation of memory */
/* */
/* Inputs : pv_mem_rec - Allocated memory records */
/* */
/* Globals : None */
/* */
/* Processing : None */
/* */
/* Outputs : None */
/* */
/* Returns : Module's handle */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* DD MM YYYY Author(s) Changes */
/* 06 09 2021 Vijay Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_nal_parse_ctxt_create(svc_dec_ctxt_t *ps_svcd_ctxt, void *pv_api_ip, void *pv_api_op)
{
isvcd_create_ip_t *ps_create_ip;
void *pv_buf;
void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
void *pv_mem_ctxt;
WORD32 size;
nal_parse_ctxt_t *ps_nal_parse_ctxt;
UWORD8 *pu1_ptr;
UNUSED(pv_api_op);
ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
/*-----------------------------------------------------------------------*/
/* Handle */
/*-----------------------------------------------------------------------*/
size = sizeof(nal_parse_ctxt_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_nal_parse_ctxt = pv_buf;
/* set the lowest dqid to -1 */
ps_nal_parse_ctxt->i4_prev_dq_id = -1;
/*-----------------------------------------------------------------------*/
/* DQID list buffer and initialization of vcl node buffer context */
/*-----------------------------------------------------------------------*/
{
WORD32 i4_lyr_idx;
WORD32 i4_max_num_lyrs;
vcl_node_t *ps_vcl_node;
dqid_node_t *ps_dqid_node;
dqid_ctxt_t *ps_dqid_ctxt;
size = sizeof(vcl_node_t);
size += sizeof(dqid_node_t);
size *= MAX_NUM_RES_LYRS;
ps_dqid_ctxt = &ps_nal_parse_ctxt->s_dqid_ctxt;
ps_dqid_ctxt->i4_max_num_lyrs = MAX_NUM_RES_LYRS;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dqid_ctxt->ps_dqid_node = pv_buf;
ps_dqid_node = ps_dqid_ctxt->ps_dqid_node;
i4_max_num_lyrs = ps_dqid_ctxt->i4_max_num_lyrs;
pu1_ptr = pv_buf;
pu1_ptr += sizeof(dqid_node_t) * i4_max_num_lyrs;
ps_vcl_node = (vcl_node_t *) pu1_ptr;
for(i4_lyr_idx = 0; i4_lyr_idx < i4_max_num_lyrs; i4_lyr_idx++)
{
ps_dqid_node->ps_vcl_node = ps_vcl_node;
/* Loop updates */
ps_vcl_node += 1;
ps_dqid_node += 1;
} /* Loop over all the layers */
}
/*-----------------------------------------------------------------------*/
/* Common memory */
/*-----------------------------------------------------------------------*/
size = UP_ALIGN_8(HEADER_BUFFER_LEN_BEFORE_EP);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_nal_parse_ctxt->pv_nal_header_buf = (void *) pv_buf;
/*-----------------------------------------------------------------------*/
/* Layer params memory */
/*-----------------------------------------------------------------------*/
size = sizeof(nal_unit_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_nal_parse_ctxt->pv_nal_unit = pv_buf;
size = MAX_VCL_NAL_BUFF_SIZE * sizeof(UWORD8);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_svcd_ctxt->pv_vcl_nal_buff = pv_buf;
size = MAX_NON_VCL_NAL_BUFF_SIZE * sizeof(UWORD8);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_svcd_ctxt->pv_non_vcl_nal_buff = pv_buf;
/*-----------------------------------------------------------------------*/
/* Registering the seq and pic prms buffer pointers */
/*-----------------------------------------------------------------------*/
if(NULL == ps_svcd_ctxt->ps_sps || NULL == ps_svcd_ctxt->ps_pps)
{
return IV_FAIL;
}
ps_svcd_ctxt->pv_nal_parse_ctxt = ps_nal_parse_ctxt;
ps_nal_parse_ctxt->pv_seq_prms = ps_svcd_ctxt->ps_sps;
ps_nal_parse_ctxt->pv_pic_prms = ps_svcd_ctxt->ps_pps;
/* register VCL and NON VCL buffer pointers */
if(NULL == ps_svcd_ctxt->pv_vcl_nal_buff || NULL == ps_svcd_ctxt->pv_non_vcl_nal_buff)
{
return IV_FAIL;
}
ps_nal_parse_ctxt->pv_vcl_nal_buf = (UWORD8 *) ps_svcd_ctxt->pv_vcl_nal_buff;
ps_nal_parse_ctxt->pv_non_vcl_nal_buf = (UWORD8 *) ps_svcd_ctxt->pv_non_vcl_nal_buff;
isvcd_nal_parse_reset_ctxt(ANNEX_B, PARTIAL_INPUT_MODE, ps_nal_parse_ctxt);
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_intra_resample_ctxt_create */
/* */
/* Description :this function is used to create intra_resamp context */
/* Inputs : */
/* Globals : none */
/* Processing : */
/* */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 25 11 2021 Kishore creation */
/* */
/*****************************************************************************/
WORD32 isvcd_intra_resample_ctxt_create(svc_dec_ctxt_t *ps_svcd_ctxt, void *pv_api_ip,
void *pv_api_op)
{
isvcd_create_ip_t *ps_create_ip;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
void *pv_buf;
UWORD8 u1_layer_id;
void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
void *pv_mem_ctxt;
WORD32 size;
intra_inter_pred_ctxt_t *ps_ii_pred_ctxt;
intra_sampling_ctxt_t *ps_ctxt;
UNUSED(pv_api_op);
ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
{
intra_samp_lyr_ctxt *ps_lyr_ctxt;
/* allocate context structure */
size = ((sizeof(intra_sampling_ctxt_t) + 127) >> 7) << 7;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_ctxt = pv_buf;
/* luma reference array buffer */
size = REF_ARRAY_WIDTH * REF_ARRAY_HEIGHT * sizeof(UWORD8);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_ctxt->pu1_refarray_buffer = pv_buf;
/* cb reference array buffer */
size = REF_ARRAY_WIDTH * REF_ARRAY_HEIGHT * sizeof(UWORD8);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_ctxt->pu1_refarray_cb = pv_buf;
/* cr reference array buffer */
size = ((DYADIC_REF_W_C + 2) * (DYADIC_REF_H_C + 2) * sizeof(UWORD8));
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_ctxt->pu1_refarray_cr = pv_buf;
/* Temp Intermediate Buffer */
size = INTERMEDIATE_BUFF_WIDTH * INTERMEDIATE_BUFF_HEIGHT * sizeof(WORD32);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_ctxt->pi4_temp_interpolation_buffer = pv_buf;
/****************** projected locations buffers ******************/
{
intra_samp_map_ctxt_t *ps_luma_map;
intra_samp_map_ctxt_t *ps_chroma_map;
WORD32 i4_lyr_id;
ref_mb_map_t *ps_off_len_map;
ref_pixel_map_t *ps_pos_phase_map;
ref_min_max_map_t *ps_min_max;
WORD16 *pi2_mem;
UWORD8 *pu1_mem;
seg_lookup_desc_t *ps_seg_lookup;
/****************** Horz offset length ******************/
size = (H264_MAX_FRAME_WIDTH >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_off_len_map = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_x_offset_length = ps_off_len_map;
ps_off_len_map += (H264_MAX_FRAME_WIDTH >> 4);
ps_chroma_map->ps_x_offset_length = ps_off_len_map;
ps_off_len_map += (H264_MAX_FRAME_WIDTH >> 4);
} /* end of loop over resolution layers */
/****************** Vert offset length ******************/
size = (H264_MAX_FRAME_HEIGHT >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_off_len_map = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_y_offset_length = ps_off_len_map;
ps_off_len_map += (H264_MAX_FRAME_HEIGHT >> 4);
ps_chroma_map->ps_y_offset_length = ps_off_len_map;
ps_off_len_map += (H264_MAX_FRAME_HEIGHT >> 4);
} /* end of loop over resolution layers */
/****************** Horz Min Max Pos ******************/
size = (H264_MAX_FRAME_WIDTH >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_min_max = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_x_min_max = ps_min_max;
ps_min_max += (H264_MAX_FRAME_WIDTH >> 4);
ps_chroma_map->ps_x_min_max = ps_min_max;
ps_min_max += (H264_MAX_FRAME_WIDTH >> 4);
} /* end of loop over resolution layers */
/****************** Vert Min Max Pos ******************/
size = (H264_MAX_FRAME_HEIGHT >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_min_max = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_y_min_max = ps_min_max;
ps_min_max += (H264_MAX_FRAME_HEIGHT >> 4);
ps_chroma_map->ps_y_min_max = ps_min_max;
ps_min_max += (H264_MAX_FRAME_HEIGHT >> 4);
} /* end of loop over resolution layers */
/****************** Horz position phase ******************/
size = (H264_MAX_FRAME_WIDTH) *MAX_NUM_RES_LYRS * 2 * sizeof(ref_pixel_map_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_pos_phase_map = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_x_pos_phase = ps_pos_phase_map;
ps_pos_phase_map += (H264_MAX_FRAME_WIDTH);
ps_chroma_map->ps_x_pos_phase = ps_pos_phase_map;
ps_pos_phase_map += (H264_MAX_FRAME_WIDTH);
} /* end of loop over resolution layers */
/****************** Vert position phase ******************/
size = (H264_MAX_FRAME_HEIGHT) *MAX_NUM_RES_LYRS * 2 * sizeof(ref_pixel_map_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_pos_phase_map = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_y_pos_phase = ps_pos_phase_map;
ps_pos_phase_map += (H264_MAX_FRAME_HEIGHT);
ps_chroma_map->ps_y_pos_phase = ps_pos_phase_map;
ps_pos_phase_map += (H264_MAX_FRAME_HEIGHT);
} /* end of loop over resolution layers */
/**************** XD Index ******************************/
size = (MB_WIDTH) *MAX_NUM_RES_LYRS * 2 * sizeof(WORD16);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
pi2_mem = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->pi2_xd_index = pi2_mem;
pi2_mem += MB_WIDTH;
ps_chroma_map->pi2_xd_index = pi2_mem;
pi2_mem += MB_WIDTH;
} /* end of loop over resolution layers */
/**************** YD Index ******************************/
size = (MB_HEIGHT) *MAX_NUM_RES_LYRS * 2 * sizeof(WORD16);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
pi2_mem = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->pi2_yd_index = pi2_mem;
pi2_mem += MB_HEIGHT;
ps_chroma_map->pi2_yd_index = pi2_mem;
pi2_mem += MB_HEIGHT;
} /* end of loop over resolution layers */
/**************** YA Index ******************************/
size = MB_HEIGHT * MAX_NUM_RES_LYRS * 2 * sizeof(WORD16);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
pi2_mem = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->pi2_ya_index = pi2_mem;
pi2_mem += MB_HEIGHT;
ps_chroma_map->pi2_ya_index = pi2_mem;
pi2_mem += MB_HEIGHT;
} /* end of loop over resolution layers */
/**************** Horizontal segment lookup **************************/
/* (MB_WIDTH x seg_lookup_desc_t) x (num layers - 1) (for luma )*/
/* (BLOCK_WIDTH x seg_lookup_desc_t) x (num layers - 1) (for chroma )*/
size = (MB_WIDTH * sizeof(seg_lookup_desc_t)) * MAX_NUM_RES_LYRS;
size += (BLOCK_WIDTH * sizeof(seg_lookup_desc_t)) * MAX_NUM_RES_LYRS;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_seg_lookup = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_seg_lookup_horz = ps_seg_lookup;
ps_seg_lookup += MB_WIDTH;
ps_chroma_map->ps_seg_lookup_horz = ps_seg_lookup;
ps_seg_lookup += BLOCK_WIDTH;
} /* end of loop over resolution layers */
/**************** Vertical segment lookup ****************************/
/* (MB_HEIGHT x seg_lookup_desc_t) x (num layers - 1) (for luma )*/
/* (BLOCK_HEIGHT x seg_lookup_desc_t) x (num layers - 1) (for chroma)*/
size = (MB_HEIGHT * sizeof(seg_lookup_desc_t)) * MAX_NUM_RES_LYRS;
size += (BLOCK_HEIGHT * sizeof(seg_lookup_desc_t)) * MAX_NUM_RES_LYRS;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_seg_lookup = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_seg_lookup_vert = ps_seg_lookup;
ps_seg_lookup += MB_HEIGHT;
ps_chroma_map->ps_seg_lookup_vert = ps_seg_lookup;
ps_seg_lookup += BLOCK_HEIGHT;
} /* end of loop over resolution layers */
/**************** X and Y Reference Array Index lookup ***************/
/* (MAX_REF_IDX_ARRAY) x (num layers - 1) (for luma x-index) */
/* (MAX_REF_IDX_ARRAY) x (num layers - 1) (for luma y-index) */
/* (MAX_REF_IDX_ARRAY) x (num layers - 1) (for chroma x-index) */
/* (MAX_REF_IDX_ARRAY) x (num layers - 1) (for chroma y-index) */
/*********************************************************************/
size = (MAX_REF_IDX_ARRAY * MAX_NUM_RES_LYRS * 4);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
pu1_mem = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->pu1_refarray_x_idx = pu1_mem;
pu1_mem += MAX_REF_IDX_ARRAY;
ps_luma_map->pu1_refarray_y_idx = pu1_mem;
pu1_mem += MAX_REF_IDX_ARRAY;
ps_chroma_map->pu1_refarray_x_idx = pu1_mem;
pu1_mem += MAX_REF_IDX_ARRAY;
ps_chroma_map->pu1_refarray_y_idx = pu1_mem;
pu1_mem += MAX_REF_IDX_ARRAY;
} /* end of loop over resolution layers */
}
size = ((sizeof(intra_inter_pred_ctxt_t) + 127) >> 7) << 7;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_ii_pred_ctxt = pv_buf;
}
ps_svcd_ctxt->pv_intra_sample_ctxt = ps_ctxt;
ps_svcd_ctxt->pv_ii_pred_ctxt = ps_ii_pred_ctxt;
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_svc_lyr_dec->pv_intra_sample_ctxt = ps_svcd_ctxt->pv_intra_sample_ctxt;
ps_svc_lyr_dec->pv_ii_pred_ctxt = ps_svcd_ctxt->pv_ii_pred_ctxt;
}
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_residual_resample_ctxt_create */
/* */
/* Description :this function is used to create resd_resamp context */
/* Inputs : */
/* Globals : none */
/* Processing : */
/* */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 25 11 2021 ittiam creation */
/* */
/*****************************************************************************/
WORD32 isvcd_residual_resample_ctxt_create(svc_dec_ctxt_t *ps_svcd_ctxt, void *pv_api_ip,
void *pv_api_op)
{
isvcd_create_ip_t *ps_create_ip;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
void *pv_buf;
UWORD8 u1_layer_id;
void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
void *pv_mem_ctxt;
WORD32 size;
residual_sampling_ctxt_t *ps_ctxt;
res_lyr_ctxt *ps_lyr_ctxt;
UNUSED(pv_api_op);
ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
/* allocate context structure */
size = ((sizeof(residual_sampling_ctxt_t) + 127) >> 7) << 7;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_ctxt = pv_buf;
/* reference array buffer */
size = REF_ARRAY_WIDTH_RES_SAMP * REF_ARRAY_HEIGHT_RES_SAMP * sizeof(WORD16);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_ctxt->pi2_refarray_buffer = pv_buf;
/* reference array pointer increment buffer */
{
WORD32 i4_size;
i4_size = REF_ARRAY_WIDTH_RES_SAMP * REF_ARRAY_HEIGHT_RES_SAMP * sizeof(UWORD8);
size = REF_ARRAY_WIDTH_RES_SAMP * REF_ARRAY_HEIGHT_RES_SAMP * 2 * sizeof(UWORD8);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_ctxt->pu1_ref_x_ptr_incr = pv_buf;
ps_ctxt->pu1_ref_y_ptr_incr = ps_ctxt->pu1_ref_x_ptr_incr + i4_size;
}
/****************** projected locations buffers ******************/
{
residual_samp_map_ctxt_t *ps_luma_map;
residual_samp_map_ctxt_t *ps_chroma_map;
WORD32 i4_lyr_id;
ref_mb_map_t *ps_off_len_map;
ref_pixel_map_t *ps_pos_phase_map;
/****************** Horz offset length ******************/
size = (H264_MAX_FRAME_WIDTH >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_off_len_map = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_x_offset_length = ps_off_len_map;
ps_off_len_map += (H264_MAX_FRAME_WIDTH >> 4);
ps_chroma_map->ps_x_offset_length = ps_off_len_map;
ps_off_len_map += (H264_MAX_FRAME_WIDTH >> 4);
} /* end of loop over resolution layers */
/****************** Vert offset length ******************/
size = (H264_MAX_FRAME_HEIGHT >> 4) * MAX_NUM_RES_LYRS * 2 * sizeof(ref_mb_map_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_off_len_map = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_y_offset_length = ps_off_len_map;
ps_off_len_map += (H264_MAX_FRAME_HEIGHT >> 4);
ps_chroma_map->ps_y_offset_length = ps_off_len_map;
ps_off_len_map += (H264_MAX_FRAME_HEIGHT >> 4);
} /* end of loop over resolution layers */
/****************** Horz position phase ******************/
size = H264_MAX_FRAME_WIDTH * MAX_NUM_RES_LYRS * 2 * sizeof(ref_pixel_map_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_pos_phase_map = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_x_pos_phase = ps_pos_phase_map;
ps_pos_phase_map += H264_MAX_FRAME_WIDTH;
ps_chroma_map->ps_x_pos_phase = ps_pos_phase_map;
ps_pos_phase_map += H264_MAX_FRAME_WIDTH;
} /* end of loop over resolution layers */
/****************** Vert position phase ******************/
size = H264_MAX_FRAME_HEIGHT * MAX_NUM_RES_LYRS * 2 * sizeof(ref_pixel_map_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_pos_phase_map = pv_buf;
/* loop over num layers -1 */
for(i4_lyr_id = 0; i4_lyr_id < MAX_NUM_RES_LYRS; i4_lyr_id++)
{
/* derive the layer map ctxt */
ps_lyr_ctxt = &ps_ctxt->as_res_lyrs[i4_lyr_id];
ps_luma_map = &ps_lyr_ctxt->s_luma_map_ctxt;
ps_chroma_map = &ps_lyr_ctxt->s_chroma_map_ctxt;
/* initialise the pointers */
ps_luma_map->ps_y_pos_phase = ps_pos_phase_map;
ps_pos_phase_map += H264_MAX_FRAME_HEIGHT;
ps_chroma_map->ps_y_pos_phase = ps_pos_phase_map;
ps_pos_phase_map += H264_MAX_FRAME_HEIGHT;
} /* end of loop over resolution layers */
}
ps_svcd_ctxt->pv_residual_sample_ctxt = ps_ctxt;
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_svc_lyr_dec->pv_residual_sample_ctxt = ps_svcd_ctxt->pv_residual_sample_ctxt;
}
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_mode_mv_resample_ctxt_create */
/* */
/* Description :this function is used to create mv_resamp context */
/* Inputs : */
/* Globals : none */
/* Processing : */
/* */
/* Outputs : none */
/* Returns : none */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 25 11 2021 Kishore creation */
/* */
/*****************************************************************************/
WORD32 isvcd_mode_mv_resample_ctxt_create(svc_dec_ctxt_t *ps_svcd_ctxt, void *pv_api_ip,
void *pv_api_op)
{
isvcd_create_ip_t *ps_create_ip;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
void *pv_buf;
WORD16 *pi2_mem;
UWORD8 u1_layer_id;
void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
void *pv_mem_ctxt;
WORD32 size, i4_res_id;
ref_lyr_scaled_offset_t *ps_ref_pic_offsets;
mode_motion_ctxt_t *ps_mode_motion;
mode_motion_lyr_ctxt *ps_lyr_mem;
UNUSED(pv_api_op);
ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
size = ((sizeof(mode_motion_ctxt_t) + 127) >> 7) << 7;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_mode_motion = pv_buf;
/* motion pred structure */
size = 2 * NUM_MB_PARTS * NUM_SUB_MB_PARTS * sizeof(mv_pred_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_mode_motion->ps_motion_pred_struct = (mv_pred_t *) pv_buf;
/* projected locations X */
size = H264_MAX_FRAME_WIDTH * MAX_NUM_RES_LYRS * sizeof(WORD16);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
pi2_mem = (WORD16 *) pv_buf;
/* loop over NUM resolution layers */
for(i4_res_id = 0; i4_res_id < MAX_NUM_RES_LYRS; i4_res_id++)
{
ps_lyr_mem = &ps_mode_motion->as_res_lyr_mem[i4_res_id];
/* initialise the pointers */
ps_lyr_mem->pi2_ref_loc_x = pi2_mem;
/* increment the buffer pointer */
pi2_mem += H264_MAX_FRAME_WIDTH;
} /* end of loop over num resolution layers */
/* projected locations Y */
size = H264_MAX_FRAME_HEIGHT * MAX_NUM_RES_LYRS * sizeof(WORD16);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
pi2_mem = (WORD16 *) pv_buf;
/* loop over NUM resolution layers */
for(i4_res_id = 0; i4_res_id < MAX_NUM_RES_LYRS; i4_res_id++)
{
ps_lyr_mem = &ps_mode_motion->as_res_lyr_mem[i4_res_id];
/* initialise the pointers */
ps_lyr_mem->pi2_ref_loc_y = pi2_mem;
/* increment the buffer pointer */
pi2_mem += H264_MAX_FRAME_HEIGHT;
} /* end of loop over num resolution layers */
size = sizeof(ref_lyr_scaled_offset_t) * MAX_NUM_RES_LYRS * MAX_NUM_PIC_BUFS;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_svcd_ctxt->pv_ref_lyr_offset = pv_buf;
/* loop over NUM resolution layers */
ps_ref_pic_offsets = (ref_lyr_scaled_offset_t *) ps_svcd_ctxt->pv_ref_lyr_offset;
for(i4_res_id = 0; i4_res_id < MAX_NUM_RES_LYRS; i4_res_id++)
{
ps_lyr_mem = &ps_mode_motion->as_res_lyr_mem[i4_res_id];
/* store the current resolution layer pic offset start pointer */
ps_lyr_mem->ps_ref_pic_lyr_offsets = ps_ref_pic_offsets + (i4_res_id * MAX_NUM_PIC_BUFS);
} /* end of loop over num resolution layers */
ps_svcd_ctxt->pv_mode_mv_sample_ctxt = ps_mode_motion;
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_svc_lyr_dec->pv_mode_mv_sample_ctxt = ps_svcd_ctxt->pv_mode_mv_sample_ctxt;
ps_svc_lyr_dec->pv_ref_lyr_offset = ps_svcd_ctxt->pv_ref_lyr_offset;
}
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_allocate_static_bufs */
/* */
/* Description : allocates static buffers */
/* */
/* 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) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_allocate_static_bufs(iv_obj_t **dec_hdl, void *pv_api_ip, void *pv_api_op)
{
isvcd_create_ip_t *ps_create_ip;
isvcd_create_op_t *ps_create_op;
void *pv_buf;
UWORD8 *pu1_buf;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
svc_dec_ctxt_t *ps_svcd_ctxt;
void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
void *pv_mem_ctxt;
WORD32 size;
UWORD8 u1_layer_id, u1_sps_ctr;
UWORD8 u1_chroma_format;
WORD32 ret;
ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
ps_create_op = (isvcd_create_op_t *) pv_api_op;
ps_create_op->s_ivd_create_op_t.u4_error_code = 0;
pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free;
pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
u1_chroma_format = (UWORD8) (ps_create_ip->s_ivd_create_ip_t.e_output_format);
if((u1_chroma_format != IV_YUV_420P) && (u1_chroma_format != IV_YUV_420SP_UV) &&
(u1_chroma_format != IV_YUV_420SP_VU))
{
ps_create_op->s_ivd_create_op_t.pv_handle = NULL;
return IV_FAIL;
}
/* Initialize return handle to NULL */
ps_create_op->s_ivd_create_op_t.pv_handle = NULL;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(iv_obj_t));
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, sizeof(iv_obj_t));
*dec_hdl = (iv_obj_t *) pv_buf;
ps_create_op->s_ivd_create_op_t.pv_handle = *dec_hdl;
(*dec_hdl)->pv_codec_handle = NULL;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(svc_dec_ctxt_t));
RETURN_IF((NULL == pv_buf), IV_FAIL);
(*dec_hdl)->pv_codec_handle = (svc_dec_ctxt_t *) pv_buf;
ps_svcd_ctxt = (svc_dec_ctxt_t *) pv_buf;
memset(ps_svcd_ctxt, 0, sizeof(svc_dec_ctxt_t));
ps_svcd_ctxt->u1_prev_num_res_layers = UINT8_MAX;
ps_svcd_ctxt->u1_pre_parse_in_flush = 1;
/* set default to maximum values supported */
ps_svcd_ctxt->u1_tgt_dep_id = MAX_DEPENDENCY_ID;
ps_svcd_ctxt->u1_tgt_quality_id = MAX_QUALITY_ID;
ps_svcd_ctxt->u1_tgt_temp_id = MAX_TEMPORAL_ID;
ps_svcd_ctxt->u1_tgt_priority_id = MAX_PRIORITY_ID;
/* two sets of MAX_NUM_SEQ_PARAMS are created one for sps-base layer; one for
* subset_sps- enhancement*/
size = ((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS * 2);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_svcd_ctxt->ps_sps = pv_buf;
/* two sets of MAX_NUM_SEQ_PARAMS are created one for sps-base layer; one for
* subset_sps- enhancement*/
size = ((sizeof(dec_svc_seq_params_t)) * MAX_NUM_SEQ_PARAMS * 2);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_svcd_ctxt->ps_subset_sps = pv_buf;
for(u1_sps_ctr = 0; u1_sps_ctr < (2 * MAX_NUM_SEQ_PARAMS); u1_sps_ctr++)
{
ps_svcd_ctxt->ps_subset_sps[u1_sps_ctr].ps_seq = &ps_svcd_ctxt->ps_sps[u1_sps_ctr];
}
size = sizeof(sei);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_svcd_ctxt->ps_sei = (sei *) pv_buf;
size = sizeof(sei);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_svcd_ctxt->ps_sei_parse = (sei *) pv_buf;
size = (sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_svcd_ctxt->ps_pps = pv_buf;
size = (sizeof(svc_dec_lyr_struct_t)) * MAX_NUM_RES_LYRS;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_svcd_ctxt->ps_svc_dec_lyr = pv_buf;
ps_svcd_ctxt->u1_target_layer_id = 0;
ps_svcd_ctxt->u1_cur_layer_id = 0;
ps_svcd_ctxt->i4_eos_flag = 0;
ret = isvcd_mode_mv_resample_ctxt_create(ps_svcd_ctxt, pv_api_ip, pv_api_op);
if(ret != IV_SUCCESS)
{
return ret;
}
ret = isvcd_intra_resample_ctxt_create(ps_svcd_ctxt, pv_api_ip, pv_api_op);
if(ret != IV_SUCCESS)
{
return ret;
}
ret = isvcd_residual_resample_ctxt_create(ps_svcd_ctxt, pv_api_ip, pv_api_op);
if(ret != IV_SUCCESS)
{
return ret;
}
ret = isvcd_nal_parse_ctxt_create(ps_svcd_ctxt, pv_api_ip, pv_api_op);
if(ret != IV_SUCCESS)
{
return ret;
}
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
ps_svc_lyr_dec->ps_svcd_ctxt = ps_svcd_ctxt;
ps_svc_lyr_dec->u1_layer_id = u1_layer_id;
ps_svc_lyr_dec->u1_dyadic_flag = 1;
ps_svc_lyr_dec->u1_restricted_res_change_flag = 1;
ps_svc_lyr_dec->u1_base_res_flag = 1;
ps_svc_lyr_dec->u1_ref_layer_id = 0;
ps_svc_lyr_dec->ps_dec_svc_ref_layer =
&ps_svcd_ctxt->ps_svc_dec_lyr[ps_svc_lyr_dec->u1_ref_layer_id];
ps_svc_lyr_dec->u4_pps_id_for_layer = UINT32_MAX;
#ifndef LOGO_EN
ps_dec->u4_share_disp_buf = ps_create_ip->s_ivd_create_ip_t.u4_share_disp_buf;
#else
ps_dec->u4_share_disp_buf = 0;
#endif
ps_dec->u1_chroma_format = (UWORD8) (ps_create_ip->s_ivd_create_ip_t.e_output_format);
if((ps_dec->u1_chroma_format != IV_YUV_420P) &&
(ps_dec->u1_chroma_format != IV_YUV_420SP_UV) &&
(ps_dec->u1_chroma_format != IV_YUV_420SP_VU))
{
ps_dec->u4_share_disp_buf = 0;
}
ps_dec->u1_enable_mb_info = ps_create_ip->u4_enable_frame_info;
ps_dec->pf_aligned_alloc = pf_aligned_alloc;
ps_dec->pf_aligned_free = pf_aligned_free;
ps_dec->pv_mem_ctxt = pv_mem_ctxt;
ps_dec->ps_sps = ps_svcd_ctxt->ps_sps;
ps_svc_lyr_dec->ps_subset_sps = ps_svcd_ctxt->ps_subset_sps;
ps_dec->ps_pps = ps_svcd_ctxt->ps_pps;
ps_dec->ps_sei = ps_svcd_ctxt->ps_sei;
ps_dec->ps_sei_parse = ps_svcd_ctxt->ps_sei_parse;
size = ithread_get_handle_size();
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pv_dec_thread_handle = pv_buf;
size = ithread_get_handle_size();
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pv_bs_deblk_thread_handle = pv_buf;
#ifdef KEEP_THREADS_ACTIVE
{
UWORD32 i;
/* Request memory to hold mutex (start/done) for both threads */
size = ithread_get_mutex_lock_size() << 2;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 8, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
// init mutex variable for both the threads
// 1. ih264d_decode_picture_thread
// 2. ih264d_recon_deblk_thread
for(i = 0; i < 2; i++)
{
WORD32 ret;
WORD32 mutex_size = ithread_get_mutex_lock_size();
ps_dec->apv_proc_start_mutex[i] = (UWORD8 *) pv_buf + (2 * i * mutex_size);
ps_dec->apv_proc_done_mutex[i] = (UWORD8 *) pv_buf + ((2 * i + 1) * mutex_size);
ret = ithread_mutex_init(ps_dec->apv_proc_start_mutex[0]);
RETURN_IF((ret != IV_SUCCESS), ret);
ret = ithread_mutex_init(ps_dec->apv_proc_done_mutex[i]);
RETURN_IF((ret != IV_SUCCESS), ret);
}
size = ithread_get_cond_struct_size() << 2;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 8, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
// init condition variable for both the threads
for(i = 0; i < 2; i++)
{
WORD32 ret;
WORD32 cond_size = ithread_get_cond_struct_size();
ps_dec->apv_proc_start_condition[i] = (UWORD8 *) pv_buf + (2 * i * cond_size);
ps_dec->apv_proc_done_condition[i] = (UWORD8 *) pv_buf + ((2 * i + 1) * cond_size);
ret = ithread_cond_init(ps_dec->apv_proc_start_condition[i]);
RETURN_IF((ret != IV_SUCCESS), ret);
ret = ithread_cond_init(ps_dec->apv_proc_done_condition[i]);
RETURN_IF((ret != IV_SUCCESS), ret);
}
}
#endif
size = sizeof(dpb_manager_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->ps_dpb_mgr = pv_buf;
size = sizeof(pred_info_t) * 2 * 32;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->ps_pred = pv_buf;
size = sizeof(disp_mgr_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pv_disp_buf_mgr = pv_buf;
size = ih264_buf_mgr_size();
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pv_pic_buf_mgr = pv_buf;
size = sizeof(struct pic_buffer_t) * (H264_MAX_REF_PICS * 2);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->ps_pic_buf_base = pv_buf;
size = sizeof(dec_err_status_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->ps_dec_err_status = (dec_err_status_t *) pv_buf;
size = sizeof(dpb_commands_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->ps_dpb_cmds = (dpb_commands_t *) pv_buf;
size = sizeof(dec_bit_stream_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->ps_bitstrm = (dec_bit_stream_t *) pv_buf;
size = sizeof(dec_nal_unit_svc_ext_params_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_svc_lyr_dec->ps_nal_svc_ext = (dec_nal_unit_svc_ext_params_t *) pv_buf;
size = sizeof(dec_slice_params_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->ps_cur_slice = (dec_slice_params_t *) pv_buf;
size = MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t));
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pv_scratch_sps_pps = pv_buf;
size = sizeof(dec_svc_seq_params_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_svc_lyr_dec->pv_scratch_subset_sps = pv_buf;
ps_dec->u4_static_bits_buf_size = 256000;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, ps_dec->u4_static_bits_buf_size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, ps_dec->u4_static_bits_buf_size);
ps_dec->pu1_bits_buf_static = pv_buf;
size = ((TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC) * sizeof(void *));
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
ps_dec->ppv_map_ref_idx_to_poc_base = pv_buf;
memset(ps_dec->ppv_map_ref_idx_to_poc_base, 0, size);
ps_dec->ppv_map_ref_idx_to_poc = ps_dec->ppv_map_ref_idx_to_poc_base + OFFSET_MAP_IDX_POC;
size = (sizeof(bin_ctxt_model_t) * NUM_CABAC_CTXTS_SVC);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->p_cabac_ctxt_table_t = pv_buf;
size = sizeof(ctxt_inc_mb_info_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->ps_left_mb_ctxt_info = pv_buf;
size = MAX_REF_BUF_SIZE * 2;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pu1_ref_buff_base = pv_buf;
ps_dec->pu1_ref_buff = ps_dec->pu1_ref_buff_base + MAX_REF_BUF_SIZE;
size = ((sizeof(WORD16)) * PRED_BUFFER_WIDTH * PRED_BUFFER_HEIGHT * 2);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pi2_pred1 = pv_buf;
size = sizeof(UWORD8) * (MB_LUM_SIZE);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pu1_temp_mc_buffer = pv_buf;
size = 8 * MAX_REF_BUFS * sizeof(struct pic_buffer_t);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pu1_init_dpb_base = pv_buf;
pu1_buf = pv_buf;
ps_dec->ps_dpb_mgr->ps_init_dpb[0][0] = (struct pic_buffer_t *) pu1_buf;
pu1_buf += size / 2;
ps_dec->ps_dpb_mgr->ps_init_dpb[1][0] = (struct pic_buffer_t *) pu1_buf;
size = (sizeof(UWORD32) * 2 * 3 * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1)) * 2);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pu4_mbaff_wt_mat = pv_buf;
size = sizeof(UWORD32) * 2 * 3 * ((MAX_FRAMES << 1) * (MAX_FRAMES << 1));
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pu4_wts_ofsts_mat = pv_buf;
size = (sizeof(neighbouradd_t) << 2);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->ps_left_mvpred_addr = pv_buf;
size = ih264_buf_mgr_size();
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
memset(pv_buf, 0, size);
ps_dec->pv_mv_buf_mgr = pv_buf;
size = sizeof(col_mv_buf_t) * (H264_MAX_REF_PICS * 2);
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
ps_dec->ps_col_mv_base = pv_buf;
memset(ps_dec->ps_col_mv_base, 0, size);
size = ((MB_SIZE * MB_SIZE * 3) >> 1) + MB_SIZE;
pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
RETURN_IF((NULL == pv_buf), IV_FAIL);
ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma = pv_buf;
ps_svc_lyr_dec->pu1_ii_resamp_buffer_chroma =
ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma + (MB_SIZE * MB_SIZE);
memset(ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma, 0, size);
isvcd_init_decoder(ps_svc_lyr_dec);
}
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_create */
/* */
/* Description : creates decoder */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore */
/* */
/*****************************************************************************/
WORD32 isvcd_create(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
isvcd_create_ip_t *ps_create_ip;
isvcd_create_op_t *ps_create_op;
WORD32 ret;
ps_create_ip = (isvcd_create_ip_t *) pv_api_ip;
ps_create_op = (isvcd_create_op_t *) pv_api_op;
ps_create_op->s_ivd_create_op_t.u4_error_code = 0;
dec_hdl = NULL;
ret = isvcd_allocate_static_bufs(&dec_hdl, pv_api_ip, pv_api_op);
/* If allocation of some buffer fails, then free buffers allocated till then */
if(IV_FAIL == ret)
{
if(dec_hdl)
{
if(dec_hdl->pv_codec_handle)
{
isvcd_free_static_bufs(dec_hdl);
}
else
{
void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
void *pv_mem_ctxt;
pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free;
pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
pf_aligned_free(pv_mem_ctxt, dec_hdl);
}
}
ps_create_op->s_ivd_create_op_t.u4_error_code = IVD_MEM_ALLOC_FAILED;
ps_create_op->s_ivd_create_op_t.u4_error_code |= 1 << IVD_FATALERROR;
return IV_FAIL;
}
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_update_dqid */
/* */
/* Description : Updates the DQID list based on reference layer DQID */
/* */
/* */
/* Inputs : 1. Reference layer DQID */
/* 2. current layer's vcl node structure */
/* 3. pointer to store the bottom layer VCL node */
/* Globals : None */
/* Processing : 1. Searches for a layer with reference layer DQID */
/* 2. Updates the bottom and top nodes of current layer and */
/* reference layer vcl nodes respectively */
/* */
/* Outputs : Updates top and bottom node field of vcl nodes of current*/
/* layer and reference layer respectively */
/* Returns : status */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Vijay Draft */
/*****************************************************************************/
WORD32 isvcd_update_dqid(WORD32 i4_ref_lyr_dqid, vcl_node_t *ps_cur_lyr_node,
vcl_node_t **pps_bot_lyr_node)
{
vcl_node_t *ps_vcl_node;
/* sanity checks */
if((NULL == ps_cur_lyr_node) || (NULL == pps_bot_lyr_node))
{
return NOT_OK;
}
ps_vcl_node = ps_cur_lyr_node->ps_bot_node;
while(NULL != ps_vcl_node)
{
WORD32 i4_dqid;
i4_dqid = (ps_vcl_node->i4_dependency_id << 4) + ps_vcl_node->i4_quality_id;
/* if reference layer DQ ID matches */
/* or reference layer is a layer below reference dq id layer */
if((i4_dqid == i4_ref_lyr_dqid) ||
(ps_vcl_node->i4_quality_id < (i4_ref_lyr_dqid & 0x0F)) ||
(ps_vcl_node->i4_dependency_id < (i4_ref_lyr_dqid >> 4)))
{
break;
}
ps_vcl_node = ps_vcl_node->ps_bot_node;
}
/* Update the top and bottom node of ref layer and current layer nodes */
if(NULL != ps_vcl_node)
{
ps_cur_lyr_node->ps_bot_node = ps_vcl_node;
ps_vcl_node->ps_top_node = ps_cur_lyr_node;
}
/* Update pointer to bottom VCL node */
*pps_bot_lyr_node = ps_vcl_node;
return (OK);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_detect_res_change */
/* */
/* Description : This function detects the resolution change */
/* */
/* */
/* Inputs : 1. Pointer to Current SPS */
/* 2. Pointer to prevoius SPS */
/* Globals : None */
/* Processing : */
/* */
/* Outputs : none */
/* Returns : SVCD_TRUE if different resolution else SVCD_FALSE */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Vijayakumar Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_detect_res_change(dec_seq_params_t *ps_curr_sps, dec_seq_params_t *ps_prev_sps,
dec_svc_seq_params_t *ps_curr_subset_sps,
dec_svc_seq_params_t *ps_prev_subset_sps)
{
UWORD16 u2_scaled_ref_width_sps;
UWORD16 u2_scaled_ref_ht_sps;
UNUSED(ps_prev_subset_sps);
if(NULL == ps_prev_sps)
{
/* indicates bottom most layer in Access unit */
return (SVCD_FALSE);
}
/* Check for the ESS idc */
if(2 == ps_curr_subset_sps->s_sps_svc_ext.u1_extended_spatial_scalability_idc)
{
return (SVCD_TRUE);
}
/* Calculate the scaled reference width and height */
u2_scaled_ref_width_sps = (ps_curr_sps->u2_frm_wd_in_mbs << 4);
u2_scaled_ref_width_sps -=
(ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_left_offset +
ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_right_offset);
u2_scaled_ref_ht_sps = (ps_curr_sps->u2_frm_ht_in_mbs << 4);
u2_scaled_ref_ht_sps -=
(ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_top_offset +
ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_bottom_offset);
/* Check for frame width being different */
if(u2_scaled_ref_width_sps != (ps_prev_sps->u2_frm_wd_in_mbs << 4))
{
return (SVCD_TRUE);
}
/* Check for frame height being different */
if(u2_scaled_ref_ht_sps != (ps_prev_sps->u2_frm_ht_in_mbs << 4))
{
return (SVCD_TRUE);
}
/* check for crop offset not MB aligned */
if((0 != (ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_left_offset & 15)) ||
(0 != (ps_curr_subset_sps->s_sps_svc_ext.i4_seq_scaled_ref_layer_top_offset & 15)))
{
return (SVCD_TRUE);
}
/* check for chroma Phase Y being different */
if(ps_curr_subset_sps->s_sps_svc_ext.u1_chroma_phase_x_plus1_flag !=
ps_curr_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_x_plus1_flag)
{
return (SVCD_TRUE);
}
/* check for chroma Phase Y being different */
if(ps_curr_subset_sps->s_sps_svc_ext.u1_chroma_phase_y_plus1 !=
ps_curr_subset_sps->s_sps_svc_ext.u1_seq_ref_layer_chroma_phase_y_plus1)
{
return (SVCD_TRUE);
}
/* If none of the above are true then there is no resolution change */
return (SVCD_FALSE);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_parse_ref_pic_list_modify */
/* */
/* Description : Parses the reference picture modification related */
/* syntax elements */
/* */
/* Inputs : 1. stream context structure */
/* 2. slice prms structure */
/* Globals : None */
/* Processing : Parses the syntax elements */
/* */
/* Outputs : Updated stream buffer context */
/* Returns : status */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Vijay Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_parse_ref_pic_list_modify(dec_bit_stream_t *ps_bitstrm,
dec_slice_params_t *ps_slice_prms,
dec_seq_params_t *ps_curr_sps)
{
WORD32 i4_mod_flag;
UWORD16 ui_nextUev;
WORD32 i4_num_sets_ctr = 0;
UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
if(I_SLICE != ps_slice_prms->u1_slice_type)
{
/* ref_pic_list_modification_flag_l0 */
i4_mod_flag = ih264d_get_bit_h264(ps_bitstrm);
if(0 != i4_mod_flag)
{
WORD32 i4_mod_pic_num_idc;
i4_num_sets_ctr = 0;
do
{
/* modification_of_pic_nums_idc */
i4_mod_pic_num_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if((i4_mod_pic_num_idc > 3) || (i4_mod_pic_num_idc < 0))
{
return ERROR_INV_SLICE_HDR_T;
}
if(3 != i4_mod_pic_num_idc)
{
/* i4_mod_pic_num_idc = 0,1 ==> abs_diff_pic_num_minus1 */
/* i4_mod_pic_num_idc = 2 ==> long_term_pic_num */
ui_nextUev = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(ui_nextUev > (ps_curr_sps->u2_u4_max_pic_num_minus1 + 1))
return ERROR_INV_SLICE_HDR_T;
}
i4_num_sets_ctr++;
/* if the number of commands recieved exceeds max limit */
if((H264_MAX_REF_PICS) == i4_num_sets_ctr) break;
} while(3 != i4_mod_pic_num_idc);
}
/*********** if (I_SLICE != u1_slice_type) ***************************/
}
if(B_SLICE != ps_slice_prms->u1_slice_type)
{
return (OK);
}
/* ref_pic_list_modification_flag_l1 */
i4_mod_flag = ih264d_get_bit_h264(ps_bitstrm);
if(0 != i4_mod_flag)
{
WORD32 i4_mod_pic_num_idc;
do
{
/* modification_of_pic_nums_idc */
i4_mod_pic_num_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if((i4_mod_pic_num_idc > 3) || (i4_mod_pic_num_idc < 0))
{
return ERROR_INV_SLICE_HDR_T;
}
if(3 != i4_mod_pic_num_idc)
{
/* i4_mod_pic_num_idc = 0,1 ==> abs_diff_pic_num_minus1 */
/* i4_mod_pic_num_idc = 2 ==> long_term_pic_num */
ui_nextUev = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(ui_nextUev > (ps_curr_sps->u2_u4_max_pic_num_minus1 + 1))
return ERROR_INV_SLICE_HDR_T;
}
i4_num_sets_ctr++;
/* if the number of commands recieved exceeds max limit */
if((H264_MAX_REF_PICS) == i4_num_sets_ctr) break;
} while(3 != i4_mod_pic_num_idc);
}
return (OK);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_parse_slice_hdr_refdq_id */
/* */
/* Description : this function decodes the slice until Inter layer deblk */
/* parameters are parsed */
/* */
/* Inputs : 1. pointer to VCL node of given layer */
/* 2. pointer toi slice params structure */
/* 3. pointer to layer params strcuture */
/* 4. pointer to stream context structure */
/* 5. pointer to store the reference DQID */
/* 6. pointer to array of SPS */
/* 7. pointer to array of PPS */
/* 8. no inter layer pred flag of current slice */
/* Globals : none */
/* Processing : prases syntax elements */
/* */
/* Outputs : reference layer DQ ID */
/* Returns : Error code */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 vijayakumar creation */
/* */
/*****************************************************************************/
WORD32 isvcd_parse_slice_hdr_refdq_id(vcl_node_t *ps_vcl_node, dec_slice_params_t *ps_slice_prms,
dec_bit_stream_t *ps_bitstrm, WORD32 *pi4_ref_dq_id,
dec_seq_params_t *ps_sps, dec_pic_params_t *ps_pps,
WORD32 i4_no_int_lyr_pred, svc_dec_ctxt_t *ps_svcd_ctxt)
{
UWORD8 u1_pps_id;
WORD32 i_temp;
UWORD32 u4_temp;
WORD32 i4_nal_unit_type;
WORD32 i4_nal_ref_idc, i4_quality_id;
WORD32 i4_use_ref_base, i4_idr_pic_flag;
UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
dec_svc_seq_params_t *ps_subset_sps = NULL;
WORD32 ret = OK;
i4_nal_unit_type = ps_vcl_node->i4_nal_unit_type;
i4_nal_ref_idc = ps_vcl_node->i4_nal_ref_idc;
i4_quality_id = ps_vcl_node->i4_quality_id;
i4_use_ref_base = ps_vcl_node->i4_use_ref_base;
i4_idr_pic_flag = ps_vcl_node->i4_idr_pic_flag;
/*-----------------------------------------------------------------------*/
/*--------------------- first mb in slice -------------------------------*/
/*-----------------------------------------------------------------------*/
ps_slice_prms->u2_first_mb_in_slice = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
/*-----------------------------------------------------------------------*/
/*---------------------------- slice type -------------------------------*/
/*-----------------------------------------------------------------------*/
ps_slice_prms->u1_slice_type = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(ps_slice_prms->u1_slice_type > 4)
{
ps_slice_prms->u1_slice_type -= 5;
}
/*-----------------------------------------------------------------------*/
/*----------------------------- PPS id ----------------------------------*/
/*-----------------------------------------------------------------------*/
u1_pps_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
/* set correspoding sps and pps id also */
ps_pps += u1_pps_id;
if(FALSE == ps_pps->u1_is_valid)
{
return ERROR_INV_SLICE_HDR_T;
}
ps_sps = ps_pps->ps_sps;
ps_subset_sps = &ps_svcd_ctxt->ps_subset_sps[ps_sps->u1_seq_parameter_set_id];
if(CODED_SLICE_EXTENSION_NAL == i4_nal_unit_type)
{
ps_sps += MAX_NUM_SEQ_PARAMS;
ps_subset_sps =
&ps_svcd_ctxt->ps_subset_sps[MAX_NUM_SEQ_PARAMS + ps_sps->u1_seq_parameter_set_id];
}
/*-----------------------------------------------------------------------*/
/*--------------------------- frm num -----------------------------------*/
/*-----------------------------------------------------------------------*/
if(!ps_sps) return ERROR_INV_SLICE_HDR_T;
if(FALSE == ps_sps->u1_is_valid) return ERROR_INV_SLICE_HDR_T;
ps_slice_prms->u2_frame_num = ih264d_get_bits_h264(ps_bitstrm, ps_sps->u1_bits_in_frm_num);
/*-----------------------------------------------------------------------*/
/*------------------ field pic flag and bottom field flag ---------------*/
/*-----------------------------------------------------------------------*/
if(SVCD_TRUE != ps_sps->u1_frame_mbs_only_flag)
{
return ERROR_INV_SLICE_HDR_T;
}
/*-----------------------------------------------------------------------*/
/*--------------------------- IDR pic id --------------------------------*/
/*-----------------------------------------------------------------------*/
if(SVCD_TRUE == i4_idr_pic_flag)
{
UWORD32 u4_idr_pic_id = 0;
u4_idr_pic_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(u4_idr_pic_id > 65535) return ERROR_INV_SLICE_HDR_T;
}
/*-----------------------------------------------------------------------*/
/*----------------- poc lsb and delts_poc_bottom ------------------------*/
/*-----------------------------------------------------------------------*/
if(0 == ps_sps->u1_pic_order_cnt_type)
{
i_temp = ih264d_get_bits_h264(ps_bitstrm, ps_sps->u1_log2_max_pic_order_cnt_lsb_minus);
if(i_temp < 0 || i_temp >= ps_sps->i4_max_pic_order_cntLsb) return ERROR_INV_SLICE_HDR_T;
if(SVCD_TRUE == ps_pps->u1_pic_order_present_flag)
{
i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
}
}
/*-----------------------------------------------------------------------*/
/*---------------- delta_poc_count[0] and [1] ---------------------------*/
/*-----------------------------------------------------------------------*/
if((1 == ps_sps->u1_pic_order_cnt_type) && (!ps_sps->u1_delta_pic_order_always_zero_flag))
{
i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(ps_pps->u1_pic_order_present_flag)
{
i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
}
}
/*-----------------------------------------------------------------------*/
/*---------------------- redundant pic cnt ------------------------------*/
/*-----------------------------------------------------------------------*/
if(ps_pps->u1_redundant_pic_cnt_present_flag)
{
u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(u4_temp > MAX_REDUNDANT_PIC_CNT) return ERROR_INV_SLICE_HDR_T;
}
/*-----------------------------------------------------------------------*/
/*-----------------Direct_spatial_mv_pred_flag --------------------------*/
/*-----------------num ref active override flag -------------------------*/
/*-----------------num_ref_idx_active_l0&1 ------------------------------*/
/*-----------------------------------------------------------------------*/
if(0 == i4_quality_id)
{
if(B_SLICE == ps_slice_prms->u1_slice_type)
{
ps_slice_prms->u1_direct_spatial_mv_pred_flag = ih264d_get_bit_h264(ps_bitstrm);
}
if((P_SLICE == ps_slice_prms->u1_slice_type) || (B_SLICE == ps_slice_prms->u1_slice_type))
{
WORD8 i1_over_ride_flag;
i1_over_ride_flag = ih264d_get_bit_h264(ps_bitstrm);
ps_slice_prms->u1_num_ref_idx_active_override_flag = i1_over_ride_flag;
if(SVCD_TRUE == i1_over_ride_flag)
{
UWORD8 u8_ref_idx_l0;
u8_ref_idx_l0 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(u8_ref_idx_l0 > H264_MAX_REF_PICS)
{
return ERROR_NUM_REF;
}
if(B_SLICE == ps_slice_prms->u1_slice_type)
{
UWORD8 u8_ref_idx_l1;
u8_ref_idx_l1 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(u8_ref_idx_l1 > H264_MAX_REF_PICS)
{
return ERROR_NUM_REF;
}
}
}
}
/*-----------------------------------------------------------------------*/
/*---------------------- ref pic list modification ----------------------*/
/*-----------------------------------------------------------------------*/
{
ret = isvcd_parse_ref_pic_list_modify(ps_bitstrm, ps_slice_prms, ps_sps);
if(OK != ret) return ret;
}
if(((1 == ps_pps->u1_wted_pred_flag) && (P_SLICE == ps_slice_prms->u1_slice_type)) ||
((B_SLICE == ps_slice_prms->u1_slice_type) && (1 == ps_pps->u1_wted_bipred_idc)))
{
if((ps_slice_prms->u1_num_ref_idx_lx_active[0] >= H264_MAX_REF_IDX) ||
(ps_slice_prms->u1_num_ref_idx_lx_active[1] >= H264_MAX_REF_IDX))
{
return ERROR_NUM_REF;
}
/*-------------------------------------------------------------------*/
/*------------------------- Pred weight table -----------------------*/
/*-------------------------------------------------------------------*/
if(CODED_SLICE_EXTENSION_NAL == i4_nal_unit_type)
{
WORD32 i4_base_pred_wt_tbl_flag = 1;
/* base_pred_weight_table_flag */
if(0 == i4_no_int_lyr_pred)
{
i4_base_pred_wt_tbl_flag = ih264d_get_bit_h264(ps_bitstrm);
}
if((1 == i4_no_int_lyr_pred) || (0 == i4_base_pred_wt_tbl_flag))
{
ret = ih264d_parse_pred_weight_table(ps_slice_prms, ps_bitstrm);
if(ret != OK) return ret;
}
}
else
{
ret = ih264d_parse_pred_weight_table(ps_slice_prms, ps_bitstrm);
if(ret != OK) return ret;
}
}
/*-----------------------------------------------------------------------*/
/*------------------------- ref pic marking -----------------------------*/
/*-----------------------------------------------------------------------*/
if(0 != i4_nal_ref_idc)
{
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
UWORD8 u1_store_ref_base_pic;
ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr;
ps_dec = &ps_svc_lyr_dec->s_dec;
{
dec_seq_params_t *ps_sps_tmp = ps_pps->ps_sps;
ps_dec->u1_nal_unit_type = i4_nal_unit_type;
ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag = i4_idr_pic_flag;
ps_dec->ps_cur_sps = ps_sps;
ps_dec->ps_cur_pps = ps_pps;
ps_pps->ps_sps = ps_sps;
if(ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag)
ps_dec->u1_nal_unit_type = IDR_SLICE_NAL;
i_temp = ih264d_read_mmco_commands(ps_dec);
ps_pps->ps_sps = ps_sps_tmp;
ps_dec->u1_nal_unit_type = i4_nal_unit_type;
if(i_temp < 0)
{
return ERROR_DBP_MANAGER_T;
}
ps_dec->u4_bitoffset = i_temp;
}
if(0 == ps_subset_sps->s_sps_svc_ext.u1_slice_header_restriction_flag)
{
/* store_ref_base_pic_flag */
u1_store_ref_base_pic = ih264d_get_bit_h264(ps_bitstrm);
if(0 != u1_store_ref_base_pic)
{
return ERROR_INV_SLICE_HDR_T;
}
if(((1 == i4_use_ref_base) || (1 == u1_store_ref_base_pic)) &&
(SVCD_FALSE == i4_idr_pic_flag))
{
i_temp = isvcd_dec_ref_base_pic_marking(
&ps_svc_lyr_dec->s_svc_slice_params.s_ref_base_pic_marking_svc_ext,
ps_bitstrm);
if(i_temp != OK)
{
return i_temp;
}
}
/******* End of if (SVC_VCL_NAL == i4_nal_unit_type) *********/
}
/******** End of if(0 != i4_nal_ref_idc) *************************/
}
/************* End of if(0 == i4_quality_id) *************************/
}
/*-----------------------------------------------------------------------*/
/*--------------------------- cabac int idc -----------------------------*/
/*-----------------------------------------------------------------------*/
if((ps_pps->u1_entropy_coding_mode == CABAC) && (I_SLICE != ps_slice_prms->u1_slice_type))
{
ps_slice_prms->u1_cabac_init_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(ps_slice_prms->u1_cabac_init_idc > MAX_CABAC_INIT_IDC)
{
return ERROR_INV_SLICE_HDR_T;
}
}
/*-----------------------------------------------------------------------*/
/*--------------------------- slice qp delta ----------------------------*/
/*-----------------------------------------------------------------------*/
{
WORD8 i1_slice_qp_delta;
i1_slice_qp_delta = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
i1_slice_qp_delta += ps_pps->u1_pic_init_qp;
if((i1_slice_qp_delta < MIN_H264_QP) || (i1_slice_qp_delta > MAX_H264_QP))
{
return ERROR_INV_RANGE_QP_T;
}
ps_slice_prms->u1_slice_qp = (UWORD8) i1_slice_qp_delta;
}
/*-----------------------------------------------------------------------*/
/*--------------------------- disable dblk filter idc -------------------*/
/*-----------------------------------------------------------------------*/
/* Set to default value */
ps_slice_prms->u1_disable_dblk_filter_idc = 0;
if(SVCD_TRUE == ps_pps->u1_deblocking_filter_parameters_present_flag)
{
ps_slice_prms->u1_disable_dblk_filter_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(ps_slice_prms->u1_disable_dblk_filter_idc > SLICE_BOUNDARY_DBLK_DISABLED)
{
return ERROR_INV_SLICE_HDR_T;
}
/*-------------------------------------------------------------------*/
/*--------------------------- slice_alpha_c0_offset_div2 ------------*/
/*--------------------------- slice_beta_offset_div2 ----------------*/
/*-------------------------------------------------------------------*/
if(1 != ps_slice_prms->u1_disable_dblk_filter_idc)
{
/* slice_alpha_c0_offset_div2 */
ps_slice_prms->i1_slice_alpha_c0_offset = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if((MIN_DBLK_FIL_OFF > ps_slice_prms->i1_slice_alpha_c0_offset) ||
(ps_slice_prms->i1_slice_alpha_c0_offset > MAX_DBLK_FIL_OFF))
{
return ERROR_INV_SLICE_HDR_T;
}
ps_slice_prms->i1_slice_beta_offset = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if((MIN_DBLK_FIL_OFF > ps_slice_prms->i1_slice_beta_offset) ||
(ps_slice_prms->i1_slice_beta_offset > MAX_DBLK_FIL_OFF))
{
return ERROR_INV_SLICE_HDR_T;
}
}
}
*pi4_ref_dq_id = -1;
if((0 == i4_no_int_lyr_pred) && (0 == i4_quality_id))
{
WORD32 i4_inter_lyr_dblk_idc;
WORD32 i4_inter_lyr_alpha_c0_offset;
WORD32 i4_inter_lyr_beta_offset;
/*-------------------------------------------------------------------*/
/*--------------------------- ref_layer_dq_id -----------------------*/
/*-------------------------------------------------------------------*/
*pi4_ref_dq_id = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(*pi4_ref_dq_id > MAX_REF_DEP_ID)
{
return ERROR_INV_SLICE_HDR_T;
}
/* ------------------------------------------- */
/* ---- Inter layer de-blocking parameters ---- */
/* ------------------------------------------- */
i4_inter_lyr_dblk_idc = 0;
i4_inter_lyr_alpha_c0_offset = 0;
i4_inter_lyr_beta_offset = 0;
if(SVCD_TRUE ==
ps_subset_sps->s_sps_svc_ext.u1_inter_layer_deblocking_filter_control_present_flag)
{
i4_inter_lyr_dblk_idc = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(i4_inter_lyr_dblk_idc > 6)
{
return ERROR_INV_SLICE_HDR_T;
}
if(1 != i4_inter_lyr_dblk_idc)
{
/* Alpha Offset */
i4_inter_lyr_alpha_c0_offset = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(i4_inter_lyr_alpha_c0_offset > 6 || i4_inter_lyr_alpha_c0_offset < -6)
{
return ERROR_INV_SLICE_HDR_T;
}
i4_inter_lyr_alpha_c0_offset <<= 1;
/* Beta Offset */
i4_inter_lyr_beta_offset = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
if(i4_inter_lyr_beta_offset > 6 || i4_inter_lyr_beta_offset < -6)
{
return ERROR_INV_SLICE_HDR_T;
}
i4_inter_lyr_beta_offset <<= 1;
}
}
ps_vcl_node->i4_inter_lyr_dblk_idc = i4_inter_lyr_dblk_idc;
ps_vcl_node->i4_inter_lyr_beta_offset = i4_inter_lyr_beta_offset;
ps_vcl_node->i4_inter_lyr_alpha_c0_offset = i4_inter_lyr_alpha_c0_offset;
}
return (0);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_get_ref_lyr_dqid */
/* */
/* Description : Parses the slice header till ref lyr dqid. */
/* */
/* */
/* Inputs : 1. vcl node */
/* 2. sequence prms set base buffer pointer */
/* 3. picture prms set base buffer pointer */
/* 4. Target layer flag */
/* 5. DPB command context structure */
/* 6. Reference layer DQID */
/* Globals : None */
/* Processing : 1. Parses the slice header till ref lyr DQID */
/* 2. If current layer is target layer then it calculates */
/* poc and gaps in frame number */
/* */
/* Outputs : Updates 1) ref dqid variable 2) dpb command context */
/* Returns : status */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Vijay Draft */
/*****************************************************************************/
WORD32 isvcd_get_ref_lyr_dqid(vcl_node_t *ps_vcl_node, dec_seq_params_t *ps_sps,
dec_pic_params_t *ps_pps, WORD32 *pi4_ref_lyr_dqid,
WORD32 i4_prev_au_dqid, WORD32 *pi4_err_code,
svc_dec_ctxt_t *ps_svcd_ctxt)
{
WORD32 i4_status;
WORD32 ai4_ref_dq_id[2] = {0};
WORD32 i4_num_slc_dec;
/* local structures */
dec_slice_params_t s_slice_prms = {0};
/* vcl buffer */
vcl_buf_hdr_t *ps_vcl_buf;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr;
UNUSED(i4_prev_au_dqid);
ps_dec = &ps_svc_lyr_dec->s_dec;
/* Sanity checks */
if((NULL == ps_vcl_node) || (NULL == ps_sps) || (NULL == ps_pps) || (NULL == pi4_ref_lyr_dqid))
{
return NOT_OK;
}
i4_num_slc_dec = 0;
ps_vcl_buf = ps_vcl_node->ps_first_vcl_nal;
i4_status = NOT_OK;
while(NULL != ps_vcl_buf)
{
WORD32 i4_error;
/* Fill the stream context structure */
ps_dec->ps_bitstrm->u4_ofst = 0;
ps_dec->ps_bitstrm->pu4_buffer =
(UWORD32 *) ((UWORD8 *) ps_vcl_buf + ps_vcl_buf->i4_buf_offset +
ps_vcl_buf->i4_slice_offset);
ps_dec->ps_bitstrm->u4_max_ofst = ps_vcl_buf->u4_max_bits;
/* call the function which decodes the slice header */
i4_error = isvcd_parse_slice_hdr_refdq_id(ps_vcl_node, &s_slice_prms, ps_dec->ps_bitstrm,
&ai4_ref_dq_id[i4_num_slc_dec], ps_sps, ps_pps,
ps_vcl_buf->i4_no_int_lyr_pred, ps_svcd_ctxt);
/* store the first error encountered */
if(0 == *pi4_err_code)
{
*pi4_err_code = i4_error;
}
if(i4_error != 0)
{
/* check on the Error returned */
return NOT_OK;
}
/* set the return status */
i4_status = OK;
break;
/* go to the next slice header */
ps_vcl_buf = ps_vcl_buf->ps_next;
}
/* set the appropriate reference dqid of the first slice */
*pi4_ref_lyr_dqid = ai4_ref_dq_id[0];
return (i4_status);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_conceal_node_params */
/* */
/* Description : This function detects the resolution change */
/* */
/* */
/* Inputs : 1. Pointer to Current SPS */
/* 2. Pointer to prevoius SPS */
/* Globals : None */
/* Processing : */
/* */
/* Outputs : none */
/* Returns : SVCD_TRUE if different resolution else SVCD_FALSE */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Vijayakumar Draft */
/* */
/*****************************************************************************/
void isvcd_conceal_node_params(vcl_nal_t *ps_vcl_nal, prev_au_prms_t *ps_prev_au_prms)
{
vcl_node_t *ps_node;
WORD32 i4_conceal_lyrs;
WORD32 i4_no_gaps_flag;
/* get the bottom node */
ps_node = ps_vcl_nal->ps_bot_node;
i4_conceal_lyrs = SVCD_FALSE;
i4_no_gaps_flag = SVCD_FALSE;
/* loop over all nodes present in the current AU */
while(NULL != ps_node)
{
WORD32 i4_dep_id = 0;
WORD32 i4_qua_id = 0;
UWORD16 u2_frm_num_dep = 0;
WORD32 i4_idr_pic_flag = 0;
WORD32 i4_idr_pic_num = 0;
WORD32 i4_nal_ref_idc = 0;
WORD32 i4_poc_syntax = 0;
WORD32 i4_qua_zero_lyr_sts = 0;
i4_dep_id = ps_node->i4_dependency_id;
i4_qua_id = ps_node->i4_quality_id;
/* reset the quality 0 layer updated status */
if(0 == i4_qua_id)
{
i4_qua_zero_lyr_sts = SVCD_FALSE;
}
/* process the quality id 0 layers */
if((0 == i4_qua_id) && (NULL != ps_node->ps_first_vcl_nal))
{
/* if current and previous are reference pictures */
if((0 != ps_prev_au_prms[i4_dep_id].i4_nal_ref_id) && (0 != ps_node->i4_nal_ref_idc))
{
if(ps_prev_au_prms[i4_dep_id].u2_frm_num == ps_node->u2_frm_num)
{
/* frame number is concealed */
ps_node->u2_frm_num++;
i4_conceal_lyrs = SVCD_TRUE;
}
else if((SVCD_TRUE == i4_conceal_lyrs) || (SVCD_TRUE == i4_no_gaps_flag))
{
/* if the current au frm_num is less than prev */
/* or the difference is greater than 1 */
if((ps_prev_au_prms[i4_dep_id].u2_frm_num > ps_node->u2_frm_num) ||
((ps_node->u2_frm_num - ps_prev_au_prms[i4_dep_id].u2_frm_num) > 1))
{
/* frame number is concealed */
ps_node->u2_frm_num = ps_prev_au_prms[i4_dep_id].u2_frm_num + 1;
}
}
/* set the no gaps flag */
if(1 == (ps_node->u2_frm_num - ps_prev_au_prms[i4_dep_id].u2_frm_num))
{
i4_no_gaps_flag = SVCD_TRUE;
}
}
/* store the final frame number */
u2_frm_num_dep = ps_node->u2_frm_num;
i4_idr_pic_flag = ps_node->i4_idr_pic_flag;
i4_idr_pic_num = ps_node->i4_idr_pic_num;
i4_nal_ref_idc = ps_node->i4_nal_ref_idc;
i4_poc_syntax = ps_node->i4_poc_syntax;
i4_qua_zero_lyr_sts = SVCD_TRUE;
}
else
{
if(SVCD_TRUE == i4_qua_zero_lyr_sts)
{
/* for higher quality layers store the same value */
/* present in the quality id 0 layer */
ps_node->u2_frm_num = u2_frm_num_dep;
ps_node->i4_idr_pic_flag = i4_idr_pic_flag;
ps_node->i4_idr_pic_num = i4_idr_pic_num;
ps_node->i4_nal_ref_idc = i4_nal_ref_idc;
ps_node->i4_poc_syntax = i4_poc_syntax;
}
}
/* get the upper node pointer */
ps_node = ps_node->ps_top_node;
}
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_refine_dep_list */
/* */
/* Description : Refines the DQID list based on reference layer DQID */
/* */
/* */
/* Inputs : 1. vcl nal structure (input and output) */
/* 2. sps prms base buffer pointer */
/* 3. pps prms base buffer pointer */
/* 4. pointer to array in which the dep id should be stored */
/* 5. pointer to array having prev AU ref dq id */
/* 6. pointer to init params structure */
/* 7. pointer to store the Error code */
/* Globals : None */
/* Processing : */
/* */
/* Outputs : Updates the vcl nal structure */
/* Also determines frm_num and poc */
/* Returns : status */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Vijay Draft */
/*****************************************************************************/
WORD32 isvcd_refine_dep_list(void *pv_out_vcl_ctxt, dec_seq_params_t *ps_sps,
dec_svc_seq_params_t *ps_subset_sps, dec_pic_params_t *ps_pps,
WORD32 *pi4_dep_id_map, prev_au_prms_t *ps_prev_au_prms,
prev_au_sps_pps_t *ps_pps_sps_prev, WORD32 *pi4_err_code,
svc_dec_ctxt_t *ps_svcd_ctxt)
{
vcl_nal_t *ps_vcl_nal;
vcl_node_t *ps_vcl_node;
WORD32 i4_idr_pic_flag;
WORD32 i4_nal_ref_idc;
WORD32 i4_idr_pic_num;
WORD32 i4_num_res_lyrs_bup;
WORD32 i4_restore_prms_flag;
vcl_node_t *ps_node_bup;
WORD32 ai4_dep_id[MAX_NUM_RES_LYRS] = {0};
/* used for checking the init prms */
dec_seq_params_t *ps_sps_tgt_minus1_lyr = NULL;
dec_seq_params_t *ps_sps_tgt_minus2_lyr = NULL;
UNUSED(pi4_err_code);
/* sanity checks */
if((NULL == pv_out_vcl_ctxt) || (NULL == ps_sps) || (NULL == ps_pps))
{
return NOT_OK;
}
ps_vcl_nal = (vcl_nal_t *) pv_out_vcl_ctxt;
/* no node is present */
if(NULL == ps_vcl_nal->ps_bot_node)
{
return (NOT_OK);
}
/* set the single layer flag if top node and bottom node are same */
if((ps_vcl_nal->ps_bot_node == ps_vcl_nal->ps_top_node) &&
(0 == ps_vcl_nal->ps_bot_node->i4_dependency_id))
{
}
else
{
/* call the function which corrects the frame number of each node */
/* based on previous access unit frame number */
isvcd_conceal_node_params(ps_vcl_nal, ps_prev_au_prms);
}
/* get the top most node */
ps_vcl_node = ps_vcl_nal->ps_top_node;
/* get the IDR picture flag for top most layer in current AU */
/* if not valid then set the value present in the first valid node */
{
vcl_node_t *ps_node;
WORD32 i4_node_present_flag;
ps_node = ps_vcl_node;
i4_node_present_flag = SVCD_FALSE;
/* store default values */
i4_idr_pic_flag = SVCD_FALSE;
i4_nal_ref_idc = 0;
i4_idr_pic_num = 0;
/* loop until valid node */
while(NULL != ps_node)
{
if(NULL != ps_node->ps_first_vcl_nal)
{
i4_idr_pic_flag = ps_node->i4_idr_pic_flag;
i4_nal_ref_idc = ps_node->i4_nal_ref_idc;
i4_idr_pic_num = ps_node->i4_idr_pic_num;
i4_node_present_flag = SVCD_TRUE;
break;
}
else if(SVCD_TRUE == ps_node->i4_idr_pic_flag)
{
i4_idr_pic_flag = ps_node->i4_idr_pic_flag;
i4_nal_ref_idc = ps_node->i4_nal_ref_idc;
i4_idr_pic_num = ps_node->i4_idr_pic_num;
i4_node_present_flag = SVCD_TRUE;
break;
}
/* point to next node */
ps_node = ps_node->ps_bot_node;
}
/* alteast one node should be present */
if(SVCD_FALSE == i4_node_present_flag)
{
return (NOT_OK);
}
}
/* initially the access unit is considered to have a single resolution */
ai4_dep_id[0] = 0;
ps_vcl_nal->i4_num_res_lyrs = 1;
i4_restore_prms_flag = SVCD_FALSE;
/*-----------------------------------------------------------------------*/
/* loop until all the nodes are processed */
/*-----------------------------------------------------------------------*/
while(NULL != ps_vcl_node)
{
WORD32 i4_ref_lyr_dqid, i4_status;
vcl_node_t *ps_bot_vcl_node;
WORD32 i4_res_chnge_flag = SVCD_FALSE;
WORD32 i4_dep_id, i4_qua_id;
WORD32 i4_prev_sps_pps_valid;
WORD32 i4_prev_au_prms_valid;
/* set the reference layer DQID to -1 */
i4_ref_lyr_dqid = -1;
/* get the current layer dependency and quality id */
i4_dep_id = ps_vcl_node->i4_dependency_id;
i4_qua_id = ps_vcl_node->i4_quality_id;
/* get the valid status of prev access unit params */
i4_prev_au_prms_valid = ps_prev_au_prms[i4_dep_id].i4_updated_sts;
i4_prev_sps_pps_valid = ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].i4_updated_sts;
/* missing layer handling */
if(NULL == ps_vcl_node->ps_first_vcl_nal)
{
/* store the params appropriately */
ps_vcl_node->i4_idr_pic_flag = i4_idr_pic_flag;
ps_vcl_node->i4_nal_ref_idc = i4_nal_ref_idc;
ps_vcl_node->i4_idr_pic_num = i4_idr_pic_num;
ps_vcl_node->i4_num_slices = 0;
ps_vcl_node->i4_use_ref_base = 0;
ps_vcl_node->i4_temporal_id = 0;
if((0 != i4_dep_id) || (0 != i4_qua_id))
{
ps_vcl_node->i4_nal_unit_type = CODED_SLICE_EXTENSION_NAL;
ps_vcl_node->u1_acc_no_int_pred = 0;
}
else if(SVCD_TRUE == i4_idr_pic_flag)
{
ps_vcl_node->i4_nal_unit_type = IDR_SLICE_NAL;
ps_vcl_node->u1_acc_no_int_pred = 1;
}
else
{
ps_vcl_node->i4_nal_unit_type = SLICE_NAL;
ps_vcl_node->u1_acc_no_int_pred = 1;
}
if(SVCD_FALSE == i4_idr_pic_flag)
{
/* pick the other params form previous access unit */
if(SVCD_TRUE == i4_prev_sps_pps_valid)
{
ps_vcl_node->u1_pps_id =
ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].u1_pps_id;
ps_vcl_node->u1_sps_id =
ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].u1_sps_id;
}
if(SVCD_TRUE == i4_prev_au_prms_valid)
{
if(0 == ps_vcl_node->i4_nal_ref_idc)
{
ps_vcl_node->u2_frm_num = ps_prev_au_prms[i4_dep_id].u2_frm_num;
}
else
{
ps_vcl_node->u2_frm_num = ps_prev_au_prms[i4_dep_id].u2_frm_num + 1;
}
}
}
}
/* SPS id cannot change unless its an IDR pic */
if(SVCD_FALSE == ps_vcl_node->i4_idr_pic_flag)
{
if(SVCD_TRUE == i4_prev_sps_pps_valid)
{
/* store the SPS id of the current layer */
ps_vcl_node->u1_sps_id = ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].u1_sps_id;
}
}
/* store the PPS id and SPS id of the current layer */
ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].u1_pps_id = ps_vcl_node->u1_pps_id;
ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].u1_sps_id = ps_vcl_node->u1_sps_id;
ps_pps_sps_prev[(i4_dep_id << 4) + i4_qua_id].i4_updated_sts = SVCD_TRUE;
/* handling of no_inter_layer_pred_flag 1 cases */
if((1 == ps_vcl_node->u1_acc_no_int_pred) && (NULL != ps_vcl_node->ps_bot_node))
{
if(SVCD_TRUE == i4_idr_pic_flag)
{
/* take a back up of the parameters till the current node. */
/* these parameters will be restored at the end of loop */
if(SVCD_FALSE == i4_restore_prms_flag)
{
/* get the number of resolution detected so far */
i4_num_res_lyrs_bup = ps_vcl_nal->i4_num_res_lyrs;
ps_node_bup = ps_vcl_node;
/* set the restore params flag */
i4_restore_prms_flag = SVCD_TRUE;
}
}
else
{
ps_vcl_node->i4_ref_dq_id = -1;
ps_vcl_node->i4_res_change_flag = i4_res_chnge_flag;
/* store the reference DQID for current dependency */
ps_prev_au_prms[i4_dep_id].i4_ref_dq_id = -1;
ps_prev_au_prms[i4_dep_id].u2_frm_num = ps_vcl_node->u2_frm_num;
ps_prev_au_prms[i4_dep_id].i4_nal_ref_id = ps_vcl_node->i4_nal_ref_idc;
/* the bottom node is set to NULL */
ps_vcl_node->ps_bot_node = NULL;
break;
}
}
/* derive the reference layer DQID for quality id equal to 0 */
if(0 == i4_qua_id)
{
dec_seq_params_t *ps_curr_sps;
dec_svc_seq_params_t *ps_curr_subset_sps;
/* derive current SPS */
ps_curr_sps = ps_sps + ps_vcl_node->u1_sps_id;
ps_curr_subset_sps = ps_subset_sps + ps_vcl_node->u1_sps_id;
{
WORD32 i4_max_frm_num;
/* get the maximum value of frame number */
i4_max_frm_num = (1 << (ps_curr_sps->u1_bits_in_frm_num + 1));
ps_vcl_node->u2_frm_num = ps_vcl_node->u2_frm_num % i4_max_frm_num;
if(SVCD_TRUE == ps_vcl_node->i4_idr_pic_flag)
{
/* if idr then frm num should be 0 */
ps_vcl_node->u2_frm_num = 0;
}
}
/* store default params to inter layer deblocking params */
ps_vcl_node->i4_inter_lyr_dblk_idc = 0;
ps_vcl_node->i4_inter_lyr_beta_offset = 0;
ps_vcl_node->i4_inter_lyr_alpha_c0_offset = 0;
/* No SEI support for scalability info*/
i4_status = NOT_OK;
/* if no inter layer pred flag is present set the */
/* status to fail since the slices will not contain */
/* reference layer Dqid */
if(1 == ps_vcl_node->u1_acc_no_int_pred)
{
i4_status = NOT_OK;
}
else
{
WORD32 *pi4_ref_dq_id;
WORD32 i4_ref_dq_id_temp;
/* check if the SEI message has given the ref_dq_id */
if(NOT_OK == i4_status)
{
pi4_ref_dq_id = &i4_ref_lyr_dqid;
}
else
{
pi4_ref_dq_id = &i4_ref_dq_id_temp;
}
i4_status = isvcd_get_ref_lyr_dqid(ps_vcl_node, ps_sps, ps_pps, pi4_ref_dq_id,
ps_prev_au_prms[i4_dep_id].i4_ref_dq_id,
&ps_svcd_ctxt->i4_error_code, ps_svcd_ctxt);
}
/* no slice in the layer has been successfully decoded */
if(NOT_OK == i4_status)
{
/* check for IDR picture */
if(SVCD_TRUE == i4_idr_pic_flag)
{
/* set the next lower layer as the reference layer */
if(NULL != ps_vcl_node->ps_bot_node)
{
i4_ref_lyr_dqid = ps_vcl_node->ps_bot_node->i4_dependency_id << 4;
i4_ref_lyr_dqid += ps_vcl_node->ps_bot_node->i4_quality_id;
}
else
{
i4_ref_lyr_dqid = -1;
}
}
else
{
/* take the reference dq id from previous access unit */
i4_ref_lyr_dqid = ps_prev_au_prms[i4_dep_id].i4_ref_dq_id;
}
}
/* Update the DQID list based on ref DQID. */
/* This routine also updates the ref_dq_id */
/* in case the actual layer is completely lost */
i4_status = isvcd_update_dqid(i4_ref_lyr_dqid, ps_vcl_node, &ps_bot_vcl_node);
if(!(OK == i4_status))
{
return i4_status;
}
/* store the reference DQID for current depedency and */
/* quality id 0 layer */
ps_prev_au_prms[i4_dep_id].i4_ref_dq_id = i4_ref_lyr_dqid;
ps_prev_au_prms[i4_dep_id].i4_nal_ref_id = ps_vcl_node->i4_nal_ref_idc;
ps_prev_au_prms[i4_dep_id].u2_frm_num = ps_vcl_node->u2_frm_num;
ps_prev_au_prms[i4_dep_id].i4_updated_sts = SVCD_TRUE;
/* ------- Detect Resolution Change ---------------- */
{
dec_seq_params_t *ps_lower_sps = NULL;
dec_svc_seq_params_t *ps_lower_subset_sps = NULL;
if(NULL != ps_bot_vcl_node)
{
if((NULL != ps_bot_vcl_node->ps_first_vcl_nal) ||
(SVCD_TRUE == i4_idr_pic_flag))
{
/* get the SPS of layer */
ps_lower_sps = ps_sps + ps_bot_vcl_node->u1_sps_id;
ps_lower_subset_sps = ps_subset_sps + ps_bot_vcl_node->u1_sps_id;
}
else
{
/* if the bottom layer is completely missed */
WORD32 i4_bot_dep_id, i4_bot_qua_id;
UWORD8 u1_sps_id = 0;
/* sps id is picked from previous access unit */
i4_bot_dep_id = ps_bot_vcl_node->i4_dependency_id;
i4_bot_qua_id = ps_bot_vcl_node->i4_quality_id;
if(SVCD_TRUE ==
ps_pps_sps_prev[(i4_bot_dep_id << 4) + i4_bot_qua_id].i4_updated_sts)
{
u1_sps_id =
ps_pps_sps_prev[(i4_bot_dep_id << 4) + i4_bot_qua_id].u1_sps_id;
}
else
{
/* should not enter here */
return NOT_OK;
}
/* get the SPS of lower layer */
ps_lower_sps = ps_sps + u1_sps_id;
ps_lower_subset_sps = ps_subset_sps + u1_sps_id;
}
}
/* call the function which detects resolution change */
i4_res_chnge_flag = isvcd_detect_res_change(
ps_curr_sps, ps_lower_sps, ps_curr_subset_sps, ps_lower_subset_sps);
/* if a resolution exists below current resolution */
if(SVCD_TRUE == i4_res_chnge_flag)
{
/* if current picture id IDR */
if(SVCD_TRUE == i4_idr_pic_flag)
{
/* store the depedency id of bottom most layer in current resolution */
ai4_dep_id[ps_vcl_nal->i4_num_res_lyrs - 1] = i4_dep_id;
}
/* increment the num resolution layer counter */
ps_vcl_nal->i4_num_res_lyrs++;
/* store the SPS of target -1 and -2 resolution layers */
if(2 == ps_vcl_nal->i4_num_res_lyrs)
{
ps_sps_tgt_minus1_lyr = ps_curr_sps;
}
else if(3 == ps_vcl_nal->i4_num_res_lyrs)
{
ps_sps_tgt_minus2_lyr = ps_curr_sps;
}
else if(ps_vcl_nal->i4_num_res_lyrs > MAX_NUM_RES_LYRS)
{
return NOT_OK;
}
}
}
/* -------- end of resolution change detection -------- */
}
else
{
i4_ref_lyr_dqid = (i4_dep_id << 4);
i4_ref_lyr_dqid += (i4_qua_id - 1);
/* Update the DQID list based on ref DQID. */
/* This routine also updates the ref_dq_id */
/* in case the actual layer is completely lost */
i4_status = isvcd_update_dqid(i4_ref_lyr_dqid, ps_vcl_node, &ps_bot_vcl_node);
if(!(OK == i4_status))
{
return i4_status;
}
if(SVCD_TRUE == ps_vcl_node->i4_idr_pic_flag)
{
/* if idr then frm num should be 0 */
ps_vcl_node->u2_frm_num = 0;
}
}
/* Update resolution change flag inside VCL */
/* node structure. This parameter is later used*/
/* in detecting the top most layer in the */
/* resolution currently being decoded */
ps_vcl_node->i4_res_change_flag = i4_res_chnge_flag;
ps_vcl_node->i4_ref_dq_id = i4_ref_lyr_dqid;
/* go to the next node */
ps_vcl_node = ps_bot_vcl_node;
}
/* update the Dependency array for each resolution */
if(SVCD_TRUE == i4_idr_pic_flag)
{
WORD32 i4_idx;
ai4_dep_id[ps_vcl_nal->i4_num_res_lyrs - 1] = 0;
/* loop over number of resolutions detected */
for(i4_idx = 0; i4_idx < ps_vcl_nal->i4_num_res_lyrs; i4_idx++)
{
pi4_dep_id_map[i4_idx] = ai4_dep_id[ps_vcl_nal->i4_num_res_lyrs - 1 - i4_idx];
}
}
if(SVCD_TRUE == i4_restore_prms_flag)
{
/* restore the number of resolutions */
ps_vcl_nal->i4_num_res_lyrs = i4_num_res_lyrs_bup;
ps_vcl_node = ps_node_bup;
/* set the bottom node to NULL */
ps_vcl_node->ps_bot_node = NULL;
ps_vcl_node->i4_ref_dq_id = -1;
ps_vcl_node->i4_res_change_flag = SVCD_FALSE;
/* store the reference DQID for current dependency */
ps_prev_au_prms[ps_vcl_node->i4_dependency_id].i4_ref_dq_id = -1;
ps_prev_au_prms[ps_vcl_node->i4_dependency_id].u2_frm_num = ps_vcl_node->u2_frm_num;
ps_prev_au_prms[ps_vcl_node->i4_dependency_id].i4_nal_ref_id = ps_vcl_node->i4_nal_ref_idc;
}
/* Finally update the bottom most node in the current access unit */
ps_vcl_node = ps_vcl_nal->ps_top_node;
while(NULL != ps_vcl_node->ps_bot_node)
{
ps_vcl_node = ps_vcl_node->ps_bot_node;
}
ps_vcl_nal->ps_bot_node = ps_vcl_node;
/* check on validity of Target Layer -1 and -2 dimensions */
if((NULL != ps_sps_tgt_minus1_lyr) && (0 == ps_sps_tgt_minus1_lyr->u1_is_valid))
{
if((H264_MAX_FRAME_WIDTH < (WORD32) (ps_sps_tgt_minus1_lyr->u2_frm_wd_in_mbs << 4)) ||
(H264_MAX_FRAME_HEIGHT < (WORD32) (ps_sps_tgt_minus1_lyr->u2_frm_ht_in_mbs << 4)))
{
return NOT_OK;
}
}
if((NULL != ps_sps_tgt_minus2_lyr) && (0 == ps_sps_tgt_minus2_lyr->u1_is_valid))
{
if((H264_MAX_FRAME_WIDTH < (WORD32) (ps_sps_tgt_minus2_lyr->u2_frm_wd_in_mbs << 4)) ||
(H264_MAX_FRAME_HEIGHT < (WORD32) (ps_sps_tgt_minus2_lyr->u2_frm_ht_in_mbs << 4)))
{
return NOT_OK;
}
}
return (OK);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_dec_non_vcl */
/* */
/* Description : this function decodes the NON VCL NAL units */
/* */
/* */
/* Inputs : pv_out_non_vcl : pointer to the structure containing */
/* NON VCL NAL units */
/* ps_seq_params : pointer to array of SPS structures */
/* ps_pic_params : pointer to array of PPS structures */
/* ps_sei_ctxt : pointer to array of SEI structures */
/* Globals : none */
/* Processing : it decodes the units unitl all the units are */
/* decoded */
/* Outputs : decoded parameters in appropriate structures */
/* Returns : Success or Faliure */
/* */
/* Issues : */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 vijayakumar creation */
/* */
/*****************************************************************************/
WORD32 isvcd_dec_non_vcl(void *pv_out_non_vcl, void *pv_seq_params, void *pv_pic_params,
svc_dec_ctxt_t *ps_svcd_ctxt)
{
/* local varibles */
non_vcl_nal_t *ps_non_vcl;
WORD32 i4_unit_indx;
non_vcl_buf_hdr_t *ps_non_vcl_buf;
WORD32 i_status = OK;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
dec_bit_stream_t *ps_bitstrm;
if((NULL == pv_out_non_vcl) || (NULL == pv_seq_params) || (NULL == pv_pic_params))
{
return NOT_OK;
}
UNUSED(pv_seq_params);
UNUSED(pv_pic_params);
/* currently SEI decoding is not supported */
/* derive the local variables */
ps_non_vcl = (non_vcl_nal_t *) pv_out_non_vcl;
ps_non_vcl_buf = ps_non_vcl->ps_first_non_vcl_nal;
if(NULL == ps_non_vcl_buf) return (NOT_OK);
/* loop until all NON VCL NAL are decoded */
for(i4_unit_indx = 0; i4_unit_indx < ps_non_vcl->i4_num_non_vcl_nals; i4_unit_indx++)
{
UWORD32 u4_nal_unit_type;
ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr;
ps_dec = &ps_svc_lyr_dec->s_dec;
if(NULL == ps_non_vcl_buf) return (NOT_OK);
/* get the current NAL unit type */
u4_nal_unit_type = (UWORD32) ps_non_vcl_buf->i4_nal_unit_type;
if(u4_nal_unit_type > MAX_SVC_NAL_UNIT_TYPE) return (NOT_OK);
ps_dec->u1_nal_unit_type = u4_nal_unit_type;
ps_dec->ps_bitstrm->pu4_buffer =
(UWORD32 *) ((UWORD8 *) ps_non_vcl_buf + ps_non_vcl_buf->i4_buf_offset);
ps_dec->ps_bitstrm->u4_ofst = 0;
ps_dec->ps_bitstrm->u4_max_ofst = isvcd_nal_rbsp_to_sodb(
(UWORD8 *) ps_dec->ps_bitstrm->pu4_buffer, ps_non_vcl_buf->i4_buf_size, 0);
if(ps_dec->ps_bitstrm->u4_max_ofst <= 0) return (NOT_OK);
ps_bitstrm = ps_dec->ps_bitstrm;
/* call the processing module based on nal unit type */
switch(u4_nal_unit_type)
{
case SEQ_PARAM_NAL:
i_status = isvcd_parse_sps(ps_svc_lyr_dec, ps_bitstrm);
if(!i_status)
{
ps_dec->i4_header_decoded |= 0x1;
ps_svcd_ctxt->u4_num_sps_ctr++;
}
if(i_status) return i_status;
break;
case SUBSET_SPS_NAL:
i_status = isvcd_parse_subset_sps(ps_svc_lyr_dec, ps_bitstrm);
if(!i_status)
{
ps_svcd_ctxt->u4_num_sps_ctr++;
ps_dec->i4_header_decoded |= 0x1;
}
if(i_status) return i_status;
break;
case PIC_PARAM_NAL:
i_status = isvcd_parse_pps(ps_svc_lyr_dec, ps_bitstrm);
if(i_status == ERROR_INV_SPS_PPS_T) return i_status;
if(!i_status)
{
ps_dec->i4_header_decoded |= 0x2;
ps_svcd_ctxt->u4_num_pps_ctr++;
}
break;
case SEI_NAL:
{
i_status = ih264d_parse_sei_message(ps_dec, ps_bitstrm);
ih264d_parse_sei(ps_dec, ps_bitstrm);
}
break;
default:
/* no other NON VCL UNIT is supported */
break;
}
/* get the next non vcl bufffer */
ps_non_vcl_buf = ps_non_vcl_buf->ps_next;
} /* end of loop over all NAL units */
return (OK);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_seq_hdr_dec */
/* */
/* Description : This function decodes sequence header, which includes */
/* non VCL NAL before the first VCL unit */
/* Inputs : Decoder context, inbufs, place holder for number of bytes*/
/* consumed and number of packets consumed */
/* Globals : None */
/* Processing : 1. Parse non VCL units before first VCL unit */
/* 2. Decode parsed non VCL units */
/* Outputs : Decoded header */
/* Returns : OK or NOT_OK */
/* */
/* Issues : no known issues */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Creation */
/* */
/*****************************************************************************/
WORD32 isvcd_seq_hdr_dec(svc_dec_ctxt_t *ps_svcd_ctxt, ivd_video_decode_ip_t *ps_in_bufs,
UWORD32 *pu4_bytes_consumed)
{
WORD32 i4_status;
/* Decode all non VCL NAL till first VCL NAL is encountered */
ps_svcd_ctxt->s_non_vcl_nal.i4_num_non_vcl_nals = 0;
i4_status = isvcd_nal_parse_non_vcl_nal(
ps_svcd_ctxt->pv_nal_parse_ctxt, ps_in_bufs->pv_stream_buffer, &ps_svcd_ctxt->s_non_vcl_nal,
pu4_bytes_consumed, &ps_in_bufs->u4_num_Bytes);
/* Note: The bitstream extraction module expects updated */
/* pointer whenever a new call to this module has been */
/* made. Hence the buffer pointer has to be incremented */
/* by bytes consumed */
ps_in_bufs->u4_num_Bytes -= *pu4_bytes_consumed;
/* ------------------------------------------------------ */
/* Decoding of non VCL data. As current implementation it */
/* decodes the followings: */
/* 1. Sequence parameter set */
/* 2. Picture parameter set */
/* 3. SEI message */
/* ------------------------------------------------------ */
isvcd_dec_non_vcl(&ps_svcd_ctxt->s_non_vcl_nal, ps_svcd_ctxt->ps_sps, ps_svcd_ctxt->ps_pps,
ps_svcd_ctxt);
return (i4_status);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_pre_parse_refine_au */
/* */
/* Description : This function process a decode call */
/* Inputs : ps_dec_ctxt : decoder context structure */
/* ps_in_bufs : input buffer descriptor */
/* pu4_bytes_consumed : pointer to store the bytes consumed */
/* pi4_packets_consumed : pointer to store the packets */
/* consumed */
/* Globals : None */
/* Processing : It calls the NAL parse module to parse the input stream */
/* if a picture boundary is detected it calls the */
/* Dependency list refiniment and Picture Decode routines */
/* Outputs : Decoded picture */
/* Returns : OK or NOT_OK */
/* */
/* Issues : None */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Creation */
/* */
/*****************************************************************************/
WORD32 isvcd_pre_parse_refine_au(svc_dec_ctxt_t *ps_svcd_ctxt, ivd_video_decode_ip_t *ps_in_bufs,
UWORD32 *pu4_bytes_consumed)
{
WORD32 i4_status, i4_non_vcl_status;
UWORD32 u4_bytes_consumed = 0;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr;
ps_dec = &ps_svc_lyr_dec->s_dec;
/* Sequence header decode: */
/* If sequence header is not decoded then decode the seq */
/* uence header */
if(SVCD_FALSE == ps_dec->i4_header_decoded)
{
i4_status = isvcd_seq_hdr_dec(ps_svcd_ctxt, ps_in_bufs, &u4_bytes_consumed);
if((VCL_NAL_FOUND_TRUE == i4_status) && (ps_svcd_ctxt->u4_num_sps_ctr != 0) &&
(ps_svcd_ctxt->u4_num_pps_ctr != 0))
{
/* set the header decoded flag */
ps_dec->i4_header_decoded = 3;
}
}
*pu4_bytes_consumed = u4_bytes_consumed;
if(1 == ps_dec->i4_decode_header)
{
return OK;
}
/* Bit-stream Parsing. It performs following tasks: */
/* 1. NAL hader decoder */
/* 2. Emulation prevention and byte swap */
/* (During this process data to moved to output*/
/* buffer) */
/* 3. Dependency list creation based on NAL header*/
/* 4. Detection of picture boundary */
/* NOTE1: */
/* Output buffers for VCL and non VCL data are */
/* different. VCL data can be retrieved through */
/* dependency list. Whereas non VCL data is stored in*/
/* one single buffer, which is accessed through NON */
/* VCL structure */
/* NOTE2:Partial input case for nal parsing requires a */
/* flush API to be called when end of bitstream */
/* occurs */
if(SVCD_FALSE == ps_svcd_ctxt->i4_eos_flag)
{
if(ps_dec->i4_header_decoded == 3)
{
i4_status = isvcd_nal_parse_vcl_nal_partial(
ps_svcd_ctxt->pv_nal_parse_ctxt, ps_in_bufs->pv_stream_buffer,
&ps_svcd_ctxt->s_non_vcl_nal, &ps_svcd_ctxt->s_vcl_nal, &u4_bytes_consumed,
&ps_in_bufs->u4_num_Bytes);
}
else
{
return NOT_OK;
}
}
else
{
void *pv_nal_parse_ctxt;
pv_nal_parse_ctxt = ps_svcd_ctxt->pv_nal_parse_ctxt;
i4_status = isvcd_nal_parse_partial_signal_eos(pv_nal_parse_ctxt, &ps_svcd_ctxt->s_vcl_nal,
&ps_svcd_ctxt->s_non_vcl_nal);
u4_bytes_consumed = 0;
}
*pu4_bytes_consumed += u4_bytes_consumed;
/* Picture Boundary detected: Go ahead and do the decoding */
/* Picture boundary not detected: Otherwsie retrun from this*/
/* function and update the bytes consumed variable. This */
/* should be repeated till we get a picture boundary */
if(PIC_BOUNDARY_FALSE == i4_status)
{
return (NOT_OK);
}
else if(FLUSH_DECODED_PICTURE == i4_status)
{
/* No more data is expected to come. Pictures decoded */
/* so far needs to be sent for display */
return (FLUSH);
}
if(PIC_BOUNDARY_TRUE != i4_status)
{
return (NOT_OK);
}
/* check if the application has set any of the skip modes */
/* add the support for P and B skip modes */
/* if(ps_dec_ctxt->s_dyn_prms.u1_frame_skip_mode) */
/* Parse slice header to decode reference layer dQId and refine */
/* the dependency list */
/* NOTE: Yes, this processing could be moved into NAL parsing */
/* routine to avoid unneccessary emulation prevention and */
/* byte swapping over discardable data. This Optimization */
/* has been deferred for some time. In future if we found */
/* that there are many such streams which doesn't set */
/* 'discard_flag' correctly in NAL header, we will take a */
/* hit to optimize it. */
/* At present this routine also performs the following */
/* 1. Refine DQID list based on reference layer DQID */
/* 2. Calculates the POC for the target layer */
{
i4_status = isvcd_refine_dep_list(
&ps_svcd_ctxt->s_vcl_nal, ps_svcd_ctxt->ps_sps, ps_svcd_ctxt->ps_subset_sps,
ps_svcd_ctxt->ps_pps, &ps_svcd_ctxt->ai4_dq_id_map[0], &ps_svcd_ctxt->as_au_prms_dep[0],
&ps_svcd_ctxt->as_pps_sps_prev_au[0], &ps_svcd_ctxt->i4_error_code, ps_svcd_ctxt);
}
if(0 != ps_svcd_ctxt->s_non_vcl_nal.i4_num_non_vcl_nals)
{
/* Decoding of non VCL data. In current implementation it */
/* decodes the followings: */
/* 1. Sequence parameter set */
/* 2. Picture parameter set */
/* 3. SEI message */
i4_non_vcl_status = isvcd_dec_non_vcl(&ps_svcd_ctxt->s_non_vcl_nal, ps_svcd_ctxt->ps_sps,
ps_svcd_ctxt->ps_pps, ps_svcd_ctxt);
if(OK != i4_non_vcl_status) return i4_non_vcl_status;
}
if(OK != i4_status) return (i4_status);
return (OK);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_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) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
dec_struct_t *ps_dec;
dec_struct_t *ps_dec_zero_lyr;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_zero_dec;
svc_dec_ctxt_t *ps_svcd_ctxt;
WORD32 i4_err_status = 0;
UWORD32 bytes_consumed = 0;
WORD32 ret = 0, api_ret_value = IV_SUCCESS;
isvcd_video_decode_ip_t *ps_h264d_dec_ip;
isvcd_video_decode_op_t *ps_h264d_dec_op;
ivd_video_decode_ip_t *ps_dec_ip;
ivd_video_decode_op_t *ps_dec_op;
UWORD8 u1_res_id;
ithread_set_name((void *) "Parse_thread");
ps_svcd_ctxt = (svc_dec_ctxt_t *) (dec_hdl->pv_codec_handle);
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
ps_dec = &ps_svc_lyr_dec->s_dec;
ps_h264d_dec_ip = (isvcd_video_decode_ip_t *) pv_api_ip;
ps_h264d_dec_op = (isvcd_video_decode_op_t *) pv_api_op;
ps_dec_ip = &ps_h264d_dec_ip->s_ivd_video_decode_ip_t;
ps_dec_op = &ps_h264d_dec_op->s_ivd_video_decode_op_t;
{
UWORD32 u4_size;
u4_size = ps_dec_op->u4_size;
memset(ps_h264d_dec_op, 0, sizeof(isvcd_video_decode_op_t));
ps_dec_op->u4_size = u4_size;
}
ps_dec->pv_dec_out = ps_dec_op;
if(ps_dec->init_done != 1)
{
return IV_FAIL;
}
/*Data memory barries instruction,so that bitstream write by the application
* is complete*/
DATA_SYNC();
if(0 == ps_dec->u1_flushfrm)
{
if(ps_dec_ip->pv_stream_buffer == NULL)
{
ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
return IV_FAIL;
}
if(ps_dec_ip->u4_num_Bytes <= 16)
{
ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
return IV_FAIL;
}
}
#ifdef KEEP_THREADS_ACTIVE
{
UWORD32 i;
ps_dec->i4_break_threads = 0;
for(i = 0; i < 2; i++)
{
ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[i]);
RETURN_IF((ret != IV_SUCCESS), ret);
ps_dec->ai4_process_start[i] = PROC_INIT;
ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[i]);
RETURN_IF((ret != IV_SUCCESS), ret);
}
}
#else
ps_dec->u4_dec_thread_created = 0;
ps_dec->u4_bs_deblk_thread_created = 0;
#endif
ps_dec_op->u4_num_bytes_consumed = 0;
ps_dec_op->i4_reorder_depth = -1;
ps_dec_op->i4_display_index = DEFAULT_POC;
ps_dec->ps_out_buffer = NULL;
if(ps_dec_ip->u4_size >= offsetof(ivd_video_decode_ip_t, s_out_buffer))
ps_dec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
if(0 == ps_dec->u4_share_disp_buf && ps_dec->i4_decode_header == 0)
{
UWORD32 i;
if((ps_dec->ps_out_buffer->u4_num_bufs == 0) ||
(ps_dec->ps_out_buffer->u4_num_bufs > IVD_VIDDEC_MAX_IO_BUFFERS))
{
ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
return IV_FAIL;
}
for(i = 0; i < ps_dec->ps_out_buffer->u4_num_bufs; i++)
{
if(ps_dec->ps_out_buffer->pu1_bufs[i] == NULL)
{
ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
return IV_FAIL;
}
if(ps_dec->ps_out_buffer->u4_min_out_buf_size[i] == 0)
{
ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
return IV_FAIL;
}
}
}
if(ps_dec->u4_total_frames_decoded >= NUM_FRAMES_LIMIT)
{
ps_dec_op->u4_error_code = ERROR_FRAME_LIMIT_OVER;
return IV_FAIL;
}
ps_dec_op->u4_error_code = 0;
ps_dec_op->e_pic_type = IV_NA_FRAME;
ps_dec_op->u4_output_present = 0;
ps_dec_op->u4_frame_decoded_flag = 0;
/* In case the decoder is not in flush mode(in shared mode),
then decoder has to pick up a buffer to write current frame.
Check if a frame is available in such cases */
if(ps_dec->u1_init_dec_flag == 1 && ps_dec->u4_share_disp_buf == 1 && ps_dec->u1_flushfrm == 0)
{
UWORD32 i;
WORD32 disp_avail = 0, free_id;
/* Check if at least one buffer is available with the codec */
/* If not then return to application with error */
for(i = 0; i < ps_dec->u1_pic_bufs; i++)
{
if(0 == ps_dec->u4_disp_buf_mapping[i] || 1 == ps_dec->u4_disp_buf_to_be_freed[i])
{
disp_avail = 1;
break;
}
}
if(0 == disp_avail)
{
/* If something is queued for display wait for that buffer to be returned
*/
ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
return (IV_FAIL);
}
while(1)
{
pic_buffer_t *ps_pic_buf;
ps_pic_buf = (pic_buffer_t *) ih264_buf_mgr_get_next_free(
(buf_mgr_t *) ps_dec->pv_pic_buf_mgr, &free_id);
if(ps_pic_buf == NULL)
{
UWORD32 display_queued = 0;
/* check if any buffer was given for display which is not returned yet */
for(i = 0; i < (MAX_DISP_BUFS_NEW); i++)
{
if(0 != ps_dec->u4_disp_buf_mapping[i])
{
display_queued = 1;
break;
}
}
/* If some buffer is queued for display, then codec has to singal an
error and wait for that buffer to be returned. If nothing is queued for
display then codec has ownership of all display buffers and it can
reuse any of the existing buffers and continue decoding */
if(1 == display_queued)
{
/* If something is queued for display wait for that buffer to be
* returned */
ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
return (IV_FAIL);
}
}
else
{
/* If the buffer is with display, then mark it as in use and then look
* for a buffer again */
if(1 == ps_dec->u4_disp_buf_mapping[free_id])
{
ih264_buf_mgr_set_status((buf_mgr_t *) ps_dec->pv_pic_buf_mgr, free_id,
BUF_MGR_IO);
}
else
{
/**
* Found a free buffer for present call. Release it now.
* Will be again obtained later.
*/
ih264_buf_mgr_release((buf_mgr_t *) ps_dec->pv_pic_buf_mgr, free_id,
BUF_MGR_IO);
break;
}
}
}
}
if(ps_dec->u1_enable_mb_info && (ps_dec->i4_header_decoded & DECODED_SPS_MASK))
{
UWORD32 blk_qp_map_size = ps_h264d_dec_ip->u4_8x8_blk_qp_map_size;
UWORD32 blk_type_map_size = ps_h264d_dec_ip->u4_8x8_blk_type_map_size;
UWORD32 blk_8x8_map_size = ps_dec->u4_total_mbs << 2;
if((ps_h264d_dec_ip->pu1_8x8_blk_qp_map && blk_qp_map_size < blk_8x8_map_size) ||
(ps_h264d_dec_ip->pu1_8x8_blk_type_map && blk_type_map_size < blk_8x8_map_size))
{
ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_dec_op->u4_error_code |= IH264D_INSUFFICIENT_METADATA_BUFFER;
return IV_FAIL;
}
}
if(ps_dec->u1_flushfrm && (1 == ps_svcd_ctxt->u1_pre_parse_in_flush))
{
if(ps_dec->u1_init_dec_flag == 0)
{
ps_dec->u1_flushfrm = 0;
return (IV_FAIL);
}
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->s_vcl_nal.i4_num_res_lyrs - 1];
ps_dec = &ps_svc_lyr_dec->s_dec;
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->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;
}
ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer, &(ps_dec->s_disp_op));
if(0 == ps_dec->s_disp_op.u4_error_code)
{
/* check output buffer size given by the application */
if(check_app_out_buf_size(ps_dec) != IV_SUCCESS)
{
ps_dec_op->u4_error_code = IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
return (IV_FAIL);
}
ps_dec->u4_fmt_conv_cur_row = 0;
ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht;
ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
ps_dec->u4_fmt_conv_num_rows);
ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
ps_dec->u4_output_present = 1;
if(ps_dec->u1_enable_mb_info)
{
UWORD32 disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
if(ps_h264d_dec_ip->pu1_8x8_blk_qp_map)
{
ps_h264d_dec_op->pu1_8x8_blk_qp_map = ps_h264d_dec_ip->pu1_8x8_blk_qp_map;
ps_h264d_dec_op->u4_8x8_blk_qp_map_size = ps_dec->u4_total_mbs << 2;
ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_qp_map,
ps_dec->as_buf_id_info_map[disp_buf_id].pu1_qp_map,
ps_dec->u4_total_mbs << 2);
}
if(ps_h264d_dec_ip->pu1_8x8_blk_type_map)
{
ps_h264d_dec_op->pu1_8x8_blk_type_map = ps_h264d_dec_ip->pu1_8x8_blk_type_map;
ps_h264d_dec_op->u4_8x8_blk_type_map_size = ps_dec->u4_total_mbs << 2;
ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_type_map,
ps_dec->as_buf_id_info_map[disp_buf_id].pu1_mb_type_map,
ps_dec->u4_total_mbs << 2);
}
}
}
ih264d_export_sei_params(&ps_dec_op->s_sei_decode_op, ps_dec);
ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op));
ps_dec_op->u4_pic_wd = (UWORD32) ps_dec->u2_disp_width;
ps_dec_op->u4_pic_ht = (UWORD32) ps_dec->u2_disp_height;
ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
ps_dec_op->i4_display_index = ps_dec->i4_display_index;
ps_dec_op->u4_new_seq = 0;
ps_dec_op->u4_output_present = ps_dec->u4_output_present;
ps_dec_op->u4_progressive_frame_flag = ps_dec->s_disp_op.u4_progressive_frame_flag;
ps_dec_op->e_output_format = ps_dec->s_disp_op.e_output_format;
ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf;
ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type;
ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts;
ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
/*In the case of flush ,since no frame is decoded set pic type as invalid*/
ps_dec_op->u4_is_ref_flag = UINT32_MAX;
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*/
if(((buf_mgr_t *) ps_dec->pv_pic_buf_mgr)->pv_mutex != NULL)
ih264_buf_mgr_free(ps_dec->pv_pic_buf_mgr);
if(((buf_mgr_t *) ps_dec->pv_mv_buf_mgr)->pv_mutex != NULL)
ih264_buf_mgr_free(ps_dec->pv_mv_buf_mgr);
isvcd_init_decoder(ps_svc_lyr_dec);
}
DEBUG_THREADS_PRINTF(" Starting process call\n");
{
vcl_node_t *ps_cur_node;
UWORD8 u1_num_res_lyrs;
vcl_buf_hdr_t *ps_vcl_buf;
UWORD8 flush_decode = 1;
ps_svcd_ctxt->u1_pre_parse_in_flush = 0;
ret = isvcd_pre_parse_refine_au(ps_svcd_ctxt, ps_dec_ip, &ps_dec_op->u4_num_bytes_consumed);
ps_svcd_ctxt->u1_pre_parse_in_flush = (ret == FLUSH);
if(ret != OK)
{
UWORD32 error = ih264d_map_error((UWORD32) ret);
if(ret != NOT_OK)
{
ps_dec_op->u4_error_code = error | ret;
}
if((ps_dec_op->u4_error_code >> IVD_FATALERROR) & 1)
{
ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
}
api_ret_value = IV_FAIL;
if((ret == IVD_RES_CHANGED) || (ret == IVD_MEM_ALLOC_FAILED) ||
(ret == ERROR_UNAVAIL_PICBUF_T) || (ret == ERROR_UNAVAIL_MVBUF_T) ||
(ret == ERROR_INV_SPS_PPS_T) || (ret == ERROR_FEATURE_UNAVAIL) ||
(ret == IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED) ||
(ret == IVD_DISP_FRM_ZERO_OP_BUF_SIZE))
{
ps_dec->u4_slice_start_code_found = 0;
}
if((ret == ERROR_INCOMPLETE_FRAME) || (ret == ERROR_DANGLING_FIELD_IN_PIC))
{
api_ret_value = IV_FAIL;
}
if(ret == ERROR_IN_LAST_SLICE_OF_PIC)
{
api_ret_value = IV_FAIL;
}
}
if(NOT_OK == ret)
{
if(ps_dec->u4_pic_buf_got == 0)
{
ps_dec->i4_error_code = ERROR_START_CODE_NOT_FOUND;
ps_dec_op->u4_error_code |= 1 << IVD_INSUFFICIENTDATA;
isvcd_fill_output_struct_from_context(ps_svc_lyr_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);
}
return (IV_SUCCESS);
}
u1_num_res_lyrs = ps_svcd_ctxt->s_vcl_nal.i4_num_res_lyrs;
/* error concelment: exit till next IDR if any of Non Target layers are
* corrupted */
{
ps_cur_node = ps_svcd_ctxt->s_vcl_nal.ps_bot_node;
if(NULL != ps_cur_node)
{
if(!ps_cur_node->i4_idr_pic_flag)
{
if(u1_num_res_lyrs != ps_svcd_ctxt->u1_prev_num_res_layers)
{
ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
ps_dec_op->u4_error_code = ERROR_UNKNOWN_NAL;
return IV_FAIL;
}
}
else
{
if(u1_num_res_lyrs != ps_svcd_ctxt->u1_prev_num_res_layers)
{
ps_svcd_ctxt->u1_prev_num_res_layers = u1_num_res_lyrs;
}
}
}
}
if(ps_svcd_ctxt->u1_prev_num_res_layers != u1_num_res_lyrs && (u1_num_res_lyrs != 0))
{
ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr + u1_num_res_lyrs - 1;
ps_dec = &ps_svc_lyr_dec->s_dec;
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);
ih264_disp_mgr_init((disp_mgr_t *) ps_dec->pv_disp_buf_mgr);
ih264_buf_mgr_reset(ps_dec->pv_pic_buf_mgr);
ih264_buf_mgr_reset(ps_dec->pv_mv_buf_mgr);
ih264d_init_ref_bufs(ps_dec->ps_dpb_mgr);
}
// ps_svcd_ctxt->u1_prev_num_res_layers = u1_num_res_lyrs;
}
ps_svcd_ctxt->u1_parse_nal_unit_error = 0;
if((1 == ps_svcd_ctxt->u1_exit_till_next_IDR) &&
(ps_svcd_ctxt->s_vcl_nal.ps_bot_node != NULL))
{
if(1 == ps_svcd_ctxt->s_vcl_nal.ps_bot_node->i4_idr_pic_flag)
{
ps_svcd_ctxt->u1_exit_till_next_IDR = 0;
for(u1_res_id = 0; u1_res_id < u1_num_res_lyrs; u1_res_id++)
{
ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr + u1_res_id;
ps_dec = &ps_svc_lyr_dec->s_dec;
ih264_buf_mgr_reset(ps_dec->pv_pic_buf_mgr);
ih264_buf_mgr_reset(ps_dec->pv_mv_buf_mgr);
}
}
else
{
ps_dec_op->u4_error_code = ERROR_UNKNOWN_NAL;
return IV_FAIL;
}
}
if((0 == ps_dec->i4_decode_header) && (OK == ret))
{
flush_decode = 0;
ps_cur_node = ps_svcd_ctxt->s_vcl_nal.ps_bot_node;
ps_svc_lyr_zero_dec = ps_svcd_ctxt->ps_svc_dec_lyr;
ps_dec_zero_lyr = &ps_svc_lyr_zero_dec->s_dec;
/* master loop */
for(u1_res_id = 0; u1_res_id < u1_num_res_lyrs; u1_res_id++)
{
UWORD8 u1_layer_nal_data_present = 0;
ps_svcd_ctxt->u1_cur_layer_id = u1_res_id;
ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr + u1_res_id;
ps_dec = &ps_svc_lyr_dec->s_dec;
ps_dec->i4_decode_header = ps_dec_zero_lyr->i4_decode_header;
ps_dec->i4_header_decoded = ps_dec_zero_lyr->i4_header_decoded;
ps_dec->u1_pic_decode_done = 0;
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_ts = ps_dec_ip->u4_ts;
ps_dec->i4_frametype = IV_NA_FRAME;
ps_dec->i4_content_type = IV_CONTENTTYPE_NA;
ps_dec->u4_slice_start_code_found = 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 = 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_cur_deblk_mb_num = 0;
ps_dec->u4_start_recon_deblk = 0;
ps_dec->u4_sps_cnt_in_process = 0;
ps_dec->u4_pic_buf_got = 0;
ps_dec->pv_dec_out = ps_dec_op;
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->u1_nal_unit_type = ps_cur_node->i4_nal_unit_type;
ps_dec->u1_separate_parse = 0;
if(u1_res_id == (u1_num_res_lyrs - 1))
{
ps_svc_lyr_dec->u1_layer_identifier = TARGET_LAYER;
if(ps_dec->u4_num_cores >= 2)
{
ps_dec->u4_num_cores = 2;
ps_dec->u1_separate_parse = 1;
}
}
else if(u1_res_id == 0)
{
ps_svc_lyr_dec->u1_layer_identifier = BASE_LAYER;
ps_dec->u1_separate_parse = 0;
ps_dec->u4_num_cores = 1;
}
else if(u1_res_id != 0)
{
ps_svc_lyr_dec->u1_layer_identifier = MEDIAL_ENHANCEMENT_LAYER;
ps_dec->u1_separate_parse = 0;
ps_dec->u4_num_cores = 1;
}
else
{
return IV_FAIL;
}
ps_svc_lyr_dec->u1_base_res_flag = (0 == u1_res_id);
ps_svc_lyr_dec->ps_nal_svc_ext->u1_idr_flag = ps_cur_node->i4_idr_pic_flag;
ps_svc_lyr_dec->ps_nal_svc_ext->u1_dependency_id = ps_cur_node->i4_dependency_id;
ps_svc_lyr_dec->ps_nal_svc_ext->u1_priority_id = ps_cur_node->i4_priority_id;
ps_svc_lyr_dec->ps_nal_svc_ext->u1_no_inter_layer_pred_flag =
ps_cur_node->u1_acc_no_int_pred;
ps_svc_lyr_dec->ps_nal_svc_ext->u1_quality_id = ps_cur_node->i4_quality_id;
ps_svc_lyr_dec->ps_nal_svc_ext->u1_temporal_id = ps_cur_node->i4_temporal_id;
ps_svc_lyr_dec->ps_nal_svc_ext->u1_use_ref_base_pic_flag =
ps_cur_node->i4_use_ref_base;
ps_svc_lyr_dec->ps_nal_svc_ext->u1_discardable_flag = 0;
ps_svc_lyr_dec->ps_nal_svc_ext->u1_svc_ext_flag = (u1_res_id > 1);
ps_svc_lyr_dec->u4_pps_id_for_layer = UINT32_MAX;
ps_vcl_buf = ps_cur_node->ps_first_vcl_nal;
ps_svc_lyr_dec->u1_error_in_cur_frame = 0;
/* Only for Non target Layers*/
if(NULL != ps_cur_node->ps_top_node)
{
ps_svc_lyr_dec->u1_inter_lyr_disable_dblk_filter_idc =
ps_cur_node->ps_top_node->i4_inter_lyr_dblk_idc;
ps_svc_lyr_dec->i1_inter_lyr_slice_alpha_c0_offset =
ps_cur_node->ps_top_node->i4_inter_lyr_alpha_c0_offset;
ps_svc_lyr_dec->i1_inter_lyr_slice_beta_offset =
ps_cur_node->ps_top_node->i4_inter_lyr_beta_offset;
}
while(NULL != ps_vcl_buf)
{
u1_layer_nal_data_present = 1;
ps_dec->ps_bitstrm->u4_ofst = 0;
ps_dec->ps_bitstrm->pu4_buffer =
(UWORD32 *) ((UWORD8 *) ps_vcl_buf + ps_vcl_buf->i4_buf_offset +
ps_vcl_buf->i4_slice_offset);
ps_dec->ps_bitstrm->u4_max_ofst = ps_vcl_buf->u4_max_bits;
ps_dec_op->u4_frame_decoded_flag = 0;
ret = isvcd_parse_nal_unit(ps_svc_lyr_dec, ps_cur_node->i4_nal_ref_idc);
if(ret != OK)
{
ps_svcd_ctxt->u1_parse_nal_unit_error = 1;
break;
}
/* go to the next slice */
ps_vcl_buf = ps_vcl_buf->ps_next;
}
/* error concelment: exit till next IDR if a Layer data is missing */
if(0 == u1_layer_nal_data_present)
{
ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
ps_dec_op->u4_error_code = ERROR_UNKNOWN_NAL;
return IV_FAIL;
}
/* error concelment: exit till next IDR if any of Non Target layers are
* corrupted */
if((ret != OK) && (u1_res_id != (u1_num_res_lyrs - 1)))
{
ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
ps_dec_op->u4_error_code = ERROR_UNKNOWN_NAL;
return IV_FAIL;
}
if((ret != OK) && (u1_res_id == (u1_num_res_lyrs - 1)))
{
ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr + u1_num_res_lyrs - 1;
ps_dec = &ps_svc_lyr_dec->s_dec;
if((0 == ps_svcd_ctxt->u4_num_sps_ctr) || (0 == ps_svcd_ctxt->u4_num_pps_ctr) ||
(NULL == ps_dec->ps_cur_pps))
{
ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
ps_dec_op->u4_error_code = ERROR_UNKNOWN_NAL;
ih264d_signal_decode_thread(ps_dec);
return IV_FAIL;
}
}
ps_cur_node = ps_cur_node->ps_top_node;
if((ps_dec->u4_pic_buf_got == 1) && (ret != IVD_MEM_ALLOC_FAILED) &&
ps_dec->u2_total_mbs_coded < ps_dec->u2_frm_ht_in_mbs * ps_dec->u2_frm_wd_in_mbs)
{
// last slice - missing/corruption
WORD32 num_mb_skipped;
WORD32 prev_slice_err;
pocstruct_t temp_poc;
WORD32 ret1;
WORD32 ht_in_mbs;
ht_in_mbs = ps_dec->u2_pic_ht >> (4 + ps_dec->ps_cur_slice->u1_field_pic_flag);
num_mb_skipped =
(ht_in_mbs * ps_dec->u2_frm_wd_in_mbs) - ps_dec->u2_total_mbs_coded;
if(ps_dec->u4_first_slice_in_pic && (ps_dec->u4_pic_buf_got == 0))
prev_slice_err = 1;
else
prev_slice_err = 2;
if(ps_dec->u2_total_mbs_coded == 0)
{
prev_slice_err = 1;
}
ret1 = isvcd_mark_err_slice_skip(
ps_svc_lyr_dec, num_mb_skipped, ps_dec->u1_nal_unit_type == IDR_SLICE_NAL,
ps_dec->ps_cur_slice->u2_frame_num, &temp_poc, prev_slice_err);
if((ret1 == ERROR_UNAVAIL_PICBUF_T) || (ret1 == ERROR_UNAVAIL_MVBUF_T) ||
(ret1 == ERROR_INV_SPS_PPS_T) || (ret1 == ERROR_CORRUPTED_SLICE) ||
(ret == NOT_OK))
{
ret = ret1;
}
}
if((ret == IVD_RES_CHANGED) || (ret == IVD_MEM_ALLOC_FAILED) ||
(ret == ERROR_UNAVAIL_PICBUF_T) || (ret == ERROR_UNAVAIL_MVBUF_T) ||
(ret == ERROR_INV_SPS_PPS_T) || (ret == ERROR_CORRUPTED_SLICE) ||
(ret == IVD_DISP_FRM_ZERO_OP_BUF_SIZE) || (ret == NOT_OK))
{
ps_svcd_ctxt->u1_exit_till_next_IDR = 1;
/* signal the decode thread */
ih264d_signal_decode_thread(ps_dec);
/* dont consume bitstream for change in resolution case */
if(ret == IVD_RES_CHANGED)
{
ps_dec_op->u4_num_bytes_consumed -= bytes_consumed;
}
return IV_FAIL;
}
/* Multi thread - for target Layer decoding*/
if((ps_dec->u1_separate_parse) &&
(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER) &&
(0 == ps_svc_lyr_dec->u1_error_in_cur_frame))
{
/* If Format conversion is not complete,
complete it here */
if(ps_dec->u4_num_cores == 2)
{
/*do deblocking of all mbs*/
if((ps_dec->u4_nmb_deblk == 0) && (ps_dec->u4_start_recon_deblk == 1) &&
(ps_dec->ps_cur_sps->u1_mb_aff_flag == 0))
{
UWORD8 u1_end_of_row = 0;
UWORD32 u4_max_addr;
tfr_ctxt_t s_tfr_ctxt = {0};
tfr_ctxt_t *ps_tfr_cxt = &s_tfr_ctxt;
pad_mgr_t *ps_pad_mgr = &ps_dec->s_pad_mgr;
UWORD32 u4_slice_end = 0;
/*BS is done for all mbs while parsing*/
u4_max_addr = (ps_dec->u2_frm_wd_in_mbs * ps_dec->u2_frm_ht_in_mbs) - 1;
/* BS is moved post recon gen in SVC ext*/
ih264d_init_deblk_tfr_ctxt(ps_dec, ps_pad_mgr, ps_tfr_cxt,
ps_dec->u2_frm_wd_in_mbs, 0);
{
while(u4_slice_end != 1)
{
dec_mb_info_t *p_cur_mb;
WORD32 i, bs_mb_grp;
bs_mb_grp = ps_dec->cur_dec_mb_num - ps_dec->u4_cur_bs_mb_num;
for(i = 0; i < bs_mb_grp; i++)
{
p_cur_mb =
&ps_dec->ps_frm_mb_info[ps_dec->u4_cur_bs_mb_num];
DEBUG_THREADS_PRINTF("ps_dec->u4_cur_bs_mb_num = %d\n",
ps_dec->u4_cur_bs_mb_num);
isvcd_compute_bs_non_mbaff_thread(ps_svc_lyr_dec, p_cur_mb,
ps_dec->u4_cur_bs_mb_num);
ps_dec->u4_cur_bs_mb_num++;
ps_dec->u4_bs_cur_slice_num_mbs++;
}
if(ps_dec->u4_cur_bs_mb_num > u4_max_addr)
{
u4_slice_end = 1;
u1_end_of_row = 1;
}
/*deblock MB group*/
{
UWORD32 u4_num_mbs;
if(ps_dec->u4_cur_bs_mb_num > ps_dec->u4_cur_deblk_mb_num)
{
if(u1_end_of_row)
{
u4_num_mbs = ps_dec->u4_cur_bs_mb_num -
ps_dec->u4_cur_deblk_mb_num;
}
else
{
u4_num_mbs = ps_dec->u4_cur_bs_mb_num -
ps_dec->u4_cur_deblk_mb_num - 1;
}
}
else
u4_num_mbs = 0;
ih264d_check_mb_map_deblk(ps_dec, u4_num_mbs, ps_tfr_cxt,
0);
}
}
}
}
}
/*signal the decode thread*/
ih264d_signal_decode_thread(ps_dec);
}
else if((ps_dec->u1_separate_parse) &&
(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER))
{
/*signal the decode thread*/
ih264d_signal_decode_thread(ps_dec);
}
DATA_SYNC();
if((ps_dec_op->u4_error_code & 0xff) != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
{
ps_dec_op->u4_pic_wd = (UWORD32) ps_dec->u2_disp_width;
ps_dec_op->u4_pic_ht = (UWORD32) ps_dec->u2_disp_height;
ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
}
// Report if header (sps and pps) has not been decoded yet
if(ps_dec->i4_decode_header == 1 && ps_dec->i4_header_decoded != 3)
{
ps_dec_op->u4_error_code |= (1 << IVD_INSUFFICIENTDATA);
api_ret_value = IV_FAIL;
}
if((ps_dec->u4_pic_buf_got == 1) && (ERROR_DANGLING_FIELD_IN_PIC != i4_err_status))
{
/* For field pictures, set bottom and top picture decoded u4_flag correctly */
if(ps_dec->ps_cur_slice->u1_field_pic_flag)
{
if(1 == ps_dec->ps_cur_slice->u1_bottom_field_flag)
{
ps_dec->u1_top_bottom_decoded |= BOT_FIELD_ONLY;
}
else
{
ps_dec->u1_top_bottom_decoded |= TOP_FIELD_ONLY;
}
}
else
{
ps_dec->u1_top_bottom_decoded = TOP_FIELD_ONLY | BOT_FIELD_ONLY;
}
/* if new frame in not found (if we are still getting slices from
* previous frame) ih264d_deblock_display is not called. Such frames
* will not be added to reference /display
*/
if((ps_dec->ps_dec_err_status->u1_err_flag & REJECT_CUR_PIC) == 0)
{
/* Calling Function to deblock Picture and Display */
ret = ih264d_deblock_display(ps_dec);
}
/*set to complete ,as we dont support partial frame decode*/
if(ps_dec->i4_header_decoded == 3)
{
ps_dec->u2_total_mbs_coded = ps_dec->ps_cur_sps->u2_max_mb_addr + 1;
}
/*Update the i4_frametype at the end of picture*/
if(ps_dec->ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL)
{
ps_dec->i4_frametype = IV_IDR_FRAME;
}
else if(ps_dec->i4_pic_type == B_SLICE)
{
ps_dec->i4_frametype = IV_B_FRAME;
}
else if(ps_dec->i4_pic_type == P_SLICE)
{
ps_dec->i4_frametype = IV_P_FRAME;
}
else if(ps_dec->i4_pic_type == I_SLICE)
{
ps_dec->i4_frametype = IV_I_FRAME;
}
else
{
H264_DEC_DEBUG_PRINT("Shouldn't come here\n");
}
// Update the content type
ps_dec->i4_content_type = ps_dec->ps_cur_slice->u1_field_pic_flag;
ps_dec->u4_total_frames_decoded = ps_dec->u4_total_frames_decoded + 2;
ps_dec->u4_total_frames_decoded =
ps_dec->u4_total_frames_decoded - ps_dec->ps_cur_slice->u1_field_pic_flag;
}
/* In case the decoder is configured to run in low delay mode,
* then get display buffer and then format convert.
* Note in this mode, format conversion does not run paralelly in a
* thread and adds to the codec cycles
*/
if((IVD_DECODE_FRAME_OUT == ps_dec->e_frm_out_mode) && ps_dec->u1_init_dec_flag)
{
ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer,
&(ps_dec->s_disp_op));
if(0 == ps_dec->s_disp_op.u4_error_code)
{
ps_dec->u4_fmt_conv_cur_row = 0;
ps_dec->u4_output_present = 1;
}
else
{
ps_dec->u4_output_present = 0;
}
}
isvcd_fill_output_struct_from_context(ps_svc_lyr_dec, ps_dec_op);
/* If Format conversion is not complete,
complete it here */
/* For Non -target Layers , Buffers are retrived but not displayed*/
if((ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER) &&
ps_dec->u4_output_present &&
(ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
{
ps_dec->u4_fmt_conv_num_rows =
ps_dec->s_disp_frame_info.u4_y_ht - ps_dec->u4_fmt_conv_cur_row;
ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
ps_dec->u4_fmt_conv_num_rows);
ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
}
ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op));
if(ps_dec->i4_decode_header == 1 && (ps_dec->i4_header_decoded & 1) == 1)
{
ps_dec_op->u4_progressive_frame_flag = 1;
if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
{
if((0 == ps_dec->ps_sps->u1_frame_mbs_only_flag) &&
(0 == ps_dec->ps_sps->u1_mb_aff_flag))
ps_dec_op->u4_progressive_frame_flag = 0;
}
}
if((TOP_FIELD_ONLY | BOT_FIELD_ONLY) == ps_dec->u1_top_bottom_decoded)
{
ps_dec->u1_top_bottom_decoded = 0;
}
/*--------------------------------------------------------------------*/
/* Do End of Pic processing. */
/* Should be called only if frame was decoded in previous process call*/
/*--------------------------------------------------------------------*/
if(ps_dec->u4_pic_buf_got == 1)
{
if(1 == ps_dec->u1_last_pic_not_decoded)
{
ret = ih264d_end_of_pic_dispbuf_mgr(ps_dec);
if(ret != OK) return ret;
ret = ih264d_end_of_pic(ps_dec);
if(ret != OK) return ret;
}
else
{
ret = ih264d_end_of_pic(ps_dec);
if(ret != OK) return ret;
}
}
if(ps_dec->u1_enable_mb_info && ps_dec->u4_output_present)
{
UWORD32 disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
if(ps_h264d_dec_ip->pu1_8x8_blk_qp_map)
{
ps_h264d_dec_op->pu1_8x8_blk_qp_map = ps_h264d_dec_ip->pu1_8x8_blk_qp_map;
ps_h264d_dec_op->u4_8x8_blk_qp_map_size = ps_dec->u4_total_mbs << 2;
ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_qp_map,
ps_dec->as_buf_id_info_map[disp_buf_id].pu1_qp_map,
ps_dec->u4_total_mbs << 2);
}
if(ps_h264d_dec_ip->pu1_8x8_blk_type_map)
{
ps_h264d_dec_op->pu1_8x8_blk_type_map =
ps_h264d_dec_ip->pu1_8x8_blk_type_map;
ps_h264d_dec_op->u4_8x8_blk_type_map_size = ps_dec->u4_total_mbs << 2;
ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_type_map,
ps_dec->as_buf_id_info_map[disp_buf_id].pu1_mb_type_map,
ps_dec->u4_total_mbs << 2);
}
}
/*Data memory barrier instruction,so that yuv write by the library is
* complete*/
DATA_SYNC();
H264_DEC_DEBUG_PRINT("The num bytes consumed: %d\n",
ps_dec_op->u4_num_bytes_consumed);
}
}
/* highest layer for flush validation */
if((ps_dec->u1_flushfrm) && (1 == flush_decode))
{
u1_res_id = u1_num_res_lyrs - 1;
ps_svc_lyr_dec = ps_svcd_ctxt->ps_svc_dec_lyr + u1_res_id;
ps_dec = &ps_svc_lyr_dec->s_dec;
ih264d_get_next_display_field(ps_dec, ps_dec->ps_out_buffer, &(ps_dec->s_disp_op));
if(0 == ps_dec->s_disp_op.u4_error_code)
{
/* check output buffer size given by the application */
if(check_app_out_buf_size(ps_dec) != IV_SUCCESS)
{
ps_dec_op->u4_error_code = IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
return (IV_FAIL);
}
ps_dec->u4_fmt_conv_cur_row = 0;
ps_dec->u4_fmt_conv_num_rows = ps_dec->s_disp_frame_info.u4_y_ht;
ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
ps_dec->u4_fmt_conv_num_rows);
ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
ps_dec->u4_output_present = 1;
}
else
{
ps_dec->u4_output_present = 0;
}
ih264d_export_sei_params(&ps_dec_op->s_sei_decode_op, ps_dec);
ih264d_release_display_field(ps_dec, &(ps_dec->s_disp_op));
ps_dec_op->u4_pic_wd = (UWORD32) ps_dec->u2_disp_width;
ps_dec_op->u4_pic_ht = (UWORD32) ps_dec->u2_disp_height;
ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
ps_dec_op->i4_display_index = ps_dec->i4_display_index;
ps_dec_op->u4_new_seq = 0;
ps_dec_op->u4_output_present = (ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
? ps_dec->u4_output_present
: 0;
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 = UINT32_MAX;
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_op->u4_error_code & 0xff) != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
{
ps_dec_op->u4_pic_wd = (UWORD32) ps_dec->u2_disp_width;
ps_dec_op->u4_pic_ht = (UWORD32) ps_dec->u2_disp_height;
ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
}
return api_ret_value;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_set_display_frame */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_set_display_frame(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
UWORD32 u4_disp_buf_size[3] = {0};
UWORD32 u4_num_disp_bufs;
ivd_set_display_frame_ip_t *dec_disp_ip;
ivd_set_display_frame_op_t *dec_disp_op;
UWORD32 i;
dec_struct_t *ps_dec;
svc_dec_ctxt_t *ps_svcd_ctxt;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
dec_disp_ip = (ivd_set_display_frame_ip_t *) pv_api_ip;
dec_disp_op = (ivd_set_display_frame_op_t *) pv_api_op;
dec_disp_op->u4_error_code = 0;
ps_dec->u4_num_disp_bufs = 0;
if(ps_dec->u4_share_disp_buf)
{
UWORD32 u4_num_bufs = dec_disp_ip->num_disp_bufs;
u4_num_bufs = MIN(u4_num_bufs, MAX_DISP_BUFS_NEW);
ps_dec->u4_num_disp_bufs = u4_num_bufs;
/* Get the number and sizes of the first buffer. Compare this with the
* rest to make sure all the buffers are of the same size.
*/
u4_num_disp_bufs = dec_disp_ip->s_disp_buffer[0].u4_num_bufs;
u4_disp_buf_size[0] = dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[0];
u4_disp_buf_size[1] = dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1];
u4_disp_buf_size[2] = dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[2];
for(i = 0; i < u4_num_bufs; i++)
{
if(dec_disp_ip->s_disp_buffer[i].u4_num_bufs != u4_num_disp_bufs)
{
return IV_FAIL;
}
if((dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0] != u4_disp_buf_size[0]) ||
(dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1] != u4_disp_buf_size[1]) ||
(dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2] != u4_disp_buf_size[2]))
{
return IV_FAIL;
}
ps_dec->disp_bufs[i].u4_num_bufs = dec_disp_ip->s_disp_buffer[i].u4_num_bufs;
ps_dec->disp_bufs[i].buf[0] = dec_disp_ip->s_disp_buffer[i].pu1_bufs[0];
ps_dec->disp_bufs[i].buf[1] = dec_disp_ip->s_disp_buffer[i].pu1_bufs[1];
ps_dec->disp_bufs[i].buf[2] = dec_disp_ip->s_disp_buffer[i].pu1_bufs[2];
ps_dec->disp_bufs[i].u4_bufsize[0] =
dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0];
ps_dec->disp_bufs[i].u4_bufsize[1] =
dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1];
ps_dec->disp_bufs[i].u4_bufsize[2] =
dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2];
}
}
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : ih264d_set_flush_mode_svt_ext */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Globals : <Does it use any global variables?> */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_set_flush_mode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
UWORD8 u1_layer_id;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t *) pv_api_op;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_ctl_op->u4_error_code = 0;
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[0];
ps_dec = &ps_svc_lyr_dec->s_dec;
if(0 == ps_dec->i4_decode_header)
{
ps_svcd_ctxt->i4_eos_flag = 1;
}
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
UNUSED(pv_api_ip);
/* Signal flush frame control call */
ps_dec->u1_flushfrm = 1;
if(ps_dec->u1_init_dec_flag == 1)
{
ih264d_release_pics_in_dpb((void *) ps_dec, ps_dec->u1_pic_bufs);
ih264d_release_display_bufs(ps_dec);
}
ps_ctl_op->u4_error_code = 0;
/* Ignore dangling fields during flush */
ps_dec->u1_top_bottom_decoded = 0;
}
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_get_status */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Globals : <Does it use any global variables?> */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_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;
svc_dec_ctxt_t *ps_svcd_ctxt;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
UNUSED(pv_api_ip);
ps_ctl_op->u4_error_code = 0;
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;
ps_ctl_op->u4_bit_rate = 0;
ps_ctl_op->e_content_type = ps_dec->i4_content_type;
ps_ctl_op->e_output_chroma_format = ps_dec->u1_chroma_format;
ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
if(ps_dec->u1_chroma_format == IV_YUV_420P)
{
ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
}
else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
{
ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
}
else if(ps_dec->u1_chroma_format == IV_RGB_565)
{
ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
}
else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) ||
(ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
{
ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
}
else
{
// Invalid chroma format; Error code may be updated, verify in testing if needed
ps_ctl_op->u4_error_code = ERROR_FEATURE_UNAVAIL;
return IV_FAIL;
}
for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
{
ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2);
}
if(ps_dec->u1_chroma_format == IV_YUV_420P)
{
ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht) >> 2;
ps_ctl_op->u4_min_out_buf_size[2] = (pic_wd * pic_ht) >> 2;
}
else if(ps_dec->u1_chroma_format == IV_YUV_422ILE)
{
ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht) * 2;
ps_ctl_op->u4_min_out_buf_size[1] = ps_ctl_op->u4_min_out_buf_size[2] = 0;
}
else if(ps_dec->u1_chroma_format == IV_RGB_565)
{
ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht) * 2;
ps_ctl_op->u4_min_out_buf_size[1] = ps_ctl_op->u4_min_out_buf_size[2] = 0;
}
else if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) ||
(ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
{
ps_ctl_op->u4_min_out_buf_size[0] = (pic_wd * pic_ht);
ps_ctl_op->u4_min_out_buf_size[1] = (pic_wd * pic_ht) >> 1;
ps_ctl_op->u4_min_out_buf_size[2] = 0;
}
ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs;
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_get_buf_info */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Globals : <Does it use any global variables?> */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_get_buf_info(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
UWORD8 i = 0; // Default for 420P format
UWORD16 pic_wd, pic_ht;
ivd_ctl_getbufinfo_op_t *ps_ctl_op = (ivd_ctl_getbufinfo_op_t *) pv_api_op;
UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS] = {0};
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
UNUSED(pv_api_ip);
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
ps_ctl_op->u4_error_code = 0;
ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
ps_ctl_op->u4_num_disp_bufs = 1;
pic_wd = 0;
pic_ht = 0;
if(ps_dec->i4_header_decoded == 3)
{
if(0 == ps_dec->u4_share_disp_buf)
{
pic_wd = ps_dec->u2_disp_width;
pic_ht = ps_dec->u2_disp_height;
}
else
{
pic_wd = ps_dec->u2_frm_wd_y;
pic_ht = ps_dec->u2_frm_ht_y;
}
}
for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
{
ps_ctl_op->u4_min_in_buf_size[i] = MAX(256000, pic_wd * pic_ht * 3 / 2);
}
if((WORD32) ps_dec->u4_app_disp_width > pic_wd) pic_wd = ps_dec->u4_app_disp_width;
if(0 == ps_dec->u4_share_disp_buf)
ps_ctl_op->u4_num_disp_bufs = 1;
else
{
if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
{
if((ps_dec->ps_cur_sps->u1_vui_parameters_present_flag == 1) &&
(1 == ps_dec->ps_cur_sps->s_vui.u1_bitstream_restriction_flag))
{
ps_ctl_op->u4_num_disp_bufs = ps_dec->ps_cur_sps->s_vui.u4_num_reorder_frames + 1;
}
else
{
/*if VUI is not present assume maximum possible refrence frames for the
* level, as max reorder frames*/
ps_ctl_op->u4_num_disp_bufs = ih264d_get_dpb_size(ps_dec->ps_cur_sps);
}
ps_ctl_op->u4_num_disp_bufs += ps_dec->ps_cur_sps->u1_num_ref_frames + 1;
}
else
{
ps_ctl_op->u4_num_disp_bufs = 32;
}
ps_ctl_op->u4_num_disp_bufs = MAX(ps_ctl_op->u4_num_disp_bufs, 6);
ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs, 32);
}
ps_ctl_op->u4_min_num_out_bufs =
ih264d_get_outbuf_size(pic_wd, pic_ht, ps_dec->u1_chroma_format, &au4_min_out_buf_size[0]);
for(i = 0; i < ps_ctl_op->u4_min_num_out_bufs; i++)
{
ps_ctl_op->u4_min_out_buf_size[i] = au4_min_out_buf_size[i];
}
ps_dec->u4_num_disp_bufs_requested = ps_ctl_op->u4_num_disp_bufs;
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_set_params */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_set_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
WORD32 ret = IV_SUCCESS;
svc_dec_ctxt_t *ps_svcd_ctxt;
WORD32 u1_layer_id;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_svcd_ctxt->i4_eos_flag = 0;
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
isvcd_ctl_set_config_ip_t *ps_h264d_ctl_ip = (isvcd_ctl_set_config_ip_t *) pv_api_ip;
isvcd_ctl_set_config_op_t *ps_h264d_ctl_op = (isvcd_ctl_set_config_op_t *) pv_api_op;
ivd_ctl_set_config_ip_t *ps_ctl_ip = &ps_h264d_ctl_ip->s_ivd_ctl_set_config_ip_t;
ivd_ctl_set_config_op_t *ps_ctl_op = &ps_h264d_ctl_op->s_ivd_ctl_set_config_op_t;
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
ps_dec->u1_flushfrm = 0;
ps_dec->u4_skip_frm_mask = 0;
ps_ctl_op->u4_error_code = 0;
if(ps_ctl_ip->e_frm_skip_mode != IVD_SKIP_NONE)
{
ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
ret = IV_FAIL;
}
if(ps_ctl_ip->u4_disp_wd >= ps_dec->u2_disp_width)
{
ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd;
}
else if(0 == ps_dec->i4_header_decoded)
{
ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd;
}
else if(ps_ctl_ip->u4_disp_wd == 0)
{
ps_dec->u4_app_disp_width = 0;
}
else
{
/*
* Set the display width to zero. This will ensure that the wrong value we
* had stored (0xFFFFFFFF) does not propogate.
*/
ps_dec->u4_app_disp_width = 0;
ps_ctl_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
ps_ctl_op->u4_error_code |= ERROR_DISP_WIDTH_INVALID;
ret = IV_FAIL;
}
if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_FRAME)
ps_dec->i4_decode_header = 0;
else if(ps_ctl_ip->e_vid_dec_mode == IVD_DECODE_HEADER)
ps_dec->i4_decode_header = 1;
else
{
ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
ps_dec->i4_decode_header = 1;
ret = IV_FAIL;
}
ps_dec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
if((ps_ctl_ip->e_frm_out_mode != IVD_DECODE_FRAME_OUT) &&
(ps_ctl_ip->e_frm_out_mode != IVD_DISPLAY_FRAME_OUT))
{
ps_ctl_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
ret = IV_FAIL;
}
ps_dec->e_frm_out_mode = ps_ctl_ip->e_frm_out_mode;
}
return ret;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_set_target_layer */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 05 04 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_set_target_layer(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
WORD32 ret = IV_SUCCESS;
isvcd_set_target_layer_ip_t *ps_ip;
isvcd_set_target_layer_op_t *ps_op;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_ip = (isvcd_set_target_layer_ip_t *) pv_api_ip;
ps_op = (isvcd_set_target_layer_op_t *) pv_api_op;
ps_svcd_ctxt->u1_tgt_dep_id = ps_ip->u1_tgt_dep_id;
ps_svcd_ctxt->u1_tgt_quality_id = ps_ip->u1_tgt_quality_id;
ps_svcd_ctxt->u1_tgt_temp_id = ps_ip->u1_tgt_temp_id;
ps_svcd_ctxt->u1_tgt_priority_id = ps_ip->u1_tgt_priority_id;
ret = isvcd_nal_parse_set_target_attr(ps_ip->u1_tgt_quality_id, ps_ip->u1_tgt_dep_id,
ps_ip->u1_tgt_temp_id, ps_ip->u1_tgt_priority_id,
ps_svcd_ctxt->pv_nal_parse_ctxt);
ps_op->u4_error_code = 0;
return ret;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_set_default_params */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Copied from set_params */
/* */
/*****************************************************************************/
WORD32 isvcd_set_default_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
WORD32 ret = IV_SUCCESS;
UWORD8 u1_layer_id;
svc_dec_ctxt_t *ps_svcd_ctxt;
ivd_ctl_set_config_op_t *ps_ctl_op = (ivd_ctl_set_config_op_t *) pv_api_op;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
UNUSED(pv_api_ip);
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
ps_dec->u4_app_disp_width = 0;
ps_dec->u4_skip_frm_mask = 0;
ps_dec->i4_decode_header = 1;
}
ps_ctl_op->u4_error_code = 0;
return ret;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_delete */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Globals : <Does it use any global variables?> */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_delete(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
isvcd_delete_ip_t *ps_ip = (isvcd_delete_ip_t *) pv_api_ip;
isvcd_delete_op_t *ps_op = (isvcd_delete_op_t *) pv_api_op;
UWORD8 u1_layer_id;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
UNUSED(ps_ip);
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
isvcd_free_dynamic_bufs(ps_svc_lyr_dec);
}
isvcd_free_static_bufs(dec_hdl);
ps_op->s_ivd_delete_op_t.u4_error_code = 0;
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_reset */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Globals : <Does it use any global variables?> */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_reset(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
ivd_ctl_reset_op_t *ps_ctl_op = (ivd_ctl_reset_op_t *) pv_api_op;
UWORD8 u1_layer_id;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
UNUSED(pv_api_ip);
ps_ctl_op->u4_error_code = 0;
ps_svcd_ctxt->i4_eos_flag = 0;
ps_svcd_ctxt->u4_num_sps_ctr = 0;
ps_svcd_ctxt->u4_num_pps_ctr = 0;
ps_svcd_ctxt->u1_pre_parse_in_flush = 1;
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
if(ps_dec != NULL)
{
if(((buf_mgr_t *) ps_dec->pv_pic_buf_mgr)->pv_mutex != NULL)
ih264_buf_mgr_free(ps_dec->pv_pic_buf_mgr);
if(((buf_mgr_t *) ps_dec->pv_mv_buf_mgr)->pv_mutex != NULL)
ih264_buf_mgr_free(ps_dec->pv_mv_buf_mgr);
isvcd_init_decoder(ps_svc_lyr_dec);
ps_dec->u1_flushfrm = 0;
}
else
{
H264_DEC_DEBUG_PRINT("\nReset called without Initializing the decoder\n");
ps_ctl_op->u4_error_code = ERROR_INIT_NOT_DONE;
}
}
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_ctl */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_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;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
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 = isvcd_get_status(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IVD_CMD_CTL_SETPARAMS:
ret = isvcd_set_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IVD_CMD_CTL_RESET:
ret = isvcd_reset(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IVD_CMD_CTL_SETDEFAULT:
ret = isvcd_set_default_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IVD_CMD_CTL_FLUSH:
ret = isvcd_set_flush_mode(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IVD_CMD_CTL_GETBUFINFO:
ret = isvcd_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 = isvcd_set_degrade(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IH264D_CMD_CTL_SET_NUM_CORES:
ret = isvcd_set_num_cores(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS:
ret = isvcd_get_frame_dimensions(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IH264D_CMD_CTL_GET_VUI_PARAMS:
ret = isvcd_get_vui_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS:
ret = isvcd_get_sei_mdcv_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IH264D_CMD_CTL_GET_SEI_CLL_PARAMS:
ret = isvcd_get_sei_cll_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IH264D_CMD_CTL_GET_SEI_AVE_PARAMS:
ret = isvcd_get_sei_ave_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IH264D_CMD_CTL_GET_SEI_CCV_PARAMS:
ret = isvcd_get_sei_ccv_params(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IH264D_CMD_CTL_SET_PROCESSOR:
ret = isvcd_set_processor(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case ISVCD_CMD_CTL_SET_TGT_LAYER:
ret = isvcd_set_target_layer(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
default:
H264_DEC_DEBUG_PRINT("\ndo nothing\n");
break;
}
return ret;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_rel_display_frame */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_rel_display_frame(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
ivd_rel_display_frame_ip_t *ps_rel_ip;
ivd_rel_display_frame_op_t *ps_rel_op;
UWORD32 buf_released = 0;
UWORD32 u4_ts = 0;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
UWORD8 u1_layer_id;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) 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;
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
if(0 == ps_dec->u4_share_disp_buf)
{
ps_dec->u4_disp_buf_mapping[u4_ts] = 0;
ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 0;
return IV_SUCCESS;
}
if(ps_dec->pv_pic_buf_mgr != NULL)
{
if(1 == ps_dec->u4_disp_buf_mapping[u4_ts])
{
ih264_buf_mgr_release((buf_mgr_t *) ps_dec->pv_pic_buf_mgr,
ps_rel_ip->u4_disp_buf_id, BUF_MGR_IO);
ps_dec->u4_disp_buf_mapping[u4_ts] = 0;
buf_released = 1;
}
}
if((1 == ps_dec->u4_share_disp_buf) && (0 == buf_released))
ps_dec->u4_disp_buf_to_be_freed[u4_ts] = 1;
}
return IV_SUCCESS;
}
/**
*******************************************************************************
*
* @brief
* Sets degrade params
*
* @par Description:
* Sets degrade params.
* Refer to ih264d_ctl_degrade_ip_t definition for details
*
* @param[in] ps_codec_obj
* Pointer to codec object at API level
*
* @param[in] pv_api_ip
* Pointer to input argument structure
*
* @param[out] pv_api_op
* Pointer to output argument structure
*
* @returns Status
*
* @remarks
*
*
*******************************************************************************
*/
WORD32 isvcd_set_degrade(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
{
isvcd_ctl_degrade_ip_t *ps_ip;
isvcd_ctl_degrade_op_t *ps_op;
dec_struct_t *ps_codec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
UWORD8 u1_layer_id;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) ps_codec_obj->pv_codec_handle;
ps_ip = (isvcd_ctl_degrade_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_degrade_op_t *) pv_api_op;
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_codec = &ps_svc_lyr_dec->s_dec;
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_codec->i4_degrade_pic_cnt = 0;
}
ps_op->u4_error_code = 0;
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_get_frame_dimensions */
/* */
/* Description : gets the frame wd and ht and the buffer sizes */
/* */
/* 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) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_get_frame_dimensions(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
isvcd_ctl_get_frame_dimensions_ip_t *ps_ip;
isvcd_ctl_get_frame_dimensions_op_t *ps_op;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
UWORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
ps_ip = (isvcd_ctl_get_frame_dimensions_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_frame_dimensions_op_t *) pv_api_op;
UNUSED(ps_ip);
if((NULL != ps_dec->ps_cur_sps) && (1 == (ps_dec->ps_cur_sps->u1_is_valid)))
{
disp_wd = ps_dec->u2_disp_width;
disp_ht = ps_dec->u2_disp_height;
if(0 == ps_dec->u4_share_disp_buf)
{
buffer_wd = disp_wd;
buffer_ht = disp_ht;
}
else
{
buffer_wd = ps_dec->u2_frm_wd_y;
buffer_ht = ps_dec->u2_frm_ht_y;
}
}
else
{
disp_wd = 0;
disp_ht = 0;
if(0 == ps_dec->u4_share_disp_buf)
{
buffer_wd = disp_wd;
buffer_ht = disp_ht;
}
else
{
buffer_wd = ALIGN16(disp_wd) + (PAD_LEN_Y_H << 1);
buffer_ht = ALIGN16(disp_ht) + (PAD_LEN_Y_V << 2);
}
}
if(ps_dec->u4_app_disp_width > buffer_wd) buffer_wd = ps_dec->u4_app_disp_width;
if(0 == ps_dec->u4_share_disp_buf)
{
x_offset = 0;
y_offset = 0;
}
else
{
y_offset = (PAD_LEN_Y_V << 1);
x_offset = PAD_LEN_Y_H;
if((NULL != ps_dec->ps_sps) && (1 == (ps_dec->ps_sps->u1_is_valid)) &&
(0 != ps_dec->u2_crop_offset_y))
{
y_offset += ps_dec->u2_crop_offset_y / ps_dec->u2_frm_wd_y;
x_offset += ps_dec->u2_crop_offset_y % ps_dec->u2_frm_wd_y;
}
}
ps_op->u4_disp_wd[0] = disp_wd;
ps_op->u4_disp_ht[0] = disp_ht;
ps_op->u4_buffer_wd[0] = buffer_wd;
ps_op->u4_buffer_ht[0] = buffer_ht;
ps_op->u4_x_offset[0] = x_offset;
ps_op->u4_y_offset[0] = y_offset;
ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1) >> 1);
ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1) >> 1);
ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0] >> 1);
ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0] >> 1);
ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = (ps_op->u4_x_offset[0] >> 1);
ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] = (ps_op->u4_y_offset[0] >> 1);
if((ps_dec->u1_chroma_format == IV_YUV_420SP_UV) ||
(ps_dec->u1_chroma_format == IV_YUV_420SP_VU))
{
ps_op->u4_disp_wd[2] = 0;
ps_op->u4_disp_ht[2] = 0;
ps_op->u4_buffer_wd[2] = 0;
ps_op->u4_buffer_ht[2] = 0;
ps_op->u4_x_offset[2] = 0;
ps_op->u4_y_offset[2] = 0;
ps_op->u4_disp_wd[1] <<= 1;
ps_op->u4_buffer_wd[1] <<= 1;
ps_op->u4_x_offset[1] <<= 1;
}
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_get_vui_params */
/* */
/* Description : gets the VUI params */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : success or failure */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
WORD32 isvcd_get_vui_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
isvcd_ctl_get_vui_params_ip_t *ps_ip;
isvcd_ctl_get_vui_params_op_t *ps_op;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
dec_seq_params_t *ps_sps;
vui_t *ps_vui;
UWORD32 u4_size;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_ip = (isvcd_ctl_get_vui_params_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_vui_params_op_t *) pv_api_op;
UNUSED(ps_ip);
u4_size = ps_op->u4_size;
memset(ps_op, 0, sizeof(isvcd_ctl_get_vui_params_op_t));
ps_op->u4_size = u4_size;
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
if(NULL == ps_dec->ps_cur_sps)
{
ps_op->u4_error_code = ERROR_VUI_PARAMS_NOT_FOUND;
return IV_FAIL;
}
ps_sps = ps_dec->ps_cur_sps;
if((0 == ps_sps->u1_is_valid) || (0 == ps_sps->u1_vui_parameters_present_flag))
{
ps_op->u4_error_code = ERROR_VUI_PARAMS_NOT_FOUND;
return IV_FAIL;
}
ps_vui = &ps_sps->s_vui;
ps_op->u1_aspect_ratio_idc = ps_vui->u1_aspect_ratio_idc;
ps_op->u2_sar_width = ps_vui->u2_sar_width;
ps_op->u2_sar_height = ps_vui->u2_sar_height;
ps_op->u1_overscan_appropriate_flag = ps_vui->u1_overscan_appropriate_flag;
ps_op->u1_video_format = ps_vui->u1_video_format;
ps_op->u1_video_full_range_flag = ps_vui->u1_video_full_range_flag;
ps_op->u1_colour_primaries = ps_vui->u1_colour_primaries;
ps_op->u1_tfr_chars = ps_vui->u1_tfr_chars;
ps_op->u1_matrix_coeffs = ps_vui->u1_matrix_coeffs;
ps_op->u1_cr_top_field = ps_vui->u1_cr_top_field;
ps_op->u1_cr_bottom_field = ps_vui->u1_cr_bottom_field;
ps_op->u4_num_units_in_tick = ps_vui->u4_num_units_in_tick;
ps_op->u4_time_scale = ps_vui->u4_time_scale;
ps_op->u1_fixed_frame_rate_flag = ps_vui->u1_fixed_frame_rate_flag;
ps_op->u1_nal_hrd_params_present = ps_vui->u1_nal_hrd_params_present;
ps_op->u1_vcl_hrd_params_present = ps_vui->u1_vcl_hrd_params_present;
ps_op->u1_low_delay_hrd_flag = ps_vui->u1_low_delay_hrd_flag;
ps_op->u1_pic_struct_present_flag = ps_vui->u1_pic_struct_present_flag;
ps_op->u1_bitstream_restriction_flag = ps_vui->u1_bitstream_restriction_flag;
ps_op->u1_mv_over_pic_boundaries_flag = ps_vui->u1_mv_over_pic_boundaries_flag;
ps_op->u4_max_bytes_per_pic_denom = ps_vui->u4_max_bytes_per_pic_denom;
ps_op->u4_max_bits_per_mb_denom = ps_vui->u4_max_bits_per_mb_denom;
ps_op->u4_log2_max_mv_length_horz = ps_vui->u4_log2_max_mv_length_horz;
ps_op->u4_log2_max_mv_length_vert = ps_vui->u4_log2_max_mv_length_vert;
ps_op->u4_num_reorder_frames = ps_vui->u4_num_reorder_frames;
ps_op->u4_max_dec_frame_buffering = ps_vui->u4_max_dec_frame_buffering;
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_get_sei_mdcv_params */
/* */
/* Description : This function populates SEI mdcv message in */
/* output structure */
/* Inputs : iv_obj_t decoder handle */
/* : pv_api_ip pointer to input structure */
/* : pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : returns 0; 1 with error code when MDCV is not present */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* */
/* */
/*****************************************************************************/
WORD32 isvcd_get_sei_mdcv_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
isvcd_ctl_get_sei_mdcv_params_ip_t *ps_ip;
isvcd_ctl_get_sei_mdcv_params_op_t *ps_op;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
sei_mdcv_params_t *ps_sei_mdcv;
WORD32 i4_count;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_ip = (isvcd_ctl_get_sei_mdcv_params_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_sei_mdcv_params_op_t *) pv_api_op;
UNUSED(ps_ip);
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
if(0 == ps_dec->s_sei_export.u1_sei_mdcv_params_present_flag)
{
ps_op->u4_error_code = ERROR_SEI_MDCV_PARAMS_NOT_FOUND;
return IV_FAIL;
}
ps_sei_mdcv = &ps_dec->s_sei_export.s_sei_mdcv_params;
for(i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; i4_count++)
{
ps_op->au2_display_primaries_x[i4_count] = ps_sei_mdcv->au2_display_primaries_x[i4_count];
ps_op->au2_display_primaries_y[i4_count] = ps_sei_mdcv->au2_display_primaries_y[i4_count];
}
ps_op->u2_white_point_x = ps_sei_mdcv->u2_white_point_x;
ps_op->u2_white_point_y = ps_sei_mdcv->u2_white_point_y;
ps_op->u4_max_display_mastering_luminance = ps_sei_mdcv->u4_max_display_mastering_luminance;
ps_op->u4_min_display_mastering_luminance = ps_sei_mdcv->u4_min_display_mastering_luminance;
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_get_sei_cll_params */
/* */
/* Description : This function populates SEI cll message in */
/* output structure */
/* Inputs : iv_obj_t decoder handle */
/* : pv_api_ip pointer to input structure */
/* : pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : returns 0; 1 with error code when CLL is not present */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* */
/* */
/*****************************************************************************/
WORD32 isvcd_get_sei_cll_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
isvcd_ctl_get_sei_cll_params_ip_t *ps_ip;
isvcd_ctl_get_sei_cll_params_op_t *ps_op;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
svc_dec_ctxt_t *ps_svcd_ctxt;
sei_cll_params_t *ps_sei_cll;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_ip = (isvcd_ctl_get_sei_cll_params_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_sei_cll_params_op_t *) pv_api_op;
UNUSED(ps_ip);
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
if(0 == ps_dec->s_sei_export.u1_sei_cll_params_present_flag)
{
ps_op->u4_error_code = ERROR_SEI_CLL_PARAMS_NOT_FOUND;
return IV_FAIL;
}
ps_sei_cll = &ps_dec->s_sei_export.s_sei_cll_params;
ps_op->u2_max_content_light_level = ps_sei_cll->u2_max_content_light_level;
ps_op->u2_max_pic_average_light_level = ps_sei_cll->u2_max_pic_average_light_level;
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_get_sei_ave_params */
/* */
/* Description : This function populates SEI ave message in */
/* output structure */
/* Inputs : iv_obj_t decoder handle */
/* : pv_api_ip pointer to input structure */
/* : pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : returns 0; 1 with error code when AVE is not present */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* */
/* */
/*****************************************************************************/
WORD32 isvcd_get_sei_ave_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
isvcd_ctl_get_sei_ave_params_ip_t *ps_ip;
isvcd_ctl_get_sei_ave_params_op_t *ps_op;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
sei_ave_params_t *ps_sei_ave;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_ip = (isvcd_ctl_get_sei_ave_params_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_sei_ave_params_op_t *) pv_api_op;
UNUSED(ps_ip);
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
if(0 == ps_dec->s_sei_export.u1_sei_ave_params_present_flag)
{
ps_op->u4_error_code = ERROR_SEI_AVE_PARAMS_NOT_FOUND;
return IV_FAIL;
}
ps_sei_ave = &ps_dec->s_sei_export.s_sei_ave_params;
ps_op->u4_ambient_illuminance = ps_sei_ave->u4_ambient_illuminance;
ps_op->u2_ambient_light_x = ps_sei_ave->u2_ambient_light_x;
ps_op->u2_ambient_light_y = ps_sei_ave->u2_ambient_light_y;
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_get_sei_ccv_params */
/* */
/* Description : This function populates SEI mdcv message in */
/* output structure */
/* Inputs : iv_obj_t decoder handle */
/* : pv_api_ip pointer to input structure */
/* : pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : returns 0; 1 with error code when CCV is not present */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* */
/* */
/*****************************************************************************/
WORD32 isvcd_get_sei_ccv_params(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
isvcd_ctl_get_sei_ccv_params_ip_t *ps_ip;
isvcd_ctl_get_sei_ccv_params_op_t *ps_op;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
sei_ccv_params_t *ps_sei_ccv;
svc_dec_ctxt_t *ps_svcd_ctxt;
WORD32 i4_count;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_ip = (isvcd_ctl_get_sei_ccv_params_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_get_sei_ccv_params_op_t *) pv_api_op;
UNUSED(ps_ip);
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[ps_svcd_ctxt->u1_target_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
if(0 == ps_dec->s_sei_export.u1_sei_ccv_params_present_flag)
{
ps_op->u4_error_code = ERROR_SEI_CCV_PARAMS_NOT_FOUND;
return IV_FAIL;
}
ps_sei_ccv = &ps_dec->s_sei_export.s_sei_ccv_params;
ps_op->u1_ccv_cancel_flag = ps_sei_ccv->u1_ccv_cancel_flag;
if(0 == ps_op->u1_ccv_cancel_flag)
{
ps_op->u1_ccv_persistence_flag = ps_sei_ccv->u1_ccv_persistence_flag;
ps_op->u1_ccv_primaries_present_flag = ps_sei_ccv->u1_ccv_primaries_present_flag;
ps_op->u1_ccv_min_luminance_value_present_flag =
ps_sei_ccv->u1_ccv_min_luminance_value_present_flag;
ps_op->u1_ccv_max_luminance_value_present_flag =
ps_sei_ccv->u1_ccv_max_luminance_value_present_flag;
ps_op->u1_ccv_avg_luminance_value_present_flag =
ps_sei_ccv->u1_ccv_avg_luminance_value_present_flag;
ps_op->u1_ccv_reserved_zero_2bits = ps_sei_ccv->u1_ccv_reserved_zero_2bits;
if(1 == ps_sei_ccv->u1_ccv_primaries_present_flag)
{
for(i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; i4_count++)
{
ps_op->ai4_ccv_primaries_x[i4_count] = ps_sei_ccv->ai4_ccv_primaries_x[i4_count];
ps_op->ai4_ccv_primaries_y[i4_count] = ps_sei_ccv->ai4_ccv_primaries_y[i4_count];
}
}
if(1 == ps_sei_ccv->u1_ccv_min_luminance_value_present_flag)
{
ps_op->u4_ccv_min_luminance_value = ps_sei_ccv->u4_ccv_min_luminance_value;
}
if(1 == ps_sei_ccv->u1_ccv_max_luminance_value_present_flag)
{
ps_op->u4_ccv_max_luminance_value = ps_sei_ccv->u4_ccv_max_luminance_value;
}
if(1 == ps_sei_ccv->u1_ccv_avg_luminance_value_present_flag)
{
ps_op->u4_ccv_avg_luminance_value = ps_sei_ccv->u4_ccv_avg_luminance_value;
}
}
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_set_num_cores */
/* */
/* Description : This function sets the no of cores which decoder */
/* can use for decoding */
/* Inputs : iv_obj_t decoder handle */
/* : pv_api_ip pointer to input structure */
/* : pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : returns 0; 1 with error code */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* */
/* */
/*****************************************************************************/
WORD32 isvcd_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
UWORD8 u1_layer_id;
isvcd_ctl_set_num_cores_ip_t *ps_ip;
isvcd_ctl_set_num_cores_op_t *ps_op;
dec_struct_t *ps_dec;
svc_dec_lyr_struct_t *ps_svc_lyr_dec;
svc_dec_ctxt_t *ps_svcd_ctxt;
ps_svcd_ctxt = (svc_dec_ctxt_t *) dec_hdl->pv_codec_handle;
ps_ip = (isvcd_ctl_set_num_cores_ip_t *) pv_api_ip;
ps_op = (isvcd_ctl_set_num_cores_op_t *) pv_api_op;
ps_op->u4_error_code = 0;
for(u1_layer_id = 0; u1_layer_id < MAX_NUM_RES_LYRS; u1_layer_id++)
{
ps_svc_lyr_dec = &ps_svcd_ctxt->ps_svc_dec_lyr[u1_layer_id];
ps_dec = &ps_svc_lyr_dec->s_dec;
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;
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_fill_output_struct_from_context */
/* */
/* Description : This function fills the output structure from the */
/* svc layer context */
/* Inputs : iv_obj_t decoder handle */
/* : ps_svc_lyr_dec pointer to svc layer context */
/* : ps_dec_op pointer to output structure */
/* Outputs : */
/* Returns : */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* */
/* */
/*****************************************************************************/
void isvcd_fill_output_struct_from_context(svc_dec_lyr_struct_t *ps_svc_lyr_dec,
ivd_video_decode_op_t *ps_dec_op)
{
dec_struct_t *ps_dec;
ps_dec = &ps_svc_lyr_dec->s_dec;
if((ps_dec_op->u4_error_code & 0xff) != ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED)
{
ps_dec_op->u4_pic_wd = (UWORD32) ps_dec->u2_disp_width;
ps_dec_op->u4_pic_ht = (UWORD32) ps_dec->u2_disp_height;
}
ps_dec_op->i4_reorder_depth = ps_dec->i4_reorder_depth;
ps_dec_op->i4_display_index = ps_dec->i4_display_index;
ps_dec_op->e_pic_type = ps_dec->i4_frametype;
ps_dec_op->u4_new_seq = 0;
ps_dec_op->u4_output_present =
(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER) ? ps_dec->u4_output_present : 0;
ps_dec_op->u4_progressive_frame_flag = ps_dec->s_disp_op.u4_progressive_frame_flag;
ps_dec_op->u4_is_ref_flag = 1;
if(ps_dec_op->u4_frame_decoded_flag)
{
if(ps_dec->ps_cur_slice->u1_nal_ref_idc == 0) ps_dec_op->u4_is_ref_flag = 0;
}
ps_dec_op->e_output_format = ps_dec->s_disp_op.e_output_format;
ps_dec_op->s_disp_frm_buf = ps_dec->s_disp_op.s_disp_frm_buf;
ps_dec_op->e4_fld_type = ps_dec->s_disp_op.e4_fld_type;
ps_dec_op->u4_ts = ps_dec->s_disp_op.u4_ts;
ps_dec_op->u4_disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id;
ih264d_export_sei_params(&ps_dec_op->s_sei_decode_op, ps_dec);
}
/*****************************************************************************/
/* */
/* Function Name : isvcd_api_function */
/* */
/* Description : */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 06 09 2021 Kishore Draft */
/* */
/*****************************************************************************/
IV_API_CALL_STATUS_T isvcd_api_function(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
UWORD32 command;
UWORD32 *pu2_ptr_cmd;
UWORD32 u4_api_ret;
IV_API_CALL_STATUS_T e_status;
e_status = api_check_struct_sanity(dec_hdl, pv_api_ip, pv_api_op);
if(e_status != IV_SUCCESS)
{
UWORD32 *ptr_err;
ptr_err = (UWORD32 *) pv_api_op;
UNUSED(ptr_err);
H264_DEC_DEBUG_PRINT("error code = %d\n", *(ptr_err + 1));
return IV_FAIL;
}
pu2_ptr_cmd = (UWORD32 *) pv_api_ip;
pu2_ptr_cmd++;
command = *pu2_ptr_cmd;
switch(command)
{
case IVD_CMD_CREATE:
u4_api_ret = isvcd_create(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IVD_CMD_DELETE:
u4_api_ret = isvcd_delete(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IVD_CMD_VIDEO_DECODE:
u4_api_ret = isvcd_video_decode(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IVD_CMD_GET_DISPLAY_FRAME:
u4_api_ret = ih264d_get_display_frame(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IVD_CMD_SET_DISPLAY_FRAME:
u4_api_ret = isvcd_set_display_frame(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IVD_CMD_REL_DISPLAY_FRAME:
u4_api_ret = isvcd_rel_display_frame(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
case IVD_CMD_VIDEO_CTL:
u4_api_ret = isvcd_ctl(dec_hdl, (void *) pv_api_ip, (void *) pv_api_op);
break;
default:
u4_api_ret = IV_FAIL;
break;
}
return u4_api_ret;
}