summaryrefslogtreecommitdiffstats
path: root/decoder
diff options
context:
space:
mode:
authorHarish Mahendrakar <harish.mahendrakar@ittiam.com>2015-08-31 09:57:29 +0530
committerMarco Nelissen <marcone@google.com>2015-10-09 11:44:26 -0700
commite3d6224dca4eb80297009b1a753aa65cb0117bd8 (patch)
treeaa281421cff69e0f7fb791852f4217c788fa0134 /decoder
parent137754b36243967714bd23e3c02ef0c44bce5b7b (diff)
downloadandroid_external_libhevc-e3d6224dca4eb80297009b1a753aa65cb0117bd8.tar.gz
android_external_libhevc-e3d6224dca4eb80297009b1a753aa65cb0117bd8.tar.bz2
android_external_libhevc-e3d6224dca4eb80297009b1a753aa65cb0117bd8.zip
Reduced memory requirements
Memory allocations are now done based on contents of SPS API changed to move allocations inside the library Change-Id: Ia4333cc2c01d7402dfe05e55e3c8a770a86be693
Diffstat (limited to 'decoder')
-rw-r--r--decoder/ihevcd_api.c2524
-rw-r--r--decoder/ihevcd_cxa.h141
-rw-r--r--decoder/ihevcd_decode.c38
-rw-r--r--decoder/ihevcd_mv_merge.c2
-rw-r--r--decoder/ihevcd_parse_headers.c17
-rw-r--r--decoder/ihevcd_structs.h113
-rw-r--r--decoder/ihevcd_utils.c202
-rw-r--r--decoder/ihevcd_utils.h10
-rw-r--r--decoder/ihevcd_version.c2
9 files changed, 905 insertions, 2144 deletions
diff --git a/decoder/ihevcd_api.c b/decoder/ihevcd_api.c
index a7a0b62..55d965c 100644
--- a/decoder/ihevcd_api.c
+++ b/decoder/ihevcd_api.c
@@ -32,8 +32,8 @@
* - ihevcd_set_default_params()
* - ihevcd_init()
* - ihevcd_get_num_rec()
-* - ihevcd_fill_num_mem_rec()
-* - ihevcd_init_mem_rec()
+* - ihevcd_allocate_static_bufs()
+* - ihevcd_create()
* - ihevcd_retrieve_memrec()
* - ihevcd_set_display_frame()
* - ihevcd_set_flush_mode()
@@ -92,12 +92,16 @@
#include "ihevcd_job_queue.h"
#include "ihevcd_statistics.h"
+
+#define ALIGNED_FREE(ps_codec, y) \
+if(y) {ps_codec->pf_aligned_free(ps_codec->pv_mem_ctxt, ((void *)y)); (y) = NULL;}
+
/*****************************************************************************/
/* Function Prototypes */
/*****************************************************************************/
IV_API_CALL_STATUS_T ihevcd_get_version(CHAR *pc_version_string,
UWORD32 u4_version_buffer_size);
-
+WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec);
/**
@@ -133,7 +137,7 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
IVD_API_COMMAND_TYPE_T e_cmd;
UWORD32 *pu4_api_ip;
UWORD32 *pu4_api_op;
- WORD32 i, j;
+ WORD32 i;
if(NULL == pv_api_op)
return (IV_FAIL);
@@ -149,31 +153,14 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
/* error checks on handle */
switch((WORD32)e_cmd)
{
- case IV_CMD_GET_NUM_MEM_REC:
- case IV_CMD_FILL_NUM_MEM_REC:
+ case IVD_CMD_CREATE:
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;
- DEBUG("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_DELETE:
case IVD_CMD_VIDEO_CTL:
if(ps_handle == NULL)
{
@@ -205,538 +192,55 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
switch((WORD32)e_cmd)
{
- case IV_CMD_GET_NUM_MEM_REC:
- {
- ihevcd_cxa_num_mem_rec_ip_t *ps_ip =
- (ihevcd_cxa_num_mem_rec_ip_t *)pv_api_ip;
- ihevcd_cxa_num_mem_rec_op_t *ps_op =
- (ihevcd_cxa_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(ihevcd_cxa_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(ihevcd_cxa_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:
- {
- ihevcd_cxa_fill_mem_rec_ip_t *ps_ip =
- (ihevcd_cxa_fill_mem_rec_ip_t *)pv_api_ip;
- ihevcd_cxa_fill_mem_rec_op_t *ps_op =
- (ihevcd_cxa_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 = ALIGN64(max_wd);
- max_ht = ALIGN64(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(ihevcd_cxa_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(ihevcd_cxa_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 < MIN_WD)
- {
- 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 > MAX_WD)
- {
- 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 < MIN_HT)
- {
- 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) > (MAX_HT * MAX_WD))
-
- {
- 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:
+ case IVD_CMD_CREATE:
{
- ihevcd_cxa_init_ip_t *ps_ip = (ihevcd_cxa_init_ip_t *)pv_api_ip;
- ihevcd_cxa_init_op_t *ps_op = (ihevcd_cxa_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;
+ ihevcd_cxa_create_ip_t *ps_ip = (ihevcd_cxa_create_ip_t *)pv_api_ip;
+ ihevcd_cxa_create_op_t *ps_op = (ihevcd_cxa_create_op_t *)pv_api_op;
- max_wd = ALIGN64(max_wd);
- max_ht = ALIGN64(max_ht);
- ps_op->s_ivd_init_op_t.u4_error_code = 0;
+ ps_op->s_ivd_create_op_t.u4_error_code = 0;
- if((ps_ip->s_ivd_init_ip_t.u4_size > sizeof(ihevcd_cxa_init_ip_t))
- || (ps_ip->s_ivd_init_ip_t.u4_size
- < sizeof(ivd_init_ip_t)))
+ if((ps_ip->s_ivd_create_ip_t.u4_size > sizeof(ihevcd_cxa_create_ip_t))
+ || (ps_ip->s_ivd_create_ip_t.u4_size
+ < sizeof(ivd_create_ip_t)))
{
- ps_op->s_ivd_init_op_t.u4_error_code |= 1
+ ps_op->s_ivd_create_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
- ps_op->s_ivd_init_op_t.u4_error_code |=
+ ps_op->s_ivd_create_op_t.u4_error_code |=
IVD_IP_API_STRUCT_SIZE_INCORRECT;
- DEBUG("\n");
- return (IV_FAIL);
- }
-
- if((ps_op->s_ivd_init_op_t.u4_size != sizeof(ihevcd_cxa_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;
- DEBUG("\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;
- DEBUG("\n");
- return (IV_FAIL);
- }
-
- if(max_wd < MIN_WD)
- {
- 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;
- DEBUG("\n");
- return (IV_FAIL);
- }
- if(max_wd > MAX_WD)
- {
- 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;
- DEBUG("\n");
return (IV_FAIL);
}
- if(max_ht < MIN_HT)
+ if((ps_op->s_ivd_create_op_t.u4_size != sizeof(ihevcd_cxa_create_op_t))
+ && (ps_op->s_ivd_create_op_t.u4_size
+ != sizeof(ivd_create_op_t)))
{
- ps_op->s_ivd_init_op_t.u4_error_code |= 1
+ ps_op->s_ivd_create_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
- ps_op->s_ivd_init_op_t.u4_error_code |=
- IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED;
- DEBUG("\n");
- return (IV_FAIL);
- }
-
- if((max_ht * max_wd) > (MAX_HT * MAX_WD))
+ ps_op->s_ivd_create_op_t.u4_error_code |=
+ IVD_OP_API_STRUCT_SIZE_INCORRECT;
- {
- 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;
- DEBUG("\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;
- DEBUG("\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
+ 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_init_ip_t.e_output_format
+ && (ps_ip->s_ivd_create_ip_t.e_output_format
!= IV_RGB_565)
- && (ps_ip->s_ivd_init_ip_t.e_output_format
- != IV_RGBA_8888)
- && (ps_ip->s_ivd_init_ip_t.e_output_format
+ && (ps_ip->s_ivd_create_ip_t.e_output_format
!= IV_YUV_420SP_UV)
- && (ps_ip->s_ivd_init_ip_t.e_output_format
+ && (ps_ip->s_ivd_create_ip_t.e_output_format
!= IV_YUV_420SP_VU))
{
- ps_op->s_ivd_init_op_t.u4_error_code |= 1
+ ps_op->s_ivd_create_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
- ps_op->s_ivd_init_op_t.u4_error_code |=
+ ps_op->s_ivd_create_op_t.u4_error_code |=
IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED;
- DEBUG("\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;
- DEBUG("\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 < (WORD32)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;
- DEBUG("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;
- DEBUG("i: %d\n", i);
- return IV_FAIL;
-
- }
-
- }
-
- /* verify memtabs for overlapping regions */
- {
- void *start[MEM_REC_CNT];
- void *end[MEM_REC_CNT];
-
- start[0] = (ps_mem_rec[0].pv_base);
- end[0] = (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] = (ps_mem_rec[i].pv_base);
- end[i] = (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;
- DEBUG("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;
- DEBUG("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;
- DEBUG("i: %d, j: %d\n", i, j);
- return IV_FAIL;
- }
- }
-
- }
- }
-
- {
- iv_mem_rec_t mem_rec_ittiam_api[MEM_REC_CNT];
- ihevcd_cxa_fill_mem_rec_ip_t s_fill_mem_rec_ip;
- ihevcd_cxa_fill_mem_rec_op_t s_fill_mem_rec_op;
- IV_API_CALL_STATUS_T e_status;
-
- WORD32 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(ihevcd_cxa_init_ip_t, i4_level))
- {
- s_fill_mem_rec_ip.i4_level = ps_ip->i4_level;
- }
- else
- {
- s_fill_mem_rec_ip.i4_level = IHEVC_LEVEL_31;
- }
-
- if(ps_ip->s_ivd_init_ip_t.u4_size
- > offsetof(ihevcd_cxa_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 = (MAX_REF_CNT + 1);
- }
-
- if(ps_ip->s_ivd_init_ip_t.u4_size
- > offsetof(ihevcd_cxa_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 = (MAX_REF_CNT + 1);
- }
-
- if(ps_ip->s_ivd_init_ip_t.u4_size
- > offsetof(ihevcd_cxa_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(ihevcd_cxa_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(ihevcd_cxa_fill_mem_rec_ip_t);
- s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size =
- sizeof(ihevcd_cxa_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 = ihevcd_cxa_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;
- DEBUG("Fail\n");
- return (IV_FAIL);
- }
-
- for(i = 0; i < MEM_REC_CNT; i++)
- {
-#ifdef ARMRVDS
- if((UWORD32)(ps_mem_rec[i].pv_base) & (mem_rec_ittiam_api[i].u4_mem_alignment - 1))
- {
- 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;
- DEBUG("Fail\n");
- return IV_FAIL;
- }
-#endif
-
- 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;
- DEBUG("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;
- DEBUG("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 != (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;
- DEBUG("i: %d \n", i);
- return IV_FAIL;
- }
- }
- }
+ return (IV_FAIL);
}
}
@@ -939,49 +443,35 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
}
break;
- case IV_CMD_RETRIEVE_MEMREC:
+ case IVD_CMD_DELETE:
{
- ihevcd_cxa_retrieve_mem_rec_ip_t *ps_ip =
- (ihevcd_cxa_retrieve_mem_rec_ip_t *)pv_api_ip;
- ihevcd_cxa_retrieve_mem_rec_op_t *ps_op =
- (ihevcd_cxa_retrieve_mem_rec_op_t *)pv_api_op;
- iv_mem_rec_t *ps_mem_rec;
+ ihevcd_cxa_delete_ip_t *ps_ip =
+ (ihevcd_cxa_delete_ip_t *)pv_api_ip;
+ ihevcd_cxa_delete_op_t *ps_op =
+ (ihevcd_cxa_delete_op_t *)pv_api_op;
- ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code = 0;
+ ps_op->s_ivd_delete_op_t.u4_error_code = 0;
- if(ps_ip->s_ivd_retrieve_mem_rec_ip_t.u4_size
- != sizeof(ihevcd_cxa_retrieve_mem_rec_ip_t))
+ if(ps_ip->s_ivd_delete_ip_t.u4_size
+ != sizeof(ihevcd_cxa_delete_ip_t))
{
- ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1
+ ps_op->s_ivd_delete_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
- ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |=
+ ps_op->s_ivd_delete_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(ihevcd_cxa_retrieve_mem_rec_op_t))
+ if(ps_op->s_ivd_delete_op_t.u4_size
+ != sizeof(ihevcd_cxa_delete_op_t))
{
- ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1
+ ps_op->s_ivd_delete_op_t.u4_error_code |= 1
<< IVD_UNSUPPORTEDPARAM;
- ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |=
+ ps_op->s_ivd_delete_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;
@@ -1480,7 +970,7 @@ void ihevcd_update_function_ptr(codec_t *ps_codec)
*******************************************************************************
*
* @brief
-* Initialize the context. This will be called by init_mem_rec and during
+* Initialize the context. This will be called by create and during
* reset
*
* @par Description:
@@ -1501,12 +991,15 @@ WORD32 ihevcd_init(codec_t *ps_codec)
WORD32 status = IV_SUCCESS;
WORD32 i;
+ /* Free any dynamic buffers that are allocated */
+ ihevcd_free_dynamic_bufs(ps_codec);
+ ps_codec->u4_allocate_dynamic_done = 0;
ps_codec->i4_num_disp_bufs = 1;
ps_codec->i4_flush_mode = 0;
- ps_codec->i4_ht = ps_codec->i4_disp_ht = ps_codec->i4_max_ht;
- ps_codec->i4_wd = ps_codec->i4_disp_wd = ps_codec->i4_max_wd;
+ ps_codec->i4_ht = ps_codec->i4_disp_ht = 0;
+ ps_codec->i4_wd = ps_codec->i4_disp_wd = 0;
ps_codec->i4_strd = 0;
ps_codec->i4_disp_strd = 0;
ps_codec->i4_num_cores = 1;
@@ -1572,23 +1065,6 @@ WORD32 ihevcd_init(codec_t *ps_codec)
}
ihevcd_set_default_params(ps_codec);
- ps_codec->pv_proc_jobq = ihevcd_jobq_init(ps_codec->pv_proc_jobq_buf, ps_codec->i4_proc_jobq_buf_size);
- RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL);
-
- /* Update the jobq context to all the threads */
- ps_codec->s_parse.pv_proc_jobq = ps_codec->pv_proc_jobq;
- for(i = 0; i < MAX_PROCESS_THREADS; i++)
- {
- ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq;
- ps_codec->as_process[i].i4_id = i;
- ps_codec->as_process[i].ps_codec = ps_codec;
-
- /* Set the following to zero assuming it is a single core solution
- * When threads are launched these will be set appropriately
- */
- ps_codec->as_process[i].i4_check_parse_status = 0;
- ps_codec->as_process[i].i4_check_proc_status = 0;
- }
/* Initialize MV Bank buffer manager */
ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_mv_buf_mgr);
@@ -1623,79 +1099,10 @@ WORD32 ihevcd_init(codec_t *ps_codec)
*******************************************************************************
*
* @brief
-* Gets number of memory records required by the codec
-*
-* @par Description:
-* Gets codec mem record requirements and adds concealment modules
-* requirements
-*
-* @param[in] pv_api_ip
-* Pointer to input argument structure
-*
-* @param[out] pv_api_op
-* Pointer to output argument structure
-*
-* @returns Status
-*
-* @remarks
-*
-*
-*******************************************************************************
-*/
-WORD32 ihevcd_get_num_rec(void *pv_api_ip, void *pv_api_op)
-{
-
- iv_num_mem_rec_op_t *ps_mem_q_op;
-
- UNUSED(pv_api_ip);
- ps_mem_q_op = (iv_num_mem_rec_op_t *)pv_api_op;
- ps_mem_q_op->u4_num_mem_rec = MEM_REC_CNT;
- DEBUG("Get num mem records without concealment %d\n",
- ps_mem_q_op->u4_num_mem_rec);
-#ifdef APPLY_CONCEALMENT
- {
- IV_API_CALL_STATUS_T status;
- icncl_num_mem_rec_ip_t cncl_mem_ip;
- icncl_num_mem_rec_op_t cncl_mem_op;
-
- cncl_mem_ip.s_ivd_num_rec_ip_t.e_cmd = IV_CMD_GET_NUM_MEM_REC;
- cncl_mem_ip.s_ivd_num_rec_ip_t.u4_size = sizeof(icncl_num_mem_rec_ip_t);
-
- status = icncl_api_function(NULL, (void *)&cncl_mem_ip, (void *)&cncl_mem_op);
-
- if(status == IV_SUCCESS)
- {
- /* Add the concealment library's memory requirements */
- ps_mem_q_op->u4_num_mem_rec += cncl_mem_op.s_ivd_num_mem_rec_op_t.u4_num_mem_rec;
- DEBUG("Get num mem records %d\n", ps_mem_q_op->u4_num_mem_rec);
- return status; /* Nothing else to do, return */
- }
- else
- {
- /*
- * Something went wrong with the concealment library call.
- */
- DEBUG("ERROR: Get num mem records %d\n", ps_mem_q_op->u4_num_mem_rec);
- return status;
- }
-
- }
-#endif //APPLY_CONCEALMENT
-
-
- return IV_SUCCESS;
-
-}
-
-/**
-*******************************************************************************
-*
-* @brief
-* Fills memory requirements of the codec
+* Allocate static memory for the codec
*
* @par Description:
-* Gets codec mem record requirements and adds concealment modules
-* requirements
+* Allocates static memory for the codec
*
* @param[in] pv_api_ip
* Pointer to input argument structure
@@ -1710,746 +1117,260 @@ WORD32 ihevcd_get_num_rec(void *pv_api_ip, void *pv_api_op)
*
*******************************************************************************
*/
-WORD32 ihevcd_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op)
+WORD32 ihevcd_allocate_static_bufs(iv_obj_t **pps_codec_obj,
+ ihevcd_cxa_create_ip_t *ps_create_ip,
+ ihevcd_cxa_create_op_t *ps_create_op)
{
-
- ihevcd_cxa_fill_mem_rec_ip_t *ps_mem_q_ip;
- ihevcd_cxa_fill_mem_rec_op_t *ps_mem_q_op;
- WORD32 level;
- WORD32 num_reorder_frames;
- WORD32 num_ref_frames;
- WORD32 num_extra_disp_bufs;
- WORD32 max_dpb_size;
-
- iv_mem_rec_t *ps_mem_rec;
- iv_mem_rec_t *ps_mem_rec_base;
- WORD32 no_of_mem_rec_filled;
- WORD32 chroma_format, share_disp_buf;
- WORD32 max_ctb_cnt;
- WORD32 max_wd_luma, max_wd_chroma;
- WORD32 max_ht_luma, max_ht_chroma;
- WORD32 max_tile_cols, max_tile_rows;
- WORD32 max_ctb_rows, max_ctb_cols;
- WORD32 max_num_cu_cols;
+ WORD32 size;
+ void *pv_buf;
+ UWORD8 *pu1_buf;
WORD32 i;
- WORD32 max_num_4x4_cols;
+ codec_t *ps_codec;
IV_API_CALL_STATUS_T status = IV_SUCCESS;
- no_of_mem_rec_filled = 0;
+ 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;
- //TODO: Remove as and when the following are used
- UNUSED(num_extra_disp_bufs);
- UNUSED(no_of_mem_rec_filled);
- UNUSED(max_wd_chroma);
- UNUSED(max_ht_chroma);
+ /* Request memory for HEVCD object */
+ ps_create_op->s_ivd_create_op_t.pv_handle = NULL;
- ps_mem_q_ip = (ihevcd_cxa_fill_mem_rec_ip_t *)pv_api_ip;
- ps_mem_q_op = (ihevcd_cxa_fill_mem_rec_op_t *)pv_api_op;
+ 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;
- if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
- > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, i4_level))
- {
- level = ps_mem_q_ip->i4_level;
- /* Spec requires level should be multiplied by 30
- * API has values where level is multiplied by 10. This keeps it consistent with H264
- * Because of the above differences, level is multiplied by 3 here.
- */
- level *= 3;
- }
- else
- {
- level = MAX_LEVEL;
- }
- if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
- > offsetof(ihevcd_cxa_fill_mem_rec_ip_t,
- u4_num_reorder_frames))
- {
- num_reorder_frames = ps_mem_q_ip->u4_num_reorder_frames;
- }
- else
- {
- num_reorder_frames = MAX_REF_CNT;
- }
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(iv_obj_t));
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ *pps_codec_obj = (iv_obj_t *)pv_buf;
+ ps_create_op->s_ivd_create_op_t.pv_handle = *pps_codec_obj;
- if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
- > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, u4_num_ref_frames))
- {
- num_ref_frames = ps_mem_q_ip->u4_num_ref_frames;
- }
- else
- {
- num_ref_frames = MAX_REF_CNT;
- }
- if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
- > offsetof(ihevcd_cxa_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;
- }
+ (*pps_codec_obj)->pv_codec_handle = NULL;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(codec_t));
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ (*pps_codec_obj)->pv_codec_handle = (codec_t *)pv_buf;
+ ps_codec = (codec_t *)pv_buf;
+
+ memset(ps_codec, 0, sizeof(codec_t));
- if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
- > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, u4_share_disp_buf))
- {
#ifndef LOGO_EN
- share_disp_buf = ps_mem_q_ip->u4_share_disp_buf;
+ ps_codec->i4_share_disp_buf = ps_create_ip->s_ivd_create_ip_t.u4_share_disp_buf;
#else
- share_disp_buf = 0;
+ ps_codec->i4_share_disp_buf = 0;
#endif
- }
- else
- {
- share_disp_buf = 0;
- }
- if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
- > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, e_output_format))
- {
- chroma_format = ps_mem_q_ip->e_output_format;
- }
- else
- {
- chroma_format = -1;
- }
-
- /* Shared disp buffer mode is supported only for 420SP formats */
- if((chroma_format != IV_YUV_420P) &&
- (chroma_format != IV_YUV_420SP_UV) &&
- (chroma_format != IV_YUV_420SP_VU))
+ /* Shared display mode is supported only for 420SP and 420P formats */
+ if((ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420P) &&
+ (ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420SP_UV) &&
+ (ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420SP_VU))
{
- share_disp_buf = 0;
+ ps_codec->i4_share_disp_buf = 0;
}
- {
-
- max_ht_luma = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht;
- max_wd_luma = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd;
-
- max_ht_luma = ALIGN64(max_ht_luma);
- max_wd_luma = ALIGN64(max_wd_luma);
-
-
-
- max_tile_cols = (max_wd_luma + MIN_TILE_WD - 1) / MIN_TILE_WD;
- max_tile_rows = (max_ht_luma + MIN_TILE_HT - 1) / MIN_TILE_HT;
- max_ctb_rows = max_ht_luma / MIN_CTB_SIZE;
- max_ctb_cols = max_wd_luma / MIN_CTB_SIZE;
- max_ctb_cnt = max_ctb_rows * max_ctb_cols;
- max_num_cu_cols = max_wd_luma / MIN_CU_SIZE;
- max_num_4x4_cols = max_wd_luma / 4;
- }
- /*
- * If level is lesser than 31 and the resolution required is higher,
- * then make the level at least 31.
- */
- /* if (num_mbs > MAX_NUM_MBS_3_0 && level < MAX_LEVEL)
- {
- level = MAX_LEVEL;
- }
- */
- if((level < MIN_LEVEL) || (level > MAX_LEVEL))
- {
- ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
- IHEVCD_LEVEL_UNSUPPORTED;
- level = MAX_LEVEL;
- }
- if(num_ref_frames > MAX_REF_CNT)
- {
- ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
- IHEVCD_NUM_REF_UNSUPPORTED;
- num_ref_frames = MAX_REF_CNT;
- }
+ ps_codec->e_chroma_fmt = ps_create_ip->s_ivd_create_ip_t.e_output_format;
- if(num_reorder_frames > MAX_REF_CNT)
- {
- ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
- IHEVCD_NUM_REORDER_UNSUPPORTED;
- num_reorder_frames = MAX_REF_CNT;
- }
+ ps_codec->pf_aligned_alloc = pf_aligned_alloc;
+ ps_codec->pf_aligned_free = pf_aligned_free;
+ ps_codec->pv_mem_ctxt = pv_mem_ctxt;
- max_dpb_size = ihevcd_get_dpb_size(level, max_wd_luma * max_ht_luma);
- ps_mem_rec_base = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location;
+ /* Request memory to hold thread handles for each processing thread */
+ size = MAX_PROCESS_THREADS * ithread_get_handle_size();
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
- /* Set all memory reconds as persistent and alignment as 128
- * by default
- */
- ps_mem_rec = ps_mem_rec_base;
- for(i = 0; i < MEM_REC_CNT; i++)
+ for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
- ps_mem_rec->u4_mem_alignment = 128;
- ps_mem_rec->e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
- ps_mem_rec++;
+ WORD32 handle_size = ithread_get_handle_size();
+ ps_codec->apv_process_thread_handle[i] =
+ (UWORD8 *)pv_buf + (i * handle_size);
}
- /* Request memory for HEVCD object */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_IV_OBJ];
- ps_mem_rec->u4_mem_size = sizeof(iv_obj_t);
-
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_IV_OBJ,
- ps_mem_rec->u4_mem_size);
-
- /* Request memory for HEVC Codec context */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
- ps_mem_rec->u4_mem_size = sizeof(codec_t);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CODEC,
- ps_mem_rec->u4_mem_size);
-
- /* Request memory for buffer which holds bitstream after emulation prevention */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_BITSBUF];
- ps_mem_rec->u4_mem_size = MAX((max_wd_luma * max_ht_luma), MIN_BITSBUF_SIZE);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BITSBUF,
- ps_mem_rec->u4_mem_size);
-
- /* Request memory for buffer which holds TU structures and coeff data for
- * a set of CTBs in the current picture */
- /*TODO Currently the buffer is allocated at a frame level. Reduce this to
- * allocate for s set of CTBs and add appropriate synchronization logic to
- * ensure that this is data is not overwritten before consumption
- */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_TU_DATA];
- ps_mem_rec->u4_mem_size = ihevcd_get_tu_data_size(max_wd_luma * max_ht_luma);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TU_DATA,
- ps_mem_rec->u4_mem_size);
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
-
- ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
-
- /* Size for holding mv_buf_t for each MV Bank */
- /* Note this allocation is done for BUF_MGR_MAX_CNT instead of
- * max_dpb_size or MAX_DPB_SIZE for following reasons
- * max_dpb_size will be based on max_wd and max_ht
- * For higher max_wd and max_ht this number will be smaller than MAX_DPB_SIZE
- * But during actual initialization number of buffers allocated can be more
- *
- * One extra MV Bank is needed to hold current pics MV bank.
- * Since this is only a structure allocation and not actual buffer allocation,
- * it is allocated for (MAX_DPB_SIZE + 1) entries
- */
- ps_mem_rec->u4_mem_size += (MAX_DPB_SIZE + 1) * sizeof(mv_buf_t);
+ /* Request memory for static bitstream buffer which holds bitstream after emulation prevention */
+ size = MIN_BITSBUF_SIZE;
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->pu1_bitsbuf_static = pv_buf;
+ ps_codec->u4_bitsbuf_size_static = size;
- {
- /* Allocate for pu_map, pu_t and pic_pu_idx for each MV bank */
- /* Note: Number of luma samples is not max_wd * max_ht here, instead it is
- * set to maximum number of luma samples allowed at the given level.
- * This is done to ensure that any stream with width and height lesser
- * than max_wd and max_ht is supported. Number of buffers required can be greater
- * for lower width and heights at a given level and this increased number of buffers
- * might require more memory than what max_wd and max_ht buffer would have required
- * Also note one extra buffer is allocted to store current pictures MV bank
- * In case of asynchronous parsing and processing, number of buffers should increase here
- * based on when parsing and processing threads are synchronized
- */
- WORD32 lvl_idx = ihevcd_get_lvl_idx(level);
- WORD32 max_luma_samples = gai4_ihevc_max_luma_pic_size[lvl_idx];
- ps_mem_rec->u4_mem_size += (max_dpb_size + 1) *
- ihevcd_get_pic_mv_bank_size(max_luma_samples);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBANK,
- ps_mem_rec->u4_mem_size);
- }
- // TODO GPU : Have to creat ping-pong view for VPS,SPS,PPS.
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_VPS];
- ps_mem_rec->u4_mem_size = MAX_VPS_CNT * sizeof(vps_t);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_VPS,
- ps_mem_rec->u4_mem_size);
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
- ps_mem_rec->u4_mem_size = MAX_SPS_CNT * sizeof(sps_t);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SPS,
- ps_mem_rec->u4_mem_size);
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
- ps_mem_rec->u4_mem_size = MAX_PPS_CNT * sizeof(pps_t);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PPS,
- ps_mem_rec->u4_mem_size);
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
- ps_mem_rec->u4_mem_size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_HDR,
- ps_mem_rec->u4_mem_size);
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE];
- {
- WORD32 tile_size;
-
- tile_size = max_tile_cols * max_tile_rows;
- tile_size *= sizeof(tile_t);
+ /* size for holding display manager context */
+ size = sizeof(buf_mgr_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->pv_disp_buf_mgr = pv_buf;
+ /* size for holding dpb manager context */
+ size = sizeof(dpb_mgr_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->pv_dpb_mgr = pv_buf;
- ps_mem_rec->u4_mem_size = MAX_PPS_CNT * tile_size;
- }
+ /* size for holding buffer manager context */
+ size = sizeof(buf_mgr_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->pv_pic_buf_mgr = pv_buf;
+
+ /* size for holding mv buffer manager context */
+ size = sizeof(buf_mgr_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->pv_mv_buf_mgr = pv_buf;
+
+ size = MAX_VPS_CNT * sizeof(vps_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->ps_vps_base = pv_buf;
+ ps_codec->s_parse.ps_vps_base = ps_codec->ps_vps_base;
+ size = MAX_SPS_CNT * sizeof(sps_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->ps_sps_base = pv_buf;
+ ps_codec->s_parse.ps_sps_base = ps_codec->ps_sps_base;
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TILE,
- ps_mem_rec->u4_mem_size);
+ size = MAX_PPS_CNT * sizeof(pps_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->ps_pps_base = pv_buf;
+ ps_codec->s_parse.ps_pps_base = ps_codec->ps_pps_base;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTRY_OFST];
- {
- WORD32 num_entry_points;
+ size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->ps_slice_hdr_base = (slice_header_t *)pv_buf;
+ ps_codec->s_parse.ps_slice_hdr_base = ps_codec->ps_slice_hdr_base;
- /* One entry point per tile */
- num_entry_points = max_tile_cols * max_tile_rows;
- /* One entry point per row of CTBs */
- /*********************************************************************/
- /* Only tiles or entropy sync is enabled at a time in main */
- /* profile, but since memory required does not increase too much, */
- /* this allocation is done to handle both cases */
- /*********************************************************************/
- num_entry_points += max_ctb_rows;
+ SCALING_MAT_SIZE(size)
+ size = (MAX_SPS_CNT + MAX_PPS_CNT) * size * sizeof(WORD16);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->pi2_scaling_mat = (WORD16 *)pv_buf;
- ps_mem_rec->u4_mem_size = sizeof(WORD32) * num_entry_points;
- }
+ /* Size for holding pic_buf_t for each reference picture
+ * Since this is only a structure allocation and not actual buffer allocation,
+ * it is allocated for BUF_MGR_MAX_CNT entries
+ */
+ size = BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
+ pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->pv_pic_buf_base = (UWORD8 *)pv_buf;
+ /* TO hold scratch buffers needed for each SAO context */
+ size = 4 * MAX_CTB_SIZE * MAX_CTB_SIZE;
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTRY_OFST,
- ps_mem_rec->u4_mem_size);
+ /* 2 temporary buffers*/
+ size *= 2;
+ size *= MAX_PROCESS_THREADS;
+ pu1_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pu1_buf), IV_FAIL);
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_SCALING_MAT];
+ for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
- WORD32 scaling_mat_size;
+ ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_luma = (UWORD8 *)pu1_buf;
+ pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
- SCALING_MAT_SIZE(scaling_mat_size)
- ps_mem_rec->u4_mem_size = (MAX_SPS_CNT + MAX_PPS_CNT) * scaling_mat_size * sizeof(WORD16);
+ ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_chroma = (UWORD8 *)pu1_buf;
+ pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
}
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SCALING_MAT,
- ps_mem_rec->u4_mem_size);
-
- /* Holds one row skip_flag at 8x8 level used during parsing */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_SKIP_FLAG];
-
- /* 1 bit per 8x8 */
- ps_mem_rec->u4_mem_size = max_num_cu_cols / 8;
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_SKIP_FLAG,
- ps_mem_rec->u4_mem_size);
-
- /* Holds one row skip_flag at 8x8 level used during parsing */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_CT_DEPTH];
-
- /* 2 bits per 8x8 */
- ps_mem_rec->u4_mem_size = max_num_cu_cols / 4;
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_CT_DEPTH,
- ps_mem_rec->u4_mem_size);
-
- /* Holds one row skip_flag at 8x8 level used during parsing */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_INTRA_PRED_MODE];
+ /* Allocate intra pred modes buffer */
/* 8 bits per 4x4 */
/* 16 bytes each for top and left 64 pixels and 16 bytes for default mode */
- ps_mem_rec->u4_mem_size = 3 * 16 * sizeof(UWORD8);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_INTRA_PRED_MODE,
- ps_mem_rec->u4_mem_size);
-
- /* Holds one intra mode at 8x8 level for entire picture */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_FLAG];
-
- /* 1 bit per 8x8 */
- ps_mem_rec->u4_mem_size = (max_wd_luma / MIN_CU_SIZE) * (max_ht_luma / MIN_CU_SIZE) / 8;
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_INTRA_FLAG,
- ps_mem_rec->u4_mem_size);
-
- /* Holds one transquant bypass flag at 8x8 level for entire picture */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_TRANSQUANT_BYPASS_FLAG];
-
- /* 1 bit per 8x8 */
- /* Extra row and column are allocated for easy processing of top and left blocks while loop filtering */
- ps_mem_rec->u4_mem_size = ((max_wd_luma + 64) / MIN_CU_SIZE) * ((max_ht_luma + 64) / MIN_CU_SIZE) / 8;
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TRANSQUANT_BYPASS_FLAG,
- ps_mem_rec->u4_mem_size);
-
- /* Request memory to hold thread handles for each processing thread */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
- ps_mem_rec->u4_mem_size = MAX_PROCESS_THREADS * ithread_get_handle_size();
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_THREAD_HANDLE,
- ps_mem_rec->u4_mem_size);
-
+ size = 3 * 16 * sizeof(UWORD8);
+ pu1_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pu1_buf), IV_FAIL);
+ ps_codec->s_parse.pu1_luma_intra_pred_mode_left = pu1_buf;
+ ps_codec->s_parse.pu1_luma_intra_pred_mode_top = pu1_buf + 16;
{
- WORD32 job_queue_size;
- WORD32 num_jobs;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
-
-
- /* One job per row of CTBs */
- num_jobs = max_ctb_rows;
-
- /* One each tile a row of CTBs, num_jobs has to incremented */
- num_jobs *= max_tile_cols;
-
- /* One format convert/frame copy job per row of CTBs for non-shared mode*/
- num_jobs += max_ctb_rows;
-
-
- job_queue_size = ihevcd_jobq_ctxt_size();
- job_queue_size += num_jobs * sizeof(proc_job_t);
- ps_mem_rec->u4_mem_size = job_queue_size;
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_JOBQ,
- ps_mem_rec->u4_mem_size);
- }
-
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_MAP];
- ps_mem_rec->u4_mem_size = max_ctb_cnt;
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_MAP,
- ps_mem_rec->u4_mem_size);
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
- ps_mem_rec->u4_mem_size = max_ctb_cnt;
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_MAP,
- ps_mem_rec->u4_mem_size);
-
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_DISP_MGR];
-
- /* size for holding display manager context */
- ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DISP_MGR,
- ps_mem_rec->u4_mem_size);
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
-
- /* size for holding dpb manager context */
- ps_mem_rec->u4_mem_size = sizeof(dpb_mgr_t);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DPB_MGR,
- ps_mem_rec->u4_mem_size);
-
- /** Holds top and left neighbor's pu idx into picture level pu array */
- /* Only one top row is enough but left has to be replicated for each process context */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PIC_PU_IDX_NEIGHBOR];
-
- ps_mem_rec->u4_mem_size = (max_num_4x4_cols /* left */ + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4)/* top */ + 1/* top right */) * sizeof(WORD32);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PIC_PU_IDX_NEIGHBOR,
- ps_mem_rec->u4_mem_size);
-
-
+ WORD32 inter_pred_tmp_buf_size, ntaps_luma;
+ WORD32 pic_pu_idx_map_size;
- /* TO hold scratch buffers needed for each process context */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
- {
- WORD32 size = 0;
- WORD32 inter_pred_tmp_buf_size;
- WORD32 ntaps_luma;
- WORD32 pu_map_size;
- WORD32 sao_size = 0;
+ /* Max inter pred size */
ntaps_luma = 8;
-
- /* Max inter pred size (number of bytes) */
inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE;
- inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size);
-
-
- /* To hold pu_index w.r.t. frame level pu_t array for a CTB at 4x4 level*/
- /* 16 x 16 4x4 in a CTB of size 64 x 64 and two extra needed for holding
- * neighbors
- */
- pu_map_size = sizeof(WORD32) * (18 * 18);
-
- pu_map_size = ALIGN64(pu_map_size);
- size += pu_map_size;
- /* To hold inter pred temporary buffers */
- size += 2 * inter_pred_tmp_buf_size;
-
-
- /* Allocate for each process context */
- size *= MAX_PROCESS_THREADS;
-
-
- /* To hold SAO left buffer for luma */
- sao_size += sizeof(UWORD8) * (MAX(max_ht_luma, max_wd_luma));
-
- /* To hold SAO left buffer for chroma */
- sao_size += sizeof(UWORD8) * (MAX(max_ht_luma, max_wd_luma));
-
- /* To hold SAO top buffer for luma */
- sao_size += sizeof(UWORD8) * max_wd_luma;
-
- /* To hold SAO top buffer for chroma */
- sao_size += sizeof(UWORD8) * max_wd_luma;
-
- /* To hold SAO top left luma pixel value for last output ctb in a row*/
- sao_size += sizeof(UWORD8) * max_ctb_rows;
-
- /* To hold SAO top left chroma pixel value last output ctb in a row*/
- sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
-
- /* To hold SAO top left pixel luma for current ctb - column array*/
- sao_size += sizeof(UWORD8) * max_ctb_rows;
-
- /* To hold SAO top left pixel chroma for current ctb-column array*/
- sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
-
- /* To hold SAO top right pixel luma pixel value last output ctb in a row*/
- sao_size += sizeof(UWORD8) * max_ctb_cols;
-
- /* To hold SAO top right pixel chroma pixel value last output ctb in a row*/
- sao_size += sizeof(UWORD8) * max_ctb_cols * 2;
-
- /*To hold SAO botton bottom left pixels for luma*/
- sao_size += sizeof(UWORD8) * max_ctb_rows;
-
- /*To hold SAO botton bottom left pixels for luma*/
- sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
- sao_size = ALIGN64(sao_size);
- size += sao_size;
- ps_mem_rec->u4_mem_size = size;
- }
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_SCRATCH,
- ps_mem_rec->u4_mem_size);
-
- /* TO hold scratch buffers needed for each SAO context */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO_SCRATCH];
- {
- WORD32 size = 0;
-
- size = 4 * MAX_CTB_SIZE * MAX_CTB_SIZE;
+ inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size);
- /* 2 temporary buffers*/
- size *= 2;
+ /* To hold pu_index w.r.t. frame level pu_t array for a CTB */
+ pic_pu_idx_map_size = sizeof(WORD32) * (18 * 18);
+ pic_pu_idx_map_size = ALIGN64(pic_pu_idx_map_size);
+ size = inter_pred_tmp_buf_size * 2;
+ size += pic_pu_idx_map_size;
size *= MAX_PROCESS_THREADS;
- ps_mem_rec->u4_mem_size = size;
- }
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SAO_SCRATCH,
- ps_mem_rec->u4_mem_size);
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
- {
- WORD32 size = 0;
- WORD32 vert_bs_size, horz_bs_size;
- WORD32 qp_const_flag_size;
- WORD32 qp_size, num_8x8;
-
- /* Max Number of vertical edges */
- vert_bs_size = max_wd_luma / 8 + 2 * MAX_CTB_SIZE / 8;
-
- /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */
- vert_bs_size *= (max_ht_luma + MAX_CTB_SIZE) / MIN_TU_SIZE;
-
- /* Number of bytes */
- vert_bs_size /= 8;
-
- /* Two bits per edge */
- vert_bs_size *= 2;
-
- /* Max Number of horizontal edges */
- horz_bs_size = max_ht_luma / 8 + MAX_CTB_SIZE / 8;
+ pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pu1_buf), IV_FAIL);
- /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */
- horz_bs_size *= (max_wd_luma + MAX_CTB_SIZE) / MIN_TU_SIZE;
-
- /* Number of bytes */
- horz_bs_size /= 8;
-
- /* Two bits per edge */
- horz_bs_size *= 2;
- /* Max CTBs in a row */
- qp_const_flag_size = max_wd_luma / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/;
-
- /* Max CTBs in a column */
- qp_const_flag_size *= max_ht_luma / MIN_CTB_SIZE;
-
- /* Number of bytes */
- qp_const_flag_size = (qp_const_flag_size + 7) >> 3;
-
- /* QP changes at CU level - So store at 8x8 level */
- num_8x8 = (max_ht_luma * max_wd_luma) / (MIN_CU_SIZE * MIN_CU_SIZE);
- qp_size = num_8x8;
-
- /* To hold vertical boundary strength */
- size += vert_bs_size;
-
- /* To hold horizontal boundary strength */
- size += horz_bs_size;
-
- /* To hold QP */
- size += qp_size;
-
- /* To hold QP const in CTB flags */
- size += qp_const_flag_size;
-
- ps_mem_rec->u4_mem_size = size;
- }
-
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BS_QP,
- ps_mem_rec->u4_mem_size);
+ for(i = 0; i < MAX_PROCESS_THREADS; i++)
+ {
+ ps_codec->as_process[i].pi2_inter_pred_tmp_buf1 = (WORD16 *)pu1_buf;
+ pu1_buf += inter_pred_tmp_buf_size;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE_IDX];
- {
- WORD32 size = 0;
- /* Max CTBs in a row */
- size = max_wd_luma / MIN_CTB_SIZE + 2 /* Top row and bottom row extra. This ensures accessing left,top in first row
- and right in last row will not result in invalid access*/;
- /* Max CTBs in a column */
- size *= max_ht_luma / MIN_CTB_SIZE;
+ ps_codec->as_process[i].pi2_inter_pred_tmp_buf2 = (WORD16 *)pu1_buf;
+ pu1_buf += inter_pred_tmp_buf_size;
- size *= sizeof(UWORD16);
- ps_mem_rec->u4_mem_size = size;
- }
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TILE_IDX,
- ps_mem_rec->u4_mem_size);
+ /* Inverse transform intermediate and inverse scan output buffers reuse inter pred scratch buffers */
+ ps_codec->as_process[i].pi2_itrans_intrmd_buf =
+ ps_codec->as_process[i].pi2_inter_pred_tmp_buf2;
+ ps_codec->as_process[i].pi2_invscan_out =
+ ps_codec->as_process[i].pi2_inter_pred_tmp_buf1;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO];
- {
- UWORD32 size;
+ ps_codec->as_process[i].pu4_pic_pu_idx_map = (UWORD32 *)pu1_buf;
+ ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx_map =
+ (UWORD32 *)pu1_buf;
+ pu1_buf += pic_pu_idx_map_size;
- /* 4 bytes per color component per CTB */
- size = 3 * 4;
+ // ps_codec->as_process[i].pi2_inter_pred_tmp_buf3 = (WORD16 *)pu1_buf;
+ // pu1_buf += inter_pred_tmp_buf_size;
- /* MAX number of CTBs in a row */
- size *= max_wd_luma / MIN_CTB_SIZE;
+ ps_codec->as_process[i].i4_inter_pred_tmp_buf_strd = MAX_CTB_SIZE;
- /* MAX number of CTBs in a column */
- size *= max_ht_luma / MIN_CTB_SIZE;
- ps_mem_rec->u4_mem_size = size;
+ }
}
-
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SAO,
- ps_mem_rec->u4_mem_size);
-
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
-
- /* size for holding buffer manager context */
- ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
-
- /* Size for holding pic_buf_t for each reference picture */
- /* Note this allocation is done for BUF_MGR_MAX_CNT instead of
- * max_dpb_size or MAX_DPB_SIZE for following reasons
- * max_dpb_size will be based on max_wd and max_ht
- * For higher max_wd and max_ht this number will be smaller than MAX_DPB_SIZE
- * But during actual initialization number of buffers allocated can be more
- *
- * Also to handle display depth application can allocate more than what
- * codec asks for in case of non-shared mode
- * Since this is only a structure allocation and not actual buffer allocation,
- * it is allocated for BUF_MGR_MAX_CNT entries
- */
- ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
-
- /* In case of non-shared mode allocate for reference picture buffers */
- /* In case of shared and 420p output, allocate for chroma samples */
- if((0 == share_disp_buf) || (chroma_format == IV_YUV_420P))
+ /* Initialize pointers in PPS structures */
{
- UWORD32 init_num_bufs;
- UWORD32 init_extra_bufs;
- WORD32 chroma_only;
-
- chroma_only = 0;
- init_extra_bufs = 0;
- init_num_bufs = num_reorder_frames + num_ref_frames + 1;
+ sps_t *ps_sps = ps_codec->ps_sps_base;
+ pps_t *ps_pps = ps_codec->ps_pps_base;
+ WORD16 *pi2_scaling_mat = ps_codec->pi2_scaling_mat;
+ WORD32 scaling_mat_size;
- /* In case of shared display buffers and chroma format 420P
- * Allocate for chroma in reference buffers, luma buffer will be display buffer
- */
+ SCALING_MAT_SIZE(scaling_mat_size);
- if((1 == share_disp_buf) && (chroma_format == IV_YUV_420P))
+ for(i = 0; i < MAX_SPS_CNT; i++)
{
- chroma_only = 1;
- init_extra_bufs = num_extra_disp_bufs;
+ ps_sps->pi2_scaling_mat = pi2_scaling_mat;
+ pi2_scaling_mat += scaling_mat_size;
+ ps_sps++;
}
- /* Note: Number of luma samples is not max_wd * max_ht here, instead it is
- * set to maximum number of luma samples allowed at the given level.
- * This is done to ensure that any stream with width and height lesser
- * than max_wd and max_ht is supported. Number of buffers required can be greater
- * for lower width and heights at a given level and this increased number of buffers
- * might require more memory than what max_wd and max_ht buffer would have required
- * Number of buffers is doubled in order to return one frame at a time instead of sending
- * multiple outputs during dpb full case.
- * Also note one extra buffer is allocted to store current picture
- * In case of asynchronous parsing and processing, number of buffers should increase here
- * based on when parsing and processing threads are synchronized
- */
- ps_mem_rec->u4_mem_size +=
- ihevcd_get_total_pic_buf_size(max_wd_luma * max_ht_luma, level, PAD_WD, PAD_HT,
- init_num_bufs, init_extra_bufs, chroma_only);
- }
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_REF_PIC,
- ps_mem_rec->u4_mem_size);
-
- /* Request memory to hold mem records to be returned during retrieve call */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
- ps_mem_rec->u4_mem_size = MEM_REC_CNT * sizeof(iv_mem_rec_t);
- DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BACKUP,
- ps_mem_rec->u4_mem_size);
-
- /* Each memtab size is aligned to next multiple of 128 bytes */
- /* This is to ensure all the memtabs start at different cache lines */
- ps_mem_rec = ps_mem_rec_base;
- for(i = 0; i < MEM_REC_CNT; i++)
- {
- ps_mem_rec->u4_mem_size = ALIGN128(ps_mem_rec->u4_mem_size);
- ps_mem_rec++;
- }
- ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled = MEM_REC_CNT;
-#ifdef APPLY_CONCEALMENT
- {
- IV_API_CALL_STATUS_T status;
- icncl_fill_mem_rec_ip_t cncl_fill_ip;
- icncl_fill_mem_rec_op_t cncl_fill_op;
- UWORD8 mem_loc = MEM_REC_CNT;
-
- cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
- cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = &(memTab[mem_loc]);
- cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_size = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size;
- cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = max_wd_luma;
- cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = max_ht_luma;
-
- status = icncl_api_function(NULL, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
-
- if(IV_SUCCESS == status)
+ for(i = 0; i < MAX_PPS_CNT; i++)
{
- icncl_num_mem_rec_ip_t cncl_mem_ip;
- icncl_num_mem_rec_op_t cncl_mem_op;
-
- cncl_mem_ip.s_ivd_num_rec_ip_t.e_cmd = IV_CMD_GET_NUM_MEM_REC;
- cncl_mem_ip.s_ivd_num_rec_ip_t.u4_size = sizeof(icncl_num_mem_rec_ip_t);
-
- status = icncl_api_function(NULL, (void *)&cncl_mem_ip, (void *)&cncl_mem_op);
- if(IV_SUCCESS == status)
- {
- ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled += cncl_mem_op.s_ivd_num_mem_rec_op_t.u4_num_mem_rec;
- }
+ ps_pps->pi2_scaling_mat = pi2_scaling_mat;
+ pi2_scaling_mat += scaling_mat_size;
+ ps_pps++;
}
-
- return status;
-
}
-#endif //APPLY_CONCEALMENT
- DEBUG("Num mem recs in fill call : %d\n",
- ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled);
-
return (status);
}
-
/**
*******************************************************************************
*
* @brief
-* Initializes from mem records passed to the codec
+* Free static memory for the codec
*
* @par Description:
-* Initializes pointers based on mem records passed
-*
-* @param[in] ps_codec_obj
-* Pointer to codec object at API level
+* Free static memory for the codec
*
-* @param[in] pv_api_ip
-* Pointer to input argument structure
-*
-* @param[out] pv_api_op
-* Pointer to output argument structure
+* @param[in] ps_codec
+* Pointer to codec context
*
* @returns Status
*
@@ -2458,212 +1379,164 @@ WORD32 ihevcd_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op)
*
*******************************************************************************
*/
-WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
- void *pv_api_ip,
- void *pv_api_op)
+WORD32 ihevcd_free_static_bufs(iv_obj_t *ps_codec_obj)
{
-
- ihevcd_cxa_init_ip_t *dec_init_ip;
- ihevcd_cxa_init_op_t *dec_init_op;
- WORD32 i;
- iv_mem_rec_t *ps_mem_rec, *ps_mem_rec_base;
- WORD32 status = IV_SUCCESS;
codec_t *ps_codec;
- WORD32 max_tile_cols, max_tile_rows;
- dec_init_ip = (ihevcd_cxa_init_ip_t *)pv_api_ip;
- dec_init_op = (ihevcd_cxa_init_op_t *)pv_api_op;
+ void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
+ void *pv_mem_ctxt;
- ps_mem_rec_base = dec_init_ip->s_ivd_init_ip_t.pv_mem_rec_location;
+ ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
+ pf_aligned_free = ps_codec->pf_aligned_free;
+ pv_mem_ctxt = ps_codec->pv_mem_ctxt;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
- ps_codec_obj->pv_codec_handle = ps_mem_rec->pv_base;
- ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
+ ALIGNED_FREE(ps_codec, ps_codec->apv_process_thread_handle[0]);
+ ALIGNED_FREE(ps_codec, ps_codec->pu1_bitsbuf_static);
- /* Note this memset can not be done in init() call, since init will called
- during reset as well. And calling this during reset will mean all pointers
- need to reinitialized*/
- memset(ps_codec, 0, sizeof(codec_t));
+ ALIGNED_FREE(ps_codec, ps_codec->pv_disp_buf_mgr);
+ ALIGNED_FREE(ps_codec, ps_codec->pv_dpb_mgr);
+ ALIGNED_FREE(ps_codec, ps_codec->pv_pic_buf_mgr);
+ ALIGNED_FREE(ps_codec, ps_codec->pv_mv_buf_mgr);
+ ALIGNED_FREE(ps_codec, ps_codec->ps_vps_base);
+ ALIGNED_FREE(ps_codec, ps_codec->ps_sps_base);
+ ALIGNED_FREE(ps_codec, ps_codec->ps_pps_base);
+ ALIGNED_FREE(ps_codec, ps_codec->ps_slice_hdr_base);
+ ALIGNED_FREE(ps_codec, ps_codec->pi2_scaling_mat);
+ ALIGNED_FREE(ps_codec, ps_codec->pv_pic_buf_base);
+ ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu1_luma_intra_pred_mode_left);
+ ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_sao_ctxt.pu1_tmp_buf_luma);
+ ALIGNED_FREE(ps_codec, ps_codec->as_process[0].pi2_inter_pred_tmp_buf1);
+ ALIGNED_FREE(ps_codec, ps_codec_obj->pv_codec_handle);
- if(dec_init_ip->s_ivd_init_ip_t.u4_size
- > offsetof(ihevcd_cxa_init_ip_t, i4_level))
+ if(ps_codec_obj)
{
- ps_codec->i4_init_level = dec_init_ip->i4_level;
-
- ps_codec->i4_init_level *= 3;
- }
- else
- {
- ps_codec->i4_init_level = MAX_LEVEL;
+ pf_aligned_free(pv_mem_ctxt, ps_codec_obj);
}
- if(dec_init_ip->s_ivd_init_ip_t.u4_size
- > offsetof(ihevcd_cxa_init_ip_t, u4_num_ref_frames))
- {
- ps_codec->i4_init_num_ref = dec_init_ip->u4_num_ref_frames;
- }
- else
- {
- ps_codec->i4_init_num_ref = MAX_REF_CNT;
- }
-
- if(dec_init_ip->s_ivd_init_ip_t.u4_size
- > offsetof(ihevcd_cxa_init_ip_t, u4_num_reorder_frames))
- {
- ps_codec->i4_init_num_reorder = dec_init_ip->u4_num_reorder_frames;
- }
- else
- {
- ps_codec->i4_init_num_reorder = MAX_REF_CNT;
- }
-
- if(dec_init_ip->s_ivd_init_ip_t.u4_size
- > offsetof(ihevcd_cxa_init_ip_t, u4_num_extra_disp_buf))
- {
- ps_codec->i4_init_num_extra_disp_buf =
- dec_init_ip->u4_num_extra_disp_buf;
- }
- else
- {
- ps_codec->i4_init_num_extra_disp_buf = 0;
- }
-
- if(dec_init_ip->s_ivd_init_ip_t.u4_size
- > offsetof(ihevcd_cxa_init_ip_t, u4_share_disp_buf))
- {
-#ifndef LOGO_EN
- ps_codec->i4_share_disp_buf = dec_init_ip->u4_share_disp_buf;
-#else
- ps_codec->i4_share_disp_buf = 0;
-#endif
- }
- else
- {
- ps_codec->i4_share_disp_buf = 0;
- }
- /* Shared display mode is supported only for 420SP and 420P formats */
- if((dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P) &&
- (dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420SP_UV) &&
- (dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420SP_VU))
- {
- ps_codec->i4_share_disp_buf = 0;
- }
-
- if((ps_codec->i4_init_level < MIN_LEVEL)
- || (ps_codec->i4_init_level > MAX_LEVEL))
- {
- dec_init_op->s_ivd_init_op_t.u4_error_code |= IHEVCD_LEVEL_UNSUPPORTED;
- return (IV_FAIL);
- }
-
- if(ps_codec->i4_init_num_ref > MAX_REF_CNT)
- {
- dec_init_op->s_ivd_init_op_t.u4_error_code |=
- IHEVCD_NUM_REF_UNSUPPORTED;
- ps_codec->i4_init_num_ref = MAX_REF_CNT;
- }
-
- if(ps_codec->i4_init_num_reorder > MAX_REF_CNT)
- {
- dec_init_op->s_ivd_init_op_t.u4_error_code |=
- IHEVCD_NUM_REORDER_UNSUPPORTED;
- ps_codec->i4_init_num_reorder = MAX_REF_CNT;
- }
-
- if(ps_codec->i4_init_num_extra_disp_buf > MAX_REF_CNT)
- {
- dec_init_op->s_ivd_init_op_t.u4_error_code |=
- IHEVCD_NUM_EXTRA_DISP_UNSUPPORTED;
- ps_codec->i4_init_num_extra_disp_buf = 0;
- }
-
- ps_codec->e_chroma_fmt = dec_init_ip->s_ivd_init_ip_t.e_output_format;
-
- ps_codec->i4_max_wd = dec_init_ip->s_ivd_init_ip_t.u4_frm_max_wd;
- ps_codec->i4_max_ht = dec_init_ip->s_ivd_init_ip_t.u4_frm_max_ht;
-
- ps_codec->i4_max_wd = ALIGN64(ps_codec->i4_max_wd);
- ps_codec->i4_max_ht = ALIGN64(ps_codec->i4_max_ht);
-
- ps_codec->i4_new_max_wd = ps_codec->i4_max_wd;
- ps_codec->i4_new_max_ht = ps_codec->i4_max_ht;
-
- max_tile_cols = (ps_codec->i4_max_wd + MIN_TILE_WD - 1) / MIN_TILE_WD;
- max_tile_rows = (ps_codec->i4_max_ht + MIN_TILE_HT - 1) / MIN_TILE_HT;
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
- ps_codec->ps_mem_rec_backup = (iv_mem_rec_t *)ps_mem_rec->pv_base;
-
- memcpy(ps_codec->ps_mem_rec_backup, ps_mem_rec_base,
- MEM_REC_CNT * sizeof(iv_mem_rec_t));
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_BITSBUF];
- ps_codec->pu1_bitsbuf = (UWORD8 *)ps_mem_rec->pv_base;
- ps_codec->u4_bitsbuf_size = ps_mem_rec->u4_mem_size;
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_TU_DATA];
- ps_codec->pv_tu_data = ps_mem_rec->pv_base;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
- ps_codec->pv_mv_buf_mgr = ps_mem_rec->pv_base;
- ps_codec->pv_mv_bank_buf_base = (UWORD8 *)ps_codec->pv_mv_buf_mgr + sizeof(buf_mgr_t);
-
- ps_codec->i4_total_mv_bank_size = ps_mem_rec->u4_mem_size - sizeof(buf_mgr_t);
-
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_VPS];
- ps_codec->ps_vps_base = (vps_t *)ps_mem_rec->pv_base;
- ps_codec->s_parse.ps_vps_base = ps_codec->ps_vps_base;
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
- ps_codec->ps_sps_base = (sps_t *)ps_mem_rec->pv_base;
- ps_codec->s_parse.ps_sps_base = ps_codec->ps_sps_base;
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
- ps_codec->ps_pps_base = (pps_t *)ps_mem_rec->pv_base;
- ps_codec->s_parse.ps_pps_base = ps_codec->ps_pps_base;
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
- ps_codec->ps_slice_hdr_base = (slice_header_t *)ps_mem_rec->pv_base;
- ps_codec->s_parse.ps_slice_hdr_base = ps_codec->ps_slice_hdr_base;
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE];
- ps_codec->ps_tile = (tile_t *)ps_mem_rec->pv_base;
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTRY_OFST];
- ps_codec->pi4_entry_ofst = (WORD32 *)ps_mem_rec->pv_base;
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_SCALING_MAT];
- ps_codec->pi2_scaling_mat = (WORD16 *)ps_mem_rec->pv_base;
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_SKIP_FLAG];
- ps_codec->s_parse.pu4_skip_cu_top = (UWORD32 *)ps_mem_rec->pv_base;
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_CT_DEPTH];
- ps_codec->s_parse.pu4_ct_depth_top = (UWORD32 *)ps_mem_rec->pv_base;
-
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_INTRA_PRED_MODE];
- ps_codec->s_parse.pu1_luma_intra_pred_mode_left =
- (UWORD8 *)ps_mem_rec->pv_base;
- ps_codec->s_parse.pu1_luma_intra_pred_mode_top =
- (UWORD8 *)ps_mem_rec->pv_base + 16;
+ return IV_SUCCESS;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_FLAG];
+}
- memset(ps_mem_rec->pv_base, 0, (ps_codec->i4_max_wd / MIN_CU_SIZE) * (ps_codec->i4_max_ht / MIN_CU_SIZE) / 8);
- ps_codec->pu1_pic_intra_flag = (UWORD8 *)ps_mem_rec->pv_base;
+/**
+*******************************************************************************
+*
+* @brief
+* Allocate dynamic memory for the codec
+*
+* @par Description:
+* Allocates dynamic memory for the codec
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @returns Status
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec)
+{
+ WORD32 max_tile_cols, max_tile_rows;
+ WORD32 max_ctb_rows, max_ctb_cols;
+ WORD32 max_num_cu_cols;
+ WORD32 max_num_cu_rows;
+ WORD32 max_num_4x4_cols;
+ WORD32 max_ctb_cnt;
+ WORD32 wd;
+ WORD32 ht;
+ WORD32 i;
+ WORD32 max_dpb_size;
+ void *pv_mem_ctxt = ps_codec->pv_mem_ctxt;
+ void *pv_buf;
+ UWORD8 *pu1_buf;
+ WORD32 size;
+
+ wd = ALIGN64(ps_codec->i4_wd);
+ ht = ALIGN64(ps_codec->i4_ht);
+
+ max_tile_cols = (wd + MIN_TILE_WD - 1) / MIN_TILE_WD;
+ max_tile_rows = (ht + MIN_TILE_HT - 1) / MIN_TILE_HT;
+ max_ctb_rows = ht / MIN_CTB_SIZE;
+ max_ctb_cols = wd / MIN_CTB_SIZE;
+ max_ctb_cnt = max_ctb_rows * max_ctb_cols;
+ max_num_cu_cols = wd / MIN_CU_SIZE;
+ max_num_cu_rows = ht / MIN_CU_SIZE;
+ max_num_4x4_cols = wd / 4;
+
+ /* Allocate tile structures */
+ size = max_tile_cols * max_tile_rows;
+ size *= sizeof(tile_t);
+ size *= MAX_PPS_CNT;
+
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_codec->ps_tile = (tile_t *)pv_buf;
+
+
+ /* Allocate memory to hold entry point offsets */
+ /* One entry point per tile */
+ size = max_tile_cols * max_tile_rows;
+
+ /* One entry point per row of CTBs */
+ /*********************************************************************/
+ /* Only tiles or entropy sync is enabled at a time in main */
+ /* profile, but since memory required does not increase too much, */
+ /* this allocation is done to handle both cases */
+ /*********************************************************************/
+ size += max_ctb_rows;
+ size *= sizeof(WORD32);
+
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_codec->pi4_entry_ofst = (WORD32 *)pv_buf;
+
+ /* Allocate parse skip flag buffer */
+ /* 1 bit per 8x8 */
+ size = max_num_cu_cols / 8;
+ size = ALIGN4(size);
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_codec->s_parse.pu4_skip_cu_top = (UWORD32 *)pv_buf;
+
+ /* Allocate parse coding tree depth buffer */
+ /* 2 bits per 8x8 */
+ size = max_num_cu_cols / 4;
+ size = ALIGN4(size);
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_codec->s_parse.pu4_ct_depth_top = (UWORD32 *)pv_buf;
+
+ /* Allocate intra flag buffer */
+ /* 1 bit per 8x8 */
+ size = max_num_cu_cols * max_num_cu_rows / 8;
+ size = ALIGN4(size);
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_codec->pu1_pic_intra_flag = (UWORD8 *)pv_buf;
ps_codec->s_parse.pu1_pic_intra_flag = ps_codec->pu1_pic_intra_flag;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_TRANSQUANT_BYPASS_FLAG];
-
- {
- WORD32 loop_filter_size = ((ps_codec->i4_max_wd + 64) / MIN_CU_SIZE) * ((ps_codec->i4_max_ht + 64) / MIN_CU_SIZE) / 8;
- WORD32 loop_filter_strd = (ps_codec->i4_max_wd + 63) >> 6;
-
- memset(ps_mem_rec->pv_base, 0, loop_filter_size);
+ /* Allocate transquant bypass flag buffer */
+ /* 1 bit per 8x8 */
+ /* Extra row and column are allocated for easy processing of top and left blocks while loop filtering */
+ size = ((max_num_cu_cols + 8) * (max_num_cu_rows + 8)) / 8;
+ size = ALIGN4(size);
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 1, size);
+ {
+ WORD32 loop_filter_strd = (wd + 63) >> 6;
+ ps_codec->pu1_pic_no_loop_filter_flag_base = pv_buf;
/* The offset is added for easy processing of top and left blocks while loop filtering */
- ps_codec->pu1_pic_no_loop_filter_flag = (UWORD8 *)ps_mem_rec->pv_base + loop_filter_strd + 1;
+ ps_codec->pu1_pic_no_loop_filter_flag = (UWORD8 *)pv_buf + loop_filter_strd + 1;
ps_codec->s_parse.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
ps_codec->s_parse.s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
ps_codec->s_parse.s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
@@ -2671,156 +1544,158 @@ WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
/* Initialize pointers in PPS structures */
{
- sps_t *ps_sps = ps_codec->ps_sps_base;
pps_t *ps_pps = ps_codec->ps_pps_base;
tile_t *ps_tile = ps_codec->ps_tile;
- WORD16 *pi2_scaling_mat = ps_codec->pi2_scaling_mat;
- WORD32 scaling_mat_size;
-
- SCALING_MAT_SIZE(scaling_mat_size);
-
- for(i = 0; i < MAX_SPS_CNT; i++)
- {
- ps_sps->pi2_scaling_mat = pi2_scaling_mat;
- pi2_scaling_mat += scaling_mat_size;
- ps_sps++;
- }
for(i = 0; i < MAX_PPS_CNT; i++)
{
ps_pps->ps_tile = ps_tile;
ps_tile += (max_tile_cols * max_tile_rows);
-
- ps_pps->pi2_scaling_mat = pi2_scaling_mat;
- pi2_scaling_mat += scaling_mat_size;
ps_pps++;
}
}
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
- for(i = 0; i < MAX_PROCESS_THREADS; i++)
- {
- WORD32 handle_size = ithread_get_handle_size();
- ps_codec->apv_process_thread_handle[i] =
- (UWORD8 *)ps_mem_rec->pv_base + (i * handle_size);
- }
+ /* Allocate memory for job queue */
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
- ps_codec->pv_proc_jobq_buf = ps_mem_rec->pv_base;
- ps_codec->i4_proc_jobq_buf_size = ps_mem_rec->u4_mem_size;
+ /* One job per row of CTBs */
+ size = max_ctb_rows;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_MAP];
- ps_codec->pu1_parse_map = (UWORD8 *)ps_mem_rec->pv_base;
+ /* One each tile a row of CTBs, num_jobs has to incremented */
+ size *= max_tile_cols;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
- ps_codec->pu1_proc_map = (UWORD8 *)ps_mem_rec->pv_base;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_DISP_MGR];
- ps_codec->pv_disp_buf_mgr = ps_mem_rec->pv_base;
+ /* One format convert/frame copy job per row of CTBs for non-shared mode*/
+ size += max_ctb_rows;
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
- ps_codec->pv_dpb_mgr = ps_mem_rec->pv_base;
+ size *= sizeof(proc_job_t);
+ size += ihevcd_jobq_ctxt_size();
+ size = ALIGN4(size);
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PIC_PU_IDX_NEIGHBOR];
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->pv_proc_jobq_buf = pv_buf;
+ ps_codec->i4_proc_jobq_buf_size = size;
+
+ size = max_ctb_cnt;
+ size = ALIGN4(size);
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_codec->pu1_parse_map = (UWORD8 *)pv_buf;
+
+ size = max_ctb_cnt;
+ size = ALIGN4(size);
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+ ps_codec->pu1_proc_map = (UWORD8 *)pv_buf;
+
+ /** Holds top and left neighbor's pu idx into picture level pu array */
+ /* Only one top row is enough but left has to be replicated for each process context */
+ size = (max_num_4x4_cols /* left */ + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4)/* top */ + 1/* top right */) * sizeof(WORD32);
+ size = ALIGN4(size);
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
- UWORD32 *pu4_buf = (UWORD32 *)ps_mem_rec->pv_base;
+ UWORD32 *pu4_buf = (UWORD32 *)pv_buf;
ps_codec->as_process[i].pu4_pic_pu_idx_left = pu4_buf + i * (MAX_CTB_SIZE / 4);
memset(ps_codec->as_process[i].pu4_pic_pu_idx_left, 0, sizeof(UWORD32) * MAX_CTB_SIZE / 4);
ps_codec->as_process[i].pu4_pic_pu_idx_top = pu4_buf + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4);
}
- memset(ps_codec->as_process[0].pu4_pic_pu_idx_top, 0, sizeof(UWORD32) * (ps_codec->i4_max_wd / 4 + 1));
-
+ memset(ps_codec->as_process[0].pu4_pic_pu_idx_top, 0, sizeof(UWORD32) * (wd / 4 + 1));
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
{
- UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
- WORD32 pic_pu_idx_map_size;
+ /* To hold SAO left buffer for luma */
+ size = sizeof(UWORD8) * (MAX(ht, wd));
- WORD32 inter_pred_tmp_buf_size, ntaps_luma;
+ /* To hold SAO left buffer for chroma */
+ size += sizeof(UWORD8) * (MAX(ht, wd));
- /* Max inter pred size */
- ntaps_luma = 8;
- inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE;
+ /* To hold SAO top buffer for luma */
+ size += sizeof(UWORD8) * wd;
- inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size);
+ /* To hold SAO top buffer for chroma */
+ size += sizeof(UWORD8) * wd;
- /* To hold pu_index w.r.t. frame level pu_t array for a CTB */
- pic_pu_idx_map_size = sizeof(WORD32) * (18 * 18);
- pic_pu_idx_map_size = ALIGN64(pic_pu_idx_map_size);
- for(i = 0; i < MAX_PROCESS_THREADS; i++)
- {
- ps_codec->as_process[i].pi2_inter_pred_tmp_buf1 = (WORD16 *)pu1_buf;
- pu1_buf += inter_pred_tmp_buf_size;
+ /* To hold SAO top left luma pixel value for last output ctb in a row*/
+ size += sizeof(UWORD8) * max_ctb_rows;
- ps_codec->as_process[i].pi2_inter_pred_tmp_buf2 = (WORD16 *)pu1_buf;
- pu1_buf += inter_pred_tmp_buf_size;
+ /* To hold SAO top left chroma pixel value last output ctb in a row*/
+ size += sizeof(UWORD8) * max_ctb_rows * 2;
- /* Inverse transform intermediate and inverse scan output buffers reuse inter pred scratch buffers */
- ps_codec->as_process[i].pi2_itrans_intrmd_buf =
- ps_codec->as_process[i].pi2_inter_pred_tmp_buf2;
- ps_codec->as_process[i].pi2_invscan_out =
- ps_codec->as_process[i].pi2_inter_pred_tmp_buf1;
+ /* To hold SAO top left pixel luma for current ctb - column array*/
+ size += sizeof(UWORD8) * max_ctb_rows;
- ps_codec->as_process[i].pu4_pic_pu_idx_map = (UWORD32 *)pu1_buf;
- ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx_map =
- (UWORD32 *)pu1_buf;
- pu1_buf += pic_pu_idx_map_size;
+ /* To hold SAO top left pixel chroma for current ctb-column array*/
+ size += sizeof(UWORD8) * max_ctb_rows * 2;
- // ps_codec->as_process[i].pi2_inter_pred_tmp_buf3 = (WORD16 *)pu1_buf;
- // pu1_buf += inter_pred_tmp_buf_size;
+ /* To hold SAO top right pixel luma pixel value last output ctb in a row*/
+ size += sizeof(UWORD8) * max_ctb_cols;
- ps_codec->as_process[i].i4_inter_pred_tmp_buf_strd = MAX_CTB_SIZE;
+ /* To hold SAO top right pixel chroma pixel value last output ctb in a row*/
+ size += sizeof(UWORD8) * max_ctb_cols * 2;
+
+ /*To hold SAO botton bottom left pixels for luma*/
+ size += sizeof(UWORD8) * max_ctb_rows;
+
+ /*To hold SAO botton bottom left pixels for luma*/
+ size += sizeof(UWORD8) * max_ctb_rows * 2;
+ size = ALIGN64(size);
+
+ pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pu1_buf), IV_FAIL);
+ memset(pu1_buf, 0, size);
- }
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf;
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf;
- pu1_buf += MAX(ps_codec->i4_max_ht, ps_codec->i4_max_wd);
+ pu1_buf += MAX(ht, wd);
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf;
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf;
- pu1_buf += MAX(ps_codec->i4_max_ht, ps_codec->i4_max_wd);
+ pu1_buf += MAX(ht, wd);
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf;
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf;
- pu1_buf += ps_codec->i4_max_wd;
+ pu1_buf += wd;
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf;
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf;
- pu1_buf += ps_codec->i4_max_wd;
+ pu1_buf += wd;
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf;
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf;
- pu1_buf += ps_codec->i4_max_ht / MIN_CTB_SIZE;
+ pu1_buf += ht / MIN_CTB_SIZE;
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf;
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf;
- pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
+ pu1_buf += (ht / MIN_CTB_SIZE) * 2;
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf;
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf;
- pu1_buf += ps_codec->i4_max_ht / MIN_CTB_SIZE;
+ pu1_buf += ht / MIN_CTB_SIZE;
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
@@ -2828,21 +1703,21 @@ WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf;
- pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
+ pu1_buf += (ht / MIN_CTB_SIZE) * 2;
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf;
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf;
- pu1_buf += ps_codec->i4_max_wd / MIN_CTB_SIZE;
+ pu1_buf += wd / MIN_CTB_SIZE;
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf;
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf;
- pu1_buf += (ps_codec->i4_max_wd / MIN_CTB_SIZE) * 2;
+ pu1_buf += (wd / MIN_CTB_SIZE) * 2;
/*Per CTB, Store 1 value for luma , 2 values for chroma*/
for(i = 0; i < MAX_PROCESS_THREADS; i++)
@@ -2851,7 +1726,7 @@ WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf;
- pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE);
+ pu1_buf += (ht / MIN_CTB_SIZE);
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
@@ -2859,35 +1734,22 @@ WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
}
ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf;
- pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
+ pu1_buf += (ht / MIN_CTB_SIZE) * 2;
}
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO_SCRATCH];
- {
- UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
- for(i = 0; i < MAX_PROCESS_THREADS; i++)
- {
- ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_luma = (UWORD8 *)pu1_buf;
- pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
-
- ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_chroma = (UWORD8 *)pu1_buf;
- pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
- }
- }
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
{
- UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
+ UWORD8 *pu1_buf = (UWORD8 *)pv_buf;
WORD32 vert_bs_size, horz_bs_size;
WORD32 qp_const_flag_size;
WORD32 qp_size;
WORD32 num_8x8;
/* Max Number of vertical edges */
- vert_bs_size = ps_codec->i4_max_wd / 8 + 2 * MAX_CTB_SIZE / 8;
+ vert_bs_size = wd / 8 + 2 * MAX_CTB_SIZE / 8;
/* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */
- vert_bs_size *= (ps_codec->i4_max_ht + MAX_CTB_SIZE) / MIN_TU_SIZE;
+ vert_bs_size *= (ht + MAX_CTB_SIZE) / MIN_TU_SIZE;
/* Number of bytes */
vert_bs_size /= 8;
@@ -2896,10 +1758,10 @@ WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
vert_bs_size *= 2;
/* Max Number of horizontal edges */
- horz_bs_size = ps_codec->i4_max_ht / 8 + MAX_CTB_SIZE / 8;
+ horz_bs_size = ht / 8 + MAX_CTB_SIZE / 8;
/* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */
- horz_bs_size *= (ps_codec->i4_max_wd + MAX_CTB_SIZE) / MIN_TU_SIZE;
+ horz_bs_size *= (wd + MAX_CTB_SIZE) / MIN_TU_SIZE;
/* Number of bytes */
horz_bs_size /= 8;
@@ -2908,18 +1770,34 @@ WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
horz_bs_size *= 2;
/* Max CTBs in a row */
- qp_const_flag_size = ps_codec->i4_max_wd / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/;
+ qp_const_flag_size = wd / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/;
/* Max CTBs in a column */
- qp_const_flag_size *= ps_codec->i4_max_ht / MIN_CTB_SIZE;
+ qp_const_flag_size *= ht / MIN_CTB_SIZE;
/* Number of bytes */
qp_const_flag_size /= 8;
/* QP changes at CU level - So store at 8x8 level */
- num_8x8 = (ps_codec->i4_max_ht * ps_codec->i4_max_wd) / (MIN_CU_SIZE * MIN_CU_SIZE);
+ num_8x8 = (ht * wd) / (MIN_CU_SIZE * MIN_CU_SIZE);
qp_size = num_8x8;
- memset(pu1_buf, 0, vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size);
+
+ /* To hold vertical boundary strength */
+ size += vert_bs_size;
+
+ /* To hold horizontal boundary strength */
+ size += horz_bs_size;
+
+ /* To hold QP */
+ size += qp_size;
+
+ /* To hold QP const in CTB flags */
+ size += qp_const_flag_size;
+
+ pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pu1_buf), IV_FAIL);
+
+ memset(pu1_buf, 0, size);
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
@@ -2959,73 +1837,194 @@ WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
}
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE_IDX];
- {
- UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
+ /* Max CTBs in a row */
+ size = wd / MIN_CTB_SIZE + 2 /* Top row and bottom row extra. This ensures accessing left,top in first row
+ and right in last row will not result in invalid access*/;
+ /* Max CTBs in a column */
+ size *= ht / MIN_CTB_SIZE;
- for(i = 0; i < MAX_PROCESS_THREADS; i++)
- {
- ps_codec->as_process[i].pu1_tile_idx = (UWORD16 *)pu1_buf + ps_codec->i4_max_wd / MIN_CTB_SIZE /* Offset 1 row */;
- }
+ size *= sizeof(UWORD16);
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+
+ ps_codec->pu1_tile_idx_base = pv_buf;
+ for(i = 0; i < MAX_PROCESS_THREADS; i++)
+ {
+ ps_codec->as_process[i].pu1_tile_idx = (UWORD16 *)pv_buf + wd / MIN_CTB_SIZE /* Offset 1 row */;
}
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO];
- ps_codec->s_parse.ps_pic_sao = (sao_t *)ps_mem_rec->pv_base;
- ps_codec->s_parse.s_sao_ctxt.ps_pic_sao = (sao_t *)ps_mem_rec->pv_base;
+ /* 4 bytes per color component per CTB */
+ size = 3 * 4;
+
+ /* MAX number of CTBs in a row */
+ size *= wd / MIN_CTB_SIZE;
+
+ /* MAX number of CTBs in a column */
+ size *= ht / MIN_CTB_SIZE;
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ memset(pv_buf, 0, size);
+
+ ps_codec->s_parse.ps_pic_sao = (sao_t *)pv_buf;
+ ps_codec->s_parse.s_sao_ctxt.ps_pic_sao = (sao_t *)pv_buf;
for(i = 0; i < MAX_PROCESS_THREADS; i++)
{
ps_codec->as_process[i].s_sao_ctxt.ps_pic_sao = ps_codec->s_parse.ps_pic_sao;
}
- ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
- ps_codec->pv_pic_buf_mgr = ps_mem_rec->pv_base;
- ps_codec->pv_pic_buf_base = (UWORD8 *)ps_codec->pv_pic_buf_mgr + sizeof(buf_mgr_t);
- ps_codec->i4_total_pic_buf_size = ps_mem_rec->u4_mem_size - sizeof(buf_mgr_t);
- ps_codec->pu1_cur_chroma_ref_buf = (UWORD8 *)ps_codec->pv_pic_buf_base + BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
- ps_codec->i4_remaining_pic_buf_size = ps_codec->i4_total_pic_buf_size - BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
+ /* Only if width * height * 3 / 2 is greater than MIN_BITSBUF_SIZE,
+ then allocate dynamic bistream buffer */
+ ps_codec->pu1_bitsbuf_dynamic = NULL;
+ size = wd * ht;
+ if(size > MIN_BITSBUF_SIZE)
+ {
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->pu1_bitsbuf_dynamic = pv_buf;
+ ps_codec->u4_bitsbuf_size_dynamic = size;
+ }
+ size = ihevcd_get_tu_data_size(wd * ht);
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
+ ps_codec->pv_tu_data = pv_buf;
+ {
+ sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
-#ifdef APPLY_CONCEALMENT
- {
+ /* Allocate for pu_map, pu_t and pic_pu_idx for each MV bank */
+ /* Note: Number of luma samples is not max_wd * max_ht here, instead it is
+ * set to maximum number of luma samples allowed at the given level.
+ * This is done to ensure that any stream with width and height lesser
+ * than max_wd and max_ht is supported. Number of buffers required can be greater
+ * for lower width and heights at a given level and this increased number of buffers
+ * might require more memory than what max_wd and max_ht buffer would have required
+ * Also note one extra buffer is allocted to store current pictures MV bank
+ * In case of asynchronous parsing and processing, number of buffers should increase here
+ * based on when parsing and processing threads are synchronized
+ */
+ max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
+ /* Size for holding mv_buf_t for each MV Bank
+ * One extra MV Bank is needed to hold current pics MV bank.
+ */
+ size = (max_dpb_size + 1) * sizeof(mv_buf_t);
- UWORD32 mem_loc;
+ size += (max_dpb_size + 1) *
+ ihevcd_get_pic_mv_bank_size(wd * ht);
- icncl_init_ip_t cncl_init_ip;
- icncl_init_op_t cncl_init_op;
- iv_mem_rec_t *ps_mem_rec;
- DecStruct *ps_codec;
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
- ps_mem_rec = dec_init_ip->s_ivd_init_ip_t.pv_mem_rec_location;
- mem_loc = MEM_REC_CNT;
+ ps_codec->pv_mv_bank_buf_base = pv_buf;
+ ps_codec->i4_total_mv_bank_size = size;
- ps_codec->ps_conceal = (iv_obj_t *)ps_mem_rec[mem_loc].pv_base;
- ps_codec->i4_first_frame_done = 0;
+ }
- cncl_init_ip.u4_size = sizeof(icncl_init_ip_t);
- cncl_init_ip.pv_mem_rec_location = &(ps_mem_rec[mem_loc]);
- cncl_init_ip.e_cmd = IV_CMD_INIT;
+ /* In case of non-shared mode allocate for reference picture buffers */
+ /* In case of shared and 420p output, allocate for chroma samples */
+ if(0 == ps_codec->i4_share_disp_buf)
+ {
+ /* Number of buffers is doubled in order to return one frame at a time instead of sending
+ * multiple outputs during dpb full case.
+ * Also note one extra buffer is allocted to store current picture
+ * In case of asynchronous parsing and processing, number of buffers should increase here
+ * based on when parsing and processing threads are synchronized
+ */
+ size = ihevcd_get_total_pic_buf_size(ps_codec, wd, ht);
+ pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pv_buf), IV_FAIL);
- status = icncl_api_function(ps_codec->ps_conceal, (void *)&cncl_init_ip, (void *)&cncl_init_op);
+ ps_codec->i4_total_pic_buf_size = size;
+ ps_codec->pu1_ref_pic_buf_base = (UWORD8 *)pv_buf;
}
-#endif //APPLY_CONCEALMENT
- status = ihevcd_init(ps_codec);
+ ps_codec->pv_proc_jobq = ihevcd_jobq_init(ps_codec->pv_proc_jobq_buf, ps_codec->i4_proc_jobq_buf_size);
+ RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL);
- TRACE_INIT(NULL);
- STATS_INIT();
- return status;
+ /* Update the jobq context to all the threads */
+ ps_codec->s_parse.pv_proc_jobq = ps_codec->pv_proc_jobq;
+ for(i = 0; i < MAX_PROCESS_THREADS; i++)
+ {
+ ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq;
+ ps_codec->as_process[i].i4_id = i;
+ ps_codec->as_process[i].ps_codec = ps_codec;
+
+ /* Set the following to zero assuming it is a single core solution
+ * When threads are launched these will be set appropriately
+ */
+ ps_codec->as_process[i].i4_check_parse_status = 0;
+ ps_codec->as_process[i].i4_check_proc_status = 0;
+ }
+
+ ps_codec->u4_allocate_dynamic_done = 1;
+
+ return IV_SUCCESS;
}
+
/**
*******************************************************************************
*
* @brief
-* Retrieves mem records passed to the codec
+* Free dynamic memory for the codec
*
* @par Description:
-* Retrieves memrecs passed earlier
+* Free dynamic memory for the codec
+*
+* @param[in] ps_codec
+* Pointer to codec context
+*
+* @returns Status
+*
+* @remarks
+*
+*
+*******************************************************************************
+*/
+WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec)
+{
+
+ if(ps_codec->pv_proc_jobq)
+ {
+ ihevcd_jobq_deinit(ps_codec->pv_proc_jobq);
+ ps_codec->pv_proc_jobq = NULL;
+ }
+
+ ALIGNED_FREE(ps_codec, ps_codec->ps_tile);
+ ALIGNED_FREE(ps_codec, ps_codec->pi4_entry_ofst);
+ ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu4_skip_cu_top);
+ ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu4_ct_depth_top);
+ ALIGNED_FREE(ps_codec, ps_codec->pu1_pic_intra_flag);
+ ALIGNED_FREE(ps_codec, ps_codec->pu1_pic_no_loop_filter_flag_base);
+ ALIGNED_FREE(ps_codec, ps_codec->pv_proc_jobq_buf);
+ ALIGNED_FREE(ps_codec, ps_codec->pu1_parse_map);
+ ALIGNED_FREE(ps_codec, ps_codec->pu1_proc_map);
+ ALIGNED_FREE(ps_codec, ps_codec->as_process[0].pu4_pic_pu_idx_left);
+ ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_sao_ctxt.pu1_sao_src_left_luma);
+ ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_bs_ctxt.pu4_pic_vert_bs);
+ ALIGNED_FREE(ps_codec, ps_codec->pu1_tile_idx_base);
+ ALIGNED_FREE(ps_codec, ps_codec->s_parse.ps_pic_sao);
+ ALIGNED_FREE(ps_codec, ps_codec->pu1_bitsbuf_dynamic);
+ ALIGNED_FREE(ps_codec, ps_codec->pv_tu_data);
+ ALIGNED_FREE(ps_codec, ps_codec->pv_mv_bank_buf_base);
+ ALIGNED_FREE(ps_codec, ps_codec->pu1_ref_pic_buf_base);
+ ALIGNED_FREE(ps_codec, ps_codec->pu1_cur_chroma_ref_buf);
+
+ ps_codec->u4_allocate_dynamic_done = 0;
+ return IV_SUCCESS;
+}
+
+
+/**
+*******************************************************************************
+*
+* @brief
+* Initializes from mem records passed to the codec
+*
+* @par Description:
+* Initializes pointers based on mem records passed
*
* @param[in] ps_codec_obj
* Pointer to codec object at API level
@@ -3043,70 +2042,78 @@ WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
*
*******************************************************************************
*/
-WORD32 ihevcd_retrieve_memrec(iv_obj_t *ps_codec_obj,
- void *pv_api_ip,
- void *pv_api_op)
+WORD32 ihevcd_create(iv_obj_t *ps_codec_obj,
+ void *pv_api_ip,
+ void *pv_api_op)
{
- iv_retrieve_mem_rec_ip_t *dec_clr_ip;
- iv_retrieve_mem_rec_op_t *dec_clr_op;
+ ihevcd_cxa_create_op_t *ps_create_op;
+
+ WORD32 ret;
codec_t *ps_codec;
- 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_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
+ ps_create_op = (ihevcd_cxa_create_op_t *)pv_api_op;
- if(ps_codec->i4_init_done != 1)
- {
- dec_clr_op->u4_error_code |= 1 << IVD_FATALERROR;
- dec_clr_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
- return IV_FAIL;
- }
+ ps_create_op->s_ivd_create_op_t.u4_error_code = 0;
- memcpy(dec_clr_ip->pv_mem_rec_location, ps_codec->ps_mem_rec_backup,
- MEM_REC_CNT * (sizeof(iv_mem_rec_t)));
- dec_clr_op->u4_num_mem_rec_filled = MEM_REC_CNT;
+ ret = ihevcd_allocate_static_bufs(&ps_codec_obj, pv_api_ip, pv_api_op);
-#ifdef APPLY_CONCEALMENT
+ /* If allocation of some buffer fails, then free buffers allocated till then */
+ if((IV_FAIL == ret) && (NULL != ps_codec_obj))
{
- IV_API_CALL_STATUS_T status;
- icncl_fill_mem_rec_ip_t cncl_fill_ip;
- icncl_fill_mem_rec_op_t cncl_fill_op;
-
- iv_mem_rec_t *ps_mem_rec;
-
- UWORD8 mem_loc = MEM_REC_CNT;
- UWORD8 num_cncl_mem = 0;
+ ihevcd_free_static_bufs(ps_codec_obj);
+ 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;
- ps_mem_rec = dec_clr_ip->pv_mem_rec_location;
-
- cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
- cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = &(ps_mem_rec[mem_loc]);
- cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_size = sizeof(icncl_fill_mem_rec_ip_t);
-
- status = icncl_api_function(NULL, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
-
- cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_RETRIEVE_MEMREC;
- cncl_fill_op.s_ivd_fill_mem_rec_op_t.u4_size = sizeof(icncl_fill_mem_rec_op_t);
-
- status = icncl_api_function(ps_codec->ps_conceal, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
-
- if(status == IV_SUCCESS)
- {
- /* Add the concealment library's memory requirements */
- dec_clr_op->u4_num_mem_rec_filled += cncl_fill_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled;
- }
+ return IV_FAIL;
}
-#endif //APPLY_CONCEALMENT
- DEBUG("Retrieve num mem recs: %d\n",
- dec_clr_op->u4_num_mem_rec_filled);
- STATS_PRINT();
- ihevcd_jobq_free((jobq_t *)ps_codec->pv_proc_jobq);
+ ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
+ ret = ihevcd_init(ps_codec);
+ TRACE_INIT(NULL);
+ STATS_INIT();
+ return ret;
+}
+/**
+*******************************************************************************
+*
+* @brief
+* Delete codec
+*
+* @par Description:
+* Delete codec
+*
+* @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 ihevcd_delete(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
+{
+ codec_t *ps_dec;
+ ihevcd_cxa_delete_ip_t *ps_ip = (ihevcd_cxa_delete_ip_t *)pv_api_ip;
+ ihevcd_cxa_delete_op_t *ps_op = (ihevcd_cxa_delete_op_t *)pv_api_op;
+ ps_dec = (codec_t *)(ps_codec_obj->pv_codec_handle);
+ UNUSED(ps_ip);
+ ps_op->s_ivd_delete_op_t.u4_error_code = 0;
+ ihevcd_free_dynamic_bufs(ps_dec);
+ ihevcd_free_static_bufs(ps_codec_obj);
return IV_SUCCESS;
-
}
+
+
/**
*******************************************************************************
*
@@ -3155,31 +2162,38 @@ WORD32 ihevcd_set_display_frame(iv_obj_t *ps_codec_obj,
pic_buf_t *ps_pic_buf;
UWORD8 *pu1_buf;
WORD32 buf_ret;
- WORD32 strd;
- strd = ps_codec->i4_strd;
- if(0 == strd)
- strd = ps_codec->i4_max_wd + PAD_WD;
+
+ UWORD8 *pu1_chroma_buf = NULL;
num_bufs = MIN(num_bufs, BUF_MGR_MAX_CNT);
ps_codec->i4_num_disp_bufs = num_bufs;
ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;
+
+ /* If color format is 420P, then allocate chroma buffers to hold semiplanar
+ * chroma data */
+ if(ps_codec->e_chroma_fmt == IV_YUV_420P)
+ {
+ WORD32 num_samples = ps_dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1] << 1;
+ WORD32 size = num_samples * num_bufs;
+ void *pv_mem_ctxt = ps_codec->pv_mem_ctxt;
+
+ pu1_chroma_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
+ RETURN_IF((NULL == pu1_chroma_buf), IV_FAIL);
+
+ ps_codec->pu1_cur_chroma_ref_buf = pu1_chroma_buf;
+ }
for(i = 0; i < (WORD32)num_bufs; i++)
{
+ /* Stride is not available in some cases here.
+ So store base pointers to buffer manager now,
+ and update these pointers once header is decoded */
pu1_buf = ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[0];
- ps_pic_buf->pu1_luma = pu1_buf + strd * PAD_TOP + PAD_LEFT;
+ ps_pic_buf->pu1_luma = pu1_buf;
if(ps_codec->e_chroma_fmt == IV_YUV_420P)
{
- pu1_buf = ps_codec->pu1_cur_chroma_ref_buf;
- ps_codec->pu1_cur_chroma_ref_buf += strd * (ps_codec->i4_ht / 2 + PAD_HT / 2);
- ps_codec->i4_remaining_pic_buf_size -= strd * (ps_codec->i4_ht / 2 + PAD_HT / 2);
-
- if(0 > ps_codec->i4_remaining_pic_buf_size)
- {
- ps_codec->i4_error_code = IHEVCD_BUF_MGR_ERROR;
- return IHEVCD_BUF_MGR_ERROR;
- }
-
+ pu1_buf = pu1_chroma_buf;
+ pu1_chroma_buf += ps_dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1] << 1;
}
else
{
@@ -3187,7 +2201,7 @@ WORD32 ihevcd_set_display_frame(iv_obj_t *ps_codec_obj,
pu1_buf = ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[1];
}
- ps_pic_buf->pu1_chroma = pu1_buf + strd * (PAD_TOP / 2) + PAD_LEFT;
+ ps_pic_buf->pu1_chroma = pu1_buf;
buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
@@ -3330,7 +2344,9 @@ WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj,
for(i = 0; i < (WORD32)ps_ctl_op->u4_min_num_in_bufs; i++)
{
- ps_ctl_op->u4_min_in_buf_size[i] = MAX((ps_codec->i4_wd * ps_codec->i4_ht), MIN_BITSBUF_SIZE);
+ wd = ALIGN64(ps_codec->i4_wd);
+ ht = ALIGN64(ps_codec->i4_ht);
+ ps_ctl_op->u4_min_in_buf_size[i] = MAX((wd * ht), MIN_BITSBUF_SIZE);
}
wd = ps_codec->i4_wd;
@@ -3350,19 +2366,6 @@ WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj,
ht = ps_codec->i4_ht + PAD_HT;
}
}
- else
- {
- if(0 == ps_codec->i4_share_disp_buf)
- {
- wd = ps_codec->i4_new_max_wd;
- ht = ps_codec->i4_new_max_ht;
- }
- else
- {
- wd = ALIGN32(wd + PAD_WD);
- ht += PAD_HT;
- }
- }
if(ps_codec->i4_disp_strd > wd)
wd = ps_codec->i4_disp_strd;
@@ -3371,36 +2374,22 @@ WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj,
ps_ctl_op->u4_num_disp_bufs = 1;
else
{
- WORD32 pic_size;
- WORD32 max_dpb_size;
-
if(ps_codec->i4_sps_done)
{
sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
- WORD32 reorder_pic_cnt;
- WORD32 ref_pic_cnt;
- WORD32 level;
-
- reorder_pic_cnt = MIN(ps_sps->ai1_sps_max_num_reorder_pics[0], ps_codec->i4_init_num_reorder);
- pic_size = ps_sps->i2_pic_width_in_luma_samples * ps_sps->i2_pic_height_in_luma_samples;
+ WORD32 reorder_pic_cnt, ref_pic_cnt;
+ reorder_pic_cnt = 0;
+ if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
+ reorder_pic_cnt = ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
+ ref_pic_cnt = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
- level = ps_codec->i4_init_level;
- max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
- ref_pic_cnt = max_dpb_size;
ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt;
ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1;
-
}
else
{
- pic_size = ps_codec->i4_max_wd * ps_codec->i4_max_ht;
- max_dpb_size = ihevcd_get_dpb_size(ps_codec->i4_init_level, pic_size);
- ps_ctl_op->u4_num_disp_bufs = 2 * max_dpb_size;
-
- ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs,
- (UWORD32)(ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1));
-
+ ps_ctl_op->u4_num_disp_bufs = MAX_REF_CNT;
}
ps_ctl_op->u4_num_disp_bufs = MIN(
@@ -3515,11 +2504,14 @@ WORD32 ihevcd_get_buf_info(iv_obj_t *ps_codec_obj,
for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
{
- ps_ctl_op->u4_min_in_buf_size[i] = MAX((ps_codec->i4_wd * ps_codec->i4_ht), MIN_BITSBUF_SIZE);
+ wd = ALIGN64(ps_codec->i4_wd);
+ ht = ALIGN64(ps_codec->i4_ht);
+
+ ps_ctl_op->u4_min_in_buf_size[i] = MAX((wd * ht), MIN_BITSBUF_SIZE);
}
- wd = ps_codec->i4_max_wd;
- ht = ps_codec->i4_max_ht;
+ wd = 0;
+ ht = 0;
if(ps_codec->i4_sps_done)
{
@@ -3551,36 +2543,22 @@ WORD32 ihevcd_get_buf_info(iv_obj_t *ps_codec_obj,
ps_ctl_op->u4_num_disp_bufs = 1;
else
{
- WORD32 pic_size;
- WORD32 max_dpb_size;
-
if(ps_codec->i4_sps_done)
{
sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
- WORD32 reorder_pic_cnt;
- WORD32 ref_pic_cnt;
- WORD32 level;
+ WORD32 reorder_pic_cnt, ref_pic_cnt;
+ reorder_pic_cnt = 0;
+ if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
+ reorder_pic_cnt = ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
+ ref_pic_cnt = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
- reorder_pic_cnt = MIN(ps_sps->ai1_sps_max_num_reorder_pics[0], ps_codec->i4_init_num_reorder);
- pic_size = ps_sps->i2_pic_width_in_luma_samples * ps_sps->i2_pic_height_in_luma_samples;
-
- level = ps_codec->i4_init_level;
- max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
- ref_pic_cnt = max_dpb_size;
ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt;
ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1;
-
}
else
{
- pic_size = ps_codec->i4_max_wd * ps_codec->i4_max_ht;
- max_dpb_size = ihevcd_get_dpb_size(ps_codec->i4_init_level, pic_size);
- ps_ctl_op->u4_num_disp_bufs = 2 * max_dpb_size;
-
- ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs,
- (UWORD32)(ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1));
-
+ ps_ctl_op->u4_num_disp_bufs = MAX_REF_CNT;
}
ps_ctl_op->u4_num_disp_bufs = MIN(
@@ -3730,6 +2708,15 @@ WORD32 ihevcd_set_params(iv_obj_t *ps_codec_obj,
ret = IV_FAIL;
}
+ ps_codec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+
+ if((s_ctl_dynparams_ip->e_frm_out_mode != IVD_DECODE_FRAME_OUT) &&
+ (s_ctl_dynparams_ip->e_frm_out_mode != IVD_DISPLAY_FRAME_OUT))
+ {
+ s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
+ ret = IV_FAIL;
+ }
+ ps_codec->e_frm_out_mode = s_ctl_dynparams_ip->e_frm_out_mode;
return ret;
@@ -3938,8 +2925,8 @@ WORD32 ihevcd_get_frame_dimensions(iv_obj_t *ps_codec_obj,
else
{
- disp_wd = ps_codec->i4_max_wd;
- disp_ht = ps_codec->i4_max_ht;
+ disp_wd = 0;
+ disp_ht = 0;
if(0 == ps_codec->i4_share_disp_buf)
{
@@ -4445,17 +3432,11 @@ IV_API_CALL_STATUS_T ihevcd_cxa_api_function(iv_obj_t *ps_handle,
switch(command)
{
- case IV_CMD_GET_NUM_MEM_REC:
- ret = ihevcd_get_num_rec((void *)pv_api_ip, (void *)pv_api_op);
-
+ case IVD_CMD_CREATE:
+ ret = ihevcd_create(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
break;
- case IV_CMD_FILL_NUM_MEM_REC:
-
- ret = ihevcd_fill_num_mem_rec((void *)pv_api_ip, (void *)pv_api_op);
- break;
- case IV_CMD_INIT:
- ret = ihevcd_init_mem_rec(ps_handle, (void *)pv_api_ip,
- (void *)pv_api_op);
+ case IVD_CMD_DELETE:
+ ret = ihevcd_delete(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
break;
case IVD_CMD_VIDEO_DECODE:
@@ -4477,11 +3458,6 @@ IV_API_CALL_STATUS_T ihevcd_cxa_api_function(iv_obj_t *ps_handle,
(void *)pv_api_op);
break;
- case IV_CMD_RETRIEVE_MEMREC:
- ret = ihevcd_retrieve_memrec(ps_handle, (void *)pv_api_ip,
- (void *)pv_api_op);
- break;
-
case IVD_CMD_VIDEO_CTL:
ret = ihevcd_ctl(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
break;
diff --git a/decoder/ihevcd_cxa.h b/decoder/ihevcd_cxa.h
index 7c71271..c23d1e7 100644
--- a/decoder/ihevcd_cxa.h
+++ b/decoder/ihevcd_cxa.h
@@ -140,159 +140,37 @@ typedef enum {
/* Extended Structures */
/*****************************************************************************/
-/*****************************************************************************/
-/* Get Number of Memory Records */
-/*****************************************************************************/
-
-
-typedef struct {
-
- /**
- * ivd_num_mem_rec_ip_t
- */
- iv_num_mem_rec_ip_t s_ivd_num_mem_rec_ip_t;
-}ihevcd_cxa_num_mem_rec_ip_t;
-
-
-typedef struct {
-
- /**
- * ivd_num_mem_rec_op_t
- */
- iv_num_mem_rec_op_t s_ivd_num_mem_rec_op_t;
-}ihevcd_cxa_num_mem_rec_op_t;
-
/*****************************************************************************/
-/* Fill Memory Records */
+/* Delete Codec */
/*****************************************************************************/
-
typedef struct {
- /**
- * ivd_fill_mem_rec_ip_t
- */
- iv_fill_mem_rec_ip_t s_ivd_fill_mem_rec_ip_t;
-
- /**
- * level
- */
- WORD32 i4_level;
-
- /**
- * num_reorder_frames
- */
- UWORD32 u4_num_reorder_frames;
-
- /**
- * num_ref_frames
- */
- UWORD32 u4_num_ref_frames;
-
- /**
- * share_disp_buf
- */
- UWORD32 u4_share_disp_buf;
-
- /**
- * format in which codec has to give out frame data for display
- */
- IV_COLOR_FORMAT_T e_output_format;
-
- /**
- * Number of extra display buffers that will be allocated to handle display pipeline depth
- */
- UWORD32 u4_num_extra_disp_buf;
-
-}ihevcd_cxa_fill_mem_rec_ip_t;
+ ivd_delete_ip_t s_ivd_delete_ip_t;
+}ihevcd_cxa_delete_ip_t;
typedef struct {
-
- /**
- * ivd_fill_mem_rec_op_t
- */
-
- iv_fill_mem_rec_op_t s_ivd_fill_mem_rec_op_t;
-
-}ihevcd_cxa_fill_mem_rec_op_t;
-
-/*****************************************************************************/
-/* Retrieve Memory Records */
-/*****************************************************************************/
-
-
-typedef struct {
-
- /**
- * ivd_retrieve_mem_rec_ip_t
- */
- iv_retrieve_mem_rec_ip_t s_ivd_retrieve_mem_rec_ip_t;
-}ihevcd_cxa_retrieve_mem_rec_ip_t;
-
-
-typedef struct {
-
- /**
- * ivd_retrieve_mem_rec_op_t
- */
- iv_retrieve_mem_rec_op_t s_ivd_retrieve_mem_rec_op_t;
-}ihevcd_cxa_retrieve_mem_rec_op_t;
-
+ ivd_delete_op_t s_ivd_delete_op_t;
+}ihevcd_cxa_delete_op_t;
/*****************************************************************************/
/* Initialize decoder */
/*****************************************************************************/
-
typedef struct {
-
- /**
- * ivd_init_ip_t
- */
- ivd_init_ip_t s_ivd_init_ip_t;
-
- /**
- * level
- */
- WORD32 i4_level;
-
- /**
- * num_reorder_frames
- */
- UWORD32 u4_num_reorder_frames;
-
- /**
- * num_ref_frames
- */
- UWORD32 u4_num_ref_frames;
-
- /**
- * share_disp_buf
- */
- UWORD32 u4_share_disp_buf;
-
- /**
- * Number of extra display buffers that will be allocated to handle display pipeline depth
- */
- UWORD32 u4_num_extra_disp_buf;
-}ihevcd_cxa_init_ip_t;
+ ivd_create_ip_t s_ivd_create_ip_t;
+}ihevcd_cxa_create_ip_t;
typedef struct {
-
- /**
- * ivd_init_op_t
- */
- ivd_init_op_t s_ivd_init_op_t;
-}ihevcd_cxa_init_op_t;
-
+ ivd_create_op_t s_ivd_create_op_t;
+}ihevcd_cxa_create_op_t;
/*****************************************************************************/
/* Video Decode */
/*****************************************************************************/
-
typedef struct {
/**
@@ -315,7 +193,6 @@ typedef struct {
/* Get Display Frame */
/*****************************************************************************/
-
typedef struct
{
/**
diff --git a/decoder/ihevcd_decode.c b/decoder/ihevcd_decode.c
index d12051a..954f8f3 100644
--- a/decoder/ihevcd_decode.c
+++ b/decoder/ihevcd_decode.c
@@ -89,6 +89,9 @@ IHEVCD_ERROR_T ihevcd_fmt_conv(codec_t *ps_codec,
WORD32 cur_row,
WORD32 num_rows);
WORD32 ihevcd_init(codec_t *ps_codec);
+
+WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec);
+WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec);
/*****************************************************************************/
/* Function Prototypes */
/*****************************************************************************/
@@ -183,12 +186,7 @@ static void ihevcd_fill_outargs(codec_t *ps_codec,
ps_dec_op->u4_error_code = ihevcd_map_error((IHEVCD_ERROR_T)ps_codec->i4_error_code);
ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes
- ps_codec->i4_bytes_remaining;
- if(ps_codec->i4_error_code == IHEVCD_UNSUPPORTED_DIMENSIONS)
- {
- ps_dec_op->u4_pic_wd = ps_codec->i4_new_max_wd;
- ps_dec_op->u4_pic_ht = ps_codec->i4_new_max_ht;
- }
- else if(ps_codec->i4_sps_done)
+ if(ps_codec->i4_sps_done)
{
ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
@@ -565,6 +563,17 @@ WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
ps_codec->i4_slice_error = 0;
}
+ if(ps_codec->pu1_bitsbuf_dynamic)
+ {
+ ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_dynamic;
+ ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_dynamic;
+ }
+ else
+ {
+ ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_static;
+ ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_static;
+ }
+
nal_ofst = ihevcd_nal_search_start_code(ps_codec->pu1_inp_bitsbuf,
ps_codec->i4_bytes_remaining);
@@ -655,6 +664,23 @@ WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
break;
}
+ /* Allocate dynamic bitstream buffer once SPS is decoded */
+ if((ps_codec->u4_allocate_dynamic_done == 0) && ps_codec->i4_sps_done)
+ {
+ WORD32 ret;
+ ret = ihevcd_allocate_dynamic_bufs(ps_codec);
+ if(ret != IV_SUCCESS)
+ {
+ /* Free any dynamic buffers that are allocated */
+ ihevcd_free_dynamic_bufs(ps_codec);
+ ps_codec->i4_error_code = IVD_MEM_ALLOC_FAILED;
+ ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
+ ps_dec_op->u4_error_code |= IVD_MEM_ALLOC_FAILED;
+
+ return IV_FAIL;
+ }
+ }
+
BREAK_AFTER_SLICE_NAL();
}
diff --git a/decoder/ihevcd_mv_merge.c b/decoder/ihevcd_mv_merge.c
index 9ec3029..08cec43 100644
--- a/decoder/ihevcd_mv_merge.c
+++ b/decoder/ihevcd_mv_merge.c
@@ -309,7 +309,7 @@ void ihevcd_collocated_mvp(mv_ctxt_t *ps_mv_ctxt,
cur_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
slice_idx = *(ps_mv_buf_col->pu1_pic_slice_map + col_ctb_x + col_ctb_y * ps_sps->i2_pic_wd_in_ctb);
-
+ slice_idx &= (MAX_SLICE_HDR_CNT - 1);
if(au4_list_col[0] == 0)
{
col_ref_poc_l0 =
diff --git a/decoder/ihevcd_parse_headers.c b/decoder/ihevcd_parse_headers.c
index 3ed70fb..ecc271a 100644
--- a/decoder/ihevcd_parse_headers.c
+++ b/decoder/ihevcd_parse_headers.c
@@ -1263,16 +1263,6 @@ IHEVCD_ERROR_T ihevcd_parse_sps(codec_t *ps_codec)
ps_sps->i2_pic_width_in_luma_samples = ALIGN8(ps_sps->i2_pic_width_in_luma_samples);
ps_sps->i2_pic_height_in_luma_samples = ALIGN8(ps_sps->i2_pic_height_in_luma_samples);
- if((ps_sps->i2_pic_width_in_luma_samples > ps_codec->i4_max_wd) ||
- (ps_sps->i2_pic_width_in_luma_samples * ps_sps->i2_pic_height_in_luma_samples >
- ps_codec->i4_max_wd * ps_codec->i4_max_ht) ||
- (ps_sps->i2_pic_height_in_luma_samples > MAX(ps_codec->i4_max_wd, ps_codec->i4_max_ht)))
- {
- ps_codec->i4_new_max_wd = ps_sps->i2_pic_width_in_luma_samples;
- ps_codec->i4_new_max_ht = ps_sps->i2_pic_height_in_luma_samples;
- return (IHEVCD_ERROR_T)IHEVCD_UNSUPPORTED_DIMENSIONS;
- }
-
BITS_PARSE("pic_cropping_flag", value, ps_bitstrm, 1);
ps_sps->i1_pic_cropping_flag = value;
@@ -1917,10 +1907,13 @@ void ihevcd_copy_pps(codec_t *ps_codec, WORD32 pps_id, WORD32 pps_id_ref)
WORD32 scaling_mat_size;
tile_t *ps_tile_backup;
WORD32 max_tile_cols, max_tile_rows;
+ WORD32 wd, ht;
+ wd = ALIGN64(ps_codec->i4_wd);
+ ht = ALIGN64(ps_codec->i4_ht);
SCALING_MAT_SIZE(scaling_mat_size);
- max_tile_cols = (ps_codec->i4_max_wd + MIN_TILE_WD - 1) / MIN_TILE_WD;
- max_tile_rows = (ps_codec->i4_max_ht + MIN_TILE_HT - 1) / MIN_TILE_HT;
+ max_tile_cols = (wd + MIN_TILE_WD - 1) / MIN_TILE_WD;
+ max_tile_rows = (ht + MIN_TILE_HT - 1) / MIN_TILE_HT;
ps_pps_ref = ps_codec->ps_pps_base + pps_id_ref;
ps_pps = ps_codec->ps_pps_base + pps_id;
diff --git a/decoder/ihevcd_structs.h b/decoder/ihevcd_structs.h
index 1e6bc20..ce0653e 100644
--- a/decoder/ihevcd_structs.h
+++ b/decoder/ihevcd_structs.h
@@ -196,21 +196,21 @@ typedef struct
/**
* Absolute POCs of reference List 0 for all slices in the frame from which this frame is reconstructed
*/
- WORD32 ai4_l0_collocated_poc[MAX_SLICE_SEGMENTS_IN_FRAME][MAX_DPB_SIZE];
+ WORD32 ai4_l0_collocated_poc[MAX_SLICE_HDR_CNT][MAX_DPB_SIZE];
/**
* Flag to indicate Long Term reference for POCs of reference List 0 for all slices in the frame from which this frame is reconstructed
*/
- WORD8 ai1_l0_collocated_poc_lt[MAX_SLICE_SEGMENTS_IN_FRAME][MAX_DPB_SIZE];
+ WORD8 ai1_l0_collocated_poc_lt[MAX_SLICE_HDR_CNT][MAX_DPB_SIZE];
/**
* Absolute POCs of reference List 1 for all slices in the frame from which this frame is reconstructed
*/
- WORD32 ai4_l1_collocated_poc[MAX_SLICE_SEGMENTS_IN_FRAME][MAX_DPB_SIZE];
+ WORD32 ai4_l1_collocated_poc[MAX_SLICE_HDR_CNT][MAX_DPB_SIZE];
/**
* Flag to indicate Long Term reference for POCs of reference List 1 for all slices in the frame from which this frame is reconstructed
*/
- WORD8 ai1_l1_collocated_poc_lt[MAX_SLICE_SEGMENTS_IN_FRAME][MAX_DPB_SIZE];
+ WORD8 ai1_l1_collocated_poc_lt[MAX_SLICE_HDR_CNT][MAX_DPB_SIZE];
}mv_buf_t;
@@ -1627,16 +1627,6 @@ typedef void (*pf_sao_chroma)(UWORD8 *,
struct _codec_t
{
/**
- * Max width the codec can support
- */
- WORD32 i4_max_wd;
-
- /**
- * Max height the codec can support
- */
- WORD32 i4_max_ht;
-
- /**
* Width : pic_width_in_luma_samples
*/
WORD32 i4_wd;
@@ -1661,21 +1651,6 @@ struct _codec_t
*/
WORD32 i4_disp_strd;
- /*
- * In case stream width/height is greater than max_wd/max_ht used during init,
- * it is stored in the following and in order to decode the current stream
- * decoder has to be recreated with these dimensions.
- */
- /**
- * Stream width if it is greater than i4_max_wd
- */
- WORD32 i4_new_max_wd;
-
- /**
- * Stream height if it is greater than i4_max_ht
- */
- WORD32 i4_new_max_ht;
-
/**
* Stride of reference buffers.
* For shared mode even display buffer will use the same stride
@@ -1683,26 +1658,6 @@ struct _codec_t
WORD32 i4_strd;
/**
- * Level specified during init
- */
- WORD32 i4_init_level;
-
- /**
- * number of reference frames specified during init
- */
- WORD32 i4_init_num_ref;
-
- /**
- * number of reorder frames specified during init
- */
- WORD32 i4_init_num_reorder;
-
- /**
- * Number of extra display buffers allocated by application
- */
- WORD32 i4_init_num_extra_disp_buf;
-
- /**
* Number of cores to be used
*/
WORD32 i4_num_cores;
@@ -1904,19 +1859,36 @@ struct _codec_t
UWORD8 *pu1_bitsbuf;
/**
+ * Pointer to static bitstream after emulation prevention
+ * This is a fixed size buffer used initially till SPS is decoded
+ */
+ UWORD8 *pu1_bitsbuf_static;
+
+ /**
+ * Pointer to dynamic bitstream after emulation prevention
+ * This is allocated after SPS is done, based on width and height
+ */
+ UWORD8 *pu1_bitsbuf_dynamic;
+
+ /**
* Size of intermediate bitstream buffer
*/
UWORD32 u4_bitsbuf_size;
/**
- * Pointer to hold TU data for a set of CTBs or a picture
+ * Size of intermediate static bitstream buffer
*/
- void *pv_tu_data;
+ UWORD32 u4_bitsbuf_size_static;
+
/**
- * Holds mem records passed during init.
- * This will be used to return the mem records during retrieve call
+ * Size of intermediate dynamic bitstream buffer
*/
- iv_mem_rec_t *ps_mem_rec_backup;
+ UWORD32 u4_bitsbuf_size_dynamic;
+
+ /**
+ * Pointer to hold TU data for a set of CTBs or a picture
+ */
+ void *pv_tu_data;
/**
* Process Job queue buffer base
@@ -1937,6 +1909,12 @@ struct _codec_t
* Current pictures intra mode map at 8x8 level
*/
UWORD8 *pu1_pic_intra_flag;
+
+ /**
+ * No LPF buffer base
+ */
+ UWORD8 *pu1_pic_no_loop_filter_flag_base;
+
/**
* Current pictures loop filter flag map at 8x8 level
*/
@@ -1982,11 +1960,6 @@ struct _codec_t
WORD32 i4_total_pic_buf_size;
/**
- * Remaining pic buffer size - used for shared mode with 420p support
- */
- WORD32 i4_remaining_pic_buf_size;
-
- /**
* Current chroma buffer base - used for shared mode with 420p output
*/
UWORD8 *pu1_cur_chroma_ref_buf;
@@ -2124,6 +2097,28 @@ struct _codec_t
/** Mask used to change MVs to full pel when configured to run in reduced complexity mode */
WORD32 i4_mv_frac_mask;
+
+ /** Memory holding tile indices */
+ UWORD8 *pu1_tile_idx_base;
+
+ /** Callback for aligned allocation */
+ void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
+
+ /** Callback for aligned free */
+ void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
+
+ /** Memory context passed from application */
+ void *pv_mem_ctxt;
+
+ /** Base address of reference buffrers allocated */
+ UWORD8 *pu1_ref_pic_buf_base;
+
+ /** Flag to indicate if dynamic buffers are allocated */
+ UWORD32 u4_allocate_dynamic_done;
+
+ /** Flag to signal display order */
+ IVD_DISPLAY_FRAME_OUT_MODE_T e_frm_out_mode;
+
/** Funtion pointers for inter_pred leaf level functions */
pf_inter_pred apf_inter_pred[22];
diff --git a/decoder/ihevcd_utils.c b/decoder/ihevcd_utils.c
index 5c10014..1cdf3be 100644
--- a/decoder/ihevcd_utils.c
+++ b/decoder/ihevcd_utils.c
@@ -163,59 +163,6 @@ WORD32 ihevcd_get_lvl_idx(WORD32 level)
*******************************************************************************
*
* @brief
-* Used to get DPB size for a given level, and number of luma samples
-*
-* @par Description:
-* For given width, height and level number of max_dpb_size is computed as per
-* Annex A.4.1
-*
-* @param[in] level
-* Level of the stream
-*
-* @param[in] pic_size
-* Width * Height
-*
-* @returns Number of buffers in DPB
-*
-* @remarks
-*
-*
-*******************************************************************************
-*/
-WORD32 ihevcd_get_dpb_size(WORD32 level, WORD32 pic_size)
-{
-
- WORD32 max_luma_samples;
-
- WORD32 max_dpb_size;
- WORD32 lvl_idx = ihevcd_get_lvl_idx(level);
- max_luma_samples = gai4_ihevc_max_luma_pic_size[lvl_idx];
-
-
-
- if(pic_size <= (max_luma_samples >> 2))
- {
- max_dpb_size = MIN(4 * MAX_DPB_PIC_BUF, 16);
- }
- else if(pic_size <= (max_luma_samples >> 1))
- {
- max_dpb_size = MIN(2 * MAX_DPB_PIC_BUF, 16);
- }
- else if(pic_size <= ((3 * max_luma_samples) >> 2))
- {
- max_dpb_size = MIN((4 * MAX_DPB_PIC_BUF) / 3, 16);
- }
- else
- {
- max_dpb_size = MAX_DPB_PIC_BUF;
- }
-
- return max_dpb_size;
-}
-/**
-*******************************************************************************
-*
-* @brief
* Used to get reference picture buffer size for a given level and
* and padding used
*
@@ -242,85 +189,37 @@ WORD32 ihevcd_get_dpb_size(WORD32 level, WORD32 pic_size)
*
*******************************************************************************
*/
-WORD32 ihevcd_get_total_pic_buf_size(WORD32 pic_size,
- WORD32 level,
- WORD32 horz_pad,
- WORD32 vert_pad,
- WORD32 init_num_bufs,
- WORD32 init_extra_bufs,
- WORD32 chroma_only)
+WORD32 ihevcd_get_total_pic_buf_size(codec_t *ps_codec,
+ WORD32 wd,
+ WORD32 ht)
{
WORD32 size;
WORD32 num_luma_samples;
- WORD32 lvl_idx;
- WORD32 max_wd, min_ht;
WORD32 max_dpb_size;
WORD32 num_samples;
- WORD32 max_num_bufs;
- WORD32 pad = MAX(horz_pad, vert_pad);
- /* Get maximum number of buffers for the current picture size */
- max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
-
-
- max_num_bufs = (2 * max_dpb_size + 1);
- /* If num_ref_frames and num_reorder_frmaes is specified
- * Use minimum value
- */
- max_num_bufs = MIN(max_num_bufs, init_num_bufs);
-
- /*
- * Add extra buffers if required
- */
- max_num_bufs += init_extra_bufs;
- max_num_bufs = MIN(max_num_bufs, BUF_MGR_MAX_CNT);
-
- /* Get level index */
- lvl_idx = ihevcd_get_lvl_idx(level);
-
-
- /* Maximum width of luma samples in a picture at given level */
- max_wd = ALIGN64(gai4_ihevc_max_wd_ht[lvl_idx]);
+ sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
- /* Minimum height of luma samples in a picture at given level */
- min_ht = ALIGN64(gai4_ihevc_min_wd_ht[lvl_idx]);
+ /* Get maximum number of buffers for the current picture size */
+ max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
- /* Use max_wd and min_ht to get maximum number of luma samples for given level */
- /* Because max_wd and min_ht are aligned to 64, product will be higher than the
- * value given by the spec for a given level
- */
- num_luma_samples = max_wd * min_ht;
+ if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
+ max_dpb_size += ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
+ max_dpb_size++;
/* Allocation is required for
* (Wd + horz_pad) * (Ht + vert_pad) * (2 * max_dpb_size + 1)
- *
- * Above expanded as
- * ((Wd * Ht) + (horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1)
- * (Wd * Ht) * (2 * max_dpb_size + 1) + ((horz_pad * vert_pad) + Wd * vert_pad + Ht * horz_pad) * (2 * max_dpb_size + 1)
- * Now max_dpb_size increases with smaller Wd and Ht, but Wd * ht * max_dpb_size will still be lesser or equal to max_wd * max_ht * dpb_size
- *
- * In the above equation (Wd * Ht) * (2 * max_dpb_size + 1) is accounted by using num_samples * (2 * max_dpb_size + 1) below
- *
- * For the padded area use MAX(horz_pad, vert_pad) as pad
- * ((pad * pad) + pad * (Wd + Ht)) * (2 * max_dpb_size + 1) has to accounted from the above for padding
- *
- * Since Width and Height can change worst Wd + Ht is when One of the dimensions is max and other is min
- * So use max_wd and min_ht
*/
/* Account for padding area */
-
- num_luma_samples += (pad * pad) + pad * (max_wd + min_ht);
+ num_luma_samples = (wd + PAD_WD) * (ht + PAD_HT);
/* Account for chroma */
- if(0 == chroma_only)
- num_samples = num_luma_samples * 3 / 2;
- else
- num_samples = num_luma_samples / 2;
+ num_samples = num_luma_samples * 3 / 2;
/* Number of bytes in reference pictures */
- size = num_samples * max_num_bufs;
+ size = num_samples * max_dpb_size;
return size;
@@ -558,43 +457,29 @@ IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
pic_buf_t *ps_pic_buf;
WORD32 pic_buf_size_allocated;
- WORD32 max_num_bufs;
- WORD32 pic_size;
- WORD32 level;
- /* Initialize MV Bank buffer manager */
+
+ /* Initialize Pic buffer manager */
ps_sps = ps_codec->s_parse.ps_sps;
- pic_size = ps_sps->i2_pic_width_in_luma_samples *
- ps_sps->i2_pic_height_in_luma_samples;
+ /* Compute the number of Pic buffers needed */
+ max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
+ if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
+ max_dpb_size += ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
- /* Compute the number of MB Bank buffers needed */
- level = ps_codec->i4_init_level;
- max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
- /* Allocate twice dpb size to handle worst case reorder without returning more
- * than one output per call
- */
- max_dpb_size *= 2;
/* Allocate one extra picture to handle current frame
* In case of asynchronous parsing and processing, number of buffers should increase here
* based on when parsing and processing threads are synchronized
*/
max_dpb_size++;
- /* If num_ref_frames and num_reorder_frmaes is specified
- * Use minimum value
- */
- max_num_bufs = MIN(max_dpb_size, (ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1));
-
- pu1_buf = (UWORD8 *)ps_codec->ps_pic_buf;
+ pu1_buf = (UWORD8 *)ps_codec->pu1_ref_pic_buf_base;
ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;
- pu1_buf += BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
-
/* In case of non-shared mode, add picture buffers to buffer manager
* In case of shared mode buffers are added in the run-time
*/
@@ -603,8 +488,7 @@ IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
WORD32 buf_ret;
WORD32 luma_samples;
WORD32 chroma_samples;
- pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size -
- BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
+ pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size;
luma_samples = (ps_codec->i4_strd) *
(ps_sps->i2_pic_height_in_luma_samples + PAD_HT);
@@ -615,18 +499,14 @@ IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
/* If the number of buffers that can be added is less than max_num_bufs
* return with an error.
*/
- for(i = 0; i < (2 * MAX_DPB_SIZE) + 1; i++)
+ for(i = 0; i < max_dpb_size; i++)
{
pic_buf_size_allocated -= (luma_samples + chroma_samples);
if(pic_buf_size_allocated < 0)
{
- if(i < max_num_bufs)
- {
- ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_PICBUF;
- return IHEVCD_INSUFFICIENT_MEM_PICBUF;
- }
- break;
+ ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_PICBUF;
+ return IHEVCD_INSUFFICIENT_MEM_PICBUF;
}
ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
@@ -637,6 +517,7 @@ IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
+
if(0 != buf_ret)
{
ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
@@ -645,6 +526,26 @@ IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
ps_pic_buf++;
}
}
+ else
+ {
+ /* In case of shared mode, buffers are added without adjusting for padding.
+ Update luma and chroma pointers here to account for padding as per stride.
+ In some cases stride might not be available when set_display_frame is called.
+ Hence updated luma and chroma pointers here */
+
+ for(i = 0; i < BUF_MGR_MAX_CNT; i++)
+ {
+ ps_pic_buf = ihevc_buf_mgr_get_buf((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i);
+ if((NULL == ps_pic_buf) ||
+ (NULL == ps_pic_buf->pu1_luma) ||
+ (NULL == ps_pic_buf->pu1_chroma))
+ {
+ break;
+ }
+ ps_pic_buf->pu1_luma += ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
+ ps_pic_buf->pu1_chroma += ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
+ }
+ }
return ret;
}
@@ -675,7 +576,7 @@ IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec)
WORD32 max_dpb_size;
WORD32 mv_bank_size_allocated;
WORD32 pic_mv_bank_size;
- WORD32 level;
+
sps_t *ps_sps;
UWORD8 *pu1_buf;
mv_buf_t *ps_mv_buf;
@@ -685,11 +586,8 @@ IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec)
ps_sps = ps_codec->s_parse.ps_sps;
- /* Compute the number of MB Bank buffers needed */
- level = ps_codec->i4_init_level;
- max_dpb_size = ihevcd_get_dpb_size(level,
- ps_sps->i2_pic_width_in_luma_samples *
- ps_sps->i2_pic_height_in_luma_samples);
+ /* Compute the number of MV Bank buffers needed */
+ max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
/* Allocate one extra MV Bank to handle current frame
* In case of asynchronous parsing and processing, number of buffers should increase here
@@ -700,9 +598,9 @@ IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec)
pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base;
ps_mv_buf = (mv_buf_t *)pu1_buf;
- pu1_buf += (MAX_DPB_SIZE + 1) * sizeof(mv_buf_t);
+ pu1_buf += max_dpb_size * sizeof(mv_buf_t);
ps_codec->ps_mv_buf = ps_mv_buf;
- mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - (MAX_DPB_SIZE + 1) * sizeof(mv_buf_t);
+ mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - max_dpb_size * sizeof(mv_buf_t);
/* Compute MV bank size per picture */
pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ps_sps->i2_pic_width_in_luma_samples *
@@ -1181,7 +1079,7 @@ IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec)
/* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */
/* Since the current will be decoded, check is fore >= instead of > */
if(((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1]) ||
- ((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_codec->i4_init_num_reorder))
+ (ps_codec->e_frm_out_mode == IVD_DECODE_FRAME_OUT))
{
ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get((disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
diff --git a/decoder/ihevcd_utils.h b/decoder/ihevcd_utils.h
index 7282ae7..893acaa 100644
--- a/decoder/ihevcd_utils.h
+++ b/decoder/ihevcd_utils.h
@@ -51,11 +51,7 @@ IHEVCD_ERROR_T ihevcd_get_tile_pos(pps_t *ps_pps,
WORD32 *pi4_ctb_tile_y,
WORD32 *pi4_tile_idx);
IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec);
-WORD32 ihevcd_get_total_pic_buf_size(WORD32 pic_size,
- WORD32 level,
- WORD32 horz_pad,
- WORD32 vert_pad,
- WORD32 init_num_bufs,
- WORD32 init_extra_bufs,
- WORD32 chroma_only);
+WORD32 ihevcd_get_total_pic_buf_size(codec_t *ps_codec,
+ WORD32 wd,
+ WORD32 ht);
#endif /* _IHEVCD_UTILS_H_ */
diff --git a/decoder/ihevcd_version.c b/decoder/ihevcd_version.c
index 6ec5992..30499d6 100644
--- a/decoder/ihevcd_version.c
+++ b/decoder/ihevcd_version.c
@@ -62,7 +62,7 @@
* Version string. First two digits signify major version and last two minor
* Increment major version for API change or major feature update
*/
-#define CODEC_RELEASE_VER "04.05"
+#define CODEC_RELEASE_VER "05.00"
/**
* Vendor name
*/