Implement bitstream debug for daala_ec

Change-Id: I809eb52e8a632189c49b8ea0a2b5de760cc2a34c
diff --git a/aom_dsp/aom_dsp.mk b/aom_dsp/aom_dsp.mk
index a06326d..97cd15f 100644
--- a/aom_dsp/aom_dsp.mk
+++ b/aom_dsp/aom_dsp.mk
@@ -24,16 +24,24 @@
 DSP_SRCS-$(CONFIG_ANS) += ans.c
 
 ifeq ($(CONFIG_ENCODERS),yes)
-DSP_SRCS-$(CONFIG_ANS) += answriter.h
-DSP_SRCS-yes += bitwriter.h
+ifeq ($(CONFIG_ANS),yes)
+DSP_SRCS-yes += answriter.h
+DSP_SRCS-yes += buf_ans.h
+DSP_SRCS-yes += buf_ans.c
+else ifeq ($(CONFIG_DAALA_EC),yes)
+DSP_SRCS-yes += entenc.c
+DSP_SRCS-yes += entenc.h
+DSP_SRCS-yes += daalaboolwriter.c
+DSP_SRCS-yes += daalaboolwriter.h
+else
 DSP_SRCS-yes += dkboolwriter.h
 DSP_SRCS-yes += dkboolwriter.c
+endif
+DSP_SRCS-yes += bitwriter.h
 DSP_SRCS-yes += bitwriter_buffer.c
 DSP_SRCS-yes += bitwriter_buffer.h
 DSP_SRCS-yes += psnr.c
 DSP_SRCS-yes += psnr.h
-DSP_SRCS-$(CONFIG_ANS) += buf_ans.h
-DSP_SRCS-$(CONFIG_ANS) += buf_ans.c
 DSP_SRCS-$(CONFIG_INTERNAL_STATS) += ssim.c
 DSP_SRCS-$(CONFIG_INTERNAL_STATS) += ssim.h
 DSP_SRCS-$(CONFIG_INTERNAL_STATS) += psnrhvs.c
@@ -41,10 +49,18 @@
 endif
 
 ifeq ($(CONFIG_DECODERS),yes)
-DSP_SRCS-$(CONFIG_ANS) += ansreader.h
-DSP_SRCS-yes += bitreader.h
+ifeq ($(CONFIG_ANS),yes)
+DSP_SRCS-yes += ansreader.h
+else ifeq ($(CONFIG_DAALA_EC),yes)
+DSP_SRCS-yes += entdec.c
+DSP_SRCS-yes += entdec.h
+DSP_SRCS-yes += daalaboolreader.c
+DSP_SRCS-yes += daalaboolreader.h
+else
 DSP_SRCS-yes += dkboolreader.h
 DSP_SRCS-yes += dkboolreader.c
+endif
+DSP_SRCS-yes += bitreader.h
 DSP_SRCS-yes += bitreader_buffer.c
 DSP_SRCS-yes += bitreader_buffer.h
 endif
@@ -53,16 +69,8 @@
 DSP_SRCS-yes += intrapred.c
 
 ifeq ($(CONFIG_DAALA_EC),yes)
-DSP_SRCS-yes += entenc.c
-DSP_SRCS-yes += entenc.h
-DSP_SRCS-yes += entdec.c
-DSP_SRCS-yes += entdec.h
 DSP_SRCS-yes += entcode.c
 DSP_SRCS-yes += entcode.h
-DSP_SRCS-yes += daalaboolreader.c
-DSP_SRCS-yes += daalaboolreader.h
-DSP_SRCS-yes += daalaboolwriter.c
-DSP_SRCS-yes += daalaboolwriter.h
 endif
 
 DSP_SRCS-$(HAVE_SSE) += x86/intrapred_sse2.asm
diff --git a/aom_dsp/daalaboolreader.h b/aom_dsp/daalaboolreader.h
index 8977995..d3b6679 100644
--- a/aom_dsp/daalaboolreader.h
+++ b/aom_dsp/daalaboolreader.h
@@ -18,6 +18,10 @@
 #if CONFIG_ACCOUNTING
 #include "av1/common/accounting.h"
 #endif
