[NORMATIVE] Film grain for odd frame dimensions BUG=aomedia:1598 Change-Id: Ib956914578bc94a5dc465c9b5ef4ee94a0f21480
diff --git a/aom_dsp/grain_synthesis.c b/aom_dsp/grain_synthesis.c index 01f518e..880144d 100644 --- a/aom_dsp/grain_synthesis.c +++ b/aom_dsp/grain_synthesis.c
@@ -792,6 +792,33 @@ return; } +static void extend_even(uint8_t *dst, int dst_stride, int width, int height, + int use_high_bit_depth) { + if ((width & 1) == 0 && (height & 1) == 0) return; + if (use_high_bit_depth) { + uint16_t *dst16 = (uint16_t *)dst; + if (width & 1) { + for (int i = 0; i < height; ++i) + dst16[i * dst_stride + width] = dst16[i * dst_stride + width - 1]; + } + width = (width + 1) & (~1); + if (height & 1) { + memcpy(&dst16[height * dst_stride], &dst16[(height - 1) * dst_stride], + sizeof(*dst16) * width); + } + } else { + if (width & 1) { + for (int i = 0; i < height; ++i) + dst[i * dst_stride + width] = dst[i * dst_stride + width - 1]; + } + width = (width + 1) & (~1); + if (height & 1) { + memcpy(&dst[height * dst_stride], &dst[(height - 1) * dst_stride], + sizeof(*dst) * width); + } + } +} + static void ver_boundary_overlap(int *left_block, int left_stride, int *right_block, int right_stride, int *dst_block, int dst_stride, int width, @@ -900,20 +927,28 @@ dst->r_w = src->r_w; dst->r_h = src->r_h; + dst->d_w = src->d_w; + dst->d_h = src->d_h; + + width = src->d_w % 2 ? src->d_w + 1 : src->d_w; + height = src->d_h % 2 ? src->d_h + 1 : src->d_h; copy_rect(src->planes[AOM_PLANE_Y], src->stride[AOM_PLANE_Y], - dst->planes[AOM_PLANE_Y], dst->stride[AOM_PLANE_Y], dst->d_w, - dst->d_h, use_high_bit_depth); + dst->planes[AOM_PLANE_Y], dst->stride[AOM_PLANE_Y], src->d_w, + src->d_h, use_high_bit_depth); + // Note that dst is already assumed to be aligned to even. + extend_even(dst->planes[AOM_PLANE_Y], dst->stride[AOM_PLANE_Y], src->d_w, + src->d_h, use_high_bit_depth); if (!src->monochrome) { copy_rect(src->planes[AOM_PLANE_U], src->stride[AOM_PLANE_U], dst->planes[AOM_PLANE_U], dst->stride[AOM_PLANE_U], - dst->d_w >> chroma_subsamp_x, dst->d_h >> chroma_subsamp_y, + width >> chroma_subsamp_x, height >> chroma_subsamp_y, use_high_bit_depth); copy_rect(src->planes[AOM_PLANE_V], src->stride[AOM_PLANE_V], dst->planes[AOM_PLANE_V], dst->stride[AOM_PLANE_V], - dst->d_w >> chroma_subsamp_x, dst->d_h >> chroma_subsamp_y, + width >> chroma_subsamp_x, height >> chroma_subsamp_y, use_high_bit_depth); } @@ -925,8 +960,6 @@ luma_stride = dst->stride[AOM_PLANE_Y] >> use_high_bit_depth; chroma_stride = dst->stride[AOM_PLANE_U] >> use_high_bit_depth; - width = dst->d_w; - height = dst->d_h; params->bit_depth = dst->bit_depth; av1_add_film_grain_run(params, luma, cb, cr, height, width, luma_stride,
diff --git a/av1/av1_dx_iface.c b/av1/av1_dx_iface.c index 052f3b7..e5d56bd 100644 --- a/av1/av1_dx_iface.c +++ b/av1/av1_dx_iface.c
@@ -519,12 +519,14 @@ if (grain_img_buf && (img->d_w != grain_img_buf->d_w || img->d_h != grain_img_buf->d_h || - img->fmt != grain_img_buf->fmt)) { + img->fmt != grain_img_buf->fmt || !(img->d_h % 2) || !(img->d_w % 2))) { aom_img_free(grain_img_buf); grain_img_buf = NULL; } if (!grain_img_buf) { - grain_img_buf = aom_img_alloc(NULL, img->fmt, img->d_w, img->d_h, 16); + int w_even = img->d_w % 2 ? img->d_w + 1 : img->d_w; + int h_even = img->d_h % 2 ? img->d_h + 1 : img->d_h; + grain_img_buf = aom_img_alloc(NULL, img->fmt, w_even, h_even, 16); grain_img_buf->bit_depth = img->bit_depth; }