media/libvpx/vp9/decoder/vp9_dboolhuff.c

changeset 0
6474c204b198
     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 +}

mercurial