summaryrefslogtreecommitdiffstats
path: root/third_party/aom/av1/encoder/encodeframe.c
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/aom/av1/encoder/encodeframe.c')
-rw-r--r--third_party/aom/av1/encoder/encodeframe.c1852
1 files changed, 1114 insertions, 738 deletions
diff --git a/third_party/aom/av1/encoder/encodeframe.c b/third_party/aom/av1/encoder/encodeframe.c
index d13eb42fb..f79a678fb 100644
--- a/third_party/aom/av1/encoder/encodeframe.c
+++ b/third_party/aom/av1/encoder/encodeframe.c
@@ -81,10 +81,8 @@ static int check_intra_sb(const AV1_COMP *cpi, const TileInfo *const tile,
int mi_row, int mi_col, BLOCK_SIZE bsize,
PC_TREE *pc_tree);
static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
-#if CONFIG_EXT_INTER
- int mi_row_ori, int mi_col_ori,
-#endif // CONFIG_EXT_INTER
- int mi_row_pred, int mi_col_pred, int plane,
+ int mi_row_ori, int mi_col_ori, int mi_row_pred,
+ int mi_col_pred, int plane,
BLOCK_SIZE bsize_pred, int b_sub8x8, int block);
static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
PC_TREE *pc_tree);
@@ -273,6 +271,7 @@ static void set_offsets_without_segment_id(const AV1_COMP *const cpi,
const int mi_height = mi_size_high[bsize];
set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
+
set_skip_context(xd, mi_row, mi_col);
#if CONFIG_VAR_TX
xd->above_txfm_context =
@@ -455,16 +454,17 @@ static void set_segment_id_supertx(const AV1_COMP *const cpi,
#if CONFIG_DUAL_FILTER
static void reset_intmv_filter_type(const AV1_COMMON *const cm, MACROBLOCKD *xd,
MB_MODE_INFO *mbmi) {
- int dir;
- for (dir = 0; dir < 2; ++dir) {
- if (!has_subpel_mv_component(xd->mi[0], xd, dir) &&
- (mbmi->ref_frame[1] == NONE_FRAME ||
- !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
- mbmi->interp_filter[dir] = (cm->interp_filter == SWITCHABLE)
- ? EIGHTTAP_REGULAR
- : cm->interp_filter;
- mbmi->interp_filter[dir + 2] = mbmi->interp_filter[dir];
+ InterpFilter filters[2];
+ InterpFilter default_filter = av1_unswitchable_filter(cm->interp_filter);
+
+ for (int dir = 0; dir < 2; ++dir) {
+ filters[dir] = ((!has_subpel_mv_component(xd->mi[0], xd, dir) &&
+ (mbmi->ref_frame[1] == NONE_FRAME ||
+ !has_subpel_mv_component(xd->mi[0], xd, dir + 2)))
+ ? default_filter
+ : av1_extract_interp_filter(mbmi->interp_filters, dir));
}
+ mbmi->interp_filters = av1_make_interp_filters(filters[0], filters[1]);
}
static void update_filter_type_count(FRAME_COUNTS *counts,
@@ -476,7 +476,11 @@ static void update_filter_type_count(FRAME_COUNTS *counts,
(mbmi->ref_frame[1] > INTRA_FRAME &&
has_subpel_mv_component(xd->mi[0], xd, dir + 2))) {
const int ctx = av1_get_pred_context_switchable_interp(xd, dir);
- ++counts->switchable_interp[ctx][mbmi->interp_filter[dir]];
+ InterpFilter filter =
+ av1_extract_interp_filter(mbmi->interp_filters, dir);
+ ++counts->switchable_interp[ctx][filter];
+ update_cdf(xd->tile_ctx->switchable_interp_cdf[ctx], filter,
+ SWITCHABLE_FILTERS);
}
}
}
@@ -485,11 +489,7 @@ static void update_filter_type_count(FRAME_COUNTS *counts,
static void update_global_motion_used(PREDICTION_MODE mode, BLOCK_SIZE bsize,
const MB_MODE_INFO *mbmi,
RD_COUNTS *rdc) {
- if (mode == ZEROMV
-#if CONFIG_EXT_INTER
- || mode == ZERO_ZEROMV
-#endif
- ) {
+ if (mode == ZEROMV || mode == ZERO_ZEROMV) {
const int num_4x4s =
num_4x4_blocks_wide_lookup[bsize] * num_4x4_blocks_high_lookup[bsize];
int ref;
@@ -521,7 +521,6 @@ static void set_ref_and_pred_mvs(MACROBLOCK *const x, int_mv *const mi_pred_mv,
MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
CANDIDATE_MV *const curr_ref_mv_stack = mbmi_ext->ref_mv_stack[rf_type];
-#if CONFIG_EXT_INTER
if (has_second_ref(mbmi)) {
// Special case: NEAR_NEWMV and NEW_NEARMV modes use 1 + mbmi->ref_mv_idx
// (like NEARMV) instead
@@ -557,7 +556,6 @@ static void set_ref_and_pred_mvs(MACROBLOCK *const x, int_mv *const mi_pred_mv,
}
#endif // CONFIG_COMPOUND_SINGLEREF
} else {
-#endif // CONFIG_EXT_INTER
if (mbmi->mode == NEWMV) {
int i;
for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
@@ -569,9 +567,7 @@ static void set_ref_and_pred_mvs(MACROBLOCK *const x, int_mv *const mi_pred_mv,
mi_pred_mv[i] = this_mv;
}
}
-#if CONFIG_EXT_INTER
}
-#endif // CONFIG_EXT_INTER
}
static void update_state(const AV1_COMP *const cpi, ThreadData *td,
@@ -590,11 +586,6 @@ static void update_state(const AV1_COMP *const cpi, ThreadData *td,
const struct segmentation *const seg = &cm->seg;
const int bw = mi_size_wide[mi->mbmi.sb_type];
const int bh = mi_size_high[mi->mbmi.sb_type];
- const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
- const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
- MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
- int w, h;
-
const int mis = cm->mi_stride;
const int mi_width = mi_size_wide[bsize];
const int mi_height = mi_size_high[bsize];
@@ -649,9 +640,10 @@ static void update_state(const AV1_COMP *const cpi, ThreadData *td,
p[i].txb_entropy_ctx = ctx->txb_entropy_ctx[i];
#endif // CONFIG_LV_MAP
}
-#if CONFIG_PALETTE
for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
-#endif // CONFIG_PALETTE
+#if CONFIG_MRC_TX
+ xd->mrc_mask = ctx->mrc_mask;
+#endif // CONFIG_MRC_TX
// 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++)
@@ -661,7 +653,7 @@ static void update_state(const AV1_COMP *const cpi, ThreadData *td,
xd->mi[x_idx + y * mis] = mi_addr;
}
-#if CONFIG_DELTA_Q && !CONFIG_EXT_DELTA_Q
+#if !CONFIG_EXT_DELTA_Q
if (cpi->oxcf.aq_mode > NO_AQ && cpi->oxcf.aq_mode < DELTA_AQ)
av1_init_plane_quantizers(cpi, x, xd->mi[0]->mbmi.segment_id);
#else
@@ -699,13 +691,11 @@ static void update_state(const AV1_COMP *const cpi, ThreadData *td,
THR_D153_PRED /*D153_PRED*/,
THR_D207_PRED /*D207_PRED*/,
THR_D63_PRED /*D63_PRED*/,
-#if CONFIG_ALT_INTRA
THR_SMOOTH, /*SMOOTH_PRED*/
#if CONFIG_SMOOTH_HV
THR_SMOOTH_V, /*SMOOTH_V_PRED*/
THR_SMOOTH_H, /*SMOOTH_H_PRED*/
#endif // CONFIG_SMOOTH_HV
-#endif // CONFIG_ALT_INTRA
THR_TM /*TM_PRED*/,
};
++mode_chosen_counts[kf_mode_index[mbmi->mode]];
@@ -747,7 +737,9 @@ static void update_state(const AV1_COMP *const cpi, ThreadData *td,
update_filter_type_count(td->counts, xd, mbmi);
#else
const int switchable_ctx = av1_get_pred_context_switchable_interp(xd);
- ++td->counts->switchable_interp[switchable_ctx][mbmi->interp_filter];
+ const InterpFilter filter =
+ av1_extract_interp_filter(mbmi->interp_filters, 0);
+ ++td->counts->switchable_interp[switchable_ctx][filter];
#endif
}
}
@@ -757,16 +749,9 @@ static void update_state(const AV1_COMP *const cpi, ThreadData *td,
rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
}
- for (h = 0; h < y_mis; ++h) {
- MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
- for (w = 0; w < x_mis; ++w) {
- MV_REF *const mv = frame_mv + w;
- mv->ref_frame[0] = mi->mbmi.ref_frame[0];
- mv->ref_frame[1] = mi->mbmi.ref_frame[1];
- mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
- mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
- }
- }
+ const int x_mis = AOMMIN(bw, cm->mi_cols - mi_col);
+ const int y_mis = AOMMIN(bh, cm->mi_rows - mi_row);
+ av1_copy_frame_mvs(cm, mi, mi_row, mi_col, x_mis, y_mis);
}
#if CONFIG_SUPERTX
@@ -788,12 +773,7 @@ static void update_state_supertx(const AV1_COMP *const cpi, ThreadData *td,
const int mis = cm->mi_stride;
const int mi_width = mi_size_wide[bsize];
const int mi_height = mi_size_high[bsize];
- const int x_mis = AOMMIN(mi_width, cm->mi_cols - mi_col);
- const int y_mis = AOMMIN(mi_height, cm->mi_rows - mi_row);
const int unify_bsize = CONFIG_CB4X4;
- MV_REF *const frame_mvs = cm->cur_frame->mvs + mi_row * cm->mi_cols + mi_col;
- int w, h;
-
int8_t rf_type;
*mi_addr = *mi;
@@ -915,16 +895,9 @@ static void update_state_supertx(const AV1_COMP *const cpi, ThreadData *td,
rdc->comp_pred_diff[REFERENCE_MODE_SELECT] += ctx->hybrid_pred_diff;
}
- for (h = 0; h < y_mis; ++h) {
- MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
- for (w = 0; w < x_mis; ++w) {
- MV_REF *const mv = frame_mv + w;
- mv->ref_frame[0] = mi->mbmi.ref_frame[0];
- mv->ref_frame[1] = mi->mbmi.ref_frame[1];
- mv->mv[0].as_int = mi->mbmi.mv[0].as_int;
- mv->mv[1].as_int = mi->mbmi.mv[1].as_int;
- }
- }
+ const int x_mis = AOMMIN(mi_width, cm->mi_cols - mi_col);
+ const int y_mis = AOMMIN(mi_height, cm->mi_rows - mi_row);
+ av1_copy_frame_mvs(cm, mi, mi_row, mi_col, x_mis, y_mis);
}
static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
@@ -1005,6 +978,9 @@ static void update_state_sb_supertx(const AV1_COMP *const cpi, ThreadData *td,
pmc = &pc_tree->split_supertx;
break;
#if CONFIG_EXT_PARTITION_TYPES
+#if CONFIG_EXT_PARTITION_TYPES_AB
+#error HORZ/VERT_A/B partitions not yet updated in superres code
+#endif
case PARTITION_HORZ_A:
set_offsets_supertx(cpi, td, tile, mi_row, mi_col, bsize2);
update_state_supertx(cpi, td, &pc_tree->horizontala[0], mi_row, mi_col,
@@ -1138,6 +1114,9 @@ static void update_supertx_param_sb(const AV1_COMP *const cpi, ThreadData *td,
}
break;
#if CONFIG_EXT_PARTITION_TYPES
+#if CONFIG_EXT_PARTITION_TYPES_AB
+#error HORZ/VERT_A/B partitions not yet updated in superres code
+#endif
case PARTITION_HORZ_A:
for (i = 0; i < 3; i++)
update_supertx_param(td, &pc_tree->horizontala[i], best_tx,
@@ -1162,7 +1141,7 @@ static void update_supertx_param_sb(const AV1_COMP *const cpi, ThreadData *td,
}
#endif // CONFIG_SUPERTX
-#if CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
+#if CONFIG_MOTION_VAR && NC_MODE_INFO
static void set_mode_info_b(const AV1_COMP *const cpi,
const TileInfo *const tile, ThreadData *td,
int mi_row, int mi_col, BLOCK_SIZE bsize,
@@ -1229,6 +1208,9 @@ static void set_mode_info_sb(const AV1_COMP *const cpi, ThreadData *td,
}
break;
#if CONFIG_EXT_PARTITION_TYPES
+#if CONFIG_EXT_PARTITION_TYPES_AB
+#error NC_MODE_INFO+MOTION_VAR not yet supported for new HORZ/VERT_AB partitions
+#endif
case PARTITION_HORZ_A:
set_mode_info_b(cpi, tile, td, mi_row, mi_col, bsize2,
&pc_tree->horizontala[0]);
@@ -1283,7 +1265,60 @@ static void set_mode_info_sb(const AV1_COMP *const cpi, ThreadData *td,
default: assert(0 && "Invalid partition type."); break;
}
}
-#endif
+
+#if CONFIG_NCOBMC_ADAPT_WEIGHT
+static void av1_get_ncobmc_mode_rd(const AV1_COMP *const cpi,
+ MACROBLOCK *const x, MACROBLOCKD *const xd,
+ int bsize, const int mi_row,
+ const int mi_col, NCOBMC_MODE *mode) {
+ const AV1_COMMON *const cm = &cpi->common;
+ const int mi_width = mi_size_wide[bsize];
+ const int mi_height = mi_size_high[bsize];
+
+ assert(bsize >= BLOCK_8X8);
+
+ reset_xd_boundary(xd, mi_row, mi_height, mi_col, mi_width, cm->mi_rows,
+ cm->mi_cols);
+
+ // set up source buffers before calling the mode searching function
+ av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
+
+ *mode = get_ncobmc_mode(cpi, x, xd, mi_row, mi_col, bsize);
+}
+static void get_ncobmc_intrpl_pred(const AV1_COMP *const cpi, ThreadData *td,
+ int mi_row, int mi_col, BLOCK_SIZE bsize) {
+ MACROBLOCK *const x = &td->mb;
+ MACROBLOCKD *const xd = &x->e_mbd;
+ MB_MODE_INFO *const mbmi = &xd->mi[0]->mbmi;
+ const int mi_width = mi_size_wide[bsize];
+ const int mi_height = mi_size_high[bsize];
+ const int hbs = AOMMAX(mi_size_wide[bsize] / 2, mi_size_high[bsize] / 2);
+ const BLOCK_SIZE sqr_blk = bsize_2_sqr_bsize[bsize];
+
+ if (mi_width > mi_height) {
+ // horizontal partition
+ av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
+ &mbmi->ncobmc_mode[0]);
+ xd->mi += hbs;
+ av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col + hbs,
+ &mbmi->ncobmc_mode[1]);
+ } else if (mi_height > mi_width) {
+ // vertical partition
+ av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
+ &mbmi->ncobmc_mode[0]);
+ xd->mi += hbs * xd->mi_stride;
+ av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row + hbs, mi_col,
+ &mbmi->ncobmc_mode[1]);
+ } else {
+ av1_get_ncobmc_mode_rd(cpi, x, xd, sqr_blk, mi_row, mi_col,
+ &mbmi->ncobmc_mode[0]);
+ }
+ // restore the info
+ av1_setup_src_planes(x, cpi->source, mi_row, mi_col);
+ set_mode_info_offsets(cpi, x, xd, mi_row, mi_col);
+}
+#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
+#endif // CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
void av1_setup_src_planes(MACROBLOCK *x, const YV12_BUFFER_CONFIG *src,
int mi_row, int mi_col) {
@@ -1384,10 +1419,6 @@ static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
mbmi->mi_row = mi_row;
mbmi->mi_col = mi_col;
#endif
-#if CONFIG_CFL
- // Don't store luma during RDO. Only store luma when best luma is known
- x->cfl_store_y = 0;
-#endif
#if CONFIG_SUPERTX
// We set tx_size here as skip blocks would otherwise not set it.
// tx_size needs to be set at this point as supertx_enable in
@@ -1413,9 +1444,10 @@ static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
#endif
}
-#if CONFIG_PALETTE
for (i = 0; i < 2; ++i) pd[i].color_index_map = ctx->color_index_map[i];
-#endif // CONFIG_PALETTE
+#if CONFIG_MRC_TX
+ xd->mrc_mask = ctx->mrc_mask;
+#endif // CONFIG_MRC_TX
ctx->skippable = 0;
@@ -1491,6 +1523,9 @@ static void rd_pick_sb_modes(const AV1_COMP *const cpi, TileDataEnc *tile_data,
if ((rd_cost->rate != INT_MAX) && (aq_mode == COMPLEXITY_AQ) &&
(bsize >= BLOCK_16X16) &&
(cm->frame_type == KEY_FRAME || cpi->refresh_alt_ref_frame ||
+#if CONFIG_EXT_REFS
+ cpi->refresh_alt2_ref_frame ||
+#endif // CONFIG_EXT_REFS
(cpi->refresh_golden_frame && !cpi->rc.is_src_frame_alt_ref))) {
av1_caq_select_segment(cpi, x, bsize, mi_row, mi_col, rd_cost->rate);
}
@@ -1542,23 +1577,19 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
int supertx_enabled
#endif
) {
-#if CONFIG_DELTA_Q
MACROBLOCK *x = &td->mb;
MACROBLOCKD *const xd = &x->e_mbd;
-#else
- const MACROBLOCK *x = &td->mb;
- const MACROBLOCKD *const xd = &x->e_mbd;
-#endif
const MODE_INFO *const mi = xd->mi[0];
const MB_MODE_INFO *const mbmi = &mi->mbmi;
const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
const BLOCK_SIZE bsize = mbmi->sb_type;
+ FRAME_CONTEXT *fc = xd->tile_ctx;
-#if CONFIG_DELTA_Q
// delta quant applies to both intra and inter
- const int super_block_upper_left = ((mi_row & 7) == 0) && ((mi_col & 7) == 0);
+ int super_block_upper_left =
+ ((mi_row & MAX_MIB_MASK) == 0) && ((mi_col & MAX_MIB_MASK) == 0);
- if (cm->delta_q_present_flag && (bsize != BLOCK_64X64 || !mbmi->skip) &&
+ if (cm->delta_q_present_flag && (bsize != cm->sb_size || !mbmi->skip) &&
super_block_upper_left) {
const int dq = (mbmi->current_q_index - xd->prev_qindex) / cm->delta_q_res;
const int absdq = abs(dq);
@@ -1569,6 +1600,35 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
if (absdq < DELTA_Q_SMALL) td->counts->delta_q[absdq][0]++;
xd->prev_qindex = mbmi->current_q_index;
#if CONFIG_EXT_DELTA_Q
+#if CONFIG_LOOPFILTER_LEVEL
+ if (cm->delta_lf_present_flag) {
+ if (cm->delta_lf_multi) {
+ for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
+ const int delta_lf =
+ (mbmi->curr_delta_lf[lf_id] - xd->prev_delta_lf[lf_id]) /
+ cm->delta_lf_res;
+ const int abs_delta_lf = abs(delta_lf);
+ for (i = 0; i < AOMMIN(abs_delta_lf, DELTA_LF_SMALL); ++i) {
+ td->counts->delta_lf_multi[lf_id][i][1]++;
+ }
+ if (abs_delta_lf < DELTA_LF_SMALL)
+ td->counts->delta_lf_multi[lf_id][abs_delta_lf][0]++;
+ xd->prev_delta_lf[lf_id] = mbmi->curr_delta_lf[lf_id];
+ }
+ } else {
+ const int delta_lf =
+ (mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
+ cm->delta_lf_res;
+ const int abs_delta_lf = abs(delta_lf);
+ for (i = 0; i < AOMMIN(abs_delta_lf, DELTA_LF_SMALL); ++i) {
+ td->counts->delta_lf[i][1]++;
+ }
+ if (abs_delta_lf < DELTA_LF_SMALL)
+ td->counts->delta_lf[abs_delta_lf][0]++;
+ xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
+ }
+ }
+#else
if (cm->delta_lf_present_flag) {
const int dlf =
(mbmi->current_delta_lf_from_base - xd->prev_delta_lf_from_base) /
@@ -1580,12 +1640,9 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
if (absdlf < DELTA_LF_SMALL) td->counts->delta_lf[absdlf][0]++;
xd->prev_delta_lf_from_base = mbmi->current_delta_lf_from_base;
}
+#endif // CONFIG_LOOPFILTER_LEVEL
#endif
}
-#else
- (void)mi_row;
- (void)mi_col;
-#endif
if (!frame_is_intra_only(cm)) {
FRAME_COUNTS *const counts = td->counts;
RD_COUNTS *rdc = &td->rd_counts;
@@ -1597,6 +1654,10 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
if (!supertx_enabled)
#endif
counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
+#if CONFIG_NEW_MULTISYMBOL
+ update_cdf(fc->intra_inter_cdf[av1_get_intra_inter_context(xd)],
+ inter_block, 2);
+#endif
// If the segment reference feature is enabled we have only a single
// reference frame allowed for the segment so exclude it from
// the reference frame counts used to work out probabilities.
@@ -1613,14 +1674,14 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
else
// This flag is also updated for 4x4 blocks
rdc->single_ref_used_flag = 1;
-#if !SUB8X8_COMP_REF
- if (mbmi->sb_type != BLOCK_4X4)
+ if (is_comp_ref_allowed(mbmi->sb_type)) {
counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
[has_second_ref(mbmi)]++;
-#else
- counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
- [has_second_ref(mbmi)]++;
-#endif
+#if CONFIG_NEW_MULTISYMBOL
+ update_cdf(av1_get_reference_mode_cdf(cm, xd), has_second_ref(mbmi),
+ 2);
+#endif // CONFIG_NEW_MULTISYMBOL
+ }
}
if (has_second_ref(mbmi)) {
@@ -1664,6 +1725,9 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p(cm, xd)][0]
[ref1 == ALTREF_FRAME]++;
+ if (ref1 != ALTREF_FRAME)
+ counts->comp_bwdref[av1_get_pred_context_comp_bwdref_p1(cm, xd)]
+ [1][ref1 == ALTREF2_FRAME]++;
#else // !CONFIG_EXT_REFS
counts->comp_ref[av1_get_pred_context_comp_ref_p(cm, xd)][0]
[ref0 == GOLDEN_FRAME]++;
@@ -1673,12 +1737,16 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
#endif // CONFIG_EXT_COMP_REFS
} else {
#if CONFIG_EXT_REFS
- const int bit = (ref0 == ALTREF_FRAME || ref0 == BWDREF_FRAME);
+ const int bit = (ref0 >= BWDREF_FRAME);
counts->single_ref[av1_get_pred_context_single_ref_p1(xd)][0][bit]++;
if (bit) {
+ assert(ref0 <= ALTREF_FRAME);
counts->single_ref[av1_get_pred_context_single_ref_p2(xd)][1]
- [ref0 != BWDREF_FRAME]++;
+ [ref0 == ALTREF_FRAME]++;
+ if (ref0 != ALTREF_FRAME)
+ counts->single_ref[av1_get_pred_context_single_ref_p6(xd)][5]
+ [ref0 == ALTREF2_FRAME]++;
} else {
const int bit1 = !(ref0 == LAST2_FRAME || ref0 == LAST_FRAME);
counts
@@ -1701,7 +1769,6 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
#endif // CONFIG_EXT_REFS
}
-#if CONFIG_EXT_INTER
#if CONFIG_COMPOUND_SINGLEREF
if (!has_second_ref(mbmi))
counts->comp_inter_mode[av1_get_inter_mode_context(xd)]
@@ -1717,31 +1784,32 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
const int bsize_group = size_group_lookup[bsize];
if (mbmi->ref_frame[1] == INTRA_FRAME) {
counts->interintra[bsize_group][1]++;
+#if CONFIG_NEW_MULTISYMBOL
+ update_cdf(fc->interintra_cdf[bsize_group], 1, 2);
+#endif
counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
- if (is_interintra_wedge_used(bsize))
+ update_cdf(fc->interintra_mode_cdf[bsize_group],
+ mbmi->interintra_mode, INTERINTRA_MODES);
+ if (is_interintra_wedge_used(bsize)) {
counts->wedge_interintra[bsize][mbmi->use_wedge_interintra]++;
+#if CONFIG_NEW_MULTISYMBOL
+ update_cdf(fc->wedge_interintra_cdf[bsize],
+ mbmi->use_wedge_interintra, 2);
+#endif
+ }
} else {
counts->interintra[bsize_group][0]++;
+#if CONFIG_NEW_MULTISYMBOL
+ update_cdf(fc->interintra_cdf[bsize_group], 0, 2);
+#endif
}
}
#endif // CONFIG_INTERINTRA
-#endif // CONFIG_EXT_INTER
#if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_WARPED_MOTION
set_ref_ptrs(cm, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
#endif
-#if CONFIG_NCOBMC_ADAPT_WEIGHT
- const MOTION_MODE motion_allowed =
- motion_mode_allowed_wrapper(0,
-#if CONFIG_GLOBAL_MOTION
- 0, xd->global_motion,
-#endif // CONFIG_GLOBAL_MOTION
-#if CONFIG_WARPED_MOTION
- xd,
-#endif
- mi);
-#else
const MOTION_MODE motion_allowed = motion_mode_allowed(
#if CONFIG_GLOBAL_MOTION
0, xd->global_motion,
@@ -1750,23 +1818,41 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
xd,
#endif
mi);
-#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
#if CONFIG_SUPERTX
if (!supertx_enabled)
#endif // CONFIG_SUPERTX
-#if CONFIG_EXT_INTER
if (mbmi->ref_frame[1] != INTRA_FRAME)
-#endif // CONFIG_EXT_INTER
#if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
{
- if (motion_allowed == WARPED_CAUSAL)
+ if (motion_allowed == WARPED_CAUSAL) {
counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
- else if (motion_allowed == OBMC_CAUSAL)
+ update_cdf(fc->motion_mode_cdf[mbmi->sb_type], mbmi->motion_mode,
+ MOTION_MODES);
+#if CONFIG_NCOBMC_ADAPT_WEIGHT
+ } else if (motion_allowed == NCOBMC_ADAPT_WEIGHT) {
+ counts->ncobmc[mbmi->sb_type][mbmi->motion_mode]++;
+ update_cdf(fc->ncobmc_cdf[mbmi->sb_type], mbmi->motion_mode,
+ OBMC_FAMILY_MODES);
+ } else if (motion_allowed == OBMC_CAUSAL) {
+ counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
+ update_cdf(fc->obmc_cdf[mbmi->sb_type], mbmi->motion_mode, 2);
+ }
+#else
+ } else if (motion_allowed == OBMC_CAUSAL) {
counts->obmc[mbmi->sb_type][mbmi->motion_mode == OBMC_CAUSAL]++;
+#if CONFIG_NEW_MULTISYMBOL
+ update_cdf(fc->obmc_cdf[mbmi->sb_type],
+ mbmi->motion_mode == OBMC_CAUSAL, 2);
+#endif
+ }
+#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
}
#else
- if (motion_allowed > SIMPLE_TRANSLATION)
- counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
+ if (motion_allowed > SIMPLE_TRANSLATION) {
+ counts->motion_mode[mbmi->sb_type][mbmi->motion_mode]++;
+ update_cdf(fc->motion_mode_cdf[mbmi->sb_type], mbmi->motion_mode,
+ MOTION_MODES);
+ }
#endif // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
#if CONFIG_NCOBMC_ADAPT_WEIGHT
@@ -1774,15 +1860,18 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
ADAPT_OVERLAP_BLOCK ao_block =
adapt_overlap_block_lookup[mbmi->sb_type];
++counts->ncobmc_mode[ao_block][mbmi->ncobmc_mode[0]];
+ update_cdf(fc->ncobmc_mode_cdf[ao_block], mbmi->ncobmc_mode[0],
+ MAX_NCOBMC_MODES);
if (mi_size_wide[mbmi->sb_type] != mi_size_high[mbmi->sb_type]) {
++counts->ncobmc_mode[ao_block][mbmi->ncobmc_mode[1]];
+ update_cdf(fc->ncobmc_mode_cdf[ao_block], mbmi->ncobmc_mode[1],
+ MAX_NCOBMC_MODES);
}
}
#endif
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
-#if CONFIG_EXT_INTER
if (
#if CONFIG_COMPOUND_SINGLEREF
is_inter_anyref_comp_mode(mbmi->mode)
@@ -1794,9 +1883,19 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
&& mbmi->motion_mode == SIMPLE_TRANSLATION
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
) {
- counts->compound_interinter[bsize][mbmi->interinter_compound_type]++;
+#if CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
+#if CONFIG_WEDGE && CONFIG_COMPOUND_SEGMENT
+ if (is_interinter_compound_used(COMPOUND_WEDGE, bsize)) {
+#endif
+ counts
+ ->compound_interinter[bsize][mbmi->interinter_compound_type]++;
+ update_cdf(fc->compound_type_cdf[bsize],
+ mbmi->interinter_compound_type, COMPOUND_TYPES);
+#if CONFIG_WEDGE && CONFIG_COMPOUND_SEGMENT
+ }
+#endif
+#endif // CONFIG_WEDGE || CONFIG_COMPOUND_SEGMENT
}
-#endif // CONFIG_EXT_INTER
}
}
@@ -1804,10 +1903,11 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
!segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
int16_t mode_ctx;
const PREDICTION_MODE mode = mbmi->mode;
-#if CONFIG_EXT_INTER
if (has_second_ref(mbmi)) {
mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
+ update_cdf(fc->inter_compound_mode_cdf[mode_ctx],
+ INTER_COMPOUND_OFFSET(mode), INTER_COMPOUND_MODES);
#if CONFIG_COMPOUND_SINGLEREF
} else if (is_inter_singleref_comp_mode(mode)) {
mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
@@ -1815,24 +1915,17 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
[INTER_SINGLEREF_COMP_OFFSET(mode)];
#endif // CONFIG_COMPOUND_SINGLEREF
} else {
-#endif // CONFIG_EXT_INTER
mode_ctx = av1_mode_context_analyzer(mbmi_ext->mode_context,
mbmi->ref_frame, bsize, -1);
update_inter_mode_stats(counts, mode, mode_ctx);
-#if CONFIG_EXT_INTER
}
-#endif // CONFIG_EXT_INTER
-#if CONFIG_EXT_INTER
+ int mode_allowed = (mbmi->mode == NEWMV);
+ mode_allowed |= (mbmi->mode == NEW_NEWMV);
#if CONFIG_COMPOUND_SINGLEREF
- if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV ||
- mbmi->mode == SR_NEW_NEWMV) {
-#else // !CONFIG_COMPOUND_SINGLEREF
- if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV) {
+ mode_allowed |= (mbmi->mode == SR_NEW_NEWMV);
#endif // CONFIG_COMPOUND_SINGLEREF
-#else // !CONFIG_EXT_INTER
- if (mbmi->mode == NEWMV) {
-#endif // CONFIG_EXT_INTER
+ if (mode_allowed) {
uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
int idx;
@@ -1847,11 +1940,7 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
}
}
-#if CONFIG_EXT_INTER
if (have_nearmv_in_inter_mode(mbmi->mode)) {
-#else
- if (mbmi->mode == NEARMV) {
-#endif
uint8_t ref_frame_type = av1_ref_frame_type(mbmi->ref_frame);
int idx;
@@ -1868,7 +1957,7 @@ static void update_stats(const AV1_COMMON *const cm, ThreadData *td, int mi_row,
}
#if CONFIG_INTRABC
} else {
- if (cm->allow_screen_content_tools && bsize >= BLOCK_8X8) {
+ if (av1_allow_intrabc(bsize, cm)) {
FRAME_COUNTS *const counts = td->counts;
++counts->intrabc[mbmi->use_intrabc];
} else {
@@ -1992,7 +2081,8 @@ static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
#endif
PICK_MODE_CONTEXT *ctx, int *rate) {
MACROBLOCK *const x = &td->mb;
-#if (CONFIG_MOTION_VAR && CONFIG_NCOBMC) | CONFIG_EXT_DELTA_Q
+#if (CONFIG_MOTION_VAR && CONFIG_NCOBMC) | CONFIG_EXT_DELTA_Q | \
+ CONFIG_NCOBMC_ADAPT_WEIGHT
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO *mbmi;
#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
@@ -2005,11 +2095,14 @@ static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
x->e_mbd.mi[0]->mbmi.partition = partition;
#endif
update_state(cpi, td, ctx, mi_row, mi_col, bsize, dry_run);
-#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
+#if CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
mbmi = &xd->mi[0]->mbmi;
#if CONFIG_WARPED_MOTION
set_ref_ptrs(&cpi->common, xd, mbmi->ref_frame[0], mbmi->ref_frame[1]);
#endif
+#endif
+
+#if CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
const MOTION_MODE motion_allowed = motion_mode_allowed(
#if CONFIG_GLOBAL_MOTION
0, xd->global_motion,
@@ -2018,6 +2111,9 @@ static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
xd,
#endif
xd->mi[0]);
+#endif // CONFIG_MOTION_VAR && (CONFIG_NCOBMC || CONFIG_NCOBMC_ADAPT_WEIGHT)
+
+#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
check_ncobmc = is_inter_block(mbmi) && motion_allowed >= OBMC_CAUSAL;
if (!dry_run && check_ncobmc) {
av1_check_ncobmc_rd(cpi, x, mi_row, mi_col);
@@ -2025,13 +2121,38 @@ static void encode_b(const AV1_COMP *const cpi, const TileInfo *const tile,
get_frame_new_buffer(&cpi->common), mi_row, mi_col);
}
#endif
+
+#if CONFIG_LV_MAP
+ av1_set_coeff_buffer(cpi, x, mi_row, mi_col);
+#endif
+
+#if CONFIG_NCOBMC_ADAPT_WEIGHT
+ if (dry_run == OUTPUT_ENABLED && !frame_is_intra_only(&cpi->common)) {
+ if (motion_allowed >= NCOBMC_ADAPT_WEIGHT && is_inter_block(mbmi)) {
+ get_ncobmc_intrpl_pred(cpi, td, mi_row, mi_col, bsize);
+ av1_check_ncobmc_adapt_weight_rd(cpi, x, mi_row, mi_col);
+ }
+ av1_setup_dst_planes(x->e_mbd.plane, bsize,
+ get_frame_new_buffer(&cpi->common), mi_row, mi_col);
+ }
+#endif // CONFIG_NCOBMC_ADAPT_WEIGHT
+
encode_superblock(cpi, td, tp, dry_run, mi_row, mi_col, bsize, rate);
+#if CONFIG_LV_MAP
+ if (dry_run == 0)
+ x->cb_offset += block_size_wide[bsize] * block_size_high[bsize];
+#endif
+
if (!dry_run) {
#if CONFIG_EXT_DELTA_Q
mbmi = &xd->mi[0]->mbmi;
- if (bsize == BLOCK_64X64 && mbmi->skip == 1 && is_inter_block(mbmi) &&
+ if (bsize == cpi->common.sb_size && mbmi->skip == 1 &&
cpi->common.delta_lf_present_flag) {
+#if CONFIG_LOOPFILTER_LEVEL
+ for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
+ mbmi->curr_delta_lf[lf_id] = xd->prev_delta_lf[lf_id];
+#endif // CONFIG_LOOPFILTER_LEVEL
mbmi->current_delta_lf_from_base = xd->prev_delta_lf_from_base;
}
#endif
@@ -2051,6 +2172,9 @@ static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
MACROBLOCK *const x = &td->mb;
MACROBLOCKD *const xd = &x->e_mbd;
const int hbs = mi_size_wide[bsize] / 2;
+#if CONFIG_EXT_PARTITION_TYPES && CONFIG_EXT_PARTITION_TYPES_AB
+ const int qbs = mi_size_wide[bsize] / 4;
+#endif
const int is_partition_root = bsize >= BLOCK_8X8;
const int ctx = is_partition_root
? partition_plane_context(xd, mi_row, mi_col,
@@ -2063,9 +2187,11 @@ static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
const PARTITION_TYPE partition = pc_tree->partitioning;
const BLOCK_SIZE subsize = get_subsize(bsize, partition);
#if CONFIG_EXT_PARTITION_TYPES
- const BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
int quarter_step = mi_size_wide[bsize] / 4;
int i;
+#if !CONFIG_EXT_PARTITION_TYPES_AB
+ BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
+#endif
#endif
#if CONFIG_CB4X4
@@ -2077,11 +2203,6 @@ static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) return;
-#if CONFIG_SPEED_REFS
- // First scanning pass of an SB is dry run only.
- if (cpi->sb_scanning_pass_idx == 0) assert(dry_run == DRY_RUN_NORMAL);
-#endif // CONFIG_SPEED_REFS
-
if (!dry_run && ctx >= 0) td->counts->partition[ctx][partition]++;
#if CONFIG_SUPERTX
@@ -2138,6 +2259,7 @@ static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
td->counts->supertx[partition_supertx_context_lookup[partition]]
[supertx_size][1]++;
td->counts->supertx_size[supertx_size]++;
+#if CONFIG_ENTROPY_STATS
#if CONFIG_EXT_TX
if (get_ext_tx_types(supertx_size, bsize, 1, cm->reduced_tx_set_used) >
1 &&
@@ -2154,6 +2276,7 @@ static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
++td->counts->inter_ext_tx[supertx_size][xd->mi[0]->mbmi.tx_type];
}
#endif // CONFIG_EXT_TX
+#endif // CONFIG_ENTROPY_STATS
}
#if CONFIG_EXT_PARTITION_TYPES
update_ext_partition_context(xd, mi_row, mi_col, subsize, bsize,
@@ -2230,7 +2353,53 @@ static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
subsize, pc_tree->split[3], rate);
}
break;
+
#if CONFIG_EXT_PARTITION_TYPES
+#if CONFIG_EXT_PARTITION_TYPES_AB
+ case PARTITION_HORZ_A:
+ encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run,
+ get_subsize(bsize, PARTITION_HORZ_4), partition,
+ &pc_tree->horizontala[0], rate);
+ encode_b(cpi, tile, td, tp, mi_row + qbs, mi_col, dry_run,
+ get_subsize(bsize, PARTITION_HORZ_4), partition,
+ &pc_tree->horizontala[1], rate);
+ encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run, subsize,
+ partition, &pc_tree->horizontala[2], rate);
+ break;
+ case PARTITION_HORZ_B:
+ encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
+ &pc_tree->horizontalb[0], rate);
+ encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col, dry_run,
+ get_subsize(bsize, PARTITION_HORZ_4), partition,
+ &pc_tree->horizontalb[1], rate);
+ if (mi_row + 3 * qbs < cm->mi_rows)
+ encode_b(cpi, tile, td, tp, mi_row + 3 * qbs, mi_col, dry_run,
+ get_subsize(bsize, PARTITION_HORZ_4), partition,
+ &pc_tree->horizontalb[2], rate);
+ break;
+ case PARTITION_VERT_A:
+ encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run,
+ get_subsize(bsize, PARTITION_VERT_4), partition,
+ &pc_tree->verticala[0], rate);
+ encode_b(cpi, tile, td, tp, mi_row, mi_col + qbs, dry_run,
+ get_subsize(bsize, PARTITION_VERT_4), partition,
+ &pc_tree->verticala[1], rate);
+ encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run, subsize,
+ partition, &pc_tree->verticala[2], rate);
+
+ break;
+ case PARTITION_VERT_B:
+ encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, subsize, partition,
+ &pc_tree->verticalb[0], rate);
+ encode_b(cpi, tile, td, tp, mi_row, mi_col + hbs, dry_run,
+ get_subsize(bsize, PARTITION_VERT_4), partition,
+ &pc_tree->verticalb[1], rate);
+ if (mi_col + 3 * qbs < cm->mi_cols)
+ encode_b(cpi, tile, td, tp, mi_row, mi_col + 3 * qbs, dry_run,
+ get_subsize(bsize, PARTITION_VERT_4), partition,
+ &pc_tree->verticalb[2], rate);
+ break;
+#else
case PARTITION_HORZ_A:
encode_b(cpi, tile, td, tp, mi_row, mi_col, dry_run, bsize2, partition,
&pc_tree->horizontala[0], rate);
@@ -2264,6 +2433,7 @@ static void encode_sb(const AV1_COMP *const cpi, ThreadData *td,
encode_b(cpi, tile, td, tp, mi_row + hbs, mi_col + hbs, dry_run, bsize2,
partition, &pc_tree->verticalb[2], rate);
break;
+#endif
case PARTITION_HORZ_4:
for (i = 0; i < 4; ++i) {
int this_mi_row = mi_row + i * quarter_step;
@@ -2468,10 +2638,10 @@ static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
bsize, ctx_none, INT64_MAX);
if (none_rdc.rate < INT_MAX) {
- none_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
+ none_rdc.rate += x->partition_cost[pl][PARTITION_NONE];
none_rdc.rdcost = RDCOST(x->rdmult, none_rdc.rate, none_rdc.dist);
#if CONFIG_SUPERTX
- none_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
+ none_rate_nocoef += x->partition_cost[pl][PARTITION_NONE];
#endif
}
@@ -2647,11 +2817,11 @@ static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
}
if (last_part_rdc.rate < INT_MAX) {
- last_part_rdc.rate += cpi->partition_cost[pl][partition];
+ last_part_rdc.rate += x->partition_cost[pl][partition];
last_part_rdc.rdcost =
RDCOST(x->rdmult, last_part_rdc.rate, last_part_rdc.dist);
#if CONFIG_SUPERTX
- last_part_rate_nocoef += cpi->partition_cost[pl][partition];
+ last_part_rate_nocoef += x->partition_cost[pl][partition];
#endif
}
@@ -2726,16 +2896,16 @@ static void rd_use_partition(AV1_COMP *cpi, ThreadData *td,
encode_sb(cpi, td, tile_info, tp, mi_row + y_idx, mi_col + x_idx,
OUTPUT_ENABLED, split_subsize, pc_tree->split[i], NULL);
- chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_NONE];
+ chosen_rdc.rate += x->partition_cost[pl][PARTITION_NONE];
#if CONFIG_SUPERTX
- chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_SPLIT];
+ chosen_rate_nocoef += x->partition_cost[pl][PARTITION_SPLIT];
#endif
}
if (chosen_rdc.rate < INT_MAX) {
- chosen_rdc.rate += cpi->partition_cost[pl][PARTITION_SPLIT];
+ chosen_rdc.rate += x->partition_cost[pl][PARTITION_SPLIT];
chosen_rdc.rdcost = RDCOST(x->rdmult, chosen_rdc.rate, chosen_rdc.dist);
#if CONFIG_SUPERTX
- chosen_rate_nocoef += cpi->partition_cost[pl][PARTITION_NONE];
+ chosen_rate_nocoef += x->partition_cost[pl][PARTITION_NONE];
#endif
}
}
@@ -2803,8 +2973,11 @@ static const BLOCK_SIZE min_partition_size[BLOCK_SIZES_ALL] = {
#if CONFIG_EXT_PARTITION
BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, // 64x128, 128x64, 128x128
#endif // CONFIG_EXT_PARTITION
- BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x16, 16x4, 8x32
- BLOCK_8X8 // 32x8
+ BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x16, 16x4, 8x32
+ BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, // 32x8, 16x64, 64x16
+#if CONFIG_EXT_PARTITION
+ BLOCK_16X16, BLOCK_16X16 // 32x128, 128x32
+#endif // CONFIG_EXT_PARTITION
};
static const BLOCK_SIZE max_partition_size[BLOCK_SIZES_ALL] = {
@@ -2820,7 +2993,10 @@ static const BLOCK_SIZE max_partition_size[BLOCK_SIZES_ALL] = {
BLOCK_LARGEST, BLOCK_LARGEST, BLOCK_LARGEST, // 64x128, 128x64, 128x128
#endif // CONFIG_EXT_PARTITION
BLOCK_16X16, BLOCK_16X16, BLOCK_32X32, // 4x16, 16x4, 8x32
- BLOCK_32X32 // 32x8
+ BLOCK_32X32, BLOCK_LARGEST, BLOCK_LARGEST, // 32x8, 16x64, 64x16
+#if CONFIG_EXT_PARTITION
+ BLOCK_LARGEST, BLOCK_LARGEST // 32x128, 128x32
+#endif // CONFIG_EXT_PARTITION
};
// Next square block size less or equal than current block size.
@@ -2837,7 +3013,10 @@ static const BLOCK_SIZE next_square_size[BLOCK_SIZES_ALL] = {
BLOCK_64X64, BLOCK_64X64, BLOCK_128X128, // 64x128, 128x64, 128x128
#endif // CONFIG_EXT_PARTITION
BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, // 4x16, 16x4, 8x32
- BLOCK_8X8 // 32x8
+ BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, // 32x8, 16x64, 64x16
+#if CONFIG_EXT_PARTITION
+ BLOCK_32X32, BLOCK_32X32 // 32x128, 128x32
+#endif // CONFIG_EXT_PARTITION
};
/* clang-format on */
@@ -2953,7 +3132,7 @@ static void set_partition_range(const AV1_COMMON *const cm,
const int idx_str = cm->mi_stride * mi_row + mi_col;
MODE_INFO **const prev_mi = &cm->prev_mi_grid_visible[idx_str];
- BLOCK_SIZE min_size = BLOCK_64X64; // default values
+ BLOCK_SIZE min_size = cm->sb_size; // default values
BLOCK_SIZE max_size = BLOCK_4X4;
if (prev_mi) {
@@ -3004,66 +3183,24 @@ static INLINE void load_pred_mv(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
#if CONFIG_FP_MB_STATS
const int qindex_skip_threshold_lookup[BLOCK_SIZES] = {
- 0,
- 10,
- 10,
- 30,
- 40,
- 40,
- 60,
- 80,
- 80,
- 90,
- 100,
- 100,
- 120,
+ 0, 10, 10, 30, 40, 40, 60, 80, 80, 90, 100, 100, 120,
#if CONFIG_EXT_PARTITION
// TODO(debargha): What are the correct numbers here?
- 130,
- 130,
- 150
+ 130, 130, 150
#endif // CONFIG_EXT_PARTITION
};
const int qindex_split_threshold_lookup[BLOCK_SIZES] = {
- 0,
- 3,
- 3,
- 7,
- 15,
- 15,
- 30,
- 40,
- 40,
- 60,
- 80,
- 80,
- 120,
+ 0, 3, 3, 7, 15, 15, 30, 40, 40, 60, 80, 80, 120,
#if CONFIG_EXT_PARTITION
// TODO(debargha): What are the correct numbers here?
- 160,
- 160,
- 240
+ 160, 160, 240
#endif // CONFIG_EXT_PARTITION
};
const int complexity_16x16_blocks_threshold[BLOCK_SIZES] = {
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 1,
- 4,
- 4,
- 6,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 6,
#if CONFIG_EXT_PARTITION
// TODO(debargha): What are the correct numbers here?
- 8,
- 8,
- 10
+ 8, 8, 10
#endif // CONFIG_EXT_PARTITION
};
@@ -3101,6 +3238,78 @@ static INLINE int get_motion_inconsistency(MOTION_DIRECTION this_mv,
#endif
#if CONFIG_EXT_PARTITION_TYPES
+// Try searching for an encoding for the given subblock. Returns zero if the
+// rdcost is already too high (to tell the caller not to bother searching for
+// encodings of further subblocks)
+static int rd_try_subblock(const AV1_COMP *const cpi, ThreadData *td,
+ TileDataEnc *tile_data, TOKENEXTRA **tp,
+ int is_first, int is_last, int mi_row, int mi_col,
+ BLOCK_SIZE subsize, RD_STATS *best_rdc,
+ RD_STATS *sum_rdc, RD_STATS *this_rdc,
+#if CONFIG_SUPERTX
+ int64_t best_rd, int *sum_rate_nocoef,
+ int *this_rate_nocoef, int *abort_flag,
+#endif
+ PARTITION_TYPE partition,
+ PICK_MODE_CONTEXT *prev_ctx,
+ PICK_MODE_CONTEXT *this_ctx) {
+#if CONFIG_SUPERTX
+#define RTS_X_RATE_NOCOEF_ARG ((is_first) ? sum_rate_nocoef : this_rate_nocoef),
+#define RTS_MAX_RDCOST INT64_MAX
+#else
+#define RTS_X_RATE_NOCOEF_ARG
+#define RTS_MAX_RDCOST best_rdc->rdcost
+#endif
+
+ MACROBLOCK *const x = &td->mb;
+
+ if (cpi->sf.adaptive_motion_search) load_pred_mv(x, prev_ctx);
+
+ // On the first time around, write the rd stats straight to sum_rdc. Also, we
+ // should treat sum_rdc as containing zeros (even if it doesn't) to avoid
+ // having to zero it at the start.
+ if (is_first) this_rdc = sum_rdc;
+ const int64_t spent_rdcost = is_first ? 0 : sum_rdc->rdcost;
+ const int64_t rdcost_remaining = best_rdc->rdcost - spent_rdcost;
+
+ rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, this_rdc,
+ RTS_X_RATE_NOCOEF_ARG partition, subsize, this_ctx,
+ rdcost_remaining);
+
+#if CONFIG_SUPERTX
+ if (is_first) *abort_flag = sum_rdc->rdcost >= best_rd;
+#endif
+
+ if (!is_first) {
+ if (this_rdc->rate == INT_MAX) {
+ sum_rdc->rdcost = INT64_MAX;
+#if CONFIG_SUPERTX
+ *sum_rate_nocoef = INT_MAX;
+#endif
+ } else {
+ sum_rdc->rate += this_rdc->rate;
+ sum_rdc->dist += this_rdc->dist;
+ sum_rdc->rdcost += this_rdc->rdcost;
+#if CONFIG_SUPERTX
+ *sum_rate_nocoef += *this_rate_nocoef;
+#endif
+ }
+ }
+
+ if (sum_rdc->rdcost >= RTS_MAX_RDCOST) return 0;
+
+ if (!is_last) {
+ update_state(cpi, td, this_ctx, mi_row, mi_col, subsize, 1);
+ encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
+ NULL);
+ }
+
+ return 1;
+
+#undef RTS_X_RATE_NOCOEF_ARG
+#undef RTS_MAX_RDCOST
+}
+
static void rd_test_partition3(
const AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data,
TOKENEXTRA **tp, PC_TREE *pc_tree, RD_STATS *best_rdc,
@@ -3113,172 +3322,165 @@ static void rd_test_partition3(
BLOCK_SIZE subsize1, int mi_row2, int mi_col2, BLOCK_SIZE subsize2) {
MACROBLOCK *const x = &td->mb;
MACROBLOCKD *const xd = &x->e_mbd;
- RD_STATS this_rdc, sum_rdc;
-#if CONFIG_SUPERTX
+ RD_STATS sum_rdc, this_rdc;
+#if CONFIG_UNPOISON_PARTITION_CTX
const AV1_COMMON *const cm = &cpi->common;
+ const int hbs = mi_size_wide[bsize] / 2;
+ const int has_rows = mi_row + hbs < cm->mi_rows;
+ const int has_cols = mi_col + hbs < cm->mi_cols;
+#endif // CONFIG_UNPOISON_PARTITION_CTX
+#if CONFIG_SUPERTX || CONFIG_EXT_PARTITION_TYPES_AB
+ const AV1_COMMON *const cm = &cpi->common;
+#endif
+#if CONFIG_SUPERTX
TileInfo *const tile_info = &tile_data->tile_info;
- int this_rate_nocoef, sum_rate_nocoef;
+ int sum_rate_nocoef, this_rate_nocoef;
int abort_flag;
const int supertx_allowed = !frame_is_intra_only(cm) &&
bsize <= MAX_SUPERTX_BLOCK_SIZE &&
!xd->lossless[0];
-#endif
- if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx);
-
- rd_pick_sb_modes(cpi, tile_data, x, mi_row0, mi_col0, &sum_rdc,
-#if CONFIG_SUPERTX
- &sum_rate_nocoef,
-#endif
-#if CONFIG_EXT_PARTITION_TYPES
- partition,
-#endif
- subsize0, &ctxs[0], best_rdc->rdcost);
-#if CONFIG_SUPERTX
- abort_flag = sum_rdc.rdcost >= best_rd;
-#endif
-#if CONFIG_SUPERTX
- if (sum_rdc.rdcost < INT64_MAX) {
+#define RTP_STX_TRY_ARGS \
+ best_rd, &sum_rate_nocoef, &this_rate_nocoef, &abort_flag,
#else
- if (sum_rdc.rdcost < best_rdc->rdcost) {
+#define RTP_STX_TRY_ARGS
#endif
- PICK_MODE_CONTEXT *ctx_0 = &ctxs[0];
- update_state(cpi, td, ctx_0, mi_row0, mi_col0, subsize0, 1);
- encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row0, mi_col0, subsize0,
- NULL);
- if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_0);
+ if (!rd_try_subblock(cpi, td, tile_data, tp, 1, 0, mi_row0, mi_col0, subsize0,
+ best_rdc, &sum_rdc, &this_rdc,
+ RTP_STX_TRY_ARGS partition, ctx, &ctxs[0]))
+ return;
-#if CONFIG_SUPERTX
- rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
- &this_rate_nocoef,
-#if CONFIG_EXT_PARTITION_TYPES
- partition,
-#endif
- subsize1, &ctxs[1], INT64_MAX - sum_rdc.rdcost);
+ if (!rd_try_subblock(cpi, td, tile_data, tp, 0, 0, mi_row1, mi_col1, subsize1,
+ best_rdc, &sum_rdc, &this_rdc,
+ RTP_STX_TRY_ARGS partition, &ctxs[0], &ctxs[1]))
+ return;
+
+// With the new layout of mixed partitions for PARTITION_HORZ_B and
+// PARTITION_VERT_B, the last subblock might start past halfway through the
+// main block, so we might signal it even though the subblock lies strictly
+// outside the image. In that case, we won't spend any bits coding it and the
+// difference (obviously) doesn't contribute to the error.
+#if CONFIG_EXT_PARTITION_TYPES_AB
+ const int try_block2 = mi_row2 < cm->mi_rows && mi_col2 < cm->mi_cols;
#else
- rd_pick_sb_modes(cpi, tile_data, x, mi_row1, mi_col1, &this_rdc,
-#if CONFIG_EXT_PARTITION_TYPES
- partition,
+ const int try_block2 = 1;
#endif
- subsize1, &ctxs[1], best_rdc->rdcost - sum_rdc.rdcost);
-#endif // CONFIG_SUPERTX
+ if (try_block2 &&
+ !rd_try_subblock(cpi, td, tile_data, tp, 0, 1, mi_row2, mi_col2, subsize2,
+ best_rdc, &sum_rdc, &this_rdc,
+ RTP_STX_TRY_ARGS partition, &ctxs[1], &ctxs[2]))
+ return;
- if (this_rdc.rate == INT_MAX) {
- sum_rdc.rdcost = INT64_MAX;
-#if CONFIG_SUPERTX
- sum_rate_nocoef = INT_MAX;
-#endif
- } else {
- sum_rdc.rate += this_rdc.rate;
- sum_rdc.dist += this_rdc.dist;
- sum_rdc.rdcost += this_rdc.rdcost;
#if CONFIG_SUPERTX
- sum_rate_nocoef += this_rate_nocoef;
-#endif
- }
+ if (supertx_allowed && !abort_flag && sum_rdc.rdcost < INT64_MAX) {
+ TX_SIZE supertx_size = max_txsize_lookup[bsize];
+ const PARTITION_TYPE best_partition = pc_tree->partitioning;
+ pc_tree->partitioning = partition;
+ sum_rdc.rate += av1_cost_bit(
+ cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
+ [supertx_size],
+ 0);
+ sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
-#if CONFIG_SUPERTX
- if (sum_rdc.rdcost < INT64_MAX) {
-#else
- if (sum_rdc.rdcost < best_rdc->rdcost) {
-#endif
- PICK_MODE_CONTEXT *ctx_1 = &ctxs[1];
- update_state(cpi, td, ctx_1, mi_row1, mi_col1, subsize1, 1);
- encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row1, mi_col1, subsize1,
- NULL);
+ if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
+ TX_TYPE best_tx = DCT_DCT;
+ RD_STATS tmp_rdc = { sum_rate_nocoef, 0, 0 };
- if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_1);
+ restore_context(x, x_ctx, mi_row, mi_col, bsize);
-#if CONFIG_SUPERTX
- rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
- &this_rate_nocoef,
-#if CONFIG_EXT_PARTITION_TYPES
- partition,
-#endif
- subsize2, &ctxs[2], INT64_MAX - sum_rdc.rdcost);
-#else
- rd_pick_sb_modes(cpi, tile_data, x, mi_row2, mi_col2, &this_rdc,
-#if CONFIG_EXT_PARTITION_TYPES
- partition,
+ rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize, &tmp_rdc.rate,
+ &tmp_rdc.dist, &best_tx, pc_tree);
+
+ tmp_rdc.rate += av1_cost_bit(
+ cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
+ [supertx_size],
+ 1);
+ tmp_rdc.rdcost = RDCOST(x->rdmult, tmp_rdc.rate, tmp_rdc.dist);
+ if (tmp_rdc.rdcost < sum_rdc.rdcost) {
+ sum_rdc = tmp_rdc;
+ update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
+ supertx_size, pc_tree);
+ }
+ }
+
+ pc_tree->partitioning = best_partition;
+ }
#endif
- subsize2, &ctxs[2], best_rdc->rdcost - sum_rdc.rdcost);
-#endif // CONFIG_SUPERTX
- if (this_rdc.rate == INT_MAX) {
- sum_rdc.rdcost = INT64_MAX;
-#if CONFIG_SUPERTX
- sum_rate_nocoef = INT_MAX;
+ if (sum_rdc.rdcost >= best_rdc->rdcost) return;
+
+ int pl = partition_plane_context(xd, mi_row, mi_col,
+#if CONFIG_UNPOISON_PARTITION_CTX
+ has_rows, has_cols,
#endif
- } else {
- sum_rdc.rate += this_rdc.rate;
- sum_rdc.dist += this_rdc.dist;
- sum_rdc.rdcost += this_rdc.rdcost;
+ bsize);
+ sum_rdc.rate += x->partition_cost[pl][partition];
+ sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
#if CONFIG_SUPERTX
- sum_rate_nocoef += this_rate_nocoef;
+ sum_rate_nocoef += x->partition_cost[pl][partition];
#endif
- }
+
+ if (sum_rdc.rdcost >= best_rdc->rdcost) return;
#if CONFIG_SUPERTX
- if (supertx_allowed && !abort_flag && sum_rdc.rdcost < INT64_MAX) {
- TX_SIZE supertx_size = max_txsize_lookup[bsize];
- const PARTITION_TYPE best_partition = pc_tree->partitioning;
- pc_tree->partitioning = partition;
- sum_rdc.rate += av1_cost_bit(
- cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
- [supertx_size],
- 0);
- sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
+ *best_rate_nocoef = sum_rate_nocoef;
+ assert(*best_rate_nocoef >= 0);
+#endif
+ *best_rdc = sum_rdc;
+ pc_tree->partitioning = partition;
- if (!check_intra_sb(cpi, tile_info, mi_row, mi_col, bsize, pc_tree)) {
- TX_TYPE best_tx = DCT_DCT;
- RD_STATS tmp_rdc = { sum_rate_nocoef, 0, 0 };
+#undef RTP_STX_TRY_ARGS
+}
+#endif // CONFIG_EXT_PARTITION_TYPES
- restore_context(x, x_ctx, mi_row, mi_col, bsize);
+#if CONFIG_DIST_8X8 && CONFIG_CB4X4
+static int64_t dist_8x8_yuv(const AV1_COMP *const cpi, MACROBLOCK *const x,
+ uint8_t *y_src_8x8) {
+ MACROBLOCKD *const xd = &x->e_mbd;
+ int64_t dist_8x8, dist_8x8_uv, total_dist;
+ const int src_stride = x->plane[0].src.stride;
+ uint8_t *decoded_8x8;
+ int plane;
- rd_supertx_sb(cpi, td, tile_info, mi_row, mi_col, bsize,
- &tmp_rdc.rate, &tmp_rdc.dist, &best_tx, pc_tree);
+#if CONFIG_HIGHBITDEPTH
+ if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
+ decoded_8x8 = CONVERT_TO_BYTEPTR(x->decoded_8x8);
+ else
+#endif
+ decoded_8x8 = (uint8_t *)x->decoded_8x8;
- tmp_rdc.rate += av1_cost_bit(
- cm->fc->supertx_prob[partition_supertx_context_lookup[partition]]
- [supertx_size],
- 1);
- tmp_rdc.rdcost = RDCOST(x->rdmult, tmp_rdc.rate, tmp_rdc.dist);
- if (tmp_rdc.rdcost < sum_rdc.rdcost) {
- sum_rdc = tmp_rdc;
- update_supertx_param_sb(cpi, td, mi_row, mi_col, bsize, best_tx,
- supertx_size, pc_tree);
- }
- }
+ dist_8x8 = av1_dist_8x8(cpi, x, y_src_8x8, src_stride, decoded_8x8, 8,
+ BLOCK_8X8, 8, 8, 8, 8, x->qindex)
+ << 4;
- pc_tree->partitioning = best_partition;
- }
-#endif // CONFIG_SUPERTX
+ // Compute chroma distortion for a luma 8x8 block
+ dist_8x8_uv = 0;
- if (sum_rdc.rdcost < best_rdc->rdcost) {
- int pl = partition_plane_context(xd, mi_row, mi_col,
-#if CONFIG_UNPOISON_PARTITION_CTX
- has_rows, has_cols,
-#endif
- bsize);
- sum_rdc.rate += cpi->partition_cost[pl][partition];
- sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
-#if CONFIG_SUPERTX
- sum_rate_nocoef += cpi->partition_cost[pl][partition];
-#endif
- if (sum_rdc.rdcost < best_rdc->rdcost) {
-#if CONFIG_SUPERTX
- *best_rate_nocoef = sum_rate_nocoef;
- assert(*best_rate_nocoef >= 0);
+ for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
+ const int src_stride_uv = x->plane[plane].src.stride;
+ const int dst_stride_uv = xd->plane[plane].dst.stride;
+ // uv buff pointers now (i.e. the last sub8x8 block) is the same
+ // to those at the first sub8x8 block because
+ // uv buff pointer is set only once at first sub8x8 block in a 8x8.
+ uint8_t *src_uv = x->plane[plane].src.buf;
+ uint8_t *dst_uv = xd->plane[plane].dst.buf;
+ unsigned sse;
+#if CONFIG_CHROMA_SUB8X8
+ const BLOCK_SIZE plane_bsize =
+ AOMMAX(BLOCK_4X4, get_plane_block_size(BLOCK_8X8, &xd->plane[plane]));
+#else
+ const BLOCK_SIZE plane_bsize =
+ get_plane_block_size(BLOCK_8X8, &xd->plane[plane]);
#endif
- *best_rdc = sum_rdc;
- pc_tree->partitioning = partition;
- }
- }
- }
+ cpi->fn_ptr[plane_bsize].vf(src_uv, src_stride_uv, dst_uv, dst_stride_uv,
+ &sse);
+ dist_8x8_uv += (int64_t)sse << 4;
}
+
+ return total_dist = dist_8x8 + dist_8x8_uv;
}
-#endif // CONFIG_EXT_PARTITION_TYPES
+#endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
// unlikely to be selected depending on previous rate-distortion optimization
@@ -3327,7 +3529,8 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#endif
bsize);
#endif // CONFIG_CB4X4
- const int *partition_cost = cpi->partition_cost[pl];
+ const int *partition_cost =
+ pl >= 0 ? x->partition_cost[pl] : x->partition_cost[0];
#if CONFIG_SUPERTX
int this_rate_nocoef, sum_rate_nocoef = 0, best_rate_nocoef = INT_MAX;
int abort_flag;
@@ -3337,7 +3540,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#endif // CONFIG_SUPERTX
int do_rectangular_split = 1;
-#if CONFIG_EXT_PARTITION_TYPES
+#if CONFIG_EXT_PARTITION_TYPES && !CONFIG_EXT_PARTITION_TYPES_AB
BLOCK_SIZE bsize2 = get_subsize(bsize, PARTITION_SPLIT);
#endif
@@ -3458,9 +3661,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
src_diff_var = get_sby_perpixel_diff_variance(cpi, &x->plane[0].src, mi_row,
mi_col, bsize);
}
-#endif
-#if CONFIG_FP_MB_STATS
// Decide whether we shall split directly and skip searching NONE by using
// the first pass block statistics
if (cpi->use_fp_mb_stats && bsize >= BLOCK_32X32 && do_square_split &&
@@ -3511,17 +3712,6 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
}
#endif
-#if CONFIG_SPEED_REFS
- if (cpi->sb_scanning_pass_idx == 0) {
- // NOTE: For the 1st pass of scanning, check all the subblocks of equal size
- // only.
- partition_none_allowed = (bsize == MIN_SPEED_REFS_BLKSIZE);
- partition_horz_allowed = 0;
- partition_vert_allowed = 0;
- do_square_split = (bsize > MIN_SPEED_REFS_BLKSIZE);
- }
-#endif // CONFIG_SPEED_REFS
-
// PARTITION_NONE
if (partition_none_allowed) {
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc,
@@ -3534,10 +3724,13 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
bsize, ctx_none, best_rdc.rdcost);
if (this_rdc.rate != INT_MAX) {
if (bsize_at_least_8x8) {
- this_rdc.rate += partition_cost[PARTITION_NONE];
+ const int pt_cost = partition_cost[PARTITION_NONE] < INT_MAX
+ ? partition_cost[PARTITION_NONE]
+ : 0;
+ this_rdc.rate += pt_cost;
this_rdc.rdcost = RDCOST(x->rdmult, this_rdc.rate, this_rdc.dist);
#if CONFIG_SUPERTX
- this_rate_nocoef += partition_cost[PARTITION_NONE];
+ this_rate_nocoef += pt_cost;
#endif
}
@@ -3622,11 +3815,22 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#else
restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
#endif
+#if CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
+ if (!x->skip_chroma_rd) {
+ cfl_clear_sub8x8_val(xd->cfl);
+ }
+#endif // CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
}
// store estimated motion vector
if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx_none);
+#if CONFIG_SUPERTX
+ int64_t temp_best_rdcost = INT64_MAX;
+#else
+ int64_t temp_best_rdcost = best_rdc.rdcost;
+#endif
+
// PARTITION_SPLIT
// TODO(jingning): use the motion vectors given by the above search as
// the starting point of motion search in the following partition type check.
@@ -3634,29 +3838,18 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
int reached_last_index = 0;
subsize = get_subsize(bsize, PARTITION_SPLIT);
if (bsize == BLOCK_8X8 && !unify_bsize) {
-#if CONFIG_DUAL_FILTER
if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
pc_tree->leaf_split[0]->pred_interp_filter =
- ctx_none->mic.mbmi.interp_filter[0];
-#else
- if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
- pc_tree->leaf_split[0]->pred_interp_filter =
- ctx_none->mic.mbmi.interp_filter;
-#endif
-#if CONFIG_SUPERTX
+ av1_extract_interp_filter(ctx_none->mic.mbmi.interp_filters, 0);
+
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
+#if CONFIG_SUPERTX
&sum_rate_nocoef,
-#if CONFIG_EXT_PARTITION_TYPES
- PARTITION_SPLIT,
#endif
- subsize, pc_tree->leaf_split[0], INT64_MAX);
-#else
- rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
#if CONFIG_EXT_PARTITION_TYPES
PARTITION_SPLIT,
#endif
- subsize, pc_tree->leaf_split[0], best_rdc.rdcost);
-#endif // CONFIG_SUPERTX
+ subsize, pc_tree->leaf_split[0], temp_best_rdcost);
if (sum_rdc.rate == INT_MAX) {
sum_rdc.rdcost = INT64_MAX;
#if CONFIG_SUPERTX
@@ -3705,11 +3898,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
reached_last_index = 1;
} else {
int idx;
-#if CONFIG_SUPERTX
- for (idx = 0; idx < 4 && sum_rdc.rdcost < INT64_MAX; ++idx) {
-#else
- for (idx = 0; idx < 4 && sum_rdc.rdcost < best_rdc.rdcost; ++idx) {
-#endif // CONFIG_SUPERTX
+ for (idx = 0; idx < 4 && sum_rdc.rdcost < temp_best_rdcost; ++idx) {
const int x_idx = (idx & 1) * mi_step;
const int y_idx = (idx >> 1) * mi_step;
@@ -3719,21 +3908,14 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
pc_tree->split[idx]->index = idx;
-#if CONFIG_SUPERTX
rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx,
- mi_col + x_idx, subsize, &this_rdc, &this_rate_nocoef,
- INT64_MAX - sum_rdc.rdcost, pc_tree->split[idx]);
-#else
- rd_pick_partition(
- cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx, subsize,
- &this_rdc, best_rdc.rdcost - sum_rdc.rdcost, pc_tree->split[idx]);
-#endif // CONFIG_SUPERTX
-
-#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- if (bsize == BLOCK_8X8 && this_rdc.rate != INT_MAX) {
- assert(this_rdc.dist_y < INT64_MAX);
- }
+ mi_col + x_idx, subsize, &this_rdc,
+#if CONFIG_SUPERTX
+ &this_rate_nocoef,
#endif
+ temp_best_rdcost - sum_rdc.rdcost,
+ pc_tree->split[idx]);
+
if (this_rdc.rate == INT_MAX) {
sum_rdc.rdcost = INT64_MAX;
#if CONFIG_SUPERTX
@@ -3747,37 +3929,18 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#if CONFIG_SUPERTX
sum_rate_nocoef += this_rate_nocoef;
#endif // CONFIG_SUPERTX
-#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- if (bsize == BLOCK_8X8) {
- assert(this_rdc.dist_y < INT64_MAX);
- sum_rdc.dist_y += this_rdc.dist_y;
- }
-#endif
}
}
reached_last_index = (idx == 4);
#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- if (reached_last_index && sum_rdc.rdcost != INT64_MAX &&
- bsize == BLOCK_8X8) {
- int64_t dist_8x8;
+ if (x->using_dist_8x8 && reached_last_index &&
+ sum_rdc.rdcost != INT64_MAX && bsize == BLOCK_8X8) {
const int src_stride = x->plane[0].src.stride;
- uint8_t *decoded_8x8;
-
-#if CONFIG_HIGHBITDEPTH
- if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
- decoded_8x8 = CONVERT_TO_BYTEPTR(x->decoded_8x8);
- else
-#endif
- decoded_8x8 = (uint8_t *)x->decoded_8x8;
-
+ int64_t dist_8x8;
dist_8x8 =
- av1_dist_8x8(cpi, xd, x->plane[0].src.buf - 4 * src_stride - 4,
- src_stride, decoded_8x8, 8, BLOCK_8X8, 8, 8, 8, 8,
- x->qindex)
- << 4;
- assert(sum_rdc.dist_y < INT64_MAX);
- sum_rdc.dist = sum_rdc.dist - sum_rdc.dist_y + dist_8x8;
+ dist_8x8_yuv(cpi, x, x->plane[0].src.buf - 4 * src_stride - 4);
+ sum_rdc.dist = dist_8x8;
sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
}
#endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
@@ -3823,6 +3986,11 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#endif // CONFIG_SUPERTX
}
+#if CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
+ if (!reached_last_index && sum_rdc.rdcost >= best_rdc.rdcost)
+ cfl_clear_sub8x8_val(xd->cfl);
+#endif // CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
+
if (reached_last_index && sum_rdc.rdcost < best_rdc.rdcost) {
sum_rdc.rate += partition_cost[PARTITION_SPLIT];
sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
@@ -3835,6 +4003,8 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#if CONFIG_SUPERTX
best_rate_nocoef = sum_rate_nocoef;
assert(best_rate_nocoef >= 0);
+#else
+ temp_best_rdcost = best_rdc.rdcost;
#endif // CONFIG_SUPERTX
pc_tree->partitioning = PARTITION_SPLIT;
}
@@ -3855,17 +4025,11 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
(do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
subsize = get_subsize(bsize, PARTITION_HORZ);
if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
-#if CONFIG_DUAL_FILTER
- if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
- partition_none_allowed)
- pc_tree->horizontal[0].pred_interp_filter =
- ctx_none->mic.mbmi.interp_filter[0];
-#else
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
partition_none_allowed)
pc_tree->horizontal[0].pred_interp_filter =
- ctx_none->mic.mbmi.interp_filter;
-#endif
+ av1_extract_interp_filter(ctx_none->mic.mbmi.interp_filters, 0);
+
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
#if CONFIG_SUPERTX
&sum_rate_nocoef,
@@ -3879,11 +4043,9 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
abort_flag =
(sum_rdc.rdcost >= best_rd && (bsize > BLOCK_8X8 || unify_bsize)) ||
(sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
- if (sum_rdc.rdcost < INT64_MAX &&
-#else
- if (sum_rdc.rdcost < best_rdc.rdcost &&
-#endif // CONFIG_SUPERTX
- !force_horz_split && (bsize > BLOCK_8X8 || unify_bsize)) {
+#endif
+ if (sum_rdc.rdcost < temp_best_rdcost && !force_horz_split &&
+ (bsize > BLOCK_8X8 || unify_bsize)) {
PICK_MODE_CONTEXT *ctx_h = &pc_tree->horizontal[0];
update_state(cpi, td, ctx_h, mi_row, mi_col, subsize, 1);
encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
@@ -3891,17 +4053,11 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_h);
-#if CONFIG_DUAL_FILTER
- if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
- partition_none_allowed)
- pc_tree->horizontal[1].pred_interp_filter =
- ctx_h->mic.mbmi.interp_filter[0];
-#else
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
partition_none_allowed)
pc_tree->horizontal[1].pred_interp_filter =
- ctx_none->mic.mbmi.interp_filter;
-#endif
+ av1_extract_interp_filter(ctx_h->mic.mbmi.interp_filters, 0);
+
#if CONFIG_SUPERTX
rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col, &this_rdc,
&this_rate_nocoef,
@@ -3919,7 +4075,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#endif // CONFIG_SUPERTX
#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- if (this_rdc.rate != INT_MAX && bsize == BLOCK_8X8) {
+ if (x->using_dist_8x8 && this_rdc.rate != INT_MAX && bsize == BLOCK_8X8) {
update_state(cpi, td, &pc_tree->horizontal[1], mi_row + mi_step, mi_col,
subsize, DRY_RUN_NORMAL);
encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row + mi_step, mi_col,
@@ -3939,28 +4095,14 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#if CONFIG_SUPERTX
sum_rate_nocoef += this_rate_nocoef;
#endif // CONFIG_SUPERTX
-#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- sum_rdc.dist_y += this_rdc.dist_y;
-#endif
}
#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- if (sum_rdc.rdcost != INT64_MAX && bsize == BLOCK_8X8) {
- int64_t dist_8x8;
+ if (x->using_dist_8x8 && sum_rdc.rdcost != INT64_MAX &&
+ bsize == BLOCK_8X8) {
const int src_stride = x->plane[0].src.stride;
- uint8_t *decoded_8x8;
-
-#if CONFIG_HIGHBITDEPTH
- if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
- decoded_8x8 = CONVERT_TO_BYTEPTR(x->decoded_8x8);
- else
-#endif
- decoded_8x8 = (uint8_t *)x->decoded_8x8;
-
- dist_8x8 = av1_dist_8x8(cpi, xd, x->plane[0].src.buf - 4 * src_stride,
- src_stride, decoded_8x8, 8, BLOCK_8X8, 8, 8, 8,
- 8, x->qindex)
- << 4;
- sum_rdc.dist = sum_rdc.dist - sum_rdc.dist_y + dist_8x8;
+ int64_t dist_8x8;
+ dist_8x8 = dist_8x8_yuv(cpi, x, x->plane[0].src.buf - 4 * src_stride);
+ sum_rdc.dist = dist_8x8;
sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
}
#endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
@@ -4007,6 +4149,9 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
}
#endif // CONFIG_SUPERTX
+#if CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
+ cfl_clear_sub8x8_val(xd->cfl);
+#endif // CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
if (sum_rdc.rdcost < best_rdc.rdcost) {
sum_rdc.rate += partition_cost[PARTITION_HORZ];
sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
@@ -4036,17 +4181,11 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
-#if CONFIG_DUAL_FILTER
- if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
- partition_none_allowed)
- pc_tree->vertical[0].pred_interp_filter =
- ctx_none->mic.mbmi.interp_filter[0];
-#else
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
partition_none_allowed)
pc_tree->vertical[0].pred_interp_filter =
- ctx_none->mic.mbmi.interp_filter;
-#endif
+ av1_extract_interp_filter(ctx_none->mic.mbmi.interp_filters, 0);
+
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc,
#if CONFIG_SUPERTX
&sum_rate_nocoef,
@@ -4059,28 +4198,23 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
abort_flag =
(sum_rdc.rdcost >= best_rd && (bsize > BLOCK_8X8 || unify_bsize)) ||
(sum_rdc.rate == INT_MAX && bsize == BLOCK_8X8);
- if (sum_rdc.rdcost < INT64_MAX &&
+ const int64_t vert_max_rdcost = INT64_MAX;
#else
- if (sum_rdc.rdcost < best_rdc.rdcost &&
+ const int64_t vert_max_rdcost = best_rdc.rdcost;
#endif // CONFIG_SUPERTX
- !force_vert_split && (bsize > BLOCK_8X8 || unify_bsize)) {
+ if (sum_rdc.rdcost < vert_max_rdcost && !force_vert_split &&
+ (bsize > BLOCK_8X8 || unify_bsize)) {
update_state(cpi, td, &pc_tree->vertical[0], mi_row, mi_col, subsize, 1);
encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col, subsize,
NULL);
if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
-#if CONFIG_DUAL_FILTER
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
partition_none_allowed)
pc_tree->vertical[1].pred_interp_filter =
- ctx_none->mic.mbmi.interp_filter[0];
-#else
- if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
- partition_none_allowed)
- pc_tree->vertical[1].pred_interp_filter =
- ctx_none->mic.mbmi.interp_filter;
-#endif
+ av1_extract_interp_filter(ctx_none->mic.mbmi.interp_filters, 0);
+
#if CONFIG_SUPERTX
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step, &this_rdc,
&this_rate_nocoef,
@@ -4099,7 +4233,7 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#endif // CONFIG_SUPERTX
#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- if (this_rdc.rate != INT_MAX && bsize == BLOCK_8X8) {
+ if (x->using_dist_8x8 && this_rdc.rate != INT_MAX && bsize == BLOCK_8X8) {
update_state(cpi, td, &pc_tree->vertical[1], mi_row, mi_col + mi_step,
subsize, DRY_RUN_NORMAL);
encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, mi_col + mi_step,
@@ -4119,28 +4253,13 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#if CONFIG_SUPERTX
sum_rate_nocoef += this_rate_nocoef;
#endif // CONFIG_SUPERTX
-#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- sum_rdc.dist_y += this_rdc.dist_y;
-#endif
}
#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- if (sum_rdc.rdcost != INT64_MAX && bsize == BLOCK_8X8) {
+ if (x->using_dist_8x8 && sum_rdc.rdcost != INT64_MAX &&
+ bsize == BLOCK_8X8) {
int64_t dist_8x8;
- const int src_stride = x->plane[0].src.stride;
- uint8_t *decoded_8x8;
-
-#if CONFIG_HIGHBITDEPTH
- if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH)
- decoded_8x8 = CONVERT_TO_BYTEPTR(x->decoded_8x8);
- else
-#endif
- decoded_8x8 = (uint8_t *)x->decoded_8x8;
-
- dist_8x8 =
- av1_dist_8x8(cpi, xd, x->plane[0].src.buf - 4, src_stride,
- decoded_8x8, 8, BLOCK_8X8, 8, 8, 8, 8, x->qindex)
- << 4;
- sum_rdc.dist = sum_rdc.dist - sum_rdc.dist_y + dist_8x8;
+ dist_8x8 = dist_8x8_yuv(cpi, x, x->plane[0].src.buf - 4);
+ sum_rdc.dist = dist_8x8;
sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
}
#endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
@@ -4186,6 +4305,10 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
}
#endif // CONFIG_SUPERTX
+#if CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
+ cfl_clear_sub8x8_val(xd->cfl);
+#endif // CONFIG_CFL && CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
+
if (sum_rdc.rdcost < best_rdc.rdcost) {
sum_rdc.rate += partition_cost[PARTITION_VERT];
sum_rdc.rdcost = RDCOST(x->rdmult, sum_rdc.rate, sum_rdc.dist);
@@ -4209,9 +4332,31 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
}
#if CONFIG_EXT_PARTITION_TYPES
+ const int ext_partition_allowed =
+ do_rectangular_split && bsize > BLOCK_8X8 && partition_none_allowed;
+
+#if CONFIG_EXT_PARTITION && CONFIG_EXT_PARTITION_TYPES_AB
+ // Don't allow A/B partitions on 128x128 blocks for now (support for
+ // 128x32 and 32x128 blocks doesn't yet exist).
+ const int ab_partition_allowed =
+ ext_partition_allowed && bsize < BLOCK_128X128;
+#else
+ const int ab_partition_allowed = ext_partition_allowed;
+#endif
+
// PARTITION_HORZ_A
- if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
- partition_none_allowed) {
+ if (partition_horz_allowed && ab_partition_allowed) {
+#if CONFIG_EXT_PARTITION_TYPES_AB
+ rd_test_partition3(
+ cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->horizontala,
+ ctx_none, mi_row, mi_col, bsize, PARTITION_HORZ_A,
+#if CONFIG_SUPERTX
+ best_rd, &best_rate_nocoef, &x_ctx,
+#endif
+ mi_row, mi_col, get_subsize(bsize, PARTITION_HORZ_4),
+ mi_row + mi_step / 2, mi_col, get_subsize(bsize, PARTITION_HORZ_4),
+ mi_row + mi_step, mi_col, get_subsize(bsize, PARTITION_HORZ));
+#else
subsize = get_subsize(bsize, PARTITION_HORZ_A);
rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
pc_tree->horizontala, ctx_none, mi_row, mi_col, bsize,
@@ -4221,11 +4366,26 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#endif
mi_row, mi_col, bsize2, mi_row, mi_col + mi_step, bsize2,
mi_row + mi_step, mi_col, subsize);
+#endif
+#if !CONFIG_PVQ
restore_context(x, &x_ctx, mi_row, mi_col, bsize);
+#else
+ restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
+#endif // !CONFIG_PVQ
}
// PARTITION_HORZ_B
- if (partition_horz_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
- partition_none_allowed) {
+ if (partition_horz_allowed && ab_partition_allowed) {
+#if CONFIG_EXT_PARTITION_TYPES_AB
+ rd_test_partition3(
+ cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->horizontalb,
+ ctx_none, mi_row, mi_col, bsize, PARTITION_HORZ_B,
+#if CONFIG_SUPERTX
+ best_rd, &best_rate_nocoef, &x_ctx,
+#endif
+ mi_row, mi_col, get_subsize(bsize, PARTITION_HORZ), mi_row + mi_step,
+ mi_col, get_subsize(bsize, PARTITION_HORZ_4), mi_row + 3 * mi_step / 2,
+ mi_col, get_subsize(bsize, PARTITION_HORZ_4));
+#else
subsize = get_subsize(bsize, PARTITION_HORZ_B);
rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
pc_tree->horizontalb, ctx_none, mi_row, mi_col, bsize,
@@ -4235,11 +4395,26 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#endif
mi_row, mi_col, subsize, mi_row + mi_step, mi_col,
bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
+#endif
+#if !CONFIG_PVQ
restore_context(x, &x_ctx, mi_row, mi_col, bsize);
+#else
+ restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
+#endif // !CONFIG_PVQ
}
// PARTITION_VERT_A
- if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
- partition_none_allowed) {
+ if (partition_vert_allowed && ab_partition_allowed) {
+#if CONFIG_EXT_PARTITION_TYPES_AB
+ rd_test_partition3(
+ cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->verticala,
+ ctx_none, mi_row, mi_col, bsize, PARTITION_VERT_A,
+#if CONFIG_SUPERTX
+ best_rd, &best_rate_nocoef, &x_ctx,
+#endif
+ mi_row, mi_col, get_subsize(bsize, PARTITION_VERT_4), mi_row,
+ mi_col + mi_step / 2, get_subsize(bsize, PARTITION_VERT_4), mi_row,
+ mi_col + mi_step, get_subsize(bsize, PARTITION_VERT));
+#else
subsize = get_subsize(bsize, PARTITION_VERT_A);
rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
pc_tree->verticala, ctx_none, mi_row, mi_col, bsize,
@@ -4249,11 +4424,26 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#endif
mi_row, mi_col, bsize2, mi_row + mi_step, mi_col, bsize2,
mi_row, mi_col + mi_step, subsize);
+#endif
+#if !CONFIG_PVQ
restore_context(x, &x_ctx, mi_row, mi_col, bsize);
+#else
+ restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
+#endif // !CONFIG_PVQ
}
// PARTITION_VERT_B
- if (partition_vert_allowed && do_rectangular_split && bsize > BLOCK_8X8 &&
- partition_none_allowed) {
+ if (partition_vert_allowed && ab_partition_allowed) {
+#if CONFIG_EXT_PARTITION_TYPES_AB
+ rd_test_partition3(
+ cpi, td, tile_data, tp, pc_tree, &best_rdc, pc_tree->verticalb,
+ ctx_none, mi_row, mi_col, bsize, PARTITION_VERT_B,
+#if CONFIG_SUPERTX
+ best_rd, &best_rate_nocoef, &x_ctx,
+#endif
+ mi_row, mi_col, get_subsize(bsize, PARTITION_VERT), mi_row,
+ mi_col + mi_step, get_subsize(bsize, PARTITION_VERT_4), mi_row,
+ mi_col + 3 * mi_step / 2, get_subsize(bsize, PARTITION_VERT_4));
+#else
subsize = get_subsize(bsize, PARTITION_VERT_B);
rd_test_partition3(cpi, td, tile_data, tp, pc_tree, &best_rdc,
pc_tree->verticalb, ctx_none, mi_row, mi_col, bsize,
@@ -4263,52 +4453,47 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#endif
mi_row, mi_col, subsize, mi_row, mi_col + mi_step,
bsize2, mi_row + mi_step, mi_col + mi_step, bsize2);
+#endif
+#if !CONFIG_PVQ
restore_context(x, &x_ctx, mi_row, mi_col, bsize);
+#else
+ restore_context(x, &x_ctx, mi_row, mi_col, &pre_rdo_buf, bsize);
+#endif // !CONFIG_PVQ
}
+#if CONFIG_EXT_PARTITION
+ const int can_partition_4 = (bsize == BLOCK_128X128 || bsize == BLOCK_64X64 ||
+ bsize == BLOCK_32X32 || bsize == BLOCK_16X16);
+#else
+ const int can_partition_4 =
+ (bsize == BLOCK_64X64 || bsize == BLOCK_32X32 || bsize == BLOCK_16X16);
+#endif // CONFIG_EXT_PARTITION
+
// PARTITION_HORZ_4
// TODO(david.barker): For this and PARTITION_VERT_4,
// * Add support for BLOCK_16X16 once we support 2x8 and 8x2 blocks for the
// chroma plane
// * Add support for supertx
- if (bsize == BLOCK_32X32 && partition_horz_allowed && !force_horz_split &&
+ if (can_partition_4 && partition_horz_allowed && !force_horz_split &&
(do_rectangular_split || av1_active_h_edge(cpi, mi_row, mi_step))) {
- int i;
const int quarter_step = mi_size_high[bsize] / 4;
PICK_MODE_CONTEXT *ctx_prev = ctx_none;
subsize = get_subsize(bsize, PARTITION_HORZ_4);
- av1_zero(sum_rdc);
- for (i = 0; i < 4; ++i) {
+ for (int i = 0; i < 4; ++i) {
int this_mi_row = mi_row + i * quarter_step;
if (i > 0 && this_mi_row >= cm->mi_rows) break;
- if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_prev);
-
- ctx_prev = &pc_tree->horizontal4[i];
+ PICK_MODE_CONTEXT *ctx_this = &pc_tree->horizontal4[i];
- rd_pick_sb_modes(cpi, tile_data, x, this_mi_row, mi_col, &this_rdc,
- PARTITION_HORZ_4, subsize, ctx_prev,
- best_rdc.rdcost - sum_rdc.rdcost);
-
- if (this_rdc.rate == INT_MAX) {
- sum_rdc.rdcost = INT64_MAX;
+ if (!rd_try_subblock(cpi, td, tile_data, tp, (i == 0), (i == 3),
+ this_mi_row, mi_col, subsize, &best_rdc, &sum_rdc,
+ &this_rdc, PARTITION_HORZ_4, ctx_prev, ctx_this))
break;
- } else {
- sum_rdc.rate += this_rdc.rate;
- sum_rdc.dist += this_rdc.dist;
- sum_rdc.rdcost += this_rdc.rdcost;
- }
- if (sum_rdc.rdcost >= best_rdc.rdcost) break;
-
- if (i < 3) {
- update_state(cpi, td, ctx_prev, this_mi_row, mi_col, subsize, 1);
- encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, this_mi_row, mi_col,
- subsize, NULL);
- }
+ ctx_prev = ctx_this;
}
if (sum_rdc.rdcost < best_rdc.rdcost) {
@@ -4326,43 +4511,26 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
#endif
}
// PARTITION_VERT_4
- if (bsize == BLOCK_32X32 && partition_vert_allowed && !force_vert_split &&
+ if (can_partition_4 && partition_vert_allowed && !force_vert_split &&
(do_rectangular_split || av1_active_v_edge(cpi, mi_row, mi_step))) {
- int i;
const int quarter_step = mi_size_wide[bsize] / 4;
PICK_MODE_CONTEXT *ctx_prev = ctx_none;
subsize = get_subsize(bsize, PARTITION_VERT_4);
- av1_zero(sum_rdc);
- for (i = 0; i < 4; ++i) {
+ for (int i = 0; i < 4; ++i) {
int this_mi_col = mi_col + i * quarter_step;
if (i > 0 && this_mi_col >= cm->mi_cols) break;
- if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_prev);
+ PICK_MODE_CONTEXT *ctx_this = &pc_tree->vertical4[i];
- ctx_prev = &pc_tree->vertical4[i];
-
- rd_pick_sb_modes(cpi, tile_data, x, mi_row, this_mi_col, &this_rdc,
- PARTITION_VERT_4, subsize, ctx_prev,
- best_rdc.rdcost - sum_rdc.rdcost);
-
- if (this_rdc.rate == INT_MAX) {
- sum_rdc.rdcost = INT64_MAX;
- } else {
- sum_rdc.rate += this_rdc.rate;
- sum_rdc.dist += this_rdc.dist;
- sum_rdc.rdcost += this_rdc.rdcost;
- }
-
- if (sum_rdc.rdcost >= best_rdc.rdcost) break;
+ if (!rd_try_subblock(cpi, td, tile_data, tp, (i == 0), (i == 3), mi_row,
+ this_mi_col, subsize, &best_rdc, &sum_rdc, &this_rdc,
+ PARTITION_VERT_4, ctx_prev, ctx_this))
+ break;
- if (i < 3) {
- update_state(cpi, td, ctx_prev, mi_row, this_mi_col, subsize, 1);
- encode_superblock(cpi, td, tp, DRY_RUN_NORMAL, mi_row, this_mi_col,
- subsize, NULL);
- }
+ ctx_prev = ctx_this;
}
if (sum_rdc.rdcost < best_rdc.rdcost) {
@@ -4381,11 +4549,6 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
}
#endif // CONFIG_EXT_PARTITION_TYPES
-#if CONFIG_SPEED_REFS
- // First scanning is done.
- if (cpi->sb_scanning_pass_idx == 0 && bsize == cm->sb_size) return;
-#endif // CONFIG_SPEED_REFS
-
// TODO(jbb): This code added so that we avoid static analysis
// warning related to the fact that best_rd isn't used after this
// point. This code should be refactored so that the duplicate
@@ -4393,25 +4556,24 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
(void)best_rd;
*rd_cost = best_rdc;
-#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- if (bsize <= BLOCK_8X8 && rd_cost->rate != INT_MAX) {
- assert(rd_cost->dist_y < INT64_MAX);
- }
-#endif // CONFIG_DIST_8X8 && CONFIG_CB4X4
#if CONFIG_SUPERTX
*rate_nocoef = best_rate_nocoef;
#endif // CONFIG_SUPERTX
-#if CONFIG_CFL
- // Store the luma for the best mode
- x->cfl_store_y = 1;
-#endif
if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
pc_tree->index != 3) {
if (bsize == cm->sb_size) {
-#if CONFIG_MOTION_VAR && CONFIG_NCOBMC
+#if CONFIG_MOTION_VAR && NC_MODE_INFO
set_mode_info_sb(cpi, td, tile_info, tp, mi_row, mi_col, bsize, pc_tree);
#endif
+
+#if CONFIG_LV_MAP
+ x->cb_offset = 0;
+#endif
+
+#if CONFIG_NCOBMC_ADAPT_WEIGHT
+ set_sb_mi_boundaries(cm, xd, mi_row, mi_col);
+#endif
encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, OUTPUT_ENABLED, bsize,
pc_tree, NULL);
} else {
@@ -4419,13 +4581,10 @@ static void rd_pick_partition(const AV1_COMP *const cpi, ThreadData *td,
pc_tree, NULL);
}
}
-#if CONFIG_CFL
- x->cfl_store_y = 0;
-#endif
#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- if (best_rdc.rate < INT_MAX && best_rdc.dist < INT64_MAX &&
- bsize == BLOCK_4X4 && pc_tree->index == 3) {
+ if (x->using_dist_8x8 && best_rdc.rate < INT_MAX &&
+ best_rdc.dist < INT64_MAX && bsize == BLOCK_4X4 && pc_tree->index == 3) {
encode_sb(cpi, td, tile_info, tp, mi_row, mi_col, DRY_RUN_NORMAL, bsize,
pc_tree, NULL);
}
@@ -4442,22 +4601,6 @@ 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) {
@@ -4476,14 +4619,18 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
// Initialize the left context for the new SB row
av1_zero_left_context(xd);
-#if CONFIG_DELTA_Q
// Reset delta for every tile
if (cm->delta_q_present_flag)
if (mi_row == tile_info->mi_row_start) xd->prev_qindex = cm->base_qindex;
#if CONFIG_EXT_DELTA_Q
- if (cm->delta_lf_present_flag)
+ if (cm->delta_lf_present_flag) {
+#if CONFIG_LOOPFILTER_LEVEL
+ if (mi_row == tile_info->mi_row_start)
+ for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id)
+ xd->prev_delta_lf[lf_id] = 0;
+#endif // CONFIG_LOOPFILTER_LEVEL
if (mi_row == tile_info->mi_row_start) xd->prev_delta_lf_from_base = 0;
-#endif
+ }
#endif
// Code each SB in the row
@@ -4503,9 +4650,21 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
MODE_INFO **mi = cm->mi_grid_visible + idx_str;
PC_TREE *const pc_root = td->pc_root[cm->mib_size_log2 - MIN_MIB_SIZE_LOG2];
+#if CONFIG_LV_MAP && LV_MAP_PROB
+ av1_fill_coeff_costs(&td->mb, xd->tile_ctx);
+#else
+ av1_fill_token_costs_from_cdf(x->token_head_costs,
+ x->e_mbd.tile_ctx->coef_head_cdfs);
+ av1_fill_token_costs_from_cdf(x->token_tail_costs,
+ x->e_mbd.tile_ctx->coef_tail_cdfs);
+#endif
+ av1_fill_mode_rates(cm, x, xd->tile_ctx);
+
if (sf->adaptive_pred_interp_filter) {
+#if !CONFIG_CB4X4
for (i = 0; i < leaf_nodes; ++i)
td->leaf_tree[i].pred_interp_filter = SWITCHABLE;
+#endif
for (i = 0; i < leaf_nodes; ++i) {
td->pc_tree[i].vertical[0].pred_interp_filter = SWITCHABLE;
@@ -4515,6 +4674,7 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
}
}
+ x->tx_rd_record.num = x->tx_rd_record.index_start = 0;
av1_zero(x->pred_mv);
pc_root->index = 0;
@@ -4524,8 +4684,10 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
int segment_id = get_segment_id(cm, map, cm->sb_size, mi_row, mi_col);
seg_skip = segfeature_active(seg, segment_id, SEG_LVL_SKIP);
}
+#if CONFIG_AMVR
+ xd->cur_frame_mv_precision_level = cm->cur_frame_mv_precision_level;
+#endif
-#if CONFIG_DELTA_Q
if (cm->delta_q_present_flag) {
// Test mode for delta quantization
int sb_row = mi_row >> 3;
@@ -4545,7 +4707,7 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
assert(current_qindex > 0);
xd->delta_qindex = current_qindex - cm->base_qindex;
- set_offsets(cpi, tile_info, x, mi_row, mi_col, BLOCK_64X64);
+ set_offsets(cpi, tile_info, x, mi_row, mi_col, cm->sb_size);
xd->mi[0]->mbmi.current_q_index = current_qindex;
#if !CONFIG_EXT_DELTA_Q
xd->mi[0]->mbmi.segment_id = 0;
@@ -4564,13 +4726,19 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
for (j = 0; j < AOMMIN(cm->mib_size, cm->mi_rows - mi_row); j++) {
for (k = 0; k < AOMMIN(cm->mib_size, cm->mi_cols - mi_col); k++) {
cm->mi[(mi_row + j) * cm->mi_stride + (mi_col + k)]
- .mbmi.current_delta_lf_from_base = current_delta_lf_from_base;
+ .mbmi.current_delta_lf_from_base =
+ clamp(current_delta_lf_from_base, 0, MAX_LOOP_FILTER);
+#if CONFIG_LOOPFILTER_LEVEL
+ for (int lf_id = 0; lf_id < FRAME_LF_COUNT; ++lf_id) {
+ cm->mi[(mi_row + j) * cm->mi_stride + (mi_col + k)]
+ .mbmi.curr_delta_lf[lf_id] = current_delta_lf_from_base;
+ }
+#endif // CONFIG_LOOPFILTER_LEVEL
}
}
}
#endif // CONFIG_EXT_DELTA_Q
}
-#endif // CONFIG_DELTA_Q
x->source_variance = UINT_MAX;
if (sf->partition_search_type == FIXED_PARTITION || seg_skip) {
@@ -4602,35 +4770,12 @@ static void encode_rd_sb_row(AV1_COMP *cpi, ThreadData *td,
rd_auto_partition_range(cpi, tile_info, xd, mi_row, mi_col,
&x->min_partition_size, &x->max_partition_size);
}
-#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
- &dummy_rate_nocoef,
-#endif // CONFIG_SUPERTX
- INT64_MAX, pc_root);
- 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
rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, cm->sb_size,
&dummy_rdc,
#if CONFIG_SUPERTX
&dummy_rate_nocoef,
#endif // CONFIG_SUPERTX
INT64_MAX, pc_root);
-#endif // CONFIG_SPEED_REFS
}
}
}
@@ -4656,7 +4801,7 @@ static int check_dual_ref_flags(AV1_COMP *cpi) {
return (!!(ref_flags & AOM_GOLD_FLAG) + !!(ref_flags & AOM_LAST_FLAG) +
#if CONFIG_EXT_REFS
!!(ref_flags & AOM_LAST2_FLAG) + !!(ref_flags & AOM_LAST3_FLAG) +
- !!(ref_flags & AOM_BWD_FLAG) +
+ !!(ref_flags & AOM_BWD_FLAG) + !!(ref_flags & AOM_ALT2_FLAG) +
#endif // CONFIG_EXT_REFS
!!(ref_flags & AOM_ALT_FLAG)) >= 2;
}
@@ -4686,9 +4831,13 @@ static MV_REFERENCE_FRAME get_frame_type(const AV1_COMP *cpi) {
cpi->rc.is_src_frame_ext_arf)
#else
else if (cpi->rc.is_src_frame_alt_ref && cpi->refresh_golden_frame)
-#endif
+#endif // CONFIG_EXT_REFS
return ALTREF_FRAME;
- else if (cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame)
+ else if (cpi->refresh_golden_frame ||
+#if CONFIG_EXT_REFS
+ cpi->refresh_alt2_ref_frame ||
+#endif // CONFIG_EXT_REFS
+ cpi->refresh_alt_ref_frame)
return GOLDEN_FRAME;
else
// TODO(zoeliu): To investigate whether a frame_type other than
@@ -4872,7 +5021,12 @@ void av1_encode_tile(AV1_COMP *cpi, ThreadData *td, int tile_row,
td->mb.daala_enc.state.adapt = &this_tile->tctx.pvq_context;
#endif // CONFIG_PVQ
- av1_setup_across_tile_boundary_info(cm, tile_info);
+#if CONFIG_LOOPFILTERING_ACROSS_TILES
+ if (!cm->loop_filter_across_tiles_enabled)
+ av1_setup_across_tile_boundary_info(cm, tile_info);
+#endif
+
+ av1_crc_calculator_init(&td->mb.tx_rd_record.crc_calculator, 24, 0x5D6DCB);
for (mi_row = tile_info->mi_row_start; mi_row < tile_info->mi_row_end;
mi_row += cm->mib_size) {
@@ -4925,8 +5079,8 @@ static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
#if CONFIG_GLOBAL_MOTION
#define GLOBAL_TRANS_TYPES_ENC 3 // highest motion model to search
-static int gm_get_params_cost(WarpedMotionParams *gm,
- WarpedMotionParams *ref_gm, int allow_hp) {
+static int gm_get_params_cost(const WarpedMotionParams *gm,
+ const WarpedMotionParams *ref_gm, int allow_hp) {
assert(gm->wmtype < GLOBAL_TRANS_TYPES);
int params_cost = 0;
int trans_bits, trans_prec_diff;
@@ -5010,7 +5164,8 @@ static int do_gm_search_logic(SPEED_FEATURES *const sf, int num_refs_using_gm,
}
#endif // CONFIG_GLOBAL_MOTION
-#if CONFIG_PALETTE
+// TODO(anybody) : remove this flag when PVQ supports pallete coding tool
+#if !CONFIG_PVQ
// Estimate if the source frame is screen content, based on the portion of
// blocks that have no more than 4 (experimentally selected) luma colors.
static int is_screen_content(const uint8_t *src,
@@ -5038,7 +5193,7 @@ static int is_screen_content(const uint8_t *src,
// The threshold is 10%.
return counts * blk_h * blk_w * 10 > width * height;
}
-#endif // CONFIG_PALETTE
+#endif // !CONFIG_PVQ
static void encode_frame_internal(AV1_COMP *cpi) {
ThreadData *const td = &cpi->td;
@@ -5057,18 +5212,21 @@ static void encode_frame_internal(AV1_COMP *cpi) {
x->min_partition_size = AOMMIN(x->min_partition_size, cm->sb_size);
x->max_partition_size = AOMMIN(x->max_partition_size, cm->sb_size);
+#if CONFIG_DIST_8X8
+ x->using_dist_8x8 = cpi->oxcf.using_dist_8x8;
+ x->tune_metric = cpi->oxcf.tuning;
+#endif
cm->setup_mi(cm);
xd->mi = cm->mi_grid_visible;
xd->mi[0] = cm->mi;
av1_zero(*td->counts);
- av1_zero(rdc->coef_counts);
av1_zero(rdc->comp_pred_diff);
-#if CONFIG_PALETTE || CONFIG_INTRABC
if (frame_is_intra_only(cm)) {
-#if CONFIG_PALETTE
+// TODO(anybody) : remove this flag when PVQ supports pallete coding tool
+#if !CONFIG_PVQ
cm->allow_screen_content_tools =
cpi->oxcf.content == AOM_CONTENT_SCREEN ||
is_screen_content(cpi->source->y_buffer,
@@ -5078,10 +5236,80 @@ static void encode_frame_internal(AV1_COMP *cpi) {
cpi->source->y_stride, cpi->source->y_width,
cpi->source->y_height);
#else
- cm->allow_screen_content_tools = cpi->oxcf.content == AOM_CONTENT_SCREEN;
-#endif // CONFIG_PALETTE
+ cm->allow_screen_content_tools = 0;
+#endif // !CONFIG_PVQ
+ }
+
+#if CONFIG_HASH_ME
+ if (cpi->oxcf.pass != 1 && cpi->common.allow_screen_content_tools) {
+ // add to hash table
+ const int pic_width = cpi->source->y_crop_width;
+ const int pic_height = cpi->source->y_crop_height;
+ uint32_t *block_hash_values[2][2];
+ int8_t *is_block_same[2][3];
+ int k, j;
+
+ for (k = 0; k < 2; k++) {
+ for (j = 0; j < 2; j++) {
+ CHECK_MEM_ERROR(cm, block_hash_values[k][j],
+ aom_malloc(sizeof(uint32_t) * pic_width * pic_height));
+ }
+
+ for (j = 0; j < 3; j++) {
+ CHECK_MEM_ERROR(cm, is_block_same[k][j],
+ aom_malloc(sizeof(int8_t) * pic_width * pic_height));
+ }
+ }
+
+ av1_hash_table_create(&cm->cur_frame->hash_table);
+ av1_generate_block_2x2_hash_value(cpi->source, block_hash_values[0],
+ is_block_same[0]);
+ av1_generate_block_hash_value(cpi->source, 4, block_hash_values[0],
+ block_hash_values[1], is_block_same[0],
+ is_block_same[1]);
+ av1_add_to_hash_map_by_row_with_precal_data(
+ &cm->cur_frame->hash_table, block_hash_values[1], is_block_same[1][2],
+ pic_width, pic_height, 4);
+ av1_generate_block_hash_value(cpi->source, 8, block_hash_values[1],
+ block_hash_values[0], is_block_same[1],
+ is_block_same[0]);
+ av1_add_to_hash_map_by_row_with_precal_data(
+ &cm->cur_frame->hash_table, block_hash_values[0], is_block_same[0][2],
+ pic_width, pic_height, 8);
+ av1_generate_block_hash_value(cpi->source, 16, block_hash_values[0],
+ block_hash_values[1], is_block_same[0],
+ is_block_same[1]);
+ av1_add_to_hash_map_by_row_with_precal_data(
+ &cm->cur_frame->hash_table, block_hash_values[1], is_block_same[1][2],
+ pic_width, pic_height, 16);
+ av1_generate_block_hash_value(cpi->source, 32, block_hash_values[1],
+ block_hash_values[0], is_block_same[1],
+ is_block_same[0]);
+ av1_add_to_hash_map_by_row_with_precal_data(
+ &cm->cur_frame->hash_table, block_hash_values[0], is_block_same[0][2],
+ pic_width, pic_height, 32);
+ av1_generate_block_hash_value(cpi->source, 64, block_hash_values[0],
+ block_hash_values[1], is_block_same[0],
+ is_block_same[1]);
+ av1_add_to_hash_map_by_row_with_precal_data(
+ &cm->cur_frame->hash_table, block_hash_values[1], is_block_same[1][2],
+ pic_width, pic_height, 64);
+
+ for (k = 0; k < 2; k++) {
+ for (j = 0; j < 2; j++) {
+ aom_free(block_hash_values[k][j]);
+ }
+
+ for (j = 0; j < 3; j++) {
+ aom_free(is_block_same[k][j]);
+ }
+ }
}
-#endif // CONFIG_PALETTE || CONFIG_INTRABC
+#endif
+
+#if CONFIG_NCOBMC_ADAPT_WEIGHT
+ alloc_ncobmc_pred_buffer(xd);
+#endif
#if CONFIG_GLOBAL_MOTION
av1_zero(rdc->global_motion_used);
@@ -5102,6 +5330,10 @@ static void encode_frame_internal(AV1_COMP *cpi) {
for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
ref_buf[frame] = get_ref_frame_buffer(cpi, frame);
int pframe;
+ cm->global_motion[frame] = default_warp_params;
+ const WarpedMotionParams *ref_params =
+ cm->error_resilient_mode ? &default_warp_params
+ : &cm->prev_frame->global_motion[frame];
// check for duplicate buffer
for (pframe = LAST_FRAME; pframe < frame; ++pframe) {
if (ref_buf[frame] == ref_buf[pframe]) break;
@@ -5168,7 +5400,7 @@ static void encode_frame_internal(AV1_COMP *cpi) {
}
if (cm->global_motion[frame].wmtype <= AFFINE)
if (!get_shear_params(&cm->global_motion[frame]))
- set_default_warp_params(&cm->global_motion[frame]);
+ cm->global_motion[frame] = default_warp_params;
if (cm->global_motion[frame].wmtype == TRANSLATION) {
cm->global_motion[frame].wmmat[0] =
@@ -5185,10 +5417,9 @@ static void encode_frame_internal(AV1_COMP *cpi) {
// this motion type, revert to IDENTITY.
if (!is_enough_erroradvantage(
(double)best_warp_error / ref_frame_error,
- gm_get_params_cost(&cm->global_motion[frame],
- &cm->prev_frame->global_motion[frame],
+ gm_get_params_cost(&cm->global_motion[frame], ref_params,
cm->allow_high_precision_mv))) {
- set_default_warp_params(&cm->global_motion[frame]);
+ cm->global_motion[frame] = default_warp_params;
}
if (cm->global_motion[frame].wmtype != IDENTITY) break;
}
@@ -5196,8 +5427,7 @@ static void encode_frame_internal(AV1_COMP *cpi) {
}
if (cm->global_motion[frame].wmtype != IDENTITY) num_refs_using_gm++;
cpi->gmparams_cost[frame] =
- gm_get_params_cost(&cm->global_motion[frame],
- &cm->prev_frame->global_motion[frame],
+ gm_get_params_cost(&cm->global_motion[frame], ref_params,
cm->allow_high_precision_mv) +
cpi->gmtype_cost[cm->global_motion[frame].wmtype] -
cpi->gmtype_cost[IDENTITY];
@@ -5221,7 +5451,6 @@ static void encode_frame_internal(AV1_COMP *cpi) {
cm->tx_mode = select_tx_mode(cpi);
-#if CONFIG_DELTA_Q
// Fix delta q resolution for the moment
cm->delta_q_res = DEFAULT_DELTA_Q_RES;
// Set delta_q_present_flag before it is used for the first time
@@ -5234,7 +5463,6 @@ static void encode_frame_internal(AV1_COMP *cpi) {
cm->delta_q_present_flag =
cpi->oxcf.aq_mode == DELTA_AQ && cm->base_qindex > 0;
#endif // CONFIG_EXT_DELTA_Q
-#endif
av1_frame_init_quantizer(cpi);
@@ -5262,19 +5490,7 @@ static void encode_frame_internal(AV1_COMP *cpi) {
#endif // CONFIG_EXT_REFS || CONFIG_TEMPMV_SIGNALING
#if CONFIG_TEMPMV_SIGNALING
- if (cm->prev_frame) {
- cm->use_prev_frame_mvs &=
- !cm->error_resilient_mode &&
-#if CONFIG_FRAME_SUPERRES
- cm->width == cm->last_width && cm->height == cm->last_height &&
-#else
- cm->width == cm->prev_frame->buf.y_crop_width &&
- cm->height == cm->prev_frame->buf.y_crop_height &&
-#endif // CONFIG_FRAME_SUPERRES
- !cm->intra_only && !cm->prev_frame->intra_only && cm->last_show_frame;
- } else {
- cm->use_prev_frame_mvs = 0;
- }
+ cm->use_prev_frame_mvs &= frame_can_use_prev_frame_mvs(cm);
#else
if (cm->prev_frame) {
cm->use_prev_frame_mvs = !cm->error_resilient_mode &&
@@ -5301,6 +5517,10 @@ static void encode_frame_internal(AV1_COMP *cpi) {
av1_zero(x->blk_skip_drl);
#endif
+#if CONFIG_MFMV
+ av1_setup_motion_field(cm);
+#endif // CONFIG_MFMV
+
{
struct aom_usec_timer emr_timer;
aom_usec_timer_start(&emr_timer);
@@ -5326,6 +5546,9 @@ static void encode_frame_internal(AV1_COMP *cpi) {
aom_usec_timer_mark(&emr_timer);
cpi->time_encode_sb_row += aom_usec_timer_elapsed(&emr_timer);
}
+#if CONFIG_NCOBMC_ADAPT_WEIGHT
+ free_ncobmc_pred_buffer(xd);
+#endif
#if 0
// Keep record of the total distortion this time around for future use
@@ -5333,7 +5556,6 @@ static void encode_frame_internal(AV1_COMP *cpi) {
#endif
}
-#if CONFIG_EXT_INTER
static void make_consistent_compound_tools(AV1_COMMON *cm) {
(void)cm;
#if CONFIG_INTERINTRA
@@ -5349,7 +5571,6 @@ static void make_consistent_compound_tools(AV1_COMMON *cm) {
cm->allow_masked_compound = 0;
#endif // CONFIG_COMPOUND_SEGMENT || CONFIG_WEDGE
}
-#endif // CONFIG_EXT_INTER
void av1_encode_frame(AV1_COMP *cpi) {
AV1_COMMON *const cm = &cpi->common;
@@ -5358,6 +5579,32 @@ void av1_encode_frame(AV1_COMP *cpi) {
// rather than the potential full set of 16 transforms
cm->reduced_tx_set_used = 0;
#endif // CONFIG_EXT_TX
+#if CONFIG_ADAPT_SCAN
+ cm->use_adapt_scan = 1;
+ // TODO(angiebird): call av1_init_scan_order only when use_adapt_scan
+ // switches from 1 to 0
+ if (cm->use_adapt_scan == 0) av1_init_scan_order(cm);
+#endif
+
+#if CONFIG_FRAME_MARKER
+ if (cm->show_frame == 0) {
+ int arf_offset = AOMMIN(
+ (MAX_GF_INTERVAL - 1),
+ cpi->twopass.gf_group.arf_src_offset[cpi->twopass.gf_group.index]);
+#if CONFIG_EXT_REFS
+ int brf_offset =
+ cpi->twopass.gf_group.brf_src_offset[cpi->twopass.gf_group.index];
+ arf_offset = AOMMIN((MAX_GF_INTERVAL - 1), arf_offset + brf_offset);
+#endif // CONFIG_EXT_REFS
+ cm->frame_offset = cm->current_video_frame + arf_offset;
+ } else {
+ cm->frame_offset = cm->current_video_frame;
+ }
+ av1_setup_frame_buf_refs(cm);
+#if CONFIG_FRAME_SIGN_BIAS
+ av1_setup_frame_sign_bias(cm);
+#endif // CONFIG_FRAME_SIGN_BIAS
+#endif // CONFIG_FRAME_MARKER
// In the longer term the encoder should be generalized to match the
// decoder such that we allow compound where one of the 3 buffers has a
@@ -5366,14 +5613,14 @@ void av1_encode_frame(AV1_COMP *cpi) {
// side behavior is where the ALT ref buffer has opposite sign bias to
// the other two.
if (!frame_is_intra_only(cm)) {
-#if !(CONFIG_ONE_SIDED_COMPOUND || CONFIG_EXT_COMP_REFS)
+#if !CONFIG_ONE_SIDED_COMPOUND
if ((cm->ref_frame_sign_bias[ALTREF_FRAME] ==
cm->ref_frame_sign_bias[GOLDEN_FRAME]) ||
(cm->ref_frame_sign_bias[ALTREF_FRAME] ==
cm->ref_frame_sign_bias[LAST_FRAME])) {
cpi->allow_comp_inter_inter = 0;
} else {
-#endif // !(CONFIG_ONE_SIDED_COMPOUND || CONFIG_EXT_COMP_REFS)
+#endif // !CONFIG_ONE_SIDED_COMPOUND
cpi->allow_comp_inter_inter = 1;
#if CONFIG_EXT_REFS
cm->comp_fwd_ref[0] = LAST_FRAME;
@@ -5381,16 +5628,16 @@ void av1_encode_frame(AV1_COMP *cpi) {
cm->comp_fwd_ref[2] = LAST3_FRAME;
cm->comp_fwd_ref[3] = GOLDEN_FRAME;
cm->comp_bwd_ref[0] = BWDREF_FRAME;
- cm->comp_bwd_ref[1] = ALTREF_FRAME;
-#else
+ cm->comp_bwd_ref[1] = ALTREF2_FRAME;
+ cm->comp_bwd_ref[2] = ALTREF_FRAME;
+#else // !CONFIG_EXT_REFS
cm->comp_fixed_ref = ALTREF_FRAME;
cm->comp_var_ref[0] = LAST_FRAME;
cm->comp_var_ref[1] = GOLDEN_FRAME;
-#endif // CONFIG_EXT_REFS
-#if !(CONFIG_ONE_SIDED_COMPOUND || \
- CONFIG_EXT_COMP_REFS) // Normative in encoder
+#endif // CONFIG_EXT_REFS
+#if !CONFIG_ONE_SIDED_COMPOUND // Normative in encoder
}
-#endif // !(CONFIG_ONE_SIDED_COMPOUND || CONFIG_EXT_COMP_REFS)
+#endif // !CONFIG_ONE_SIDED_COMPOUND
} else {
cpi->allow_comp_inter_inter = 0;
}
@@ -5444,9 +5691,7 @@ void av1_encode_frame(AV1_COMP *cpi) {
cm->interp_filter = SWITCHABLE;
#endif
-#if CONFIG_EXT_INTER
make_consistent_compound_tools(cm);
-#endif // CONFIG_EXT_INTER
rdc->single_ref_used_flag = 0;
rdc->compound_ref_used_flag = 0;
@@ -5469,9 +5714,7 @@ void av1_encode_frame(AV1_COMP *cpi) {
#endif // !CONFIG_REF_ADAPT
}
}
-#if CONFIG_EXT_INTER
make_consistent_compound_tools(cm);
-#endif // CONFIG_EXT_INTER
#if CONFIG_VAR_TX
#if CONFIG_RECT_TX_EXT
@@ -5483,10 +5726,11 @@ void av1_encode_frame(AV1_COMP *cpi) {
cm->tx_mode = ALLOW_32X32 + CONFIG_TX64X64;
#else
#if CONFIG_RECT_TX_EXT && CONFIG_EXT_TX
- if (cm->tx_mode == TX_MODE_SELECT && counts->quarter_tx_size[1] == 0) {
+ if (cm->tx_mode == TX_MODE_SELECT && counts->quarter_tx_size[1] == 0)
#else
- if (cm->tx_mode == TX_MODE_SELECT) {
+ if (cm->tx_mode == TX_MODE_SELECT)
#endif
+ {
#if CONFIG_TX64X64
int count4x4 = 0;
int count8x8_8x8p = 0, count8x8_lp = 0;
@@ -5653,9 +5897,7 @@ void av1_encode_frame(AV1_COMP *cpi) {
}
#endif
} else {
-#if CONFIG_EXT_INTER
make_consistent_compound_tools(cm);
-#endif // CONFIG_EXT_INTER
encode_frame_internal(cpi);
}
}
@@ -5664,21 +5906,15 @@ static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
const MODE_INFO *mi, const MODE_INFO *above_mi,
const MODE_INFO *left_mi, const int intraonly,
const int mi_row, const int mi_col) {
+ FRAME_CONTEXT *fc = xd->tile_ctx;
const MB_MODE_INFO *const mbmi = &mi->mbmi;
-#if CONFIG_ENTROPY_STATS
const PREDICTION_MODE y_mode = mbmi->mode;
const UV_PREDICTION_MODE uv_mode = mbmi->uv_mode;
-#else // CONFIG_ENTROPY_STATS
(void)counts;
- (void)above_mi;
- (void)left_mi;
- (void)intraonly;
-#endif // CONFIG_ENTROPY_STATS
const BLOCK_SIZE bsize = mbmi->sb_type;
const int unify_bsize = CONFIG_CB4X4;
if (bsize < BLOCK_8X8 && !unify_bsize) {
-#if CONFIG_ENTROPY_STATS
int idx, idy;
const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
@@ -5687,30 +5923,38 @@ static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
const int bidx = idy * 2 + idx;
const PREDICTION_MODE bmode = mi->bmi[bidx].as_mode;
if (intraonly) {
+#if CONFIG_ENTROPY_STATS
const PREDICTION_MODE a = av1_above_block_mode(mi, above_mi, bidx);
const PREDICTION_MODE l = av1_left_block_mode(mi, left_mi, bidx);
++counts->kf_y_mode[a][l][bmode];
+#endif // CONFIG_ENTROPY_STATS
+ update_cdf(get_y_mode_cdf(fc, mi, above_mi, left_mi, bidx), bmode,
+ INTRA_MODES);
} else {
+#if CONFIG_ENTROPY_STATS
++counts->y_mode[0][bmode];
+#endif // CONFIG_ENTROPY_STATS
+ update_cdf(fc->y_mode_cdf[0], bmode, INTRA_MODES);
}
}
-#endif // CONFIG_ENTROPY_STATS
} else {
-#if CONFIG_ENTROPY_STATS
if (intraonly) {
+#if CONFIG_ENTROPY_STATS
const PREDICTION_MODE above = av1_above_block_mode(mi, above_mi, 0);
const PREDICTION_MODE left = av1_left_block_mode(mi, left_mi, 0);
++counts->kf_y_mode[above][left][y_mode];
+#endif // CONFIG_ENTROPY_STATS
+ update_cdf(get_y_mode_cdf(fc, mi, above_mi, left_mi, 0), y_mode,
+ INTRA_MODES);
} else {
+#if CONFIG_ENTROPY_STATS
++counts->y_mode[size_group_lookup[bsize]][y_mode];
- }
#endif // CONFIG_ENTROPY_STATS
+ update_cdf(fc->y_mode_cdf[size_group_lookup[bsize]], y_mode, INTRA_MODES);
+ }
+
#if CONFIG_FILTER_INTRA
- if (mbmi->mode == DC_PRED
-#if CONFIG_PALETTE
- && mbmi->palette_mode_info.palette_size[0] == 0
-#endif // CONFIG_PALETTE
- ) {
+ if (mbmi->mode == DC_PRED && mbmi->palette_mode_info.palette_size[0] == 0) {
const int use_filter_intra_mode =
mbmi->filter_intra_mode_info.use_filter_intra_mode[0];
++counts->filter_intra[0][use_filter_intra_mode];
@@ -5721,10 +5965,7 @@ static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
is_chroma_reference(mi_row, mi_col, bsize, xd->plane[1].subsampling_x,
xd->plane[1].subsampling_y)
#endif
-#if CONFIG_PALETTE
- && mbmi->palette_mode_info.palette_size[1] == 0
-#endif // CONFIG_PALETTE
- ) {
+ && mbmi->palette_mode_info.palette_size[1] == 0) {
const int use_filter_intra_mode =
mbmi->filter_intra_mode_info.use_filter_intra_mode[1];
++counts->filter_intra[1][use_filter_intra_mode];
@@ -5753,6 +5994,7 @@ static void sum_intra_stats(FRAME_COUNTS *counts, MACROBLOCKD *xd,
#if CONFIG_ENTROPY_STATS
++counts->uv_mode[y_mode][uv_mode];
#endif // CONFIG_ENTROPY_STATS
+ update_cdf(fc->uv_mode_cdf[y_mode], uv_mode, UV_INTRA_MODES);
}
#if CONFIG_VAR_TX
@@ -5770,13 +6012,26 @@ static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
const TX_SIZE plane_tx_size = mbmi->inter_tx_size[tx_row][tx_col];
if (blk_row >= max_blocks_high || blk_col >= max_blocks_wide) return;
+ assert(tx_size > TX_4X4);
+
+ if (depth == MAX_VARTX_DEPTH) {
+// Don't add to counts in this case
+#if CONFIG_RECT_TX_EXT
+ if (tx_size == plane_tx_size)
+#endif
+ mbmi->tx_size = tx_size;
+ txfm_partition_update(xd->above_txfm_context + blk_col,
+ xd->left_txfm_context + blk_row, tx_size, tx_size);
+ return;
+ }
#if CONFIG_RECT_TX_EXT
if (tx_size == plane_tx_size ||
- mbmi->tx_size == quarter_txsize_lookup[mbmi->sb_type]) {
+ mbmi->tx_size == quarter_txsize_lookup[mbmi->sb_type])
#else
- if (tx_size == plane_tx_size) {
+ if (tx_size == plane_tx_size)
#endif
+ {
++counts->txfm_partition[ctx][0];
#if CONFIG_RECT_TX_EXT
if (tx_size == plane_tx_size)
@@ -5792,7 +6047,7 @@ static void update_txfm_count(MACROBLOCK *x, MACROBLOCKD *xd,
++counts->txfm_partition[ctx][1];
++x->txb_split_count;
- if (tx_size == TX_8X8) {
+ if (sub_txs == TX_4X4) {
mbmi->inter_tx_size[tx_row][tx_col] = TX_4X4;
mbmi->tx_size = TX_4X4;
txfm_partition_update(xd->above_txfm_context + blk_col,
@@ -5815,10 +6070,22 @@ static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
MACROBLOCKD *xd = &x->e_mbd;
const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
const int mi_height = block_size_high[plane_bsize] >> tx_size_wide_log2[0];
- TX_SIZE max_tx_size = get_vartx_max_txsize(&xd->mi[0]->mbmi, plane_bsize);
+ TX_SIZE max_tx_size = get_vartx_max_txsize(&xd->mi[0]->mbmi, plane_bsize, 0);
const int bh = tx_size_high_unit[max_tx_size];
const int bw = tx_size_wide_unit[max_tx_size];
int idx, idy;
+ int init_depth =
+ (mi_height != mi_width) ? RECT_VARTX_DEPTH_INIT : SQR_VARTX_DEPTH_INIT;
+
+#if CONFIG_INTRABC
+ // Intrabc doesn't support var-tx yet. So no need to update tx partition
+ // info., except for the split count (otherwise common->tx_mode may be
+ // modified, causing mismatch).
+ if (is_intrabc_block(&x->e_mbd.mi[0]->mbmi)) {
+ if (x->e_mbd.mi[0]->mbmi.tx_size != max_tx_size) ++x->txb_split_count;
+ return;
+ }
+#endif // CONFIG_INTRABC
xd->above_txfm_context =
cm->above_txfm_context + (mi_col << TX_UNIT_WIDE_LOG2);
@@ -5827,8 +6094,7 @@ static void tx_partition_count_update(const AV1_COMMON *const cm, MACROBLOCK *x,
for (idy = 0; idy < mi_height; idy += bh)
for (idx = 0; idx < mi_width; idx += bw)
- update_txfm_count(x, xd, td_counts, max_tx_size, mi_width != mi_height,
- idy, idx);
+ update_txfm_count(x, xd, td_counts, max_tx_size, init_depth, idy, idx);
}
static void set_txfm_context(MACROBLOCKD *xd, TX_SIZE tx_size, int blk_row,
@@ -5874,7 +6140,7 @@ static void tx_partition_set_contexts(const AV1_COMMON *const cm,
int mi_row, int mi_col) {
const int mi_width = block_size_wide[plane_bsize] >> tx_size_wide_log2[0];
const int mi_height = block_size_high[plane_bsize] >> tx_size_high_log2[0];
- TX_SIZE max_tx_size = get_vartx_max_txsize(&xd->mi[0]->mbmi, plane_bsize);
+ TX_SIZE max_tx_size = get_vartx_max_txsize(&xd->mi[0]->mbmi, plane_bsize, 0);
const int bh = tx_size_high_unit[max_tx_size];
const int bw = tx_size_wide_unit[max_tx_size];
int idx, idy;
@@ -5898,6 +6164,10 @@ void av1_update_tx_type_count(const AV1_COMMON *cm, MACROBLOCKD *xd,
FRAME_COUNTS *counts) {
MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
int is_inter = is_inter_block(mbmi);
+ FRAME_CONTEXT *fc = xd->tile_ctx;
+#if !CONFIG_ENTROPY_STATS
+ (void)counts;
+#endif // !CONFIG_ENTROPY_STATS
#if !CONFIG_TXK_SEL
TX_TYPE tx_type = mbmi->tx_type;
@@ -5916,12 +6186,64 @@ void av1_update_tx_type_count(const AV1_COMMON *cm, MACROBLOCKD *xd,
const int eset =
get_ext_tx_set(tx_size, bsize, is_inter, cm->reduced_tx_set_used);
if (eset > 0) {
+#if !CONFIG_LGT_FROM_PRED
+ const TxSetType tx_set_type = get_ext_tx_set_type(
+ tx_size, bsize, is_inter, cm->reduced_tx_set_used);
if (is_inter) {
+ update_cdf(fc->inter_ext_tx_cdf[eset][txsize_sqr_map[tx_size]],
+ av1_ext_tx_ind[tx_set_type][tx_type],
+ av1_num_ext_tx_set[tx_set_type]);
+#if CONFIG_ENTROPY_STATS
++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]][tx_type];
+#endif // CONFIG_ENTROPY_STATS
} else {
+#if CONFIG_ENTROPY_STATS
++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
[tx_type];
+#endif // CONFIG_ENTROPY_STATS
+ update_cdf(
+ fc->intra_ext_tx_cdf[eset][txsize_sqr_map[tx_size]][mbmi->mode],
+ av1_ext_tx_ind[tx_set_type][tx_type],
+ av1_num_ext_tx_set[tx_set_type]);
+ }
+#else
+ (void)tx_type;
+ (void)fc;
+ if (is_inter) {
+ if (LGT_FROM_PRED_INTER) {
+ if (is_lgt_allowed(mbmi->mode, tx_size) && !cm->reduced_tx_set_used)
+ ++counts->inter_lgt[txsize_sqr_map[tx_size]][mbmi->use_lgt];
+#if CONFIG_ENTROPY_STATS
+ if (!mbmi->use_lgt)
+ ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]][tx_type];
+ else
+#endif // CONFIG_ENTROPY_STATS
+ mbmi->tx_type = DCT_DCT;
+ } else {
+#if CONFIG_ENTROPY_STATS
+ ++counts->inter_ext_tx[eset][txsize_sqr_map[tx_size]][tx_type];
+#endif // CONFIG_ENTROPY_STATS
+ }
+ } else {
+ if (LGT_FROM_PRED_INTRA) {
+ if (is_lgt_allowed(mbmi->mode, tx_size) && !cm->reduced_tx_set_used)
+ ++counts->intra_lgt[txsize_sqr_map[tx_size]][mbmi->mode]
+ [mbmi->use_lgt];
+#if CONFIG_ENTROPY_STATS
+ if (!mbmi->use_lgt)
+ ++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
+ [tx_type];
+ else
+#endif // CONFIG_ENTROPY_STATS
+ mbmi->tx_type = DCT_DCT;
+ } else {
+#if CONFIG_ENTROPY_STATS
+ ++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
+ [tx_type];
+#endif // CONFIG_ENTROPY_STATS
+ }
}
+#endif // CONFIG_LGT_FROM_PRED
}
}
#else
@@ -5932,10 +6254,20 @@ void av1_update_tx_type_count(const AV1_COMMON *cm, MACROBLOCKD *xd,
!mbmi->skip &&
!segfeature_active(&cm->seg, mbmi->segment_id, SEG_LVL_SKIP)) {
if (is_inter) {
+#if CONFIG_ENTROPY_STATS
++counts->inter_ext_tx[tx_size][tx_type];
+#endif // CONFIG_ENTROPY_STATS
+ update_cdf(fc->inter_ext_tx_cdf[tx_size], av1_ext_tx_ind[tx_type],
+ TX_TYPES);
} else {
+#if CONFIG_ENTROPY_STATS
++counts->intra_ext_tx[tx_size][intra_mode_to_tx_type_context[mbmi->mode]]
[tx_type];
+#endif // CONFIG_ENTROPY_STATS
+ update_cdf(
+ fc->intra_ext_tx_cdf[tx_size]
+ [intra_mode_to_tx_type_context[mbmi->mode]],
+ av1_ext_tx_ind[tx_type], TX_TYPES);
}
}
#endif // CONFIG_EXT_TX
@@ -5966,29 +6298,48 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
x->pvq_speed = 0;
x->pvq_coded = (dry_run == OUTPUT_ENABLED) ? 1 : 0;
#endif
-#if CONFIG_CFL
- x->cfl_store_y = 1;
-#endif
if (!is_inter) {
+#if CONFIG_CFL
+ xd->cfl->store_y = 1;
+#endif // CONFIG_CFL
int plane;
mbmi->skip = 1;
for (plane = 0; plane < MAX_MB_PLANE; ++plane) {
av1_encode_intra_block_plane((AV1_COMMON *)cm, x, block_size, plane, 1,
mi_row, mi_col);
}
+#if CONFIG_CFL
+ xd->cfl->store_y = 0;
+#if CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
+ if (is_chroma_reference(mi_row, mi_col, bsize, xd->cfl->subsampling_x,
+ xd->cfl->subsampling_y) &&
+ !xd->cfl->are_parameters_computed) {
+ cfl_clear_sub8x8_val(xd->cfl);
+ }
+#endif // CONFIG_CHROMA_SUB8X8 && CONFIG_DEBUG
+#endif // CONFIG_CFL
if (!dry_run) {
sum_intra_stats(td->counts, xd, mi, xd->above_mi, xd->left_mi,
frame_is_intra_only(cm), mi_row, mi_col);
}
-#if CONFIG_PALETTE
- if (bsize >= BLOCK_8X8 && !dry_run) {
+
+// TODO(anybody) : remove this flag when PVQ supports pallete coding tool
+#if !CONFIG_PVQ
+ if (bsize >= BLOCK_8X8) {
for (plane = 0; plane <= 1; ++plane) {
- if (mbmi->palette_mode_info.palette_size[plane] > 0)
- av1_tokenize_palette_sb(cpi, td, plane, t, dry_run, bsize, rate);
+ if (mbmi->palette_mode_info.palette_size[plane] > 0) {
+ if (!dry_run)
+ av1_tokenize_color_map(x, plane, 0, t, bsize, mbmi->tx_size,
+ PALETTE_MAP);
+ else if (dry_run == DRY_RUN_COSTCOEFFS)
+ rate += av1_cost_color_map(x, plane, 0, bsize, mbmi->tx_size,
+ PALETTE_MAP);
+ }
}
}
-#endif // CONFIG_PALETTE
+#endif // !CONFIG_PVQ
+
#if CONFIG_VAR_TX
mbmi->min_tx_size = get_min_tx_size(mbmi->tx_size);
#endif
@@ -6012,7 +6363,7 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
av1_setup_pre_planes(xd, ref, cfg, mi_row, mi_col,
&xd->block_refs[ref]->sf);
}
-#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
+#if CONFIG_COMPOUND_SINGLEREF
// Single ref compound mode
if (!is_compound && is_inter_singleref_comp_mode(mbmi->mode)) {
xd->block_refs[1] = xd->block_refs[0];
@@ -6024,9 +6375,11 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
#endif // !CONFIG_INTRABC
av1_setup_pre_planes(xd, 1, cfg, mi_row, mi_col, &xd->block_refs[1]->sf);
}
-#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
+#endif // CONFIG_COMPOUND_SINGLEREF
av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, block_size);
+
+#if !CONFIG_NCOBMC_ADAPT_WEIGHT
#if CONFIG_MOTION_VAR
if (mbmi->motion_mode == OBMC_CAUSAL) {
#if CONFIG_NCOBMC
@@ -6037,6 +6390,17 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
}
#endif // CONFIG_MOTION_VAR
+#else
+ if (mbmi->motion_mode == OBMC_CAUSAL) {
+ av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
+ } else if (mbmi->motion_mode == NCOBMC_ADAPT_WEIGHT &&
+ dry_run == OUTPUT_ENABLED) {
+ int p;
+ for (p = 0; p < MAX_MB_PLANE; ++p) {
+ get_pred_from_intrpl_buf(xd, mi_row, mi_col, block_size, p);
+ }
+ }
+#endif
av1_encode_sb((AV1_COMMON *)cm, x, block_size, mi_row, mi_col);
#if CONFIG_VAR_TX
@@ -6053,7 +6417,7 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
}
#if CONFIG_DIST_8X8 && CONFIG_CB4X4
- if (bsize < BLOCK_8X8) {
+ if (x->using_dist_8x8 && bsize < BLOCK_8X8) {
dist_8x8_set_sub8x8_dst(x, (uint8_t *)x->decoded_8x8, bsize,
block_size_wide[bsize], block_size_high[bsize],
mi_row, mi_col);
@@ -6079,8 +6443,8 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
tx_partition_count_update(cm, x, bsize, mi_row, mi_col, td->counts);
} else {
const int tx_size_ctx = get_tx_size_context(xd);
- const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
- : intra_tx_size_cat_lookup[bsize];
+ const int32_t tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
+ : intra_tx_size_cat_lookup[bsize];
const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
const int depth = tx_size_to_depth(coded_tx_size);
++td->counts->tx_size[tx_size_cat][tx_size_ctx][depth];
@@ -6088,8 +6452,8 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
}
#else
const int tx_size_ctx = get_tx_size_context(xd);
- const int tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
- : intra_tx_size_cat_lookup[bsize];
+ const int32_t tx_size_cat = is_inter ? inter_tx_size_cat_lookup[bsize]
+ : intra_tx_size_cat_lookup[bsize];
const TX_SIZE coded_tx_size = txsize_sqr_up_map[tx_size];
const int depth = tx_size_to_depth(coded_tx_size);
@@ -6141,9 +6505,6 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
#endif
}
- ++td->counts->tx_size_totals[txsize_sqr_map[tx_size]];
- ++td->counts->tx_size_totals[txsize_sqr_map[av1_get_uv_tx_size(
- mbmi, &xd->plane[1])]];
#if !CONFIG_TXK_SEL
av1_update_tx_type_count(cm, xd, bsize, tx_size, td->counts);
#endif
@@ -6156,27 +6517,46 @@ static void encode_superblock(const AV1_COMP *const cpi, ThreadData *td,
#else
mbmi->sb_type >= BLOCK_8X8 &&
#endif
- is_inter && !(mbmi->skip || seg_skip)) {
+ is_inter && !(mbmi->skip || seg_skip) &&
+ !xd->lossless[mbmi->segment_id]) {
if (dry_run) tx_partition_set_contexts(cm, xd, bsize, mi_row, mi_col);
} else {
TX_SIZE tx_size = mbmi->tx_size;
// The new intra coding scheme requires no change of transform size
- if (is_inter)
- tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, is_inter);
- else
+ if (is_inter) {
+ if (xd->lossless[mbmi->segment_id]) {
+ tx_size = TX_4X4;
+ } else {
+ tx_size = tx_size_from_tx_mode(bsize, cm->tx_mode, is_inter);
+ }
+ } else {
tx_size = (bsize > BLOCK_4X4) ? tx_size : TX_4X4;
+ }
mbmi->tx_size = tx_size;
set_txfm_ctxs(tx_size, xd->n8_w, xd->n8_h, (mbmi->skip || seg_skip), xd);
}
#endif // CONFIG_VAR_TX
+#if CONFIG_CFL && CONFIG_CHROMA_SUB8X8
+ CFL_CTX *const cfl = xd->cfl;
+#if CONFIG_DEBUG
+ if (is_chroma_reference(mi_row, mi_col, bsize, cfl->subsampling_x,
+ cfl->subsampling_y) &&
+ !cfl->are_parameters_computed) {
+ cfl_clear_sub8x8_val(cfl);
+ }
+#endif // CONFIG_DEBUG
+ if (is_inter_block(mbmi) &&
+ !is_chroma_reference(mi_row, mi_col, bsize, cfl->subsampling_x,
+ cfl->subsampling_y)) {
+ cfl_store_block(xd, mbmi->sb_type, mbmi->tx_size);
+ }
+#endif // CONFIG_CFL && CONFIG_CHROMA_SUB8X8
}
#if CONFIG_SUPERTX
static int check_intra_b(PICK_MODE_CONTEXT *ctx) {
if (!is_inter_mode((&ctx->mic)->mbmi.mode)) return 1;
-#if CONFIG_EXT_INTER
if (ctx->mic.mbmi.ref_frame[1] == INTRA_FRAME) return 1;
-#endif // CONFIG_EXT_INTER
return 0;
}
@@ -6235,6 +6615,9 @@ static int check_intra_sb(const AV1_COMP *const cpi, const TileInfo *const tile,
}
break;
#if CONFIG_EXT_PARTITION_TYPES
+#if CONFIG_EXT_PARTITION_TYPES_AB
+#error HORZ/VERT_A/B partitions not yet updated in superres code
+#endif
case PARTITION_HORZ_A:
for (i = 0; i < 3; i++) {
if (check_intra_b(&pc_tree->horizontala[i])) return 1;
@@ -6289,6 +6672,9 @@ static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
else
return check_supertx_sb(subsize, supertx_size, pc_tree->split[0]);
#if CONFIG_EXT_PARTITION_TYPES
+#if CONFIG_EXT_PARTITION_TYPES_AB
+#error HORZ/VERT_A/B partitions not yet updated in superres code
+#endif
case PARTITION_HORZ_A:
return check_supertx_b(supertx_size, &pc_tree->horizontala[0]);
case PARTITION_HORZ_B:
@@ -6303,10 +6689,8 @@ static int check_supertx_sb(BLOCK_SIZE bsize, TX_SIZE supertx_size,
}
static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
-#if CONFIG_EXT_INTER
- int mi_row_ori, int mi_col_ori,
-#endif // CONFIG_EXT_INTER
- int mi_row_pred, int mi_col_pred, int plane,
+ int mi_row_ori, int mi_col_ori, int mi_row_pred,
+ int mi_col_pred, int plane,
BLOCK_SIZE bsize_pred, int b_sub8x8, int block) {
// Used in supertx
// (mi_row_ori, mi_col_ori): location for mv
@@ -6328,7 +6712,7 @@ static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
&xd->block_refs[ref]->sf);
}
-#if CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
+#if CONFIG_COMPOUND_SINGLEREF
// Single ref compound mode
if (!is_compound && is_inter_singleref_comp_mode(mbmi->mode)) {
xd->block_refs[1] = xd->block_refs[0];
@@ -6336,20 +6720,14 @@ static void predict_superblock(const AV1_COMP *const cpi, ThreadData *td,
av1_setup_pre_planes(xd, 1, cfg, mi_row_pred, mi_col_pred,
&xd->block_refs[1]->sf);
}
-#endif // CONFIG_EXT_INTER && CONFIG_COMPOUND_SINGLEREF
+#endif // CONFIG_COMPOUND_SINGLEREF
if (!b_sub8x8)
- av1_build_inter_predictor_sb_extend(cm, xd,
-#if CONFIG_EXT_INTER
- mi_row_ori, mi_col_ori,
-#endif // CONFIG_EXT_INTER
+ av1_build_inter_predictor_sb_extend(cm, xd, mi_row_ori, mi_col_ori,
mi_row_pred, mi_col_pred, plane,
bsize_pred);
else
- av1_build_inter_predictor_sb_sub8x8_extend(cm, xd,
-#if CONFIG_EXT_INTER
- mi_row_ori, mi_col_ori,
-#endif // CONFIG_EXT_INTER
+ av1_build_inter_predictor_sb_sub8x8_extend(cm, xd, mi_row_ori, mi_col_ori,
mi_row_pred, mi_col_pred, plane,
bsize_pred, block);
}
@@ -6390,12 +6768,8 @@ static void predict_b_extend(const AV1_COMP *const cpi, ThreadData *td,
dst_buf + (r >> xd->plane[plane].subsampling_y) * dst_stride +
(c >> xd->plane[plane].subsampling_x);
- predict_superblock(cpi, td,
-#if CONFIG_EXT_INTER
- mi_row_ori, mi_col_ori,
-#endif // CONFIG_EXT_INTER
- mi_row_pred, mi_col_pred, plane, bsize_pred, b_sub8x8,
- block);
+ predict_superblock(cpi, td, mi_row_ori, mi_col_ori, mi_row_pred, mi_col_pred,
+ plane, bsize_pred, b_sub8x8, block);
if (!dry_run && (plane == 0) && (block == 0 || !b_sub8x8))
update_stats(&cpi->common, td, mi_row_pred, mi_col_pred, 1);
@@ -6940,6 +7314,9 @@ static void predict_sb_complex(const AV1_COMP *const cpi, ThreadData *td,
}
break;
#if CONFIG_EXT_PARTITION_TYPES
+#if CONFIG_EXT_PARTITION_TYPES_AB
+#error HORZ/VERT_A/B partitions not yet updated in superres code
+#endif
case PARTITION_HORZ_A:
predict_b_extend(cpi, td, tile, 0, mi_row, mi_col, mi_row, mi_col,
mi_row_top, mi_col_top, dst_buf, dst_stride, top_bsize,
@@ -7130,9 +7507,6 @@ static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
TX_SIZE tx_size;
MB_MODE_INFO *mbmi;
TX_TYPE tx_type, best_tx_nostx;
-#if CONFIG_EXT_TX
- int ext_tx_set;
-#endif // CONFIG_EXT_TX
int tmp_rate_tx = 0, skip_tx = 0;
int64_t tmp_dist_tx = 0, rd_tx, bestrd_tx = INT64_MAX;
@@ -7202,7 +7576,9 @@ static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
tx_size = max_txsize_lookup[bsize];
av1_subtract_plane(x, bsize, 0);
#if CONFIG_EXT_TX
- ext_tx_set = get_ext_tx_set(tx_size, bsize, 1, cm->reduced_tx_set_used);
+ int ext_tx_set = get_ext_tx_set(tx_size, bsize, 1, cm->reduced_tx_set_used);
+ const TxSetType tx_set_type =
+ get_ext_tx_set_type(tx_size, bsize, 1, cm->reduced_tx_set_used);
#endif // CONFIG_EXT_TX
for (tx_type = DCT_DCT; tx_type < TX_TYPES; ++tx_type) {
#if CONFIG_VAR_TX
@@ -7213,7 +7589,7 @@ static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
#endif // CONFIG_VAR_TX
#if CONFIG_EXT_TX
- if (!ext_tx_used_inter[ext_tx_set][tx_type]) continue;
+ if (!av1_ext_tx_used[tx_set_type][tx_type]) continue;
#else
if (tx_size >= TX_32X32 && tx_type != DCT_DCT) continue;
#endif // CONFIG_EXT_TX
@@ -7239,12 +7615,12 @@ static void rd_supertx_sb(const AV1_COMP *const cpi, ThreadData *td,
!xd->lossless[xd->mi[0]->mbmi.segment_id] && this_rate != INT_MAX) {
if (ext_tx_set > 0)
this_rate +=
- cpi->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
+ x->inter_tx_type_costs[ext_tx_set][mbmi->tx_size][mbmi->tx_type];
}
#else
if (tx_size < TX_32X32 && !xd->lossless[xd->mi[0]->mbmi.segment_id] &&
this_rate != INT_MAX) {
- this_rate += cpi->inter_tx_type_costs[tx_size][mbmi->tx_type];
+ this_rate += x->inter_tx_type_costs[tx_size][mbmi->tx_type];
}
#endif // CONFIG_EXT_TX
*tmp_rate = rate_uv + this_rate;