2 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of FFmpeg.
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.
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.
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
21 #include "libavcodec/cabac.c"
25 #include "libavutil/lfg.h"
26 #include "libavcodec/avcodec.h"
27 #include "libavcodec/put_bits.h"
29 typedef struct CABACTestContext {
31 int outstanding_count;
35 static inline void put_cabac_bit(CABACTestContext *c, int b)
37 put_bits(&c->pb, 1, b);
38 for(;c->outstanding_count; c->outstanding_count--){
39 put_bits(&c->pb, 1, 1-b);
43 static inline void renorm_cabac_encoder(CABACTestContext *c)
45 while (c->dec.range < 0x100) {
47 if (c->dec.low < 0x100) {
49 } else if (c->dec.low < 0x200) {
50 c->outstanding_count++;
57 c->dec.range += c->dec.range;
58 c->dec.low += c->dec.low;
62 static void put_cabac(CABACTestContext *c, uint8_t * const state, int bit)
64 int RangeLPS = ff_h264_lps_range[2 * (c->dec.range & 0xC0) + *state];
66 if(bit == ((*state)&1)){
67 c->dec.range -= RangeLPS;
68 *state = ff_h264_mlps_state[128 + *state];
70 c->dec.low += c->dec.range - RangeLPS;
71 c->dec.range = RangeLPS;
72 *state= ff_h264_mlps_state[127 - *state];
75 renorm_cabac_encoder(c);
79 * @param bit 0 -> write zero bit, !=0 write one bit
81 static void put_cabac_bypass(CABACTestContext *c, int bit)
83 c->dec.low += c->dec.low;
86 c->dec.low += c->dec.range;
89 if (c->dec.low < 0x200) {
91 } else if (c->dec.low < 0x400) {
92 c->outstanding_count++;
102 * @return the number of bytes written
104 static int put_cabac_terminate(CABACTestContext *c, int bit)
109 renorm_cabac_encoder(c);
111 c->dec.low += c->dec.range;
114 renorm_cabac_encoder(c);
116 av_assert0(c->dec.low <= 0x1FF);
117 put_cabac_bit(c, c->dec.low >> 9);
118 put_bits(&c->pb, 2, ((c->dec.low >> 7) & 3) | 1);
120 flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
123 return put_bytes_count(&c->pb, 1);
127 * @param buf_size size of buf in bits
129 static void init_cabac_encoder(CABACTestContext *c, uint8_t *buf, int buf_size)
131 init_put_bits(&c->pb, buf, buf_size);
134 c->dec.range = 0x1FE;
135 c->outstanding_count = 0;
136 c->pb.bit_left++; //avoids firstBitFlag
144 uint8_t state[10]= {0};
147 av_lfg_init(&prng, 1);
148 init_cabac_encoder(&c, b, SIZE);
150 for(i=0; i<SIZE; i++){
151 if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7;
152 else r[i] = (i>>8)&1;
155 for(i=0; i<SIZE; i++){
156 put_cabac_bypass(&c, r[i]&1);
159 for(i=0; i<SIZE; i++){
160 put_cabac(&c, state, r[i]&1);
163 i= put_cabac_terminate(&c, 1);
164 b[i++] = av_lfg_get(&prng);
165 b[i ] = av_lfg_get(&prng);
167 ff_init_cabac_decoder(&c.dec, b, SIZE);
169 memset(state, 0, sizeof(state));
171 for(i=0; i<SIZE; i++){
172 if ((r[i] & 1) != get_cabac_bypass(&c.dec)) {
173 av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i);
178 for(i=0; i<SIZE; i++){
179 if ((r[i] & 1) != get_cabac_noinline(&c.dec, state)) {
180 av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
184 if (!get_cabac_terminate(&c.dec)) {
185 av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");