+#if CONFIG_BITSTREAM_DEBUG
+#include <stdio.h>
+#include "aom_util/debug_util.h"
+#endif  // CONFIG_BITSTREAM_DEBUG
 
 #ifdef __cplusplus
 extern "C" {
@@ -40,12 +44,60 @@
 uint32_t aom_daala_reader_tell_frac(const daala_reader *r);
 
 static INLINE int aom_daala_read(daala_reader *r, int prob) {
-  if (prob == 128) {
-    return od_ec_dec_bits(&r->ec, 1, "aom_bits");
-  } else {
-    int p = ((prob << 15) + (256 - prob)) >> 8;
-    return od_ec_decode_bool_q15(&r->ec, p);
+  int bit;
+  int p = ((prob << 15) + (256 - prob)) >> 8;
+#if CONFIG_BITSTREAM_DEBUG
+  {
+    const int queue_r = bitstream_queue_get_read();
+    const int frame_idx = bitstream_queue_get_frame_read();
+    if (frame_idx == 3 && queue_r == 72877) {
+      fprintf(stderr, "\n *** bitstream queue at frame_idx_r %d queue_r %d\n",
+              frame_idx, queue_r);
+    }
   }
+#endif
+
+  if (prob == 128) {
+    bit = od_ec_dec_bits(&r->ec, 1, "aom_bits");
+  } else {
+    bit = od_ec_decode_bool_q15(&r->ec, p);
+  }
+
+#if CONFIG_BITSTREAM_DEBUG
+  {
+    int i;
+    int ref_bit, ref_nsymbs;
+    aom_cdf_prob ref_cdf[16];
+    const int queue_r = bitstream_queue_get_read();
+    const int frame_idx = bitstream_queue_get_frame_read();
+    bitstream_queue_pop(&ref_bit, ref_cdf, &ref_nsymbs);
+    if (ref_nsymbs != 2) {
+      fprintf(stderr,
+              "\n *** [bit] nsymbs error, frame_idx_r %d nsymbs %d ref_nsymbs "
+              "%d queue_r %d\n",
+              frame_idx, 2, ref_nsymbs, queue_r);
+      assert(0);
+    }
+    if ((ref_nsymbs != 2) || (ref_cdf[0] != (aom_cdf_prob)p) ||
+        (ref_cdf[1] != 32767)) {
+      fprintf(stderr,
+              "\n *** [bit] cdf error, frame_idx_r %d cdf {%d, %d} ref_cdf {%d",
+              frame_idx, p, 32767, ref_cdf[0]);
+      for (i = 1; i < ref_nsymbs; ++i) fprintf(stderr, ", %d", ref_cdf[i]);
+      fprintf(stderr, "} queue_r %d\n", queue_r);
+      assert(0);
+    }
+    if (bit != ref_bit) {
+      fprintf(stderr,
+              "\n *** [bit] symb error, frame_idx_r %d symb %d ref_symb %d "
+              "queue_r %d\n",
+              frame_idx, bit, ref_bit, queue_r);
+      assert(0);
+    }
+  }
+#endif
+
+  return bit;
 }
 
 static INLINE int aom_daala_read_bit(daala_reader *r) {
@@ -56,6 +108,52 @@
   return r->ec.error;
 }
 
+static INLINE int daala_read_symbol(daala_reader *r, const aom_cdf_prob *cdf,
+                                    int nsymbs) {
+  int symb = od_ec_decode_cdf_q15(&r->ec, cdf, nsymbs);
+
+#if CONFIG_BITSTREAM_DEBUG
+  {
+    int i;
+    int cdf_error = 0;
+    int ref_symb, ref_nsymbs;
+    aom_cdf_prob ref_cdf[16];
+    const int queue_r = bitstream_queue_get_read();
+    const int frame_idx = bitstream_queue_get_frame_read();
+    bitstream_queue_pop(&ref_symb, ref_cdf, &ref_nsymbs);
+    if (nsymbs != ref_nsymbs) {
+      fprintf(stderr,
+              "\n *** nsymbs error, frame_idx_r %d nsymbs %d ref_nsymbs %d "
+              "queue_r %d\n",
+              frame_idx, nsymbs, ref_nsymbs, queue_r);
+      cdf_error = 0;
+      assert(0);
+    } else {
+      for (i = 0; i < nsymbs; ++i)
+        if (cdf[i] != ref_cdf[i]) cdf_error = 1;
+    }
+    if (cdf_error) {
+      fprintf(stderr, "\n *** cdf error, frame_idx_r %d cdf {%d", frame_idx,
+              cdf[0]);
+      for (i = 1; i < nsymbs; ++i) fprintf(stderr, ", %d", cdf[i]);
+      fprintf(stderr, "} ref_cdf {%d", ref_cdf[0]);
+      for (i = 1; i < ref_nsymbs; ++i) fprintf(stderr, ", %d", ref_cdf[i]);
+      fprintf(stderr, "} queue_r %d\n", queue_r);
+      assert(0);
+    }
+    if (symb != ref_symb) {
+      fprintf(
+          stderr,
+          "\n *** symb error, frame_idx_r %d symb %d ref_symb %d queue_r %d\n",
+          frame_idx, symb, ref_symb, queue_r);
+      assert(0);
+    }
+  }
+#endif
+
+  return symb;
+}
+
 static INLINE int daala_read_tree_bits(daala_reader *r,
                                        const aom_tree_index *tree,
                                        const aom_prob *probs) {
@@ -68,18 +166,13 @@
     int nsymbs;
     int symb;
     nsymbs = tree_to_cdf(tree, probs, i, cdf, index, path, dist);
-    symb = od_ec_decode_cdf_q15(&r->ec, cdf, nsymbs);
+    symb = daala_read_symbol(r, cdf, nsymbs);
     OD_ASSERT(symb >= 0 && symb < nsymbs);
     i = index[symb];
   } while (i > 0);
   return -i;
 }
 
-static INLINE int daala_read_symbol(daala_reader *r, const aom_cdf_prob *cdf,
-                                    int nsymbs) {
-  return od_ec_decode_cdf_q15(&r->ec, cdf, nsymbs);
-}
-
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/aom_dsp/daalaboolwriter.h b/aom_dsp/daalaboolwriter.h
index 5183a90..5386c83 100644
--- a/aom_dsp/daalaboolwriter.h
+++ b/aom_dsp/daalaboolwriter.h
@@ -12,8 +12,13 @@
 #ifndef AOM_DSP_DAALABOOLWRITER_H_
 #define AOM_DSP_DAALABOOLWRITER_H_
 
+#include <stdio.h>
+
 #include "aom_dsp/entenc.h"
 #include "aom_dsp/prob.h"
+#if CONFIG_BITSTREAM_DEBUG
+#include "aom_util/debug_util.h"
+#endif  // CONFIG_BITSTREAM_DEBUG
 
 #ifdef __cplusplus
 extern "C" {
@@ -31,14 +36,44 @@
 void aom_daala_stop_encode(daala_writer *w);
 
 static INLINE void aom_daala_write(daala_writer *w, int bit, int prob) {
+  int p = ((prob << 15) + (256 - prob)) >> 8;
+#if CONFIG_BITSTREAM_DEBUG
+  aom_cdf_prob cdf[2] = { (aom_cdf_prob)p, 32767 };
+  /*int queue_r = 0;
+  int frame_idx_r = 0;
+  int queue_w = bitstream_queue_get_write();
+  int frame_idx_w = bitstream_queue_get_frame_write();
+  if (frame_idx_w == frame_idx_r && queue_w == queue_r) {
+    fprintf(stderr, "\n *** bitstream queue at frame_idx_w %d queue_w %d\n",
+    frame_idx_w, queue_w);
+  }*/
+  bitstream_queue_push(bit, cdf, 2);
+#endif
+
   if (prob == 128) {
     od_ec_enc_bits(&w->ec, bit, 1);
   } else {
-    int p = ((prob << 15) + (256 - prob)) >> 8;
     od_ec_encode_bool_q15(&w->ec, bit, p);
   }
 }
 
+static INLINE void daala_write_symbol(daala_writer *w, int symb,
+                                      const aom_cdf_prob *cdf, int nsymbs) {
+#if CONFIG_BITSTREAM_DEBUG
+  /*int queue_r = 0;
+  int frame_idx_r = 0;
+  int queue_w = bitstream_queue_get_write();
+  int frame_idx_w = bitstream_queue_get_frame_write();
+  if (frame_idx_w == frame_idx_r && queue_w == queue_r) {
+    fprintf(stderr, "\n *** bitstream queue at frame_idx_w %d queue_w %d\n",
+    frame_idx_w, queue_w);
+  }*/
+  bitstream_queue_push(symb, cdf, nsymbs);
+#endif
+
+  od_ec_encode_cdf_q15(&w->ec, symb, cdf, nsymbs);
+}
+
 static INLINE void daala_write_tree_bits(daala_writer *w,
                                          const aom_tree_index *tree,
                                          const aom_prob *probs, int bits,
@@ -72,17 +107,12 @@
       }
     }
     OD_ASSERT(symb != -1);
-    od_ec_encode_cdf_q15(&w->ec, symb, cdf, nsymbs);
+    daala_write_symbol(w, symb, cdf, nsymbs);
     bits &= (1 << (len - dist[symb])) - 1;
     len -= dist[symb];
   } while (len);
 }
 
