Imported Debian version 2.4.3~trusty1
[deb_ffmpeg.git] / ffmpeg / libavcodec / cabac.c
CommitLineData
2ba45a60
DM
1/*
2 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/**
23 * @file
24 * Context Adaptive Binary Arithmetic Coder.
25 */
26
27#include <string.h>
28
29#include "libavutil/common.h"
30#include "libavutil/timer.h"
31#include "get_bits.h"
32#include "cabac.h"
33#include "cabac_functions.h"
34
35#include "cabac_tablegen.h"
36
37/**
38 *
39 * @param buf_size size of buf in bits
40 */
41void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){
42 init_put_bits(&c->pb, buf, buf_size);
43
44 c->low= 0;
45 c->range= 0x1FE;
46 c->outstanding_count= 0;
47 c->pb.bit_left++; //avoids firstBitFlag
48}
49
50/**
51 *
52 * @param buf_size size of buf in bits
53 */
54void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
55 c->bytestream_start=
56 c->bytestream= buf;
57 c->bytestream_end= buf + buf_size;
58
59#if CABAC_BITS == 16
60 c->low = (*c->bytestream++)<<18;
61 c->low+= (*c->bytestream++)<<10;
62#else
63 c->low = (*c->bytestream++)<<10;
64#endif
65 c->low+= ((*c->bytestream++)<<2) + 2;
66 c->range= 0x1FE;
67}
68
69void ff_init_cabac_states(void)
70{
71 static int initialized = 0;
72
73 if (initialized)
74 return;
75
76 cabac_tableinit();
77
78 initialized = 1;
79}
80
81#ifdef TEST
82#define SIZE 10240
83
84#include "libavutil/lfg.h"
85#include "avcodec.h"
86
87static inline void put_cabac_bit(CABACContext *c, int b){
88 put_bits(&c->pb, 1, b);
89 for(;c->outstanding_count; c->outstanding_count--){
90 put_bits(&c->pb, 1, 1-b);
91 }
92}
93
94static inline void renorm_cabac_encoder(CABACContext *c){
95 while(c->range < 0x100){
96 //FIXME optimize
97 if(c->low<0x100){
98 put_cabac_bit(c, 0);
99 }else if(c->low<0x200){
100 c->outstanding_count++;
101 c->low -= 0x100;
102 }else{
103 put_cabac_bit(c, 1);
104 c->low -= 0x200;
105 }
106
107 c->range+= c->range;
108 c->low += c->low;
109 }
110}
111
112static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
113 int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
114
115 if(bit == ((*state)&1)){
116 c->range -= RangeLPS;
117 *state = ff_h264_mlps_state[128 + *state];
118 }else{
119 c->low += c->range - RangeLPS;
120 c->range = RangeLPS;
121 *state= ff_h264_mlps_state[127 - *state];
122 }
123
124 renorm_cabac_encoder(c);
125}
126
127/**
128 * @param bit 0 -> write zero bit, !=0 write one bit
129 */
130static void put_cabac_bypass(CABACContext *c, int bit){
131 c->low += c->low;
132
133 if(bit){
134 c->low += c->range;
135 }
136//FIXME optimize
137 if(c->low<0x200){
138 put_cabac_bit(c, 0);
139 }else if(c->low<0x400){
140 c->outstanding_count++;
141 c->low -= 0x200;
142 }else{
143 put_cabac_bit(c, 1);
144 c->low -= 0x400;
145 }
146}
147
148/**
149 *
150 * @return the number of bytes written
151 */
152static int put_cabac_terminate(CABACContext *c, int bit){
153 c->range -= 2;
154
155 if(!bit){
156 renorm_cabac_encoder(c);
157 }else{
158 c->low += c->range;
159 c->range= 2;
160
161 renorm_cabac_encoder(c);
162
163 av_assert0(c->low <= 0x1FF);
164 put_cabac_bit(c, c->low>>9);
165 put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
166
167 flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
168 }
169
170 return (put_bits_count(&c->pb)+7)>>3;
171}
172
173int main(void){
174 CABACContext c;
175 uint8_t b[9*SIZE];
176 uint8_t r[9*SIZE];
177 int i;
178 uint8_t state[10]= {0};
179 AVLFG prng;
180
181 av_lfg_init(&prng, 1);
182 ff_init_cabac_encoder(&c, b, SIZE);
183 ff_init_cabac_states();
184
185 for(i=0; i<SIZE; i++){
186 if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7;
187 else r[i] = (i>>8)&1;
188 }
189
190 for(i=0; i<SIZE; i++){
191START_TIMER
192 put_cabac_bypass(&c, r[i]&1);
193STOP_TIMER("put_cabac_bypass")
194 }
195
196 for(i=0; i<SIZE; i++){
197START_TIMER
198 put_cabac(&c, state, r[i]&1);
199STOP_TIMER("put_cabac")
200 }
201
202 put_cabac_terminate(&c, 1);
203
204 ff_init_cabac_decoder(&c, b, SIZE);
205
206 memset(state, 0, sizeof(state));
207
208 for(i=0; i<SIZE; i++){
209START_TIMER
210 if( (r[i]&1) != get_cabac_bypass(&c) )
211 av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i);
212STOP_TIMER("get_cabac_bypass")
213 }
214
215 for(i=0; i<SIZE; i++){
216START_TIMER
217 if( (r[i]&1) != get_cabac_noinline(&c, state) )
218 av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
219STOP_TIMER("get_cabac")
220 }
221 if(!get_cabac_terminate(&c))
222 av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
223
224 return 0;
225}
226
227#endif /* TEST */