]> granicus.if.org Git - libvpx/commitdiff
Use Daala entropy coder to code bits.
authorNathan E. Egge <negge@mozilla.com>
Sun, 6 Mar 2016 17:42:47 +0000 (12:42 -0500)
committerYaowu Xu <yaowu@google.com>
Fri, 14 Oct 2016 21:59:27 +0000 (14:59 -0700)
When building with --enable-daala_ec, calls to aom_write() and aom_read()
 use the daala entropy coder to write and read bits.
When the probability is exactly 0.5 (128), then raw bits are used.

ntt-short-1:

          MEDIUM (%) HIGH (%)
    PSNR -0.027556  -0.020114
 PSNRHVS -0.027401  -0.020169
    SSIM -0.027587  -0.020151
FASTSSIM -0.027592  -0.020102

subset1:

         RATE (%)  DSNR (dB)
    PSNR 0.03296  -0.00210
 PSNRHVS 0.03537  -0.00281
    SSIM 0.03299  -0.00161
FASTSSIM 0.03458  -0.00111

Change-Id: I48ad8eb40fc895d62d6e241ea8abc02820d573f7

aom_dsp/aom_dsp.mk
aom_dsp/bitreader.h
aom_dsp/bitwriter.h
aom_dsp/daalaboolreader.c [new file with mode: 0644]
aom_dsp/daalaboolreader.h [new file with mode: 0644]
aom_dsp/daalaboolwriter.c [new file with mode: 0644]
aom_dsp/daalaboolwriter.h [new file with mode: 0644]
av1/common/entropy.h
av1/common/entropymode.h
av1/encoder/tokenize.c
av1/encoder/tokenize.h

index 9db0fa79739bebde899f92270f00698b041c8c97..238853f869f18d89f5b535d3d150ab2b4ad9330a 100644 (file)
@@ -59,6 +59,10 @@ 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
index 52e4dc8ab8d29450d6d6a730539212916aaf22fc..13fd2eb3c44db521cc71f63375c223abec9fdab1 100644 (file)
@@ -20,6 +20,8 @@
 #include "aom/aom_integer.h"
 #if CONFIG_ANS
 #include "aom_dsp/ansreader.h"
+#elif CONFIG_DAALA_EC
+#include "aom_dsp/daalaboolreader.h"
 #else
 #include "aom_dsp/dkboolreader.h"
 #endif