-static INLINE void daala_write_symbol(daala_writer *w, int symb,
-                                      const aom_cdf_prob *cdf, int nsymbs) {
-  od_ec_encode_cdf_q15(&w->ec, symb, cdf, nsymbs);
-}
-
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/aom_util/debug_util.c b/aom_util/debug_util.c
index 52389d0..d0589ca 100644
--- a/aom_util/debug_util.c
+++ b/aom_util/debug_util.c
@@ -11,10 +11,18 @@
 
 #include <assert.h>
 #include <stdio.h>
+#include <string.h>
 #include "aom_util/debug_util.h"
+
 #define QUEUE_MAX_SIZE 2000000
 static int result_queue[QUEUE_MAX_SIZE];
+#if CONFIG_DAALA_EC
+static int nsymbs_queue[QUEUE_MAX_SIZE];
+static aom_cdf_prob cdf_queue[QUEUE_MAX_SIZE][16];
+#else
 static int prob_queue[QUEUE_MAX_SIZE];
+#endif
+
 static int queue_r = 0;
 static int queue_w = 0;
 static int queue_prev_w = -1;
@@ -45,6 +53,33 @@
 
 int bitstream_queue_get_read(void) { return queue_r; }
 
+#if CONFIG_DAALA_EC
+void bitstream_queue_pop(int *result, aom_cdf_prob *cdf, int *nsymbs) {
+  if (!skip_r) {
+    if (queue_w == queue_r) {
+      printf("buffer underflow queue_w %d queue_r %d\n", queue_w, queue_r);
+      assert(0);
+    }
+    *result = result_queue[queue_r];
+    *nsymbs = nsymbs_queue[queue_r];
+    memcpy(cdf, cdf_queue[queue_r], *nsymbs * sizeof(*cdf));
+    queue_r = (queue_r + 1) % QUEUE_MAX_SIZE;
+  }
+}
+
+void bitstream_queue_push(int result, const aom_cdf_prob *cdf, int nsymbs) {
+  if (!skip_w) {
+    result_queue[queue_w] = result;
+    nsymbs_queue[queue_w] = nsymbs;
+    memcpy(cdf_queue[queue_w], cdf, nsymbs * sizeof(*cdf));
+    queue_w = (queue_w + 1) % QUEUE_MAX_SIZE;
+    if (queue_w == queue_r) {
+      printf("buffer overflow queue_w %d queue_r %d\n", queue_w, queue_r);
+      assert(0);
+    }
+  }
+}
+#else
 void bitstream_queue_pop(int *result, int *prob) {
   if (!skip_r) {
     if (queue_w == queue_r) {
@@ -68,3 +103,4 @@
     }
   }
 }
+#endif
diff --git a/aom_util/debug_util.h b/aom_util/debug_util.h
index c52e385..2ed56ea 100644
--- a/aom_util/debug_util.h
+++ b/aom_util/debug_util.h
@@ -13,6 +13,9 @@
 #define AOM_UTIL_DEBUG_UTIL_H_
 
 #include "./aom_config.h"
+#if CONFIG_DAALA_EC
+#include "aom_dsp/prob.h"
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -30,8 +33,13 @@
 int bitstream_queue_get_read(void);
 void bitstream_queue_record_write(void);
 void bitstream_queue_reset_write(void);
+#if CONFIG_DAALA_EC
+void bitstream_queue_pop(int *result, aom_cdf_prob *cdf, int *nsymbs);
+void bitstream_queue_push(int result, const aom_cdf_prob *cdf, int nsymbs);
+#else
 void bitstream_queue_pop(int *result, int *prob);
 void bitstream_queue_push(int result, int prob);
+#endif
 void bitstream_queue_set_skip_write(int skip);
 void bitstream_queue_set_skip_read(int skip);
 void bitstream_queue_set_frame_write(int frame_idx);