Use tx_size_cdf with CONFIG_EC_MULTISYMBOL.
This commit produces a bit-exact bitstream because prior calls to code
the tx_size using aom_write_tree() would automatically convert the
aom_tree_index on the fly to a CDF.
The tx_size_cdf[]'s are now computed once per frame.
Based on recent tests, this patch reduces decode time by 4%.
Change-Id: I920dbf036b8a9574ea6e65ae5f9c43eef1c3f864
diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index 1ae3a52..e36c52c 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -1632,6 +1632,10 @@
av1_tree_to_cdf_2D(av1_intra_mode_tree, av1_kf_y_mode_prob, av1_kf_y_mode_cdf,
INTRA_MODES, INTRA_MODES);
av1_tree_to_cdf(av1_segment_tree, fc->seg.tree_probs, fc->seg.tree_cdf);
+ for (int k = 0; k < MAX_TX_DEPTH; k++) {
+ av1_tree_to_cdf_1D(av1_tx_size_tree[k], fc->tx_size_probs[k],
+ fc->tx_size_cdf[k], TX_SIZE_CONTEXTS);
+ }
#endif
#if CONFIG_DELTA_Q
av1_copy(fc->delta_q_prob, default_delta_q_probs);
@@ -1684,6 +1688,12 @@
av1_tree_to_cdf(av1_ext_tx_tree, fc->inter_ext_tx_prob[i],
fc->inter_ext_tx_cdf[i]);
#endif
+ for (i = 0; i < MAX_TX_DEPTH; i++) {
+ for (j = 0; j < TX_SIZE_CONTEXTS; j++) {
+ av1_tree_to_cdf(av1_tx_size_tree[i], fc->tx_size_probs[i][j],
+ fc->tx_size_cdf[i][j]);
+ }
+ }
}
#endif
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index 8dfae58..64f3ddf 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -243,6 +243,8 @@
multiple copies for adaptation in tiles easier */
aom_cdf_prob kf_y_cdf[INTRA_MODES][INTRA_MODES]
[INTRA_MODES + CONFIG_EC_ADAPT];
+ aom_cdf_prob tx_size_cdf[MAX_TX_DEPTH][TX_SIZE_CONTEXTS]
+ [MAX_TX_DEPTH + 1 + CONFIG_EC_ADAPT];
#if !CONFIG_EXT_TX
aom_cdf_prob intra_ext_tx_cdf[EXT_TX_SIZES][TX_TYPES]
[TX_TYPES + CONFIG_EC_ADAPT];
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index e7d386f..a5b4cbc 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -404,8 +404,13 @@
FRAME_COUNTS *counts = xd->counts;
const int ctx = get_tx_size_context(xd);
const int depth =
+#if CONFIG_EC_MULTISYMBOL
+ aom_read_symbol(r, cm->fc->tx_size_cdf[tx_size_cat][ctx], tx_size_cat + 2,
+ ACCT_STR);
+#else
aom_read_tree(r, av1_tx_size_tree[tx_size_cat],
cm->fc->tx_size_probs[tx_size_cat][ctx], ACCT_STR);
+#endif
const TX_SIZE tx_size = depth_to_tx_size(depth);
#if CONFIG_RECT_TX
assert(!is_rect_tx(tx_size));
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index bda7217..8331e8a 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -80,6 +80,7 @@
static struct av1_token palette_color_index_encodings[PALETTE_MAX_SIZE - 1]
[PALETTE_MAX_SIZE];
#endif // CONFIG_PALETTE
+#if !CONFIG_EC_MULTISYMBOL
static const struct av1_token tx_size_encodings[MAX_TX_DEPTH][TX_SIZES] = {
{ { 0, 1 }, { 1, 1 } }, // Max tx_size is 8X8
{ { 0, 1 }, { 2, 2 }, { 3, 2 } }, // Max tx_size is 16X16
@@ -88,6 +89,7 @@
{ { 0, 1 }, { 2, 2 }, { 6, 3 }, { 14, 4 }, { 15, 4 } }, // Max tx_size 64X64
#endif // CONFIG_TX64X64
};
+#endif
#if CONFIG_EXT_INTRA || CONFIG_FILTER_INTRA || CONFIG_PALETTE
static INLINE void write_uniform(aom_writer *w, int n, int v) {
@@ -456,9 +458,14 @@
IMPLIES(is_rect_tx(tx_size), tx_size == max_txsize_rect_lookup[bsize]));
#endif // CONFIG_EXT_TX && CONFIG_RECT_TX
+#if CONFIG_EC_MULTISYMBOL
+ aom_write_symbol(w, depth, cm->fc->tx_size_cdf[tx_size_cat][tx_size_ctx],
+ tx_size_cat + 2);
+#else
av1_write_token(w, av1_tx_size_tree[tx_size_cat],
cm->fc->tx_size_probs[tx_size_cat][tx_size_ctx],
&tx_size_encodings[tx_size_cat][depth]);
+#endif
}
}