From: Yaowu Xu Date: Fri, 5 Feb 2016 23:41:32 +0000 (-0800) Subject: Refactor internal stats code X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1a69cb286f79ce97dfc1653f343df2b503e5fab1;p=libvpx Refactor internal stats code Also removed the use of postprocessing in computing internal stats. Change-Id: Ib8fdbdfe7b7ca05cd1a034a373aa7762fa44323c --- diff --git a/vp10/encoder/encoder.c b/vp10/encoder/encoder.c index 5165e9af1..80bf47cc9 100644 --- a/vp10/encoder/encoder.c +++ b/vp10/encoder/encoder.c @@ -1689,15 +1689,9 @@ VP10_COMP *vp10_create_compressor(VP10EncoderConfig *oxcf, if (cpi->b_calculate_psnr) { cpi->total_sq_error = 0; cpi->total_samples = 0; - - cpi->totalp_sq_error = 0; - cpi->totalp_samples = 0; - cpi->tot_recode_hits = 0; cpi->summed_quality = 0; cpi->summed_weights = 0; - cpi->summedp_quality = 0; - cpi->summedp_weights = 0; } cpi->fastssim.worst = 100.0; @@ -1713,7 +1707,6 @@ VP10_COMP *vp10_create_compressor(VP10EncoderConfig *oxcf, 4 * cpi->common.mi_rows * cpi->common.mi_cols); cpi->worst_consistency = 100.0; } - #endif cpi->first_time_stamp_ever = INT64_MAX; @@ -1909,14 +1902,8 @@ void vp10_remove_compressor(VP10_COMP *cpi) { const double total_psnr = vpx_sse_to_psnr((double)cpi->total_samples, peak, (double)cpi->total_sq_error); - const double totalp_psnr = - vpx_sse_to_psnr((double)cpi->totalp_samples, peak, - (double)cpi->totalp_sq_error); const double total_ssim = 100 * pow(cpi->summed_quality / cpi->summed_weights, 8.0); - const double totalp_ssim = 100 * pow(cpi->summedp_quality / - cpi->summedp_weights, 8.0); - snprintf(headings, sizeof(headings), "Bitrate\tAVGPsnr\tGLBPsnr\tAVPsnrP\tGLPsnrP\t" "VPXSSIM\tVPSSIMP\tFASTSIM\tPSNRHVS\t" @@ -1926,8 +1913,8 @@ void vp10_remove_compressor(VP10_COMP *cpi) { "%7.3f\t%7.3f\t%7.3f\t%7.3f\t" "%7.3f\t%7.3f\t%7.3f\t%7.3f", dr, cpi->psnr.stat[ALL] / cpi->count, total_psnr, - cpi->psnrp.stat[ALL] / cpi->count, totalp_psnr, - total_ssim, totalp_ssim, + cpi->psnr.stat[ALL] / cpi->count, total_psnr, + total_ssim, total_ssim, cpi->fastssim.stat[ALL] / cpi->count, cpi->psnrhvs.stat[ALL] / cpi->count, cpi->psnr.worst, cpi->worst_ssim, cpi->fastssim.worst, @@ -1941,7 +1928,7 @@ void vp10_remove_compressor(VP10_COMP *cpi) { if (cpi->b_calculate_consistency) { double consistency = - vpx_sse_to_psnr((double)cpi->totalp_samples, peak, + vpx_sse_to_psnr((double)cpi->total_samples, peak, (double)cpi->total_inconsistency); SNPRINT(headings, "\tConsist\tWstCons"); @@ -4169,6 +4156,103 @@ static void adjust_image_stat(double y, double u, double v, double all, s->stat[ALL] += all; s->worst = VPXMIN(s->worst, all); } + +static void compute_internal_stats(VP10_COMP *cpi) { + VP10_COMMON *const cm = &cpi->common; + double samples = 0.0; + uint32_t in_bit_depth = 8; + uint32_t bit_depth = 8; + +#if CONFIG_VP9_HIGHBITDEPTH + if (cm->use_highbitdepth) { + in_bit_depth = cpi->oxcf.input_bit_depth; + bit_depth = cm->bit_depth; + } +#endif + if (cm->show_frame) { + const YV12_BUFFER_CONFIG *orig = cpi->Source; + const YV12_BUFFER_CONFIG *recon = cpi->common.frame_to_show; + double y, u, v, frame_all; + + cpi->count++; + if (cpi->b_calculate_psnr) { + PSNR_STATS psnr; + double frame_ssim2 = 0.0, weight = 0.0; + vpx_clear_system_state(); + // TODO(yaowu): unify these two versions into one. +#if CONFIG_VP9_HIGHBITDEPTH + calc_highbd_psnr(orig, recon, &psnr, cpi->td.mb.e_mbd.bd, in_bit_depth); +#else + calc_psnr(orig, recon, &psnr); +#endif // CONFIG_VP9_HIGHBITDEPTH + + adjust_image_stat(psnr.psnr[1], psnr.psnr[2], psnr.psnr[3], + psnr.psnr[0], &cpi->psnr); + cpi->total_sq_error += psnr.sse[0]; + cpi->total_samples += psnr.samples[0]; + samples = psnr.samples[0]; + // TODO(yaowu): unify these two versions into one. +#if CONFIG_VP9_HIGHBITDEPTH + if (cm->use_highbitdepth) + frame_ssim2 = vpx_highbd_calc_ssim(orig, recon, &weight, bit_depth); + else + frame_ssim2 = vpx_calc_ssim(orig, recon, &weight); +#else + frame_ssim2 = vpx_calc_ssim(orig, recon, &weight); +#endif // CONFIG_VP9_HIGHBITDEPTH + + cpi->worst_ssim= VPXMIN(cpi->worst_ssim, frame_ssim2); + cpi->summed_quality += frame_ssim2 * weight; + cpi->summed_weights += weight; + +#if 0 + { + FILE *f = fopen("q_used.stt", "a"); + fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n", + cpi->common.current_video_frame, y2, u2, v2, + frame_psnr2, frame_ssim2); + fclose(f); + } +#endif + } + if (cpi->b_calculate_blockiness) { +#if CONFIG_VP9_HIGHBITDEPTH + if (!cm->use_highbitdepth) +#endif + { + const double frame_blockiness = vp10_get_blockiness( + orig->y_buffer, orig->y_stride, recon->y_buffer, recon->y_stride, + orig->y_width, orig->y_height); + cpi->worst_blockiness = VPXMAX(cpi->worst_blockiness, frame_blockiness); + cpi->total_blockiness += frame_blockiness; + } + + if (cpi->b_calculate_consistency) { +#if CONFIG_VP9_HIGHBITDEPTH + if (!cm->use_highbitdepth) +#endif + { + const double this_inconsistency = vpx_get_ssim_metrics( + orig->y_buffer, orig->y_stride, recon->y_buffer, recon->y_stride, + orig->y_width, orig->y_height, cpi->ssim_vars, &cpi->metrics, 1); + + const double peak = (double)((1 << in_bit_depth) - 1); + const double consistency = vpx_sse_to_psnr( + samples, peak, cpi->total_inconsistency); + if (consistency > 0.0) + cpi->worst_consistency = + VPXMIN(cpi->worst_consistency, consistency); + cpi->total_inconsistency += this_inconsistency; + } + } + } + + frame_all = vpx_calc_fastssim(orig, recon, &y, &u, &v, bit_depth); + adjust_image_stat(y, u, v, frame_all, &cpi->fastssim); + frame_all = vpx_psnrhvs(orig, recon, &y, &u, &v, bit_depth); + adjust_image_stat(y, u, v, frame_all, &cpi->psnrhvs); + } +} #endif // CONFIG_INTERNAL_STATS int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags, @@ -4364,158 +4448,11 @@ int vp10_get_compressed_data(VP10_COMP *cpi, unsigned int *frame_flags, generate_psnr_packet(cpi); #if CONFIG_INTERNAL_STATS - if (oxcf->pass != 1) { - double samples = 0.0; + compute_internal_stats(cpi); cpi->bytes += (int)(*size); - - if (cm->show_frame) { - YV12_BUFFER_CONFIG *orig = cpi->Source; - YV12_BUFFER_CONFIG *recon = cpi->common.frame_to_show; - uint32_t bit_depth = 8; -#if CONFIG_VP9_HIGHBITDEPTH - uint32_t in_bit_depth = 8; -#endif - cpi->count++; - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - in_bit_depth = cpi->oxcf.input_bit_depth; - bit_depth = cm->bit_depth; - } -#endif - - if (cpi->b_calculate_psnr) { - PSNR_STATS psnr; - YV12_BUFFER_CONFIG *pp = &cm->post_proc_buffer; -#if CONFIG_VP9_HIGHBITDEPTH - calc_highbd_psnr(orig, recon, &psnr, cpi->td.mb.e_mbd.bd, - in_bit_depth); -#else - calc_psnr(orig, recon, &psnr); -#endif // CONFIG_VP9_HIGHBITDEPTH - - adjust_image_stat(psnr.psnr[1], psnr.psnr[2], psnr.psnr[3], - psnr.psnr[0], &cpi->psnr); - cpi->total_sq_error += psnr.sse[0]; - cpi->total_samples += psnr.samples[0]; - samples = psnr.samples[0]; - - { - PSNR_STATS psnr2; - double frame_ssim2 = 0, weight = 0; -#if CONFIG_VP9_POSTPROC - if (vpx_alloc_frame_buffer(pp, - recon->y_crop_width, recon->y_crop_height, - cm->subsampling_x, cm->subsampling_y, -#if CONFIG_VP9_HIGHBITDEPTH - cm->use_highbitdepth, -#endif - VP9_ENC_BORDER_IN_PIXELS, - cm->byte_alignment) < 0) { - vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, - "Failed to allocate post processing buffer"); - } - - vp10_deblock(recon, pp, cm->lf.filter_level * 10 / 6); -#endif - vpx_clear_system_state(); - -#if CONFIG_VP9_HIGHBITDEPTH - calc_highbd_psnr(orig, pp, &psnr2, cpi->td.mb.e_mbd.bd, - cpi->oxcf.input_bit_depth); -#else - calc_psnr(orig, pp, &psnr2); -#endif // CONFIG_VP9_HIGHBITDEPTH - - cpi->totalp_sq_error += psnr2.sse[0]; - cpi->totalp_samples += psnr2.samples[0]; - adjust_image_stat(psnr2.psnr[1], psnr2.psnr[2], psnr2.psnr[3], - psnr2.psnr[0], &cpi->psnrp); - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - frame_ssim2 = vpx_highbd_calc_ssim(orig, recon, &weight, - (int)cm->bit_depth); - } else { - frame_ssim2 = vpx_calc_ssim(orig, recon, &weight); - } -#else - frame_ssim2 = vpx_calc_ssim(orig, recon, &weight); -#endif // CONFIG_VP9_HIGHBITDEPTH - - cpi->worst_ssim= VPXMIN(cpi->worst_ssim, frame_ssim2); - cpi->summed_quality += frame_ssim2 * weight; - cpi->summed_weights += weight; - -#if CONFIG_VP9_HIGHBITDEPTH - if (cm->use_highbitdepth) { - frame_ssim2 = vpx_highbd_calc_ssim(orig, pp, &weight, - (int)cm->bit_depth); - } else { - frame_ssim2 = vpx_calc_ssim(orig, pp, &weight); - } -#else - frame_ssim2 = vpx_calc_ssim(orig, pp, &weight); -#endif // CONFIG_VP9_HIGHBITDEPTH - - cpi->summedp_quality += frame_ssim2 * weight; - cpi->summedp_weights += weight; -#if 0 - { - FILE *f = fopen("q_used.stt", "a"); - fprintf(f, "%5d : Y%f7.3:U%f7.3:V%f7.3:F%f7.3:S%7.3f\n", - cpi->common.current_video_frame, y2, u2, v2, - frame_psnr2, frame_ssim2); - fclose(f); - } -#endif - } - } - if (cpi->b_calculate_blockiness) { -#if CONFIG_VP9_HIGHBITDEPTH - if (!cm->use_highbitdepth) -#endif - { - double frame_blockiness = vp10_get_blockiness( - orig->y_buffer, orig->y_stride, recon->y_buffer, recon->y_stride, - orig->y_width, orig->y_height); - cpi->worst_blockiness = - VPXMAX(cpi->worst_blockiness, frame_blockiness); - cpi->total_blockiness += frame_blockiness; - } - } - - if (cpi->b_calculate_consistency) { -#if CONFIG_VP9_HIGHBITDEPTH - if (!cm->use_highbitdepth) -#endif - { - double this_inconsistency = vpx_get_ssim_metrics( - orig->y_buffer, orig->y_stride, recon->y_buffer, recon->y_stride, - orig->y_width, orig->y_height, cpi->ssim_vars, &cpi->metrics, 1); - - const double peak = (double)((1 << cpi->oxcf.input_bit_depth) - 1); - double consistency = vpx_sse_to_psnr(samples, peak, - (double)cpi->total_inconsistency); - if (consistency > 0.0) - cpi->worst_consistency = - VPXMIN(cpi->worst_consistency, consistency); - cpi->total_inconsistency += this_inconsistency; - } - } - - { - double y, u, v, frame_all; - frame_all = vpx_calc_fastssim(orig, recon, &y, &u, &v, bit_depth); - adjust_image_stat(y, u, v, frame_all, &cpi->fastssim); - frame_all = vpx_psnrhvs(orig, recon, &y, &u, &v, bit_depth); - adjust_image_stat(y, u, v, frame_all, &cpi->psnrhvs); - } - } } #endif - vpx_clear_system_state(); return 0; } diff --git a/vp10/encoder/encoder.h b/vp10/encoder/encoder.h index f7c601339..8faf4eded 100644 --- a/vp10/encoder/encoder.h +++ b/vp10/encoder/encoder.h @@ -421,18 +421,12 @@ typedef struct VP10_COMP { uint64_t total_samples; ImageStat psnr; - uint64_t totalp_sq_error; - uint64_t totalp_samples; - ImageStat psnrp; - double total_blockiness; double worst_blockiness; int bytes; double summed_quality; double summed_weights; - double summedp_quality; - double summedp_weights; unsigned int tot_recode_hits; double worst_ssim; @@ -440,7 +434,6 @@ typedef struct VP10_COMP { ImageStat psnrhvs; int b_calculate_blockiness; - int b_calculate_consistency; double total_inconsistency; diff --git a/vpx_dsp/fastssim.c b/vpx_dsp/fastssim.c index ad1fe5e71..e3746f080 100644 --- a/vpx_dsp/fastssim.c +++ b/vpx_dsp/fastssim.c @@ -138,9 +138,10 @@ static void fs_downsample_level(fs_ctx *_ctx, int _l) { } } -static void fs_downsample_level0(fs_ctx *_ctx, const unsigned char *_src1, - int _s1ystride, const unsigned char *_src2, - int _s2ystride, int _w, int _h) { +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) { uint32_t *dst1; uint32_t *dst2; int w; @@ -161,44 +162,23 @@ static void fs_downsample_level0(fs_ctx *_ctx, const unsigned char *_src1, int i1; i0 = 2 * i; i1 = FS_MINI(i0 + 1, _w); - dst1[j * w + i] = _src1[j0 * _s1ystride + i0] - + _src1[j0 * _s1ystride + i1] + _src1[j1 * _s1ystride + i0] - + _src1[j1 * _s1ystride + i1]; - dst2[j * w + i] = _src2[j0 * _s2ystride + i0] - + _src2[j0 * _s2ystride + i1] + _src2[j1 * _s2ystride + i0] - + _src2[j1 * _s2ystride + i1]; - } - } -} -static void hbd_fs_downsample_level0(fs_ctx *_ctx, const uint16_t *_src1, - int _s1ystride, const uint16_t *_src2, - int _s2ystride, int _w, int _h) { - uint32_t *dst1; - uint32_t *dst2; - int w; - int h; - int i; - int j; - w = _ctx->level[0].w; - h = _ctx->level[0].h; - dst1 = _ctx->level[0].im1; - dst2 = _ctx->level[0].im2; - for (j = 0; j < h; j++) { - int j0; - int j1; - j0 = 2 * j; - j1 = FS_MINI(j0 + 1, _h); - for (i = 0; i < w; i++) { - int i0; - int i1; - i0 = 2 * i; - i1 = FS_MINI(i0 + 1, _w); - dst1[j * w + i] = _src1[j0 * _s1ystride + i0] - + _src1[j0 * _s1ystride + i1] + _src1[j1 * _s1ystride + i0] - + _src1[j1 * _s1ystride + i1]; - dst2[j * w + i] = _src2[j0 * _s2ystride + i0] - + _src2[j0 * _s2ystride + i1] + _src2[j1 * _s2ystride + i0] - + _src2[j1 * _s2ystride + i1]; + if (bit_depth == 8) { + dst1[j * w + i] = _src1[j0 * _s1ystride + i0] + + _src1[j0 * _s1ystride + i1] + _src1[j1 * _s1ystride + i0] + + _src1[j1 * _s1ystride + i1]; + dst2[j * w + i] = _src2[j0 * _s2ystride + i0] + + _src2[j0 * _s2ystride + i1] + _src2[j1 * _s2ystride + i0] + + _src2[j1 * _s2ystride + i1]; + } 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]; + } } } } @@ -485,39 +465,16 @@ static double convert_ssim_db(double _ssim, double _weight) { return 10 * (log10(_weight) - log10(_weight - _ssim)); } -static double calc_ssim(const unsigned char *_src, int _systride, - const unsigned char *_dst, int _dystride, int _w, int _h) { +static double calc_ssim(const uint8_t *_src, int _systride, + const uint8_t *_dst, int _dystride, + int _w, int _h, uint32_t bit_depth) { 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); - for (l = 0; l < FS_NLEVELS - 1; l++) { - fs_calc_structure(&ctx, l, 8); - ret *= fs_average(&ctx, l); - fs_downsample_level(&ctx, l + 1); - } - fs_calc_structure(&ctx, l, 8); - fs_apply_luminance(&ctx, l, 8); - ret *= fs_average(&ctx, l); - fs_ctx_clear(&ctx); - return ret; -} - - -static double calc_hbd_ssim(const uint8_t *_src, int _systride, - const uint8_t *_dst, int _dystride, - int _w, int _h, uint32_t bit_depth) { - fs_ctx ctx; - double ret; - int l; - ret = 1; - fs_ctx_init(&ctx, _w, _h, FS_NLEVELS); - hbd_fs_downsample_level0(&ctx, - CONVERT_TO_SHORTPTR(_src), _systride, - CONVERT_TO_SHORTPTR(_dst), _dystride, - _w, _h); + fs_downsample_level0(&ctx, _src, _systride, _dst, _dystride, + _w, _h, bit_depth); for (l = 0; l < FS_NLEVELS - 1; l++) { fs_calc_structure(&ctx, l, bit_depth); ret *= fs_average(&ctx, l); @@ -536,31 +493,15 @@ double vpx_calc_fastssim(const YV12_BUFFER_CONFIG *source, uint32_t bit_depth) { double ssimv; vpx_clear_system_state(); - - if (bit_depth == 8) { - *ssim_y = calc_ssim(source->y_buffer, source->y_stride, dest->y_buffer, - dest->y_stride, source->y_crop_width, - source->y_crop_height); - *ssim_u = calc_ssim(source->u_buffer, source->uv_stride, dest->u_buffer, - dest->uv_stride, source->uv_crop_width, - source->uv_crop_height); - *ssim_v = calc_ssim(source->v_buffer, source->uv_stride, dest->v_buffer, - dest->uv_stride, source->uv_crop_width, - source->uv_crop_height); - } else if (bit_depth == 10 || bit_depth == 12) { - *ssim_y = calc_hbd_ssim(source->y_buffer, source->y_stride, dest->y_buffer, - dest->y_stride, source->y_crop_width, - source->y_crop_height, bit_depth); - *ssim_u = calc_hbd_ssim(source->u_buffer, source->uv_stride, dest->u_buffer, - dest->uv_stride, source->uv_crop_width, - source->uv_crop_height, bit_depth); - *ssim_v = calc_hbd_ssim(source->v_buffer, source->uv_stride, dest->v_buffer, - dest->uv_stride, source->uv_crop_width, - source->uv_crop_height, bit_depth); - - } else { - assert(0); - } + *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); + *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); + *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); ssimv = (*ssim_y) * .8 + .1 * ((*ssim_u) + (*ssim_v)); return convert_ssim_db(ssimv, 1.0);