From: Nathan E. Egge Date: Sun, 6 Mar 2016 17:42:47 +0000 (-0500) Subject: Use Daala entropy coder to code bits. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8043cc40182b1c94417edc44451655e06b9c8a55;p=libvpx Use Daala entropy coder to code bits. 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 --- diff --git a/aom_dsp/aom_dsp.mk b/aom_dsp/aom_dsp.mk index 9db0fa797..238853f86 100644 --- a/aom_dsp/aom_dsp.mk +++ b/aom_dsp/aom_dsp.mk @@ -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 diff --git a/aom_dsp/bitreader.h b/aom_dsp/bitreader.h index 52e4dc8ab..13fd2eb3c 100644 --- a/aom_dsp/bitreader.h +++ b/aom_dsp/bitreader.h @@ -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 diff --git a/aom_dsp/bitwriter.h b/aom_dsp/bitwriter.h index d6937aa53..720228bdc 100644 --- a/aom_dsp/bitwriter.h +++ b/aom_dsp/bitwriter.h @@ -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 index 000000000..d9ef88700 --- /dev/null +++ b/aom_dsp/daalaboolreader.c @@ -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 index 000000000..c15f74978 --- /dev/null +++ b/aom_dsp/daalaboolreader.h @@ -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 index 000000000..15a3af7a8 --- /dev/null +++ b/aom_dsp/daalaboolwriter.c @@ -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 +#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 index 000000000..250ec62b9 --- /dev/null +++ b/aom_dsp/daalaboolwriter.h @@ -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 diff --git a/av1/common/entropy.h b/av1/common/entropy.h index fd68e825d..47825b4ea 100644 --- a/av1/common/entropy.h +++ b/av1/common/entropy.h @@ -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] diff --git a/av1/common/entropymode.h b/av1/common/entropymode.h index cfe279e80..1caf31904 100644 --- a/av1/common/entropymode.h +++ b/av1/common/entropymode.h @@ -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] diff --git a/av1/encoder/tokenize.c b/av1/encoder/tokenize.c index aa67f6c4b..173c9348b 100644 --- a/av1/encoder/tokenize.c +++ b/av1/encoder/tokenize.c @@ -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]); diff --git a/av1/encoder/tokenize.h b/av1/encoder/tokenize.h index 7f1bc74f2..677d0414f 100644 --- a/av1/encoder/tokenize.h +++ b/av1/encoder/tokenize.h @@ -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;