FFmpeg
vpx_rac.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @file
23  * Common VP5-VP9 range decoder stuff
24  */
25 
26 #ifndef AVCODEC_VPX_RAC_H
27 #define AVCODEC_VPX_RAC_H
28 
29 #include <stdint.h>
30 
31 #include "config.h"
32 #include "libavutil/attributes.h"
33 #include "bytestream.h"
34 
35 typedef struct VPXRangeCoder {
36  int high;
37  int bits; /* stored negated (i.e. negative "bits" is a positive number of
38  bits left) in order to eliminate a negate in cache refilling */
39  const uint8_t *buffer;
40  const uint8_t *end;
41  unsigned int code_word;
44 
45 extern const uint8_t ff_vpx_norm_shift[256];
46 int ff_vpx_init_range_decoder(VPXRangeCoder *c, const uint8_t *buf, int buf_size);
47 
48 /**
49  * returns 1 if the end of the stream has been reached, 0 otherwise.
50  */
52 {
53  if (c->end <= c->buffer && c->bits >= 0)
54  c->end_reached ++;
55  return c->end_reached > 10;
56 }
57 
59 {
60  int shift = ff_vpx_norm_shift[c->high];
61  int bits = c->bits;
62  unsigned int code_word = c->code_word;
63 
64  c->high <<= shift;
65  code_word <<= shift;
66  bits += shift;
67  if(bits >= 0 && c->buffer < c->end) {
68  code_word |= bytestream_get_be16(&c->buffer) << bits;
69  bits -= 16;
70  }
71  c->bits = bits;
72  return code_word;
73 }
74 
75 #if ARCH_ARM
76 #include "arm/vpx_arith.h"
77 #elif ARCH_X86
78 #include "x86/vpx_arith.h"
79 #endif
80 
81 #ifndef vpx_rac_get_prob
82 #define vpx_rac_get_prob vpx_rac_get_prob
84 {
85  unsigned int code_word = vpx_rac_renorm(c);
86  unsigned int low = 1 + (((c->high - 1) * prob) >> 8);
87  unsigned int low_shift = low << 16;
88  int bit = code_word >= low_shift;
89 
90  c->high = bit ? c->high - low : low;
91  c->code_word = bit ? code_word - low_shift : code_word;
92 
93  return bit;
94 }
95 #endif
96 
97 #ifndef vpx_rac_get_prob_branchy
98 // branchy variant, to be used where there's a branch based on the bit decoded
100 {
101  unsigned long code_word = vpx_rac_renorm(c);
102  unsigned low = 1 + (((c->high - 1) * prob) >> 8);
103  unsigned low_shift = low << 16;
104 
105  if (code_word >= low_shift) {
106  c->high -= low;
107  c->code_word = code_word - low_shift;
108  return 1;
109  }
110 
111  c->high = low;
112  c->code_word = code_word;
113  return 0;
114 }
115 #endif
116 
118 {
119  unsigned int code_word = vpx_rac_renorm(c);
120  /* equiprobable */
121  int low = (c->high + 1) >> 1;
122  unsigned int low_shift = low << 16;
123  int bit = code_word >= low_shift;
124  if (bit) {
125  c->high -= low;
126  code_word -= low_shift;
127  } else {
128  c->high = low;
129  }
130 
131  c->code_word = code_word;
132  return bit;
133 }
134 
135 #endif /* AVCODEC_VPX_RAC_H */
VPXRangeCoder::end
const uint8_t * end
Definition: vpx_rac.h:40
VPXRangeCoder
Definition: vpx_rac.h:35
bit
#define bit(string, value)
Definition: cbs_mpeg2.c:56
vpx_arith.h
VPXRangeCoder::high
int high
Definition: vpx_rac.h:36
vpx_rac_renorm
static av_always_inline unsigned int vpx_rac_renorm(VPXRangeCoder *c)
Definition: vpx_rac.h:58
bits
uint8_t bits
Definition: vp3data.h:128
VPXRangeCoder::end_reached
int end_reached
Definition: vpx_rac.h:42
ff_vpx_norm_shift
const uint8_t ff_vpx_norm_shift[256]
Definition: vpx_rac.c:27
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
vpx_arith.h
VPXRangeCoder::buffer
const uint8_t * buffer
Definition: vpx_rac.h:39
shift
static int shift(int a, int b)
Definition: bonk.c:262
attributes.h
vpx_rac_is_end
static av_always_inline int vpx_rac_is_end(VPXRangeCoder *c)
returns 1 if the end of the stream has been reached, 0 otherwise.
Definition: vpx_rac.h:51
av_always_inline
#define av_always_inline
Definition: attributes.h:49
vpx_rac_get_prob_branchy
static av_always_inline int vpx_rac_get_prob_branchy(VPXRangeCoder *c, int prob)
Definition: vpx_rac.h:99
prob
#define prob(name, subs,...)
Definition: cbs_vp9.c:325
VPXRangeCoder::bits
int bits
Definition: vpx_rac.h:37
ff_vpx_init_range_decoder
int ff_vpx_init_range_decoder(VPXRangeCoder *c, const uint8_t *buf, int buf_size)
Definition: vpx_rac.c:42
VPXRangeCoder::code_word
unsigned int code_word
Definition: vpx_rac.h:41
vpx_rac_get
static av_always_inline int vpx_rac_get(VPXRangeCoder *c)
Definition: vpx_rac.h:117
bytestream.h
vpx_rac_get_prob
#define vpx_rac_get_prob
Definition: vpx_rac.h:82