From 26f91d31d18d8f9299183a2663a99be48a9241c8 Mon Sep 17 00:00:00 2001 From: John Koleszar <jkoleszar@google.com> Date: Thu, 3 Feb 2011 09:04:26 -0500 Subject: [PATCH] dixie: simplify bool decoder Use the simplified bool decoder from the bitstream guide, slightly modified to prevent reading past the end of the buffer. Modified the token decoder to use the normal bool decoder rather than inlining its own. Change-Id: Ic525e773e9f8331ba548a6505cc6d9e5372a5af0 --- vp8/dixie/bool_decoder.c | 61 ---------------- vp8/dixie/bool_decoder.h | 150 ++++++++++++++------------------------- vp8/dixie/dixie.c | 4 +- vp8/dixie/predict.c | 1 + vp8/dixie/tokens.c | 103 ++++----------------------- vp8/vp8dx.mk | 1 - 6 files changed, 68 insertions(+), 252 deletions(-) delete mode 100644 vp8/dixie/bool_decoder.c diff --git a/vp8/dixie/bool_decoder.c b/vp8/dixie/bool_decoder.c deleted file mode 100644 index bda52d2a2d..0000000000 --- a/vp8/dixie/bool_decoder.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license and patent - * grant that can be found in the LICENSE file in the root of the source - * tree. All contributing project authors may be found in the AUTHORS - * file in the root of the source tree. - */ -#include "bool_decoder.h" -#include "vpx_ports/mem.h" - - -DECLARE_ALIGNED(16, const unsigned int, vp8dx_bool_norm[256]) = -{ - 0, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - - -int vp8dx_bool_init(struct bool_decoder *br, const unsigned char *source, - unsigned int source_sz) -{ - br->user_buffer_end = source + source_sz; - br->user_buffer = source; - br->value = 0; - br->count = -8; - br->range = 255; - - if (source_sz && !source) - return 1; - - /* Populate the buffer */ - vp8dx_bool_fill(br); - - return 0; -} - - -void vp8dx_bool_fill(struct bool_decoder *br) -{ - const unsigned char *bufptr; - const unsigned char *bufend; - vp8_bool_value_t value; - int count; - bufend = br->user_buffer_end; - bufptr = br->user_buffer; - value = br->value; - count = br->count; - - VP8DX_BOOL_DECODER_FILL(count, value, bufptr, bufend); - - br->user_buffer = bufptr; - br->value = value; - br->count = count; -} diff --git a/vp8/dixie/bool_decoder.h b/vp8/dixie/bool_decoder.h index bda472f278..53a2dc1b9f 100644 --- a/vp8/dixie/bool_decoder.h +++ b/vp8/dixie/bool_decoder.h @@ -11,104 +11,71 @@ #ifndef BOOL_DECODER_H #define BOOL_DECODER_H #include <stddef.h> -#include <limits.h> -#include "vpx_ports/config.h" -#include "vpx_ports/mem.h" - - -typedef size_t vp8_bool_value_t; -# define VP8_BD_VALUE_SIZE ((int)sizeof(vp8_bool_value_t)*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 VP8_LOTS_OF_BITS (0x40000000) - - -DECLARE_ALIGNED(16, extern const unsigned int, vp8dx_bitreader_norm[256]); - struct bool_decoder { - const unsigned char *user_buffer_end; - const unsigned char *user_buffer; - vp8_bool_value_t value; - int count; - unsigned int range; + const unsigned char *input; /* pointer to next compressed data byte */ + size_t input_len; /* length of the input buffer */ + unsigned int range; /* always identical to encoder's range */ + unsigned int value; /* contains at least 8 significant bits */ + int bit_count; /* # of bits shifted out of value, max 7 */ }; -int vp8dx_bool_init(struct bool_decoder *br, const unsigned char *source, - unsigned int source_sz); - -void vp8dx_bool_fill(struct bool_decoder *br); - - -/*The refill loop is used in several places, so define it in a macro to make - sure they're all consistent. - An inline function would be cleaner, but has a significant penalty, because - multiple BOOL_DECODER fields must be modified, and the compiler is not smart - enough to eliminate the stores to those fields and the subsequent reloads - from them when inlining the function.*/ -#define VP8DX_BOOL_DECODER_FILL(_count,_value,_bufptr,_bufend) \ - do \ - { \ - int shift; \ - for(shift = VP8_BD_VALUE_SIZE - 8 - ((_count) + 8); shift >= 0; ) \ - { \ - if((_bufptr) >= (_bufend)) { \ - (_count) = VP8_LOTS_OF_BITS; \ - break; \ - } \ - (_count) += 8; \ - (_value) |= (vp8_bool_value_t)*(_bufptr)++ << shift; \ - shift -= 8; \ - } \ - } \ - while(0) - - -static int bool_get(struct bool_decoder *br, int probability) +static void +init_bool_decoder(struct bool_decoder *d, + const unsigned char *start_partition, + size_t sz) { - unsigned int bit = 0; - vp8_bool_value_t value; - unsigned int split; - vp8_bool_value_t bigsplit; - int count; - unsigned int range; - - value = br->value; - count = br->count; - range = br->range; - - split = 1 + (((range - 1) * probability) >> 8); - bigsplit = (vp8_bool_value_t)split << (VP8_BD_VALUE_SIZE - 8); - - range = split; - - if (value >= bigsplit) + if(sz >= 2) { - range = br->range - split; - value = value - bigsplit; - bit = 1; + d->value = (start_partition[0] << 8) /* first 2 input bytes */ + | start_partition[1]; + d->input = start_partition + 2; /* ptr to next byte to be read */ + d->input_len = sz - 2; } - + else { - register unsigned int shift = vp8dx_bitreader_norm[range]; - range <<= shift; - value <<= shift; - count -= shift; + d->value = 0; + d->input = NULL; + d->input_len = 0; } + d->range = 255; /* initial range is full */ + d->bit_count = 0; /* have not yet shifted out any bits */ +} - br->value = value; - br->count = count; - br->range = range; - - if (count < 0) - vp8dx_bool_fill(br); - return bit; +static int bool_get(struct bool_decoder *d, int probability) +{ + /* range and split are identical to the corresponding values + used by the encoder when this bool was written */ + + unsigned int split = 1 + ( ((d->range - 1) * probability) >> 8); + unsigned int SPLIT = split << 8; + int retval; /* will be 0 or 1 */ + + if( d->value >= SPLIT) { /* encoded a one */ + retval = 1; + d->range -= split; /* reduce range */ + d->value -= SPLIT; /* subtract off left endpoint of interval */ + } else { /* encoded a zero */ + retval = 0; + d->range = split; /* reduce range, no change in left endpoint */ + } + + while( d->range < 128) { /* shift out irrelevant value bits */ + d->value <<= 1; + d->range <<= 1; + if( ++d->bit_count == 8) { /* shift in new bits 8 at a time */ + d->bit_count = 0; + if(d->input_len) + { + d->value |= *d->input++; + d->input_len--; + } + } + } + return retval; } @@ -148,18 +115,7 @@ static int bool_get_int(struct bool_decoder *br, int bits) static int bool_maybe_get_int(struct bool_decoder *br, int bits) { - int z = 0; - int bit; - - if (!bool_get_bit(br)) - return 0; - - for (bit = bits - 1; bit >= 0; bit--) - { - z |= (bool_get_bit(br) << bit); - } - - return bool_get_bit(br) ? -z : z; + return bool_get_bit(br) ? bool_get_int(br, bits) : 0; } diff --git a/vp8/dixie/dixie.c b/vp8/dixie/dixie.c index be3a6a92e2..e895f316e0 100644 --- a/vp8/dixie/dixie.c +++ b/vp8/dixie/dixie.c @@ -151,7 +151,7 @@ decode_and_init_token_partitions(struct vp8_decoder_ctx *ctx, for (i = 0; i < ctx->token_hdr.partitions; i++) { - vp8dx_bool_init(&ctx->tokens[i].bool, data, + init_bool_decoder(&ctx->tokens[i].bool, data, ctx->token_hdr.partition_sz[i]); data += ctx->token_hdr.partition_sz[i]; } @@ -332,7 +332,7 @@ decode_frame(struct vp8_decoder_ctx *ctx, } /* Start the bitreader for the header/entropy partition */ - vp8dx_bool_init(&bool, data, ctx->frame_hdr.part0_sz); + init_bool_decoder(&bool, data, ctx->frame_hdr.part0_sz); /* Skip the colorspace and clamping bits */ if (ctx->frame_hdr.is_keyframe) diff --git a/vp8/dixie/predict.c b/vp8/dixie/predict.c index 0a5f4cac62..22fab6536e 100644 --- a/vp8/dixie/predict.c +++ b/vp8/dixie/predict.c @@ -10,6 +10,7 @@ #include "dixie.h" #include "predict.h" #include "idct_add.h" +#include "vpx_ports/mem.h" #include <assert.h> #include <string.h> diff --git a/vp8/dixie/tokens.c b/vp8/dixie/tokens.c index 787aa202c2..89f1a3ea80 100644 --- a/vp8/dixie/tokens.c +++ b/vp8/dixie/tokens.c @@ -86,74 +86,23 @@ static const unsigned int zigzag[16] = 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 }; -#define FILL \ - if(count < 0) \ - VP8DX_BOOL_DECODER_FILL(count, value, bufptr, bufend); - -#define NORMALIZE \ - /*if(range < 0x80)*/ \ - { \ - shift = vp8dx_bitreader_norm[range]; \ - range <<= shift; \ - value <<= shift; \ - count -= shift; \ - } - #define DECODE_AND_APPLYSIGN(value_to_sign) \ - split = (range + 1) >> 1; \ - bigsplit = (vp8_bool_value_t)split << (VP8_BD_VALUE_SIZE - 8); \ - FILL \ - if ( value < bigsplit ) \ - { \ - range = split; \ - v= value_to_sign; \ - } \ - else \ - { \ - range = range-split; \ - value = value-bigsplit; \ - v = -value_to_sign; \ - } \ - v *= dqf[!!c]; \ - range +=range; \ - value +=value; \ - count--; + v = (bool_get_bit(bool) ? -value_to_sign : value_to_sign) * dqf[!!c]; #define DECODE_AND_BRANCH_IF_ZERO(probability,branch) \ - { \ - split = 1 + ((( probability*(range-1) ) )>> 8); \ - bigsplit = (vp8_bool_value_t)split << (VP8_BD_VALUE_SIZE - 8); \ - FILL \ - if ( value < bigsplit ) \ - { \ - range = split; \ - NORMALIZE \ - goto branch; \ - } \ - value -= bigsplit; \ - range = range - split; \ - NORMALIZE \ - } + if (!bool_get(bool, probability)) goto branch; #define DECODE_AND_LOOP_IF_ZERO(probability,branch) \ + if (!bool_get(bool, probability)) \ { \ - split = 1 + ((( probability*(range-1) ) ) >> 8); \ - bigsplit = (vp8_bool_value_t)split << (VP8_BD_VALUE_SIZE - 8); \ - FILL \ - if ( value < bigsplit ) \ - { \ - range = split; \ - NORMALIZE \ - prob = type_probs; \ - if(c<15) {\ - ++c; \ - prob += bands_x[c]; \ - goto branch; \ - } goto BLOCK_FINISHED; /*for malformed input */\ - } \ - value -= bigsplit; \ - range = range - split; \ - NORMALIZE \ + prob = type_probs; \ + if(c<15) {\ + ++c; \ + prob += bands_x[c]; \ + goto branch; \ + }\ + else \ + goto BLOCK_FINISHED; /*for malformed input */\ } #define DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val) \ @@ -168,20 +117,7 @@ static const unsigned int zigzag[16] = #define DECODE_EXTRABIT_AND_ADJUST_VAL(t,bits_count)\ - split = 1 + (((range-1) * extrabits[t].probs[bits_count]) >> 8); \ - bigsplit = (vp8_bool_value_t)split << (VP8_BD_VALUE_SIZE - 8); \ - FILL \ - if(value >= bigsplit)\ - {\ - range = range-split;\ - value = value-bigsplit;\ - val += 1<<bits_count;\ - }\ - else\ - {\ - range = split;\ - }\ - NORMALIZE + val += bool_get(bool, extrabits[t].probs[bits_count]) << bits_count; static int @@ -202,16 +138,6 @@ decode_mb_tokens(struct bool_decoder *bool, unsigned char *prob; short *dqf; - /* Unpack bool decoder to local variables */ - const unsigned char *bufend = bool->user_buffer_end; - const unsigned char *bufptr = bool->user_buffer; - vp8_bool_value_t value = bool->value; - int count = bool->count; - unsigned int range = bool->range; - unsigned int split; - vp8_bool_value_t bigsplit; - unsigned int shift; - eob_mask = 0; if (mode != B_PRED && mode != SPLITMV) @@ -360,11 +286,6 @@ BLOCK_FINISHED: goto BLOCK_LOOP; } - FILL - bool->user_buffer = bufptr; - bool->value = value; - bool->count = count; - bool->range = range; return eob_mask; } diff --git a/vp8/vp8dx.mk b/vp8/vp8dx.mk index 7ae3875aed..a36bbfcc9c 100644 --- a/vp8/vp8dx.mk +++ b/vp8/vp8dx.mk @@ -27,7 +27,6 @@ VP8_DX_SRCS-$(CONFIG_DIXIE) += vp8_dixie_iface.c VP8_DX_SRCS-$(CONFIG_DIXIE) += dixie/bit_ops.h VP8_DX_SRCS-$(CONFIG_DIXIE) += dixie/dixie.h VP8_DX_SRCS-$(CONFIG_DIXIE) += dixie/dixie.c -VP8_DX_SRCS-$(CONFIG_DIXIE) += dixie/bool_decoder.c VP8_DX_SRCS-$(CONFIG_DIXIE) += dixie/bool_decoder.h VP8_DX_SRCS-$(CONFIG_DIXIE) += dixie/modemv.c VP8_DX_SRCS-$(CONFIG_DIXIE) += dixie/modemv.h -- GitLab