Add cdf_update_mode experiment
Allow the CDF update to operate in different modes, e.g. update vs no
update.
The update mode is transmitted in the uncompressed frame header of
every keyframe and intra-only frame.
This patch only adds bitstream signaling and API support. The
implementation of the update modes will be in later patches.
Change-Id: Ic9fcd60e8a75f9c01f414253823d78cf9b3113dd
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 4152165..a17c810 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3757,6 +3757,9 @@
#endif
aom_wb_write_bit(wb, cm->allow_intrabc);
#endif // CONFIG_INTRABC
+#if CONFIG_CDF_UPDATE_MODE
+ aom_wb_write_literal(wb, cm->cdf_update_mode, 2);
+#endif // CONFIG_CDF_UPDATE_MODE
} else {
#if !CONFIG_NO_FRAME_CONTEXT_SIGNALING
if (!cm->error_resilient_mode) {
@@ -3800,6 +3803,9 @@
#endif
aom_wb_write_bit(wb, cm->allow_intrabc);
#endif // CONFIG_INTRABC
+#if CONFIG_CDF_UPDATE_MODE
+ aom_wb_write_literal(wb, cm->cdf_update_mode, 2);
+#endif // CONFIG_CDF_UPDATE_MODE
} else {
aom_wb_write_literal(wb, cpi->refresh_frame_mask, REF_FRAMES);
@@ -4108,6 +4114,9 @@
#endif
aom_wb_write_bit(wb, cm->allow_intrabc);
#endif // CONFIG_INTRABC
+#if CONFIG_CDF_UPDATE_MODE
+ aom_wb_write_literal(wb, cm->cdf_update_mode, 2);
+#endif // CONFIG_CDF_UPDATE_MODE
} else if (cm->frame_type == INTRA_ONLY_FRAME) {
#if !CONFIG_NO_FRAME_CONTEXT_SIGNALING
if (!cm->error_resilient_mode) {
@@ -4137,6 +4146,9 @@
#endif
aom_wb_write_bit(wb, cm->allow_intrabc);
#endif // CONFIG_INTRABC
+#if CONFIG_CDF_UPDATE_MODE
+ aom_wb_write_literal(wb, cm->cdf_update_mode, 2);
+#endif // CONFIG_CDF_UPDATE_MODE
}
} else if (cm->frame_type == INTER_FRAME) {
MV_REFERENCE_FRAME ref_frame;
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index b4e2623..80637f2 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -356,9 +356,10 @@
InterpFilter filter =
av1_extract_interp_filter(mbmi->interp_filters, dir);
++counts->switchable_interp[ctx][filter];
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(xd->tile_ctx->switchable_interp_cdf[ctx], filter,
SWITCHABLE_FILTERS);
+ }
}
}
}
@@ -824,10 +825,11 @@
}
#endif // CONFIG_ENTROPY_STATS
if (allow_update_cdf) {
- if (use_filter_intra_mode)
+ if (use_filter_intra_mode) {
update_cdf(fc->filter_intra_mode_cdf,
mbmi->filter_intra_mode_info.filter_intra_mode,
FILTER_INTRA_MODES);
+ }
update_cdf(fc->filter_intra_cdfs[mbmi->tx_size], use_filter_intra_mode,
2);
}
@@ -840,10 +842,11 @@
++counts->angle_delta[mbmi->mode - V_PRED]
[mbmi->angle_delta[PLANE_TYPE_Y] + MAX_ANGLE_DELTA];
#endif
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(fc->angle_delta_cdf[mbmi->mode - V_PRED],
mbmi->angle_delta[PLANE_TYPE_Y] + MAX_ANGLE_DELTA,
2 * MAX_ANGLE_DELTA + 1);
+ }
}
#endif // CONFIG_EXT_INTRA_MOD
@@ -858,10 +861,11 @@
++counts->angle_delta[mbmi->uv_mode - V_PRED]
[mbmi->angle_delta[PLANE_TYPE_UV] + MAX_ANGLE_DELTA];
#endif
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(fc->angle_delta_cdf[mbmi->uv_mode - V_PRED],
mbmi->angle_delta[PLANE_TYPE_UV] + MAX_ANGLE_DELTA,
2 * MAX_ANGLE_DELTA + 1);
+ }
}
#endif // CONFIG_EXT_INTRA_MOD
#if CONFIG_ENTROPY_STATS
@@ -1005,13 +1009,13 @@
frame_is_intra_only(cm), mi_row, mi_col,
tile_data->allow_update_cdf);
if (av1_allow_palette(cm->allow_screen_content_tools, bsize) &&
- tile_data->allow_update_cdf)
+ allow_update_cdf)
update_palette_cdf(xd, mi);
}
#if CONFIG_INTRABC
if (frame_is_intra_only(cm) && av1_allow_intrabc(cm)) {
- if (tile_data->allow_update_cdf)
+ if (allow_update_cdf)
update_cdf(fc->intrabc_cdf, is_intrabc_block(mbmi), 2);
#if CONFIG_ENTROPY_STATS
++td->counts->intrabc[is_intrabc_block(mbmi)];
@@ -1040,9 +1044,10 @@
if (!seg_ref_active) {
counts->intra_inter[av1_get_intra_inter_context(xd)][inter_block]++;
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(fc->intra_inter_cdf[av1_get_intra_inter_context(xd)],
inter_block, 2);
+ }
// 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.
@@ -1061,9 +1066,10 @@
counts->comp_inter[av1_get_reference_mode_context(cm, xd)]
[has_second_ref(mbmi)]++;
#endif // CONFIG_ENTROPY_STATS
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(av1_get_reference_mode_cdf(cm, xd),
has_second_ref(mbmi), 2);
+ }
}
}
@@ -1220,14 +1226,16 @@
if (allow_update_cdf)
update_cdf(fc->interintra_cdf[bsize_group], 1, 2);
counts->interintra_mode[bsize_group][mbmi->interintra_mode]++;
- if (allow_update_cdf)
+ if (allow_update_cdf) {
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 (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(fc->wedge_interintra_cdf[bsize],
mbmi->use_wedge_interintra, 2);
+ }
}
} else {
counts->interintra[bsize_group][0]++;
@@ -1242,14 +1250,16 @@
if (mbmi->ref_frame[1] != INTRA_FRAME) {
if (motion_allowed == WARPED_CAUSAL) {
counts->motion_mode[bsize][mbmi->motion_mode]++;
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(fc->motion_mode_cdf[bsize], mbmi->motion_mode,
MOTION_MODES);
+ }
} else if (motion_allowed == OBMC_CAUSAL) {
counts->obmc[bsize][mbmi->motion_mode == OBMC_CAUSAL]++;
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(fc->obmc_cdf[bsize], mbmi->motion_mode == OBMC_CAUSAL,
2);
+ }
}
}
@@ -1264,26 +1274,29 @@
if (masked_compound_used) {
const int comp_group_idx_ctx = get_comp_group_idx_context(xd);
++counts->comp_group_idx[comp_group_idx_ctx][mbmi->comp_group_idx];
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(fc->comp_group_idx_cdf[comp_group_idx_ctx],
mbmi->comp_group_idx, 2);
+ }
}
if (mbmi->comp_group_idx == 0) {
const int comp_index_ctx = get_comp_index_context(cm, xd);
++counts->compound_index[comp_index_ctx][mbmi->compound_idx];
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(fc->compound_index_cdf[comp_index_ctx],
mbmi->compound_idx, 2);
+ }
} else {
assert(masked_compound_used);
if (is_interinter_compound_used(COMPOUND_WEDGE, bsize)) {
counts->compound_interinter[bsize]
[mbmi->interinter_compound_type - 1]++;
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(fc->compound_type_cdf[bsize],
mbmi->interinter_compound_type - 1,
COMPOUND_TYPES - 1);
+ }
}
}
}
@@ -1294,9 +1307,10 @@
if (is_interinter_compound_used(COMPOUND_WEDGE, bsize)) {
counts
->compound_interinter[bsize][mbmi->interinter_compound_type]++;
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(fc->compound_type_cdf[bsize],
mbmi->interinter_compound_type, COMPOUND_TYPES);
+ }
}
}
#endif // CONFIG_JNT_COMP
@@ -1323,9 +1337,10 @@
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)];
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(fc->inter_compound_mode_cdf[mode_ctx],
INTER_COMPOUND_OFFSET(mode), INTER_COMPOUND_MODES);
+ }
} else {
mode_ctx =
av1_mode_context_analyzer(mbmi_ext->mode_context, mbmi->ref_frame);
@@ -3868,7 +3883,6 @@
pre_tok = cpi->tile_tok[tile_row][tile_col];
tile_tok = allocated_tokens(
*tile_info, cm->seq_params.mib_size_log2 + MI_SIZE_LOG2, num_planes);
-
#if CONFIG_EXT_TILE
tile_data->allow_update_cdf = !cm->large_scale_tile;
#else
@@ -4251,6 +4265,9 @@
cm->allow_screen_content_tools =
cm->seq_params.force_screen_content_tools;
}
+#if CONFIG_CDF_UPDATE_MODE
+ cm->cdf_update_mode = cpi->oxcf.cdf_update_mode;
+#endif // CONFIG_CDF_UPDATE_MODE
}
#if CONFIG_INTRABC
@@ -4861,10 +4878,11 @@
const TxSetType tx_set_type = get_ext_tx_set_type(
tx_size, bsize, is_inter, cm->reduced_tx_set_used);
if (is_inter) {
- if (allow_update_cdf)
+ if (allow_update_cdf) {
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
@@ -4880,21 +4898,23 @@
++counts
->intra_ext_tx[eset][txsize_sqr_map[tx_size]][intra_dir][tx_type];
#endif // CONFIG_ENTROPY_STATS
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(
fc->intra_ext_tx_cdf[eset][txsize_sqr_map[tx_size]][intra_dir],
av1_ext_tx_ind[tx_set_type][tx_type],
av1_num_ext_tx_set[tx_set_type]);
+ }
#else
#if CONFIG_ENTROPY_STATS
++counts->intra_ext_tx[eset][txsize_sqr_map[tx_size]][mbmi->mode]
[tx_type];
#endif // CONFIG_ENTROPY_STATS
- if (allow_update_cdf)
+ if (allow_update_cdf) {
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]);
+ }
#endif
}
}
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 9c18941..d2c391e 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -309,6 +309,9 @@
int film_grain_test_vector;
#endif
+#if CONFIG_CDF_UPDATE_MODE
+ uint8_t cdf_update_mode;
+#endif // CONFIG_CDF_UPDATE_MODE
#if CONFIG_EXT_PARTITION
aom_superblock_size_t superblock_size;
#endif // CONFIG_EXT_PARTITION
diff --git a/av1/encoder/encodetxb.c b/av1/encoder/encodetxb.c
index 83d4598..569b3d2 100644
--- a/av1/encoder/encodetxb.c
+++ b/av1/encoder/encodetxb.c
@@ -209,28 +209,32 @@
break;
case 3:
++counts->eob_multi128[plane][eob_multi_ctx][eob_pt - 1];
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(ec_ctx->eob_flag_cdf128[plane][eob_multi_ctx], eob_pt - 1,
8);
+ }
break;
case 4:
++counts->eob_multi256[plane][eob_multi_ctx][eob_pt - 1];
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(ec_ctx->eob_flag_cdf256[plane][eob_multi_ctx], eob_pt - 1,
9);
+ }
break;
case 5:
++counts->eob_multi512[plane][eob_multi_ctx][eob_pt - 1];
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(ec_ctx->eob_flag_cdf512[plane][eob_multi_ctx], eob_pt - 1,
10);
+ }
break;
case 6:
default:
++counts->eob_multi1024[plane][eob_multi_ctx][eob_pt - 1];
- if (allow_update_cdf)
+ if (allow_update_cdf) {
update_cdf(ec_ctx->eob_flag_cdf1024[plane][eob_multi_ctx], eob_pt - 1,
11);
+ }
break;
}