Merge "Fix integer overflows while intializing reference lists"

This commit is contained in:
Treehugger Robot 2019-09-28 17:18:51 +00:00 committed by Gerrit Code Review
commit 47d5e6bb93
2 changed files with 111 additions and 87 deletions

View file

@ -1193,6 +1193,23 @@ void ih264d_convert_frm_mbaff_list(dec_struct_t *ps_dec)
} }
} }
} }
static int poc_compare(const void *pv_pic1, const void *pv_pic2)
{
struct pic_buffer_t *ps_pic1 = *(struct pic_buffer_t **) pv_pic1;
struct pic_buffer_t *ps_pic2 = *(struct pic_buffer_t **) pv_pic2;
if (ps_pic1->i4_poc < ps_pic2->i4_poc)
{
return -1;
}
else if (ps_pic1->i4_poc > ps_pic2->i4_poc)
{
return 1;
}
else
{
return 0;
}
}
/*! /*!
************************************************************************** **************************************************************************
* \if Function name : ih264d_init_ref_idx_lx_b \endif * \if Function name : ih264d_init_ref_idx_lx_b \endif
@ -1211,15 +1228,16 @@ void ih264d_init_ref_idx_lx_b(dec_struct_t *ps_dec)
dpb_manager_t *ps_dpb_mgr; dpb_manager_t *ps_dpb_mgr;
struct dpb_info_t *ps_next_dpb; struct dpb_info_t *ps_next_dpb;
WORD32 i_cur_poc, i_max_st_poc, i_min_st_poc, i_ref_poc, i_temp_poc; WORD32 i_cur_poc, i_max_st_poc, i_min_st_poc, i_ref_poc, i_temp_poc;
WORD8 i; WORD8 i, j;
UWORD8 u1_max_lt_index, u1_min_lt_index; UWORD8 u1_max_lt_index, u1_min_lt_index;
UWORD32 u4_lt_index; UWORD32 u4_lt_index;
WORD32 i_cur_idx;
UWORD8 u1_field_pic_flag; UWORD8 u1_field_pic_flag;
dec_slice_params_t *ps_cur_slice; dec_slice_params_t *ps_cur_slice;
UWORD8 u1_L0, u1_L1; UWORD8 u1_L0, u1_L1;
UWORD8 u1_num_short_term_bufs; UWORD8 u1_num_short_term_bufs;
UWORD8 u1_max_ref_idx_l0, u1_max_ref_idx_l1; UWORD8 u1_max_ref_idx_l0, u1_max_ref_idx_l1;
struct pic_buffer_t *aps_st_pic_bufs[2 * MAX_REF_BUFS] = {NULL};
ps_cur_slice = ps_dec->ps_cur_slice; ps_cur_slice = ps_dec->ps_cur_slice;
u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag; u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag;
u1_max_ref_idx_l0 = ps_cur_slice->u1_num_ref_idx_lx_active[0] u1_max_ref_idx_l0 = ps_cur_slice->u1_num_ref_idx_lx_active[0]
@ -1256,6 +1274,16 @@ void ih264d_init_ref_idx_lx_b(dec_struct_t *ps_dec)
ps_next_dpb = ps_next_dpb->ps_prev_short; ps_next_dpb = ps_next_dpb->ps_prev_short;
} }
/* Sort ST ref pocs in ascending order */
ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
for (j = 0; j < ps_dpb_mgr->u1_num_st_ref_bufs; j++)
{
aps_st_pic_bufs[j] = ps_next_dpb->ps_pic_buf;
ps_next_dpb = ps_next_dpb->ps_prev_short;
}
qsort(aps_st_pic_bufs, ps_dpb_mgr->u1_num_st_ref_bufs,
sizeof(aps_st_pic_bufs[0]), poc_compare);
/* Start from LT head */ /* Start from LT head */
ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
if(ps_next_dpb) if(ps_next_dpb)
@ -1275,58 +1303,57 @@ void ih264d_init_ref_idx_lx_b(dec_struct_t *ps_dec)
/* 1. Initialize refIdxL0 */ /* 1. Initialize refIdxL0 */
u1_L0 = 0; u1_L0 = 0;
i_temp_poc = i_cur_poc;
if(u1_field_pic_flag) if(u1_field_pic_flag)
{ {
ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0]; ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0];
ps_ref_pic_buf_lx += MAX_REF_BUFS; ps_ref_pic_buf_lx += MAX_REF_BUFS;
i_temp_poc = i_cur_poc;
} }
else else
{ {
ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0]; ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0];
i_temp_poc = i_cur_poc - 1; /* Avoid integer overflow while decrementing by one */
if (i_temp_poc > INT32_MIN)
i_temp_poc--;
}
i_cur_idx = -1;
for(j = 0; j < ps_dpb_mgr->u1_num_st_ref_bufs; j++)
{
if (NULL == aps_st_pic_bufs[j])
{
break;
}
if (aps_st_pic_bufs[j]->i4_poc <= i_temp_poc)
{
i_cur_idx = j;
}
} }
/* Arrange all short term buffers in output order as given by POC */ /* Arrange all short term buffers in output order as given by POC */
/* 1.1 Arrange POC's less than CurrPOC in the descending POC order starting /* 1.1 Arrange POC's less than CurrPOC in the descending POC order starting
from (CurrPOC - 1)*/ from (CurrPOC - 1)*/
for(; i_temp_poc >= i_min_st_poc; i_temp_poc--) for(j = i_cur_idx; j >= 0; j--)
{ {
/* Start from ST head */ if(aps_st_pic_bufs[j])
ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
{ {
if((WORD32)ps_next_dpb->ps_pic_buf->i4_poc == i_temp_poc) /* Copy info in pic buffer */
{ ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx,
/* Copy info in pic buffer */ aps_st_pic_bufs[j]);
ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, ps_ref_pic_buf_lx++;
ps_next_dpb->ps_pic_buf); u1_L0++;
ps_ref_pic_buf_lx++;
u1_L0++;
break;
}
ps_next_dpb = ps_next_dpb->ps_prev_short;
} }
} }
/* 1.2. Arrange POC's more than CurrPOC in the ascending POC order starting
from (CurrPOC + 1)*/
for(j = i_cur_idx + 1; j < ps_dpb_mgr->u1_num_st_ref_bufs; j++)
{ {
/* 1.2. Arrange POC's more than CurrPOC in the ascending POC order starting if(aps_st_pic_bufs[j])
from (CurrPOC + 1)*/
for(i_temp_poc = i_cur_poc + 1; i_temp_poc <= i_max_st_poc; i_temp_poc++)
{ {
/* Start from ST head */ ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx,
ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head; aps_st_pic_bufs[j]);
for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++) ps_ref_pic_buf_lx++;
{ u1_L0++;
if((WORD32)ps_next_dpb->ps_pic_buf->i4_poc == i_temp_poc)
{
ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx,
ps_next_dpb->ps_pic_buf);
ps_ref_pic_buf_lx++;
u1_L0++;
break;
}
ps_next_dpb = ps_next_dpb->ps_prev_short;
}
} }
} }
@ -1415,51 +1442,29 @@ void ih264d_init_ref_idx_lx_b(dec_struct_t *ps_dec)
/* 2.1. Arrange POC's more than CurrPOC in the ascending POC order starting /* 2.1. Arrange POC's more than CurrPOC in the ascending POC order starting
from (CurrPOC + 1)*/ from (CurrPOC + 1)*/
for(i_temp_poc = i_cur_poc + 1; i_temp_poc <= i_max_st_poc; i_temp_poc++) for(j = i_cur_idx + 1; j < ps_dpb_mgr->u1_num_st_ref_bufs; j++)
{ {
/* Start from ST head */ if(aps_st_pic_bufs[j])
ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
{ {
if((WORD32)ps_next_dpb->ps_pic_buf->i4_poc == i_temp_poc) /* Start from ST head */
{ ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx,
ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, aps_st_pic_bufs[j]);
ps_next_dpb->ps_pic_buf); ps_ref_pic_buf_lx++;
ps_ref_pic_buf_lx++; u1_L1++;
u1_L1++;
break;
}
ps_next_dpb = ps_next_dpb->ps_prev_short;
} }
} }
if(u1_field_pic_flag)
{
i_temp_poc = i_cur_poc;
}
else
{
i_temp_poc = i_cur_poc - 1;
}
/* Arrange all short term buffers in output order as given by POC */ /* Arrange all short term buffers in output order as given by POC */
/* 2.2 Arrange POC's less than CurrPOC in the descending POC order starting /* 2.2 Arrange POC's less than CurrPOC in the descending POC order starting
from (CurrPOC - 1)*/ from (CurrPOC - 1)*/
for(; i_temp_poc >= i_min_st_poc; i_temp_poc--) for(j = i_cur_idx; j >= 0; j--)
{ {
/* Start from ST head */ if(aps_st_pic_bufs[j])
ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
{ {
if((WORD32)ps_next_dpb->ps_pic_buf->i4_poc == i_temp_poc) ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx,
{ aps_st_pic_bufs[j]);
ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, ps_ref_pic_buf_lx++;
ps_next_dpb->ps_pic_buf); u1_L1++;
ps_ref_pic_buf_lx++;
u1_L1++;
break;
}
ps_next_dpb = ps_next_dpb->ps_prev_short;
} }
} }

