blob: 18e4c2e92e107641f812d62d483ad08043811829 [file] [log] [blame]
/******************************************************************************
*
* Copyright (C) 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
/*****************************************************************************/
/* */
/* File Name : ih264d_api.c */
/* */
/* Description : Has all API related functions */
/* */
/* */
/* List of Functions : api_check_struct_sanity */
/* ih264d_set_processor */
/* ih264d_get_num_rec */
/* ih264d_init_decoder */
/* ih264d_init_video_decoder */
/* ih264d_fill_num_mem_rec */
/* ih264d_clr */
/* ih264d_init */
/* ih264d_map_error */
/* ih264d_video_decode */
/* ih264d_get_version */
/* ih264d_get_display_frame */
/* ih264d_set_display_frame */
/* ih264d_set_flush_mode */
/* ih264d_get_status */
/* ih264d_get_buf_info */
/* ih264d_set_params */
/* ih264d_set_default_params */
/* ih264d_reset */
/* ih264d_ctl */
/* ih264d_rel_display_frame */
/* ih264d_set_degrade */
/* ih264d_get_frame_dimensions */
/* ih264d_set_num_cores */
/* ih264d_fill_output_struct_from_context */
/* ih264d_api_function */
/* */
/* Issues / Problems : None */
/* */
/* Revision History : */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 14 10 2008 100356(SKV) Draft */
/* */
/*****************************************************************************/
#include "ih264_typedefs.h"
#include "ih264_macros.h"
#include "ih264_platform_macros.h"
#include "ih264d_tables.h"
#include "iv.h"
#include "ivd.h"
#include "ih264d.h"
#include "ih264d_defs.h"
#include <string.h>
#include <limits.h>
#include <stddef.h>
#include "ih264d_inter_pred.h"
#include "ih264d_structs.h"
#include "ih264d_nal.h"
#include "ih264d_error_handler.h"
#include "ih264d_defs.h"
#include "ithread.h"
#include "ih264d_parse_slice.h"
#include "ih264d_function_selector.h"
#include "ih264_error.h"
#include "ih264_disp_mgr.h"
#include "ih264_buf_mgr.h"
#include "ih264d_deblocking.h"
#include "ih264d_parse_cavlc.h"
#include "ih264d_parse_cabac.h"
#include "ih264d_utils.h"
#include "ih264d_format_conv.h"
#include "ih264d_parse_headers.h"
#include "ih264d_thread_compute_bs.h"
#include <assert.h>
/*********************/
/* Codec Versioning */
/*********************/
//Move this to where it is used
#define CODEC_NAME "H264VDEC"
#define CODEC_RELEASE_TYPE "production"
#define CODEC_RELEASE_VER "04.00"
#define CODEC_VENDOR "ITTIAM"
#define MAXVERSION_STRLEN 511
#define VERSION(version_string, codec_name, codec_release_type, codec_release_ver, codec_vendor) \
strncpy(version_string,"@(#)Id:", MAXVERSION_STRLEN); \
strncat(version_string,codec_name, MAXVERSION_STRLEN); \
strncat(version_string,"_", MAXVERSION_STRLEN); \
strncat(version_string,codec_release_type, MAXVERSION_STRLEN); \
strncat(version_string," Ver:", MAXVERSION_STRLEN); \
strncat(version_string,codec_release_ver, MAXVERSION_STRLEN); \
strncat(version_string," Released by ", MAXVERSION_STRLEN); \
strncat(version_string,codec_vendor, MAXVERSION_STRLEN); \
strncat(version_string," Build: ", MAXVERSION_STRLEN); \
strncat(version_string,__DATE__, MAXVERSION_STRLEN); \
strncat(version_string," @ ", MAXVERSION_STRLEN); \
strncat(version_string,__TIME__, MAXVERSION_STRLEN);
#define MAX_NAL_UNIT_SIZE MAX((H264_MAX_FRAME_HEIGHT * H264_MAX_FRAME_HEIGHT),MIN_NALUNIT_SIZE)
#define MIN_NALUNIT_SIZE 200000
#define MIN_IN_BUFS 1
#define MIN_OUT_BUFS_420 3
#define MIN_OUT_BUFS_422ILE 1
#define MIN_OUT_BUFS_RGB565 1
#define MIN_OUT_BUFS_420SP 2
#define MIN_IN_BUF_SIZE (2*1024*1024) // Currently, i4_size set to 500kb, CHECK LATER
#define NUM_FRAMES_LIMIT_ENABLED 0
#if NUM_FRAMES_LIMIT_ENABLED
#define NUM_FRAMES_LIMIT 10000
#else
#define NUM_FRAMES_LIMIT 0x7FFFFFFF
#endif
UWORD32 ih264d_get_extra_mem_external(UWORD32 width, UWORD32 height);
WORD32 ih264d_get_frame_dimensions(iv_obj_t *dec_hdl,
void *pv_api_ip,
void *pv_api_op);
WORD32 ih264d_set_num_cores(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op);
WORD32 ih264d_deblock_display(dec_struct_t *ps_dec);
void ih264d_signal_decode_thread(dec_struct_t *ps_dec);
void ih264d_signal_bs_deblk_thread(dec_struct_t *ps_dec);
void ih264d_decode_picture_thread(dec_struct_t *ps_dec);
WORD32 ih264d_set_degrade(iv_obj_t *ps_codec_obj,
void *pv_api_ip,
void *pv_api_op);
void ih264d_fill_output_struct_from_context(dec_struct_t *ps_dec,
ivd_video_decode_op_t *ps_dec_op);
static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
void *pv_api_ip,
void *pv_api_op)
{
IVD_API_COMMAND_TYPE_T e_cmd;
UWORD32 *pu4_api_ip;
UWORD32 *pu4_api_op;
UWORD32 i, j;
if(NULL == pv_api_op)
return (IV_FAIL);
if(NULL == pv_api_ip)
return (IV_FAIL);
pu4_api_ip = (UWORD32 *)pv_api_ip;
pu4_api_op = (UWORD32 *)pv_api_op;
e_cmd = *(pu4_api_ip + 1);
/* error checks on handle */
switch((WORD32)e_cmd)
{
case IV_CMD_GET_NUM_MEM_REC:
case IV_CMD_FILL_NUM_MEM_REC:
break;
case IV_CMD_INIT:
if(ps_handle == NULL)
{
*(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
*(pu4_api_op + 1) |= IVD_HANDLE_NULL;
return IV_FAIL;
}
if(ps_handle->u4_size != sizeof(iv_obj_t))
{
*(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
*(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT;
H264_DEC_DEBUG_PRINT(
"Sizes do not match. Expected: %d, Got: %d",
sizeof(iv_obj_t), ps_handle->u4_size);
return IV_FAIL;
}
break;
case IVD_CMD_REL_DISPLAY_FRAME:
case IVD_CMD_SET_DISPLAY_FRAME:
case IVD_CMD_GET_DISPLAY_FRAME:
case IVD_CMD_VIDEO_DECODE:
case IV_CMD_RETRIEVE_MEMREC:
case IVD_CMD_VIDEO_CTL:
if(ps_handle == NULL)
{
*(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
*(pu4_api_op + 1) |= IVD_HANDLE_NULL;
return IV_FAIL;
}
if(ps_handle->u4_size != sizeof(iv_obj_t))
{
*(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
*(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_handle->pv_fxns != ih264d_api_function)
{
*(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
*(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
return IV_FAIL;
}
if(ps_handle->pv_codec_handle == NULL)
{
*(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
*(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
return IV_FAIL;
}
break;
default:
*(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
*(pu4_api_op + 1) |= IVD_INVALID_API_CMD;
return IV_FAIL;
}
switch((WORD32)e_cmd)
{
case IV_CMD_GET_NUM_MEM_REC:
{
ih264d_num_mem_rec_ip_t *ps_ip =
(ih264d_num_mem_rec_ip_t *)pv_api_ip;
ih264d_num_mem_rec_op_t *ps_op =
(ih264d_num_mem_rec_op_t *)pv_api_op;
ps_op->s_ivd_num_mem_rec_op_t.u4_error_code = 0;
if(ps_ip->s_ivd_num_mem_rec_ip_t.u4_size
!= sizeof(ih264d_num_mem_rec_ip_t))
{
ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
if(ps_op->s_ivd_num_mem_rec_op_t.u4_size
!= sizeof(ih264d_num_mem_rec_op_t))
{
ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
}
break;
case IV_CMD_FILL_NUM_MEM_REC:
{
ih264d_fill_mem_rec_ip_t *ps_ip =
(ih264d_fill_mem_rec_ip_t *)pv_api_ip;
ih264d_fill_mem_rec_op_t *ps_op =
(ih264d_fill_mem_rec_op_t *)pv_api_op;
iv_mem_rec_t *ps_mem_rec;
WORD32 max_wd = ps_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd;
WORD32 max_ht = ps_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht;
max_wd = ALIGN16(max_wd);
max_ht = ALIGN32(max_ht);
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code = 0;
if((ps_ip->s_ivd_fill_mem_rec_ip_t.u4_size
> sizeof(ih264d_fill_mem_rec_ip_t))
|| (ps_ip->s_ivd_fill_mem_rec_ip_t.u4_size
< sizeof(iv_fill_mem_rec_ip_t)))
{
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
if((ps_op->s_ivd_fill_mem_rec_op_t.u4_size
!= sizeof(ih264d_fill_mem_rec_op_t))
&& (ps_op->s_ivd_fill_mem_rec_op_t.u4_size
!= sizeof(iv_fill_mem_rec_op_t)))
{
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
if(max_wd < H264_MIN_FRAME_WIDTH)
{
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
IVD_REQUESTED_WIDTH_NOT_SUPPPORTED;
return (IV_FAIL);
}
if(max_wd > H264_MAX_FRAME_WIDTH)
{
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
IVD_REQUESTED_WIDTH_NOT_SUPPPORTED;
return (IV_FAIL);
}
if(max_ht < H264_MIN_FRAME_HEIGHT)
{
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
IVD_REQUESTED_HEIGHT_NOT_SUPPPORTED;
return (IV_FAIL);
}
if((max_ht * max_wd)
> (H264_MAX_FRAME_HEIGHT * H264_MAX_FRAME_WIDTH))
{
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
IVD_REQUESTED_HEIGHT_NOT_SUPPPORTED;
return (IV_FAIL);
}
if(NULL == ps_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location)
{
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
IVD_NUM_REC_NOT_SUFFICIENT;
return (IV_FAIL);
}
/* check memrecords sizes are correct */
ps_mem_rec = ps_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location;
for(i = 0; i < MEM_REC_CNT; i++)
{
if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
{
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
IVD_MEM_REC_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
}
}
break;
case IV_CMD_INIT:
{
ih264d_init_ip_t *ps_ip = (ih264d_init_ip_t *)pv_api_ip;
ih264d_init_op_t *ps_op = (ih264d_init_op_t *)pv_api_op;
iv_mem_rec_t *ps_mem_rec;
WORD32 max_wd = ps_ip->s_ivd_init_ip_t.u4_frm_max_wd;
WORD32 max_ht = ps_ip->s_ivd_init_ip_t.u4_frm_max_ht;
max_wd = ALIGN16(max_wd);
max_ht = ALIGN32(max_ht);
ps_op->s_ivd_init_op_t.u4_error_code = 0;
if((ps_ip->s_ivd_init_ip_t.u4_size > sizeof(ih264d_init_ip_t))
|| (ps_ip->s_ivd_init_ip_t.u4_size
< sizeof(ivd_init_ip_t)))
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
H264_DEC_DEBUG_PRINT("\n");
return (IV_FAIL);
}
if((ps_op->s_ivd_init_op_t.u4_size != sizeof(ih264d_init_op_t))
&& (ps_op->s_ivd_init_op_t.u4_size
!= sizeof(ivd_init_op_t)))
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
H264_DEC_DEBUG_PRINT("\n");
return (IV_FAIL);
}
if(ps_ip->s_ivd_init_ip_t.u4_num_mem_rec != MEM_REC_CNT)
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_NOT_SUFFICIENT;
H264_DEC_DEBUG_PRINT("\n");
return (IV_FAIL);
}
if(max_wd < H264_MIN_FRAME_WIDTH)
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_WIDTH_NOT_SUPPPORTED;
H264_DEC_DEBUG_PRINT("\n");
return (IV_FAIL);
}
if(max_wd > H264_MAX_FRAME_WIDTH)
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_WIDTH_NOT_SUPPPORTED;
H264_DEC_DEBUG_PRINT("\n");
return (IV_FAIL);
}
if(max_ht < H264_MIN_FRAME_HEIGHT)
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED;
H264_DEC_DEBUG_PRINT("\n");
return (IV_FAIL);
}
if((max_ht * max_wd)
> (H264_MAX_FRAME_HEIGHT * H264_MAX_FRAME_WIDTH))
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED;
H264_DEC_DEBUG_PRINT("\n");
return (IV_FAIL);
}
if(NULL == ps_ip->s_ivd_init_ip_t.pv_mem_rec_location)
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_NUM_REC_NOT_SUFFICIENT;
H264_DEC_DEBUG_PRINT("\n");
return (IV_FAIL);
}
if((ps_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P)
&& (ps_ip->s_ivd_init_ip_t.e_output_format
!= IV_YUV_422ILE)
&& (ps_ip->s_ivd_init_ip_t.e_output_format
!= IV_RGB_565)
&& (ps_ip->s_ivd_init_ip_t.e_output_format
!= IV_YUV_420SP_UV)
&& (ps_ip->s_ivd_init_ip_t.e_output_format
!= IV_YUV_420SP_VU))
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED;
H264_DEC_DEBUG_PRINT("\n");
return (IV_FAIL);
}
/* verify number of mem records */
if(ps_ip->s_ivd_init_ip_t.u4_num_mem_rec < MEM_REC_CNT)
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_MEM_REC_NOT_SUFFICIENT;
H264_DEC_DEBUG_PRINT("\n");
return IV_FAIL;
}
ps_mem_rec = ps_ip->s_ivd_init_ip_t.pv_mem_rec_location;
/* check memrecords sizes are correct */
for(i = 0; i < ps_ip->s_ivd_init_ip_t.u4_num_mem_rec; i++)
{
if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_MEM_REC_STRUCT_SIZE_INCORRECT;
H264_DEC_DEBUG_PRINT("i: %d\n", i);
return IV_FAIL;
}
/* check memrecords pointers are not NULL */
if(ps_mem_rec[i].pv_base == NULL)
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_MEM_REC_BASE_NULL;
H264_DEC_DEBUG_PRINT("i: %d\n", i);
return IV_FAIL;
}
}
/* verify memtabs for overlapping regions */
{
void *start[MEM_REC_CNT];
void *end[MEM_REC_CNT];
start[0] = (void *)(ps_mem_rec[0].pv_base);
end[0] = (void *)((UWORD8 *)ps_mem_rec[0].pv_base
+ ps_mem_rec[0].u4_mem_size - 1);
for(i = 1; i < MEM_REC_CNT; i++)
{
/* This array is populated to check memtab overlapp */
start[i] = (void *)(ps_mem_rec[i].pv_base);
end[i] = (void *)((UWORD8 *)ps_mem_rec[i].pv_base
+ ps_mem_rec[i].u4_mem_size - 1);
for(j = 0; j < i; j++)
{
if((start[i] >= start[j]) && (start[i] <= end[j]))
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_MEM_REC_OVERLAP_ERR;
H264_DEC_DEBUG_PRINT("i: %d, j: %d\n", i, j);
return IV_FAIL;
}
if((end[i] >= start[j]) && (end[i] <= end[j]))
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_MEM_REC_OVERLAP_ERR;
H264_DEC_DEBUG_PRINT("i: %d, j: %d\n", i, j);
return IV_FAIL;
}
if((start[i] < start[j]) && (end[i] > end[j]))
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_MEM_REC_OVERLAP_ERR;
H264_DEC_DEBUG_PRINT("i: %d, j: %d\n", i, j);
return IV_FAIL;
}
}
}
}
{
iv_mem_rec_t mem_rec_ittiam_api[MEM_REC_CNT];
ih264d_fill_mem_rec_ip_t s_fill_mem_rec_ip;
ih264d_fill_mem_rec_op_t s_fill_mem_rec_op;
IV_API_CALL_STATUS_T e_status;
UWORD32 i;
s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.e_cmd =
IV_CMD_FILL_NUM_MEM_REC;
s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location =
mem_rec_ittiam_api;
s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd =
max_wd;
s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht =
max_ht;
if(ps_ip->s_ivd_init_ip_t.u4_size
> offsetof(ih264d_init_ip_t, i4_level))
{
s_fill_mem_rec_ip.i4_level = ps_ip->i4_level;
}
else
{
s_fill_mem_rec_ip.i4_level = H264_LEVEL_3_1;
}
if(ps_ip->s_ivd_init_ip_t.u4_size
> offsetof(ih264d_init_ip_t, u4_num_ref_frames))
{
s_fill_mem_rec_ip.u4_num_ref_frames =
ps_ip->u4_num_ref_frames;
}
else
{
s_fill_mem_rec_ip.u4_num_ref_frames =
(H264_MAX_REF_PICS + 1);
}
if(ps_ip->s_ivd_init_ip_t.u4_size
> offsetof(ih264d_init_ip_t,
u4_num_reorder_frames))
{
s_fill_mem_rec_ip.u4_num_reorder_frames =
ps_ip->u4_num_reorder_frames;
}
else
{
s_fill_mem_rec_ip.u4_num_reorder_frames = (H264_MAX_REF_PICS
+ 1);
}
if(ps_ip->s_ivd_init_ip_t.u4_size
> offsetof(ih264d_init_ip_t,
u4_num_extra_disp_buf))
{
s_fill_mem_rec_ip.u4_num_extra_disp_buf =
ps_ip->u4_num_extra_disp_buf;
}
else
{
s_fill_mem_rec_ip.u4_num_extra_disp_buf = 0;
}
if(ps_ip->s_ivd_init_ip_t.u4_size
> offsetof(ih264d_init_ip_t, u4_share_disp_buf))
{
#ifndef LOGO_EN
s_fill_mem_rec_ip.u4_share_disp_buf =
ps_ip->u4_share_disp_buf;
#else
s_fill_mem_rec_ip.u4_share_disp_buf = 0;
#endif
}
else
{
s_fill_mem_rec_ip.u4_share_disp_buf = 0;
}
s_fill_mem_rec_ip.e_output_format =
ps_ip->s_ivd_init_ip_t.e_output_format;
if((s_fill_mem_rec_ip.e_output_format != IV_YUV_420P)
&& (s_fill_mem_rec_ip.e_output_format
!= IV_YUV_420SP_UV)
&& (s_fill_mem_rec_ip.e_output_format
!= IV_YUV_420SP_VU))
{
s_fill_mem_rec_ip.u4_share_disp_buf = 0;
}
s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_size =
sizeof(ih264d_fill_mem_rec_ip_t);
s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size =
sizeof(ih264d_fill_mem_rec_op_t);
for(i = 0; i < MEM_REC_CNT; i++)
mem_rec_ittiam_api[i].u4_size = sizeof(iv_mem_rec_t);
e_status = ih264d_api_function(NULL,
(void *)&s_fill_mem_rec_ip,
(void *)&s_fill_mem_rec_op);
if(IV_FAIL == e_status)
{
ps_op->s_ivd_init_op_t.u4_error_code =
s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_error_code;
H264_DEC_DEBUG_PRINT("Fail\n");
return (IV_FAIL);
}
for(i = 0; i < MEM_REC_CNT; i++)
{
if(ps_mem_rec[i].u4_mem_size
< mem_rec_ittiam_api[i].u4_mem_size)
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_MEM_REC_INSUFFICIENT_SIZE;
H264_DEC_DEBUG_PRINT("i: %d \n", i);
return IV_FAIL;
}
if(ps_mem_rec[i].u4_mem_alignment
!= mem_rec_ittiam_api[i].u4_mem_alignment)
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_MEM_REC_ALIGNMENT_ERR;
H264_DEC_DEBUG_PRINT("i: %d \n", i);
return IV_FAIL;
}
if(ps_mem_rec[i].e_mem_type
!= mem_rec_ittiam_api[i].e_mem_type)
{
UWORD32 check = IV_SUCCESS;
UWORD32 diff = mem_rec_ittiam_api[i].e_mem_type
- ps_mem_rec[i].e_mem_type;
if((ps_mem_rec[i].e_mem_type
<= IV_EXTERNAL_CACHEABLE_SCRATCH_MEM)
&& (mem_rec_ittiam_api[i].e_mem_type
>= IV_INTERNAL_NONCACHEABLE_PERSISTENT_MEM))
{
check = IV_FAIL;
}
if(3 != MOD(mem_rec_ittiam_api[i].e_mem_type, 4))
{
/*
* It is not IV_EXTERNAL_NONCACHEABLE_PERSISTENT_MEM or IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM
*/
if((diff < 1) || (diff > 3))
{
// Difference between 1 and 3 is okay for all cases other than the two filtered
// with the MOD condition above
check = IV_FAIL;
}
}
else
{
if(diff == 1)
{
/*
* This particular case is when codec asked for External Persistent, but got
* Internal Scratch.
*/
check = IV_FAIL;
}
if((diff != 2) && (diff != 3))
{
check = IV_FAIL;
}
}
if(check == IV_FAIL)
{
ps_op->s_ivd_init_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_init_op_t.u4_error_code |=
IVD_INIT_DEC_MEM_REC_INCORRECT_TYPE;
H264_DEC_DEBUG_PRINT("i: %d \n", i);
return IV_FAIL;
}
}
}
}
}
break;
case IVD_CMD_GET_DISPLAY_FRAME:
{
ih264d_get_display_frame_ip_t *ps_ip =
(ih264d_get_display_frame_ip_t *)pv_api_ip;
ih264d_get_display_frame_op_t *ps_op =
(ih264d_get_display_frame_op_t *)pv_api_op;
ps_op->s_ivd_get_display_frame_op_t.u4_error_code = 0;
if((ps_ip->s_ivd_get_display_frame_ip_t.u4_size
!= sizeof(ih264d_get_display_frame_ip_t))
&& (ps_ip->s_ivd_get_display_frame_ip_t.u4_size
!= sizeof(ivd_get_display_frame_ip_t)))
{
ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
if((ps_op->s_ivd_get_display_frame_op_t.u4_size
!= sizeof(ih264d_get_display_frame_op_t))
&& (ps_op->s_ivd_get_display_frame_op_t.u4_size
!= sizeof(ivd_get_display_frame_op_t)))
{
ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
}
break;
case IVD_CMD_REL_DISPLAY_FRAME:
{
ih264d_rel_display_frame_ip_t *ps_ip =
(ih264d_rel_display_frame_ip_t *)pv_api_ip;
ih264d_rel_display_frame_op_t *ps_op =
(ih264d_rel_display_frame_op_t *)pv_api_op;
ps_op->s_ivd_rel_display_frame_op_t.u4_error_code = 0;
if((ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
!= sizeof(ih264d_rel_display_frame_ip_t))
&& (ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
!= sizeof(ivd_rel_display_frame_ip_t)))
{
ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
if((ps_op->s_ivd_rel_display_frame_op_t.u4_size
!= sizeof(ih264d_rel_display_frame_op_t))
&& (ps_op->s_ivd_rel_display_frame_op_t.u4_size
!= sizeof(ivd_rel_display_frame_op_t)))
{
ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
}
break;
case IVD_CMD_SET_DISPLAY_FRAME:
{
ih264d_set_display_frame_ip_t *ps_ip =
(ih264d_set_display_frame_ip_t *)pv_api_ip;
ih264d_set_display_frame_op_t *ps_op =
(ih264d_set_display_frame_op_t *)pv_api_op;
UWORD32 j;
ps_op->s_ivd_set_display_frame_op_t.u4_error_code = 0;
if((ps_ip->s_ivd_set_display_frame_ip_t.u4_size
!= sizeof(ih264d_set_display_frame_ip_t))
&& (ps_ip->s_ivd_set_display_frame_ip_t.u4_size
!= sizeof(ivd_set_display_frame_ip_t)))
{
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
if((ps_op->s_ivd_set_display_frame_op_t.u4_size
!= sizeof(ih264d_set_display_frame_op_t))
&& (ps_op->s_ivd_set_display_frame_op_t.u4_size
!= sizeof(ivd_set_display_frame_op_t)))
{
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
if(ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs == 0)
{
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
IVD_DISP_FRM_ZERO_OP_BUFS;
return IV_FAIL;
}
for(j = 0; j < ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs;
j++)
{
if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs
== 0)
{
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
IVD_DISP_FRM_ZERO_OP_BUFS;
return IV_FAIL;
}
for(i = 0;
i
< ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs;
i++)
{
if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].pu1_bufs[i]
== NULL)
{
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
IVD_DISP_FRM_OP_BUF_NULL;
return IV_FAIL;
}
if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_min_out_buf_size[i]
== 0)
{
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
return IV_FAIL;
}
}
}
}
break;
case IVD_CMD_VIDEO_DECODE:
{
ih264d_video_decode_ip_t *ps_ip =
(ih264d_video_decode_ip_t *)pv_api_ip;
ih264d_video_decode_op_t *ps_op =
(ih264d_video_decode_op_t *)pv_api_op;
H264_DEC_DEBUG_PRINT("The input bytes is: %d",
ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes);
ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
if(ps_ip->s_ivd_video_decode_ip_t.u4_size
!= sizeof(ih264d_video_decode_ip_t)&&
ps_ip->s_ivd_video_decode_ip_t.u4_size != offsetof(ivd_video_decode_ip_t, s_out_buffer))
{
ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_video_decode_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
if(ps_op->s_ivd_video_decode_op_t.u4_size
!= sizeof(ih264d_video_decode_op_t)&&
ps_op->s_ivd_video_decode_op_t.u4_size != offsetof(ivd_video_decode_op_t, u4_output_present))
{
ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_video_decode_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
}
break;
case IV_CMD_RETRIEVE_MEMREC:
{
ih264d_retrieve_mem_rec_ip_t *ps_ip =
(ih264d_retrieve_mem_rec_ip_t *)pv_api_ip;
ih264d_retrieve_mem_rec_op_t *ps_op =
(ih264d_retrieve_mem_rec_op_t *)pv_api_op;
iv_mem_rec_t *ps_mem_rec;
ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code = 0;
if(ps_ip->s_ivd_retrieve_mem_rec_ip_t.u4_size
!= sizeof(ih264d_retrieve_mem_rec_ip_t))
{
ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
if(ps_op->s_ivd_retrieve_mem_rec_op_t.u4_size
!= sizeof(ih264d_retrieve_mem_rec_op_t))
{
ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return (IV_FAIL);
}
ps_mem_rec = ps_ip->s_ivd_retrieve_mem_rec_ip_t.pv_mem_rec_location;
/* check memrecords sizes are correct */
for(i = 0; i < MEM_REC_CNT; i++)
{
if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
{
ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |=
IVD_MEM_REC_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
}
}
break;
case IVD_CMD_VIDEO_CTL:
{
UWORD32 *pu4_ptr_cmd;
UWORD32 sub_command;
pu4_ptr_cmd = (UWORD32 *)pv_api_ip;
pu4_ptr_cmd += 2;
sub_command = *pu4_ptr_cmd;
switch(sub_command)
{
case IVD_CMD_CTL_SETPARAMS:
{
ih264d_ctl_set_config_ip_t *ps_ip;
ih264d_ctl_set_config_op_t *ps_op;
ps_ip = (ih264d_ctl_set_config_ip_t *)pv_api_ip;
ps_op = (ih264d_ctl_set_config_op_t *)pv_api_op;
if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size
!= sizeof(ih264d_ctl_set_config_ip_t))
{
ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
}
//no break; is needed here
case IVD_CMD_CTL_SETDEFAULT:
{
ih264d_ctl_set_config_op_t *ps_op;
ps_op = (ih264d_ctl_set_config_op_t *)pv_api_op;
if(ps_op->s_ivd_ctl_set_config_op_t.u4_size
!= sizeof(ih264d_ctl_set_config_op_t))
{
ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
}
break;
case IVD_CMD_CTL_GETPARAMS:
{
ih264d_ctl_getstatus_ip_t *ps_ip;
ih264d_ctl_getstatus_op_t *ps_op;
ps_ip = (ih264d_ctl_getstatus_ip_t *)pv_api_ip;
ps_op = (ih264d_ctl_getstatus_op_t *)pv_api_op;
if(ps_ip->s_ivd_ctl_getstatus_ip_t.u4_size
!= sizeof(ih264d_ctl_getstatus_ip_t))
{
ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->s_ivd_ctl_getstatus_op_t.u4_size
!= sizeof(ih264d_ctl_getstatus_op_t))
{
ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
}
break;
case IVD_CMD_CTL_GETBUFINFO:
{
ih264d_ctl_getbufinfo_ip_t *ps_ip;
ih264d_ctl_getbufinfo_op_t *ps_op;
ps_ip = (ih264d_ctl_getbufinfo_ip_t *)pv_api_ip;
ps_op = (ih264d_ctl_getbufinfo_op_t *)pv_api_op;
if(ps_ip->s_ivd_ctl_getbufinfo_ip_t.u4_size
!= sizeof(ih264d_ctl_getbufinfo_ip_t))
{
ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->s_ivd_ctl_getbufinfo_op_t.u4_size
!= sizeof(ih264d_ctl_getbufinfo_op_t))
{
ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
}
break;
case IVD_CMD_CTL_GETVERSION:
{
ih264d_ctl_getversioninfo_ip_t *ps_ip;
ih264d_ctl_getversioninfo_op_t *ps_op;
ps_ip = (ih264d_ctl_getversioninfo_ip_t *)pv_api_ip;
ps_op = (ih264d_ctl_getversioninfo_op_t *)pv_api_op;
if(ps_ip->s_ivd_ctl_getversioninfo_ip_t.u4_size
!= sizeof(ih264d_ctl_getversioninfo_ip_t))
{
ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->s_ivd_ctl_getversioninfo_op_t.u4_size
!= sizeof(ih264d_ctl_getversioninfo_op_t))
{
ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
}
break;
case IVD_CMD_CTL_FLUSH:
{
ih264d_ctl_flush_ip_t *ps_ip;
ih264d_ctl_flush_op_t *ps_op;
ps_ip = (ih264d_ctl_flush_ip_t *)pv_api_ip;
ps_op = (ih264d_ctl_flush_op_t *)pv_api_op;
if(ps_ip->s_ivd_ctl_flush_ip_t.u4_size
!= sizeof(ih264d_ctl_flush_ip_t))
{
ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->s_ivd_ctl_flush_op_t.u4_size
!= sizeof(ih264d_ctl_flush_op_t))
{
ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
}
break;
case IVD_CMD_CTL_RESET:
{
ih264d_ctl_reset_ip_t *ps_ip;
ih264d_ctl_reset_op_t *ps_op;
ps_ip = (ih264d_ctl_reset_ip_t *)pv_api_ip;
ps_op = (ih264d_ctl_reset_op_t *)pv_api_op;
if(ps_ip->s_ivd_ctl_reset_ip_t.u4_size
!= sizeof(ih264d_ctl_reset_ip_t))
{
ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->s_ivd_ctl_reset_op_t.u4_size
!= sizeof(ih264d_ctl_reset_op_t))
{
ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
}
break;
case IH264D_CMD_CTL_DEGRADE:
{
ih264d_ctl_degrade_ip_t *ps_ip;
ih264d_ctl_degrade_op_t *ps_op;
ps_ip = (ih264d_ctl_degrade_ip_t *)pv_api_ip;
ps_op = (ih264d_ctl_degrade_op_t *)pv_api_op;
if(ps_ip->u4_size != sizeof(ih264d_ctl_degrade_ip_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->u4_size != sizeof(ih264d_ctl_degrade_op_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if((ps_ip->i4_degrade_pics < 0)
|| (ps_ip->i4_degrade_pics > 4)
|| (ps_ip->i4_nondegrade_interval < 0)
|| (ps_ip->i4_degrade_type < 0)
|| (ps_ip->i4_degrade_type > 15))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
return IV_FAIL;
}
break;
}
case IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS:
{
ih264d_ctl_get_frame_dimensions_ip_t *ps_ip;
ih264d_ctl_get_frame_dimensions_op_t *ps_op;
ps_ip = (ih264d_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
ps_op = (ih264d_ctl_get_frame_dimensions_op_t *)pv_api_op;
if(ps_ip->u4_size
!= sizeof(ih264d_ctl_get_frame_dimensions_ip_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->u4_size
!= sizeof(ih264d_ctl_get_frame_dimensions_op_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
break;
}
case IH264D_CMD_CTL_SET_NUM_CORES:
{
ih264d_ctl_set_num_cores_ip_t *ps_ip;
ih264d_ctl_set_num_cores_op_t *ps_op;
ps_ip = (ih264d_ctl_set_num_cores_ip_t *)pv_api_ip;
ps_op = (ih264d_ctl_set_num_cores_op_t *)pv_api_op;
if(ps_ip->u4_size != sizeof(ih264d_ctl_set_num_cores_ip_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->u4_size != sizeof(ih264d_ctl_set_num_cores_op_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if((ps_ip->u4_num_cores != 1) && (ps_ip->u4_num_cores != 2)
&& (ps_ip->u4_num_cores != 3)
&& (ps_ip->u4_num_cores != 4))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
return IV_FAIL;
}
break;
}
case IH264D_CMD_CTL_SET_PROCESSOR:
{
ih264d_ctl_set_processor_ip_t *ps_ip;
ih264d_ctl_set_processor_op_t *ps_op;
ps_ip = (ih264d_ctl_set_processor_ip_t *)pv_api_ip;
ps_op = (ih264d_ctl_set_processor_op_t *)pv_api_op;
if(ps_ip->u4_size != sizeof(ih264d_ctl_set_processor_ip_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
if(ps_op->u4_size != sizeof(ih264d_ctl_set_processor_op_t))
{
ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_op->u4_error_code |=
IVD_OP_API_STRUCT_SIZE_INCORRECT;
return IV_FAIL;
}
break;
}
default:
*(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
*(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD;
return IV_FAIL;
break;
}
}
break;
}
return IV_SUCCESS;
}
/**
*******************************************************************************
*
* @brief
* Sets Processor type
*
* @par Description:
* Sets Processor type
*
* @param[in] ps_codec_obj
* Pointer to codec object at API level
*
* @param[in] pv_api_ip
* Pointer to input argument structure
*
* @param[out] pv_api_op
* Pointer to output argument structure
*
* @returns Status
*
* @remarks
*
*
*******************************************************************************
*/
WORD32 ih264d_set_processor(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
ih264d_ctl_set_processor_ip_t *ps_ip;
ih264d_ctl_set_processor_op_t *ps_op;
dec_struct_t *ps_codec = (dec_struct_t *)dec_hdl->pv_codec_handle;
ps_ip = (ih264d_ctl_set_processor_ip_t *)pv_api_ip;
ps_op = (ih264d_ctl_set_processor_op_t *)pv_api_op;
ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch;
ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc;
ih264d_init_function_ptr(ps_codec);
ps_op->u4_error_code = 0;
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : ih264d_get_num_rec */
/* */
/* Description : returns number of mem records required */
/* */
/* Inputs : pv_api_ip input api structure */
/* : pv_api_op output api structure */
/* Outputs : */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 22 10 2008 100356 Draft */
/* */
/*****************************************************************************/
WORD32 ih264d_get_num_rec(void *pv_api_ip, void *pv_api_op)
{
iv_num_mem_rec_ip_t *ps_mem_q_ip;
iv_num_mem_rec_op_t *ps_mem_q_op;
ps_mem_q_ip = (iv_num_mem_rec_ip_t *)pv_api_ip;
ps_mem_q_op = (iv_num_mem_rec_op_t *)pv_api_op;
UNUSED(ps_mem_q_ip);
ps_mem_q_op->u4_num_mem_rec = MEM_REC_CNT;
return IV_SUCCESS;
}
/**************************************************************************
* \if Function name : ih264d_init_decoder \endif
*
*
* \brief
* Initializes the decoder
*
* \param apiVersion : Version of the api being used.
* \param errorHandlingMechanism : Mechanism to be used for errror handling.
* \param postFilteringType: Type of post filtering operation to be used.
* \param uc_outputFormat: Format of the decoded picture [default 4:2:0].
* \param uc_dispBufs: Number of Display Buffers.
* \param p_NALBufAPI: Pointer to NAL Buffer API.
* \param p_DispBufAPI: Pointer to Display Buffer API.
* \param ih264d_dec_mem_manager :Pointer to the function that will be called by decoder
* for memory allocation and freeing.
*
* \return
* 0 on Success and -1 on error
*
**************************************************************************
*/
void ih264d_init_decoder(void * ps_dec_params)
{
dec_struct_t * ps_dec = (dec_struct_t *)ps_dec_params;
dec_slice_params_t *ps_cur_slice;
pocstruct_t *ps_prev_poc, *ps_cur_poc;
/* Set pic_parameter_set_id to -1 */
ps_cur_slice = ps_dec->ps_cur_slice;
ps_dec->init_done = 0;
ps_dec->u4_num_cores = 1;
ps_dec->u2_pic_ht = ps_dec->u2_pic_wd = 0;
ps_dec->u1_separate_parse = DEFAULT_SEPARATE_PARSE;
ps_dec->u4_app_disable_deblk_frm = 0;
ps_dec->i4_degrade_type = 0;
ps_dec->i4_degrade_pics = 0;
ps_dec->i4_app_skip_mode = IVD_SKIP_NONE;
ps_dec->i4_dec_skip_mode = IVD_SKIP_NONE;
memset(ps_dec->ps_pps, 0,
((sizeof(dec_pic_params_t)) * MAX_NUM_PIC_PARAMS));
memset(ps_dec->ps_sps, 0,
((sizeof(dec_seq_params_t)) * MAX_NUM_SEQ_PARAMS));
/* Initialization of function pointers ih264d_deblock_picture function*/
ps_dec->p_DeblockPicture[0] = ih264d_deblock_picture_non_mbaff;
ps_dec->p_DeblockPicture[1] = ih264d_deblock_picture_mbaff;
ps_dec->s_cab_dec_env.pv_codec_handle = ps_dec;
ps_dec->u4_num_fld_in_frm = 0;
ps_dec->ps_dpb_mgr->pv_codec_handle = ps_dec;
/* Initialize the sei validity u4_flag with zero indiacting sei is not valid*/
ps_dec->ps_sei->u1_is_valid = 0;
/* decParams Initializations */
ps_dec->ps_cur_pps = NULL;
ps_dec->ps_cur_sps = NULL;
ps_dec->u1_init_dec_flag = 0;
ps_dec->u1_first_slice_in_stream = 1;
ps_dec->u1_first_pb_nal_in_pic = 1;
ps_dec->u1_last_pic_not_decoded = 0;
ps_dec->u4_app_disp_width = 0;
ps_dec->i4_header_decoded = 0;
ps_dec->u4_total_frames_decoded = 0;
ps_dec->i4_error_code = 0;
ps_dec->i4_content_type = -1;
ps_dec->ps_cur_slice->u1_mbaff_frame_flag = 0;
ps_dec->ps_dec_err_status->u1_err_flag = ACCEPT_ALL_PICS; //REJECT_PB_PICS;
ps_dec->ps_dec_err_status->u1_cur_pic_type = PIC_TYPE_UNKNOWN;
ps_dec->ps_dec_err_status->u4_frm_sei_sync = SYNC_FRM_DEFAULT;
ps_dec->ps_dec_err_status->u4_cur_frm = INIT_FRAME;
ps_dec->ps_dec_err_status->u1_pic_aud_i = PIC_TYPE_UNKNOWN;
ps_dec->u1_pr_sl_type = 0xFF;
ps_dec->u2_mbx = 0xffff;
ps_dec->u2_mby = 0;
ps_dec->u2_total_mbs_coded = 0;
ps_cur_slice->u1_end_of_frame_signal = 0;
/* POC initializations */
ps_prev_poc = &ps_dec->s_prev_pic_poc;
ps_cur_poc = &ps_dec->s_cur_pic_poc;
ps_prev_poc->i4_pic_order_cnt_lsb = ps_cur_poc->i4_pic_order_cnt_lsb = 0;
ps_prev_poc->i4_pic_order_cnt_msb = ps_cur_poc->i4_pic_order_cnt_msb = 0;
ps_prev_poc->i4_delta_pic_order_cnt_bottom =
ps_cur_poc->i4_delta_pic_order_cnt_bottom = 0;
ps_prev_poc->i4_delta_pic_order_cnt[0] =
ps_cur_poc->i4_delta_pic_order_cnt[0] = 0;
ps_prev_poc->i4_delta_pic_order_cnt[1] =
ps_cur_poc->i4_delta_pic_order_cnt[1] = 0;
ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
ps_prev_poc->i4_top_field_order_count = ps_cur_poc->i4_top_field_order_count =
0;
ps_prev_poc->i4_bottom_field_order_count =
ps_cur_poc->i4_bottom_field_order_count = 0;
ps_prev_poc->u1_bot_field = ps_cur_poc->u1_bot_field = 0;
ps_prev_poc->u1_mmco_equalto5 = ps_cur_poc->u1_mmco_equalto5 = 0;
ps_prev_poc->i4_prev_frame_num_ofst = ps_cur_poc->i4_prev_frame_num_ofst = 0;
ps_cur_slice->u1_mmco_equalto5 = 0;
ps_cur_slice->u2_frame_num = 0;
ps_dec->i4_max_poc = 0;
ps_dec->i4_prev_max_display_seq = 0;
ps_dec->u1_recon_mb_grp = 4;
/* Field PIC initializations */
ps_dec->u1_second_field = 0;
ps_dec->s_prev_seq_params.u1_eoseq_pending = 0;
/* Set the cropping parameters as zero */
ps_dec->u2_crop_offset_y = 0;
ps_dec->u2_crop_offset_uv = 0;
/* The Initial Frame Rate Info is not Present */
ps_dec->i4_vui_frame_rate = -1;
ps_dec->i4_pic_type = -1;
ps_dec->i4_frametype = -1;
ps_dec->i4_content_type = -1;
ps_dec->u1_res_changed = 0;
ps_dec->u1_frame_decoded_flag = 0;
/* Set the default frame seek mask mode */
ps_dec->u4_skip_frm_mask = SKIP_NONE;
/********************************************************/
/* Initialize CAVLC residual decoding function pointers */
/********************************************************/
ps_dec->pf_cavlc_4x4res_block[0] = ih264d_cavlc_4x4res_block_totalcoeff_1;
ps_dec->pf_cavlc_4x4res_block[1] =
ih264d_cavlc_4x4res_block_totalcoeff_2to10;
ps_dec->pf_cavlc_4x4res_block[2] =
ih264d_cavlc_4x4res_block_totalcoeff_11to16;
ps_dec->pf_cavlc_parse4x4coeff[0] = ih264d_cavlc_parse4x4coeff_n0to7;
ps_dec->pf_cavlc_parse4x4coeff[1] = ih264d_cavlc_parse4x4coeff_n8;
ps_dec->pf_cavlc_parse_8x8block[0] =
ih264d_cavlc_parse_8x8block_none_available;
ps_dec->pf_cavlc_parse_8x8block[1] =
ih264d_cavlc_parse_8x8block_left_available;
ps_dec->pf_cavlc_parse_8x8block[2] =
ih264d_cavlc_parse_8x8block_top_available;
ps_dec->pf_cavlc_parse_8x8block[3] =
ih264d_cavlc_parse_8x8block_both_available;
/***************************************************************************/
/* Initialize Bs calculation function pointers for P and B, 16x16/non16x16 */
/***************************************************************************/
ps_dec->pf_fill_bs1[0][0] = ih264d_fill_bs1_16x16mb_pslice;
ps_dec->pf_fill_bs1[0][1] = ih264d_fill_bs1_non16x16mb_pslice;
ps_dec->pf_fill_bs1[1][0] = ih264d_fill_bs1_16x16mb_bslice;
ps_dec->pf_fill_bs1[1][1] = ih264d_fill_bs1_non16x16mb_bslice;
ps_dec->pf_fill_bs_xtra_left_edge[0] =
ih264d_fill_bs_xtra_left_edge_cur_frm;
ps_dec->pf_fill_bs_xtra_left_edge[1] =
ih264d_fill_bs_xtra_left_edge_cur_fld;
/* Initialize Reference Pic Buffers */
ih264d_init_ref_bufs(ps_dec->ps_dpb_mgr);
#if VERT_SCALE_UP_AND_422
ps_dec->u1_vert_up_scale_flag = 1;
#else
ps_dec->u1_vert_up_scale_flag = 0;
#endif
ps_dec->u2_prv_frame_num = 0;
ps_dec->u1_top_bottom_decoded = 0;
ps_dec->u1_dangling_field = 0;
ps_dec->s_cab_dec_env.cabac_table = gau4_ih264d_cabac_table;
ps_dec->pu1_left_mv_ctxt_inc = ps_dec->u1_left_mv_ctxt_inc_arr[0];
ps_dec->pi1_left_ref_idx_ctxt_inc =
&ps_dec->i1_left_ref_idx_ctx_inc_arr[0][0];
ps_dec->pu1_left_yuv_dc_csbp = &ps_dec->u1_yuv_dc_csbp_topmb;
/* ! */
/* Initializing flush frame u4_flag */
ps_dec->u1_flushfrm = 0;
{
ps_dec->s_cab_dec_env.pv_codec_handle = (void*)ps_dec;
ps_dec->ps_bitstrm->pv_codec_handle = (void*)ps_dec;
ps_dec->ps_cur_slice->pv_codec_handle = (void*)ps_dec;
ps_dec->ps_dpb_mgr->pv_codec_handle = (void*)ps_dec;
}
memset(ps_dec->disp_bufs, 0, (MAX_DISP_BUFS_NEW) * sizeof(disp_buf_t));
memset(ps_dec->u4_disp_buf_mapping, 0,
(MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
memset(ps_dec->u4_disp_buf_to_be_freed, 0,
(MAX_DISP_BUFS_NEW) * sizeof(UWORD32));
ih264d_init_arch(ps_dec);
ih264d_init_function_ptr(ps_dec);
ps_dec->init_done = 1;
ps_dec->process_called = 1;
ps_dec->pv_pic_buf_mgr = NULL;
ps_dec->pv_mv_buf_mgr = NULL;
}
/**************************************************************************
* \if Function name : ih264d_init_video_decoder \endif
*
* \brief
* Wrapper for the decoder init
*
* \param p_NALBufAPI: Pointer to NAL Buffer API.
* \param ih264d_dec_mem_manager :Pointer to the function that will be called by decoder
* for memory allocation and freeing.
*
* \return
* pointer to the decparams
*
**************************************************************************
*/
WORD32 ih264d_init_video_decoder(iv_obj_t *dec_hdl,
ih264d_init_ip_t *ps_init_ip,
ih264d_init_op_t *ps_init_op)
{
dec_struct_t * ps_dec;
iv_mem_rec_t *memtab;
UWORD8 *pu1_extra_mem_base,*pu1_mem_base;
memtab = ps_init_ip->s_ivd_init_ip_t.pv_mem_rec_location;
dec_hdl->pv_codec_handle = memtab[MEM_REC_CODEC].pv_base;
ps_dec = dec_hdl->pv_codec_handle;
memset(ps_dec, 0, sizeof(dec_struct_t));
if(ps_init_ip->s_ivd_init_ip_t.u4_size
> offsetof(ih264d_init_ip_t, i4_level))
{
ps_dec->u4_level_at_init = ps_init_ip->i4_level;
}
else
{
ps_dec->u4_level_at_init = H264_LEVEL_3_1;
}
if(ps_init_ip->s_ivd_init_ip_t.u4_size
> offsetof(ih264d_init_ip_t, u4_num_ref_frames))
{
ps_dec->u4_num_ref_frames_at_init = ps_init_ip->u4_num_ref_frames;
}
else
{
ps_dec->u4_num_ref_frames_at_init = H264_MAX_REF_PICS;
}
if(ps_init_ip->s_ivd_init_ip_t.u4_size
> offsetof(ih264d_init_ip_t, u4_num_reorder_frames))
{
ps_dec->u4_num_reorder_frames_at_init =
ps_init_ip->u4_num_reorder_frames;
}
else
{
ps_dec->u4_num_reorder_frames_at_init = H264_MAX_REF_PICS;
}
if(ps_init_ip->s_ivd_init_ip_t.u4_size
> offsetof(ih264d_init_ip_t, u4_num_extra_disp_buf))
{
ps_dec->u4_num_extra_disp_bufs_at_init =
ps_init_ip->u4_num_extra_disp_buf;
}
else
{
ps_dec->u4_num_extra_disp_bufs_at_init = 0;
}
if(ps_init_ip->s_ivd_init_ip_t.u4_size
> offsetof(ih264d_init_ip_t, u4_share_disp_buf))
{
#ifndef LOGO_EN
ps_dec->u4_share_disp_buf = ps_init_ip->u4_share_disp_buf;
#else
ps_dec->u4_share_disp_buf = 0;
#endif
}
else
{
ps_dec->u4_share_disp_buf = 0;
}
if((ps_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P)
&& (ps_init_ip->s_ivd_init_ip_t.e_output_format
!= IV_YUV_420SP_UV)
&& (ps_init_ip->s_ivd_init_ip_t.e_output_format
!= IV_YUV_420SP_VU))
{
ps_dec->u4_share_disp_buf = 0;
}
if((ps_dec->u4_level_at_init < MIN_LEVEL_SUPPORTED)
|| (ps_dec->u4_level_at_init > MAX_LEVEL_SUPPORTED))
{
ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_LEVEL_UNSUPPORTED;
return (IV_FAIL);
}
if(ps_dec->u4_num_ref_frames_at_init > H264_MAX_REF_PICS)
{
ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_NUM_REF;
ps_dec->u4_num_ref_frames_at_init = H264_MAX_REF_PICS;
}
if(ps_dec->u4_num_reorder_frames_at_init > H264_MAX_REF_PICS)
{
ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_NUM_REF;
ps_dec->u4_num_reorder_frames_at_init = H264_MAX_REF_PICS;
}
if(ps_dec->u4_num_extra_disp_bufs_at_init > H264_MAX_REF_PICS)
{
ps_init_op->s_ivd_init_op_t.u4_error_code |= ERROR_NUM_REF;
ps_dec->u4_num_extra_disp_bufs_at_init = 0;
}
if(0 == ps_dec->u4_share_disp_buf)
ps_dec->u4_num_extra_disp_bufs_at_init = 0;
ps_dec->u4_num_disp_bufs_requested = 1;
ps_dec->u4_width_at_init = ps_init_ip->s_ivd_init_ip_t.u4_frm_max_wd;
ps_dec->u4_height_at_init = ps_init_ip->s_ivd_init_ip_t.u4_frm_max_ht;
ps_dec->u4_width_at_init = ALIGN16(ps_dec->u4_width_at_init);
ps_dec->u4_height_at_init = ALIGN32(ps_dec->u4_height_at_init);
ps_dec->pv_dec_thread_handle = memtab[MEM_REC_THREAD_HANDLE].pv_base;
pu1_mem_base = memtab[MEM_REC_THREAD_HANDLE].pv_base;
ps_dec->pv_bs_deblk_thread_handle = pu1_mem_base
+ ithread_get_handle_size();
ps_dec->u4_extra_mem_used = 0;
pu1_extra_mem_base = memtab[MEM_REC_EXTRA_MEM].pv_base;
ps_dec->ps_dec_err_status = (dec_err_status_t *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used);
ps_dec->u4_extra_mem_used += (((sizeof(dec_err_status_t) + 127) >> 7) << 7);
ps_dec->ps_mem_tab = memtab[MEM_REC_BACKUP].pv_base;
memcpy(ps_dec->ps_mem_tab, memtab, sizeof(iv_mem_rec_t) * MEM_REC_CNT);
ps_dec->ps_pps = memtab[MEM_REC_PPS].pv_base;
ps_dec->ps_sps = memtab[MEM_REC_SPS].pv_base;
ps_dec->ps_sei = (sei *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used);
ps_dec->u4_extra_mem_used += sizeof(sei);
ps_dec->ps_dpb_mgr = memtab[MEM_REC_DPB_MGR].pv_base;
ps_dec->ps_dpb_cmds = (dpb_commands_t *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used);
ps_dec->u4_extra_mem_used += sizeof(dpb_commands_t);
ps_dec->ps_bitstrm = (dec_bit_stream_t *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used);
ps_dec->u4_extra_mem_used += sizeof(dec_bit_stream_t);
ps_dec->ps_cur_slice =(dec_slice_params_t *) (pu1_extra_mem_base + ps_dec->u4_extra_mem_used);
ps_dec->u4_extra_mem_used += sizeof(dec_slice_params_t);
ps_dec->pv_scratch_sps_pps = (void *)(pu1_extra_mem_base + ps_dec->u4_extra_mem_used);
ps_dec->u4_extra_mem_used += MAX(sizeof(dec_seq_params_t),
sizeof(dec_pic_params_t));
ps_dec->ps_pred_pkd = memtab[MEM_REC_PRED_INFO_PKD].pv_base;
ps_dec->ps_dpb_mgr->pv_codec_handle = ps_dec;
ps_dec->pv_dec_out = (void *)ps_init_op;
ps_dec->pv_dec_in = (void *)ps_init_ip;
ps_dec->u1_chroma_format =
(UWORD8)(ps_init_ip->s_ivd_init_ip_t.e_output_format);
ih264d_init_decoder(ps_dec);
return (IV_SUCCESS);
}
/*****************************************************************************/
/* */
/* Function Name : ih264d_fill_num_mem_rec */
/* */
/* Description : fills memory records */
/* */
/* Inputs : pv_api_ip input api structure */
/* : pv_api_op output api structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 22 10 2008 100356 Draft */
/* */
/*****************************************************************************/
WORD32 ih264d_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op)
{
ih264d_fill_mem_rec_ip_t *ps_mem_q_ip;
ih264d_fill_mem_rec_op_t *ps_mem_q_op;
WORD32 level;
UWORD32 num_reorder_frames;
UWORD32 num_ref_frames;
UWORD32 num_extra_disp_bufs;
UWORD32 u4_dpb_size_num_frames;
iv_mem_rec_t *memTab;
UWORD32 chroma_format, u4_share_disp_buf;
UWORD32 u4_total_num_mbs;
UWORD32 luma_width, luma_width_in_mbs;
UWORD32 luma_height, luma_height_in_mbs;
UWORD32 max_dpb_size;
ps_mem_q_ip = (ih264d_fill_mem_rec_ip_t *)pv_api_ip;
ps_mem_q_op = (ih264d_fill_mem_rec_op_t *)pv_api_op;
if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
> offsetof(ih264d_fill_mem_rec_ip_t, i4_level))
{
level = ps_mem_q_ip->i4_level;
}
else
{
level = H264_LEVEL_3_1;
}
if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
> offsetof(ih264d_fill_mem_rec_ip_t, u4_num_reorder_frames))
{
num_reorder_frames = ps_mem_q_ip->u4_num_reorder_frames;
}
else
{
num_reorder_frames = H264_MAX_REF_PICS;
}
if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
> offsetof(ih264d_fill_mem_rec_ip_t, u4_num_ref_frames))
{
num_ref_frames = ps_mem_q_ip->u4_num_ref_frames;
}
else
{
num_ref_frames = H264_MAX_REF_PICS;
}
if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
> offsetof(ih264d_fill_mem_rec_ip_t, u4_num_extra_disp_buf))
{
num_extra_disp_bufs = ps_mem_q_ip->u4_num_extra_disp_buf;
}
else
{
num_extra_disp_bufs = 0;
}
if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
> offsetof(ih264d_fill_mem_rec_ip_t, u4_share_disp_buf))
{
#ifndef LOGO_EN
u4_share_disp_buf = ps_mem_q_ip->u4_share_disp_buf;
#else
u4_share_disp_buf = 0;
#endif
}
else
{
u4_share_disp_buf = 0;
}
if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
> offsetof(ih264d_fill_mem_rec_ip_t, e_output_format))
{
chroma_format = ps_mem_q_ip->e_output_format;
}
else
{
chroma_format = -1;
}
if((chroma_format != IV_YUV_420P) && (chroma_format != IV_YUV_420SP_UV)
&& (chroma_format != IV_YUV_420SP_VU))
{
u4_share_disp_buf = 0;
}
if(0 == u4_share_disp_buf)
num_extra_disp_bufs = 0;
{
luma_height = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht;
luma_width = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd;
luma_height = ALIGN32(luma_height);
luma_width = ALIGN16(luma_width);
luma_width_in_mbs = luma_width >> 4;
luma_height_in_mbs = luma_height >> 4;
u4_total_num_mbs = (luma_height * luma_width) >> 8;
}
/*
* If level is lesser than 31 and the resolution required is higher,
* then make the level at least 31.
*/
if(u4_total_num_mbs > MAX_MBS_LEVEL_30 && level < H264_LEVEL_3_1)
{
level = H264_LEVEL_3_1;
}
if((level < MIN_LEVEL_SUPPORTED) || (level > MAX_LEVEL_SUPPORTED))
{
ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
ERROR_LEVEL_UNSUPPORTED;
return (IV_FAIL);
}
if(num_ref_frames > H264_MAX_REF_PICS)
{
ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= ERROR_NUM_REF;
num_ref_frames = H264_MAX_REF_PICS;
}
if(num_reorder_frames > H264_MAX_REF_PICS)
{
ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= ERROR_NUM_REF;
num_reorder_frames = H264_MAX_REF_PICS;
}
memTab = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location;
memTab[MEM_REC_IV_OBJ].u4_mem_size = sizeof(iv_obj_t);
memTab[MEM_REC_IV_OBJ].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_IV_OBJ].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
H264_DEC_DEBUG_PRINT("MEM_REC_IV_OBJ MEM Size = %d\n",
memTab[MEM_REC_IV_OBJ].u4_mem_size);
memTab[MEM_REC_CODEC].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_CODEC].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_CODEC].u4_mem_size = sizeof(dec_struct_t);
{
UWORD32 mvinfo_size, mv_info_size_pad;
UWORD32 MVbank, MVbank_pad;
UWORD32 Ysize;
UWORD32 UVsize;
UWORD32 one_frm_size;
UWORD32 extra_mem = 0;
UWORD32 pad_len_h, pad_len_v;
/*
* For low_delay, use num_buf as 2 -
* num_buf = (num_buf_ref) + 1;
* where num_buf_ref is 1.
*/
UWORD32 num_buf;
{
UWORD32 num_bufs_app, num_bufs_level;
num_bufs_app = num_ref_frames + num_reorder_frames + 1;
if(num_bufs_app <= 1)
num_bufs_app = 2;
num_bufs_level = ih264d_get_dpb_size_new(level, (luma_width >> 4),
(luma_height >> 4));
max_dpb_size = num_bufs_level;
num_bufs_level = num_bufs_level * 2 + 1;
num_buf = MIN(num_bufs_level, num_bufs_app);
num_buf += num_extra_disp_bufs;
}
mvinfo_size = ((luma_width * (luma_height)) >> 4);
mv_info_size_pad = ((luma_width * (PAD_MV_BANK_ROW)) >> 4);
Ysize = ALIGN32((luma_width + (PAD_LEN_Y_H << 1)))
* (luma_height + (PAD_LEN_Y_V << 2));
UVsize = Ysize >> 2;
if(u4_share_disp_buf == 1)
{
/* In case of buffers getting shared between application and library
there is no need of reference memtabs. Instead of setting the i4_size
to zero, it is reduced to a small i4_size to ensure that changes
in the code are minimal */
if((chroma_format == IV_YUV_420P)
|| (chroma_format == IV_YUV_420SP_UV)
|| (chroma_format == IV_YUV_420SP_VU))
{
Ysize = 64;
}
if(chroma_format == IV_YUV_420SP_UV)
{
UVsize = 64;
}
}
one_frm_size = (((Ysize + 127) >> 7) << 7)
+ ((((UVsize << 1) + 127) >> 7) << 7);
//Note that for ARM RVDS WS the sizeof(mv_pred_t) is 16
/*Add memory for colocated MB*/
MVbank = sizeof(mv_pred_t) * mvinfo_size;
MVbank_pad = sizeof(mv_pred_t) * mv_info_size_pad;
MVbank = (((MVbank + 127) >> 7) << 7);
MVbank_pad = (((MVbank_pad + 127) >> 7) << 7);
memTab[MEM_REC_MVBANK].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_MVBANK].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_MVBANK].u4_mem_size = (MVbank + MVbank_pad)
* (MIN(max_dpb_size, num_ref_frames) + 1);
memTab[MEM_REC_REF_PIC].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_REF_PIC].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_REF_PIC].u4_mem_size = one_frm_size * num_buf;
}
memTab[MEM_REC_DEBLK_MB_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_DEBLK_MB_INFO].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_DEBLK_MB_INFO].u4_mem_size = (((((u4_total_num_mbs
+ (luma_width >> 4)) * sizeof(deblk_mb_t)) + 127) >> 7) << 7);
memTab[MEM_REC_NEIGHBOR_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_NEIGHBOR_INFO].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_NEIGHBOR_INFO].u4_mem_size = sizeof(mb_neigbour_params_t)
* ((luma_width + 16) >> 4) * 2 * 2;
{
WORD32 size;
WORD32 num_entries;
num_entries = MIN(MAX_FRAMES, num_ref_frames);
num_entries = 2 * ((2 * num_entries) + 1);
size = num_entries * sizeof(void *);
size += PAD_MAP_IDX_POC * sizeof(void *);
size *= u4_total_num_mbs;
size += sizeof(dec_slice_struct_t) * u4_total_num_mbs;
memTab[MEM_REC_SLICE_HDR].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_SLICE_HDR].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_SLICE_HDR].u4_mem_size = size;
}
{
UWORD32 u4_num_entries;
u4_num_entries = u4_total_num_mbs;
memTab[MEM_REC_MB_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_MB_INFO].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_MB_INFO].u4_mem_size = sizeof(dec_mb_info_t)
* u4_num_entries;
memTab[MEM_REC_PRED_INFO].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_PRED_INFO].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_PRED_INFO].u4_mem_size = sizeof(pred_info_t) * 2*32;
memTab[MEM_REC_COEFF_DATA].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_COEFF_DATA].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_COEFF_DATA].u4_mem_size = MB_LUM_SIZE * sizeof(WORD16);
/*For I16x16 MBs, 16 4x4 AC coeffs and 1 4x4 DC coeff TU blocks will be sent
For all MBs along with 8 4x4 AC coeffs 2 2x2 DC coeff TU blocks will be sent
So use 17 4x4 TU blocks for luma and 9 4x4 TU blocks for chroma */
memTab[MEM_REC_COEFF_DATA].u4_mem_size += u4_num_entries
* (MAX(17 * sizeof(tu_sblk4x4_coeff_data_t),4 * sizeof(tu_blk8x8_coeff_data_t))
+ 9 * sizeof(tu_sblk4x4_coeff_data_t));
//32 bytes for each mb to store u1_prev_intra4x4_pred_mode and u1_rem_intra4x4_pred_mode data
memTab[MEM_REC_COEFF_DATA].u4_mem_size += u4_num_entries * 32;
}
memTab[MEM_REC_SPS].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_SPS].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_SPS].u4_mem_size = ((sizeof(dec_seq_params_t))
* MAX_NUM_SEQ_PARAMS);
memTab[MEM_REC_PPS].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_PPS].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_PPS].u4_mem_size = (sizeof(dec_pic_params_t))
* MAX_NUM_PIC_PARAMS;
{
UWORD32 u4_mem_size;
u4_mem_size = 0;
u4_mem_size += (((sizeof(dec_err_status_t) + 127) >> 7) << 7);
u4_mem_size += sizeof(sei);
u4_mem_size += sizeof(dpb_commands_t);
u4_mem_size += sizeof(dec_bit_stream_t);
u4_mem_size += sizeof(dec_slice_params_t);
u4_mem_size += MAX(sizeof(dec_seq_params_t), sizeof(dec_pic_params_t));
memTab[MEM_REC_EXTRA_MEM].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_EXTRA_MEM].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_EXTRA_MEM].u4_mem_size = u4_mem_size;
}
{
UWORD32 u4_mem_size;
u4_mem_size = 0;
u4_mem_size += ((TOTAL_LIST_ENTRIES + PAD_MAP_IDX_POC) * sizeof(void *));
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += (sizeof(bin_ctxt_model_t) * NUM_CABAC_CTXTS);
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += sizeof(ctxt_inc_mb_info_t);
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += sizeof(UWORD32) * (MAX_REF_BUFS * MAX_REF_BUFS);
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += MAX_REF_BUF_SIZE * 2;
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += ((sizeof(WORD16)) * PRED_BUFFER_WIDTH
* PRED_BUFFER_HEIGHT * 2);
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += sizeof(UWORD8) * (MB_LUM_SIZE);
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += sizeof(parse_pmbarams_t) * luma_width_in_mbs; //Max recon mb group*/
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += (sizeof(parse_part_params_t) * luma_width_in_mbs) << 4; //Max recon mb group*/
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += 2 * MAX_REF_BUFS * sizeof(struct pic_buffer_t);
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += 2 * MAX_REF_BUFS * sizeof(struct pic_buffer_t);
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += (sizeof(UWORD32) * 3 * (MAX_REF_BUFS * MAX_REF_BUFS)) << 3;
u4_mem_size = ALIGN64(u4_mem_size);
u4_mem_size += sizeof(UWORD32) * 2 * 3 * (MAX_REF_BUFS * MAX_REF_BUFS);
u4_mem_size = ALIGN64(u4_mem_size);
memTab[MEM_REC_INTERNAL_SCRATCH].u4_mem_alignment =
(128 * 8) / CHAR_BIT;
memTab[MEM_REC_INTERNAL_SCRATCH].e_mem_type =
IV_EXTERNAL_CACHEABLE_SCRATCH_MEM;
memTab[MEM_REC_INTERNAL_SCRATCH].u4_mem_size = u4_mem_size;
}
{
UWORD32 u4_mem_used;
UWORD32 u4_numRows = MB_SIZE << 1;
UWORD32 u4_blk_wd = ((luma_width_in_mbs << 4) >> 1) + 8;
u4_mem_used = 0;
u4_mem_used += ((luma_width_in_mbs * sizeof(deblkmb_neighbour_t)) << 1);
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += (sizeof(neighbouradd_t) << 2);
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += ((sizeof(ctxt_inc_mb_info_t))
* (((luma_width_in_mbs + 1) << 1) + 1));
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += (sizeof(mv_pred_t) * luma_width_in_mbs * 16);
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += (sizeof(mv_pred_t) * luma_width_in_mbs * 16);
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += (sizeof(mv_pred_t) * luma_width_in_mbs * 4
* MV_SCRATCH_BUFS);
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd;
u4_mem_used = ALIGN64(u4_mem_used);
u4_numRows = BLK8x8SIZE << 1;
u4_blk_wd = ((luma_width_in_mbs << 3) >> 1) + 8;
u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += sizeof(UWORD8) * u4_numRows * u4_blk_wd;
u4_mem_used += 32;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += sizeof(UWORD8) * (luma_width + 16) * 2;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += sizeof(UWORD8) * (luma_width + 16) * 2;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += sizeof(UWORD8) * (luma_width + 16) * 2;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += sizeof(mb_neigbour_params_t) * (luma_width_in_mbs + 1)
* luma_height_in_mbs;
u4_mem_used += luma_width;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += luma_width;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += luma_width;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += ((MB_SIZE + 4) << 1) * PAD_LEN_Y_H;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += ((BLK8x8SIZE + 2) << 1) * PAD_LEN_UV_H;
u4_mem_used = ALIGN64(u4_mem_used);
u4_mem_used += ((BLK8x8SIZE + 2) << 1) * PAD_LEN_UV_H;
u4_mem_used = ALIGN64(u4_mem_used);
memTab[MEM_REC_INTERNAL_PERSIST].u4_mem_alignment =
(128 * 8) / CHAR_BIT;
memTab[MEM_REC_INTERNAL_PERSIST].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_INTERNAL_PERSIST].u4_mem_size = u4_mem_used;
}
memTab[MEM_REC_BITSBUF].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_BITSBUF].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_BITSBUF].u4_mem_size = MAX(256000, (luma_width * luma_height * 3 / 2));
{
UWORD32 u4_thread_struct_size = ithread_get_handle_size();
memTab[MEM_REC_THREAD_HANDLE].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_THREAD_HANDLE].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_THREAD_HANDLE].u4_mem_size = u4_thread_struct_size * 2;
}
memTab[MEM_REC_PARSE_MAP].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_PARSE_MAP].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_PARSE_MAP].u4_mem_size = u4_total_num_mbs;
memTab[MEM_REC_PROC_MAP].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_PROC_MAP].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_PROC_MAP].u4_mem_size = u4_total_num_mbs;
memTab[MEM_REC_SLICE_NUM_MAP].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_SLICE_NUM_MAP].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_SLICE_NUM_MAP].u4_mem_size = u4_total_num_mbs
* sizeof(UWORD16);
memTab[MEM_REC_DPB_MGR].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_DPB_MGR].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_DPB_MGR].u4_mem_size = sizeof(dpb_manager_t);
memTab[MEM_REC_BACKUP].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_BACKUP].e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_BACKUP].u4_mem_size = sizeof(iv_mem_rec_t) * MEM_REC_CNT;
{
UWORD32 u4_mem_size;
u4_mem_size = sizeof(disp_mgr_t);
u4_mem_size += sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
u4_mem_size += sizeof(struct pic_buffer_t) * (H264_MAX_REF_PICS * 2);
memTab[MEM_REC_PIC_BUF_MGR].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_PIC_BUF_MGR].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_PIC_BUF_MGR].u4_mem_size = u4_mem_size;
}
{
UWORD32 u4_mem_size;
u4_mem_size = sizeof(buf_mgr_t) + ithread_get_mutex_lock_size();
u4_mem_size += sizeof(col_mv_buf_t) * (H264_MAX_REF_PICS * 2);
u4_mem_size = ALIGN128(u4_mem_size);
u4_mem_size += ((luma_width * luma_height) >> 4)
* (MIN(max_dpb_size, num_ref_frames) + 1);
memTab[MEM_REC_MV_BUF_MGR].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_MV_BUF_MGR].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
memTab[MEM_REC_MV_BUF_MGR].u4_mem_size = u4_mem_size;
}
memTab[MEM_REC_PRED_INFO_PKD].u4_mem_alignment = (128 * 8) / CHAR_BIT;
memTab[MEM_REC_PRED_INFO_PKD].e_mem_type =
IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
{
UWORD32 u4_num_entries;
u4_num_entries = u4_total_num_mbs;
if(1 == num_ref_frames)
u4_num_entries *= 16;
else
u4_num_entries *= 16 * 2;
memTab[MEM_REC_PRED_INFO_PKD].u4_mem_size = sizeof(pred_info_pkd_t)
* u4_num_entries;
}
ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled = MEM_REC_CNT;
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : ih264d_clr */
/* */
/* Description : returns memory records to app */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 22 10 2008 100356 Draft */
/* */
/*****************************************************************************/
WORD32 ih264d_clr(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
dec_struct_t * ps_dec;
iv_retrieve_mem_rec_ip_t *dec_clr_ip;
iv_retrieve_mem_rec_op_t *dec_clr_op;
dec_clr_ip = (iv_retrieve_mem_rec_ip_t *)pv_api_ip;
dec_clr_op = (iv_retrieve_mem_rec_op_t *)pv_api_op;
ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
if(ps_dec->init_done != 1)
{
//return a proper Error Code
return IV_FAIL;
}
if(ps_dec->pv_pic_buf_mgr)
ih264_buf_mgr_free((buf_mgr_t *)ps_dec->pv_pic_buf_mgr);
if(ps_dec->pv_mv_buf_mgr)
ih264_buf_mgr_free((buf_mgr_t *)ps_dec->pv_mv_buf_mgr);
memcpy(dec_clr_ip->pv_mem_rec_location, ps_dec->ps_mem_tab,
MEM_REC_CNT * (sizeof(iv_mem_rec_t)));
dec_clr_op->u4_num_mem_rec_filled = MEM_REC_CNT;
H264_DEC_DEBUG_PRINT("The clear non-conceal num mem recs: %d\n",
dec_clr_op->u4_num_mem_rec_filled);
return IV_SUCCESS;
}
/*****************************************************************************/
/* */
/* Function Name : ih264d_init */
/* */
/* Description : initializes decoder */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 22 10 2008 100356 Draft */
/* */
/*****************************************************************************/
WORD32 ih264d_init(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
ih264d_init_ip_t *ps_init_ip;
ih264d_init_op_t *ps_init_op;
ps_init_ip = (ih264d_init_ip_t *)pv_api_ip;
ps_init_op = (ih264d_init_op_t *)pv_api_op;
WORD32 init_status = IV_SUCCESS;
init_status = ih264d_init_video_decoder(dec_hdl, ps_init_ip, ps_init_op);
if(IV_SUCCESS != init_status)
{
return init_status;
}
return init_status;
}
/*****************************************************************************/
/* */
/* Function Name : ih264d_map_error */
/* */
/* Description : Maps error codes to IVD error groups */
/* */
/* Inputs : */
/* Globals : <Does it use any global variables?> */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 22 10 2008 100356 Draft */
/* */
/*****************************************************************************/
UWORD32 ih264d_map_error(UWORD32 i4_err_status)
{
UWORD32 temp = 0;
switch(i4_err_status)
{
case ERROR_MEM_ALLOC_ISRAM_T:
case ERROR_MEM_ALLOC_SDRAM_T:
case ERROR_BUF_MGR:
case ERROR_MB_GROUP_ASSGN_T:
case ERROR_FRAME_LIMIT_OVER:
case ERROR_ACTUAL_RESOLUTION_GREATER_THAN_INIT:
case ERROR_PROFILE_NOT_SUPPORTED:
case ERROR_INIT_NOT_DONE:
temp = 1 << IVD_FATALERROR;
H264_DEC_DEBUG_PRINT("\nFatal Error\n");
break;
case ERROR_DBP_MANAGER_T:
case ERROR_GAPS_IN_FRM_NUM:
case ERROR_UNKNOWN_NAL:
case ERROR_INV_MB_SLC_GRP_T:
case ERROR_MULTIPLE_SLC_GRP_T:
case ERROR_UNKNOWN_LEVEL:
case ERROR_UNAVAIL_PICBUF_T:
case ERROR_UNAVAIL_MVBUF_T:
case ERROR_UNAVAIL_DISPBUF_T:
case ERROR_NUM_REF:
case ERROR_REFIDX_ORDER_T:
case ERROR_PIC0_NOT_FOUND_T:
case ERROR_MB_TYPE:
case ERROR_SUB_MB_TYPE:
case ERROR_CBP:
case ERROR_REF_IDX:
case ERROR_NUM_MV:
case ERROR_CHROMA_PRED_MODE:
case ERROR_INTRAPRED:
case ERROR_NEXT_MB_ADDRESS_T:
case ERROR_MB_ADDRESS_T:
case ERROR_PIC1_NOT_FOUND_T:
case ERROR_CAVLC_NUM_COEFF_T:
case ERROR_CAVLC_SCAN_POS_T:
case ERROR_PRED_WEIGHT_TABLE_T:
case ERROR_CORRUPTED_SLICE:
temp = 1 << IVD_CORRUPTEDDATA;
break;
case ERROR_NOT_SUPP_RESOLUTION:
case ERROR_FEATURE_UNAVAIL:
case ERROR_ACTUAL_LEVEL_GREATER_THAN_INIT:
temp = 1 << IVD_UNSUPPORTEDINPUT;
break;
case ERROR_INVALID_PIC_PARAM:
case ERROR_INVALID_SEQ_PARAM:
case ERROR_EGC_EXCEED_32_1_T:
case ERROR_EGC_EXCEED_32_2_T:
case ERROR_INV_RANGE_TEV_T:
case ERROR_INV_SLC_TYPE_T:
case ERROR_INV_POC_TYPE_T:
case ERROR_INV_RANGE_QP_T:
case ERROR_INV_SPS_PPS_T:
case ERROR_INV_SLICE_HDR_T:
temp = 1 << IVD_CORRUPTEDHEADER;
break;
case ERROR_EOB_FLUSHBITS_T:
case ERROR_EOB_GETBITS_T:
case ERROR_EOB_GETBIT_T:
case ERROR_EOB_BYPASS_T:
case ERROR_EOB_DECISION_T:
case ERROR_EOB_TERMINATE_T:
case ERROR_EOB_READCOEFF4X4CAB_T:
temp = 1 << IVD_INSUFFICIENTDATA;
break;
case ERROR_DYNAMIC_RESOLUTION_NOT_SUPPORTED:
case ERROR_DISP_WIDTH_RESET_TO_PIC_WIDTH:
temp = 1 << IVD_UNSUPPORTEDPARAM | 1 << IVD_FATALERROR;
break;
case ERROR_DANGLING_FIELD_IN_PIC:
temp = 1 << IVD_APPLIEDCONCEALMENT;
break;
}
return temp;
}
/*****************************************************************************/
/* */
/* Function Name : ih264d_video_decode */
/* */
/* Description : handle video decode API command */
/* */
/* Inputs :iv_obj_t decoder handle */
/* :pv_api_ip pointer to input structure */
/* :pv_api_op pointer to output structure */
/* Outputs : */
/* Returns : void */
/* */
/* Issues : none */
/* */
/* Revision History: */
/* */
/* DD MM YYYY Author(s) Changes (Describe the changes made) */
/* 22 10 2008 100356 Draft */
/* */
/*****************************************************************************/
WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op)
{
/* ! */
dec_struct_t * ps_dec = (dec_struct_t *)(dec_hdl->pv_codec_handle);
WORD32 i4_err_status = 0;
UWORD8 *pu1_buf = NULL;
WORD32 buflen;
UWORD32 u4_max_ofst, u4_length_of_start_code = 0;
UWORD32 bytes_consumed = 0;
UWORD32 cur_slice_is_nonref = 0;
UWORD32 u4_next_is_aud;
UWORD32 u4_first_start_code_found = 0;
WORD32 ret,api_ret_value = IV_SUCCESS;
WORD32 header_data_left = 0,frame_data_left = 0;
UWORD8 *pu1_bitstrm_buf;
ithread_set_name((void*)"Parse_thread");
ivd_video_decode_ip_t *ps_dec_ip;
ivd_video_decode_op_t *ps_dec_op;
ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip;
ps_dec_op = (ivd_video_decode_op_t *)pv_api_op;
ps_dec->pv_dec_out = ps_dec_op;
ps_dec->process_called = 1;
if(ps_dec->init_done != 1)
{
return IV_FAIL;
}
/*Data memory barries instruction,so that bitstream write by the application is complete*/
DATA_SYNC();
if(0 == ps_dec->u1_flushfrm)
{
if(ps_dec_ip->pv_stream_buffer == NULL)
{
ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
return IV_FAIL;
}
if(ps_dec_ip->u4_num_Bytes <= 0)
{
ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
return IV_FAIL;
}
}
ps_dec->u1_pic_decode_done = 0;
ps_dec_op->u4_num_bytes_consumed = 0;
ps_dec->ps_out_buffer = NULL;
if(ps_dec_ip->u4_size
>= offsetof(ivd_video_decode_ip_t, s_out_buffer))
ps_dec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
ps_dec->u4_fmt_conv_cur_row = 0;
ps_dec->u4_output_present = 0;
ps_dec->s_disp_op.u4_error_code = 1;
ps_dec->u4_fmt_conv_num_rows = FMT_CONV_NUM_ROWS;
ps_dec->u4_stop_threads = 0;
if(0 == ps_dec->u4_share_disp_buf
&& ps_dec->i4_decode_header == 0)
{
UWORD32 i;
if(ps_dec->ps_out_buffer->u4_num_bufs == 0)
{
ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
return IV_FAIL;
}
for(i = 0; i < ps_dec->ps_out_buffer->u4_num_bufs; i++)
{
if(ps_dec->ps_out_buffer->pu1_bufs[i] == NULL)
{
ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
return IV_FAIL;
}
if(ps_dec->ps_out_buffer->u4_min_out_buf_size[i] == 0)
{
ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
ps_dec_op->u4_error_code |=
IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
return IV_FAIL;
}
}
}
if(ps_dec->u4_total_frames_decoded >= NUM_FRAMES_LIMIT)
{
ps_dec_op->u4_error_code = ERROR_FRAME_LIMIT_OVER;
return IV_FAIL;
}
/* ! */
ps_dec->u4_ts = ps_dec_ip->u4_ts;
ps_dec_op->u4_error_code = 0;
ps_dec_op->e_pic_type = -1;
ps_dec_op->u4_output_present = 0;
ps_dec_op->u4_frame_decoded_flag = 0;
ps_dec->i4_frametype = -1;
ps_dec->i4_content_type = -1;
/*
* For field pictures, set the bottom and top picture decoded u4_flag correctly.
*/
{
if((TOP_FIELD_ONLY | BOT_FIELD_ONLY) == ps_dec->u1_top_bottom_decoded)
{
ps_dec->u1_top_bottom_decoded = 0;
}
}
ps_dec->u4_slice_start_code_found = 0;
/* In case the deocder is not in flush mode(in shared mode),
then decoder has to pick up a buffer to write current frame.
Check if a frame is available in such cases */
if(ps_dec->u1_init_dec_flag == 1 && ps_dec->u4_share_disp_buf == 1
&& ps_dec->u1_flushfrm == 0)
{
UWORD32 i;
WORD32 disp_avail = 0, free_id;
/* Check if at least one buffer is available with the codec */
/* If not then return to application with error */
for(i = 0; i < ps_dec->u1_pic_bufs; i++)
{
if(0 == ps_dec->u4_disp_buf_mapping[i]
|| 1 == ps_dec->u4_disp_buf_to_be_freed[i])
{
disp_avail = 1;