summaryrefslogtreecommitdiff
path: root/vp8/decoder/dboolhuff.h
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/decoder/dboolhuff.h')
-rw-r--r--vp8/decoder/dboolhuff.h226
1 files changed, 226 insertions, 0 deletions
diff --git a/vp8/decoder/dboolhuff.h b/vp8/decoder/dboolhuff.h
new file mode 100644
index 000000000..f5c982202
--- /dev/null
+++ b/vp8/decoder/dboolhuff.h
@@ -0,0 +1,226 @@
+/*
+ * 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.
+ */
+
+
+#ifndef DBOOLHUFF_H
+#define DBOOLHUFF_H
+#include "vpx_ports/config.h"
+#include "vpx_ports/mem.h"
+#include "vpx_ports/vpx_integer.h"
+
+/* Size of the bool decoder backing storage
+ *
+ * This size was chosen to be greater than the worst case encoding of a
+ * single macroblock. This was calcluated as follows (python):
+ *
+ * def max_cost(prob):
+ * return max(prob_costs[prob], prob_costs[255-prob]) / 256;
+ *
+ * tree_nodes_cost = 7 * max_cost(255)
+ * extra_bits_cost = sum([max_cost(bit) for bit in extra_bits])
+ * sign_bit_cost = max_cost(128)
+ * total_cost = tree_nodes_cost + extra_bits_cost + sign_bit_cost
+ *
+ * where the prob_costs table was taken from the C vp8_prob_cost table in
+ * boolhuff.c and the extra_bits table was taken from the 11 extrabits for
+ * a category 6 token as defined in vp8d_token_extra_bits2/detokenize.c
+ *
+ * This equation produced a maximum of 79 bits per coefficient. Scaling up
+ * to the macroblock level:
+ *
+ * 79 bits/coeff * 16 coeff/block * 25 blocks/macroblock = 31600 b/mb
+ *
+ * 4096 bytes = 32768 bits > 31600
+ */
+#define VP8_BOOL_DECODER_SZ 4096
+#define VP8_BOOL_DECODER_MASK (VP8_BOOL_DECODER_SZ-1)
+#define VP8_BOOL_DECODER_PTR_MASK (~(uintptr_t)(VP8_BOOL_DECODER_SZ))
+
+struct vp8_dboolhuff_rtcd_vtable;
+
+typedef struct
+{
+ unsigned int lowvalue;
+ unsigned int range;
+ unsigned int value;
+ int count;
+ const unsigned char *user_buffer;
+ unsigned int user_buffer_sz;
+ unsigned char *decode_buffer;
+ const unsigned char *read_ptr;
+ unsigned char *write_ptr;
+#if CONFIG_RUNTIME_CPU_DETECT
+ struct vp8_dboolhuff_rtcd_vtable *rtcd;
+#endif
+} BOOL_DECODER;
+
+#define prototype_dbool_start(sym) int sym(BOOL_DECODER *br, \
+ const unsigned char *source, unsigned int source_sz)
+#define prototype_dbool_stop(sym) void sym(BOOL_DECODER *bc)
+#define prototype_dbool_fill(sym) void sym(BOOL_DECODER *br)
+#define prototype_dbool_debool(sym) int sym(BOOL_DECODER *br, int probability)
+#define prototype_dbool_devalue(sym) int sym(BOOL_DECODER *br, int bits);
+
+#if ARCH_ARM
+#include "arm/dboolhuff_arm.h"
+#endif
+
+#ifndef vp8_dbool_start
+#define vp8_dbool_start vp8dx_start_decode_c
+#endif
+
+#ifndef vp8_dbool_stop
+#define vp8_dbool_stop vp8dx_stop_decode_c
+#endif
+
+#ifndef vp8_dbool_fill
+#define vp8_dbool_fill vp8dx_bool_decoder_fill_c
+#endif
+
+#ifndef vp8_dbool_debool
+#define vp8_dbool_debool vp8dx_decode_bool_c
+#endif
+
+#ifndef vp8_dbool_devalue
+#define vp8_dbool_devalue vp8dx_decode_value_c
+#endif
+
+extern prototype_dbool_start(vp8_dbool_start);
+extern prototype_dbool_stop(vp8_dbool_stop);
+extern prototype_dbool_fill(vp8_dbool_fill);
+extern prototype_dbool_debool(vp8_dbool_debool);
+extern prototype_dbool_devalue(vp8_dbool_devalue);
+
+typedef prototype_dbool_start((*vp8_dbool_start_fn_t));
+typedef prototype_dbool_stop((*vp8_dbool_stop_fn_t));
+typedef prototype_dbool_fill((*vp8_dbool_fill_fn_t));
+typedef prototype_dbool_debool((*vp8_dbool_debool_fn_t));
+typedef prototype_dbool_devalue((*vp8_dbool_devalue_fn_t));
+
+typedef struct vp8_dboolhuff_rtcd_vtable {
+ vp8_dbool_start_fn_t start;
+ vp8_dbool_stop_fn_t stop;
+ vp8_dbool_fill_fn_t fill;
+ vp8_dbool_debool_fn_t debool;
+ vp8_dbool_devalue_fn_t devalue;
+} vp8_dboolhuff_rtcd_vtable_t;
+
+// There are no processor-specific versions of these
+// functions right now. Disable RTCD to avoid using
+// function pointers which gives a speed boost
+//#ifdef ENABLE_RUNTIME_CPU_DETECT
+//#define DBOOLHUFF_INVOKE(ctx,fn) (ctx)->fn
+//#define IF_RTCD(x) (x)
+//#else
+#define DBOOLHUFF_INVOKE(ctx,fn) vp8_dbool_##fn
+#define IF_RTCD(x) NULL
+//#endif
+
+static unsigned char *br_ptr_advance(const unsigned char *_ptr,
+ unsigned int n)
+{
+ uintptr_t ptr = (uintptr_t)_ptr;
+
+ ptr += n;
+ ptr &= VP8_BOOL_DECODER_PTR_MASK;
+
+ return (void *)ptr;
+}
+
+DECLARE_ALIGNED(16, extern const unsigned int, vp8dx_bitreader_norm[256]);
+
+/* wrapper functions to hide RTCD. static means inline means hopefully no
+ * penalty
+ */
+static int vp8dx_start_decode(BOOL_DECODER *br,
+ struct vp8_dboolhuff_rtcd_vtable *rtcd,
+ const unsigned char *source, unsigned int source_sz) {
+#if CONFIG_RUNTIME_CPU_DETECT
+ br->rtcd = rtcd;
+#endif
+ return DBOOLHUFF_INVOKE(rtcd, start)(br, source, source_sz);
+}
+static void vp8dx_stop_decode(BOOL_DECODER *br) {
+ DBOOLHUFF_INVOKE(br->rtcd, stop)(br);
+}
+static void vp8dx_bool_decoder_fill(BOOL_DECODER *br) {
+ DBOOLHUFF_INVOKE(br->rtcd, fill)(br);
+}
+static int vp8dx_decode_bool(BOOL_DECODER *br, int probability) {
+ /*
+ * Until optimized versions of this function are available, we
+ * keep the implementation in the header to allow inlining.
+ *
+ *return DBOOLHUFF_INVOKE(br->rtcd, debool)(br, probability);
+ */
+ unsigned int bit = 0;
+ unsigned int split;
+ unsigned int bigsplit;
+ register unsigned int range = br->range;
+ register unsigned int value = br->value;
+
+ split = 1 + (((range - 1) * probability) >> 8);
+ bigsplit = (split << 8);
+
+ range = split;
+
+ if (value >= bigsplit)
+ {
+ range = br->range - split;
+ value = value - bigsplit;
+ bit = 1;
+ }
+
+ /*if(range>=0x80)
+ {
+ br->value = value;
+ br->range = range;
+ return bit
+ }*/
+
+ {
+ int count = br->count;
+ register unsigned int shift = vp8dx_bitreader_norm[range];
+ range <<= shift;
+ value <<= shift;
+ count -= shift;
+
+ if (count <= 0)
+ {
+ value |= (*br->read_ptr) << (-count);
+ br->read_ptr = br_ptr_advance(br->read_ptr, 1);
+ count += 8 ;
+ }
+
+ br->count = count;
+ }
+ br->value = value;
+ br->range = range;
+ return bit;
+}
+
+static int vp8_decode_value(BOOL_DECODER *br, int bits)
+{
+ /*
+ * Until optimized versions of this function are available, we
+ * keep the implementation in the header to allow inlining.
+ *
+ *return DBOOLHUFF_INVOKE(br->rtcd, devalue)(br, bits);
+ */
+ int z = 0;
+ int bit;
+
+ for (bit = bits - 1; bit >= 0; bit--)
+ {
+ z |= (vp8dx_decode_bool(br, 0x80) << bit);
+ }
+
+ return z;
+}
+#endif