diff options
author | Harish Mahendrakar <harish.mahendrakar@ittiam.com> | 2015-06-09 17:48:53 +0530 |
---|---|---|
committer | Ronghua Wu <ronghuawu@google.com> | 2015-06-12 18:34:16 -0700 |
commit | cf91c87b25ad49fc7e307932754d188e3ba2a479 (patch) | |
tree | 881c74b4e114b82b5a226678e26a6caf34660ae1 | |
parent | c75cf37283c11079d6015385453200f4710656da (diff) | |
download | android_external_libavc-cf91c87b25ad49fc7e307932754d188e3ba2a479.tar.gz android_external_libavc-cf91c87b25ad49fc7e307932754d188e3ba2a479.tar.bz2 android_external_libavc-cf91c87b25ad49fc7e307932754d188e3ba2a479.zip |
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
Bug: 21586373
Change-Id: I83ff8165364a863d577fcac81e711b07eec9c004
-rw-r--r-- | encoder/ih264e_api.c | 5 | ||||
-rw-r--r-- | encoder/ih264e_process.c | 52 | ||||
-rw-r--r-- | test/encoder/main.c | 2 | ||||
-rw-r--r-- | test/encoder/recon.c | 2 |
4 files changed, 58 insertions, 3 deletions
diff --git a/encoder/ih264e_api.c b/encoder/ih264e_api.c index b68d6dc..8a478bb 100644 --- a/encoder/ih264e_api.c +++ b/encoder/ih264e_api.c @@ -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); diff --git a/encoder/ih264e_process.c b/encoder/ih264e_process.c index 7b39fe5..670428e 100644 --- a/encoder/ih264e_process.c +++ b/encoder/ih264e_process.c @@ -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 : diff --git a/test/encoder/main.c b/test/encoder/main.c index bb9cabf..26420e2 100644 --- a/test/encoder/main.c +++ b/test/encoder/main.c @@ -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; diff --git a/test/encoder/recon.c b/test/encoder/recon.c index 7fd0f5c..ed63aac 100644 --- a/test/encoder/recon.c +++ b/test/encoder/recon.c @@ -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; |