]> granicus.if.org Git - libvpx/commitdiff
Refactor internal stats code
authorYaowu Xu <yaowu@google.com>
Fri, 5 Feb 2016 23:41:32 +0000 (15:41 -0800)
committerYaowu Xu <yaowu@google.com>
Fri, 12 Feb 2016 15:31:29 +0000 (07:31 -0800)
Also removed the use of postprocessing in computing internal stats.

Change-Id: Ib8fdbdfe7b7ca05cd1a034a373aa7762fa44323c

vp10/encoder/encoder.c
vp10/encoder/encoder.h
vpx_dsp/fastssim.c

index 5165e9af1c01021aad08f4d8e9663c93d562aaca..80bf47cc948fa92183f59eceeebdfa44eeadff0e 100644 (file)
@@ -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;
 }
index f7c60133973d7074e2c67c53f82b92622d7cafeb..8faf4ededf1e1f879d391ce024d756004bc7116f 100644 (file)
@@ -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;
index ad1fe5e712c2c89314046cb9858f9948ca7cfc74..e3746f080366b86c63588be618de8f9cd9c789ce 100644 (file)
@@ -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);