1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libvpx/vp9/decoder/vp9_dboolhuff.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,92 @@ 1.4 +/* 1.5 + * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license 1.8 + * that can be found in the LICENSE file in the root of the source 1.9 + * tree. An additional intellectual property rights grant can be found 1.10 + * in the file PATENTS. All contributing project authors may 1.11 + * be found in the AUTHORS file in the root of the source tree. 1.12 + */ 1.13 + 1.14 +#include "vpx_ports/mem.h" 1.15 +#include "vpx_mem/vpx_mem.h" 1.16 + 1.17 +#include "vp9/decoder/vp9_dboolhuff.h" 1.18 + 1.19 +// This is meant to be a large, positive constant that can still be efficiently 1.20 +// loaded as an immediate (on platforms like ARM, for example). 1.21 +// Even relatively modest values like 100 would work fine. 1.22 +#define LOTS_OF_BITS 0x40000000 1.23 + 1.24 + 1.25 +int vp9_reader_init(vp9_reader *r, const uint8_t *buffer, size_t size) { 1.26 + int marker_bit; 1.27 + 1.28 + r->buffer_end = buffer + size; 1.29 + r->buffer = buffer; 1.30 + r->value = 0; 1.31 + r->count = -8; 1.32 + r->range = 255; 1.33 + 1.34 + if (size && !buffer) 1.35 + return 1; 1.36 + 1.37 + vp9_reader_fill(r); 1.38 + marker_bit = vp9_read_bit(r); 1.39 + return marker_bit != 0; 1.40 +} 1.41 + 1.42 +void vp9_reader_fill(vp9_reader *r) { 1.43 + const uint8_t *const buffer_end = r->buffer_end; 1.44 + const uint8_t *buffer = r->buffer; 1.45 + VP9_BD_VALUE value = r->value; 1.46 + int count = r->count; 1.47 + int shift = BD_VALUE_SIZE - 8 - (count + 8); 1.48 + int loop_end = 0; 1.49 + const int bits_left = (int)((buffer_end - buffer)*CHAR_BIT); 1.50 + const int x = shift + CHAR_BIT - bits_left; 1.51 + 1.52 + if (x >= 0) { 1.53 + count += LOTS_OF_BITS; 1.54 + loop_end = x; 1.55 + } 1.56 + 1.57 + if (x < 0 || bits_left) { 1.58 + while (shift >= loop_end) { 1.59 + count += CHAR_BIT; 1.60 + value |= (VP9_BD_VALUE)*buffer++ << shift; 1.61 + shift -= CHAR_BIT; 1.62 + } 1.63 + } 1.64 + 1.65 + r->buffer = buffer; 1.66 + r->value = value; 1.67 + r->count = count; 1.68 +} 1.69 + 1.70 +const uint8_t *vp9_reader_find_end(vp9_reader *r) { 1.71 + // Find the end of the coded buffer 1.72 + while (r->count > CHAR_BIT && r->count < BD_VALUE_SIZE) { 1.73 + r->count -= CHAR_BIT; 1.74 + r->buffer--; 1.75 + } 1.76 + return r->buffer; 1.77 +} 1.78 + 1.79 +int vp9_reader_has_error(vp9_reader *r) { 1.80 + // Check if we have reached the end of the buffer. 1.81 + // 1.82 + // Variable 'count' stores the number of bits in the 'value' buffer, minus 1.83 + // 8. The top byte is part of the algorithm, and the remainder is buffered 1.84 + // to be shifted into it. So if count == 8, the top 16 bits of 'value' are 1.85 + // occupied, 8 for the algorithm and 8 in the buffer. 1.86 + // 1.87 + // When reading a byte from the user's buffer, count is filled with 8 and 1.88 + // one byte is filled into the value buffer. When we reach the end of the 1.89 + // data, count is additionally filled with LOTS_OF_BITS. So when 1.90 + // count == LOTS_OF_BITS - 1, the user's data has been exhausted. 1.91 + // 1.92 + // 1 if we have tried to decode bits after the end of stream was encountered. 1.93 + // 0 No error. 1.94 + return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS; 1.95 +}