From 59f707666b8d242ec22c25ac11cbdbe7f480b4bd Mon Sep 17 00:00:00 2001 From: Yaowu Xu Date: Mon, 2 May 2016 11:50:56 -0700 Subject: [PATCH] Add shift stage in FASTSSIM computation Ported from libvpx/nextgenv2: d1c5cd4 Change-Id: If6cb82d38d2bc63fc61d577f81de939c11f73c5a --- aom_dsp/fastssim.c | 46 +++++++++++++++++++++++----------------- aom_dsp/ssim.h | 7 ++---- av1/encoder/encoder.c | 3 ++- test/hbd_metrics_test.cc | 4 ++-- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/aom_dsp/fastssim.c b/aom_dsp/fastssim.c index 2a9860e6c..74f751577 100644 --- a/aom_dsp/fastssim.c +++ b/aom_dsp/fastssim.c @@ -138,8 +138,8 @@ static void fs_downsample_level(fs_ctx *_ctx, int _l) { static void fs_downsample_level0(fs_ctx *_ctx, const uint8_t *_src1, int _s1ystride, const uint8_t *_src2, - int _s2ystride, int _w, int _h, - uint32_t bit_depth) { + int _s2ystride, int _w, int _h, uint32_t bd, + uint32_t shift) { uint32_t *dst1; uint32_t *dst2; int w; @@ -160,7 +160,7 @@ static void fs_downsample_level0(fs_ctx *_ctx, const uint8_t *_src1, int i1; i0 = 2 * i; i1 = FS_MINI(i0 + 1, _w); - if (bit_depth == 8) { + if (bd == 8 && shift == 0) { dst1[j * w + i] = _src1[j0 * _s1ystride + i0] + _src1[j0 * _s1ystride + i1] + _src1[j1 * _s1ystride + i0] + _src1[j1 * _s1ystride + i1]; @@ -170,12 +170,14 @@ static void fs_downsample_level0(fs_ctx *_ctx, const uint8_t *_src1, } else { uint16_t *src1s = CONVERT_TO_SHORTPTR(_src1); uint16_t *src2s = CONVERT_TO_SHORTPTR(_src2); - dst1[j * w + i] = - src1s[j0 * _s1ystride + i0] + src1s[j0 * _s1ystride + i1] + - src1s[j1 * _s1ystride + i0] + src1s[j1 * _s1ystride + i1]; - dst2[j * w + i] = - src2s[j0 * _s2ystride + i0] + src2s[j0 * _s2ystride + i1] + - src2s[j1 * _s2ystride + i0] + src2s[j1 * _s2ystride + i1]; + dst1[j * w + i] = (src1s[j0 * _s1ystride + i0] >> shift) + + (src1s[j0 * _s1ystride + i1] >> shift) + + (src1s[j1 * _s1ystride + i0] >> shift) + + (src1s[j1 * _s1ystride + i1] >> shift); + dst2[j * w + i] = (src2s[j0 * _s2ystride + i0] >> shift) + + (src2s[j0 * _s2ystride + i1] >> shift) + + (src2s[j1 * _s2ystride + i0] >> shift) + + (src2s[j1 * _s2ystride + i1] >> shift); } } } @@ -442,21 +444,22 @@ static double convert_ssim_db(double _ssim, double _weight) { } static double calc_ssim(const uint8_t *_src, int _systride, const uint8_t *_dst, - int _dystride, int _w, int _h, uint32_t bit_depth) { + int _dystride, int _w, int _h, uint32_t _bd, + uint32_t _shift) { fs_ctx ctx; double ret; int l; ret = 1; fs_ctx_init(&ctx, _w, _h, FS_NLEVELS); - fs_downsample_level0(&ctx, _src, _systride, _dst, _dystride, _w, _h, - bit_depth); + fs_downsample_level0(&ctx, _src, _systride, _dst, _dystride, _w, _h, _bd, + _shift); for (l = 0; l < FS_NLEVELS - 1; l++) { - fs_calc_structure(&ctx, l, bit_depth); + fs_calc_structure(&ctx, l, _bd); ret *= fs_average(&ctx, l); fs_downsample_level(&ctx, l + 1); } - fs_calc_structure(&ctx, l, bit_depth); - fs_apply_luminance(&ctx, l, bit_depth); + fs_calc_structure(&ctx, l, _bd); + fs_apply_luminance(&ctx, l, _bd); ret *= fs_average(&ctx, l); fs_ctx_clear(&ctx); return ret; @@ -464,19 +467,24 @@ static double calc_ssim(const uint8_t *_src, int _systride, const uint8_t *_dst, double aom_calc_fastssim(const YV12_BUFFER_CONFIG *source, const YV12_BUFFER_CONFIG *dest, double *ssim_y, - double *ssim_u, double *ssim_v, uint32_t bit_depth) { + double *ssim_u, double *ssim_v, uint32_t bd, + uint32_t in_bd) { double ssimv; + uint32_t bd_shift = 0; aom_clear_system_state(); + assert(bd >= in_bd); + + bd_shift = bd - in_bd; *ssim_y = calc_ssim(source->y_buffer, source->y_stride, dest->y_buffer, dest->y_stride, source->y_crop_width, - source->y_crop_height, bit_depth); + source->y_crop_height, in_bd, bd_shift); *ssim_u = calc_ssim(source->u_buffer, source->uv_stride, dest->u_buffer, dest->uv_stride, source->uv_crop_width, - source->uv_crop_height, bit_depth); + source->uv_crop_height, in_bd, bd_shift); *ssim_v = calc_ssim(source->v_buffer, source->uv_stride, dest->v_buffer, dest->uv_stride, source->uv_crop_width, - source->uv_crop_height, bit_depth); + source->uv_crop_height, in_bd, bd_shift); ssimv = (*ssim_y) * .8 + .1 * ((*ssim_u) + (*ssim_v)); return convert_ssim_db(ssimv, 1.0); } diff --git a/aom_dsp/ssim.h b/aom_dsp/ssim.h index 6ad187533..d76ae0f36 100644 --- a/aom_dsp/ssim.h +++ b/aom_dsp/ssim.h @@ -70,13 +70,10 @@ double aom_get_ssim_metrics(uint8_t *img1, int img1_pitch, uint8_t *img2, double aom_calc_ssim(const YV12_BUFFER_CONFIG *source, const YV12_BUFFER_CONFIG *dest, double *weight); -double aom_calc_ssimg(const YV12_BUFFER_CONFIG *source, - const YV12_BUFFER_CONFIG *dest, double *ssim_y, - double *ssim_u, double *ssim_v); - double aom_calc_fastssim(const YV12_BUFFER_CONFIG *source, const YV12_BUFFER_CONFIG *dest, double *ssim_y, - double *ssim_u, double *ssim_v, uint32_t bit_depth); + double *ssim_u, double *ssim_v, uint32_t bd, + uint32_t in_bd); #if CONFIG_AOM_HIGHBITDEPTH double aom_highbd_calc_ssim(const YV12_BUFFER_CONFIG *source, diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index 2f7f5060f..e4a4e83a4 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c @@ -3604,7 +3604,8 @@ static void compute_internal_stats(AV1_COMP *cpi) { } } - frame_all = aom_calc_fastssim(orig, recon, &y, &u, &v, bit_depth); + frame_all = + aom_calc_fastssim(orig, recon, &y, &u, &v, bit_depth, in_bit_depth); adjust_image_stat(y, u, v, frame_all, &cpi->fastssim); frame_all = aom_psnrhvs(orig, recon, &y, &u, &v, bit_depth, in_bit_depth); adjust_image_stat(y, u, v, frame_all, &cpi->psnrhvs); diff --git a/test/hbd_metrics_test.cc b/test/hbd_metrics_test.cc index a42eed60d..d2a8f6667 100644 --- a/test/hbd_metrics_test.cc +++ b/test/hbd_metrics_test.cc @@ -65,13 +65,13 @@ double compute_hbd_fastssim(const YV12_BUFFER_CONFIG *source, const YV12_BUFFER_CONFIG *dest, uint32_t in_bd, uint32_t bd) { double tempy, tempu, tempv; - return aom_calc_fastssim(source, dest, &tempy, &tempu, &tempv, bd); + return aom_calc_fastssim(source, dest, &tempy, &tempu, &tempv, bd, in_bd); } double compute_fastssim(const YV12_BUFFER_CONFIG *source, const YV12_BUFFER_CONFIG *dest) { double tempy, tempu, tempv; - return aom_calc_fastssim(source, dest, &tempy, &tempu, &tempv, 8); + return aom_calc_fastssim(source, dest, &tempy, &tempu, &tempv, 8, 8); } double compute_hbd_aomssim(const YV12_BUFFER_CONFIG *source,