summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2017-11-08 22:41:37 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2017-11-08 22:41:37 +0000
commit8100e11aff8e0fac381a82a8d5d2947fd81996c0 (patch)
treefd1c34076c2856dacc7aed7207289672f4937a6f
parent5a87af31465b8dfb905611365ab614541569de82 (diff)
parent7d4d089f5d0ff26880515025cf5b71e653003762 (diff)
downloadlibmpeg2-oreo-r4-release.tar.gz
Merge cherrypicks of [3192228, 3193161, 3192849, 3192850, 3192851, 3193150, 3193193, 3193195, 3193196, 3192852, 3193233, 3193234, 3192311, 3192312, 3193273, 3193218] into oc-r4-releaseandroid-8.0.0_r35oreo-r4-release
Change-Id: Ia54787fbc02a7c2a75b93df53faf5973423286ec
-rw-r--r--decoder/impeg2d_api_main.c1
-rw-r--r--decoder/impeg2d_bitstream.c20
-rw-r--r--decoder/impeg2d_dec_hdr.c26
-rw-r--r--decoder/impeg2d_decoder.c12
-rw-r--r--decoder/impeg2d_pnb_pic.c29
-rw-r--r--decoder/impeg2d_structs.h4
6 files changed, 71 insertions, 21 deletions
diff --git a/decoder/impeg2d_api_main.c b/decoder/impeg2d_api_main.c
index cfef75d..5693555 100644
--- a/decoder/impeg2d_api_main.c
+++ b/decoder/impeg2d_api_main.c
@@ -1026,6 +1026,7 @@ IV_API_CALL_STATUS_T impeg2d_api_reset(iv_obj_t *ps_dechdl,
ps_dec_state->u2_header_done = 0; /* Header decoding not done */
ps_dec_state->u4_frm_buf_stride = 0;
+ ps_dec_state->i4_pic_count = 0;
ps_dec_state->u2_is_mpeg2 = 0;
ps_dec_state->aps_ref_pics[0] = NULL;
ps_dec_state->aps_ref_pics[1] = NULL;
diff --git a/decoder/impeg2d_bitstream.c b/decoder/impeg2d_bitstream.c
index 36092e5..57a9e2f 100644
--- a/decoder/impeg2d_bitstream.c
+++ b/decoder/impeg2d_bitstream.c
@@ -191,21 +191,17 @@ INLINE UWORD8 impeg2d_bit_stream_get_bit(stream_t *ps_stream)
INLINE void impeg2d_bit_stream_flush(void* pv_ctxt, UWORD32 u4_no_of_bits)
{
stream_t *ps_stream = (stream_t *)pv_ctxt;
- if ((ps_stream->u4_offset + 64) < ps_stream->u4_max_offset)
+
+
+ if (ps_stream->u4_offset <= ps_stream->u4_max_offset)
{
+ /* We have to flush the bytes even if the offset is equal to the maximum
+ * offset. This will ensure that a stream with an error exactly at the
+ * offset will not get stuck in an infinite loop - If we do not flush
+ * these bytes, then we keep feeding the erroneous bits.
+ */
FLUSH_BITS(ps_stream->u4_offset,ps_stream->u4_buf,ps_stream->u4_buf_nxt,u4_no_of_bits,ps_stream->pu4_buf_aligned)
}
- else
- {
- UWORD32 u4_temp;
-
- if (((ps_stream->u4_offset & 0x1f) + u4_no_of_bits) >= 32)
- {
- ps_stream->u4_buf = ps_stream->u4_buf_nxt;
- ps_stream->u4_buf_nxt = 0;
- }
- ps_stream->u4_offset += u4_no_of_bits;
- }
return;
}
/******************************************************************************
diff --git a/decoder/impeg2d_dec_hdr.c b/decoder/impeg2d_dec_hdr.c
index 46502c4..aa3c70f 100644
--- a/decoder/impeg2d_dec_hdr.c
+++ b/decoder/impeg2d_dec_hdr.c
@@ -174,7 +174,16 @@ IMPEG2D_ERROR_CODES_T impeg2d_dec_seq_hdr(dec_state_t *ps_dec)
}
else
{
- if((u2_width > ps_dec->u2_create_max_width)
+ if (0 == ps_dec->i4_pic_count)
+ {
+ /* Decoder has not decoded a single frame since the last
+ * reset/init. This implies that we have two headers in the
+ * input stream. So, do not indicate a resolution change, since
+ * this can take the decoder into an infinite loop.
+ */
+ return (IMPEG2D_ERROR_CODES_T) IMPEG2D_FRM_HDR_DECODE_ERR;
+ }
+ else if((u2_width > ps_dec->u2_create_max_width)
|| (u2_height > ps_dec->u2_create_max_height))
{
IMPEG2D_ERROR_CODES_T e_error = IMPEG2D_UNSUPPORTED_DIMENSIONS;
@@ -936,7 +945,7 @@ void impeg2d_dec_pic_data_thread(dec_state_t *ps_dec)
{
pu1_buf = ps_dec->pu1_inp_bits_buf + s_job.i4_bistream_ofst;
impeg2d_bit_stream_init(&(ps_dec->s_bit_stream), pu1_buf,
- (ps_dec->u4_num_inp_bytes - s_job.i4_bistream_ofst) + 8);
+ (ps_dec->u4_num_inp_bytes - s_job.i4_bistream_ofst));
i4_cur_row = s_job.i2_start_mb_y;
ps_dec->i4_start_mb_y = s_job.i2_start_mb_y;
ps_dec->i4_end_mb_y = s_job.i2_end_mb_y;
@@ -978,6 +987,11 @@ void impeg2d_dec_pic_data_thread(dec_state_t *ps_dec)
if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
{
impeg2d_next_start_code(ps_dec);
+ if(ps_dec->s_bit_stream.u4_offset >= ps_dec->s_bit_stream.u4_max_offset)
+ {
+ ps_dec->u4_error_code = IMPEG2D_BITSTREAM_BUFF_EXCEEDED_ERR;
+ return;
+ }
}
}
@@ -1092,6 +1106,7 @@ static WORD32 impeg2d_init_thread_dec_ctxt(dec_state_t *ps_dec,
ps_dec_thd->u2_mb_x = 0;
ps_dec_thd->u2_mb_y = 0;
ps_dec_thd->u2_is_mpeg2 = ps_dec->u2_is_mpeg2;
+ ps_dec_thd->i4_pic_count = ps_dec->i4_pic_count;
ps_dec_thd->u2_frame_width = ps_dec->u2_frame_width;
ps_dec_thd->u2_frame_height = ps_dec->u2_frame_height;
ps_dec_thd->u2_picture_width = ps_dec->u2_picture_width;
@@ -1364,8 +1379,6 @@ void impeg2d_dec_pic_data(dec_state_t *ps_dec)
WORD32 i;
dec_state_multi_core_t *ps_dec_state_multi_core;
- UWORD32 u4_error_code;
-
dec_state_t *ps_dec_thd;
WORD32 i4_status;
WORD32 i4_min_mb_y;
@@ -1373,7 +1386,6 @@ void impeg2d_dec_pic_data(dec_state_t *ps_dec)
/* Resetting the MB address and MB coordinates at the start of the Frame */
ps_dec->u2_mb_x = ps_dec->u2_mb_y = 0;
- u4_error_code = 0;
ps_dec_state_multi_core = ps_dec->ps_dec_state_multi_core;
impeg2d_get_slice_pos(ps_dec_state_multi_core);
@@ -1417,8 +1429,6 @@ void impeg2d_dec_pic_data(dec_state_t *ps_dec)
}
}
- ps_dec->u4_error_code = u4_error_code;
-
}
/*******************************************************************************
*
@@ -1752,6 +1762,7 @@ IMPEG2D_ERROR_CODES_T impeg2d_process_video_bit_stream(dec_state_t *ps_dec)
else if((ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset)
&& (u4_next_bits == PICTURE_START_CODE))
{
+ ps_dec->i4_pic_count++;
e_error = impeg2d_dec_pic_hdr(ps_dec);
if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
@@ -1844,6 +1855,7 @@ IMPEG2D_ERROR_CODES_T impeg2d_process_video_bit_stream(dec_state_t *ps_dec)
else if ((impeg2d_bit_stream_nxt(ps_stream,START_CODE_LEN) == PICTURE_START_CODE)
&& (ps_dec->s_bit_stream.u4_offset < ps_dec->s_bit_stream.u4_max_offset))
{
+ ps_dec->i4_pic_count++;
e_error = impeg2d_dec_pic_hdr(ps_dec);
if ((IMPEG2D_ERROR_CODES_T)IVD_ERROR_NONE != e_error)
diff --git a/decoder/impeg2d_decoder.c b/decoder/impeg2d_decoder.c
index fa88bb5..e4ff79c 100644
--- a/decoder/impeg2d_decoder.c
+++ b/decoder/impeg2d_decoder.c
@@ -98,12 +98,17 @@ void impeg2d_dec_hdr(void *pv_dec,impeg2d_video_decode_ip_t *ps_ip,
UWORD32 u4_bits_read;
dec_state_t *ps_dec;
+ UWORD32 u4_size = ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes;
ps_dec = (dec_state_t *)pv_dec;
ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
+ if (u4_size >= MAX_BITSTREAM_BUFFER_SIZE)
+ {
+ u4_size = MAX_BITSTREAM_BUFFER_SIZE - MIN_BUFFER_BYTES_AT_EOS;
+ }
impeg2d_bit_stream_init(&(ps_dec->s_bit_stream),ps_ip->s_ivd_video_decode_ip_t.pv_stream_buffer,
- ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes);
+ u4_size);
{
{
@@ -189,12 +194,15 @@ void impeg2d_dec_frm(void *pv_dec,impeg2d_video_decode_ip_t *ps_ip,
ps_op->s_ivd_video_decode_op_t.u4_num_bytes_consumed = 0;
IMPEG2D_FRM_NUM_SET();
+ if (u4_size >= MAX_BITSTREAM_BUFFER_SIZE)
+ {
+ u4_size = MAX_BITSTREAM_BUFFER_SIZE - MIN_BUFFER_BYTES_AT_EOS;
+ }
ps_dec->pu1_inp_bits_buf = ps_ip->s_ivd_video_decode_ip_t.pv_stream_buffer;
ps_dec->u4_num_inp_bytes = u4_size;
ps_stream = &ps_dec->s_bit_stream;
-
impeg2d_bit_stream_init(ps_stream,ps_ip->s_ivd_video_decode_ip_t.pv_stream_buffer,u4_size);
/* @ */ /* Updating the bufferID */
diff --git a/decoder/impeg2d_pnb_pic.c b/decoder/impeg2d_pnb_pic.c
index 570f0d2..a3ae436 100644
--- a/decoder/impeg2d_pnb_pic.c
+++ b/decoder/impeg2d_pnb_pic.c
@@ -122,6 +122,33 @@ WORD32 impeg2d_dec_p_mb_params(dec_state_t *ps_dec)
impeg2d_dec_skip_mbs(ps_dec, (UWORD16)(u2_mb_addr_incr - 1));
}
+ else
+ {
+
+ /****************************************************************/
+ /* Section 6.3.17 */
+ /* The first MB of a slice cannot be skipped */
+ /* But the mb_addr_incr can be > 1, because at the beginning of */
+ /* a slice, it indicates the offset from the last MB in the */
+ /* previous row. Hence for the first slice in a row, the */
+ /* mb_addr_incr needs to be 1. */
+ /****************************************************************/
+ /* MB_x is set to zero whenever MB_y changes. */
+ ps_dec->u2_mb_x = u2_mb_addr_incr - 1;
+ /* For error resilience */
+ ps_dec->u2_mb_x = MIN(ps_dec->u2_mb_x, (ps_dec->u2_num_horiz_mb - 1));
+ 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_mb_x;
+
+ /****************************************************************/
+ /* mb_addr_incr is forced to 1 because in this decoder it is used */
+ /* more as an indicator of the number of MBs skipped than the */
+ /* as defined by the standard (Section 6.3.17) */
+ /****************************************************************/
+ u2_mb_addr_incr = 1;
+ ps_dec->u2_first_mb = 0;
+
+ }
}
u4_next_word = (UWORD16)impeg2d_bit_stream_nxt(ps_stream,16);
@@ -286,6 +313,8 @@ WORD32 impeg2d_dec_pnb_mb_params(dec_state_t *ps_dec)
ps_dec->u2_mb_x = u2_mb_addr_incr - 1;
/* For error resilience */
ps_dec->u2_mb_x = MIN(ps_dec->u2_mb_x, (ps_dec->u2_num_horiz_mb - 1));
+ 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_mb_x;
/****************************************************************/
/* mb_addr_incr is forced to 1 because in this decoder it is used */
diff --git a/decoder/impeg2d_structs.h b/decoder/impeg2d_structs.h
index 03cd54c..46538bf 100644
--- a/decoder/impeg2d_structs.h
+++ b/decoder/impeg2d_structs.h
@@ -40,6 +40,7 @@ Because of temporal dependency in deinterlacer one additional buffer is also nee
#define DEC_ORDER 0
#define MAX_BITSTREAM_BUFFER_SIZE 2000 * 1024
+#define MIN_BUFFER_BYTES_AT_EOS 8
/* Flag to signal that buffer is held by deinterlacing */
#define MPEG2_BUF_MGR_DEINT (BUF_MGR_DISP << 1)
@@ -331,6 +332,9 @@ typedef struct dec_state_struct_t
UWORD8 *pu1_chroma_ref_buf[BUF_MGR_MAX_CNT];
ivd_out_bufdesc_t as_disp_buffers[BUF_MGR_MAX_CNT];
+ /* Count the number of pictures decoded after init/reset */
+ WORD32 i4_pic_count;
+
/* Flag to signal last coeff in a 8x8 block is one
after mismatch contol */
WORD32 i4_last_value_one;