Fix bug in using first pass stats in second pass
active_h_edge() and active_v_edge() use first pass stats to decide whether
or not this block is within the inactive region. There are bugs in the code.
1. frame_stats_arr stats buffer is only used in the first pass, and is invalid
in the second pass. Should get stats from twopass->stats_in.
2. mi size is 4x4 in AV1, need to modify the code accordingly.
Ran AWCY tests before/after the CL. Saw no quality difference except 1 clip:
kirland360p_60f.y4m, which got a small gain.
PSNR PSNR HVS SSIM CIEDE2000 PSNR Cb PSNR Cr MS SSIM VMAF
-0.09 -0.18 -0.04 -0.14 -0.34 0.24 -0.01 -0.91
STATS_CHANGED
BUG=aomedia:2480
Change-Id: I91de86e0fcc69a057bded92f5f6a67771274f244
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 7188d45..d3d6a00 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -2155,6 +2155,14 @@
}
#if !CONFIG_REALTIME_ONLY
+static const FIRSTPASS_STATS *read_one_frame_stats(const TWO_PASS *p, int frm) {
+ assert(frm >= 0);
+ if (frm < 0 || p->stats_in_start + frm > p->stats_in_end) {
+ return NULL;
+ }
+
+ return &p->stats_in_start[frm];
+}
// Checks to see if a super block is on a horizontal image edge.
// In most cases this is the "real" edge unless there are formatting
// bars embedded in the stream.
@@ -2165,15 +2173,16 @@
// For two pass account for any formatting bars detected.
if (cpi->oxcf.pass == 2) {
- const TWO_PASS *const twopass = &cpi->twopass;
- const FIRSTPASS_STATS *const this_frame_stats =
- twopass->frame_stats_arr + twopass->frame_stats_next_idx;
+ const AV1_COMMON *const cm = &cpi->common;
+ const FIRSTPASS_STATS *const this_frame_stats = read_one_frame_stats(
+ &cpi->twopass, cm->current_frame.display_order_hint);
+ if (this_frame_stats == NULL) return AOM_CODEC_ERROR;
// The inactive region is specified in MBs not mi units.
// The image edge is in the following MB row.
- top_edge += (int)(this_frame_stats->inactive_zone_rows * 2);
+ top_edge += (int)(this_frame_stats->inactive_zone_rows * 4);
- bottom_edge -= (int)(this_frame_stats->inactive_zone_rows * 2);
+ bottom_edge -= (int)(this_frame_stats->inactive_zone_rows * 4);
bottom_edge = AOMMAX(top_edge, bottom_edge);
}
@@ -2194,15 +2203,16 @@
// For two pass account for any formatting bars detected.
if (cpi->oxcf.pass == 2) {
- const TWO_PASS *const twopass = &cpi->twopass;
- const FIRSTPASS_STATS *const this_frame_stats =
- twopass->frame_stats_arr + twopass->frame_stats_next_idx;
+ const AV1_COMMON *const cm = &cpi->common;
+ const FIRSTPASS_STATS *const this_frame_stats = read_one_frame_stats(
+ &cpi->twopass, cm->current_frame.display_order_hint);
+ if (this_frame_stats == NULL) return AOM_CODEC_ERROR;
// The inactive region is specified in MBs not mi units.
// The image edge is in the following MB row.
- left_edge += (int)(this_frame_stats->inactive_zone_cols * 2);
+ left_edge += (int)(this_frame_stats->inactive_zone_cols * 4);
- right_edge -= (int)(this_frame_stats->inactive_zone_cols * 2);
+ right_edge -= (int)(this_frame_stats->inactive_zone_cols * 4);
right_edge = AOMMAX(left_edge, right_edge);
}