From 785e975ae2e7cce2cc3985bd691b728d033116a1 Mon Sep 17 00:00:00 2001
From: "Nathan E. Egge" <negge@mozilla.com>
Date: Tue, 26 Apr 2016 12:31:14 -0400
Subject: [PATCH] Update intra_ext_tx_cdf per frame.

Move computing the intra_ext_tx_cdf tables per symbol to
 computing them only when the probabilities are updated.

Change-Id: I26d5e419e103093e98a7d896c196176305b50fc9
---
 av1/common/entropymode.c  | 12 +++++++++++-
 av1/common/entropymode.h  |  5 +++++
 av1/decoder/decodeframe.c |  7 ++++++-
 av1/decoder/decodemv.c    |  5 +++++
 av1/decoder/decoder.c     |  2 ++
 av1/encoder/bitstream.c   | 20 +++++++++++++++++++-
 6 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/av1/common/entropymode.c b/av1/common/entropymode.c
index d140836d25..03bd120f66 100644
--- a/av1/common/entropymode.c
+++ b/av1/common/entropymode.c
@@ -353,6 +353,9 @@ const aom_tree_index av1_ext_tx_tree[TREE_SIZE(TX_TYPES)] = {
   -DCT_DCT, 2, -ADST_ADST, 4, -ADST_DCT, -DCT_ADST
 };
 
+int av1_ext_tx_ind[TX_TYPES];
+int av1_ext_tx_inv[TX_TYPES];
+
 static const aom_prob
     default_intra_ext_tx_prob[EXT_TX_SIZES][TX_TYPES][TX_TYPES - 1] = {
       { { 240, 85, 128 }, { 4, 1, 248 }, { 4, 1, 8 }, { 4, 248, 128 } },
@@ -399,6 +402,8 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
 #if CONFIG_DAALA_EC
   av1_tree_to_cdf_1D(av1_switchable_interp_tree, fc->switchable_interp_prob,
                      fc->switchable_interp_cdf, SWITCHABLE_FILTER_CONTEXTS);
+  av1_tree_to_cdf_2D(av1_ext_tx_tree, fc->intra_ext_tx_prob,
+                     fc->intra_ext_tx_cdf, EXT_TX_SIZES, TX_TYPES);
 #endif
 }
 
