diff options
author | Shivaansh Agrawal <Shivaansh.Agrawal@ittiam.com> | 2020-10-16 23:50:30 +0530 |
---|---|---|
committer | Cherrypicker Worker <android-build-cherrypicker-worker@google.com> | 2022-08-21 20:37:53 +0000 |
commit | 40e55db03d004c00f620c1da847dca09745c0810 (patch) | |
tree | 71ca49ae7cb1872d80113928e2e1aee1a241515c | |
parent | 1797ff521fed73a57ef48c3cb24d4c5f4b38737b (diff) | |
download | libavc-40e55db03d004c00f620c1da847dca09745c0810.tar.gz |
Decoder: add support for QP and block_type map export in library
Bug: 175179303
Test: avcdec -c dec.cfg
Test: atest CtsMediaV2TestCases:CodecDecoderTest
Test: atest VtsHalMediaC2V1_0TargetVideoDecTest
Change-Id: I68f3a85aae1f4bca2c3e1eaad69d8eb7f23481b8
(cherry picked from commit 0033e0fe5e591626ad319669362879224d891f50)
Merged-In: I68f3a85aae1f4bca2c3e1eaad69d8eb7f23481b8
-rwxr-xr-x | FrameInfo.md | 18 | ||||
-rw-r--r-- | common/ih264_defs.h | 8 | ||||
-rw-r--r-- | decoder/ih264d.h | 80 | ||||
-rw-r--r-- | decoder/ih264d_api.c | 69 | ||||
-rw-r--r-- | decoder/ih264d_defs.h | 3 | ||||
-rw-r--r-- | decoder/ih264d_dpb_mgr.c | 4 | ||||
-rw-r--r-- | decoder/ih264d_mb_utils.c | 93 | ||||
-rw-r--r-- | decoder/ih264d_mb_utils.h | 6 | ||||
-rw-r--r-- | decoder/ih264d_parse_headers.c | 1 | ||||
-rw-r--r-- | decoder/ih264d_parse_islice.c | 12 | ||||
-rw-r--r-- | decoder/ih264d_parse_pslice.c | 12 | ||||
-rw-r--r-- | decoder/ih264d_parse_slice.c | 24 | ||||
-rw-r--r-- | decoder/ih264d_structs.h | 29 | ||||
-rw-r--r-- | decoder/ih264d_utils.c | 23 | ||||
-rw-r--r-- | test/decoder/main.c | 227 |
15 files changed, 551 insertions, 58 deletions
diff --git a/FrameInfo.md b/FrameInfo.md new file mode 100755 index 0000000..6351293 --- /dev/null +++ b/FrameInfo.md @@ -0,0 +1,18 @@ +## Frame Info exported from libAVC + +### Introduction +QP and block type maps for H264 are defined for each 8x8 MB sub-block. +The QP values defined as unsigned 8-bit numbers can range from <0, 51> and the block type can +be INTER/INTRA/SKIP. Set the “u4_frame_info_enable” flag to enable encoder/decoder to populate +and return the qp values and block type data in their output structures ih264e_video_encode_op_t +and ih264d_video_decode_op_t respectively via pu1_8x8_blk_qp_map and pu1_8x8_blk_type_map. + +### Mapping to the frame +Let’s say, a frame has a total of ‘n’ MBs (each 16x16). Since the QP and block type are defined +for each 8x8 block, hence each MB will have 4 entries in the maps. Thus, a total of n x 4 entries +for each frame. Qp and block type values for each 8x8 block are stored in raster scan order. Refer +to ih264d.h for details. + +### Plugin/Application +The encoder/decoder keeps the QP and block type map as a part of its output handle. The plugins can +access these data through the output structure. diff --git a/common/ih264_defs.h b/common/ih264_defs.h index 9c84be9..d9fea26 100644 --- a/common/ih264_defs.h +++ b/common/ih264_defs.h @@ -276,6 +276,14 @@ typedef enum MAX_MBTYPES, }MBTYPES_T; +/* Pred Modes */ +enum +{ + BLOCK_TYPE_INTER_MB = 0, + BLOCK_TYPE_INTRA_MB = 1, + BLOCK_TYPE_SKIP_MB = 2 +}; + /* Prediction list */ /* Do not change enum values */ enum diff --git a/decoder/ih264d.h b/decoder/ih264d.h index fa9d7f1..bee6b34 100644 --- a/decoder/ih264d.h +++ b/decoder/ih264d.h @@ -79,6 +79,8 @@ IV_API_CALL_STATUS_T ih264d_api_function(iv_obj_t *ps_handle, void *pv_api_ip,vo typedef enum { IH264D_VID_HDR_DEC_NUM_FRM_BUF_NOT_SUFFICIENT = IVD_DUMMY_ELEMENT_FOR_CODEC_EXTENSIONS + 1, + IH264D_FRAME_INFO_OP_BUF_NULL, + IH264D_INSUFFICIENT_METADATA_BUFFER, }IH264D_ERROR_CODES_T; @@ -109,6 +111,11 @@ typedef struct{ typedef struct { ivd_create_ip_t s_ivd_create_ip_t; + + /** + * enable_frm_info + */ + UWORD32 u4_enable_frame_info; }ih264d_create_ip_t; @@ -124,11 +131,84 @@ typedef struct{ typedef struct { ivd_video_decode_ip_t s_ivd_video_decode_ip_t; + + /** + * 8x8 block QP map size + */ + UWORD32 u4_8x8_blk_qp_map_size; + + /** + * 8x8 block QP map + */ + UWORD8 *pu1_8x8_blk_qp_map; + + /** + * 8x8 block type map size + */ + UWORD32 u4_8x8_blk_type_map_size; + + /** + * 8x8 block type map + */ + UWORD8 *pu1_8x8_blk_type_map; }ih264d_video_decode_ip_t; +/*****************************************************************************/ +/* QP and block type maps are defined for each 8x8 MB sub-block. */ +/* QP can range from <0, 51> and block type can be INTER/INTRA/SKIP. */ +/* */ +/* Let’s say, a frame has a total of ‘m’ MBs (each 16x16). Since the QP */ +/* and block type are defined for each 8x8 block, hence each MB has */ +/* 4 entries giving m x 4 total entires for QP and block type map each. */ +/* */ +/* For example, for a frame of size 60x60 shown in the figure down, both */ +/* maps (QP and MB type) have the same layout. */ +/* Each block represents an 8x8 sub-block. Both width and height are aligned */ +/* to next largest multiple of 8, 64 in this case. */ +/* */ +/* 0 8 16 24 32 40 48 56 64 */ +/* 0 ------------------------------------------------ */ +/* | 0th | 1st | 2nd | 3rd | 4th | 5th | 6th | 7th | */ +/* 8 ------------------------------------------------ */ +/* | 8th | 9th | 10th | - | - | - | - | - | */ +/* 16 ------------------------------------------------ */ +/* | - | - | - | - | - | - | - | - | */ +/* 24 ------------------------------------------------ */ +/* | - | - | - | - | - | - | - | - | */ +/* 32 ------------------------------------------------ */ +/* | - | - | - | - | - | - | - | - | */ +/* 40 ------------------------------------------------ */ +/* | - | - | - | - | - | - | - | - | */ +/* 48 ------------------------------------------------ */ +/* | - | - | - | - | - | - | - | - | */ +/* 56 ------------------------------------------------ */ +/* | - | - | - | - | - | - | - | - | */ +/* 64 ------------------------------------------------ */ +/* */ +/*****************************************************************************/ typedef struct{ ivd_video_decode_op_t s_ivd_video_decode_op_t; + + /** + * 8x8 block QP map size + */ + UWORD32 u4_8x8_blk_qp_map_size; + + /** + * 8x8 block QP map + */ + UWORD8 *pu1_8x8_blk_qp_map; + + /** + * 8x8 block type map size + */ + UWORD32 u4_8x8_blk_type_map_size; + + /** + * 8x8 block type map + */ + UWORD8 *pu1_8x8_blk_type_map; }ih264d_video_decode_op_t; diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c index 923c519..cb6462e 100644 --- a/decoder/ih264d_api.c +++ b/decoder/ih264d_api.c @@ -506,6 +506,20 @@ static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, return (IV_FAIL); } + { + dec_struct_t *ps_dec = (dec_struct_t *)(ps_handle->pv_codec_handle); + if(ps_dec->u1_enable_mb_info) + { + if(!ps_ip->pu1_8x8_blk_qp_map && !ps_ip->pu1_8x8_blk_type_map) + { + ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 + << IVD_UNSUPPORTEDPARAM; + ps_op->s_ivd_video_decode_op_t.u4_error_code |= + IH264D_FRAME_INFO_OP_BUF_NULL; + return IV_FAIL; + } + } + } } break; @@ -1491,6 +1505,7 @@ WORD32 ih264d_allocate_static_bufs(iv_obj_t **dec_hdl, void *pv_api_ip, void *pv ps_dec->u4_share_disp_buf = 0; } + ps_dec->u1_enable_mb_info = ps_create_ip->u4_enable_frame_info; ps_dec->pf_aligned_alloc = pf_aligned_alloc; ps_dec->pf_aligned_free = pf_aligned_free; ps_dec->pv_mem_ctxt = pv_mem_ctxt; @@ -2298,6 +2313,20 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) } + if(ps_dec->u1_enable_mb_info && (ps_dec->i4_header_decoded & DECODED_SPS_MASK)) + { + UWORD32 blk_qp_map_size = ps_h264d_dec_ip->u4_8x8_blk_qp_map_size; + UWORD32 blk_type_map_size = ps_h264d_dec_ip->u4_8x8_blk_type_map_size; + UWORD32 blk_8x8_map_size = ps_dec->u4_total_mbs << 2; + if ((ps_h264d_dec_ip->pu1_8x8_blk_qp_map && blk_qp_map_size < blk_8x8_map_size) || + (ps_h264d_dec_ip->pu1_8x8_blk_type_map && blk_type_map_size < blk_8x8_map_size)) + { + ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; + ps_dec_op->u4_error_code |= IH264D_INSUFFICIENT_METADATA_BUFFER; + return IV_FAIL; + } + } + if(ps_dec->u1_flushfrm) { if(ps_dec->u1_init_dec_flag == 0) @@ -2328,6 +2357,26 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows; ps_dec->u4_output_present = 1; + if(ps_dec->u1_enable_mb_info) + { + UWORD32 disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id; + if(ps_h264d_dec_ip->pu1_8x8_blk_qp_map) + { + ps_h264d_dec_op->pu1_8x8_blk_qp_map = ps_h264d_dec_ip->pu1_8x8_blk_qp_map; + ps_h264d_dec_op->u4_8x8_blk_qp_map_size = ps_dec->u4_total_mbs << 2; + ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_qp_map, + ps_dec->as_buf_id_info_map[disp_buf_id].pu1_qp_map, + ps_dec->u4_total_mbs << 2); + } + if(ps_h264d_dec_ip->pu1_8x8_blk_type_map) + { + ps_h264d_dec_op->pu1_8x8_blk_type_map = ps_h264d_dec_ip->pu1_8x8_blk_type_map; + ps_h264d_dec_op->u4_8x8_blk_type_map_size = ps_dec->u4_total_mbs << 2; + ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_type_map, + ps_dec->as_buf_id_info_map[disp_buf_id].pu1_mb_type_map, + ps_dec->u4_total_mbs << 2); + } + } } ih264d_export_sei_params(&ps_dec_op->s_sei_decode_op, ps_dec); @@ -2820,6 +2869,26 @@ WORD32 ih264d_video_decode(iv_obj_t *dec_hdl, void *pv_api_ip, void *pv_api_op) } + if(ps_dec->u1_enable_mb_info && ps_dec->u4_output_present) + { + UWORD32 disp_buf_id = ps_dec->s_disp_op.u4_disp_buf_id; + if(ps_h264d_dec_ip->pu1_8x8_blk_qp_map) + { + ps_h264d_dec_op->pu1_8x8_blk_qp_map = ps_h264d_dec_ip->pu1_8x8_blk_qp_map; + ps_h264d_dec_op->u4_8x8_blk_qp_map_size = ps_dec->u4_total_mbs << 2; + ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_qp_map, + ps_dec->as_buf_id_info_map[disp_buf_id].pu1_qp_map, + ps_dec->u4_total_mbs << 2); + } + if(ps_h264d_dec_ip->pu1_8x8_blk_type_map) + { + ps_h264d_dec_op->pu1_8x8_blk_type_map = ps_h264d_dec_ip->pu1_8x8_blk_type_map; + ps_h264d_dec_op->u4_8x8_blk_type_map_size = ps_dec->u4_total_mbs << 2; + ih264_memcpy(ps_h264d_dec_op->pu1_8x8_blk_type_map, + ps_dec->as_buf_id_info_map[disp_buf_id].pu1_mb_type_map, + ps_dec->u4_total_mbs << 2); + } + } /*Data memory barrier instruction,so that yuv write by the library is complete*/ DATA_SYNC(); diff --git a/decoder/ih264d_defs.h b/decoder/ih264d_defs.h index aeb2520..894fc78 100644 --- a/decoder/ih264d_defs.h +++ b/decoder/ih264d_defs.h @@ -122,6 +122,9 @@ * greater than the allocated buffer size*/ #define EXTRA_BS_OFFSET 16*16*2 +#define DECODED_SPS_MASK 1 +#define DECODED_PPS_MASK 2 + /** *************************************************************************** * Enum to hold various mem records being request diff --git a/decoder/ih264d_dpb_mgr.c b/decoder/ih264d_dpb_mgr.c index ce977d7..f5974ba 100644 --- a/decoder/ih264d_dpb_mgr.c +++ b/decoder/ih264d_dpb_mgr.c @@ -118,7 +118,7 @@ void ih264d_free_ref_pic_mv_bufs(void* pv_dec, UWORD8 pic_buf_id) pic_buf_id, BUF_MGR_REF); ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, - ps_dec->au1_pic_buf_id_mv_buf_id_map[pic_buf_id], + ps_dec->as_buf_id_info_map[pic_buf_id].mv_buf_id, BUF_MGR_REF); } /*! @@ -1413,7 +1413,7 @@ void ih264d_release_pics_in_dpb(void *pv_dec, i, BUF_MGR_REF); ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, - ps_dec->au1_pic_buf_id_mv_buf_id_map[i], + ps_dec->as_buf_id_info_map[i].mv_buf_id, BUF_MGR_REF); } } diff --git a/decoder/ih264d_mb_utils.c b/decoder/ih264d_mb_utils.c index ded2756..213fbc8 100644 --- a/decoder/ih264d_mb_utils.c +++ b/decoder/ih264d_mb_utils.c @@ -32,6 +32,7 @@ */ #include <string.h> #include <stdlib.h> +#include "ih264_defs.h" #include "ih264d_bitstrm.h" #include "ih264d_defs.h" #include "ih264d_debug.h" @@ -1468,3 +1469,95 @@ void ih264d_transfer_mb_group_data(dec_struct_t * ps_dec, } +/* + ************************************************************************** + * \if Function name : ih264d_populate_mb_info_map \endif + * + * \brief + * Populate mb info values for mbtype and qp map at 8x8 level for each MB + * + * \return + * void + * + ************************************************************************** + */ +void ih264d_populate_mb_info_map(dec_struct_t *ps_dec, dec_mb_info_t *ps_cur_mb_info, + UWORD16 u2_blk_x, UWORD16 u2_blk_y, UWORD8 u1_qp_val) +{ + UWORD16 stride = ps_dec->u2_frm_wd_in_mbs << 1; + UWORD8 *pu1_qp_map = ps_dec->as_buf_id_info_map[ps_dec->u1_pic_buf_id].pu1_qp_map; + UWORD8 *pu1_mb_type_map = ps_dec->as_buf_id_info_map[ps_dec->u1_pic_buf_id].pu1_mb_type_map; + + UWORD8 cur_mb_type = ps_cur_mb_info->u1_mb_type; + UWORD8 mb_is_inter = + (cur_mb_type == P_MB || cur_mb_type == B_MB || cur_mb_type == SP_MB); + UWORD8 mb_type = mb_is_inter ? BLOCK_TYPE_INTER_MB : BLOCK_TYPE_INTRA_MB; + if(cur_mb_type == MB_SKIP) mb_type = BLOCK_TYPE_SKIP_MB; + + // populate qp_map, mb_type_map for mbx, mby + // since we store values at 8x8 level, duplicate values for blocks while storing in map + if(ps_dec->ps_cur_slice->u1_mbaff_frame_flag) + { + UWORD8 bot_mb = ps_cur_mb_info->u1_topmb ? 0 : 1; + if(ps_cur_mb_info->u1_mb_field_decodingflag) + { + pu1_qp_map[u2_blk_x + stride * ( u2_blk_y + bot_mb)] = + pu1_qp_map[u2_blk_x + 1 + stride * ( u2_blk_y + bot_mb)] = + pu1_qp_map[u2_blk_x + stride * ((u2_blk_y + 2) + bot_mb)] = + pu1_qp_map[u2_blk_x + 1 + stride * ((u2_blk_y + 2) + bot_mb)] = + u1_qp_val; + + pu1_mb_type_map[u2_blk_x + stride * ( u2_blk_y + bot_mb)] = + pu1_mb_type_map[u2_blk_x + 1 + stride * ( u2_blk_y + bot_mb)] = + pu1_mb_type_map[u2_blk_x + stride * ((u2_blk_y + 2) + bot_mb)] = + pu1_mb_type_map[u2_blk_x + 1 + stride * ((u2_blk_y + 2) + bot_mb)] = + mb_type; + } + else + { + pu1_qp_map[u2_blk_x + stride * ( u2_blk_y + (2 * bot_mb))] = + pu1_qp_map[u2_blk_x + 1 + stride * ( u2_blk_y + (2 * bot_mb))] = + pu1_qp_map[u2_blk_x + stride * ((u2_blk_y + 1) + (2 * bot_mb))] = + pu1_qp_map[u2_blk_x + 1 + stride * ((u2_blk_y + 1) + (2 * bot_mb))] = + u1_qp_val; + + pu1_mb_type_map[u2_blk_x + stride * ( u2_blk_y + (2 * bot_mb))] = + pu1_mb_type_map[u2_blk_x + 1 + stride * ( u2_blk_y + (2 * bot_mb))] = + pu1_mb_type_map[u2_blk_x + stride * ((u2_blk_y + 1) + (2 * bot_mb))] = + pu1_mb_type_map[u2_blk_x + 1 + stride * ((u2_blk_y + 1) + (2 * bot_mb))] = + mb_type; + } + } + else + { + if(ps_dec->ps_cur_slice->u1_field_pic_flag) + { + UWORD8 bot_mb = ps_dec->ps_cur_slice->u1_bottom_field_flag; + pu1_qp_map[u2_blk_x + stride * (2 * u2_blk_y + bot_mb)] = + pu1_qp_map[u2_blk_x + 1 + stride * (2 * u2_blk_y + bot_mb)] = + pu1_qp_map[u2_blk_x + stride * (2 * (u2_blk_y + 1) + bot_mb)] = + pu1_qp_map[u2_blk_x + 1 + stride * (2 * (u2_blk_y + 1) + bot_mb)] = + u1_qp_val; + + pu1_mb_type_map[u2_blk_x + stride * (2 * u2_blk_y + bot_mb)] = + pu1_mb_type_map[u2_blk_x + 1 + stride * (2 * u2_blk_y + bot_mb)] = + pu1_mb_type_map[u2_blk_x + stride * (2 * (u2_blk_y + 1) + bot_mb)] = + pu1_mb_type_map[u2_blk_x + 1 + stride * (2 * (u2_blk_y + 1) + bot_mb)] = + mb_type; + } + else + { + pu1_qp_map[u2_blk_x + stride * u2_blk_y ] = + pu1_qp_map[u2_blk_x + 1 + stride * u2_blk_y ] = + pu1_qp_map[u2_blk_x + stride * (u2_blk_y + 1)] = + pu1_qp_map[u2_blk_x + 1 + stride * (u2_blk_y + 1)] = + u1_qp_val; + + pu1_mb_type_map[u2_blk_x + stride * u2_blk_y ] = + pu1_mb_type_map[u2_blk_x + 1 + stride * u2_blk_y ] = + pu1_mb_type_map[u2_blk_x + stride * (u2_blk_y + 1)] = + pu1_mb_type_map[u2_blk_x + 1 + stride * (u2_blk_y + 1)] = + mb_type; + } + } +} diff --git a/decoder/ih264d_mb_utils.h b/decoder/ih264d_mb_utils.h index 158319a..25011f5 100644 --- a/decoder/ih264d_mb_utils.h +++ b/decoder/ih264d_mb_utils.h @@ -288,6 +288,12 @@ void ih264d_transfer_mb_group_data(dec_struct_t * ps_dec, const UWORD8 u1_end_of_row_next /* Next n-Mb End of Row Flag */ ); +void ih264d_populate_mb_info_map(dec_struct_t *ps_dec, + dec_mb_info_t *ps_cur_mb_info, + UWORD16 u2_blk_x, + UWORD16 u2_blk_y, + UWORD8 u1_val); + //void FillRandomData(UWORD8 *pu1_buf, WORD32 u4_bufSize); #endif /* _MB_UTILS_H_ */ diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c index 8f0cb40..dc11adb 100644 --- a/decoder/ih264d_parse_headers.c +++ b/decoder/ih264d_parse_headers.c @@ -1128,6 +1128,7 @@ WORD32 ih264d_parse_sps(dec_struct_t *ps_dec, dec_bit_stream_t *ps_bitstrm) ps_dec->u2_pic_wd = u2_pic_wd; ps_dec->u2_pic_ht = u2_pic_ht; + ps_dec->u4_total_mbs = ps_seq->u2_total_num_of_mbs << (1 - ps_seq->u1_frame_mbs_only_flag); /* Determining the Width and Height of Frame from that of Picture */ ps_dec->u2_frm_wd_y = u2_frm_wd_y; diff --git a/decoder/ih264d_parse_islice.c b/decoder/ih264d_parse_islice.c index 0b8111a..21c50ea 100644 --- a/decoder/ih264d_parse_islice.c +++ b/decoder/ih264d_parse_islice.c @@ -865,6 +865,12 @@ WORD32 ih264d_parse_islice_data_cavlc(dec_struct_t * ps_dec, ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp; } + if(ps_dec->u1_enable_mb_info) + { + ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1, + ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp); + } + uc_more_data_flag = MORE_RBSP_DATA(ps_bitstrm); if(u1_mbaff) @@ -1084,6 +1090,12 @@ WORD32 ih264d_parse_islice_data_cabac(dec_struct_t * ps_dec, ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp; } + if(ps_dec->u1_enable_mb_info) + { + ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1, + ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp); + } + if(u1_mbaff) { ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info); diff --git a/decoder/ih264d_parse_pslice.c b/decoder/ih264d_parse_pslice.c index 77ea4b3..beb24d4 100644 --- a/decoder/ih264d_parse_pslice.c +++ b/decoder/ih264d_parse_pslice.c @@ -1003,6 +1003,12 @@ WORD32 ih264d_parse_inter_slice_data_cabac(dec_struct_t * ps_dec, } + if(ps_dec->u1_enable_mb_info) + { + ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1, + ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp); + } + if(u1_mbaff) { ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info); @@ -1354,6 +1360,12 @@ WORD32 ih264d_parse_inter_slice_data_cavlc(dec_struct_t * ps_dec, } ps_cur_deblk_mb->u1_mb_qp = ps_dec->u1_qp; + if(ps_dec->u1_enable_mb_info) + { + ih264d_populate_mb_info_map(ps_dec, ps_cur_mb_info, ps_cur_mb_info->u2_mbx << 1, + ps_cur_mb_info->u2_mby << 1, ps_cur_deblk_mb->u1_mb_qp); + } + if(u1_mbaff) { ih264d_update_mbaff_left_nnz(ps_dec, ps_cur_mb_info); diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c index 12fbeeb..a0e6eb5 100644 --- a/decoder/ih264d_parse_slice.c +++ b/decoder/ih264d_parse_slice.c @@ -320,7 +320,7 @@ WORD32 ih264d_start_of_pic(dec_struct_t *ps_dec, j, BUF_MGR_REF); ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, - ps_dec->au1_pic_buf_id_mv_buf_id_map[j], + ps_dec->as_buf_id_info_map[j].mv_buf_id, BUF_MGR_REF); ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, j, @@ -434,7 +434,17 @@ WORD32 ih264d_start_of_pic(dec_struct_t *ps_dec, memcpy(&ps_cur_pic->s_sei_pic, ps_dec->ps_sei, sizeof(sei)); ps_cur_pic->u1_mv_buf_id = cur_mv_buf_id; - ps_dec->au1_pic_buf_id_mv_buf_id_map[cur_pic_buf_id] = cur_mv_buf_id; + ps_dec->as_buf_id_info_map[cur_pic_buf_id].mv_buf_id = cur_mv_buf_id; + if(ps_dec->u1_enable_mb_info) + { + UWORD32 mb_info_map_size = ps_dec->u4_total_mbs << 2; + ps_dec->as_buf_id_info_map[cur_pic_buf_id].pu1_qp_map + = ps_dec->pu1_qp_map_base + cur_pic_buf_id * mb_info_map_size; + ps_dec->as_buf_id_info_map[cur_pic_buf_id].pu1_mb_type_map + = ps_dec->pu1_mb_type_map_base + cur_pic_buf_id * mb_info_map_size; + memset(ps_dec->as_buf_id_info_map[cur_pic_buf_id].pu1_qp_map, 0, mb_info_map_size); + memset(ps_dec->as_buf_id_info_map[cur_pic_buf_id].pu1_mb_type_map, 0, mb_info_map_size); + } ps_cur_pic->pu1_col_zero_flag = (UWORD8 *)ps_col_mv->pv_col_zero_flag; ps_cur_pic->ps_mv = (mv_pred_t *)ps_col_mv->pv_mv; @@ -471,7 +481,7 @@ WORD32 ih264d_start_of_pic(dec_struct_t *ps_dec, j, BUF_MGR_REF); ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, - ps_dec->au1_pic_buf_id_mv_buf_id_map[j], + ps_dec->as_buf_id_info_map[j].mv_buf_id, BUF_MGR_REF); ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, j, @@ -505,7 +515,7 @@ WORD32 ih264d_start_of_pic(dec_struct_t *ps_dec, ps_dec->apv_buf_id_pic_buf_map[cur_pic_buf_id] = (void *)ps_cur_pic; ps_cur_pic->u1_mv_buf_id = cur_mv_buf_id; - ps_dec->au1_pic_buf_id_mv_buf_id_map[cur_pic_buf_id] = cur_mv_buf_id; + ps_dec->as_buf_id_info_map[cur_pic_buf_id].mv_buf_id = cur_mv_buf_id; ps_cur_pic->pu1_col_zero_flag = (UWORD8 *)ps_col_mv->pv_col_zero_flag; ps_cur_pic->ps_mv = (mv_pred_t *)ps_col_mv->pv_mv; @@ -793,7 +803,7 @@ WORD32 ih264d_end_of_pic_dispbuf_mgr(dec_struct_t * ps_dec) BUF_MGR_REF); /* Mark mv buf as needed for reference */ ih264_buf_mgr_set_status((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, - ps_dec->au1_pic_buf_id_mv_buf_id_map[ps_dec->u1_pic_buf_id], + ps_dec->as_buf_id_info_map[ps_dec->u1_pic_buf_id].mv_buf_id, BUF_MGR_REF); ps_dec->au1_pic_buf_ref_flag[ps_dec->u1_pic_buf_id] = 1; } @@ -852,7 +862,7 @@ WORD32 ih264d_end_of_pic_dispbuf_mgr(dec_struct_t * ps_dec) if(ps_dec->au1_pic_buf_ref_flag[ps_dec->u1_pic_buf_id] == 0) { ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, - ps_dec->au1_pic_buf_id_mv_buf_id_map[ps_dec->u1_pic_buf_id], + ps_dec->as_buf_id_info_map[ps_dec->u1_pic_buf_id].mv_buf_id, BUF_MGR_REF); ps_dec->au1_pic_buf_ref_flag[ps_dec->u1_pic_buf_id] = 0; @@ -893,7 +903,7 @@ void ih264d_err_pic_dispbuf_mgr(dec_struct_t *ps_dec) ps_dec->u1_pic_buf_id, BUF_MGR_REF); ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr, - ps_dec->au1_pic_buf_id_mv_buf_id_map[ps_dec->u1_pic_buf_id], + ps_dec->as_buf_id_info_map[ps_dec->u1_pic_buf_id].mv_buf_id, BUF_MGR_REF); ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_pic_buf_mgr, ps_dec->u1_pic_buf_id, diff --git a/decoder/ih264d_structs.h b/decoder/ih264d_structs.h index e6a962c..bcab1ea 100644 --- a/decoder/ih264d_structs.h +++ b/decoder/ih264d_structs.h @@ -714,6 +714,28 @@ typedef struct WORD16 ai2_level[64]; }tu_blk8x8_coeff_data_t; +/** + * Reference mapping from pic_buf_id to mv_buf_id and pointers to corresponding qp_map and + * mb_type_map + */ +typedef struct +{ + /** + * mv buf id + */ + WORD32 mv_buf_id; + + /** + * qp_map buffer + */ + UWORD8 *pu1_qp_map; + + /** + * mbtype buffer + */ + UWORD8 *pu1_mb_type_map; +}ref_map_t; + /** Aggregating structure that is globally available */ typedef struct _DecStruct { @@ -751,6 +773,7 @@ typedef struct _DecStruct UWORD16 u2_pic_wd; /** Width of the picture being decoded */ UWORD16 u2_pic_ht; /** Height of the picture being decoded */ + UWORD32 u4_total_mbs; /** Total MBs in the picture being decoded */ UWORD8 u1_first_slice_in_stream; UWORD8 u1_mb_ngbr_availablity; @@ -761,6 +784,10 @@ typedef struct _DecStruct UWORD8 u1_qp_y_rem6; UWORD8 u1_qp_u_rem6; + /** mb_info variables - qp_map, mb_type_map */ + UWORD8 u1_enable_mb_info; + UWORD8 *pu1_qp_map_base; + UWORD8 *pu1_mb_type_map_base; /*********************************/ /* configurable mb-group numbers */ /* very critical to the decoder */ @@ -1390,7 +1417,7 @@ typedef struct _DecStruct void *apv_buf_id_pic_buf_map[MAX_DISP_BUFS_NEW]; - UWORD8 au1_pic_buf_id_mv_buf_id_map[MAX_DISP_BUFS_NEW]; + ref_map_t as_buf_id_info_map[MAX_DISP_BUFS_NEW]; UWORD8 au1_pic_buf_ref_flag[MAX_DISP_BUFS_NEW]; diff --git a/decoder/ih264d_utils.c b/decoder/ih264d_utils.c index 93c379b..9d616d3 100644 --- a/decoder/ih264d_utils.c +++ b/decoder/ih264d_utils.c @@ -2172,6 +2172,22 @@ WORD16 ih264d_allocate_dynamic_bufs(dec_struct_t * ps_dec) memset(pv_buf, 0, size); ps_dec->pu1_pic_buf_base = pv_buf; + /* Allocate memory for mb_info maps */ + if(ps_dec->u1_enable_mb_info) + { + size = (u4_total_mbs << 2) * MAX_DISP_BUFS_NEW; + + pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size); + RETURN_IF((NULL == pv_buf), IV_FAIL); + memset(pv_buf, 0, size); + ps_dec->pu1_qp_map_base = pv_buf; + + pv_buf = ps_dec->pf_aligned_alloc(pv_mem_ctxt, 128, size); + RETURN_IF((NULL == pv_buf), IV_FAIL); + memset(pv_buf, 0, size); + ps_dec->pu1_mb_type_map_base = pv_buf; + } + /* Post allocation Increment Actions */ /***************************************************************************/ @@ -2319,6 +2335,13 @@ WORD16 ih264d_free_dynamic_bufs(dec_struct_t * ps_dec) PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->ps_nbr_mb_row); PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_mv_bank_buf_base); PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_pic_buf_base); + + /* Free memory for mb_info maps */ + if(ps_dec->u1_enable_mb_info) + { + PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_qp_map_base); + PS_DEC_ALIGNED_FREE(ps_dec, ps_dec->pu1_mb_type_map_base); + } return 0; } diff --git a/test/decoder/main.c b/test/decoder/main.c index 046c689..bddf0b8 100644 --- a/test/decoder/main.c +++ b/test/decoder/main.c @@ -73,6 +73,8 @@ #define MAX_DISP_BUFFERS 64 #define EXTRA_DISP_BUFFERS 8 #define STRLENGTH 1000 +#define STR2(x) #x +#define STR(X) STR2(X) //#define TEST_FLUSH #define FLUSH_FRM_CNT 100 @@ -178,6 +180,7 @@ typedef struct { UWORD32 u4_piclen_flag; UWORD32 u4_file_save_flag; + UWORD32 u4_frame_info_enable; UWORD32 u4_chksum_save_flag; UWORD32 u4_max_frm_ts; IV_COLOR_FORMAT_T e_output_chroma_format; @@ -202,6 +205,8 @@ typedef struct CHAR ac_piclen_fname[STRLENGTH]; CHAR ac_ip_fname[STRLENGTH]; CHAR ac_op_fname[STRLENGTH]; + CHAR ac_qp_map_fname[STRLENGTH]; + CHAR ac_blk_type_map_fname[STRLENGTH]; CHAR ac_op_chksum_fname[STRLENGTH]; ivd_out_bufdesc_t s_disp_buffers[MAX_DISP_BUFFERS]; iv_yuv_buf_t s_disp_frm_queue[MAX_DISP_BUFFERS]; @@ -251,8 +256,11 @@ typedef enum VERSION, INPUT_FILE, OUTPUT, + QP_MAP_FILE, + BLK_TYPE_MAP_FILE, CHKSUM, SAVE_OUTPUT, + SAVE_FRAME_INFO, SAVE_CHKSUM, CHROMA_FORMAT, NUM_FRAMES, @@ -295,6 +303,10 @@ static const argument_t argument_mapping[] = "Input file\n"}, {"-o", "--output", OUTPUT, "Output file\n"}, + {"--", "--qp_map_file", QP_MAP_FILE, + "QP map file\n"}, + {"--", "--blk_type_map_file", BLK_TYPE_MAP_FILE, + "Block type map file\n"}, {"--", "--piclen", PICLEN, "Flag to signal if the decoder has to use a file containing number of bytes in each picture to be fed in each call\n"}, {"--", "--piclen_file", PICLEN_FILE, @@ -303,6 +315,8 @@ static const argument_t argument_mapping[] = "Output MD5 Checksum file\n"}, { "-s", "--save_output", SAVE_OUTPUT, "Save Output file\n" }, + { "--", "--save_frame_info", SAVE_FRAME_INFO, + "Save frame_info file\n" }, { "--", "--save_chksum", SAVE_CHKSUM, "Save Check sum file\n" }, {"--", "--chroma_format", CHROMA_FORMAT, @@ -883,12 +897,16 @@ void codec_exit(CHAR *pc_err_message) /*****************************************************************************/ void dump_output(vid_dec_ctx_t *ps_app_ctx, iv_yuv_buf_t *ps_disp_frm_buf, + ih264d_video_decode_op_t *ps_h264d_decode_op, UWORD32 u4_disp_frm_id, FILE *ps_op_file, + FILE *ps_qp_file, + FILE *ps_mb_type_file, FILE *ps_op_chksum_file, WORD32 i4_op_frm_ts, UWORD32 file_save, - UWORD32 chksum_save) + UWORD32 chksum_save, + UWORD32 mbinfo_save) { @@ -933,9 +951,26 @@ void dump_output(vid_dec_ctx_t *ps_app_ctx, release_disp_frame(ps_app_ctx->cocodec_obj, u4_disp_id); - if(0 == file_save && 0 == chksum_save) + if(0 == file_save && 0 == chksum_save && 0 == mbinfo_save) return; + if(0 != mbinfo_save) + { + UWORD8 *buf; + if(ps_h264d_decode_op->pu1_8x8_blk_qp_map && ps_qp_file) + { + buf = ps_h264d_decode_op->pu1_8x8_blk_qp_map; + fwrite(buf, 1, ps_h264d_decode_op->u4_8x8_blk_qp_map_size, ps_qp_file); + fflush(ps_qp_file); + } + if(ps_h264d_decode_op->pu1_8x8_blk_type_map && ps_mb_type_file) + { + buf = ps_h264d_decode_op->pu1_8x8_blk_type_map; + fwrite(buf, 1, ps_h264d_decode_op->u4_8x8_blk_type_map_size, ps_mb_type_file); + fflush(ps_mb_type_file); + } + } + if(NULL == s_dump_disp_frm_buf.pv_y_buf) return; @@ -950,7 +985,7 @@ void dump_output(vid_dec_ctx_t *ps_app_ctx, } #else - if(0 != file_save) + if(0 != file_save && ps_op_file) { UWORD8 *buf; @@ -977,7 +1012,7 @@ void dump_output(vid_dec_ctx_t *ps_app_ctx, } - if(0 != chksum_save) + if(0 != chksum_save && ps_op_chksum_file) { UWORD8 au1_y_chksum[16]; UWORD8 au1_u_chksum[16]; @@ -1178,22 +1213,34 @@ void parse_argument(vid_dec_ctx_t *ps_app_ctx, CHAR *argument, CHAR *value) case VERSION: break; case INPUT_FILE: - sscanf(value, "%s", ps_app_ctx->ac_ip_fname); + sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_ip_fname); //input_passed = 1; break; case OUTPUT: - sscanf(value, "%s", ps_app_ctx->ac_op_fname); + sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_op_fname); + break; + + case QP_MAP_FILE: + sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_qp_map_fname); + break; + + case BLK_TYPE_MAP_FILE: + sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_blk_type_map_fname); break; case CHKSUM: - sscanf(value, "%s", ps_app_ctx->ac_op_chksum_fname); + sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_op_chksum_fname); break; case SAVE_OUTPUT: sscanf(value, "%d", &ps_app_ctx->u4_file_save_flag); break; + case SAVE_FRAME_INFO: + sscanf(value, "%d", &ps_app_ctx->u4_frame_info_enable); + break; + case SAVE_CHKSUM: sscanf(value, "%d", &ps_app_ctx->u4_chksum_save_flag); break; @@ -1303,7 +1350,7 @@ void parse_argument(vid_dec_ctx_t *ps_app_ctx, CHAR *argument, CHAR *value) break; case PICLEN_FILE: - sscanf(value, "%s", ps_app_ctx->ac_piclen_fname); + sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_piclen_fname); break; case DISABLE_DEBLOCK_LEVEL: sscanf(value, "%d", &ps_app_ctx->u4_disable_dblk_level); @@ -1636,6 +1683,10 @@ void flush_output(iv_obj_t *codec_obj, UWORD8 *pu1_bs_buf, UWORD32 *pu4_op_frm_ts, FILE *ps_op_file, + FILE *ps_qp_file, + FILE *ps_mb_type_file, + UWORD8 *pu1_qp_map_buf, + UWORD8 *pu1_blk_type_map_buf, FILE *ps_op_chksum_file, UWORD32 u4_ip_frm_ts, UWORD32 u4_bytes_remaining) @@ -1692,6 +1743,10 @@ void flush_output(iv_obj_t *codec_obj, ps_out_buf->u4_num_bufs; ps_video_decode_op->u4_size = sizeof(ih264d_video_decode_op_t); + s_h264d_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf; + s_h264d_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf; + s_h264d_decode_ip.u4_8x8_blk_qp_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6; + s_h264d_decode_ip.u4_8x8_blk_type_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6; /*****************************************************************************/ /* API Call: Video Decode */ @@ -1847,19 +1902,19 @@ void flush_output(iv_obj_t *codec_obj, if (NULL == ps_op_file) { CHAR ac_error_str[STRLENGTH]; - sprintf(ac_error_str, "Could not open output file %s", - cur_fname); + snprintf(ac_error_str, sizeof(ac_error_str), + "Could not open output file %s", cur_fname); codec_exit(ac_error_str); } } } - dump_output(ps_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), - ps_video_decode_op->u4_disp_buf_id, ps_op_file, - ps_op_chksum_file, - *pu4_op_frm_ts, ps_app_ctx->u4_file_save_flag, - ps_app_ctx->u4_chksum_save_flag); + dump_output(ps_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), &s_h264d_decode_op, + ps_video_decode_op->u4_disp_buf_id, ps_op_file, ps_qp_file, + ps_mb_type_file, ps_op_chksum_file, *pu4_op_frm_ts, + ps_app_ctx->u4_file_save_flag, ps_app_ctx->u4_chksum_save_flag, + ps_app_ctx->u4_frame_info_enable); if (extn != NULL) fclose(ps_op_file); (*pu4_op_frm_ts)++; @@ -1923,11 +1978,15 @@ int main(WORD32 argc, CHAR *argv[]) FILE *ps_piclen_file = NULL; FILE *ps_ip_file = NULL; FILE *ps_op_file = NULL; + FILE *ps_qp_file = NULL; + FILE *ps_mb_type_file = NULL; FILE *ps_op_chksum_file = NULL; WORD32 ret; CHAR ac_error_str[STRLENGTH]; vid_dec_ctx_t s_app_ctx; UWORD8 *pu1_bs_buf = NULL; + UWORD8 *pu1_qp_map_buf = NULL; + UWORD8 *pu1_blk_type_map_buf = NULL; ivd_out_bufdesc_t *ps_out_buf; UWORD32 u4_num_bytes_dec = 0; @@ -2037,6 +2096,7 @@ int main(WORD32 argc, CHAR *argv[]) s_app_ctx.paused = 0; //s_app_ctx.u4_output_present = 0; s_app_ctx.u4_chksum_save_flag = 0; + s_app_ctx.u4_frame_info_enable = 0; s_app_ctx.get_stride = &default_get_stride; @@ -2104,8 +2164,8 @@ int main(WORD32 argc, CHAR *argv[]) strcpy(ac_cfg_fname, argv[i + 1]); if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL) { - sprintf(ac_error_str, "Could not open Configuration file %s", - ac_cfg_fname); + snprintf(ac_error_str, sizeof(ac_error_str), + "Could not open Configuration file %s", ac_cfg_fname); codec_exit(ac_error_str); } read_cfg_file(&s_app_ctx, fp_cfg_file); @@ -2121,7 +2181,7 @@ int main(WORD32 argc, CHAR *argv[]) { if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL) { - sprintf(ac_error_str, "Could not open Configuration file %s", + snprintf(ac_error_str, sizeof(ac_error_str), "Could not open Configuration file %s", ac_cfg_fname); codec_exit(ac_error_str); } @@ -2129,10 +2189,10 @@ int main(WORD32 argc, CHAR *argv[]) fclose(fp_cfg_file); } #else - sprintf(filename_with_path, "%s/%s", homedir, ac_cfg_fname); + snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", homedir, ac_cfg_fname); if((fp_cfg_file = fopen(filename_with_path, "r")) == NULL) { - sprintf(ac_error_str, "Could not open Configuration file %s", + snprintf(ac_error_str, sizeof(ac_error_str),"Could not open Configuration file %s", ac_cfg_fname); codec_exit(ac_error_str); @@ -2165,20 +2225,26 @@ int main(WORD32 argc, CHAR *argv[]) exit(-1); } + if(1 == s_app_ctx.u4_frame_info_enable) + { + pu1_qp_map_buf = calloc((ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6, 1); + pu1_blk_type_map_buf = calloc((ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6, 1); + } + /***********************************************************************/ /* create the file object for input file */ /***********************************************************************/ #ifdef IOS - sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_ip_fname); + snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", homedir, s_app_ctx.ac_ip_fname); ps_ip_file = fopen(filename_with_path, "rb"); #else ps_ip_file = fopen(s_app_ctx.ac_ip_fname, "rb"); #endif if(NULL == ps_ip_file) { - sprintf(ac_error_str, "Could not open input file %s", + snprintf(ac_error_str, sizeof(ac_error_str), "Could not open input file %s", s_app_ctx.ac_ip_fname); codec_exit(ac_error_str); } @@ -2188,14 +2254,15 @@ int main(WORD32 argc, CHAR *argv[]) if(1 == s_app_ctx.u4_piclen_flag) { #ifdef IOS - sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_piclen_fname); + snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", + s_app_ctx.ac_piclen_fname); ps_piclen_file = fopen(filename_with_path, "rb"); #else ps_piclen_file = fopen(s_app_ctx.ac_piclen_fname, "rb"); #endif if(NULL == ps_piclen_file) { - sprintf(ac_error_str, "Could not open piclen file %s", + snprintf(ac_error_str, sizeof(ac_error_str), "Could not open piclen file %s", s_app_ctx.ac_piclen_fname); codec_exit(ac_error_str); } @@ -2210,7 +2277,8 @@ int main(WORD32 argc, CHAR *argv[]) if((1 == s_app_ctx.u4_file_save_flag) && (strstr(s_app_ctx.ac_op_fname,"%d") == NULL)) { #ifdef IOS - sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_fname); + snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir, + s_app_ctx.ac_op_fname); ps_op_file = fopen(filename_with_path,"wb"); #else ps_op_file = fopen(s_app_ctx.ac_op_fname, "wb"); @@ -2218,26 +2286,59 @@ int main(WORD32 argc, CHAR *argv[]) if(NULL == ps_op_file) { - sprintf(ac_error_str, "Could not open output file %s", + snprintf(ac_error_str, sizeof(ac_error_str), "Could not open output file %s", s_app_ctx.ac_op_fname); codec_exit(ac_error_str); } } /***********************************************************************/ + /* create the file object for mbinfo file */ + /***********************************************************************/ + + if(1 == s_app_ctx.u4_frame_info_enable) + { +#ifdef IOS + snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir, + s_app_ctx.ac_qp_map_fname); + ps_qp_file = fopen(filename_with_path, "wb"); + + snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir, + s_app_ctx.ac_blk_type_map_fname); + ps_mb_type_file = fopen(filename_with_path, "wb"); +#else + ps_qp_file = fopen(s_app_ctx.ac_qp_map_fname, "wb"); + ps_mb_type_file = fopen(s_app_ctx.ac_blk_type_map_fname, "wb"); + +#endif + + if(NULL == ps_qp_file) + { + snprintf(ac_error_str, sizeof(ac_error_str), "Could not open block_qp map file %s", + s_app_ctx.ac_qp_map_fname); + } + if(NULL == ps_mb_type_file) + { + snprintf(ac_error_str, sizeof(ac_error_str), "Could not open block_type map file %s", + s_app_ctx.ac_blk_type_map_fname); + } + } + + /***********************************************************************/ /* create the file object for check sum file */ /***********************************************************************/ if(1 == s_app_ctx.u4_chksum_save_flag) { #if IOS - sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_chksum_fname); + snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir, + s_app_ctx.ac_op_chksum_fname); ps_op_chksum_file = fopen(filename_with_path,"wb"); #else ps_op_chksum_file = fopen(s_app_ctx.ac_op_chksum_fname, "wb"); #endif if(NULL == ps_op_chksum_file) { - sprintf(ac_error_str, "Could not open check sum file %s", + snprintf(ac_error_str, sizeof(ac_error_str), "Could not open check sum file %s", s_app_ctx.ac_op_chksum_fname); codec_exit(ac_error_str); } @@ -2253,8 +2354,8 @@ int main(WORD32 argc, CHAR *argv[]) /* API Call: Initialize the Decoder */ /*****************************************************************************/ { - ih264d_create_ip_t s_create_ip; - ih264d_create_op_t s_create_op; + ih264d_create_ip_t s_create_ip = {}; + ih264d_create_op_t s_create_op = {}; void *fxns = &ivd_api_function; s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE; @@ -2265,6 +2366,7 @@ int main(WORD32 argc, CHAR *argv[]) s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL; s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(ih264d_create_ip_t); s_create_op.s_ivd_create_op_t.u4_size = sizeof(ih264d_create_op_t); + s_create_ip.u4_enable_frame_info = s_app_ctx.u4_frame_info_enable; @@ -2369,10 +2471,10 @@ int main(WORD32 argc, CHAR *argv[]) } - flush_output(codec_obj, &s_app_ctx, ps_out_buf, - pu1_bs_buf, &u4_op_frm_ts, - ps_op_file, ps_op_chksum_file, - u4_ip_frm_ts, u4_bytes_remaining); + flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, + ps_op_file, ps_qp_file, ps_mb_type_file, + pu1_qp_map_buf, pu1_blk_type_map_buf, + ps_op_chksum_file, u4_ip_frm_ts, u4_bytes_remaining); /*****************************************************************************/ /* Decode header to get width and height and buffer sizes */ @@ -2458,6 +2560,10 @@ int main(WORD32 argc, CHAR *argv[]) ps_video_decode_ip->u4_num_Bytes = u4_bytes_remaining; ps_video_decode_ip->u4_size = sizeof(ih264d_video_decode_ip_t); ps_video_decode_op->u4_size = sizeof(ih264d_video_decode_op_t); + s_h264d_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf; + s_h264d_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf; + s_h264d_decode_ip.u4_8x8_blk_qp_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6; + s_h264d_decode_ip.u4_8x8_blk_type_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6; /*****************************************************************************/ /* API Call: Header Decode */ @@ -2998,6 +3104,10 @@ int main(WORD32 argc, CHAR *argv[]) ps_video_decode_ip->s_out_buffer.u4_num_bufs = ps_out_buf->u4_num_bufs; ps_video_decode_op->u4_size = sizeof(ih264d_video_decode_op_t); + s_h264d_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf; + s_h264d_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf; + s_h264d_decode_ip.u4_8x8_blk_qp_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6; + s_h264d_decode_ip.u4_8x8_blk_type_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6; /* Get display buffer pointers */ if(1 == s_app_ctx.display) @@ -3077,10 +3187,10 @@ int main(WORD32 argc, CHAR *argv[]) ivd_ctl_reset_ip_t s_ctl_ip; ivd_ctl_reset_op_t s_ctl_op; - flush_output(codec_obj, &s_app_ctx, ps_out_buf, - pu1_bs_buf, &u4_op_frm_ts, - ps_op_file, ps_op_chksum_file, - u4_ip_frm_ts, u4_bytes_remaining); + flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, + ps_op_file, ps_qp_file, ps_mb_type_file, + pu1_qp_map_buf, pu1_blk_type_map_buf, + ps_op_chksum_file, u4_ip_frm_ts, u4_bytes_remaining); s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET; @@ -3311,8 +3421,8 @@ int main(WORD32 argc, CHAR *argv[]) ps_op_file = fopen(cur_fname,"wb"); if (NULL == ps_op_file) { - sprintf(ac_error_str, "Could not open output file %s", - cur_fname); + snprintf(ac_error_str, sizeof(ac_error_str), + "Could not open output file %s", cur_fname); codec_exit(ac_error_str); } @@ -3321,11 +3431,11 @@ int main(WORD32 argc, CHAR *argv[]) width = ps_video_decode_op->s_disp_frm_buf.u4_y_wd; height = ps_video_decode_op->s_disp_frm_buf.u4_y_ht; - dump_output(&s_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), + dump_output(&s_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), &s_h264d_decode_op, ps_video_decode_op->u4_disp_buf_id, ps_op_file, - ps_op_chksum_file, + ps_qp_file, ps_mb_type_file, ps_op_chksum_file, u4_op_frm_ts, s_app_ctx.u4_file_save_flag, - s_app_ctx.u4_chksum_save_flag); + s_app_ctx.u4_chksum_save_flag, s_app_ctx.u4_frame_info_enable); u4_op_frm_ts++; if (extn != NULL) @@ -3347,10 +3457,10 @@ int main(WORD32 argc, CHAR *argv[]) /***********************************************************************/ /* To get the last decoded frames, call process with NULL input */ /***********************************************************************/ - flush_output(codec_obj, &s_app_ctx, ps_out_buf, - pu1_bs_buf, &u4_op_frm_ts, - ps_op_file, ps_op_chksum_file, - u4_ip_frm_ts, u4_bytes_remaining); + flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, + ps_op_file, ps_qp_file, ps_mb_type_file, + pu1_qp_map_buf, pu1_blk_type_map_buf, + ps_op_chksum_file, u4_ip_frm_ts, u4_bytes_remaining); /* set disp_end u4_flag */ s_app_ctx.quit = 1; @@ -3423,7 +3533,17 @@ int main(WORD32 argc, CHAR *argv[]) { fclose(ps_op_chksum_file); } - + if(1 == s_app_ctx.u4_frame_info_enable) + { + if(NULL != ps_qp_file) + { + fclose(ps_qp_file); + } + if(NULL != ps_mb_type_file) + { + fclose(ps_mb_type_file); + } + } } if(0 == s_app_ctx.u4_share_disp_buf) @@ -3438,6 +3558,17 @@ int main(WORD32 argc, CHAR *argv[]) free(ps_out_buf); free(pu1_bs_buf); + if(1 == s_app_ctx.u4_frame_info_enable) + { + if(pu1_qp_map_buf) + { + free(pu1_qp_map_buf); + } + if(pu1_blk_type_map_buf) + { + free(pu1_blk_type_map_buf); + } + } if(s_app_ctx.display_thread_handle) free(s_app_ctx.display_thread_handle); |