View file

@ -940,7 +940,23 @@ WORD32 ih264d_parse_pred_weight_table(dec_slice_params_t * ps_cur_slice,
return OK; return OK;
} }
static int pic_num_compare(const void *pv_pic1, const void *pv_pic2)
{
struct pic_buffer_t *ps_pic1 = *(struct pic_buffer_t **) pv_pic1;
struct pic_buffer_t *ps_pic2 = *(struct pic_buffer_t **) pv_pic2;
if (ps_pic1->i4_pic_num < ps_pic2->i4_pic_num)
{
return -1;
}
else if (ps_pic1->i4_pic_num > ps_pic2->i4_pic_num)
{
return 1;
}
else
{
return 0;
}
}
/*****************************************************************************/ /*****************************************************************************/
/* */ /* */
/* Function Name : ih264d_init_ref_idx_lx_p */ /* Function Name : ih264d_init_ref_idx_lx_p */
@ -970,7 +986,7 @@ void ih264d_init_ref_idx_lx_p(dec_struct_t *ps_dec)
struct pic_buffer_t *ps_ref_pic_buf_lx; struct pic_buffer_t *ps_ref_pic_buf_lx;
dpb_manager_t *ps_dpb_mgr; dpb_manager_t *ps_dpb_mgr;
struct dpb_info_t *ps_next_dpb; struct dpb_info_t *ps_next_dpb;
WORD8 i; WORD8 i, j;
UWORD8 u1_max_lt_index, u1_min_lt_index; UWORD8 u1_max_lt_index, u1_min_lt_index;
UWORD32 u4_lt_index; UWORD32 u4_lt_index;
UWORD8 u1_field_pic_flag; UWORD8 u1_field_pic_flag;
@ -980,6 +996,7 @@ void ih264d_init_ref_idx_lx_p(dec_struct_t *ps_dec)
WORD32 i4_temp_pic_num, i4_ref_pic_num; WORD32 i4_temp_pic_num, i4_ref_pic_num;
UWORD8 u1_num_short_term_bufs; UWORD8 u1_num_short_term_bufs;
UWORD8 u1_max_ref_idx_l0; UWORD8 u1_max_ref_idx_l0;
struct pic_buffer_t *aps_st_pic_bufs[2 * MAX_REF_BUFS] = {NULL};
ps_cur_slice = ps_dec->ps_cur_slice; ps_cur_slice = ps_dec->ps_cur_slice;
u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag; u1_field_pic_flag = ps_cur_slice->u1_field_pic_flag;
@ -1010,6 +1027,16 @@ void ih264d_init_ref_idx_lx_p(dec_struct_t *ps_dec)
ps_next_dpb = ps_next_dpb->ps_prev_short; ps_next_dpb = ps_next_dpb->ps_prev_short;
} }
/* Sort ST ref pocs in ascending order */
ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
for (j = 0; j < ps_dpb_mgr->u1_num_st_ref_bufs; j++)
{
aps_st_pic_bufs[j] = ps_next_dpb->ps_pic_buf;
ps_next_dpb = ps_next_dpb->ps_prev_short;
}
qsort(aps_st_pic_bufs, ps_dpb_mgr->u1_num_st_ref_bufs,
sizeof(aps_st_pic_bufs[0]), pic_num_compare);
/* Start from LT head */ /* Start from LT head */
ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head; ps_next_dpb = ps_dpb_mgr->ps_dpb_ht_head;
if(ps_next_dpb) if(ps_next_dpb)
@ -1040,26 +1067,18 @@ void ih264d_init_ref_idx_lx_p(dec_struct_t *ps_dec)
ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0]; ps_ref_pic_buf_lx = ps_dpb_mgr->ps_init_dpb[0][0];
i4_temp_pic_num = i4_cur_pic_num; i4_temp_pic_num = i4_cur_pic_num;
} }
/* Arrange all short term buffers in output order as given by pic_num */ /* Arrange all short term buffers in output order as given by pic_num */
/* Arrange pic_num's less than Curr pic_num in the descending pic_num */ /* Arrange pic_num's less than Curr pic_num in the descending pic_num */
/* order starting from (Curr pic_num - 1) */ /* order starting from (Curr pic_num - 1) */
for(; i4_temp_pic_num >= i4_min_st_pic_num; i4_temp_pic_num--) for(j = ps_dpb_mgr->u1_num_st_ref_bufs - 1; j >= 0; j--)
{ {
/* Start from ST head */ if(aps_st_pic_bufs[j])
ps_next_dpb = ps_dpb_mgr->ps_dpb_st_head;
for(i = 0; i < ps_dpb_mgr->u1_num_st_ref_bufs; i++)
{ {
if((WORD32)ps_next_dpb->ps_pic_buf->i4_pic_num == i4_temp_pic_num) /* Copy info in pic buffer */
{ ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx,
/* Copy info in pic buffer */ aps_st_pic_bufs[j]);
ih264d_insert_pic_in_ref_pic_listx(ps_ref_pic_buf_lx, ps_ref_pic_buf_lx++;
ps_next_dpb->ps_pic_buf); u1_L0++;
ps_ref_pic_buf_lx++;
u1_L0++;
break;
}
ps_next_dpb = ps_next_dpb->ps_prev_short;
} }
} }