decoder: Update check for first mb in slice am: 7e06940dce am: 4fb26568a9 am: 2bf6790f63 am: 5f4f6e2ecf am: 640eda280b am: d6c30aa7da am: 82e6bc3fd0
Original change: https://googleplex-android-review.googlesource.com/c/platform/external/libavc/+/13171299
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: Ia1d88ff27097e0fdc9cc7620ffde47cbf44bd2ab
diff --git a/Android.bp b/Android.bp
index ae0567e..5ba9c7a 100644
--- a/Android.bp
+++ b/Android.bp
@@ -162,18 +162,6 @@
],
},
- mips: {
- local_include_dirs: ["common/mips"],
-
- srcs: ["decoder/mips/ih264d_function_selector.c"],
- },
-
- mips64: {
- local_include_dirs: ["common/mips"],
-
- srcs: ["decoder/mips/ih264d_function_selector.c"],
- },
-
x86: {
cflags: [
"-DX86",
@@ -242,7 +230,7 @@
misc_undefined: ["bounds"],
// Enable CFI if this becomes a shared library.
// cfi: true,
- blacklist: "libavc_blacklist.txt",
+ blocklist: "libavc_blocklist.txt",
},
apex_available: [
"//apex_available:platform", // used by libstagefright_soft_avcdec
@@ -427,24 +415,6 @@
],
},
- mips: {
- local_include_dirs: [
- "common/mips",
- "encoder/mips",
- ],
-
- srcs: ["encoder/mips/ih264e_function_selector.c"],
- },
-
- mips64: {
- local_include_dirs: [
- "common/mips",
- "encoder/mips",
- ],
-
- srcs: ["encoder/mips/ih264e_function_selector.c"],
- },
-
x86: {
cflags: [
"-DX86",
@@ -521,7 +491,7 @@
misc_undefined: ["bounds"],
// Enable CFI if this becomes a shared library.
// cfi: true,
- blacklist: "libavc_blacklist.txt",
+ blocklist: "libavc_blocklist.txt",
},
apex_available: [
"//apex_available:platform", //due to libstagefright_soft_avcenc
diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..d97975c
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,3 @@
+third_party {
+ license_type: NOTICE
+}
diff --git a/OWNERS b/OWNERS
index acffb3a..b2faa25 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,4 @@
-marcone@google.com
+# owners for external/libavc
+include platform/frameworks/av:/media/janitors/OWNERS-codecs
essick@google.com
-lajos@google.com
-hkuang@google.com
+hkuang@google.com
\ No newline at end of file
diff --git a/decoder/ih264d_api.c b/decoder/ih264d_api.c
index 3a73938..3dfcbf2 100644
--- a/decoder/ih264d_api.c
+++ b/decoder/ih264d_api.c
@@ -3253,7 +3253,7 @@
ret = IV_FAIL;
}
- if(ps_ctl_ip->u4_disp_wd >= ps_dec->u2_pic_wd)
+ if(ps_ctl_ip->u4_disp_wd >= ps_dec->u2_disp_width)
{
ps_dec->u4_app_disp_width = ps_ctl_ip->u4_disp_wd;
}
diff --git a/decoder/ih264d_defs.h b/decoder/ih264d_defs.h
index 2758a59..aeb2520 100644
--- a/decoder/ih264d_defs.h
+++ b/decoder/ih264d_defs.h
@@ -45,6 +45,11 @@
#define FMT_CONV_NUM_ROWS 16
+/** Decoder currently has an additional latency of 2 pictures when
+ * returning output for display
+ */
+#define DISPLAY_LATENCY 2
+
/** Bit manipulation macros */
#define CHECKBIT(a,i) ((a) & (1 << i))
#define CLEARBIT(a,i) ((a) &= ~(1 << i))
@@ -597,8 +602,9 @@
#define DISP_BOT_FLD_FIRST 2
/** Misc error resilience requirements*/
-#define MASK_LOG2_WEIGHT_DENOM 0xFFFFFFF8
-#define MASK_PRED_WEIGHT_OFFSET 0xFFFFFF00
+#define MAX_LOG2_WEIGHT_DENOM 7
+#define PRED_WEIGHT_MIN (-128)
+#define PRED_WEIGHT_MAX 127
#define MAX_REDUNDANT_PIC_CNT 127
diff --git a/decoder/ih264d_dpb_manager.h b/decoder/ih264d_dpb_manager.h
index a9539c8..5747016 100644
--- a/decoder/ih264d_dpb_manager.h
+++ b/decoder/ih264d_dpb_manager.h
@@ -50,6 +50,7 @@
#define RESET_NONREF_PICTURES 7
#define RESET_ALL_PICTURES 8
+#define NO_LONG_TERM_INDICIES 255
struct field_t
{
/* picNum of tbe reference field */
@@ -93,7 +94,7 @@
struct dpb_info_t as_dpb_info[MAX_REF_BUFS]; /** Physical storage for dpbInfo for ref bufs */
UWORD8 u1_num_st_ref_bufs; /** Number of short term ref. buffers */
UWORD8 u1_num_lt_ref_bufs; /** Number of long term ref. buffer */
- UWORD8 u1_max_lt_pic_idx_plus1; /** Maximum long term pictures - 0 to max_long_term_pic_idx */
+ UWORD8 u1_max_lt_frame_idx; /** Maximum long term frame index */
UWORD8 u1_num_gaps; /** Total number of outstanding gaps */
void * pv_codec_handle; /* For Error Handling */
WORD32 i4_max_frm_num; /** Max frame number */
@@ -105,6 +106,7 @@
WORD8 i1_gaps_deleted;
UWORD16 u2_pic_wd;
UWORD16 u2_pic_ht;
+ UWORD8 u1_mmco_error_in_seq;
}dpb_manager_t;
/** Structure store the MMC Commands */
diff --git a/decoder/ih264d_dpb_mgr.c b/decoder/ih264d_dpb_mgr.c
index 0b8426b..ce977d7 100644
--- a/decoder/ih264d_dpb_mgr.c
+++ b/decoder/ih264d_dpb_mgr.c
@@ -88,6 +88,7 @@
ps_dpb_mgr->ps_dpb_ht_head = NULL;
ps_dpb_mgr->i1_gaps_deleted = 0;
ps_dpb_mgr->i1_poc_buf_id_entries = 0;
+ ps_dpb_mgr->u1_mmco_error_in_seq = 0;
ps_dpb_mgr->u1_num_gaps = 0;
for(i = 0; i < MAX_FRAMES; i++)
@@ -647,6 +648,7 @@
ps_dpb_mgr->u1_num_st_ref_bufs = ps_dpb_mgr->u1_num_lt_ref_bufs = 0;
ps_dpb_mgr->ps_dpb_st_head = NULL;
ps_dpb_mgr->ps_dpb_ht_head = NULL;
+ ps_dpb_mgr->u1_mmco_error_in_seq = 0;
/* release all gaps */
ps_dpb_mgr->u1_num_gaps = 0;
@@ -851,6 +853,8 @@
*/
WORD32 ih264d_read_mmco_commands(struct _DecStruct * ps_dec)
{
+ dec_pic_params_t *ps_pps = ps_dec->ps_cur_pps;
+ dec_seq_params_t *ps_sps = ps_pps->ps_sps;
dec_bit_stream_t *ps_bitstrm = ps_dec->ps_bitstrm;
dpb_commands_t *ps_dpb_cmds = &(ps_dec->s_dpb_cmds_scratch);
dec_slice_params_t * ps_slice = ps_dec->ps_cur_slice;
@@ -890,7 +894,7 @@
{
UWORD32 u4_mmco;
UWORD32 u4_diff_pic_num;
- UWORD32 u4_lt_idx, u4_max_lt_idx;
+ UWORD32 u4_lt_idx, u4_max_lt_idx_plus1;
u4_mmco = ih264d_uev(pu4_bitstrm_ofst,
pu4_bitstrm_buf);
@@ -933,9 +937,14 @@
case SET_MAX_LT_INDEX:
{
- u4_max_lt_idx = ih264d_uev(pu4_bitstrm_ofst,
- pu4_bitstrm_buf);
- ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx;
+ u4_max_lt_idx_plus1 = ih264d_uev(pu4_bitstrm_ofst,
+ pu4_bitstrm_buf);
+ if (u4_max_lt_idx_plus1 > ps_sps->u1_num_ref_frames)
+ {
+ /* Invalid max LT ref index */
+ return -1;
+ }
+ ps_mmc_params->u4_max_lt_idx_plus1 = u4_max_lt_idx_plus1;
break;
}
case RESET_REF_PICTURES:
@@ -959,7 +968,6 @@
j++;
}
ps_dpb_cmds->u1_num_of_commands = j;
-
}
}
ps_dpb_cmds->u1_dpb_commands_read = 1;
@@ -1243,6 +1251,13 @@
}
u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
+
+ if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
+ (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
+
if(ps_dpb_mgr->u1_num_st_ref_bufs > 0)
{
ret = ih264d_delete_st_node_or_make_lt(ps_dpb_mgr,
@@ -1257,7 +1272,7 @@
{
UWORD8 uc_numLT = ps_dpb_mgr->u1_num_lt_ref_bufs;
u4_lt_idx = ps_mmc_params->u4_max_lt_idx_plus1; //Get Max_long_term_index_plus1
- if(u4_lt_idx < ps_dpb_mgr->u1_max_lt_pic_idx_plus1
+ if(u4_lt_idx <= ps_dpb_mgr->u1_max_lt_frame_idx
&& uc_numLT > 0)
{
struct dpb_info_t *ps_nxtDPB;
@@ -1302,13 +1317,25 @@
ps_nxtDPB->ps_prev_long = NULL;
}
}
- ps_dpb_mgr->u1_max_lt_pic_idx_plus1 = u4_lt_idx;
+ if(u4_lt_idx == 0)
+ {
+ ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
+ }
+ else
+ {
+ ps_dpb_mgr->u1_max_lt_frame_idx = u4_lt_idx - 1;
+ }
break;
}
case SET_LT_INDEX:
{
u4_lt_idx = ps_mmc_params->u4_lt_idx; //Get long term index
+ if((ps_dpb_mgr->u1_max_lt_frame_idx == NO_LONG_TERM_INDICIES) ||
+ (u4_lt_idx > ps_dpb_mgr->u1_max_lt_frame_idx))
+ {
+ return ERROR_DBP_MANAGER_T;
+ }
ret = ih264d_insert_st_node(ps_dpb_mgr, ps_pic_buf, u1_buf_id,
u4_cur_pic_num);
if(ret != OK)
diff --git a/decoder/ih264d_error_handler.h b/decoder/ih264d_error_handler.h
index 6cdbc81..a651c46 100644
--- a/decoder/ih264d_error_handler.h
+++ b/decoder/ih264d_error_handler.h
@@ -122,7 +122,8 @@
ERROR_INV_SEI_MDCV_PARAMS = 0x9C,
ERROR_INV_SEI_CLL_PARAMS = 0x9D,
ERROR_INV_SEI_AVE_PARAMS = 0x9E,
- ERROR_INV_SEI_CCV_PARAMS = 0x9F
+ ERROR_INV_SEI_CCV_PARAMS = 0x9F,
+ ERROR_INV_FRAME_NUM = 0xA0
} h264_decoder_error_code_t;
diff --git a/decoder/ih264d_parse_bslice.c b/decoder/ih264d_parse_bslice.c
index 0af4214..936963a 100644
--- a/decoder/ih264d_parse_bslice.c
+++ b/decoder/ih264d_parse_bslice.c
@@ -34,6 +34,7 @@
*/
#include <string.h>
+#include "ih264_defs.h"
#include "ih264d_bitstrm.h"
#include "ih264d_defs.h"
#include "ih264d_debug.h"
@@ -1196,8 +1197,8 @@
UWORD8 i, j;
struct pic_buffer_t *ps_pic_buff0, *ps_pic_buff1;
WORD16 i2_dist_scale_factor;
- WORD16 i16_tb, i16_td, i16_tx;
- WORD32 i4_tb, i4_td;
+ WORD16 i2_tb, i2_td, i2_tx;
+ WORD64 i8_tb, i8_td;
WORD32 i4_poc0, i4_poc1;
UWORD32 ui_temp0, ui_temp1;
UWORD8 uc_num_ref_idx_l0_active, uc_num_ref_idx_l1_active;
@@ -1219,13 +1220,13 @@
if(i4_poc1 != i4_poc0)
{
- i4_tb = ps_dec->ps_cur_pic->i4_poc - i4_poc0;
- i16_tb = CLIP_S8(i4_tb);
- i4_td = i4_poc1 - i4_poc0;
- i16_td = CLIP_S8(i4_td);
- i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) / i16_td;
+ i8_tb = (WORD64)ps_dec->ps_cur_pic->i4_poc - i4_poc0;
+ i2_tb = CLIP_S8(i8_tb);
+ i8_td = (WORD64)i4_poc1 - i4_poc0;
+ i2_td = CLIP_S8(i8_td);
+ i2_tx = (16384 + ABS(SIGN_POW2_DIV(i2_td, 1))) / i2_td;
i2_dist_scale_factor = CLIP_S11(
- (((i16_tb * i16_tx) + 32) >> 6));
+ (((i2_tb * i2_tx) + 32) >> 6));
if(/*((u4_poc1 - u4_poc0) == 0) ||*/
(!(ps_pic_buff1->u1_is_short && ps_pic_buff0->u1_is_short))
@@ -1289,14 +1290,14 @@
i4_poc1 = ps_pic_buff1->i4_poc;
if(i4_poc1 != i4_poc0)
{
- i4_tb = i4_cur_poc - i4_poc0;
- i16_tb = CLIP_S8(i4_tb);
- i4_td = i4_poc1 - i4_poc0;
- i16_td = CLIP_S8(i4_td);
- i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1)))
- / i16_td;
+ i8_tb = (WORD64)i4_cur_poc - i4_poc0;
+ i2_tb = CLIP_S8(i8_tb);
+ i8_td = (WORD64)i4_poc1 - i4_poc0;
+ i2_td = CLIP_S8(i8_td);
+ i2_tx = (16384 + ABS(SIGN_POW2_DIV(i2_td, 1)))
+ / i2_td;
i2_dist_scale_factor = CLIP_S11(
- (((i16_tb * i16_tx) + 32) >> 6));
+ (((i2_tb * i2_tx) + 32) >> 6));
if(/*((u4_poc1 - u4_poc0) == 0) ||*/
(!(ps_pic_buff1->u1_is_short && ps_pic_buff0->u1_is_short))
@@ -1354,6 +1355,7 @@
UWORD32 *pu4_bitstrm_buf = ps_bitstrm->pu4_buffer;
UWORD32 *pu4_bitstrm_ofst = &ps_bitstrm->u4_ofst;
+ UWORD64 u8_ref_idx_l0, u8_ref_idx_l1;
UWORD32 u4_temp, ui_temp1;
WORD32 i_temp;
WORD32 ret;
@@ -1380,31 +1382,31 @@
COPYTHECONTEXT("SH: num_ref_idx_override_flag",
ps_slice->u1_num_ref_idx_active_override_flag);
- u4_temp = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0];
- ui_temp1 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[1];
+ u8_ref_idx_l0 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0];
+ u8_ref_idx_l1 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[1];
if(ps_slice->u1_num_ref_idx_active_override_flag)
{
- u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ u8_ref_idx_l0 = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
COPYTHECONTEXT("SH: num_ref_idx_l0_active_minus1",
- u4_temp - 1);
- ui_temp1 = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ u8_ref_idx_l0 - 1);
+
+ u8_ref_idx_l1 = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
COPYTHECONTEXT("SH: num_ref_idx_l1_active_minus1",
- ui_temp1 - 1);
+ u8_ref_idx_l1 - 1);
}
{
- UWORD8 u1_max_ref_idx = MAX_FRAMES;
+ UWORD8 u1_max_ref_idx = H264_MAX_REF_PICS;
if(ps_slice->u1_field_pic_flag)
{
- u1_max_ref_idx = MAX_FRAMES << 1;
+ u1_max_ref_idx = H264_MAX_REF_PICS << 1;
}
- if((u4_temp > u1_max_ref_idx) || (ui_temp1 > u1_max_ref_idx)
- || (u4_temp < 1) || (ui_temp1 < 1))
+ if((u8_ref_idx_l0 > u1_max_ref_idx) || (u8_ref_idx_l1 > u1_max_ref_idx))
{
return ERROR_NUM_REF;
}
- ps_slice->u1_num_ref_idx_lx_active[0] = u4_temp;
- ps_slice->u1_num_ref_idx_lx_active[1] = ui_temp1;
+ ps_slice->u1_num_ref_idx_lx_active[0] = u8_ref_idx_l0;
+ ps_slice->u1_num_ref_idx_lx_active[1] = u8_ref_idx_l1;
}
@@ -1600,13 +1602,13 @@
}
/* Read slice_qp_delta */
- i_temp = ps_pps->u1_pic_init_qp
- + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if((i_temp < 0) || (i_temp > 51))
+ WORD64 i8_temp = (WORD64)ps_pps->u1_pic_init_qp
+ + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
{
return ERROR_INV_RANGE_QP_T;
}
- ps_slice->u1_slice_qp = i_temp;
+ ps_slice->u1_slice_qp = i8_temp;
COPYTHECONTEXT("SH: slice_qp_delta",
(WORD8)(ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp));
diff --git a/decoder/ih264d_parse_headers.c b/decoder/ih264d_parse_headers.c
index 9220707..8f0cb40 100644
--- a/decoder/ih264d_parse_headers.c
+++ b/decoder/ih264d_parse_headers.c
@@ -35,6 +35,7 @@
#include "ih264_typedefs.h"
#include "ih264_macros.h"
#include "ih264_platform_macros.h"
+#include "ih264_defs.h"
#include "ih264d_bitstrm.h"
#include "ih264d_structs.h"
#include "ih264d_parse_cavlc.h"
@@ -275,6 +276,7 @@
UWORD32 *pu4_bitstrm_ofst = &ps_dec->ps_bitstrm->u4_ofst;
/* Variables used for error resilience checks */
+ UWORD64 u8_temp;
UWORD32 u4_temp;
WORD32 i_temp;
@@ -327,30 +329,28 @@
/*--------------------------------------------------------------------*/
/* Decode num_slice_groups_minus1 */
/*--------------------------------------------------------------------*/
- u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + 1;
- if(u4_temp != 1)
+ u8_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + (UWORD64)1;
+ if(u8_temp != 1)
{
- UWORD32 i4_error_code;
- i4_error_code = ERROR_FEATURE_UNAVAIL;
- return i4_error_code;
+ return ERROR_FEATURE_UNAVAIL;
}
- ps_pps->u1_num_slice_groups = u4_temp;
+ ps_pps->u1_num_slice_groups = u8_temp;
COPYTHECONTEXT("PPS: num_slice_groups_minus1",ps_pps->u1_num_slice_groups -1);
/*--------------------------------------------------------------------*/
/* Other parameter set values */
/*--------------------------------------------------------------------*/
- u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if(u4_temp > H264_MAX_REF_IDX)
+ u8_temp = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp > H264_MAX_REF_IDX)
return ERROR_REF_IDX;
- ps_pps->u1_num_ref_idx_lx_active[0] = u4_temp;
+ ps_pps->u1_num_ref_idx_lx_active[0] = u8_temp;
COPYTHECONTEXT("PPS: num_ref_idx_l0_active_minus1",
ps_pps->u1_num_ref_idx_lx_active[0] - 1);
- u4_temp = 1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if(u4_temp > H264_MAX_REF_IDX)
+ u8_temp = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp > H264_MAX_REF_IDX)
return ERROR_REF_IDX;
- ps_pps->u1_num_ref_idx_lx_active[1] = u4_temp;
+ ps_pps->u1_num_ref_idx_lx_active[1] = u8_temp;
COPYTHECONTEXT("PPS: num_ref_idx_l1_active_minus1",
ps_pps->u1_num_ref_idx_lx_active[1] - 1);
@@ -363,20 +363,21 @@
if(ps_pps->u1_wted_bipred_idc > MAX_WEIGHT_BIPRED_IDC)
return ERROR_INV_SPS_PPS_T;
- i_temp = 26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ WORD64 i8_temp = (WORD64)26
+ + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if((i_temp < 0) || (i_temp > 51))
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
return ERROR_INV_RANGE_QP_T;
- ps_pps->u1_pic_init_qp = i_temp;
+ ps_pps->u1_pic_init_qp = i8_temp;
COPYTHECONTEXT("PPS: pic_init_qp_minus26",ps_pps->u1_pic_init_qp - 26);
- i_temp = 26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ i8_temp = (WORD64)26 + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if((i_temp < 0) || (i_temp > 51))
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
return ERROR_INV_RANGE_QP_T;
- ps_pps->u1_pic_init_qs = i_temp;
+ ps_pps->u1_pic_init_qs = i8_temp;
COPYTHECONTEXT("PPS: pic_init_qs_minus26",ps_pps->u1_pic_init_qs - 26);
i_temp = ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
@@ -577,6 +578,7 @@
UWORD8 u1_frm, uc_constraint_set0_flag, uc_constraint_set1_flag;
WORD32 i4_cropped_ht, i4_cropped_wd;
UWORD32 u4_temp;
+ UWORD64 u8_temp;
UWORD32 u4_pic_height_in_map_units, u4_pic_width_in_mbs;
UWORD32 u2_pic_wd = 0;
UWORD32 u2_pic_ht = 0;
@@ -771,12 +773,12 @@
/*--------------------------------------------------------------------*/
/* Decode MaxFrameNum */
/*--------------------------------------------------------------------*/
- u4_temp = 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if(u4_temp > MAX_BITS_IN_FRAME_NUM)
+ u8_temp = (UWORD64)4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp > MAX_BITS_IN_FRAME_NUM)
{
return ERROR_INV_SPS_PPS_T;
}
- ps_seq->u1_bits_in_frm_num = u4_temp;
+ ps_seq->u1_bits_in_frm_num = u8_temp;
COPYTHECONTEXT("SPS: log2_max_frame_num_minus4",
(ps_seq->u1_bits_in_frm_num - 4));
@@ -797,14 +799,14 @@
ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle = 1;
if(ps_seq->u1_pic_order_cnt_type == 0)
{
- u4_temp = 4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if(u4_temp > MAX_BITS_IN_POC_LSB)
+ u8_temp = (UWORD64)4 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if(u8_temp > MAX_BITS_IN_POC_LSB)
{
return ERROR_INV_SPS_PPS_T;
}
- ps_seq->u1_log2_max_pic_order_cnt_lsb_minus = u4_temp;
- ps_seq->i4_max_pic_order_cntLsb = (1 << u4_temp);
- COPYTHECONTEXT("SPS: log2_max_pic_order_cnt_lsb_minus4",(u4_temp - 4));
+ ps_seq->u1_log2_max_pic_order_cnt_lsb_minus = u8_temp;
+ ps_seq->i4_max_pic_order_cntLsb = (1 << u8_temp);
+ COPYTHECONTEXT("SPS: log2_max_pic_order_cnt_lsb_minus4",(u8_temp - 4));
}
else if(ps_seq->u1_pic_order_cnt_type == 1)
{
@@ -864,20 +866,23 @@
/*--------------------------------------------------------------------*/
/* Decode FrameWidth and FrameHeight and related values */
/*--------------------------------------------------------------------*/
- u4_pic_width_in_mbs = 1
- + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- COPYTHECONTEXT("SPS: pic_width_in_mbs_minus1",
- u4_pic_width_in_mbs - 1);
-
- u4_pic_height_in_map_units = 1 + ih264d_uev(pu4_bitstrm_ofst,
- pu4_bitstrm_buf);
-
+ u8_temp = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
/* Check for unsupported resolutions*/
- if((u4_pic_width_in_mbs > (H264_MAX_FRAME_WIDTH >> 4)) ||
- (u4_pic_height_in_map_units > (H264_MAX_FRAME_HEIGHT >> 4)))
+ if(u8_temp > (H264_MAX_FRAME_WIDTH >> 4))
{
return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
}
+ u4_pic_width_in_mbs = u8_temp;
+ COPYTHECONTEXT("SPS: pic_width_in_mbs_minus1",
+ u4_pic_width_in_mbs - 1);
+
+ u8_temp = (UWORD64)1 + ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if (u8_temp > (H264_MAX_FRAME_HEIGHT >> 4))
+ {
+ return IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED;
+ }
+ u4_pic_height_in_map_units = u8_temp;
+
ps_seq->u2_frm_wd_in_mbs = u4_pic_width_in_mbs;
ps_seq->u2_frm_ht_in_mbs = u4_pic_height_in_map_units;
@@ -1101,6 +1106,23 @@
/*--------------------------------------------------------------------*/
/* All initializations to ps_dec are beyond this point */
/*--------------------------------------------------------------------*/
+ {
+ WORD32 reorder_depth = ih264d_get_dpb_size(ps_seq);
+ if((1 == ps_seq->u1_vui_parameters_present_flag) &&
+ (1 == ps_seq->s_vui.u1_bitstream_restriction_flag))
+ {
+ reorder_depth = ps_seq->s_vui.u4_num_reorder_frames + 1;
+ }
+
+ if (reorder_depth > H264_MAX_REF_PICS)
+ {
+ return ERROR_INV_SPS_PPS_T;
+ }
+
+ if(ps_seq->u1_frame_mbs_only_flag != 1)
+ reorder_depth *= 2;
+ ps_dec->i4_reorder_depth = reorder_depth + DISPLAY_LATENCY;
+ }
ps_dec->u2_disp_height = i4_cropped_ht;
ps_dec->u2_disp_width = i4_cropped_wd;
diff --git a/decoder/ih264d_parse_islice.c b/decoder/ih264d_parse_islice.c
index 46a87d1..0b8111a 100644
--- a/decoder/ih264d_parse_islice.c
+++ b/decoder/ih264d_parse_islice.c
@@ -33,9 +33,10 @@
* \author NS
**************************************************************************
*/
+#include <string.h>
+#include "ih264_defs.h"
#include "ih264d_error_handler.h"
#include "ih264d_debug.h"
-#include <string.h>
#include "ih264d_bitstrm.h"
#include "ih264d_defs.h"
#include "ih264d_debug.h"
@@ -1399,11 +1400,11 @@
/* G050 */
/* Read slice_qp_delta */
- i_temp = ps_pps->u1_pic_init_qp
- + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if((i_temp < 0) || (i_temp > 51))
+ WORD64 i8_temp = (WORD64)ps_pps->u1_pic_init_qp
+ + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
return ERROR_INV_RANGE_QP_T;
- ps_slice->u1_slice_qp = i_temp;
+ ps_slice->u1_slice_qp = i8_temp;
COPYTHECONTEXT("SH: slice_qp_delta",
ps_slice->u1_slice_qp - ps_pps->u1_pic_init_qp);
diff --git a/decoder/ih264d_parse_pslice.c b/decoder/ih264d_parse_pslice.c
index 9b9256b..6f8df9e 100644
--- a/decoder/ih264d_parse_pslice.c
+++ b/decoder/ih264d_parse_pslice.c
@@ -35,6 +35,7 @@
*/
#include <string.h>
+#include "ih264_defs.h"
#include "ih264d_bitstrm.h"
#include "ih264d_defs.h"
#include "ih264d_debug.h"
@@ -1494,7 +1495,11 @@
ps_dec->p_motion_compensate = ih264d_motion_compensate_bp;
if(ps_dec->ps_cur_pic != NULL)
- poc = ps_dec->ps_cur_pic->i4_poc + 2;
+ {
+ poc = ps_dec->ps_cur_pic->i4_poc;
+ if (poc <= INT32_MAX - 2)
+ poc += 2;
+ }
j = -1;
for(i = 0; i < MAX_NUM_PIC_PARAMS; i++)
@@ -1922,6 +1927,7 @@
UWORD8 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag; //ps_dec->ps_cur_sps->u1_mb_aff_flag;
UWORD8 u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag;
+ UWORD64 u8_ref_idx_l0;
UWORD32 u4_temp;
WORD32 i_temp;
WORD32 ret;
@@ -1950,22 +1956,19 @@
COPYTHECONTEXT("SH: num_ref_idx_override_flag",
ps_cur_slice->u1_num_ref_idx_active_override_flag);
- u4_temp = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0];
+ u8_ref_idx_l0 = ps_dec->ps_cur_pps->u1_num_ref_idx_lx_active[0];
if(ps_cur_slice->u1_num_ref_idx_active_override_flag)
{
- u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + 1;
+ u8_ref_idx_l0 = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf) + (UWORD64)1;
}
{
-
-
-
- UWORD8 u1_max_ref_idx = MAX_FRAMES << u1_field_pic_flag;
- if(u4_temp > u1_max_ref_idx || u4_temp < 1)
+ UWORD8 u1_max_ref_idx = H264_MAX_REF_PICS << u1_field_pic_flag;
+ if(u8_ref_idx_l0 > u1_max_ref_idx)
{
return ERROR_NUM_REF;
}
- ps_cur_slice->u1_num_ref_idx_lx_active[0] = u4_temp;
+ ps_cur_slice->u1_num_ref_idx_lx_active[0] = u8_ref_idx_l0;
COPYTHECONTEXT("SH: num_ref_idx_l0_active_minus1",
ps_cur_slice->u1_num_ref_idx_lx_active[0] - 1);
@@ -2126,13 +2129,13 @@
}
/* Read slice_qp_delta */
- i_temp = ps_pps->u1_pic_init_qp
- + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if((i_temp < 0) || (i_temp > 51))
+ WORD64 i8_temp = (WORD64)ps_pps->u1_pic_init_qp
+ + ih264d_sev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
+ if((i8_temp < MIN_H264_QP) || (i8_temp > MAX_H264_QP))
{
return ERROR_INV_RANGE_QP_T;
}
- ps_cur_slice->u1_slice_qp = i_temp;
+ ps_cur_slice->u1_slice_qp = i8_temp;
COPYTHECONTEXT("SH: slice_qp_delta",
(WORD8)(ps_cur_slice->u1_slice_qp - ps_pps->u1_pic_init_qp));
diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c
index cc1d90f..f4413c7 100644
--- a/decoder/ih264d_parse_slice.c
+++ b/decoder/ih264d_parse_slice.c
@@ -826,8 +826,8 @@
ps_cur_pic->u2_crop_offset_uv = ps_dec->u2_crop_offset_uv;
ps_cur_pic->u1_pic_type = 0;
{
- UWORD64 i8_display_poc;
- i8_display_poc = (UWORD64)ps_dec->i4_prev_max_display_seq +
+ WORD64 i8_display_poc;
+ i8_display_poc = (WORD64)ps_dec->i4_prev_max_display_seq +
ps_dec->ps_cur_pic->i4_poc;
if(IS_OUT_OF_RANGE_S32(i8_display_poc))
{
@@ -1472,10 +1472,20 @@
else
i4_temp_poc = ps_dec->ps_cur_pic->i4_bottom_field_order_cnt;
- ps_dec->ps_cur_pic->i4_top_field_order_cnt = i4_temp_poc
+ WORD64 i8_result = (WORD64)i4_temp_poc
- ps_dec->ps_cur_pic->i4_top_field_order_cnt;
- ps_dec->ps_cur_pic->i4_bottom_field_order_cnt = i4_temp_poc
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ ps_dec->ps_cur_pic->i4_top_field_order_cnt = i8_result;
+ i8_result = (WORD64)i4_temp_poc
- ps_dec->ps_cur_pic->i4_bottom_field_order_cnt;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ ps_dec->ps_cur_pic->i4_bottom_field_order_cnt = i8_result;
ps_dec->ps_cur_pic->i4_poc = i4_temp_poc;
ps_dec->ps_cur_pic->i4_avg_poc = i4_temp_poc;
}
@@ -1495,13 +1505,13 @@
/* IDR Picture or POC wrap around */
if(i4_poc == 0)
{
- UWORD64 u8_temp;
- u8_temp = (UWORD64)ps_dec->i4_prev_max_display_seq
+ WORD64 i8_temp;
+ i8_temp = (WORD64)ps_dec->i4_prev_max_display_seq
+ ps_dec->i4_max_poc
+ ps_dec->u1_max_dec_frame_buffering + 1;
/*If i4_prev_max_display_seq overflows integer range, reset it */
- ps_dec->i4_prev_max_display_seq = (u8_temp > 0x7fffffff)?
- 0 : u8_temp;
+ ps_dec->i4_prev_max_display_seq = IS_OUT_OF_RANGE_S32(i8_temp)?
+ 0 : i8_temp;
ps_dec->i4_max_poc = 0;
}
}
diff --git a/decoder/ih264d_process_bslice.c b/decoder/ih264d_process_bslice.c
index 5dfba33..fffa586 100644
--- a/decoder/ih264d_process_bslice.c
+++ b/decoder/ih264d_process_bslice.c
@@ -756,7 +756,7 @@
}
{
WORD16 i16_td;
- WORD32 diff;
+ WORD64 diff;
if(c_refFrm0 >= 0)
{
i2_mv_x0 = ps_mv->i2_mv[0];
@@ -782,7 +782,7 @@
i2_mv_y0 *= 2;
}
- diff = pic1_poc - pic0_poc;
+ diff = (WORD64)pic1_poc - pic0_poc;
i16_td = CLIP_S8(diff);
if((ps_pic_buff0->u1_is_short == 0) || (i16_td == 0))
{
@@ -791,21 +791,21 @@
}
else
{
- WORD16 i16_tb, i16_tx, i2_dist_scale_factor, i16_temp;
+ WORD16 i2_tb, i2_tx, i2_dist_scale_factor, i2_temp;
- diff = cur_poc - pic0_poc;
- i16_tb = CLIP_S8(diff);
+ diff = (WORD64)cur_poc - pic0_poc;
+ i2_tb = CLIP_S8(diff);
- i16_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) / i16_td;
+ i2_tx = (16384 + ABS(SIGN_POW2_DIV(i16_td, 1))) / i16_td;
i2_dist_scale_factor = CLIP_S11(
- (((i16_tb * i16_tx) + 32) >> 6));
- i16_temp = (i2_mv_x0 * i2_dist_scale_factor + 128) >> 8;
- i2_mv_x1 = i16_temp - i2_mv_x0;
- i2_mv_x0 = i16_temp;
+ (((i2_tb * i2_tx) + 32) >> 6));
+ i2_temp = (i2_mv_x0 * i2_dist_scale_factor + 128) >> 8;
+ i2_mv_x1 = i2_temp - i2_mv_x0;
+ i2_mv_x0 = i2_temp;
- i16_temp = (i2_mv_y0 * i2_dist_scale_factor + 128) >> 8;
- i2_mv_y1 = i16_temp - i2_mv_y0;
- i2_mv_y0 = i16_temp;
+ i2_temp = (i2_mv_y0 * i2_dist_scale_factor + 128) >> 8;
+ i2_mv_y1 = i2_temp - i2_mv_y0;
+ i2_mv_y0 = i2_temp;
}
{
mv_pred_t *ps_mv;
@@ -2304,8 +2304,9 @@
{
if(ABS(ps_col_pic->i4_top_field_order_cnt
- - ps_dec->ps_cur_pic->i4_poc) >=
- ABS(ps_dec->ps_cur_pic->i4_poc - ps_col_pic->i4_bottom_field_order_cnt))
+ - (WORD64)ps_dec->ps_cur_pic->i4_poc) >=
+ ABS((WORD64)ps_dec->ps_cur_pic->i4_poc
+ - ps_col_pic->i4_bottom_field_order_cnt))
{
ps_col_pic = ps_dec->ps_ref_pic_buf_lx[1][MAX_REF_BUFS];
}
@@ -2336,8 +2337,9 @@
if(u1_is_cur_mb_fld == 0)
{
if(ABS(ps_col_pic->i4_top_field_order_cnt
- - ps_dec->ps_cur_pic->i4_poc) >=
- ABS(ps_dec->ps_cur_pic->i4_poc - ps_col_pic->i4_bottom_field_order_cnt))
+ - (WORD64)ps_dec->ps_cur_pic->i4_poc) >=
+ ABS((WORD64)ps_dec->ps_cur_pic->i4_poc
+ - ps_col_pic->i4_bottom_field_order_cnt))
{
u2_sub_mb_ofst += 0x10;
}
diff --git a/decoder/ih264d_process_pslice.c b/decoder/ih264d_process_pslice.c
index 7c24383..c29063a 100644
--- a/decoder/ih264d_process_pslice.c
+++ b/decoder/ih264d_process_pslice.c
@@ -829,7 +829,7 @@
WORD32 i_temp;
u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if(u4_temp & MASK_LOG2_WEIGHT_DENOM)
+ if(u4_temp > MAX_LOG2_WEIGHT_DENOM)
{
return ERROR_PRED_WEIGHT_TABLE_T;
}
@@ -838,7 +838,7 @@
ui32_y_def_weight_ofst = (1 << uc_luma_log2_weight_denom);
u4_temp = ih264d_uev(pu4_bitstrm_ofst, pu4_bitstrm_buf);
- if(u4_temp & MASK_LOG2_WEIGHT_DENOM)
+ if(u4_temp > MAX_LOG2_WEIGHT_DENOM)
{
return ERROR_PRED_WEIGHT_TABLE_T;
}
@@ -864,14 +864,14 @@
{
i_temp = ih264d_sev(pu4_bitstrm_ofst,
pu4_bitstrm_buf);
- if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET)
+ if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX))
return ERROR_PRED_WEIGHT_TABLE_T;
c_weight = i_temp;
COPYTHECONTEXT("SH: luma_weight_l0",c_weight);
i_temp = ih264d_sev(pu4_bitstrm_ofst,
pu4_bitstrm_buf);
- if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET)
+ if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX))
return ERROR_PRED_WEIGHT_TABLE_T;
c_offset = i_temp;
COPYTHECONTEXT("SH: luma_offset_l0",c_offset);
@@ -894,14 +894,14 @@
{
i_temp = ih264d_sev(pu4_bitstrm_ofst,
pu4_bitstrm_buf);
- if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET)
+ if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX))
return ERROR_PRED_WEIGHT_TABLE_T;
c_weightCb = i_temp;
COPYTHECONTEXT("SH: chroma_weight_l0",c_weightCb);
i_temp = ih264d_sev(pu4_bitstrm_ofst,
pu4_bitstrm_buf);
- if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET)
+ if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX))
return ERROR_PRED_WEIGHT_TABLE_T;
c_offsetCb = i_temp;
COPYTHECONTEXT("SH: chroma_weight_l0",c_offsetCb);
@@ -911,14 +911,14 @@
i_temp = ih264d_sev(pu4_bitstrm_ofst,
pu4_bitstrm_buf);
- if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET)
+ if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX))
return ERROR_PRED_WEIGHT_TABLE_T;
c_weightCr = i_temp;
COPYTHECONTEXT("SH: chroma_weight_l0",c_weightCr);
i_temp = ih264d_sev(pu4_bitstrm_ofst,
pu4_bitstrm_buf);
- if((i_temp + 128) & MASK_PRED_WEIGHT_OFFSET)
+ if((i_temp < PRED_WEIGHT_MIN) || (i_temp > PRED_WEIGHT_MAX))
return ERROR_PRED_WEIGHT_TABLE_T;
c_offsetCr = i_temp;
COPYTHECONTEXT("SH: chroma_weight_l0",c_offsetCr);
diff --git a/decoder/ih264d_utils.c b/decoder/ih264d_utils.c
index 35cd7b9..93c379b 100644
--- a/decoder/ih264d_utils.c
+++ b/decoder/ih264d_utils.c
@@ -161,7 +161,7 @@
UWORD8 u1_field_pic_flag,
WORD32 *pi4_poc)
{
- WORD16 i1_pic_msb;
+ WORD64 i8_pic_msb;
WORD32 i4_top_field_order_cnt = 0, i4_bottom_field_order_cnt = 0;
dec_seq_params_t *ps_seq = ps_pps->ps_sps;
WORD32 i4_prev_frame_num_ofst;
@@ -197,7 +197,7 @@
>= (ps_seq->i4_max_pic_order_cntLsb
>> 1)))
{
- i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb
+ i8_pic_msb = (WORD64)ps_prev_poc->i4_pic_order_cnt_msb
+ ps_seq->i4_max_pic_order_cntLsb;
}
else if((ps_cur_poc->i4_pic_order_cnt_lsb
@@ -207,29 +207,49 @@
>= (ps_seq->i4_max_pic_order_cntLsb
>> 1)))
{
- i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb
+ i8_pic_msb = (WORD64)ps_prev_poc->i4_pic_order_cnt_msb
- ps_seq->i4_max_pic_order_cntLsb;
}
else
{
- i1_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb;
+ i8_pic_msb = ps_prev_poc->i4_pic_order_cnt_msb;
}
if(!u1_field_pic_flag || !u1_bottom_field_flag)
- i4_top_field_order_cnt = i1_pic_msb
- + ps_cur_poc->i4_pic_order_cnt_lsb;
+ {
+ WORD64 i8_result = i8_pic_msb + ps_cur_poc->i4_pic_order_cnt_lsb;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ i4_top_field_order_cnt = i8_result;
+ }
if(!u1_field_pic_flag)
{
- i4_bottom_field_order_cnt = i4_top_field_order_cnt
- + ps_cur_poc->i4_delta_pic_order_cnt_bottom;
+ WORD64 i8_result = (WORD64)i4_top_field_order_cnt
+ + ps_cur_poc->i4_delta_pic_order_cnt_bottom;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ i4_bottom_field_order_cnt = i8_result;
}
else if(u1_bottom_field_flag)
{
- i4_bottom_field_order_cnt = i1_pic_msb
- + ps_cur_poc->i4_pic_order_cnt_lsb;
+ WORD64 i8_result = i8_pic_msb + ps_cur_poc->i4_pic_order_cnt_lsb;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ i4_bottom_field_order_cnt = i8_result;
}
- ps_cur_poc->i4_pic_order_cnt_msb = i1_pic_msb;
+
+ if(IS_OUT_OF_RANGE_S32(i8_pic_msb))
+ {
+ return ERROR_INV_POC;
+ }
+ ps_cur_poc->i4_pic_order_cnt_msb = i8_pic_msb;
break;
case 1:
@@ -269,15 +289,27 @@
}
else if(prev_frame_num > ((WORD32)u2_frame_num))
{
- frame_num_ofst = i4_prev_frame_num_ofst
- + (WORD32)ps_seq->u2_u4_max_pic_num_minus1 + 1;
+ WORD64 i8_result = i4_prev_frame_num_ofst
+ + (WORD64)ps_seq->u2_u4_max_pic_num_minus1 + 1;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_FRAME_NUM;
+ }
+ frame_num_ofst = i8_result;
}
else
frame_num_ofst = i4_prev_frame_num_ofst;
/* 2. Derivation for absFrameNum */
if(0 != ps_seq->u1_num_ref_frames_in_pic_order_cnt_cycle)
- abs_frm_num = frame_num_ofst + (WORD32)u2_frame_num;
+ {
+ WORD64 i8_result = frame_num_ofst + (WORD64)u2_frame_num;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_FRAME_NUM;
+ }
+ abs_frm_num = i8_result;
+ }
else
abs_frm_num = 0;
if((u1_nal_ref_idc == 0) && (abs_frm_num > 0))
@@ -405,8 +437,13 @@
}
else if(prev_frame_num > ((WORD32)u2_frame_num))
{
- frame_num_ofst = i4_prev_frame_num_ofst
- + (WORD32)ps_seq->u2_u4_max_pic_num_minus1 + 1;
+ WORD64 i8_result = i4_prev_frame_num_ofst
+ + (WORD64)ps_seq->u2_u4_max_pic_num_minus1 + 1;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_FRAME_NUM;
+ }
+ frame_num_ofst = i8_result;
}
else
frame_num_ofst = i4_prev_frame_num_ofst;
@@ -415,10 +452,23 @@
if(u1_is_idr_slice)
tmp_poc = 0;
else if(u1_nal_ref_idc == 0)
- tmp_poc = ((frame_num_ofst + (WORD32)u2_frame_num) << 1)
- - 1;
+ {
+ WORD64 i8_result = ((frame_num_ofst + (WORD64)u2_frame_num) << 1) - 1;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ tmp_poc = i8_result;
+ }
else
- tmp_poc = ((frame_num_ofst + (WORD32)u2_frame_num) << 1);
+ {
+ WORD64 i8_result = (frame_num_ofst + (WORD64)u2_frame_num) << 1;
+ if(IS_OUT_OF_RANGE_S32(i8_result))
+ {
+ return ERROR_INV_POC;
+ }
+ tmp_poc = i8_result;
+ }
/* 6. TopFieldOrderCnt or BottomFieldOrderCnt are derived as */
if(!u1_field_pic_flag)
@@ -501,6 +551,7 @@
{
if(ps_cur_slice->u1_nal_unit_type == IDR_SLICE_NAL)
{
+ ps_dec->ps_dpb_mgr->u1_mmco_error_in_seq = 0;
if(ps_dec->ps_dpb_cmds->u1_long_term_reference_flag == 0)
{
ih264d_reset_ref_bufs(ps_dec->ps_dpb_mgr);
@@ -509,6 +560,7 @@
ps_dec->ps_cur_pic,
ps_dec->u1_pic_buf_id,
ps_cur_slice->u2_frame_num);
+ ps_dec->ps_dpb_mgr->u1_max_lt_frame_idx = NO_LONG_TERM_INDICIES;
}
else
{
@@ -527,7 +579,7 @@
ps_cur_slice->u2_frame_num, 0,
ps_cur_slice->u1_field_pic_flag);
- ps_dec->ps_dpb_mgr->u1_max_lt_pic_idx_plus1 = 1;
+ ps_dec->ps_dpb_mgr->u1_max_lt_frame_idx = 0;
}
}
}
@@ -537,16 +589,17 @@
{
UWORD16 u2_pic_num = ps_cur_slice->u2_frame_num;
- /* ignore DPB errors */
- ih264d_do_mmco_buffer(ps_dec->ps_dpb_cmds, ps_dec->ps_dpb_mgr,
- ps_dec->ps_cur_sps->u1_num_ref_frames, u2_pic_num,
- (ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1),
- ps_dec->u1_nal_unit_type, ps_dec->ps_cur_pic,
- ps_dec->u1_pic_buf_id,
- ps_cur_slice->u1_field_pic_flag,
- ps_dec->e_dec_status);
-
-
+ if(!ps_dec->ps_dpb_mgr->u1_mmco_error_in_seq)
+ {
+ WORD32 ret = ih264d_do_mmco_buffer(ps_dec->ps_dpb_cmds, ps_dec->ps_dpb_mgr,
+ ps_dec->ps_cur_sps->u1_num_ref_frames, u2_pic_num,
+ (ps_dec->ps_cur_sps->u2_u4_max_pic_num_minus1),
+ ps_dec->u1_nal_unit_type, ps_dec->ps_cur_pic,
+ ps_dec->u1_pic_buf_id,
+ ps_cur_slice->u1_field_pic_flag,
+ ps_dec->e_dec_status);
+ ps_dec->ps_dpb_mgr->u1_mmco_error_in_seq = ret != OK;
+ }
}
}
ih264d_update_default_index_list(ps_dec->ps_dpb_mgr);
@@ -769,7 +822,6 @@
else
ps_dec->i4_display_delay = ps_seq->s_vui.u4_num_reorder_frames * 2 + 2;
}
- ps_dec->i4_reorder_depth = ps_dec->i4_display_delay;
if(IVD_DECODE_FRAME_OUT == ps_dec->e_frm_out_mode)
ps_dec->i4_display_delay = 0;
@@ -1300,7 +1352,7 @@
WORD32 i4_min_poc;
WORD32 i4_min_poc_buf_id;
WORD32 i4_min_index;
- UWORD64 u8_temp;
+ WORD64 i8_temp;
dpb_manager_t *ps_dpb_mgr = ps_dec->ps_dpb_mgr;
WORD32 (*i4_poc_buf_id_map)[3] = ps_dpb_mgr->ai4_poc_buf_id_map;
@@ -1347,11 +1399,11 @@
}
}
ps_dpb_mgr->i1_poc_buf_id_entries = 0;
- u8_temp = (UWORD64)ps_dec->i4_prev_max_display_seq + ps_dec->i4_max_poc
+ i8_temp = (WORD64)ps_dec->i4_prev_max_display_seq + ps_dec->i4_max_poc
+ ps_dec->u1_max_dec_frame_buffering + 1;
/*If i4_prev_max_display_seq overflows integer range, reset it */
- ps_dec->i4_prev_max_display_seq = (u8_temp > 0x7fffffff)?
- 0 : u8_temp;
+ ps_dec->i4_prev_max_display_seq = IS_OUT_OF_RANGE_S32(i8_temp)?
+ 0 : i8_temp;
ps_dec->i4_max_poc = 0;
}
@@ -1623,13 +1675,13 @@
/* IDR Picture or POC wrap around */
if(i4_poc == 0)
{
- UWORD64 u8_temp;
- u8_temp = (UWORD64)ps_dec->i4_prev_max_display_seq
+ WORD64 i8_temp;
+ i8_temp = (WORD64)ps_dec->i4_prev_max_display_seq
+ ps_dec->i4_max_poc
+ ps_dec->u1_max_dec_frame_buffering + 1;
/*If i4_prev_max_display_seq overflows integer range, reset it */
- ps_dec->i4_prev_max_display_seq = (u8_temp > 0x7fffffff)?
- 0 : u8_temp;
+ ps_dec->i4_prev_max_display_seq = IS_OUT_OF_RANGE_S32(i8_temp)?
+ 0 : i8_temp;
ps_dec->i4_max_poc = 0;
}
@@ -1647,8 +1699,8 @@
}
{
- UWORD64 i8_display_poc;
- i8_display_poc = (UWORD64)ps_dec->i4_prev_max_display_seq +
+ WORD64 i8_display_poc;
+ i8_display_poc = (WORD64)ps_dec->i4_prev_max_display_seq +
i4_poc;
if(IS_OUT_OF_RANGE_S32(i8_display_poc))
{
diff --git a/encoder/ih264e_encode.c b/encoder/ih264e_encode.c
index fb37765..9210b3e 100644
--- a/encoder/ih264e_encode.c
+++ b/encoder/ih264e_encode.c
@@ -545,16 +545,16 @@
* We need to return a recon when ever we consume an input buffer. This
* comsumption include a pre or post enc skip. Thus dump recon is set for
* all cases except when
- * 1) We are waiting -> ps_codec->i4_frame_num > 1
- * 2) When the input buffer is null [ ie we are not consuming any inp]
+ * 1) We are waiting -> ps_codec->i4_pic_cnt > ps_codec->s_cfg.u4_num_bframe
* An exception need to be made for the case when we have the last buffer
* since we need to flush out the on remainig recon.
****************************************************************************/
ps_video_encode_op->s_ive_op.dump_recon = 0;
- if (ps_codec->s_cfg.u4_enable_recon && (ps_codec->i4_frame_num > 1 || s_inp_buf.u4_is_last)
- && (s_inp_buf.s_raw_buf.apv_bufs[0] || s_inp_buf.u4_is_last))
+ if (ps_codec->s_cfg.u4_enable_recon
+ && (ps_codec->i4_pic_cnt > (WORD32)ps_codec->s_cfg.u4_num_bframes ||
+ s_inp_buf.u4_is_last))
{
/* error status */
IH264_ERROR_T ret = IH264_SUCCESS;
diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp
index 8540107..cb9d246 100644
--- a/fuzzer/Android.bp
+++ b/fuzzer/Android.bp
@@ -13,4 +13,32 @@
enabled: false,
},
},
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ },
+}
+
+cc_fuzz {
+ name: "avc_enc_fuzzer",
+ host_supported: true,
+ srcs: [
+ "avc_enc_fuzzer.cpp",
+ ],
+ static_libs: [
+ "libavcenc",
+ "liblog",
+ ],
+ cflags: [
+ "-Wall",
+ "-Werror",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ },
}
diff --git a/fuzzer/README.md b/fuzzer/README.md
index a42e8b5..8e29ec6 100644
--- a/fuzzer/README.md
+++ b/fuzzer/README.md
@@ -64,6 +64,138 @@
$ $ANDROID_HOST_OUT/fuzz/avc_dec_fuzzer CORPUS_DIR
```
+
+# Fuzzer for libavc encoder
+
+## Plugin Design Considerations
+The fuzzer plugin for AVC is designed based on the understanding of the
+codec and tries to achieve the following:
+
+##### Maximize code coverage
+The configuration parameters are not hardcoded, but instead selected based on
+incoming data. This ensures more code paths are reached by the fuzzer.
+
+AVC supports the following parameters:
+1. Frame Width (parameter name: `u4_wd`)
+2. Frame Height (parameter name: `u4_ht`)
+3. Input color format (parameter name: `e_inp_color_fmt`)
+4. Architecture type (parameter name: `e_arch`)
+5. Rate control mode (parameter name: `e_rc_mode`)
+6. Number of cores (parameter name: `u4_num_cores`)
+7. Maximum B frames (parameter name: `u4_num_bframes`)
+8. Encoder speed preset (parameter name: `u4_enc_speed_preset`)
+9. enable constrained intra prediction (parameter name: `u4_constrained_intra_pred`)
+10. enable intra 4x4 (parameter name: `u4_enable_intra_4x4`)
+11. Qp for I frames (parameter name: `u4_i_qp`)
+12. Qp for P frames (parameter name: `u4_p_qp`)
+13. Qp for B frames (parameter name: `u4_b_qp`)
+14. Target Bitrate (parameter name: `u4_target_bitrate`)
+15. Intra refresh period in frames (parameter name: `u4_air_refresh_period`)
+16. Enable half pel ME (parameter name: `u4_enable_hpel`)
+17. Enable quarter pel ME (parameter name: `u4_enable_qpel`)
+18. ME speed preset (parameter name: `u4_me_speed_preset`)
+19. Adaptive intra refresh mode (parameter name: `e_air_mode`)
+20. Disable deblock level (parameter name: `u4_disable_deblock_level`)
+21. Max search range in X direction (parameter name: `u4_srch_rng_x`)
+22. Max search range in Y direction (parameter name: `u4_srch_rng_y`)
+23. I frame interval (parameter name: `u4_i_frm_interval`)
+24. IDR frame interval (parameter name: `u4_idr_frm_interval`)
+25. Enable mastering display color volume info (parameter name: `u1_sei_mdcv_params_present_flag`)
+26. Enable content light level info (parameter name: `u1_sei_cll_params_present_flag`)
+27. Enable ambient viewing environment info (parameter name: `u1_sei_ave_params_present_flag`)
+28. Enable content color volume info (parameter name: `u1_sei_ccv_params_present_flag`)
+29. Profile (parameter name: `e_profile`)
+30. Enable aspect_ratio info (parameter name: `u1_aspect_ratio_info_present_flag`)
+31. Enable NAL HRD parameters presence (parameter name: `u1_nal_hrd_parameters_present_flag`)
+32. Enable VCL HRD parameters presence (parameter name: `u1_vcl_hrd_parameters_present_flag`)
+33. Enable force IDR frame (parameter name: `mIsForceIdrEnabled`)
+34. Enable dynamic bitrate change (parameter name: `mIsDynamicBitRateChangeEnabled`)
+35. Enable dynamic framerate change (parameter name: `mIsDynamicFrameRateChangeEnabled`)
+36. Force IDR frame number (parameter name: `mForceIdrInterval`)
+37. Frame number for dynamic bitrate (parameter name: `mDynamicBitRateInterval`)
+38. Frame number for dynamic framerate (parameter name: `mDynamicFrameRateInterval`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+| `u4_wd` | In the range `0 to 10239` | All the bits of 1st and 2nd byte of data |
+| `u4_ht` | In the range `0 to 10239` | All the bits of 3rd and 4th byte of data |
+| `e_inp_color_fmt` | 0. `IV_YUV_420P` 1. `IV_YUV_420SP_UV` 2. `IV_YUV_422ILE` 3. `IV_YUV_420SP_VU` | All the bits of 5th byte of data |
+| `e_arch` | 0. `ARCH_ARM_NONEON` 1. `ARCH_NA` | bit 0 and 1 of 6th byte of data |
+| `e_rc_mode` | 0. `IVE_RC_NONE` 1. `IVE_RC_STORAGE` 2. `IVE_RC_CBR_NON_LOW_DELAY` 3. `IVE_RC_CBR_LOW_DELAY` | All the bits of 7th byte of data modulus 4 |
+| `u4_num_cores` | 0. `0` 1. `1` 2. `2` 3. `3`| bit 0 and 1 of 8th byte of data |
+| `u4_num_bframes` | In the range `0 to 7` | bit 0, 1 and 2 of 9th byte of data |
+| `u4_enc_speed_preset` | 0. `IVE_CONFIG` 1. `IVE_SLOWEST` 2. `IVE_NORMAL` 3. `IVE_FAST` 4. `IVE_HIGH_SPEED` 5. `IVE_FASTEST` | All the bits of 10th byte of data modulus 6 |
+| `u4_constrained_intra_pred` | 0. `0` 1. `1` | bit 0 of 11th byte of data |
+| `u4_enable_intra_4x4` | 0. `0` 1. `1` | bit 0 of 12th byte of data |
+| `u4_i_qp` | In the range `4 to 51` | All the bits of 13th byte of data |
+| `u4_p_qp` | In the range `4 to 51` | All the bits of 14th byte of data |
+| `u4_b_qp` | In the range `4 to 51` | All the bits of 15th byte of data |
+| `u4_target_bitrate` | In the range `0 to 500000000` | All the bits of 16th and 17th byte of data |
+| `u4_target_bitrate` | In the range `0 to 255` | All the bits of 18th byte of data |
+| `u4_air_refresh_period` | In the range `1 to 256` | All the bits of 19th byte of data |
+| `u4_air_refresh_period` | In the range `1 to 256` | All the bits of 19th byte of data |
+| `u4_enable_hpel` | 0. `0` 1. `1` | bit 0 of 20th byte of data |
+| `u4_enable_qpel` | 0. `0` 1. `1` | bit 0 of 21st byte of data |
+| `u4_me_speed_preset` | 0. `0` 1. `50` 2. `75` 3. `100` | All the bits of 22nd byte of data modulus 4 |
+| `e_air_mode` | 0. `IVE_AIR_MODE_NONE` 1. `IVE_AIR_MODE_CYCLIC` 2. `IVE_AIR_MODE_RANDOM` | All the bits of 23rd byte of data modulus 3 |
+| `u4_disable_deblock_level` | 0. `0` 1. `1` 2. `2` 3. `3` | bit 0 and 1 of 24th byte of data |
+| `u4_srch_rng_x` | In the range `0 to 255` | All the bits of 25th byte of data |
+| `u4_srch_rng_y` | In the range `0 to 255`| All the bits of 26th byte of data |
+| `u4_i_frm_interval` | In the range `1 to 256` | All the bits of 27th byte of data |
+| `u4_idr_frm_interval` | In the range `1 to 256` | All the bits of 28th byte of data |
+| `u1_sei_mdcv_params_present_flag` | 0. `0` 1. `1` | bit 0 of 29th byte of data |
+| `u1_sei_cll_params_present_flag` | 0. `0` 1. `1` | bit 0 of 30th byte of data |
+| `u1_sei_ave_params_present_flag` | 0. `0` 1. `1` | bit 0 of 31st byte of data |
+| `u1_sei_ccv_params_present_flag` | 0. `0` 1. `1` | bit 0 of 32nd byte of data |
+| `e_profile` | 0. `IV_PROFILE_BASE` 1. `IV_PROFILE_MAIN` | bit 0 and 1 of 33th byte of data modulus 2 |
+| `u1_aspect_ratio_info_present_flag` | 0. `0` 1. `1` | bit 0 of 34th byte of data |
+| `u1_nal_hrd_parameters_present_flag` | 0. `0` 1. `1` | bit 0 of 35th byte of data |
+| `u1_vcl_hrd_parameters_present_flag` | 0. `0` 1. `1` | bit 0 of 36th byte of data |
+| `mIsForceIdrEnabled` | 0. `0` 1. `1` | bit 0 of 37th byte of data |
+| `mIsDynamicBitRateChangeEnabled` | 0. `0` 1. `1` | bit 0 of 38th byte of data |
+| `mIsDynamicFrameRateChangeEnabled` | 0. `0` 1. `1` | bit 0 of 39th byte of data |
+| `mForceIdrInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 40th byte of data |
+| `mDynamicBitRateInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 41st byte of data |
+| `mDynamicFrameRateInterval` | In the range `0 to 7` | bit 0, 1 and 2 of 42nd byte of data |
+
+This also ensures that the plugin is always deterministic for any given input.
+
+##### Maximize utilization of input data
+The plugin feeds the entire input data to the codec using a loop.
+If the encode operation was successful, the input is advanced by the frame size.
+If the encode operation was un-successful, the input is still advanced by frame size so
+that the fuzzer can proceed to feed the next frame.
+
+This ensures that the plugin tolerates any kind of input (empty, huge,
+malformed, etc) and doesnt `exit()` on any input and thereby increasing the
+chance of identifying vulnerabilities.
+
+## Build
+
+This describes steps to build avc_enc_fuzzer binary.
+
+### Android
+
+#### Steps to build
+Build the fuzzer
+```
+ $ mm -j$(nproc) avc_enc_fuzzer
+```
+
+#### Steps to run
+Create a directory CORPUS_DIR and copy some yuv files to that folder
+Push this directory to device.
+
+To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/avc_enc_fuzzer/avc_enc_fuzzer CORPUS_DIR
+```
+To run on host
+```
+ $ $ANDROID_HOST_OUT/fuzz/x86_64/avc_enc_fuzzer/avc_enc_fuzzer CORPUS_DIR
+```
+
## References:
* http://llvm.org/docs/LibFuzzer.html
* https://github.com/google/oss-fuzz
diff --git a/fuzzer/avc_enc_fuzzer.cpp b/fuzzer/avc_enc_fuzzer.cpp
new file mode 100644
index 0000000..e01f6a5
--- /dev/null
+++ b/fuzzer/avc_enc_fuzzer.cpp
@@ -0,0 +1,1001 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+#include <malloc.h>
+#include <algorithm>
+
+#include "ih264_defs.h"
+#include "ih264_typedefs.h"
+#include "ih264e.h"
+#include "ih264e_error.h"
+#define ive_api_function ih264e_api_function
+
+constexpr uint32_t kHeaderLength = 0x800;
+constexpr int16_t kCompressionRatio = 1;
+
+constexpr int kMeSpeedPreset[] = {0, 50, 75, 100};
+constexpr IVE_AIR_MODE_T kAirMode[] = {IVE_AIR_MODE_NONE, IVE_AIR_MODE_CYCLIC, IVE_AIR_MODE_RANDOM};
+constexpr IVE_SPEED_CONFIG kEncSpeed[] = {IVE_CONFIG, IVE_SLOWEST, IVE_NORMAL,
+ IVE_FAST, IVE_HIGH_SPEED, IVE_FASTEST};
+constexpr IV_PROFILE_T kProfle[] = {IV_PROFILE_BASE, IV_PROFILE_MAIN};
+constexpr IVE_RC_MODE_T kRCMode[] = {IVE_RC_NONE, IVE_RC_STORAGE, IVE_RC_CBR_NON_LOW_DELAY,
+ IVE_RC_CBR_LOW_DELAY};
+constexpr IV_COLOR_FORMAT_T kSupportedColorFormats[] = {IV_YUV_420P, IV_YUV_420SP_UV, IV_YUV_422ILE,
+ IV_YUV_420SP_VU};
+
+constexpr size_t kAirModeNum = std::size(kAirMode);
+constexpr size_t kEncSpeedNum = std::size(kEncSpeed);
+constexpr size_t kMeSpeedPresetNum = std::size(kMeSpeedPreset);
+constexpr size_t kProfleNum = std::size(kProfle);
+constexpr size_t kRCModeNum = std::size(kRCMode);
+constexpr size_t kSupportedColorFormatsNum = std::size(kSupportedColorFormats);
+constexpr size_t kMinQP = 4;
+constexpr size_t kMaxWidth = 10240;
+constexpr size_t kMaxHeight = 10240;
+constexpr size_t kMaxBitrate = 500000000;
+
+enum {
+ IDX_WD_BYTE_1,
+ IDX_WD_BYTE_2,
+ IDX_HT_BYTE_1,
+ IDX_HT_BYTE_2,
+ IDX_COLOR_FORMAT,
+ IDX_ARCH_TYPE,
+ IDX_RC_MODE,
+ IDX_NUM_CORES,
+ IDX_NUM_B_FRAMES,
+ IDX_ENC_SPEED,
+ IDX_CONSTRAINED_INTRA_FLAG,
+ IDX_INTRA_4x4,
+ IDX_I_FRAME_QP,
+ IDX_P_FRAME_QP,
+ IDX_B_FRAME_QP,
+ IDX_BITRATE_BYTE_1,
+ IDX_BITRATE_BYTE_2,
+ IDX_FRAME_RATE,
+ IDX_INTRA_REFRESH,
+ IDX_ENABLE_HALF_PEL,
+ IDX_ENABLE_Q_PEL,
+ IDX_ME_SPEED_PRESET,
+ IDX_AIR_MODE,
+ IDX_DISABLE_DEBLOCK_LEVEL,
+ IDX_SEARCH_RANGE_X,
+ IDX_SEARCH_RANGE_Y,
+ IDX_I_INTERVAL,
+ IDX_IDR_INTERVAL,
+ IDX_SEI_MDCV_FLAG,
+ IDX_SEI_CLL_FLAG,
+ IDX_SEI_AVE_FLAG,
+ IDX_SEI_CCV_FLAG,
+ IDX_PROFILE,
+ IDX_ASPECT_RATIO_FLAG,
+ IDX_NAL_HRD_FLAG,
+ IDX_VCL_HRD_FLAG,
+ IDX_ENABLE_FORCE_IDR,
+ IDX_ENABLE_DYNAMIC_BITRATE,
+ IDX_ENABLE_DYNAMIC_FRAME_RATE,
+ IDX_FORCE_IDR_INTERVAL,
+ IDX_DYNAMIC_BITRATE_INTERVAL,
+ IDX_DYNAMIC_FRAME_RATE_INTERVAL,
+ IDX_LAST
+};
+
+class Codec {
+ public:
+ Codec() = default;
+ ~Codec() { deInitEncoder(); }
+ bool initEncoder(const uint8_t **pdata, size_t *psize);
+ void encodeFrames(const uint8_t *data, size_t size);
+ void deInitEncoder();
+
+ private:
+ void setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data);
+ void setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType);
+ void setQp();
+ void setEncMode(IVE_ENC_MODE_T eEncMode);
+ void setDimensions();
+ void setNumCores();
+ void setFrameRate();
+ void setIpeParams();
+ void setBitRate();
+ void setAirParams();
+ void setMeParams();
+ void setGopParams();
+ void setProfileParams();
+ void setDeblockParams();
+ void setVbvParams();
+ void setDefault();
+ void setVuiParams();
+ void getBufInfo();
+ void setSeiMdcvParams();
+ void setSeiCllParams();
+ void setSeiAveParams();
+ void setSeiCcvParams();
+ void logVersion();
+ bool mHalfPelEnable = 1;
+ bool mQPelEnable = 1;
+ bool mIntra4x4 = 0;
+ bool mEnableFastSad = 0;
+ bool mEnableAltRef = 0;
+ bool mConstrainedIntraFlag = 0;
+ bool mSeiCllFlag = 1;
+ bool mSeiAveFlag = 1;
+ bool mSeiCcvFlag = 1;
+ bool mSeiMdcvFlag = 1;
+ bool mAspectRatioFlag = 0;
+ bool mNalHrdFlag = 0;
+ bool mVclHrdFlag = 0;
+ bool mIsForceIdrEnabled = false;
+ bool mIsDynamicBitRateChangeEnabled = false;
+ bool mIsDynamicFrameRateChangeEnabled = false;
+ uint32_t mWidth = 2560;
+ uint32_t mHeight = 2560;
+ uint32_t mAvcEncLevel = 41;
+ uint32_t mNumMemRecords = 0;
+ uint32_t mNumCores = 1;
+ uint32_t mBframes = 0;
+ uint32_t mSliceParam = 256;
+ uint32_t mMeSpeedPreset = 100;
+ uint32_t mIInterval = 60;
+ uint32_t mIDRInterval = 60;
+ uint32_t mDisableDeblockLevel = 0;
+ uint32_t m_I_QP = 22;
+ uint32_t m_P_QP = 28;
+ uint32_t m_B_QP = 22;
+ uint32_t mIntraRefresh = 30;
+ uint32_t mSearchRangeX = 64;
+ uint32_t mSearchRangeY = 48;
+ uint32_t mForceIdrInterval = 0; // in number of frames
+ uint32_t mDynamicBitRateInterval = 0; // in number of frames
+ uint32_t mDynamicFrameRateInterval = 0; // in number of frames
+ uint64_t mBitrate = 6000000;
+ float mFrameRate = 30;
+ iv_obj_t *mCodecCtx = nullptr;
+ iv_mem_rec_t *mMemRecords = nullptr;
+ IVE_AIR_MODE_T mAirMode = IVE_AIR_MODE_NONE;
+ IVE_SPEED_CONFIG mEncSpeed = IVE_NORMAL;
+ IVE_RC_MODE_T mRCMode = IVE_RC_STORAGE;
+ IV_ARCH_T mArch = ARCH_NA;
+ IVE_SLICE_MODE_T mSliceMode = IVE_SLICE_MODE_NONE;
+ IV_COLOR_FORMAT_T mIvVideoColorFormat = IV_YUV_420P;
+ IV_COLOR_FORMAT_T mReconFormat = IV_YUV_420P;
+ IV_PROFILE_T mProfile = IV_PROFILE_BASE;
+};
+
+bool Codec::initEncoder(const uint8_t **pdata, size_t *psize) {
+ uint8_t *data = const_cast<uint8_t *>(*pdata);
+ mWidth = ((data[IDX_WD_BYTE_1] << 8) | data[IDX_WD_BYTE_2]) % kMaxWidth;
+ mHeight = ((data[IDX_HT_BYTE_1] << 8) | data[IDX_HT_BYTE_2]) % kMaxHeight;
+
+ mIvVideoColorFormat =
+ kSupportedColorFormats[data[IDX_COLOR_FORMAT] % kSupportedColorFormatsNum];
+ mArch = ((data[IDX_ARCH_TYPE] & 0x03) == 0x00) ? ARCH_ARM_NONEON : ARCH_NA;
+ mRCMode = kRCMode[data[IDX_RC_MODE] % kRCModeNum];
+ mNumCores = (data[IDX_NUM_CORES] & 0x07) + 1;
+ mBframes = data[IDX_NUM_B_FRAMES] & 0x07;
+ mEncSpeed = kEncSpeed[data[IDX_ENC_SPEED] % kEncSpeedNum];
+ mConstrainedIntraFlag = data[IDX_CONSTRAINED_INTRA_FLAG] & 0x01;
+ mIntra4x4 = data[IDX_INTRA_4x4] & 0x01;
+ m_I_QP = (data[IDX_I_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP;
+ m_P_QP = (data[IDX_P_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP;
+ m_B_QP = (data[IDX_B_FRAME_QP] % (MAX_H264_QP - kMinQP)) + kMinQP;
+ mBitrate = (((data[IDX_BITRATE_BYTE_1] << 8) | data[IDX_BITRATE_BYTE_2]) * 1000) % kMaxBitrate;
+ mFrameRate = data[IDX_FRAME_RATE];
+ mIntraRefresh = data[IDX_INTRA_REFRESH] + 1;
+ mHalfPelEnable = data[IDX_ENABLE_HALF_PEL] & 0x01;
+ mQPelEnable = data[IDX_ENABLE_Q_PEL] & 0x01;
+ mMeSpeedPreset = kMeSpeedPreset[data[IDX_ME_SPEED_PRESET] % kMeSpeedPresetNum];
+ mAirMode = kAirMode[data[IDX_AIR_MODE] % kAirModeNum];
+ mDisableDeblockLevel = data[IDX_DISABLE_DEBLOCK_LEVEL] & 0x03;
+ mSearchRangeX = data[IDX_SEARCH_RANGE_X];
+ mSearchRangeY = data[IDX_SEARCH_RANGE_Y];
+ mIInterval = data[IDX_I_INTERVAL] + 1;
+ mIDRInterval = data[IDX_IDR_INTERVAL] + 1;
+ mSeiMdcvFlag = data[IDX_SEI_MDCV_FLAG] & 0x01;
+ mSeiCllFlag = data[IDX_SEI_CLL_FLAG] & 0x01;
+ mSeiAveFlag = data[IDX_SEI_AVE_FLAG] & 0x01;
+ mSeiCcvFlag = data[IDX_SEI_CCV_FLAG] & 0x01;
+ mProfile = kProfle[data[IDX_PROFILE] % kProfleNum];
+ mAspectRatioFlag = data[IDX_ASPECT_RATIO_FLAG] & 0x01;
+ mNalHrdFlag = data[IDX_NAL_HRD_FLAG] & 0x01;
+ mVclHrdFlag = data[IDX_VCL_HRD_FLAG] & 0x01;
+ mIsForceIdrEnabled = data[IDX_ENABLE_FORCE_IDR] & 0x01;
+ mIsDynamicBitRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_BITRATE] & 0x01;
+ mIsDynamicFrameRateChangeEnabled = data[IDX_ENABLE_DYNAMIC_FRAME_RATE] & 0x01;
+ mForceIdrInterval = data[IDX_FORCE_IDR_INTERVAL] & 0x07;
+ mDynamicBitRateInterval = data[IDX_DYNAMIC_BITRATE_INTERVAL] & 0x07;
+ mDynamicFrameRateInterval = data[IDX_DYNAMIC_FRAME_RATE_INTERVAL] & 0x07;
+
+ /* Getting Number of MemRecords */
+ iv_num_mem_rec_ip_t sNumMemRecIp{};
+ iv_num_mem_rec_op_t sNumMemRecOp{};
+
+ sNumMemRecIp.u4_size = sizeof(iv_num_mem_rec_ip_t);
+ sNumMemRecOp.u4_size = sizeof(iv_num_mem_rec_op_t);
+ sNumMemRecIp.e_cmd = IV_CMD_GET_NUM_MEM_REC;
+
+ if (IV_SUCCESS != ive_api_function(nullptr, &sNumMemRecIp, &sNumMemRecOp)) {
+ return false;
+ }
+ mNumMemRecords = sNumMemRecOp.u4_num_mem_rec;
+ mMemRecords = (iv_mem_rec_t *)malloc(mNumMemRecords * sizeof(iv_mem_rec_t));
+ if (!mMemRecords) {
+ return false;
+ }
+ iv_mem_rec_t *psMemRec;
+ psMemRec = mMemRecords;
+ for (size_t i = 0; i < mNumMemRecords; ++i) {
+ psMemRec->u4_size = sizeof(iv_mem_rec_t);
+ psMemRec->pv_base = nullptr;
+ psMemRec->u4_mem_size = 0;
+ psMemRec->u4_mem_alignment = 0;
+ psMemRec->e_mem_type = IV_NA_MEM_TYPE;
+ ++psMemRec;
+ }
+
+ /* Getting MemRecords Attributes */
+ iv_fill_mem_rec_ip_t sFillMemRecIp{};
+ iv_fill_mem_rec_op_t sFillMemRecOp{};
+
+ sFillMemRecIp.u4_size = sizeof(iv_fill_mem_rec_ip_t);
+ sFillMemRecOp.u4_size = sizeof(iv_fill_mem_rec_op_t);
+
+ sFillMemRecIp.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
+ sFillMemRecIp.ps_mem_rec = mMemRecords;
+ sFillMemRecIp.u4_num_mem_rec = mNumMemRecords;
+ sFillMemRecIp.u4_max_wd = mWidth;
+ sFillMemRecIp.u4_max_ht = mHeight;
+ sFillMemRecIp.u4_max_level = mAvcEncLevel;
+ sFillMemRecIp.e_color_format = IV_YUV_420SP_VU;
+ sFillMemRecIp.u4_max_ref_cnt = 2;
+ sFillMemRecIp.u4_max_reorder_cnt = 0;
+ sFillMemRecIp.u4_max_srch_rng_x = 256;
+ sFillMemRecIp.u4_max_srch_rng_y = 256;
+
+ if (IV_SUCCESS != ive_api_function(nullptr, &sFillMemRecIp, &sFillMemRecOp)) {
+ return false;
+ }
+ /* Allocating Memory for Mem Records */
+ psMemRec = mMemRecords;
+ for (size_t i = 0; i < mNumMemRecords; ++i) {
+ posix_memalign(&psMemRec->pv_base, psMemRec->u4_mem_alignment, psMemRec->u4_mem_size);
+ if (!psMemRec->pv_base) {
+ return false;
+ }
+ ++psMemRec;
+ }
+
+ /* Codec Instance Creation */
+ ive_init_ip_t sInitIp{};
+ ive_init_op_t sInitOp{};
+
+ mCodecCtx = (iv_obj_t *)mMemRecords[0].pv_base;
+ mCodecCtx->u4_size = sizeof(iv_obj_t);
+ mCodecCtx->pv_fxns = (void *)ive_api_function;
+
+ sInitIp.u4_size = sizeof(ive_init_ip_t);
+ sInitOp.u4_size = sizeof(ive_init_op_t);
+
+ sInitIp.e_cmd = IV_CMD_INIT;
+ sInitIp.u4_num_mem_rec = mNumMemRecords;
+ sInitIp.ps_mem_rec = mMemRecords;
+ sInitIp.u4_max_wd = mWidth;
+ sInitIp.u4_max_ht = mHeight;
+ sInitIp.u4_max_ref_cnt = 2;
+ sInitIp.u4_max_reorder_cnt = 0;
+ sInitIp.u4_max_level = mAvcEncLevel;
+ sInitIp.e_inp_color_fmt = mIvVideoColorFormat;
+ sInitIp.u4_enable_recon = 0;
+ sInitIp.e_recon_color_fmt = mReconFormat;
+ sInitIp.e_rc_mode = mRCMode;
+ sInitIp.u4_max_framerate = 120000;
+ sInitIp.u4_max_bitrate = 240000000;
+ sInitIp.u4_num_bframes = mBframes;
+ sInitIp.e_content_type = IV_PROGRESSIVE;
+ sInitIp.u4_max_srch_rng_x = 256;
+ sInitIp.u4_max_srch_rng_y = 256;
+ sInitIp.e_slice_mode = mSliceMode;
+ sInitIp.u4_slice_param = mSliceParam;
+ sInitIp.e_arch = mArch;
+ sInitIp.e_soc = SOC_GENERIC;
+
+ if (IV_SUCCESS != ive_api_function(mCodecCtx, &sInitIp, &sInitOp)) {
+ return false;
+ }
+
+ logVersion();
+ setDefault();
+ getBufInfo();
+ setNumCores();
+ setDimensions();
+ setFrameRate();
+ setIpeParams();
+ setBitRate();
+ setQp();
+ setAirParams();
+ setVbvParams();
+ setMeParams();
+ setGopParams();
+ setDeblockParams();
+ setVuiParams();
+ setSeiMdcvParams();
+ setSeiCllParams();
+ setSeiAveParams();
+ setSeiCcvParams();
+ setProfileParams();
+ setEncMode(IVE_ENC_MODE_HEADER);
+
+ *pdata += IDX_LAST;
+ *psize -= IDX_LAST;
+ return true;
+}
+
+void Codec::setDimensions() {
+ ive_ctl_set_dimensions_ip_t sDimensionsIp{};
+ ive_ctl_set_dimensions_op_t sDimensionsOp{};
+
+ sDimensionsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sDimensionsIp.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS;
+ sDimensionsIp.u4_ht = mHeight;
+ sDimensionsIp.u4_wd = mWidth;
+
+ sDimensionsIp.u4_timestamp_high = -1;
+ sDimensionsIp.u4_timestamp_low = -1;
+
+ sDimensionsIp.u4_size = sizeof(ive_ctl_set_dimensions_ip_t);
+ sDimensionsOp.u4_size = sizeof(ive_ctl_set_dimensions_op_t);
+
+ ive_api_function(mCodecCtx, &sDimensionsIp, &sDimensionsOp);
+ return;
+}
+
+void Codec::setNumCores() {
+ ive_ctl_set_num_cores_ip_t sNumCoresIp{};
+ ive_ctl_set_num_cores_op_t sNumCoresOp{};
+
+ sNumCoresIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sNumCoresIp.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES;
+ sNumCoresIp.u4_num_cores = mNumCores;
+
+ sNumCoresIp.u4_timestamp_high = -1;
+ sNumCoresIp.u4_timestamp_low = -1;
+
+ sNumCoresIp.u4_size = sizeof(ive_ctl_set_num_cores_ip_t);
+ sNumCoresOp.u4_size = sizeof(ive_ctl_set_num_cores_op_t);
+
+ ive_api_function(mCodecCtx, (void *)&sNumCoresIp, (void *)&sNumCoresOp);
+ return;
+}
+
+void Codec::setDefault() {
+ ive_ctl_setdefault_ip_t sDefaultIp{};
+ ive_ctl_setdefault_op_t sDefaultOp{};
+
+ sDefaultIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sDefaultIp.e_sub_cmd = IVE_CMD_CTL_SETDEFAULT;
+
+ sDefaultIp.u4_timestamp_high = -1;
+ sDefaultIp.u4_timestamp_low = -1;
+
+ sDefaultIp.u4_size = sizeof(ive_ctl_setdefault_ip_t);
+ sDefaultOp.u4_size = sizeof(ive_ctl_setdefault_op_t);
+
+ ive_api_function(mCodecCtx, &sDefaultIp, &sDefaultOp);
+ return;
+}
+
+void Codec::getBufInfo() {
+ ih264e_ctl_getbufinfo_ip_t sGetBufInfoIp{};
+ ih264e_ctl_getbufinfo_op_t sGetBufInfoOp{};
+
+ sGetBufInfoIp.s_ive_ip.u4_size = sizeof(ih264e_ctl_getbufinfo_ip_t);
+ sGetBufInfoOp.s_ive_op.u4_size = sizeof(ih264e_ctl_getbufinfo_op_t);
+
+ sGetBufInfoIp.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL;
+ sGetBufInfoIp.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETBUFINFO;
+ sGetBufInfoIp.s_ive_ip.u4_max_ht = mHeight;
+ sGetBufInfoIp.s_ive_ip.u4_max_wd = mWidth;
+ sGetBufInfoIp.s_ive_ip.e_inp_color_fmt = mIvVideoColorFormat;
+
+ ih264e_api_function(mCodecCtx, &sGetBufInfoIp, &sGetBufInfoOp);
+ return;
+}
+
+void Codec::setFrameRate() {
+ ive_ctl_set_frame_rate_ip_t sFrameRateIp{};
+ ive_ctl_set_frame_rate_op_t sFrameRateOp{};
+
+ sFrameRateIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sFrameRateIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE;
+ sFrameRateIp.u4_src_frame_rate = mFrameRate;
+ sFrameRateIp.u4_tgt_frame_rate = mFrameRate;
+
+ sFrameRateIp.u4_timestamp_high = -1;
+ sFrameRateIp.u4_timestamp_low = -1;
+
+ sFrameRateIp.u4_size = sizeof(ive_ctl_set_frame_rate_ip_t);
+ sFrameRateOp.u4_size = sizeof(ive_ctl_set_frame_rate_op_t);
+
+ ive_api_function(mCodecCtx, &sFrameRateIp, &sFrameRateOp);
+ return;
+}
+
+void Codec::setIpeParams() {
+ ive_ctl_set_ipe_params_ip_t sIpeParamsIp{};
+ ive_ctl_set_ipe_params_op_t sIpeParamsOp{};
+
+ sIpeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sIpeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS;
+ sIpeParamsIp.u4_enable_intra_4x4 = mIntra4x4;
+ sIpeParamsIp.u4_enc_speed_preset = mEncSpeed;
+ sIpeParamsIp.u4_constrained_intra_pred = mConstrainedIntraFlag;
+
+ sIpeParamsIp.u4_timestamp_high = -1;
+ sIpeParamsIp.u4_timestamp_low = -1;
+
+ sIpeParamsIp.u4_size = sizeof(ive_ctl_set_ipe_params_ip_t);
+ sIpeParamsOp.u4_size = sizeof(ive_ctl_set_ipe_params_op_t);
+
+ ive_api_function(mCodecCtx, &sIpeParamsIp, &sIpeParamsOp);
+ return;
+}
+
+void Codec::setBitRate() {
+ ive_ctl_set_bitrate_ip_t sBitrateIp{};
+ ive_ctl_set_bitrate_op_t sBitrateOp{};
+
+ sBitrateIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sBitrateIp.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE;
+ sBitrateIp.u4_target_bitrate = mBitrate;
+
+ sBitrateIp.u4_timestamp_high = -1;
+ sBitrateIp.u4_timestamp_low = -1;
+
+ sBitrateIp.u4_size = sizeof(ive_ctl_set_bitrate_ip_t);
+ sBitrateOp.u4_size = sizeof(ive_ctl_set_bitrate_op_t);
+
+ ive_api_function(mCodecCtx, &sBitrateIp, &sBitrateOp);
+ return;
+}
+
+void Codec::setFrameType(IV_PICTURE_CODING_TYPE_T eFrameType) {
+ ive_ctl_set_frame_type_ip_t sFrameTypeIp{};
+ ive_ctl_set_frame_type_op_t sFrameTypeOp{};
+
+ sFrameTypeIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sFrameTypeIp.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE;
+ sFrameTypeIp.e_frame_type = eFrameType;
+
+ sFrameTypeIp.u4_timestamp_high = -1;
+ sFrameTypeIp.u4_timestamp_low = -1;
+
+ sFrameTypeIp.u4_size = sizeof(ive_ctl_set_frame_type_ip_t);
+ sFrameTypeOp.u4_size = sizeof(ive_ctl_set_frame_type_op_t);
+
+ ive_api_function(mCodecCtx, &sFrameTypeIp, &sFrameTypeOp);
+ return;
+}
+
+void Codec::setQp() {
+ ive_ctl_set_qp_ip_t s_QpIp{};
+ ive_ctl_set_qp_op_t s_QpOp{};
+
+ s_QpIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ s_QpIp.e_sub_cmd = IVE_CMD_CTL_SET_QP;
+
+ s_QpIp.u4_i_qp = m_I_QP;
+ s_QpIp.u4_i_qp_max = MAX_H264_QP;
+ s_QpIp.u4_i_qp_min = kMinQP;
+
+ s_QpIp.u4_p_qp = m_P_QP;
+ s_QpIp.u4_p_qp_max = MAX_H264_QP;
+ s_QpIp.u4_p_qp_min = kMinQP;
+
+ s_QpIp.u4_b_qp = m_B_QP;
+ s_QpIp.u4_b_qp_max = MAX_H264_QP;
+ s_QpIp.u4_b_qp_min = kMinQP;
+
+ s_QpIp.u4_timestamp_high = -1;
+ s_QpIp.u4_timestamp_low = -1;
+
+ s_QpIp.u4_size = sizeof(ive_ctl_set_qp_ip_t);
+ s_QpOp.u4_size = sizeof(ive_ctl_set_qp_op_t);
+
+ ive_api_function(mCodecCtx, &s_QpIp, &s_QpOp);
+ return;
+}
+
+void Codec::setEncMode(IVE_ENC_MODE_T eEncMode) {
+ ive_ctl_set_enc_mode_ip_t sEncModeIp{};
+ ive_ctl_set_enc_mode_op_t sEncModeOp{};
+
+ sEncModeIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sEncModeIp.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE;
+ sEncModeIp.e_enc_mode = eEncMode;
+
+ sEncModeIp.u4_timestamp_high = -1;
+ sEncModeIp.u4_timestamp_low = -1;
+
+ sEncModeIp.u4_size = sizeof(ive_ctl_set_enc_mode_ip_t);
+ sEncModeOp.u4_size = sizeof(ive_ctl_set_enc_mode_op_t);
+
+ ive_api_function(mCodecCtx, &sEncModeIp, &sEncModeOp);
+ return;
+}
+
+void Codec::setVbvParams() {
+ ive_ctl_set_vbv_params_ip_t sVbvIp{};
+ ive_ctl_set_vbv_params_op_t sVbvOp{};
+
+ sVbvIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sVbvIp.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS;
+ sVbvIp.u4_vbv_buf_size = 0;
+ sVbvIp.u4_vbv_buffer_delay = 1000;
+
+ sVbvIp.u4_timestamp_high = -1;
+ sVbvIp.u4_timestamp_low = -1;
+
+ sVbvIp.u4_size = sizeof(ive_ctl_set_vbv_params_ip_t);
+ sVbvOp.u4_size = sizeof(ive_ctl_set_vbv_params_op_t);
+
+ ive_api_function(mCodecCtx, &sVbvIp, &sVbvOp);
+ return;
+}
+
+void Codec::setAirParams() {
+ ive_ctl_set_air_params_ip_t sAirIp{};
+ ive_ctl_set_air_params_op_t sAirOp{};
+
+ sAirIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sAirIp.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS;
+ sAirIp.e_air_mode = mAirMode;
+ sAirIp.u4_air_refresh_period = mIntraRefresh;
+
+ sAirIp.u4_timestamp_high = -1;
+ sAirIp.u4_timestamp_low = -1;
+
+ sAirIp.u4_size = sizeof(ive_ctl_set_air_params_ip_t);
+ sAirOp.u4_size = sizeof(ive_ctl_set_air_params_op_t);
+
+ ive_api_function(mCodecCtx, &sAirIp, &sAirOp);
+ return;
+}
+
+void Codec::setMeParams() {
+ ive_ctl_set_me_params_ip_t sMeParamsIp{};
+ ive_ctl_set_me_params_op_t sMeParamsOp{};
+
+ sMeParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sMeParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS;
+ sMeParamsIp.u4_enable_fast_sad = mEnableFastSad;
+ sMeParamsIp.u4_enable_alt_ref = mEnableAltRef;
+
+ sMeParamsIp.u4_enable_hpel = mHalfPelEnable;
+ sMeParamsIp.u4_enable_qpel = mQPelEnable;
+ sMeParamsIp.u4_me_speed_preset = mMeSpeedPreset;
+ sMeParamsIp.u4_srch_rng_x = mSearchRangeX;
+ sMeParamsIp.u4_srch_rng_y = mSearchRangeY;
+
+ sMeParamsIp.u4_timestamp_high = -1;
+ sMeParamsIp.u4_timestamp_low = -1;
+
+ sMeParamsIp.u4_size = sizeof(ive_ctl_set_me_params_ip_t);
+ sMeParamsOp.u4_size = sizeof(ive_ctl_set_me_params_op_t);
+
+ ive_api_function(mCodecCtx, &sMeParamsIp, &sMeParamsOp);
+ return;
+}
+
+void Codec::setGopParams() {
+ ive_ctl_set_gop_params_ip_t sGopParamsIp{};
+ ive_ctl_set_gop_params_op_t sGopParamsOp{};
+
+ sGopParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sGopParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS;
+
+ sGopParamsIp.u4_i_frm_interval = mIInterval;
+ sGopParamsIp.u4_idr_frm_interval = mIDRInterval;
+
+ sGopParamsIp.u4_timestamp_high = -1;
+ sGopParamsIp.u4_timestamp_low = -1;
+
+ sGopParamsIp.u4_size = sizeof(ive_ctl_set_gop_params_ip_t);
+ sGopParamsOp.u4_size = sizeof(ive_ctl_set_gop_params_op_t);
+
+ ive_api_function(mCodecCtx, &sGopParamsIp, &sGopParamsOp);
+ return;
+}
+
+void Codec::setProfileParams() {
+ ive_ctl_set_profile_params_ip_t sProfileParamsIp{};
+ ive_ctl_set_profile_params_op_t sProfileParamsOp{};
+
+ sProfileParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sProfileParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS;
+
+ sProfileParamsIp.e_profile = mProfile;
+ if (sProfileParamsIp.e_profile == IV_PROFILE_BASE) {
+ sProfileParamsIp.u4_entropy_coding_mode = 0;
+ } else {
+ sProfileParamsIp.u4_entropy_coding_mode = 1;
+ }
+ sProfileParamsIp.u4_timestamp_high = -1;
+ sProfileParamsIp.u4_timestamp_low = -1;
+
+ sProfileParamsIp.u4_size = sizeof(ive_ctl_set_profile_params_ip_t);
+ sProfileParamsOp.u4_size = sizeof(ive_ctl_set_profile_params_op_t);
+
+ ive_api_function(mCodecCtx, &sProfileParamsIp, &sProfileParamsOp);
+ return;
+}
+
+void Codec::setDeblockParams() {
+ ive_ctl_set_deblock_params_ip_t sDeblockParamsIp{};
+ ive_ctl_set_deblock_params_op_t sDeblockParamsOp{};
+
+ sDeblockParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sDeblockParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS;
+
+ sDeblockParamsIp.u4_disable_deblock_level = mDisableDeblockLevel;
+
+ sDeblockParamsIp.u4_timestamp_high = -1;
+ sDeblockParamsIp.u4_timestamp_low = -1;
+
+ sDeblockParamsIp.u4_size = sizeof(ive_ctl_set_deblock_params_ip_t);
+ sDeblockParamsOp.u4_size = sizeof(ive_ctl_set_deblock_params_op_t);
+
+ ive_api_function(mCodecCtx, &sDeblockParamsIp, &sDeblockParamsOp);
+ return;
+}
+
+void Codec::setVuiParams() {
+ ih264e_vui_ip_t sVuiParamsIp{};
+ ih264e_vui_op_t sVuiParamsOp{};
+
+ sVuiParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sVuiParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_VUI_PARAMS;
+
+ sVuiParamsIp.u1_aspect_ratio_info_present_flag = mAspectRatioFlag;
+ sVuiParamsIp.u1_aspect_ratio_idc = 0;
+ sVuiParamsIp.u2_sar_width = 0;
+ sVuiParamsIp.u2_sar_height = 0;
+ sVuiParamsIp.u1_overscan_info_present_flag = 0;
+ sVuiParamsIp.u1_overscan_appropriate_flag = 0;
+ sVuiParamsIp.u1_video_signal_type_present_flag = 1;
+ sVuiParamsIp.u1_video_format = 0;
+ sVuiParamsIp.u1_video_full_range_flag = 0;
+ sVuiParamsIp.u1_colour_description_present_flag = 1;
+ sVuiParamsIp.u1_colour_primaries = 0;
+ sVuiParamsIp.u1_transfer_characteristics = 0;
+ sVuiParamsIp.u1_matrix_coefficients = 0;
+ sVuiParamsIp.u1_chroma_loc_info_present_flag = 0;
+ sVuiParamsIp.u1_chroma_sample_loc_type_top_field = 0;
+ sVuiParamsIp.u1_chroma_sample_loc_type_bottom_field = 0;
+ sVuiParamsIp.u1_vui_timing_info_present_flag = 0;
+ sVuiParamsIp.u4_vui_num_units_in_tick = 0;
+ sVuiParamsIp.u4_vui_time_scale = 0;
+ sVuiParamsIp.u1_fixed_frame_rate_flag = 0;
+ sVuiParamsIp.u1_nal_hrd_parameters_present_flag = mNalHrdFlag;
+ sVuiParamsIp.u1_vcl_hrd_parameters_present_flag = mVclHrdFlag;
+ sVuiParamsIp.u1_low_delay_hrd_flag = 0;
+ sVuiParamsIp.u1_pic_struct_present_flag = 0;
+ sVuiParamsIp.u1_bitstream_restriction_flag = 0;
+ sVuiParamsIp.u1_motion_vectors_over_pic_boundaries_flag = 0;
+ sVuiParamsIp.u1_max_bytes_per_pic_denom = 0;
+ sVuiParamsIp.u1_max_bits_per_mb_denom = 0;
+ sVuiParamsIp.u1_log2_max_mv_length_horizontal = 0;
+ sVuiParamsIp.u1_log2_max_mv_length_vertical = 0;
+ sVuiParamsIp.u1_num_reorder_frames = 0;
+ sVuiParamsIp.u1_max_dec_frame_buffering = 0;
+
+ sVuiParamsIp.u4_size = sizeof(ih264e_vui_ip_t);
+ sVuiParamsOp.u4_size = sizeof(ih264e_vui_op_t);
+
+ ive_api_function(mCodecCtx, &sVuiParamsIp, &sVuiParamsOp);
+ return;
+}
+
+void Codec::setSeiMdcvParams() {
+ ih264e_ctl_set_sei_mdcv_params_ip_t sSeiMdcvParamsIp{};
+ ih264e_ctl_set_sei_mdcv_params_op_t sSeiMdcvParamsOp{};
+
+ sSeiMdcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sSeiMdcvParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_MDCV_PARAMS;
+ sSeiMdcvParamsIp.u1_sei_mdcv_params_present_flag = mSeiMdcvFlag;
+ if (mSeiMdcvFlag) {
+ for (int i4_count = 0; i4_count < NUM_SEI_MDCV_PRIMARIES; ++i4_count) {
+ sSeiMdcvParamsIp.au2_display_primaries_x[i4_count] = 30000;
+ sSeiMdcvParamsIp.au2_display_primaries_y[i4_count] = 35000;
+ }
+ sSeiMdcvParamsIp.u2_white_point_x = 30000;
+ sSeiMdcvParamsIp.u2_white_point_y = 35000;
+ sSeiMdcvParamsIp.u4_max_display_mastering_luminance = 100000000;
+ sSeiMdcvParamsIp.u4_min_display_mastering_luminance = 50000;
+ }
+
+ sSeiMdcvParamsIp.u4_timestamp_high = -1;
+ sSeiMdcvParamsIp.u4_timestamp_low = -1;
+
+ sSeiMdcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_ip_t);
+ sSeiMdcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_mdcv_params_op_t);
+ ih264e_api_function(mCodecCtx, &sSeiMdcvParamsIp, &sSeiMdcvParamsOp);
+ return;
+}
+
+void Codec::setSeiCllParams() {
+ ih264e_ctl_set_sei_cll_params_ip_t sSeiCllParamsIp{};
+ ih264e_ctl_set_sei_cll_params_op_t sSeiCllParamsOp{};
+
+ sSeiCllParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sSeiCllParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_CLL_PARAMS;
+ sSeiCllParamsIp.u1_sei_cll_params_present_flag = mSeiCllFlag;
+ if (mSeiCllFlag) {
+ sSeiCllParamsIp.u2_max_content_light_level = 0;
+ sSeiCllParamsIp.u2_max_pic_average_light_level = 0;
+ }
+
+ sSeiCllParamsIp.u4_timestamp_high = -1;
+ sSeiCllParamsIp.u4_timestamp_low = -1;
+
+ sSeiCllParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_ip_t);
+ sSeiCllParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_cll_params_op_t);
+
+ ih264e_api_function(mCodecCtx, &sSeiCllParamsIp, &sSeiCllParamsOp);
+ return;
+}
+
+void Codec::setSeiAveParams() {
+ ih264e_ctl_set_sei_ave_params_ip_t sSeiAveParamsIp{};
+ ih264e_ctl_set_sei_ave_params_op_t sSeiAveParamsOp{};
+
+ sSeiAveParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sSeiAveParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_AVE_PARAMS;
+ sSeiAveParamsIp.u1_sei_ave_params_present_flag = mSeiAveFlag;
+ if (mSeiAveFlag) {
+ sSeiAveParamsIp.u4_ambient_illuminance = 1;
+ sSeiAveParamsIp.u2_ambient_light_x = 0;
+ sSeiAveParamsIp.u2_ambient_light_y = 0;
+ }
+
+ sSeiAveParamsIp.u4_timestamp_high = -1;
+ sSeiAveParamsIp.u4_timestamp_low = -1;
+
+ sSeiAveParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_ip_t);
+ sSeiAveParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ave_params_op_t);
+
+ ih264e_api_function(mCodecCtx, &sSeiAveParamsIp, &sSeiAveParamsOp);
+ return;
+}
+
+void Codec::setSeiCcvParams() {
+ ih264e_ctl_set_sei_ccv_params_ip_t sSeiCcvParamsIp{};
+ ih264e_ctl_set_sei_ccv_params_op_t sSeiCcvParamsOp{};
+
+ sSeiCcvParamsIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sSeiCcvParamsIp.e_sub_cmd = IVE_CMD_CTL_SET_SEI_CCV_PARAMS;
+ sSeiCcvParamsIp.u1_sei_ccv_params_present_flag = mSeiCcvFlag;
+ if (mSeiCcvFlag) {
+ sSeiCcvParamsIp.u1_ccv_cancel_flag = 0;
+ sSeiCcvParamsIp.u1_ccv_persistence_flag = 1;
+ sSeiCcvParamsIp.u1_ccv_primaries_present_flag = 1;
+ sSeiCcvParamsIp.u1_ccv_min_luminance_value_present_flag = 1;
+ sSeiCcvParamsIp.u1_ccv_max_luminance_value_present_flag = 1;
+ sSeiCcvParamsIp.u1_ccv_avg_luminance_value_present_flag = 1;
+ sSeiCcvParamsIp.u1_ccv_reserved_zero_2bits = 0;
+ for (int i4_count = 0; i4_count < NUM_SEI_CCV_PRIMARIES; ++i4_count) {
+ sSeiCcvParamsIp.ai4_ccv_primaries_x[i4_count] = 1;
+ sSeiCcvParamsIp.ai4_ccv_primaries_y[i4_count] = 1;
+ }
+ sSeiCcvParamsIp.u4_ccv_min_luminance_value = 1;
+ sSeiCcvParamsIp.u4_ccv_max_luminance_value = 1;
+ sSeiCcvParamsIp.u4_ccv_avg_luminance_value = 1;
+ }
+
+ sSeiCcvParamsIp.u4_timestamp_high = -1;
+ sSeiCcvParamsIp.u4_timestamp_low = -1;
+
+ sSeiCcvParamsIp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_ip_t);
+ sSeiCcvParamsOp.u4_size = sizeof(ih264e_ctl_set_sei_ccv_params_op_t);
+
+ ih264e_api_function(mCodecCtx, &sSeiCcvParamsIp, &sSeiCcvParamsOp);
+ return;
+}
+
+void Codec::logVersion() {
+ ive_ctl_getversioninfo_ip_t sCtlIp{};
+ ive_ctl_getversioninfo_op_t sCtlOp{};
+ UWORD8 au1Buf[512];
+
+ sCtlIp.e_cmd = IVE_CMD_VIDEO_CTL;
+ sCtlIp.e_sub_cmd = IVE_CMD_CTL_GETVERSION;
+
+ sCtlIp.u4_size = sizeof(ive_ctl_getversioninfo_ip_t);
+ sCtlOp.u4_size = sizeof(ive_ctl_getversioninfo_op_t);
+ sCtlIp.pu1_version = au1Buf;
+ sCtlIp.u4_version_bufsize = sizeof(au1Buf);
+
+ ive_api_function(mCodecCtx, (void *)&sCtlIp, (void *)&sCtlOp);
+ return;
+}
+
+void Codec::encodeFrames(const uint8_t *data, size_t size) {
+ size_t frameSize = (mIvVideoColorFormat == IV_YUV_422ILE) ? (mWidth * mHeight * 2)
+ : ((mWidth * mHeight * 3) / 2);
+ ive_video_encode_ip_t sEncodeIp{};
+ ive_video_encode_op_t sEncodeOp{};
+ uint8_t header[kHeaderLength];
+ iv_raw_buf_t *psInpRawBuf = &sEncodeIp.s_inp_buf;
+ sEncodeIp.s_out_buf.pv_buf = header;
+ sEncodeIp.s_out_buf.u4_bytes = 0;
+ sEncodeIp.s_out_buf.u4_bufsize = kHeaderLength;
+ sEncodeIp.u4_size = sizeof(ive_video_encode_ip_t);
+ sEncodeOp.u4_size = sizeof(ive_video_encode_op_t);
+
+ sEncodeIp.e_cmd = IVE_CMD_VIDEO_ENCODE;
+ sEncodeIp.pv_bufs = nullptr;
+ sEncodeIp.pv_mb_info = nullptr;
+ sEncodeIp.pv_pic_info = nullptr;
+ sEncodeIp.u4_mb_info_type = 0;
+ sEncodeIp.u4_pic_info_type = 0;
+ sEncodeIp.u4_is_last = 0;
+ sEncodeOp.s_out_buf.pv_buf = nullptr;
+
+ /* Initialize color formats */
+ memset(psInpRawBuf, 0, sizeof(iv_raw_buf_t));
+ psInpRawBuf->u4_size = sizeof(iv_raw_buf_t);
+ psInpRawBuf->e_color_fmt = mIvVideoColorFormat;
+
+ ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp);
+ size_t numFrame = 0;
+ while (size > 0) {
+ uint8_t *tmpData = (uint8_t *)malloc(frameSize);
+ size_t bytesConsumed = std::min(size, frameSize);
+ if (bytesConsumed < frameSize) {
+ memset(&tmpData[bytesConsumed], data[0], frameSize - bytesConsumed);
+ }
+ memcpy(tmpData, data, bytesConsumed);
+ setEncParams(psInpRawBuf, tmpData);
+ uint64_t OutputBufferSize = (frameSize / kCompressionRatio);
+ uint8_t *OutputBuffer = (uint8_t *)malloc(OutputBufferSize);
+ sEncodeIp.s_out_buf.pv_buf = OutputBuffer;
+ sEncodeIp.s_out_buf.u4_bufsize = OutputBufferSize;
+ if (mIsForceIdrEnabled) {
+ if (numFrame == mForceIdrInterval) {
+ setFrameType(IV_IDR_FRAME);
+ }
+ }
+ if (mIsDynamicBitRateChangeEnabled) {
+ if (numFrame == mDynamicBitRateInterval) {
+ if (data[0] & 0x01) {
+ mBitrate *= 2;
+ } else {
+ mBitrate /= 2;
+ }
+ setBitRate();
+ }
+ }
+ if (mIsDynamicFrameRateChangeEnabled) {
+ if (numFrame == mDynamicFrameRateInterval) {
+ if (size > 1 && data[1] & 0x01) {
+ mFrameRate *= 2;
+ } else {
+ mFrameRate /= 2;
+ }
+ setFrameRate();
+ }
+ }
+ ive_api_function(mCodecCtx, &sEncodeIp, &sEncodeOp);
+ ++numFrame;
+ data += bytesConsumed;
+ size -= bytesConsumed;
+ free(tmpData);
+ free(OutputBuffer);
+ }
+}
+
+void Codec::setEncParams(iv_raw_buf_t *psInpRawBuf, const uint8_t *data) {
+ switch (mIvVideoColorFormat) {
+ case IV_YUV_420SP_UV:
+ [[fallthrough]];
+ case IV_YUV_420SP_VU: {
+ uint8_t *yPlane = const_cast<uint8_t *>(data);
+ uint8_t *uPlane = const_cast<uint8_t *>(data + (mWidth * mHeight));
+ int32_t yStride = mWidth;
+ int32_t uStride = mWidth / 2;
+ psInpRawBuf->apv_bufs[0] = yPlane;
+ psInpRawBuf->apv_bufs[1] = uPlane;
+
+ psInpRawBuf->au4_wd[0] = mWidth;
+ psInpRawBuf->au4_wd[1] = mWidth;
+
+ psInpRawBuf->au4_ht[0] = mHeight;
+ psInpRawBuf->au4_ht[1] = mHeight / 2;
+
+ psInpRawBuf->au4_strd[0] = yStride;
+ psInpRawBuf->au4_strd[1] = uStride;
+ break;
+ }
+ case IV_YUV_422ILE: {
+ uint8_t *yPlane = const_cast<uint8_t *>(data);
+ psInpRawBuf->apv_bufs[0] = yPlane;
+
+ psInpRawBuf->au4_wd[0] = mWidth * 2;
+
+ psInpRawBuf->au4_ht[0] = mHeight;
+
+ psInpRawBuf->au4_strd[0] = mWidth * 2;
+ break;
+ }
+ case IV_YUV_420P:
+ [[fallthrough]];
+ default: {
+ uint8_t *yPlane = const_cast<uint8_t *>(data);
+ uint8_t *uPlane = const_cast<uint8_t *>(data + (mWidth * mHeight));
+ uint8_t *vPlane = const_cast<uint8_t *>(data + ((mWidth * mHeight) * 5) / 4);
+ int32_t yStride = mWidth;
+ int32_t uStride = mWidth / 2;
+ int32_t vStride = mWidth / 2;
+
+ psInpRawBuf->apv_bufs[0] = yPlane;
+ psInpRawBuf->apv_bufs[1] = uPlane;
+ psInpRawBuf->apv_bufs[2] = vPlane;
+
+ psInpRawBuf->au4_wd[0] = mWidth;
+ psInpRawBuf->au4_wd[1] = mWidth / 2;
+ psInpRawBuf->au4_wd[2] = mWidth / 2;
+
+ psInpRawBuf->au4_ht[0] = mHeight;
+ psInpRawBuf->au4_ht[1] = mHeight / 2;
+ psInpRawBuf->au4_ht[2] = mHeight / 2;
+
+ psInpRawBuf->au4_strd[0] = yStride;
+ psInpRawBuf->au4_strd[1] = uStride;
+ psInpRawBuf->au4_strd[2] = vStride;
+ break;
+ }
+ }
+ return;
+}
+
+void Codec::deInitEncoder() {
+ iv_mem_rec_t *ps_mem_rec = mMemRecords;
+ for (size_t i = 0; i < mNumMemRecords; ++i) {
+ if (ps_mem_rec) {
+ free(ps_mem_rec->pv_base);
+ }
+ ++ps_mem_rec;
+ }
+ if (mMemRecords) {
+ free(mMemRecords);
+ }
+ mCodecCtx = nullptr;
+ return;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ if (size < IDX_LAST) {
+ return 0;
+ }
+ Codec *codec = new Codec();
+ if (codec->initEncoder(&data, &size)) {
+ codec->encodeFrames(data, size);
+ }
+ delete codec;
+ return 0;
+}
diff --git a/libavc_blacklist.txt b/libavc_blocklist.txt
similarity index 100%
rename from libavc_blacklist.txt
rename to libavc_blocklist.txt
diff --git a/test/encoder/psnr.c b/test/encoder/psnr.c
index d5a953c..87a03b0 100644
--- a/test/encoder/psnr.c
+++ b/test/encoder/psnr.c
@@ -111,13 +111,13 @@
pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[comp];
wd = ps_buf1->au4_wd[comp];
ht = ps_buf1->au4_ht[comp];
- strd1 = ps_buf1->au4_strd[comp];
- strd2 = ps_buf2->au4_strd[comp];
+ strd1 = ps_buf1->au4_strd[comp] - ps_buf1->au4_wd[comp];
+ strd2 = ps_buf2->au4_strd[comp] - ps_buf2->au4_wd[comp];
incr1 = 1;
incr2 = 1;
if((IV_YUV_420SP_UV == ps_buf1->e_color_fmt)
- || (IV_YUV_420SP_UV == ps_buf1->e_color_fmt))
+ || (IV_YUV_420SP_VU == ps_buf1->e_color_fmt))
{
switch(comp)
{
@@ -130,6 +130,8 @@
else
pu1_buf1 = (UWORD8 *)ps_buf1->apv_bufs[1] + 1;
incr1 = 2;
+ wd = ps_buf1->au4_wd[0] >> 1;
+ ht = ps_buf1->au4_ht[0] >> 1;
break;
case 2:
if(IV_YUV_420SP_UV == ps_buf1->e_color_fmt)
@@ -137,11 +139,14 @@
else
pu1_buf1 = ps_buf1->apv_bufs[1];
incr1 = 2;
+ wd = ps_buf1->au4_wd[0] >> 1;
+ ht = ps_buf1->au4_ht[0] >> 1;
+ strd1 = ps_buf1->au4_strd[1] - ps_buf1->au4_wd[1];
break;
}
}
if ((IV_YUV_420SP_UV == ps_buf2->e_color_fmt)
- || (IV_YUV_420SP_UV == ps_buf2->e_color_fmt))
+ || (IV_YUV_420SP_VU == ps_buf2->e_color_fmt))
{
switch(comp)
{
@@ -153,14 +158,21 @@
pu1_buf2 = ps_buf2->apv_bufs[1];
else
pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[1] + 1;
- incr1 = 2;
+ incr2 = 2;
+ wd = ps_buf2->au4_wd[0] >> 1;
+ ht = ps_buf2->au4_ht[0] >> 1;
+
break;
case 2:
if(IV_YUV_420SP_UV == ps_buf2->e_color_fmt)
pu1_buf2 = (UWORD8 *)ps_buf2->apv_bufs[1] + 1;
else
pu1_buf2 = ps_buf2->apv_bufs[1];
- incr1 = 2;
+ incr2 = 2;
+ wd = ps_buf2->au4_wd[0] >> 1;
+ ht = ps_buf2->au4_ht[0] >> 1;
+ strd2 = ps_buf2->au4_strd[1] - ps_buf2->au4_wd[1];
+
break;
}
}
@@ -175,8 +187,8 @@
pu1_buf2 += incr2;
df_psnr[comp] += diff * diff;
}
- pu1_buf1 += strd1 - ps_buf1->au4_wd[comp];
- pu1_buf2 += strd2 - ps_buf2->au4_wd[comp];
+ pu1_buf1 += strd1;
+ pu1_buf2 += strd2;
}
df_psnr[comp] /= (wd * ht);
if(df_psnr[comp])