Support two scanning passes for rd_pick_partition.
Reset xd->mi and x->mbmi_ext for the superblock after the first
scanning pass.
Change-Id: Iae9142ff2b1a2b576f54dc545b58fe37c97cecac
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index f69e32b..159e18c 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -33,7 +33,7 @@
#define ACCT_STR __func__
-#define COMPOUND_SINGLEREF_DEBUG 0
+#define DEC_MISMATCH_DEBUG 0
#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
static INLINE int read_uniform(aom_reader *r, int n) {
@@ -1937,6 +1937,64 @@
mi_row << pbi->common.mib_size_log2);
}
+#if DEC_MISMATCH_DEBUG
+static void dec_dump_logs(AV1_COMMON *cm, MODE_INFO *const mi,
+ MACROBLOCKD *const xd, int mi_row, int mi_col) {
+ int_mv mv[2] = { { 0 } };
+ int ref;
+ MB_MODE_INFO *const mbmi = &mi->mbmi;
+ int16_t inter_mode_ctx[MODE_CTX_REF_FRAMES];
+ int16_t mode_ctx = 0;
+ for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref)
+ mv[ref].as_mv = mbmi->mv[ref].as_mv;
+
+ int interp_ctx[2] = { -1 };
+ int interp_filter[2] = { cm->interp_filter };
+ if (cm->interp_filter == SWITCHABLE) {
+ int dir;
+ for (dir = 0; dir < 2; ++dir) {
+ if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
+ (mbmi->ref_frame[1] > INTRA_FRAME &&
+ has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
+ interp_ctx[dir] = av1_get_pred_context_switchable_interp(xd, dir);
+ interp_filter[dir] = mbmi->interp_filter[dir];
+ } else {
+ interp_filter[dir] = EIGHTTAP_REGULAR;
+ }
+ }
+ }
+
+ const int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK;
+ int16_t zeromv_ctx = -1;
+ int16_t refmv_ctx = -1;
+ if (mbmi->mode != NEWMV) {
+ if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) assert(mbmi->mode == ZEROMV);
+ zeromv_ctx = (mode_ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
+ if (mbmi->mode != ZEROMV) {
+ refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
+ if (mode_ctx & (1 << SKIP_NEARESTMV_OFFSET)) refmv_ctx = 6;
+ if (mode_ctx & (1 << SKIP_NEARMV_OFFSET)) refmv_ctx = 7;
+ if (mode_ctx & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) refmv_ctx = 8;
+ }
+ }
+
+ int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
+ printf(
+ "=== DECODER ===: "
+ "Frame=%d, (mi_row,mi_col)=(%d,%d), mode=%d, bsize=%d, "
+ "show_frame=%d, mv[0]=(%d,%d), mv[1]=(%d,%d), ref[0]=%d, "
+ "ref[1]=%d, motion_mode=%d, inter_mode_ctx=%d, mode_ctx=%d, "
+ "interp_ctx=(%d,%d), interp_filter=(%d,%d), newmv_ctx=%d, "
+ "zeromv_ctx=%d, refmv_ctx=%d\n",
+ cm->current_video_frame, mi_row, mi_col, mbmi->mode, mbmi->sb_type,
+ cm->show_frame, mv[0].as_mv.row, mv[0].as_mv.col, mv[1].as_mv.row,
+ mv[1].as_mv.col, mbmi->ref_frame[0], mbmi->ref_frame[1],
+ mbmi->motion_mode, inter_mode_ctx[ref_frame_type], mode_ctx,
+ interp_ctx[0], interp_ctx[1], interp_filter[0], interp_filter[1],
+ newmv_ctx, zeromv_ctx, refmv_ctx);
+}
+#endif // DEC_MISMATCH_DEBUG
+
static void read_inter_block_mode_info(AV1Decoder *const pbi,
MACROBLOCKD *const xd,
MODE_INFO *const mi,
@@ -2482,38 +2540,10 @@
read_mb_interp_filter(cm, xd, mbmi, r);
#endif // CONFIG_DUAL_FILTER || CONFIG_WARPED_MOTION
-#if CONFIG_EXT_INTER
-#if COMPOUND_SINGLEREF_DEBUG
-// NOTE(zoeliu): For debug
-#define FRAME_TO_CHECK 1
- if (cm->current_video_frame == FRAME_TO_CHECK &&
- ((cm->reference_mode != SINGLE_REFERENCE && cm->show_frame == 0) ||
- cm->show_frame == 1)) {
- const PREDICTION_MODE mode = mbmi->mode;
-
- int_mv mv[2];
-#if CONFIG_COMPOUND_SINGLEREF
- int is_comp_pred =
- has_second_ref(mbmi) || is_inter_singleref_comp_mode(mbmi->mode);
-#else
- int is_comp_pred = has_second_ref(mbmi);
-#endif // CONFIG_COMPOUND_SINGLEREF
-
- mv[0].as_int = mbmi->mv[0].as_int;
- mv[1].as_int = is_comp_pred ? mbmi->mv[1].as_int : 0;
-
- printf(
- "=== DECODER ===: "
- "Frame=%d, (mi_row,mi_col)=(%d,%d), mode=%d, bsize=%d, "
- "show_frame=%d, mv[0]=(%d,%d), mv[1]=(%d,%d), ref[0]=%d, ref[1]=%d, "
- "motion_mode=%d\n",
- cm->current_video_frame, mi_row, mi_col, mode, bsize, cm->show_frame,
- mv[0].as_mv.row, mv[0].as_mv.col, mv[1].as_mv.row, mv[1].as_mv.col,
- mbmi->ref_frame[0], mbmi->ref_frame[1], mbmi->motion_mode);
- }
-#endif // COMPOUND_SINGLEREF_DEBUG
-#undef COMPOUND_SINGLEREF_DEBUG
-#endif // CONFIG_EXT_INTER
+#if DEC_MISMATCH_DEBUG
+ // NOTE(zoeliu): For debug
+ dec_dump_logs(cm, mi, xd, mi_row, mi_col);
+#endif // DEC_MISMATCH_DEBUG
}
static void read_inter_frame_mode_info(AV1Decoder *const pbi,
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 99fc32a..b449fab 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -61,7 +61,7 @@
#include "av1/encoder/pvq_encoder.h"
#endif
-#define COMPOUND_SINGLEREF_DEBUG 0
+#define ENC_MISMATCH_DEBUG 0
static struct av1_token intra_mode_encodings[INTRA_MODES];
static struct av1_token switchable_interp_encodings[SWITCHABLE_FILTERS];
@@ -2005,6 +2005,7 @@
mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
else
#endif // CONFIG_EXT_INTER
+
mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
mbmi->ref_frame, bsize, -1);
@@ -2448,6 +2449,93 @@
}
#endif
+#if ENC_MISMATCH_DEBUG
+static void enc_dump_logs(AV1_COMP *cpi, int mi_row, int mi_col) {
+ AV1_COMMON *const cm = &cpi->common;
+ MACROBLOCKD *const xd = &cpi->td.mb.e_mbd;
+ MODE_INFO *m;
+ xd->mi = cm->mi_grid_visible + (mi_row * cm->mi_stride + mi_col);
+ m = xd->mi[0];
+ if (is_inter_block(&m->mbmi)) {
+#define FRAME_TO_CHECK 1
+ if (cm->current_video_frame == FRAME_TO_CHECK && cm->show_frame == 0) {
+ const MB_MODE_INFO *const mbmi = &m->mbmi;
+ const BLOCK_SIZE bsize = mbmi->sb_type;
+
+ int_mv mv[2];
+ int is_comp_ref = has_second_ref(&m->mbmi);
+ int ref;
+
+ for (ref = 0; ref < 1 + is_comp_ref; ++ref)
+ mv[ref].as_mv = m->mbmi.mv[ref].as_mv;
+
+ if (!is_comp_ref) {
+#if CONFIG_COMPOUND_SINGLEREF
+ if (is_inter_singleref_comp_mode(m->mbmi.mode))
+ mv[1].as_mv = m->mbmi.mv[1].as_mv;
+ else
+#endif // CONFIG_COMPOUND_SINGLEREF
+ mv[1].as_int = 0;
+ }
+ int interp_ctx[2] = { -1 };
+ int interp_filter[2] = { cm->interp_filter };
+ if (cm->interp_filter == SWITCHABLE) {
+ int dir;
+ for (dir = 0; dir < 2; ++dir) {
+ if (has_subpel_mv_component(xd->mi[0], xd, dir) ||
+ (mbmi->ref_frame[1] > INTRA_FRAME &&
+ has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
+ interp_ctx[dir] = av1_get_pred_context_switchable_interp(xd, dir);
+ interp_filter[dir] = mbmi->interp_filter[dir];
+ } else {
+ interp_filter[dir] = EIGHTTAP_REGULAR;
+ }
+ }
+ }
+
+#if CONFIG_DELTA_Q || CONFIG_EC_ADAPT
+ MACROBLOCK *const x = &cpi->td.mb;
+#else
+ const MACROBLOCK *x = &cpi->td.mb;
+#endif
+ const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
+ const int16_t mode_ctx = av1_mode_context_analyzer(
+ mbmi_ext->mode_context, mbmi->ref_frame, bsize, -1);
+ const int16_t newmv_ctx = mode_ctx & NEWMV_CTX_MASK;
+ int16_t zeromv_ctx = -1;
+ int16_t refmv_ctx = -1;
+ if (mbmi->mode != NEWMV) {
+ zeromv_ctx = (mode_ctx >> ZEROMV_OFFSET) & ZEROMV_CTX_MASK;
+ if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET)) {
+ assert(mbmi->mode == ZEROMV);
+ }
+ if (mbmi->mode != ZEROMV) {
+ refmv_ctx = (mode_ctx >> REFMV_OFFSET) & REFMV_CTX_MASK;
+ if (mode_ctx & (1 << SKIP_NEARESTMV_OFFSET)) refmv_ctx = 6;
+ if (mode_ctx & (1 << SKIP_NEARMV_OFFSET)) refmv_ctx = 7;
+ if (mode_ctx & (1 << SKIP_NEARESTMV_SUB8X8_OFFSET)) refmv_ctx = 8;
+ }
+ }
+
+ int8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
+ printf(
+ "=== ENCODER ===: "
+ "Frame=%d, (mi_row,mi_col)=(%d,%d), mode=%d, bsize=%d, "
+ "show_frame=%d, mv[0]=(%d,%d), mv[1]=(%d,%d), ref[0]=%d, "
+ "ref[1]=%d, motion_mode=%d, inter_mode_ctx=%d, mode_ctx=%d, "
+ "interp_ctx=(%d,%d), interp_filter=(%d,%d), newmv_ctx=%d, "
+ "zeromv_ctx=%d, refmv_ctx=%d\n",
+ cm->current_video_frame, mi_row, mi_col, mbmi->mode, bsize,
+ cm->show_frame, mv[0].as_mv.row, mv[0].as_mv.col, mv[1].as_mv.row,
+ mv[1].as_mv.col, mbmi->ref_frame[0], mbmi->ref_frame[1],
+ mbmi->motion_mode, mbmi_ext->mode_context[ref_frame_type], mode_ctx,
+ interp_ctx[0], interp_ctx[1], interp_filter[0], interp_filter[1],
+ newmv_ctx, zeromv_ctx, refmv_ctx);
+ }
+ }
+}
+#endif // ENC_MISMATCH_DEBUG
+
static void write_mbmi_b(AV1_COMP *cpi, const TileInfo *const tile,
aom_writer *w,
#if CONFIG_SUPERTX
@@ -2498,47 +2586,11 @@
#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
#endif // CONFIG_DUAL_FILTER
-#if CONFIG_EXT_INTER
-#if COMPOUND_SINGLEREF_DEBUG
+#if ENC_MISMATCH_DEBUG
// NOTE(zoeliu): For debug
- if (is_inter_block(&m->mbmi)) {
-#define FRAME_TO_CHECK 1
- if (cm->current_video_frame == FRAME_TO_CHECK &&
- ((cm->reference_mode != SINGLE_REFERENCE && cm->show_frame == 0) ||
- cm->show_frame == 1)) {
- const MB_MODE_INFO *const mbmi = &m->mbmi;
- const BLOCK_SIZE bsize = mbmi->sb_type;
+ enc_dump_logs(cpi, mi_row, mi_col);
+#endif // ENC_MISMATCH_DEBUG
- int_mv mv[2];
- int is_comp_ref = has_second_ref(&m->mbmi);
- int ref;
-
- for (ref = 0; ref < 1 + is_comp_ref; ++ref)
- mv[ref].as_mv = m->mbmi.mv[ref].as_mv;
-
- if (!is_comp_ref) {
-#if CONFIG_COMPOUND_SINGLEREF
- if (is_inter_singleref_comp_mode(m->mbmi.mode))
- mv[1].as_mv = m->mbmi.mv[1].as_mv;
- else
-#endif // CONFIG_COMPOUND_SINGLEREF
- mv[1].as_int = 0;
- }
-
- printf(
- "=== ENCODER ===: "
- "Frame=%d, (mi_row,mi_col)=(%d,%d), mode=%d, bsize=%d, "
- "show_frame=%d, mv[0]=(%d,%d), mv[1]=(%d,%d), ref[0]=%d, "
- "ref[1]=%d, motion_mode=%d\n",
- cm->current_video_frame, mi_row, mi_col, mbmi->mode, bsize,
- cm->show_frame, mv[0].as_mv.row, mv[0].as_mv.col, mv[1].as_mv.row,
- mv[1].as_mv.col, mbmi->ref_frame[0], mbmi->ref_frame[1],
- mbmi->motion_mode);
- }
- }
-#endif // COMPOUND_SINGLEREF_DEBUG
-#undef COMPOUND_SINGLEREF_DEBUG
-#endif // CONFIG_EXT_INTER
pack_inter_mode_mvs(cpi, mi_row, mi_col,
#if CONFIG_SUPERTX
supertx_enabled,
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 070cea2..ddecf49 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -648,7 +648,6 @@
#if CONFIG_PALETTE
for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
#endif // CONFIG_PALETTE
-
// Restore the coding context of the MB to that that was in place
// when the mode was picked for it
for (y = 0; y < mi_height; y++)
@@ -827,7 +826,6 @@
}
mi_addr->mbmi.segment_id_supertx = MAX_SEGMENTS;
}
-
// Restore the coding context of the MB to that that was in place
// when the mode was picked for it
for (y = 0; y < mi_height; y++)
@@ -4177,6 +4175,22 @@
}
}
+#if CONFIG_SPEED_REFS
+static void restore_mi(const AV1_COMP *const cpi, MACROBLOCK *const x,
+ int mi_row, int mi_col) {
+ const AV1_COMMON *cm = &cpi->common;
+ MACROBLOCKD *const xd = &x->e_mbd;
+ set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
+ int x_idx, y;
+ for (y = 0; y < mi_size_high[cm->sb_size]; y++)
+ for (x_idx = 0; x_idx < mi_size_wide[cm->sb_size]; x_idx++)
+ if (mi_col + x_idx < cm->mi_cols && mi_row + y < cm->mi_rows) {
+ memset(xd->mi + y * cm->mi_stride + x_idx, 0, sizeof(*xd->mi));
+ memset(x->mbmi_ext + y * cm->mi_cols + x_idx, 0, sizeof(*x->mbmi_ext));
+ }
+}
+#endif // CONFIG_SPEED_REFS
+
static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
TileDataEnc *tile_data, int mi_row,
TOKENEXTRA **tp) {
@@ -4326,8 +4340,11 @@
#if CONFIG_SPEED_REFS
// NOTE: Two scanning passes for the current superblock - the first pass
// is only targeted to collect stats.
+ int m_search_count_backup = *(x->m_search_count_ptr);
for (int sb_pass_idx = 0; sb_pass_idx < 2; ++sb_pass_idx) {
cpi->sb_scanning_pass_idx = sb_pass_idx;
+ if (frame_is_intra_only(cm) && sb_pass_idx == 0) continue;
+
rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
&dummy_rdc,
#if CONFIG_SUPERTX
@@ -4337,6 +4354,8 @@
if (sb_pass_idx == 0) {
av1_zero(x->pred_mv);
pc_root->index = 0;
+ restore_mi(cpi, x, mi_row, mi_col);
+ *(x->m_search_count_ptr) = m_search_count_backup;
}
}
#else // !CONFIG_SPEED_REFS