From e3d6224dca4eb80297009b1a753aa65cb0117bd8 Mon Sep 17 00:00:00 2001 From: Harish Mahendrakar Date: Mon, 31 Aug 2015 09:57:29 +0530 Subject: Reduced memory requirements Memory allocations are now done based on contents of SPS API changed to move allocations inside the library Change-Id: Ia4333cc2c01d7402dfe05e55e3c8a770a86be693 --- decoder/ihevcd_api.c | 2530 ++++++++++++---------------------------- decoder/ihevcd_cxa.h | 141 +-- decoder/ihevcd_decode.c | 38 +- decoder/ihevcd_mv_merge.c | 2 +- decoder/ihevcd_parse_headers.c | 17 +- decoder/ihevcd_structs.h | 113 +- decoder/ihevcd_utils.c | 202 +--- decoder/ihevcd_utils.h | 10 +- decoder/ihevcd_version.c | 2 +- 9 files changed, 908 insertions(+), 2147 deletions(-) (limited to 'decoder') 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,11 +1099,10 @@ WORD32 ihevcd_init(codec_t *ps_codec) ******************************************************************************* * * @brief -* Gets number of memory records required by 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 @@ -1642,814 +1117,260 @@ WORD32 ihevcd_init(codec_t *ps_codec) * ******************************************************************************* */ -WORD32 ihevcd_get_num_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) { + WORD32 size; + void *pv_buf; + UWORD8 *pu1_buf; + WORD32 i; + codec_t *ps_codec; + IV_API_CALL_STATUS_T status = IV_SUCCESS; + 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; - 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; + /* Request memory for HEVCD object */ + ps_create_op->s_ivd_create_op_t.pv_handle = NULL; - 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); + 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; - 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; - } + 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; - } -#endif //APPLY_CONCEALMENT + (*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; - return IV_SUCCESS; + memset(ps_codec, 0, sizeof(codec_t)); -} - -/** -******************************************************************************* -* -* @brief -* Fills memory requirements of 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_fill_num_mem_rec(void *pv_api_ip, void *pv_api_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 i; - WORD32 max_num_4x4_cols; - IV_API_CALL_STATUS_T status = IV_SUCCESS; - no_of_mem_rec_filled = 0; - - //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); - - 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; - - 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; - } - - 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; - } - - 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; + ps_codec->e_chroma_fmt = ps_create_ip->s_ivd_create_ip_t.e_output_format; - max_ht_luma = ALIGN64(max_ht_luma); - max_wd_luma = ALIGN64(max_wd_luma); + ps_codec->pf_aligned_alloc = pf_aligned_alloc; + ps_codec->pf_aligned_free = pf_aligned_free; + ps_codec->pv_mem_ctxt = pv_mem_ctxt; + /* 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); - - 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; - } - - 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; - } - - 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; - - /* 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); - - { - /* 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; + /* 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; - 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 -* -* @param[in] pv_api_ip -* Pointer to input argument structure +* Free static memory for the codec * -* @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; - - ps_mem_rec_base = dec_init_ip->s_ivd_init_ip_t.pv_mem_rec_location; - - 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); - - /* 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)); - - if(dec_init_ip->s_ivd_init_ip_t.u4_size - > offsetof(ihevcd_cxa_init_ip_t, i4_level)) - { - ps_codec->i4_init_level = dec_init_ip->i4_level; - - ps_codec->i4_init_level *= 3; - } - else - { - ps_codec->i4_init_level = MAX_LEVEL; - } - - 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; - } + void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf); + void *pv_mem_ctxt; - 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; - } + 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; - 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; - } + ALIGNED_FREE(ps_codec, ps_codec->apv_process_thread_handle[0]); + ALIGNED_FREE(ps_codec, ps_codec->pu1_bitsbuf_static); - 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; - } + 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(ps_codec->i4_init_num_extra_disp_buf > MAX_REF_CNT) + if(ps_codec_obj) { - 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; + pf_aligned_free(pv_mem_ctxt, ps_codec_obj); } - 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++; - } + pps_t *ps_pps = ps_codec->ps_pps_base; + tile_t *ps_tile = ps_codec->ps_tile; 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 */ + + /* One job per row of CTBs */ + size = max_ctb_rows; + + /* 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_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 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_PARSE_MAP]; - ps_codec->pu1_parse_map = (UWORD8 *)ps_mem_rec->pv_base; + size *= sizeof(proc_job_t); - 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; + size += ihevcd_jobq_ctxt_size(); + size = ALIGN4(size); - ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR]; - ps_codec->pv_dpb_mgr = ps_mem_rec->pv_base; + 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; - ps_mem_rec = &ps_mem_rec_base[MEM_REC_PIC_PU_IDX_NEIGHBOR]; + 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 +* Free dynamic memory for the codec +* +* @par Description: +* 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 -* Retrieves mem records passed to the codec +* Initializes from mem records passed to the codec * * @par Description: -* Retrieves memrecs passed earlier +* 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; - - 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); + 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; - 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; - - 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( @@ -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); - - break; - case IV_CMD_FILL_NUM_MEM_REC: - - ret = ihevcd_fill_num_mem_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_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; @@ -1626,16 +1626,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 */ @@ -1661,47 +1651,12 @@ 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 */ 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 */ @@ -1903,20 +1858,37 @@ 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 */ @@ -1981,11 +1959,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 */ @@ -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 @@ -159,59 +159,6 @@ WORD32 ihevcd_get_lvl_idx(WORD32 level) return (lvl_idx); } -/** -******************************************************************************* -* -* @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; -} /** ******************************************************************************* * @@ -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 */ -- cgit v1.2.3