Add OWNERS in external/libmpeg2 am: a0f640e21e
am: 6cde010fe6
Change-Id: Ib51e447e021edbcf80d7bcbdcead508673e4eb47
diff --git a/decoder/impeg2d_api_main.c b/decoder/impeg2d_api_main.c
index a792f06..c0813c4 100644
--- a/decoder/impeg2d_api_main.c
+++ b/decoder/impeg2d_api_main.c
@@ -3136,7 +3136,8 @@
bytes_remaining -= ps_dec_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed;
}
- if((1 != ps_dec_state->u2_decode_header) && ((bytes_remaining > 0) || ps_dec_state->u1_flushfrm))
+ if((1 != ps_dec_state->u2_decode_header) &&
+ (((bytes_remaining > 0) && (1 == ps_dec_state->u2_header_done)) || ps_dec_state->u1_flushfrm))
{
if(ps_dec_state->u1_flushfrm)
{
diff --git a/decoder/impeg2d_dec_hdr.c b/decoder/impeg2d_dec_hdr.c
index 459eaaa..19de4c8 100644
--- a/decoder/impeg2d_dec_hdr.c
+++ b/decoder/impeg2d_dec_hdr.c
@@ -153,6 +153,12 @@
u2_width = impeg2d_bit_stream_get(ps_stream,12);
u2_height = impeg2d_bit_stream_get(ps_stream,12);
+ if (0 == u2_width || 0 == u2_height)
+ {
+ IMPEG2D_ERROR_CODES_T e_error = IMPEG2D_FRM_HDR_DECODE_ERR;
+ return e_error;
+ }
+
if ((u2_width != ps_dec->u2_horizontal_size)
|| (u2_height != ps_dec->u2_vertical_size))
{
@@ -190,7 +196,9 @@
|| (ps_dec->u2_vertical_size > ps_dec->u2_create_max_height))
{
IMPEG2D_ERROR_CODES_T e_error = IMPEG2D_UNSUPPORTED_DIMENSIONS;
- return SET_IVD_FATAL_ERROR(e_error);
+ ps_dec->u2_reinit_max_height = ps_dec->u2_vertical_size;
+ ps_dec->u2_reinit_max_width = ps_dec->u2_horizontal_size;
+ return e_error;
}
@@ -709,11 +717,12 @@
* Arguments :
* dec : Decoder context
*
-* Values Returned : None
+* Values Returned : Error
*******************************************************************************/
-void impeg2d_dec_pic_coding_ext(dec_state_t *ps_dec)
+IMPEG2D_ERROR_CODES_T impeg2d_dec_pic_coding_ext(dec_state_t *ps_dec)
{
stream_t *ps_stream;
+ IMPEG2D_ERROR_CODES_T e_error = (IMPEG2D_ERROR_CODES_T) IV_SUCCESS;
ps_stream = &ps_dec->s_bit_stream;
impeg2d_bit_stream_flush(ps_stream,START_CODE_LEN);
@@ -726,6 +735,11 @@
ps_dec->au2_f_code[1][1] = impeg2d_bit_stream_get(ps_stream,4);
ps_dec->u2_intra_dc_precision = impeg2d_bit_stream_get(ps_stream,2);
ps_dec->u2_picture_structure = impeg2d_bit_stream_get(ps_stream,2);
+ if (ps_dec->u2_picture_structure < TOP_FIELD ||
+ ps_dec->u2_picture_structure > FRAME_PICTURE)
+ {
+ return IMPEG2D_FRM_HDR_DECODE_ERR;
+ }
ps_dec->u2_top_field_first = impeg2d_bit_stream_get_bit(ps_stream);
ps_dec->u2_frame_pred_frame_dct = impeg2d_bit_stream_get_bit(ps_stream);
ps_dec->u2_concealment_motion_vectors = impeg2d_bit_stream_get_bit(ps_stream);
@@ -753,6 +767,7 @@
{
ps_dec->pu1_inv_scan_matrix = (UWORD8 *)gau1_impeg2_inv_scan_zig_zag;
}
+ return e_error;
}
/*******************************************************************************
@@ -803,6 +818,12 @@
{
ps_dec->u2_mb_y = u4_slice_vertical_position;
ps_dec->u2_mb_x = 0;
+
+ /* Update the number of MBs left, since we have probably missed a slice
+ * (that's why we see a mismatch between u2_mb_y and current position).
+ */
+ ps_dec->u2_num_mbs_left = (ps_dec->u2_num_vert_mb - ps_dec->u2_mb_y)
+ * ps_dec->u2_num_horiz_mb;
}
ps_dec->u2_first_mb = 1;
@@ -1716,7 +1737,11 @@
{
return e_error;
}
- impeg2d_dec_pic_coding_ext(ps_dec);
+ e_error = impeg2d_dec_pic_coding_ext(ps_dec);
+ if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
+ {
+ return e_error;
+ }
e_error = impeg2d_dec_pic_ext_data(ps_dec);
if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
{
@@ -1736,6 +1761,15 @@
if(u4_start_code_found == 0)
{
impeg2d_next_start_code(ps_dec);
+ /* In case a dec_pic_data call has not been made, the number of
+ * bytes consumed in the previous header decode has to be
+ * consumed. Not consuming it will result in zero bytes consumed
+ * loops in case there are multiple headers and the second
+ * or a future header has a resolution change/other error where
+ * the bytes of the last header are not consumed.
+ */
+ ps_dec->i4_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
+ ps_dec->i4_bytes_consumed -= ((size_t)ps_dec->s_bit_stream.pv_bs_buf & 3);
}
}
if((u4_start_code_found == 0) && (ps_dec->s_bit_stream.u4_offset > ps_dec->s_bit_stream.u4_max_offset))
@@ -1802,7 +1836,18 @@
FLUSH_BITS(ps_dec->s_bit_stream.u4_offset, ps_dec->s_bit_stream.u4_buf, ps_dec->s_bit_stream.u4_buf_nxt, 8, ps_dec->s_bit_stream.pu4_buf_aligned);
}
impeg2d_next_start_code(ps_dec);
-
+ if (0 == u4_start_code_found)
+ {
+ /* In case a dec_pic_data call has not been made, the number of
+ * bytes consumed in the previous header decode has to be
+ * consumed. Not consuming it will result in zero bytes consumed
+ * loops in case there are multiple headers and the second
+ * or a future header has a resolution change/other error where
+ * the bytes of the last header are not consumed.
+ */
+ ps_dec->i4_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
+ ps_dec->i4_bytes_consumed -= ((size_t)ps_dec->s_bit_stream.pv_bs_buf & 3);
+ }
}
if((u4_start_code_found == 0) && (ps_dec->s_bit_stream.u4_offset > ps_dec->s_bit_stream.u4_max_offset))
{
diff --git a/decoder/impeg2d_decoder.c b/decoder/impeg2d_decoder.c
index 7bc3253..fa88bb5 100644
--- a/decoder/impeg2d_decoder.c
+++ b/decoder/impeg2d_decoder.c
@@ -123,7 +123,14 @@
if(ps_op->s_ivd_video_decode_op_t.u4_error_code == 0)
ps_op->s_ivd_video_decode_op_t.u4_error_code = e_error;
+ if (IMPEG2D_UNSUPPORTED_DIMENSIONS == e_error)
+ {
+ ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
+ ps_dec->u2_header_done = 0;
+ ps_op->s_ivd_video_decode_op_t.u4_pic_ht = ps_dec->u2_reinit_max_height;
+ ps_op->s_ivd_video_decode_op_t.u4_pic_wd = ps_dec->u2_reinit_max_width;
+ }
impeg2d_next_code(ps_dec, SEQUENCE_HEADER_CODE);
return;
}
@@ -178,6 +185,8 @@
ps_dec = (dec_state_t *)pv_dec;
ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
+ ps_dec->i4_bytes_consumed = 0;
+ ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
IMPEG2D_FRM_NUM_SET();
@@ -202,7 +211,7 @@
if ((IMPEG2D_ERROR_CODES_T) IVD_RES_CHANGED == e_error)
{
- ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
+ ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
ps_dec->u2_header_done = 0;
}
else if (IMPEG2D_UNSUPPORTED_DIMENSIONS == e_error)
@@ -215,8 +224,18 @@
}
else
{
- if(ps_dec->i4_num_cores > 1)
+ if(ps_dec->i4_num_cores > 1 && 0 != ps_dec->i4_bytes_consumed)
+ {
+ /* If the number of bytes consumed has been updated by
+ * get_slice_pos function, then use that. Else, the bytes consumed is
+ * calculated from the offset. The bytes consumed for multi-thread runs
+ * is updated only into ps_dec->i4_bytes_consumed if the get_slice_pos
+ * function has been called. If that function has not run, then we have
+ * encountered an error but still have to consume the bytes in header
+ * decode, etc.
+ */
ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
+ }
else
{
ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
@@ -246,8 +265,18 @@
/**************************************************************************/
ps_op->s_ivd_video_decode_op_t.u4_error_code = IV_SUCCESS;
- if(ps_dec->i4_num_cores > 1)
+ if(ps_dec->i4_num_cores > 1 && 0 != ps_dec->i4_bytes_consumed)
+ {
+ /* If the number of bytes consumed has been updated by
+ * get_slice_pos function, then use that. Else, the bytes consumed is
+ * calculated from the offset. The bytes consumed for multi-thread runs
+ * is updated only into ps_dec->i4_bytes_consumed if the get_slice_pos
+ * function has been called. If that function has not run, then we have
+ * encountered an error but still have to consume the bytes in header
+ * decode, etc.
+ */
ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = ps_dec->i4_bytes_consumed;
+ }
else
{
ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = (ps_dec->s_bit_stream.u4_offset + 7) >> 3;
diff --git a/decoder/impeg2d_pic_proc.c b/decoder/impeg2d_pic_proc.c
index 029f1bf..fbbbf79 100644
--- a/decoder/impeg2d_pic_proc.c
+++ b/decoder/impeg2d_pic_proc.c
@@ -555,6 +555,32 @@
ps_dec->as_recent_fld[1][1] = ps_dec->as_recent_fld[0][1];
}
+ /* Error resilience: If forward and backward pictures are going to be NULL*/
+ /* then assign both to the current */
+ /* if one of them NULL then we will assign the non null to the NULL one */
+
+ if((NULL == ps_dec->as_recent_fld[0][1].pu1_y) && (NULL == ps_dec->as_recent_fld[1][1].pu1_y))
+ {
+ // assign the current picture to both
+ ps_dec->as_recent_fld[1][0] = ps_dec->s_cur_frm_buf;
+ impeg2d_get_bottom_field_buf(&ps_dec->s_cur_frm_buf, &ps_dec->as_recent_fld[1][1],
+ ps_dec->u2_frame_width);
+ ps_dec->as_recent_fld[0][0] = ps_dec->s_cur_frm_buf;
+ ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
+ }
+ //Assign the non-null picture to the null picture
+
+ else if((NULL == ps_dec->as_recent_fld[0][1].pu1_y) && (NULL != ps_dec->as_recent_fld[1][1].pu1_y))
+ {
+ ps_dec->as_recent_fld[0][0] = ps_dec->as_recent_fld[1][0];
+ ps_dec->as_recent_fld[0][1] = ps_dec->as_recent_fld[1][1];
+ }
+
+ else if((NULL == ps_dec->as_recent_fld[1][1].pu1_y) && (NULL != ps_dec->as_recent_fld[0][1].pu1_y))
+ {
+ ps_dec->as_recent_fld[1][0] = ps_dec->as_recent_fld[0][0];
+ ps_dec->as_recent_fld[1][1] = ps_dec->as_recent_fld[0][1];
+ }
ps_dec->as_ref_buf[FORW][TOP] = ps_dec->as_recent_fld[0][0];
ps_dec->as_ref_buf[FORW][BOTTOM] = ps_dec->as_recent_fld[0][1];
ps_dec->as_ref_buf[BACK][TOP] = ps_dec->as_recent_fld[1][0];
diff --git a/decoder/impeg2d_pnb_pic.c b/decoder/impeg2d_pnb_pic.c
index a6c2351..5540044 100644
--- a/decoder/impeg2d_pnb_pic.c
+++ b/decoder/impeg2d_pnb_pic.c
@@ -106,6 +106,14 @@
u2_mb_addr_incr = ps_dec->u2_num_horiz_mb - ps_dec->u2_mb_x;
}
+ if ((u2_mb_addr_incr - 1) > ps_dec->u2_num_mbs_left)
+ {
+ /* If the number of skip MBs are more than the number of MBs
+ * left, indicate error.
+ */
+ return IV_FAIL;
+ }
+
impeg2d_dec_skip_mbs(ps_dec, (UWORD16)(u2_mb_addr_incr - 1));
}
@@ -297,6 +305,13 @@
u2_mb_addr_incr = ps_dec->u2_num_horiz_mb - ps_dec->u2_mb_x;
}
+ if ((u2_mb_addr_incr - 1) > ps_dec->u2_num_mbs_left)
+ {
+ /* If the number of skip MBs are more than the number of MBs
+ * left, indicate error.
+ */
+ return IV_FAIL;
+ }
impeg2d_dec_skip_mbs(ps_dec, (UWORD16)(u2_mb_addr_incr - 1));
}
@@ -488,7 +503,6 @@
IMPEG2D_TRACE_MB_START(ps_dec->u2_mb_x, ps_dec->u2_mb_y);
-
if(ps_dec->e_pic_type == B_PIC)
ret = impeg2d_dec_pnb_mb_params(ps_dec);
else
@@ -687,7 +701,6 @@
}
}
-
ps_dec->u2_num_mbs_left--;
ps_dec->u2_first_mb = 0;
ps_dec->u2_mb_x++;
diff --git a/decoder/impeg2d_vld.c b/decoder/impeg2d_vld.c
index 12bb617..80ee403 100644
--- a/decoder/impeg2d_vld.c
+++ b/decoder/impeg2d_vld.c
@@ -655,7 +655,11 @@
{
u4_run = ((DecodedValue >> 4) & 0x1f);
u4_numCoeffs += u4_run;
- u4_pos = pu1_scan[u4_numCoeffs++ & 63];
+ if (u4_numCoeffs >= NUM_COEFFS)
+ {
+ return IMPEG2D_MB_TEX_DECODE_ERR;
+ }
+ u4_pos = pu1_scan[u4_numCoeffs++];
pu1_pos[*pi4_num_coeffs] = u4_pos;
FLUSH_BITS(u4_offset,u4_buf,u4_buf_nxt,u4_sym_len,pu4_buf_aligned)
@@ -701,7 +705,11 @@
u4_level = ((WORD16) DecodedValue) >> 9;
u4_numCoeffs += u4_run;
- u4_pos = pu1_scan[u4_numCoeffs++ & 63];
+ if (u4_numCoeffs >= NUM_COEFFS)
+ {
+ return IMPEG2D_MB_TEX_DECODE_ERR;
+ }
+ u4_pos = pu1_scan[u4_numCoeffs++];
pu1_pos[*pi4_num_coeffs] = u4_pos;
pi2_outAddr[*pi4_num_coeffs] = u4_level;
(*pi4_num_coeffs)++;
@@ -722,7 +730,11 @@
u4_level = (u4_level - ((u4_level & 0x0800) << 1));
u4_numCoeffs += u4_run;
- u4_pos = pu1_scan[u4_numCoeffs++ & 63];
+ if (u4_numCoeffs >= NUM_COEFFS)
+ {
+ return IMPEG2D_MB_TEX_DECODE_ERR;
+ }
+ u4_pos = pu1_scan[u4_numCoeffs++];
pu1_pos[*pi4_num_coeffs] = u4_pos;
pi2_outAddr[*pi4_num_coeffs] = u4_level;
(*pi4_num_coeffs)++;
@@ -785,8 +797,12 @@
u4_level = (u4_level - (u4_level_first_byte << 1));
}
u4_numCoeffs += u4_run;
+ if (u4_numCoeffs >= NUM_COEFFS)
+ {
+ return IMPEG2D_MB_TEX_DECODE_ERR;
+ }
- u4_pos = pu1_scan[u4_numCoeffs++ & 63];
+ u4_pos = pu1_scan[u4_numCoeffs++];
pu1_pos[*pi4_num_coeffs] = u4_pos;
pi2_outAddr[*pi4_num_coeffs] = u4_level;
@@ -798,11 +814,6 @@
u4_nz_cols |= 1 << (u4_pos & 0x7);
u4_nz_rows |= 1 << (u4_pos >> 0x3);
- if (u4_numCoeffs > 64)
- {
- return IMPEG2D_MB_TEX_DECODE_ERR;
- }
-
}
IBITS_GET(u4_buf,u4_buf_nxt,u4_offset,u4_bits,pu4_buf_aligned,u4_sym_len)
}
@@ -836,8 +847,12 @@
u4_run = BITS(DecodedValue, 8,4);
u4_numCoeffs += u4_run;
+ if (u4_numCoeffs >= NUM_COEFFS)
+ {
+ return IMPEG2D_MB_TEX_DECODE_ERR;
+ }
- u4_pos = pu1_scan[u4_numCoeffs++ & 63];
+ u4_pos = pu1_scan[u4_numCoeffs++];
pu1_pos[*pi4_num_coeffs] = u4_pos;
FLUSH_BITS(u4_offset,u4_buf,u4_buf_nxt,u4_sym_len,pu4_buf_aligned)
@@ -872,8 +887,12 @@
u4_level = ((WORD16) DecodedValue) >> 9;
u4_numCoeffs += u4_run;
+ if (u4_numCoeffs >= NUM_COEFFS)
+ {
+ return IMPEG2D_MB_TEX_DECODE_ERR;
+ }
- u4_pos = pu1_scan[u4_numCoeffs++ & 63];
+ u4_pos = pu1_scan[u4_numCoeffs++];
pu1_pos[*pi4_num_coeffs] = u4_pos;
if (1 == lead_zeros)
u4_sym_len--;
@@ -897,8 +916,12 @@
u4_level = (u4_level - ((u4_level & 0x0800) << 1));
u4_numCoeffs += u4_run;
+ if (u4_numCoeffs >= NUM_COEFFS)
+ {
+ return IMPEG2D_MB_TEX_DECODE_ERR;
+ }
- u4_pos = pu1_scan[u4_numCoeffs++ & 63];
+ u4_pos = pu1_scan[u4_numCoeffs++];
pu1_pos[*pi4_num_coeffs] = u4_pos;
pi2_outAddr[*pi4_num_coeffs] = u4_level;
@@ -962,8 +985,12 @@
u4_level = (u4_level - (u4_level_first_byte << 1));
}
u4_numCoeffs += u4_run;
+ if (u4_numCoeffs >= NUM_COEFFS)
+ {
+ return IMPEG2D_MB_TEX_DECODE_ERR;
+ }
- u4_pos = pu1_scan[u4_numCoeffs++ & 63];
+ u4_pos = pu1_scan[u4_numCoeffs++];
pu1_pos[*pi4_num_coeffs] = u4_pos;
pi2_outAddr[*pi4_num_coeffs] = u4_level;
@@ -974,10 +1001,6 @@
u4_nz_cols |= 1 << (u4_pos & 0x7);
u4_nz_rows |= 1 << (u4_pos >> 0x3);
- if (u4_numCoeffs > 64)
- {
- return IMPEG2D_MB_TEX_DECODE_ERR;
- }
}