Commit 56586622 authored by Di Chen's avatar Di Chen

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
parent d62e2a3a
......@@ -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 @@ static void fpm_sync(void *const data, int mi_row) {
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 @@ static void read_inter_block_mode_info(AV1Decoder *const pbi,
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,
......
......@@ -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 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const int mi_row,
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 @@ static int rd_token_stats_mismatch(RD_STATS *rd_stats, TOKEN_STATS *token_stats,
}
#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 @@ static void write_mbmi_b(AV1_COMP *cpi, const TileInfo *const tile,
#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;
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;
}
enc_dump_logs(cpi, mi_row, mi_col);
#endif // ENC_MISMATCH_DEBUG
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,
......
......@@ -648,7 +648,6 @@ static void update_state(const AV1_COMP *const cpi, ThreadData *td,
#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 @@ static void update_state_supertx(const AV1_COMP *const cpi, ThreadData *td,
}
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 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
}
}
#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 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
#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 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment