aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShivaansh Agrawal <Shivaansh.Agrawal@ittiam.com>2020-10-16 23:50:30 +0530
committerCherrypicker Worker <android-build-cherrypicker-worker@google.com>2022-08-21 20:37:53 +0000
commit40e55db03d004c00f620c1da847dca09745c0810 (patch)
tree71ca49ae7cb1872d80113928e2e1aee1a241515c
parent1797ff521fed73a57ef48c3cb24d4c5f4b38737b (diff)
downloadlibavc-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-xFrameInfo.md18
-rw-r--r--common/ih264_defs.h8
-rw-r--r--decoder/ih264d.h80
-rw-r--r--decoder/ih264d_api.c69
-rw-r--r--decoder/ih264d_defs.h3
-rw-r--r--decoder/ih264d_dpb_mgr.c4
-rw-r--r--decoder/ih264d_mb_utils.c93
-rw-r--r--decoder/ih264d_mb_utils.h6
-rw-r--r--decoder/ih264d_parse_headers.c1
-rw-r--r--decoder/ih264d_parse_islice.c12
-rw-r--r--decoder/ih264d_parse_pslice.c12
-rw-r--r--decoder/ih264d_parse_slice.c24
-rw-r--r--decoder/ih264d_structs.h29
-rw-r--r--decoder/ih264d_utils.c23
-rw-r--r--test/decoder/main.c227
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);