7292 lines
318 KiB
C
7292 lines
318 KiB
C
/******************************************************************************
|
|
*
|
|
* 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;
|
|
}
|