From eb00cb289bb8a0072e2cc8ec3af66b11c2889ac2 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Mon, 6 Jun 2016 15:12:06 -0700 Subject: [PATCH] Move and wrap the old vpx boolcoder. This should make room for compile time pluggable replacements. Change-Id: Ib7afcffa93bf664b89a49da21a20138127443292 (cherry picked from commit 9dd0b8982445515d6dddb6342e655b56062a8f7f) --- aom_dsp/aom_dsp.mk | 6 +- aom_dsp/bitreader.h | 132 +++---------------- aom_dsp/bitwriter.h | 90 ++----------- aom_dsp/{bitreader.c => dkboolreader.c} | 15 ++- aom_dsp/dkboolreader.h | 164 ++++++++++++++++++++++++ aom_dsp/{bitwriter.c => dkboolwriter.c} | 10 +- aom_dsp/dkboolwriter.h | 114 ++++++++++++++++ 7 files changed, 320 insertions(+), 211 deletions(-) rename aom_dsp/{bitreader.c => dkboolreader.c} (87%) create mode 100644 aom_dsp/dkboolreader.h rename aom_dsp/{bitwriter.c => dkboolwriter.c} (80%) create mode 100644 aom_dsp/dkboolwriter.h diff --git a/aom_dsp/aom_dsp.mk b/aom_dsp/aom_dsp.mk index 24068272f..5bebb26f3 100644 --- a/aom_dsp/aom_dsp.mk +++ b/aom_dsp/aom_dsp.mk @@ -22,7 +22,8 @@ DSP_SRCS-yes += prob.c ifeq ($(CONFIG_ENCODERS),yes) DSP_SRCS-yes += bitwriter.h -DSP_SRCS-yes += bitwriter.c +DSP_SRCS-yes += dkboolwriter.h +DSP_SRCS-yes += dkboolwriter.c DSP_SRCS-yes += bitwriter_buffer.c DSP_SRCS-yes += bitwriter_buffer.h DSP_SRCS-yes += psnr.c @@ -35,7 +36,8 @@ endif ifeq ($(CONFIG_DECODERS),yes) DSP_SRCS-yes += bitreader.h -DSP_SRCS-yes += bitreader.c +DSP_SRCS-yes += dkboolreader.h +DSP_SRCS-yes += dkboolreader.c DSP_SRCS-yes += bitreader_buffer.c DSP_SRCS-yes += bitreader_buffer.h endif diff --git a/aom_dsp/bitreader.h b/aom_dsp/bitreader.h index ed977761c..609242188 100644 --- a/aom_dsp/bitreader.h +++ b/aom_dsp/bitreader.h @@ -12,147 +12,45 @@ #ifndef AOM_DSP_BITREADER_H_ #define AOM_DSP_BITREADER_H_ -#include -#include - #include "./aom_config.h" - -#if CONFIG_BITSTREAM_DEBUG -#include -#include -#endif // CONFIG_BITSTREAM_DEBUG - -#include "aom_ports/mem.h" #include "aom/aomdx.h" #include "aom/aom_integer.h" +#include "aom_dsp/dkboolreader.h" #include "aom_dsp/prob.h" -#include "aom_util/debug_util.h" #ifdef __cplusplus extern "C" { #endif -typedef size_t BD_VALUE; +typedef struct aom_dk_reader aom_reader; -#define BD_VALUE_SIZE ((int)sizeof(BD_VALUE) * CHAR_BIT) +static INLINE int aom_reader_init(aom_reader *r, const uint8_t *buffer, + size_t size, aom_decrypt_cb decrypt_cb, + void *decrypt_state) { + return aom_dk_reader_init(r, buffer, size, decrypt_cb, decrypt_state); +} -// This is meant to be a large, positive constant that can still be efficiently -// loaded as an immediate (on platforms like ARM, for example). -// Even relatively modest values like 100 would work fine. -#define LOTS_OF_BITS 0x40000000 - -typedef struct { - // Be careful when reordering this struct, it may impact the cache negatively. - BD_VALUE value; - unsigned int range; - int count; - const uint8_t *buffer_end; - const uint8_t *buffer; - aom_decrypt_cb decrypt_cb; - void *decrypt_state; - uint8_t clear_buffer[sizeof(BD_VALUE) + 1]; -} aom_reader; - -int aom_reader_init(aom_reader *r, const uint8_t *buffer, size_t size, - aom_decrypt_cb decrypt_cb, void *decrypt_state); - -void aom_reader_fill(aom_reader *r); - -const uint8_t *aom_reader_find_end(aom_reader *r); +static INLINE const uint8_t *aom_reader_find_end(aom_reader *r) { + return aom_dk_reader_find_end(r); +} static INLINE int aom_reader_has_error(aom_reader *r) { - // Check if we have reached the end of the buffer. - // - // Variable 'count' stores the number of bits in the 'value' buffer, minus - // 8. The top byte is part of the algorithm, and the remainder is buffered - // to be shifted into it. So if count == 8, the top 16 bits of 'value' are - // occupied, 8 for the algorithm and 8 in the buffer. - // - // When reading a byte from the user's buffer, count is filled with 8 and - // one byte is filled into the value buffer. When we reach the end of the - // data, count is additionally filled with LOTS_OF_BITS. So when - // count == LOTS_OF_BITS - 1, the user's data has been exhausted. - // - // 1 if we have tried to decode bits after the end of stream was encountered. - // 0 No error. - return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS; + return aom_dk_reader_has_error(r); } static INLINE int aom_read(aom_reader *r, int prob) { - unsigned int bit = 0; - BD_VALUE value; - BD_VALUE bigsplit; - int count; - unsigned int range; - unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; - - if (r->count < 0) aom_reader_fill(r); - - value = r->value; - count = r->count; - - bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); - - range = split; - - if (value >= bigsplit) { - range = r->range - split; - value = value - bigsplit; - bit = 1; - } - - { - register int shift = aom_norm[range]; - range <<= shift; - value <<= shift; - count -= shift; - } - r->value = value; - r->count = count; - r->range = range; - -#if CONFIG_BITSTREAM_DEBUG - { - int ref_bit, ref_prob; - const int queue_r = bitstream_queue_get_read(); - const int frame_idx = bitstream_queue_get_frame_read(); - bitstream_queue_pop(&ref_bit, &ref_prob); - if (prob != ref_prob) { - fprintf( - stderr, - "\n *** prob error, frame_idx_r %d prob %d ref_prob %d queue_r %d\n", - frame_idx, prob, ref_prob, queue_r); - assert(0); - } - if ((int)bit != ref_bit) { - fprintf(stderr, "\n *** bit error, frame_idx_r %d bit %d ref_bit %d\n", - frame_idx, bit, ref_bit); - assert(0); - } - } -#endif // CONFIG_BITSTREAM_DEBUG - return bit; + return aom_dk_read(r, prob); } -static INLINE int aom_read_bit(aom_reader *r) { - return aom_read(r, 128); // aom_prob_half -} +static INLINE int aom_read_bit(aom_reader *r) { return aom_dk_read_bit(r); } static INLINE int aom_read_literal(aom_reader *r, int bits) { - int literal = 0, bit; - - for (bit = bits - 1; bit >= 0; bit--) literal |= aom_read_bit(r) << bit; - - return literal; + return aom_dk_read_literal(r, bits); } static INLINE int aom_read_tree(aom_reader *r, const aom_tree_index *tree, const aom_prob *probs) { - aom_tree_index i = 0; - - while ((i = tree[i + aom_read(r, probs[i >> 1])]) > 0) continue; - - return -i; + return aom_dk_read_tree(r, tree, probs); } #ifdef __cplusplus diff --git a/aom_dsp/bitwriter.h b/aom_dsp/bitwriter.h index 594290ae8..550893a42 100644 --- a/aom_dsp/bitwriter.h +++ b/aom_dsp/bitwriter.h @@ -12,103 +12,33 @@ #ifndef AOM_DSP_BITWRITER_H_ #define AOM_DSP_BITWRITER_H_ -#include "./aom_config.h" - -#if CONFIG_BITSTREAM_DEBUG -#include -#endif - -#include "aom_ports/mem.h" +#include "aom_dsp/dkboolwriter.h" #include "aom_dsp/prob.h" -#include "aom_util/debug_util.h" #ifdef __cplusplus extern "C" { #endif -typedef struct aom_writer { - unsigned int lowvalue; - unsigned int range; - int count; - unsigned int pos; - uint8_t *buffer; -} aom_writer; +typedef struct aom_dk_writer aom_writer; -void aom_start_encode(aom_writer *bc, uint8_t *buffer); -void aom_stop_encode(aom_writer *bc); +static INLINE void aom_start_encode(aom_writer *bc, uint8_t *buffer) { + aom_dk_start_encode(bc, buffer); +} + +static INLINE void aom_stop_encode(aom_writer *bc) { aom_dk_stop_encode(bc); } static INLINE void aom_write(aom_writer *br, int bit, int probability) { - unsigned int split; - int count = br->count; - unsigned int range = br->range; - unsigned int lowvalue = br->lowvalue; - register int shift; - -#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(bit, probability); -#endif // CONFIG_BITSTREAM_DEBUG - - split = 1 + (((range - 1) * probability) >> 8); - - range = split; - - if (bit) { - lowvalue += split; - range = br->range - split; - } - - shift = aom_norm[range]; - - range <<= shift; - count += shift; - - if (count >= 0) { - int offset = shift - count; - - if ((lowvalue << (offset - 1)) & 0x80000000) { - int x = br->pos - 1; - - while (x >= 0 && br->buffer[x] == 0xff) { - br->buffer[x] = 0; - x--; - } - - br->buffer[x] += 1; - } - - br->buffer[br->pos++] = (lowvalue >> (24 - offset)); - lowvalue <<= offset; - shift = count; - lowvalue &= 0xffffff; - count -= 8; - } - - lowvalue <<= shift; - br->count = count; - br->lowvalue = lowvalue; - br->range = range; + aom_dk_write(br, bit, probability); } static INLINE void aom_write_bit(aom_writer *w, int bit) { - aom_write(w, bit, 128); // aom_prob_half + aom_dk_write_bit(w, bit); } static INLINE void aom_write_literal(aom_writer *w, int data, int bits) { - int bit; - - for (bit = bits - 1; bit >= 0; bit--) aom_write_bit(w, 1 & (data >> bit)); + aom_dk_write_literal(w, data, bits); } -#define aom_write_prob(w, v) aom_write_literal((w), (v), 8) - #ifdef __cplusplus } // extern "C" #endif diff --git a/aom_dsp/bitreader.c b/aom_dsp/dkboolreader.c similarity index 87% rename from aom_dsp/bitreader.c rename to aom_dsp/dkboolreader.c index 60c546d25..c26d90baa 100644 --- a/aom_dsp/bitreader.c +++ b/aom_dsp/dkboolreader.c @@ -11,15 +11,16 @@ #include "./aom_config.h" -#include "aom_dsp/bitreader.h" +#include "aom_dsp/dkboolreader.h" #include "aom_dsp/prob.h" #include "aom_dsp/aom_dsp_common.h" #include "aom_ports/mem.h" #include "aom_mem/aom_mem.h" #include "aom_util/endian_inl.h" -int aom_reader_init(aom_reader *r, const uint8_t *buffer, size_t size, - aom_decrypt_cb decrypt_cb, void *decrypt_state) { +int aom_dk_reader_init(struct aom_dk_reader *r, const uint8_t *buffer, + size_t size, aom_decrypt_cb decrypt_cb, + void *decrypt_state) { if (size && !buffer) { return 1; } else { @@ -30,12 +31,12 @@ int aom_reader_init(aom_reader *r, const uint8_t *buffer, size_t size, r->range = 255; r->decrypt_cb = decrypt_cb; r->decrypt_state = decrypt_state; - aom_reader_fill(r); - return aom_read_bit(r) != 0; // marker bit + aom_dk_reader_fill(r); + return aom_dk_read_bit(r) != 0; // marker bit } } -void aom_reader_fill(aom_reader *r) { +void aom_dk_reader_fill(struct aom_dk_reader *r) { const uint8_t *const buffer_end = r->buffer_end; const uint8_t *buffer = r->buffer; const uint8_t *buffer_start = buffer; @@ -90,7 +91,7 @@ void aom_reader_fill(aom_reader *r) { r->count = count; } -const uint8_t *aom_reader_find_end(aom_reader *r) { +const uint8_t *aom_dk_reader_find_end(struct aom_dk_reader *r) { // Find the end of the coded buffer while (r->count > CHAR_BIT && r->count < BD_VALUE_SIZE) { r->count -= CHAR_BIT; diff --git a/aom_dsp/dkboolreader.h b/aom_dsp/dkboolreader.h new file mode 100644 index 000000000..a2f67fffe --- /dev/null +++ b/aom_dsp/dkboolreader.h @@ -0,0 +1,164 @@ +/* + * 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_DKBOOLREADER_H_ +#define AOM_DSP_DKBOOLREADER_H_ + +#include +#include + +#include "./aom_config.h" +#if CONFIG_BITSTREAM_DEBUG +#include +#include +#endif // CONFIG_BITSTREAM_DEBUG + +#include "aom_ports/mem.h" +#include "aom/aomdx.h" +#include "aom/aom_integer.h" +#include "aom_dsp/prob.h" +#include "aom_util/debug_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef size_t BD_VALUE; + +#define BD_VALUE_SIZE ((int)sizeof(BD_VALUE) * CHAR_BIT) + +// This is meant to be a large, positive constant that can still be efficiently +// loaded as an immediate (on platforms like ARM, for example). +// Even relatively modest values like 100 would work fine. +#define LOTS_OF_BITS 0x40000000 + +struct aom_dk_reader { + // Be careful when reordering this struct, it may impact the cache negatively. + BD_VALUE value; + unsigned int range; + int count; + const uint8_t *buffer_end; + const uint8_t *buffer; + aom_decrypt_cb decrypt_cb; + void *decrypt_state; + uint8_t clear_buffer[sizeof(BD_VALUE) + 1]; +}; + +int aom_dk_reader_init(struct aom_dk_reader *r, const uint8_t *buffer, + size_t size, aom_decrypt_cb decrypt_cb, + void *decrypt_state); + +void aom_dk_reader_fill(struct aom_dk_reader *r); + +const uint8_t *aom_dk_reader_find_end(struct aom_dk_reader *r); + +static INLINE int aom_dk_reader_has_error(struct aom_dk_reader *r) { + // Check if we have reached the end of the buffer. + // + // Variable 'count' stores the number of bits in the 'value' buffer, minus + // 8. The top byte is part of the algorithm, and the remainder is buffered + // to be shifted into it. So if count == 8, the top 16 bits of 'value' are + // occupied, 8 for the algorithm and 8 in the buffer. + // + // When reading a byte from the user's buffer, count is filled with 8 and + // one byte is filled into the value buffer. When we reach the end of the + // data, count is additionally filled with LOTS_OF_BITS. So when + // count == LOTS_OF_BITS - 1, the user's data has been exhausted. + // + // 1 if we have tried to decode bits after the end of stream was encountered. + // 0 No error. + return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS; +} + +static INLINE int aom_dk_read(struct aom_dk_reader *r, int prob) { + unsigned int bit = 0; + BD_VALUE value; + BD_VALUE bigsplit; + int count; + unsigned int range; + unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; + + if (r->count < 0) aom_dk_reader_fill(r); + + value = r->value; + count = r->count; + + bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); + + range = split; + + if (value >= bigsplit) { + range = r->range - split; + value = value - bigsplit; + bit = 1; + } + + { + register int shift = aom_norm[range]; + range <<= shift; + value <<= shift; + count -= shift; + } + r->value = value; + r->count = count; + r->range = range; + +#if CONFIG_BITSTREAM_DEBUG + { + int ref_bit, ref_prob; + const int queue_r = bitstream_queue_get_read(); + const int frame_idx = bitstream_queue_get_frame_read(); + bitstream_queue_pop(&ref_bit, &ref_prob); + if (prob != ref_prob) { + fprintf( + stderr, + "\n *** prob error, frame_idx_r %d prob %d ref_prob %d queue_r %d\n", + frame_idx, prob, ref_prob, queue_r); + assert(0); + } + if ((int)bit != ref_bit) { + fprintf(stderr, "\n *** bit error, frame_idx_r %d bit %d ref_bit %d\n", + frame_idx, bit, ref_bit); + assert(0); + } + } +#endif // CONFIG_BITSTREAM_DEBUG + + return bit; +} + +static INLINE int aom_dk_read_bit(struct aom_dk_reader *r) { + return aom_dk_read(r, 128); // aom_prob_half +} + +static INLINE int aom_dk_read_literal(struct aom_dk_reader *r, int bits) { + int literal = 0, bit; + + for (bit = bits - 1; bit >= 0; bit--) literal |= aom_dk_read_bit(r) << bit; + + return literal; +} + +static INLINE int aom_dk_read_tree(struct aom_dk_reader *r, + const aom_tree_index *tree, + const aom_prob *probs) { + aom_tree_index i = 0; + + while ((i = tree[i + aom_dk_read(r, probs[i >> 1])]) > 0) continue; + + return -i; +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // AOM_DSP_DKBOOLREADER_H_ diff --git a/aom_dsp/bitwriter.c b/aom_dsp/dkboolwriter.c similarity index 80% rename from aom_dsp/bitwriter.c rename to aom_dsp/dkboolwriter.c index 9009a44ae..259316c93 100644 --- a/aom_dsp/bitwriter.c +++ b/aom_dsp/dkboolwriter.c @@ -10,25 +10,25 @@ #include -#include "./bitwriter.h" +#include "./dkboolwriter.h" -void aom_start_encode(aom_writer *br, uint8_t *source) { +void aom_dk_start_encode(aom_dk_writer *br, uint8_t *source) { br->lowvalue = 0; br->range = 255; br->count = -24; br->buffer = source; br->pos = 0; - aom_write_bit(br, 0); + aom_dk_write_bit(br, 0); } -void aom_stop_encode(aom_writer *br) { +void aom_dk_stop_encode(aom_dk_writer *br) { int i; #if CONFIG_BITSTREAM_DEBUG bitstream_queue_set_skip_write(1); #endif // CONFIG_BITSTREAM_DEBUG - for (i = 0; i < 32; i++) aom_write_bit(br, 0); + for (i = 0; i < 32; i++) aom_dk_write_bit(br, 0); #if CONFIG_BITSTREAM_DEBUG bitstream_queue_set_skip_write(0); diff --git a/aom_dsp/dkboolwriter.h b/aom_dsp/dkboolwriter.h new file mode 100644 index 000000000..ebad40eeb --- /dev/null +++ b/aom_dsp/dkboolwriter.h @@ -0,0 +1,114 @@ +/* + * 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_DKBOOLWRITER_H_ +#define AOM_DSP_DKBOOLWRITER_H_ + +#include "./aom_config.h" + +#if CONFIG_BITSTREAM_DEBUG +#include +#endif + +#include "aom_dsp/prob.h" +#include "aom_ports/mem.h" +#include "aom_util/debug_util.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct aom_dk_writer { + unsigned int lowvalue; + unsigned int range; + int count; + unsigned int pos; + uint8_t *buffer; +} aom_dk_writer; + +void aom_dk_start_encode(aom_dk_writer *bc, uint8_t *buffer); +void aom_dk_stop_encode(aom_dk_writer *bc); + +static INLINE void aom_dk_write(aom_dk_writer *br, int bit, int probability) { + unsigned int split; + int count = br->count; + unsigned int range = br->range; + unsigned int lowvalue = br->lowvalue; + register int shift; + +#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(bit, probability); +#endif // CONFIG_BITSTREAM_DEBUG + + split = 1 + (((range - 1) * probability) >> 8); + + range = split; + + if (bit) { + lowvalue += split; + range = br->range - split; + } + + shift = aom_norm[range]; + + range <<= shift; + count += shift; + + if (count >= 0) { + int offset = shift - count; + + if ((lowvalue << (offset - 1)) & 0x80000000) { + int x = br->pos - 1; + + while (x >= 0 && br->buffer[x] == 0xff) { + br->buffer[x] = 0; + x--; + } + + br->buffer[x] += 1; + } + + br->buffer[br->pos++] = (lowvalue >> (24 - offset)); + lowvalue <<= offset; + shift = count; + lowvalue &= 0xffffff; + count -= 8; + } + + lowvalue <<= shift; + br->count = count; + br->lowvalue = lowvalue; + br->range = range; +} + +static INLINE void aom_dk_write_bit(aom_dk_writer *w, int bit) { + aom_dk_write(w, bit, 128); // aom_prob_half +} + +static INLINE void aom_dk_write_literal(aom_dk_writer *w, int data, int bits) { + int bit; + + for (bit = bits - 1; bit >= 0; bit--) aom_dk_write_bit(w, 1 & (data >> bit)); +} + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // AOM_DSP_DKBOOLWRITER_H_