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;
4 * cpi->common.mi_rows * cpi->common.mi_cols);
cpi->worst_consistency = 100.0;
}
-
#endif
cpi->first_time_stamp_ever = INT64_MAX;
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"
"%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,
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");
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,
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;
}
}
}
-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;
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];
+ }
}
}
}
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);
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);