FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cabac.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
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 #include "libavcodec/cabac.c"
22 
23 #define SIZE 10240
24 
25 #include "libavutil/lfg.h"
26 #include "libavcodec/avcodec.h"
27 
28 static inline void put_cabac_bit(CABACContext *c, int b){
29  put_bits(&c->pb, 1, b);
30  for(;c->outstanding_count; c->outstanding_count--){
31  put_bits(&c->pb, 1, 1-b);
32  }
33 }
34 
35 static inline void renorm_cabac_encoder(CABACContext *c){
36  while(c->range < 0x100){
37  //FIXME optimize
38  if(c->low<0x100){
39  put_cabac_bit(c, 0);
40  }else if(c->low<0x200){
41  c->outstanding_count++;
42  c->low -= 0x100;
43  }else{
44  put_cabac_bit(c, 1);
45  c->low -= 0x200;
46  }
47 
48  c->range+= c->range;
49  c->low += c->low;
50  }
51 }
52 
53 static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
54  int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
55 
56  if(bit == ((*state)&1)){
57  c->range -= RangeLPS;
58  *state = ff_h264_mlps_state[128 + *state];
59  }else{
60  c->low += c->range - RangeLPS;
61  c->range = RangeLPS;
62  *state= ff_h264_mlps_state[127 - *state];
63  }
64 
66 }
67 
68 /**
69  * @param bit 0 -> write zero bit, !=0 write one bit
70  */
71 static void put_cabac_bypass(CABACContext *c, int bit){
72  c->low += c->low;
73 
74  if(bit){
75  c->low += c->range;
76  }
77 //FIXME optimize
78  if(c->low<0x200){
79  put_cabac_bit(c, 0);
80  }else if(c->low<0x400){
81  c->outstanding_count++;
82  c->low -= 0x200;
83  }else{
84  put_cabac_bit(c, 1);
85  c->low -= 0x400;
86  }
87 }
88 
89 /**
90  *
91  * @return the number of bytes written
92  */
93 static int put_cabac_terminate(CABACContext *c, int bit){
94  c->range -= 2;
95 
96  if(!bit){
98  }else{
99  c->low += c->range;
100  c->range= 2;
101 
103 
104  av_assert0(c->low <= 0x1FF);
105  put_cabac_bit(c, c->low>>9);
106  put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
107 
108  flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
109  }
110 
111  return (put_bits_count(&c->pb)+7)>>3;
112 }
113 
114 int main(void){
115  CABACContext c;
116  uint8_t b[9*SIZE];
117  uint8_t r[9*SIZE];
118  int i, ret = 0;
119  uint8_t state[10]= {0};
120  AVLFG prng;
121 
122  av_lfg_init(&prng, 1);
123  ff_init_cabac_encoder(&c, b, SIZE);
124 
125  for(i=0; i<SIZE; i++){
126  if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7;
127  else r[i] = (i>>8)&1;
128  }
129 
130  for(i=0; i<SIZE; i++){
131  put_cabac_bypass(&c, r[i]&1);
132  }
133 
134  for(i=0; i<SIZE; i++){
135  put_cabac(&c, state, r[i]&1);
136  }
137 
138  i= put_cabac_terminate(&c, 1);
139  b[i++] = av_lfg_get(&prng);
140  b[i ] = av_lfg_get(&prng);
141 
142  ff_init_cabac_decoder(&c, b, SIZE);
143 
144  memset(state, 0, sizeof(state));
145 
146  for(i=0; i<SIZE; i++){
147  if( (r[i]&1) != get_cabac_bypass(&c) ) {
148  av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i);
149  ret = 1;
150  }
151  }
152 
153  for(i=0; i<SIZE; i++){
154  if( (r[i]&1) != get_cabac_noinline(&c, state) ) {
155  av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
156  ret = 1;
157  }
158  }
159  if(!get_cabac_terminate(&c)) {
160  av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
161  ret = 1;
162  }
163 
164  return ret;
165 }
Definition: lfg.h:25
#define NULL
Definition: coverity.c:32
static void renorm_cabac_encoder(CABACContext *c)
Definition: cabac.c:35
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition: j2kenc.c:206
const char * b
Definition: vf_curves.c:109
static int put_cabac_terminate(CABACContext *c, int bit)
Definition: cabac.c:93
static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t *const state)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
int main(void)
Definition: cabac.c:114
static void put_cabac(CABACContext *c, uint8_t *const state, int bit)
Definition: cabac.c:53
uint8_t
#define SIZE
Definition: cabac.c:23
#define av_log(a,...)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
const char * r
Definition: vf_curves.c:107
static int put_bits_count(PutBitContext *s)
Definition: put_bits.h:85
int ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size)
Definition: cabac.c:177
void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size)
Definition: cabac.c:164
static int av_unused get_cabac_terminate(CABACContext *c)
Libavcodec external API header.
static void put_cabac_bypass(CABACContext *c, int bit)
Definition: cabac.c:71
int outstanding_count
Definition: cabac.h:46
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition: lfg.h:38
int range
Definition: cabac.h:45
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:30
PutBitContext pb
Definition: cabac.h:50
static void put_cabac_bit(CABACContext *c, int b)
Definition: cabac.c:28
static struct @228 state
static int av_unused get_cabac_bypass(CABACContext *c)
int low
Definition: cabac.h:44
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition: put_bits.h:101
static double c[64]
static const uint8_t *const ff_h264_lps_range
Context Adaptive Binary Arithmetic Coder.
static const uint8_t *const ff_h264_mlps_state