@@ -31,6 +33,8 @@ extern "C" {
 
 #if CONFIG_ANS
 typedef struct AnsDecoder aom_reader;
+#elif CONFIG_DAALA_EC
+typedef struct daala_reader aom_reader;
 #else
 typedef struct aom_dk_reader aom_reader;
 #endif
@@ -43,6 +47,10 @@ static INLINE int aom_reader_init(aom_reader *r, const uint8_t *buffer,
   (void)decrypt_state;
   assert(size <= INT_MAX);
   return ans_read_init(r, buffer, size);
+#elif CONFIG_DAALA_EC
+  (void)decrypt_cb;
+  (void)decrypt_state;
+  return aom_daala_reader_init(r, buffer, size);
 #else
   return aom_dk_reader_init(r, buffer, size, decrypt_cb, decrypt_state);
 #endif
@@ -53,6 +61,8 @@ static INLINE const uint8_t *aom_reader_find_end(aom_reader *r) {
   (void)r;
   assert(0 && "Use the raw buffer size with ANS");
   return NULL;
+#elif CONFIG_DAALA_EC
+  return aom_daala_reader_find_end(r);
 #else
   return aom_dk_reader_find_end(r);
 #endif
@@ -61,6 +71,8 @@ static INLINE const uint8_t *aom_reader_find_end(aom_reader *r) {
 static INLINE int aom_reader_has_error(aom_reader *r) {
 #if CONFIG_ANS
   return ans_reader_has_error(r);
+#elif CONFIG_DAALA_EC
+  return aom_daala_reader_has_error(r);
 #else
   return aom_dk_reader_has_error(r);
 #endif
@@ -69,6 +81,8 @@ static INLINE int aom_reader_has_error(aom_reader *r) {
 static INLINE int aom_read(aom_reader *r, int prob) {
 #if CONFIG_ANS
   return uabs_read(r, prob);
+#elif CONFIG_DAALA_EC
+  return aom_daala_read(r, prob);
 #else
   return aom_dk_read(r, prob);
 #endif
index d6937aa53b119760c083f9a3dd3bcdddaefc0c50..720228bdcddfba47867c51511fe8e3b9a47ea2df 100644 (file)
@@ -29,6 +29,8 @@ extern "C" {
 
 #if CONFIG_ANS
 typedef struct BufAnsCoder aom_writer;
+#elif CONFIG_DAALA_EC
+typedef struct daala_writer aom_writer;
 #else
 typedef struct aom_dk_writer aom_writer;
 #endif
@@ -38,6 +40,8 @@ static INLINE void aom_start_encode(aom_writer *bc, uint8_t *buffer) {
   (void)bc;
   (void)buffer;
   assert(0 && "buf_ans requires a more complicated startup procedure");
+#elif CONFIG_DAALA_EC
+  aom_daala_start_encode(bc, buffer);
 #else
   aom_dk_start_encode(bc, buffer);
 #endif
@@ -47,6 +51,8 @@ static INLINE void aom_stop_encode(aom_writer *bc) {
 #if CONFIG_ANS
   (void)bc;
   assert(0 && "buf_ans requires a more complicated shutdown procedure");
+#elif CONFIG_DAALA_EC
+  aom_daala_stop_encode(bc);
 #else
   aom_dk_stop_encode(bc);
 #endif
@@ -55,6 +61,8 @@ static INLINE void aom_stop_encode(aom_writer *bc) {
 static INLINE void aom_write(aom_writer *br, int bit, int probability) {
 #if CONFIG_ANS
   buf_uabs_write(br, bit, probability);
+#elif CONFIG_DAALA_EC
+  aom_daala_write(br, bit, probability);
 #else
   aom_dk_write(br, bit, probability);
 #endif
diff --git a/aom_dsp/daalaboolreader.c b/aom_dsp/daalaboolreader.c
new file mode 100644 (file)
index 0000000..d9ef887
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#include "aom_dsp/daalaboolreader.h"
+
+int aom_daala_reader_init(daala_reader *r, const uint8_t *buffer, int size) {
+  if (size && !buffer) {
+    return 1;
+  }
+  r->buffer_end = buffer + size;
+  r->buffer = buffer;
+  od_ec_dec_init(&r->ec, buffer, size - 1);
+  return 0;
+}
+
+const uint8_t *aom_daala_reader_find_end(daala_reader *r) {
+  return r->buffer_end;
+}
diff --git a/aom_dsp/daalaboolreader.h b/aom_dsp/daalaboolreader.h
new file mode 100644 (file)
index 0000000..c15f749
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#ifndef AOM_DSP_DAALABOOLREADER_H_
+#define AOM_DSP_DAALABOOLREADER_H_
+
+#include "aom_dsp/entdec.h"
+#include "aom_dsp/prob.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct daala_reader {
+  const uint8_t *buffer;
+  const uint8_t *buffer_end;
+  od_ec_dec ec;
+};
+
+typedef struct daala_reader daala_reader;
+
+int aom_daala_reader_init(daala_reader *r, const uint8_t *buffer, int size);
+const uint8_t *aom_daala_reader_find_end(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, "aom");
+  }
+}
+
+static INLINE int aom_daala_read_bit(daala_reader *r) {
+  return aom_daala_read(r, 128);
+}
+
+static INLINE int aom_daala_reader_has_error(daala_reader *r) {
+  return r->ec.error;
+}
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif
diff --git a/aom_dsp/daalaboolwriter.c b/aom_dsp/daalaboolwriter.c
new file mode 100644 (file)
index 0000000..15a3af7
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#include <string.h>
+#include "aom_dsp/daalaboolwriter.h"
+
+void aom_daala_start_encode(daala_writer *br, uint8_t *source) {
+  br->buffer = source;
+  br->pos = 0;
+  od_ec_enc_init(&br->ec, 62025);
+}
+
+void aom_daala_stop_encode(daala_writer *br) {
+  uint32_t daala_bytes;
+  unsigned char *daala_data;
+  daala_data = od_ec_enc_done(&br->ec, &daala_bytes);
+  memcpy(br->buffer, daala_data, daala_bytes);
+  br->pos = daala_bytes;
+  /* Prevent ec bitstream from being detected as a superframe marker.
+     Must always be added, so that rawbits knows the exact length of the
+      bitstream. */
+  br->buffer[br->pos++] = 0;
+}
diff --git a/aom_dsp/daalaboolwriter.h b/aom_dsp/daalaboolwriter.h
new file mode 100644 (file)
index 0000000..250ec62
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2016, Alliance for Open Media. All rights reserved
+ *
+ * This source code is subject to the terms of the BSD 2 Clause License and
+ * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
+ * was not distributed with this source code in the LICENSE file, you can
+ * obtain it at www.aomedia.org/license/software. If the Alliance for Open
+ * Media Patent License 1.0 was not distributed with this source code in the
+ * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
+ */
+
+#ifndef AOM_DSP_DAALABOOLWRITER_H_
+#define AOM_DSP_DAALABOOLWRITER_H_
+
+#include "aom_dsp/entenc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct daala_writer {
+  unsigned int pos;
+  uint8_t *buffer;
+  od_ec_enc ec;
+};
+
+typedef struct daala_writer daala_writer;
+
+void aom_daala_start_encode(daala_writer *w, uint8_t *buffer);
+void aom_daala_stop_encode(daala_writer *w);
+
+static INLINE void aom_daala_write(daala_writer *w, int bit, int prob) {
+  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);
+  }
+}
+
+#ifdef __cplusplus
+}  // extern "C"
+#endif
+
+#endif
index fd68e825d5fe4ea2e511697cc6f6b975c4e6d113..47825b4eae83912fd4745bdb9f90c47c7787267a 100644 (file)
@@ -190,7 +190,7 @@ static INLINE const uint8_t *get_band_translate(TX_SIZE tx_size) {
 #define MODEL_NODES (ENTROPY_NODES - UNCONSTRAINED_NODES)
 extern const aom_tree_index av1_coef_con_tree[TREE_SIZE(ENTROPY_TOKENS)];
 extern const aom_prob av1_pareto8_full[COEFF_PROB_MODELS][MODEL_NODES];
-#if CONFIG_ANS
+#if CONFIG_ANS || CONFIG_DAALA_EC
 typedef aom_cdf_prob coeff_cdf_model[REF_TYPES][COEF_BANDS][COEFF_CONTEXTS]
                                     [ENTROPY_TOKENS];
 extern const aom_cdf_prob av1_pareto8_token_probs[COEFF_PROB_MODELS]
index cfe279e809d5060762416e64121536c5aed7c903..1caf31904d76ba94ca0a035fa7f971804cb250e8 100644 (file)
@@ -56,7 +56,7 @@ typedef struct frame_contexts {
   aom_prob partition_prob[PARTITION_CONTEXTS][PARTITION_TYPES - 1];
 #endif
   av1_coeff_probs_model coef_probs[TX_SIZES][PLANE_TYPES];
-#if CONFIG_ANS
+#if CONFIG_ANS || CONFIG_DAALA_EC
   coeff_cdf_model coef_cdfs[TX_SIZES][PLANE_TYPES];
 #endif
   aom_prob switchable_interp_prob[SWITCHABLE_FILTER_CONTEXTS]
index aa67f6c4b5e9d8f1cf3d72d2306a1092b431cf63..173c9348bb82354df5cd3555815f3ed00bbdfbab 100644 (file)
@@ -386,7 +386,7 @@ static void set_entropy_context_b(int plane, int block, int blk_row,
 }
 
 static INLINE void add_token(TOKENEXTRA **t, const aom_prob *context_tree,
-#if CONFIG_ANS
+#if CONFIG_ANS || CONFIG_DAALA_EC
                              const aom_cdf_prob (*token_cdf)[ENTROPY_TOKENS],
 #endif  // CONFIG_ANS
                              int32_t extra, uint8_t token,
@@ -394,7 +394,7 @@ static INLINE void add_token(TOKENEXTRA **t, const aom_prob *context_tree,
   (*t)->token = token;
   (*t)->extra = extra;
   (*t)->context_tree = context_tree;
-#if CONFIG_ANS
+#if CONFIG_ANS || CONFIG_DAALA_EC
   (*t)->token_cdf = token_cdf;
 #endif  // CONFIG_ANS
   (*t)->skip_eob_node = skip_eob_node;
@@ -488,7 +488,7 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
   aom_prob(*const coef_probs)[COEFF_CONTEXTS][UNCONSTRAINED_NODES] =
       cpi->common.fc->coef_probs[txsize_sqr_map[tx_size]][type][ref];
 #endif  // CONFIG_ENTROPY
-#if CONFIG_ANS
+#if CONFIG_ANS || CONFIG_DAALA_EC
   aom_cdf_prob(*const coef_cdfs)[COEFF_CONTEXTS][ENTROPY_TOKENS] =
       cpi->common.fc->coef_cdfs[tx_size][type][ref];
 #endif  // CONFIG_ANS
@@ -512,7 +512,7 @@ static void tokenize_b(int plane, int block, int blk_row, int blk_col,
     av1_get_token_extra(v, &token, &extra);
 
     add_token(&t, coef_probs[band[c]][pt],
-#if CONFIG_ANS
+#if CONFIG_ANS || CONFIG_DAALA_EC
               (const aom_cdf_prob(*)[ENTROPY_TOKENS]) & coef_cdfs[band[c]][pt],
 #endif  // CONFIG_ANS
               extra, (uint8_t)token, (uint8_t)skip_eob, counts[band[c]][pt]);
index 7f1bc74f2bc3a90d6bd11d7740c999cb93523d3a..677d0414f0a743c10411d2c74073016ff6ed0587 100644 (file)
@@ -36,7 +36,7 @@ typedef struct {
 
 typedef struct {
   const aom_prob *context_tree;
-#if CONFIG_ANS
+#if CONFIG_ANS || CONFIG_DAALA_EC
   const aom_cdf_prob (*token_cdf)[ENTROPY_TOKENS];
 #endif  // CONFIG_ANS
   EXTRABIT extra;