Fixed an overread in YUV420 Semi-planar input usecase

Handled non-multiple of 16 dimensions for 420 semiplanar input
Modified test code to remove alignment of width and height

Change-Id: I83ff8165364a863d577fcac81e711b07eec9c004
This commit is contained in:
Harish Mahendrakar 2015-06-09 17:48:53 +05:30
parent bf9cd17d31
commit 5cdb888fea
4 changed files with 58 additions and 3 deletions

View file

@ -3381,6 +3381,11 @@ static WORD32 ih264e_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op)
* (wd * ht) for luma and (wd * ht / 2) for chroma*/
ps_mem_rec->u4_mem_size = MAX_CTXT_SETS
* ((3 * max_ht_luma * max_wd_luma) >> 1);
/* Allocate an extra row, since inverse transform functions for
* chroma access(only read, not used) few extra bytes due to
* interleaved input
*/
ps_mem_rec->u4_mem_size += max_wd_luma;
}
DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CSC, ps_mem_rec->u4_mem_size);

View file

@ -1052,7 +1052,21 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc)
/* init buffer pointers */
ps_proc->pu1_src_buf_chroma = ps_proc->pu1_src_buf_chroma_base + (i4_mb_x * MB_SIZE) + ps_codec->s_cfg.u4_max_wd * (i4_mb_y * BLK8x8SIZE);
if (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE ||
ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420P ||
ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
{
if ((ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420SP_UV) ||
(ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420SP_VU))
ps_proc->pu1_src_buf_chroma_base = ps_codec->pu1_uv_csc_buf_base;
ps_proc->pu1_src_buf_chroma = ps_proc->pu1_src_buf_chroma_base + (i4_mb_x * MB_SIZE) + ps_codec->s_cfg.u4_max_wd * (i4_mb_y * BLK8x8SIZE);
}
else
{
ps_proc->pu1_src_buf_chroma = ps_proc->pu1_src_buf_chroma_base + (i4_mb_x * MB_SIZE) + i4_src_strd * (i4_mb_y * BLK8x8SIZE);
}
ps_proc->pu1_rec_buf_luma = ps_proc->pu1_rec_buf_luma_base + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * MB_SIZE);
ps_proc->pu1_rec_buf_chroma = ps_proc->pu1_rec_buf_chroma_base + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * BLK8x8SIZE);
ps_proc->pu1_ref_buf_luma = ps_proc->pu1_ref_buf_luma_base + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * MB_SIZE);
@ -1067,6 +1081,42 @@ IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc)
{
case IV_YUV_420SP_UV:
case IV_YUV_420SP_VU:
/* In case of 420 semi-planar input, copy last few rows to intermediate
buffer as chroma trans functions access one extra byte due to interleaved input.
This data will be padded if required */
if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
{
WORD32 num_rows = ps_codec->s_cfg.u4_disp_ht & 0xF;
UWORD8 *pu1_src;
UWORD8 *pu1_dst;
WORD32 i;
pu1_src = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[0] + (i4_mb_x * MB_SIZE) +
ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] * (i4_mb_y * MB_SIZE);
pu1_dst = ps_proc->pu1_src_buf_luma;
for (i = 0; i < num_rows; i++)
{
memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_wd);
pu1_src += ps_proc->s_inp_buf.s_raw_buf.au4_strd[0];
pu1_dst += ps_proc->i4_src_strd;
}
pu1_src = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[1] + (i4_mb_x * BLK8x8SIZE) +
ps_proc->s_inp_buf.s_raw_buf.au4_strd[1] * (i4_mb_y * BLK8x8SIZE);
pu1_dst = ps_proc->pu1_src_buf_chroma;
/* Last MB row of chroma is copied unconditionally, since trans functions access an extra byte
* due to interleaved input
*/
num_rows = (ps_codec->s_cfg.u4_disp_ht >> 1) - (ps_proc->i4_mb_y * BLK8x8SIZE);
for (i = 0; i < num_rows; i++)
{
memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_wd);
pu1_src += ps_proc->s_inp_buf.s_raw_buf.au4_strd[1];
pu1_dst += ps_proc->i4_src_strd;
}
}
break;
case IV_YUV_420P :

View file

@ -1591,7 +1591,7 @@ void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt)
ps_inp_raw_buf->apv_bufs[0] = pu1_buf;
/*Init chroma buffer*/
pu1_buf += (ps_app_ctxt->u4_strd) * ALIGN16(ps_app_ctxt->u4_ht);
pu1_buf += ps_app_ctxt->u4_strd * ps_app_ctxt->u4_ht;
ps_inp_raw_buf->apv_bufs[1] = pu1_buf;
ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd;

View file

@ -97,7 +97,7 @@ void allocate_recon(app_ctxt_t *ps_app_ctxt)
num_bufs = DEFAULT_NUM_RECON_BUFS;
/* Size of buffer for YUV420/420SP */
luma_size = ALIGN16(ps_app_ctxt->u4_max_wd) * ALIGN16(ps_app_ctxt->u4_max_ht);
luma_size = ps_app_ctxt->u4_max_wd * ps_app_ctxt->u4_max_ht;
chroma_size = (luma_size) / 4;
pic_size = luma_size + chroma_size * 2;