@@ -541,10 +546,15 @@ void av1_adapt_intra_frame_probs(AV1_COMMON *cm) {
 
   for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
     int j;
-    for (j = 0; j < TX_TYPES; ++j)
+    for (j = 0; j < TX_TYPES; ++j) {
       aom_tree_merge_probs(av1_ext_tx_tree, pre_fc->intra_ext_tx_prob[i][j],
                            counts->intra_ext_tx[i][j],
                            fc->intra_ext_tx_prob[i][j]);
+#if CONFIG_DAALA_EC
+      av1_tree_to_cdf(av1_ext_tx_tree, fc->intra_ext_tx_prob[i][j],
+                      fc->intra_ext_tx_cdf[i][j]);
+#endif
+    }
   }
   for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
     aom_tree_merge_probs(av1_ext_tx_tree, pre_fc->inter_ext_tx_prob[i],
diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h
index 6bf0ab7d97..d22c6e6da5 100644
--- a/av1/common/entropymode.h
+++ b/av1/common/entropymode.h
@@ -97,6 +97,7 @@ typedef struct frame_contexts {
 #if CONFIG_DAALA_EC
   uint16_t
       switchable_interp_cdf[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS];
+  uint16_t intra_ext_tx_cdf[EXT_TX_SIZES][TX_TYPES][TX_TYPES];
 #endif
 } FRAME_CONTEXT;
 
@@ -175,6 +176,10 @@ void av1_tx_counts_to_branch_counts_8x8(const unsigned int *tx_count_8x8p,
                                         unsigned int (*ct_8x8p)[2]);
 
 extern const aom_tree_index av1_ext_tx_tree[TREE_SIZE(TX_TYPES)];
+#if CONFIG_DAALA_EC
+extern int av1_ext_tx_ind[TX_TYPES];
+extern int av1_ext_tx_inv[TX_TYPES];
+#endif
 
 static INLINE int av1_ceil_log2(int n) {
   int i = 1, p = 2;
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 978176c6ac..1ef85ebb3a 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -1930,9 +1930,14 @@ static void read_ext_tx_probs(FRAME_CONTEXT *fc, aom_reader *r) {
   int i, j, k;
   if (aom_read(r, GROUP_DIFF_UPDATE_PROB)) {
     for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
-      for (j = 0; j < TX_TYPES; ++j)
+      for (j = 0; j < TX_TYPES; ++j) {
         for (k = 0; k < TX_TYPES - 1; ++k)
           av1_diff_update_prob(r, &fc->intra_ext_tx_prob[i][j][k]);
+#if CONFIG_DAALA_EC
+        av1_tree_to_cdf(av1_ext_tx_tree, fc->intra_ext_tx_prob[i][j],
+                        fc->intra_ext_tx_cdf[i][j]);
+#endif
+      }
     }
   }
   if (aom_read(r, GROUP_DIFF_UPDATE_PROB)) {
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index c2f84629a7..65a055f9f4 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -976,9 +976,14 @@ static void read_inter_frame_mode_info(AV1Decoder *const pbi,
       if (counts) ++counts->inter_ext_tx[mbmi->tx_size][mbmi->tx_type];
     } else {
       const TX_TYPE tx_type_nom = intra_mode_to_tx_type_context[mbmi->mode];
+#if CONFIG_DAALA_EC
+      mbmi->tx_type = av1_ext_tx_inv[aom_read_tree_cdf(
+          r, cm->fc->intra_ext_tx_cdf[mbmi->tx_size][tx_type_nom], TX_TYPES)];
+#else
       mbmi->tx_type =
           aom_read_tree(r, av1_ext_tx_tree,
                         cm->fc->intra_ext_tx_prob[mbmi->tx_size][tx_type_nom]);
+#endif
       if (counts)
         ++counts->intra_ext_tx[mbmi->tx_size][tx_type_nom][mbmi->tx_type];
     }
diff --git a/av1/decoder/decoder.c b/av1/decoder/decoder.c
index c75e00fd33..2c38cca5e9 100644
--- a/av1/decoder/decoder.c
+++ b/av1/decoder/decoder.c
@@ -46,6 +46,8 @@ static void initialize_dec(void) {
 #if CONFIG_DAALA_EC
     av1_indices_from_tree(av1_switchable_interp_ind, av1_switchable_interp_inv,
                           SWITCHABLE_FILTERS, av1_switchable_interp_tree);
+    av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, TX_TYPES,
+                          av1_ext_tx_tree);
 #endif
   }
 }
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 5b9e486a43..d961f1d1a3 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -71,6 +71,11 @@ void av1_encode_token_init() {
       an in-order traversal of the av1_switchable_interp_tree structure. */
   av1_indices_from_tree(av1_switchable_interp_ind, av1_switchable_interp_inv,
                         SWITCHABLE_FILTERS, av1_switchable_interp_tree);
+  /* This hack is necessary because the four TX_TYPES are not consecutive,
+      e.g., 0, 1, 2, 3, when doing an in-order traversal of the av1_ext_tx_tree
+      structure. */
+  av1_indices_from_tree(av1_ext_tx_ind, av1_ext_tx_inv, TX_TYPES,
+                        av1_ext_tx_tree);
 #endif
 }
 
@@ -285,9 +290,14 @@ static void update_ext_tx_probs(AV1_COMMON *cm, aom_writer *w) {
   aom_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
   if (do_update) {
     for (i = TX_4X4; i < EXT_TX_SIZES; ++i) {
-      for (j = 0; j < TX_TYPES; ++j)
+      for (j = 0; j < TX_TYPES; ++j) {
         prob_diff_update(av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
                          cm->counts.intra_ext_tx[i][j], TX_TYPES, w);
+#if CONFIG_DAALA_EC
+        av1_tree_to_cdf(av1_ext_tx_tree, cm->fc->intra_ext_tx_prob[i][j],
+                        cm->fc->intra_ext_tx_cdf[i][j]);
+#endif
+      }
     }
   }
   savings = 0;
@@ -701,11 +711,19 @@ static void pack_inter_mode_mvs(AV1_COMP *cpi, const MODE_INFO *mi,
                       cm->fc->inter_ext_tx_prob[mbmi->tx_size],
                       &ext_tx_encodings[mbmi->tx_type]);
     } else {
+#if CONFIG_DAALA_EC
+      aom_write_tree_cdf(
+          w, av1_ext_tx_ind[mbmi->tx_type],
+          cm->fc->intra_ext_tx_cdf[mbmi->tx_size]
+                                  [intra_mode_to_tx_type_context[mbmi->mode]],
+          TX_TYPES);
+#else
       av1_write_token(
           w, av1_ext_tx_tree,
           cm->fc->intra_ext_tx_prob[mbmi->tx_size]
                                    [intra_mode_to_tx_type_context[mbmi->mode]],
           &ext_tx_encodings[mbmi->tx_type]);
+#endif
     }
   } else {
     if (!mbmi->skip) assert(mbmi->tx_type == DCT_DCT);
-- 
GitLab