summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVenkatarama Avadhani <venkatarama.avadhani@ittiam.com>2017-08-09 12:15:02 +0530
committerTim Schumacher <timschumi@gmx.de>2018-03-08 22:34:55 +0100
commitf4d3e28ca141f22b2576a4884f5bb11bf4527fa8 (patch)
treee4ce2e5c780e61213c0afff25f6ef881b98d1a3d
parent56eedc3af100b78100e3f16e44763abee305cc2c (diff)
downloadandroid_external_libmpeg2-f4d3e28ca141f22b2576a4884f5bb11bf4527fa8.tar.gz
android_external_libmpeg2-f4d3e28ca141f22b2576a4884f5bb11bf4527fa8.tar.bz2
android_external_libmpeg2-f4d3e28ca141f22b2576a4884f5bb11bf4527fa8.zip
Adding Error Check for Output Buffer Size
The output buffer size given by the application, needs to be checked in every process call. This is required in the case of resolution change. Bug: 70399408 Test: manual Change-Id: Id0d615e44d30f61702b3839be7b679d7d77a2411 (cherry picked from commit 7c88212153fbff998b337e899b496e2e382af54c)
-rw-r--r--decoder/impeg2d_api_main.c199
-rw-r--r--decoder/impeg2d_structs.h2
-rw-r--r--test/decoder/main.c7
3 files changed, 154 insertions, 54 deletions
diff --git a/decoder/impeg2d_api_main.c b/decoder/impeg2d_api_main.c
index 7fd3e4a..871945b 100644
--- a/decoder/impeg2d_api_main.c
+++ b/decoder/impeg2d_api_main.c
@@ -125,6 +125,7 @@
void impeg2d_init_arch(void *pv_codec);
void impeg2d_init_function_ptr(void *pv_codec);
+UWORD32 impeg2d_get_outbuf_size(WORD32 pic_wd,UWORD32 pic_ht, WORD32 u1_chroma_format,UWORD32 *p_buf_size);
/*****************************************************************************/
/* */
@@ -211,6 +212,8 @@ IV_API_CALL_STATUS_T impeg2d_api_set_display_frame(iv_obj_t *ps_dechdl,
dec_state_t *ps_dec_state;
dec_state_multi_core_t *ps_dec_state_multi_core;
UWORD32 u4_num_disp_bufs;
+ UWORD32 u4_disp_buf_size[3];
+ UWORD32 num_bufs;
dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip;
@@ -224,12 +227,41 @@ IV_API_CALL_STATUS_T impeg2d_api_set_display_frame(iv_obj_t *ps_dechdl,
ps_dec_state_multi_core = (dec_state_multi_core_t *) (ps_dechdl->pv_codec_handle);
ps_dec_state = ps_dec_state_multi_core->ps_dec_state[0];
+ num_bufs = dec_disp_ip->s_disp_buffer[0].u4_num_bufs;
+
if(ps_dec_state->u4_share_disp_buf)
{
pic_buf_t *ps_pic_buf;
ps_pic_buf = (pic_buf_t *)ps_dec_state->pv_pic_buf_base;
+
+ /* Get the sizes of the first buffer structure. Compare this with the
+ * rest to make sure all the buffers are of the same size.
+ */
+ u4_disp_buf_size[0] =
+ dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[0];
+ u4_disp_buf_size[1] =
+ dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1];
+ u4_disp_buf_size[2] =
+ dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[2];
for(i = 0; i < u4_num_disp_bufs; i++)
{
+ /* Verify all buffer structures have the same sized buffers as the
+ * first buffer structure*/
+ if ((dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[0]
+ != u4_disp_buf_size[0])
+ || (dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[1]
+ != u4_disp_buf_size[1])
+ || (dec_disp_ip->s_disp_buffer[i].u4_min_out_buf_size[2]
+ != u4_disp_buf_size[2]))
+ {
+ return IV_FAIL;
+ }
+ /* Verify all buffer structures have the same number of
+ * buffers (e.g. y, u, v) */
+ if (dec_disp_ip->s_disp_buffer[i].u4_num_bufs != num_bufs)
+ {
+ return IV_FAIL;
+ }
ps_pic_buf->pu1_y = dec_disp_ip->s_disp_buffer[i].pu1_bufs[0];
if(IV_YUV_420P == ps_dec_state->i4_chromaFormat)
@@ -715,35 +747,6 @@ IV_API_CALL_STATUS_T impeg2d_api_get_buf_info(iv_obj_t *ps_dechdl,
ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_num_in_bufs = 1;
ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_num_out_bufs = 1;
- if(ps_dec_state->i4_chromaFormat == IV_YUV_420P)
- {
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_num_out_bufs =
- MIN_OUT_BUFS_420;
- }
- else if((ps_dec_state->i4_chromaFormat == IV_YUV_420SP_UV)
- || (ps_dec_state->i4_chromaFormat == IV_YUV_420SP_VU))
- {
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_num_out_bufs =
- MIN_OUT_BUFS_420SP;
- }
- else if(ps_dec_state->i4_chromaFormat == IV_YUV_422ILE)
- {
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_num_out_bufs =
- MIN_OUT_BUFS_422ILE;
- }
- else if(ps_dec_state->i4_chromaFormat == IV_RGB_565)
- {
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_num_out_bufs =
- MIN_OUT_BUFS_RGB565;
- }
- else
- {
- //Invalid chroma format; Error code may be updated, verify in testing if needed
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code =
- IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED;
- return IV_FAIL;
- }
-
for(u4_i = 0; u4_i < IVD_VIDDEC_MAX_IO_BUFFERS; u4_i++)
{
ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_in_buf_size[u4_i] =
@@ -778,31 +781,19 @@ IV_API_CALL_STATUS_T impeg2d_api_get_buf_info(iv_obj_t *ps_dechdl,
u4_stride = ALIGN16(u4_stride);
u4_height = ALIGN32(ps_dec_state->u2_frame_height) + 9;
- if(ps_dec_state->i4_chromaFormat == IV_YUV_420P)
- {
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_out_buf_size[0] =
- (u4_stride * u4_height);
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_out_buf_size[1] =
- (u4_stride * u4_height) >> 2;
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_out_buf_size[2] =
- (u4_stride * u4_height) >> 2;
- }
- else if((ps_dec_state->i4_chromaFormat == IV_YUV_420SP_UV)
- || (ps_dec_state->i4_chromaFormat == IV_YUV_420SP_VU))
- {
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_out_buf_size[0] =
- (u4_stride * u4_height);
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_out_buf_size[1] =
- (u4_stride * u4_height) >> 1;
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_out_buf_size[2] = 0;
- }
- else if(ps_dec_state->i4_chromaFormat == IV_YUV_422ILE)
+ ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_num_out_bufs =
+ impeg2d_get_outbuf_size(
+ u4_stride,
+ u4_height,
+ ps_dec_state->i4_chromaFormat,
+ &ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_out_buf_size[0]);
+
+ if (0 == ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_num_out_bufs)
{
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_out_buf_size[0] =
- (u4_stride * u4_height) * 2;
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_out_buf_size[1] =
- ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_min_out_buf_size[2] =
- 0;
+ //Invalid chroma format; Error code may be updated, verify in testing if needed
+ ps_ctl_bufinfo_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code =
+ IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED;
+ return IV_FAIL;
}
/* Adding initialization for 2 uninitialized values */
@@ -1465,6 +1456,100 @@ IV_API_CALL_STATUS_T impeg2d_api_fill_mem_rec(void *pv_api_ip,void *pv_api_op)
}
+UWORD32 impeg2d_get_outbuf_size(WORD32 pic_wd,UWORD32 pic_ht, WORD32 u1_chroma_format,UWORD32 *p_buf_size)
+{
+ UWORD32 u4_min_num_out_bufs = 0;
+ if(u1_chroma_format == IV_YUV_420P)
+ u4_min_num_out_bufs = MIN_OUT_BUFS_420;
+ else if(u1_chroma_format == IV_YUV_422ILE)
+ u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
+ else if(u1_chroma_format == IV_RGB_565)
+ u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
+ else if((u1_chroma_format == IV_YUV_420SP_UV)
+ || (u1_chroma_format == IV_YUV_420SP_VU))
+ u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
+
+ if(u1_chroma_format == IV_YUV_420P)
+ {
+ p_buf_size[0] = (pic_wd * pic_ht);
+ p_buf_size[1] = (pic_wd * pic_ht)
+ >> 2;
+ p_buf_size[2] = (pic_wd * pic_ht)
+ >> 2;
+ }
+ else if(u1_chroma_format == IV_YUV_422ILE)
+ {
+ p_buf_size[0] = (pic_wd * pic_ht)
+ * 2;
+ p_buf_size[1] =
+ p_buf_size[2] = 0;
+ }
+ else if(u1_chroma_format == IV_RGB_565)
+ {
+ p_buf_size[0] = (pic_wd * pic_ht)
+ * 2;
+ p_buf_size[1] =
+ p_buf_size[2] = 0;
+ }
+ else if((u1_chroma_format == IV_YUV_420SP_UV)
+ || (u1_chroma_format == IV_YUV_420SP_VU))
+ {
+ p_buf_size[0] = (pic_wd * pic_ht);
+ p_buf_size[1] = (pic_wd * pic_ht)
+ >> 1;
+ p_buf_size[2] = 0;
+ }
+
+ return u4_min_num_out_bufs;
+}
+
+WORD32 check_app_out_buf_size(dec_state_t *ps_dec)
+{
+ UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS];
+ UWORD32 u4_min_num_out_bufs, i;
+ UWORD32 pic_wd, pic_ht;
+
+ pic_wd = ps_dec->u2_horizontal_size;
+ pic_ht = ps_dec->u2_vertical_size;
+
+ if(ps_dec->u4_frm_buf_stride > pic_wd)
+ pic_wd = ps_dec->u4_frm_buf_stride;
+
+ u4_min_num_out_bufs = impeg2d_get_outbuf_size(pic_wd, pic_ht, ps_dec->i4_chromaFormat, &au4_min_out_buf_size[0]);
+
+ if (0 == ps_dec->u4_share_disp_buf)
+ {
+ if(ps_dec->ps_out_buf->u4_num_bufs < u4_min_num_out_bufs)
+ {
+ return IV_FAIL;
+ }
+
+ for (i = 0 ; i < u4_min_num_out_bufs; i++)
+ {
+ if(ps_dec->ps_out_buf->u4_min_out_buf_size[i] < au4_min_out_buf_size[i])
+ return (IV_FAIL);
+ }
+ }
+ else
+ {
+ if(ps_dec->as_disp_buffers[0].u4_num_bufs < u4_min_num_out_bufs)
+ return IV_FAIL;
+
+ for (i = 0 ; i < u4_min_num_out_bufs; i++)
+ {
+ /* We need to check only with the disp_buffer[0], because we have
+ * already ensured that all the buffers are of the same size in
+ * impeg2d_api_set_display_frame.
+ */
+ if(ps_dec->as_disp_buffers[0].u4_min_out_buf_size[i] <
+ au4_min_out_buf_size[i])
+ return (IV_FAIL);
+ }
+ }
+
+ return(IV_SUCCESS);
+}
+
/*****************************************************************************/
@@ -1748,7 +1833,6 @@ IV_API_CALL_STATUS_T impeg2d_api_init(iv_obj_t *ps_dechdl,
}
}
-
ps_dec_state = ps_dec_state_multi_core->ps_dec_state[0];
if((ps_dec_state->i4_chromaFormat == IV_YUV_422ILE)
@@ -3295,6 +3379,13 @@ IV_API_CALL_STATUS_T impeg2d_api_entity(iv_obj_t *ps_dechdl,
{
ps_dec_state->u1_flushcnt = 0;
+ ps_dec_state->ps_out_buf = &ps_dec_ip->s_ivd_video_decode_ip_t.s_out_buffer;
+ if (IV_SUCCESS != check_app_out_buf_size(ps_dec_state))
+ {
+ ps_dec_op->s_ivd_video_decode_op_t.u4_error_code = IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
+ return IV_FAIL;
+ }
+
/*************************************************************************/
/* Frame Decode */
/*************************************************************************/
diff --git a/decoder/impeg2d_structs.h b/decoder/impeg2d_structs.h
index 1c23b95..971bc91 100644
--- a/decoder/impeg2d_structs.h
+++ b/decoder/impeg2d_structs.h
@@ -358,6 +358,8 @@ typedef struct dec_state_struct_t
/* Number of bytes in the input bitstream */
UWORD32 u4_num_inp_bytes;
+ ivd_out_bufdesc_t *ps_out_buf;
+
/* Bytes consumed */
WORD32 i4_bytes_consumed;
diff --git a/test/decoder/main.c b/test/decoder/main.c
index c344ec0..e6eb1ef 100644
--- a/test/decoder/main.c
+++ b/test/decoder/main.c
@@ -2246,6 +2246,7 @@ int main(WORD32 argc, CHAR *argv[])
u4_ip_buf_len);
codec_exit(ac_error_str);
}
+
s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
/* Allocate output buffer only if display buffers are not shared */
/* Or if shared and output is 420P */
@@ -2988,6 +2989,12 @@ int main(WORD32 argc, CHAR *argv[])
break;
}
+ else if (IVD_DISP_FRM_ZERO_OP_BUF_SIZE ==
+ (IMPEG2D_ERROR_CODES_T)s_video_decode_op.u4_error_code)
+ {
+ printf("Output buffer is not large enough!\n");
+ break;
+ }
}
if((1 == s_app_ctx.display) &&