FFmpeg
Loading...
Searching...
No Matches
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
22#include "libavcodec/cabac.c"
23
24#define SIZE 10240
25
26#include "libavutil/lfg.h"
27#include "libavcodec/put_bits.h"
28
34
35static inline void put_cabac_bit(CABACTestContext *c, int b)
36{
37 put_bits(&c->pb, 1, b);
38 for(;c->outstanding_count; c->outstanding_count--){
39 put_bits(&c->pb, 1, 1-b);
40 }
41}
42
44{
45 while (c->dec.range < 0x100) {
46 //FIXME optimize
47 if (c->dec.low < 0x100) {
48 put_cabac_bit(c, 0);
49 } else if (c->dec.low < 0x200) {
50 c->outstanding_count++;
51 c->dec.low -= 0x100;
52 }else{
53 put_cabac_bit(c, 1);
54 c->dec.low -= 0x200;
55 }
56
57 c->dec.range += c->dec.range;
58 c->dec.low += c->dec.low;
59 }
60}
61
62static void put_cabac(CABACTestContext *c, uint8_t * const state, int bit)
63{
64 int RangeLPS = ff_h264_lps_range[2 * (c->dec.range & 0xC0) + *state];
65
66 if(bit == ((*state)&1)){
67 c->dec.range -= RangeLPS;
69 }else{
70 c->dec.low += c->dec.range - RangeLPS;
71 c->dec.range = RangeLPS;
73 }
74
76}
77
78/**
79 * @param bit 0 -> write zero bit, !=0 write one bit
80 */
82{
83 c->dec.low += c->dec.low;
84
85 if(bit){
86 c->dec.low += c->dec.range;
87 }
88//FIXME optimize
89 if (c->dec.low < 0x200) {
90 put_cabac_bit(c, 0);
91 } else if (c->dec.low < 0x400) {
92 c->outstanding_count++;
93 c->dec.low -= 0x200;
94 }else{
95 put_cabac_bit(c, 1);
96 c->dec.low -= 0x400;
97 }
98}
99
100/**
101 *
102 * @return the number of bytes written
103 */
105{
106 c->dec.range -= 2;
107
108 if(!bit){
110 }else{
111 c->dec.low += c->dec.range;
112 c->dec.range = 2;
113
115
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);
119
120 flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
121 }
122
123 return put_bytes_count(&c->pb, 1);
124}
125
126/**
127 * @param buf_size size of buf in bits
128 */
129static void init_cabac_encoder(CABACTestContext *c, uint8_t *buf, int buf_size)
130{
131 init_put_bits(&c->pb, buf, buf_size);
132
133 c->dec.low = 0;
134 c->dec.range = 0x1FE;
135 c->outstanding_count = 0;
136 c->pb.bit_left++; //avoids firstBitFlag
137}
138
139int main(void){
141 uint8_t b[9*SIZE];
142 uint8_t r[9*SIZE];
143 int i, ret = 0;
144 uint8_t state[10]= {0};
145 AVLFG prng;
146
147 av_lfg_init(&prng, 1);
149
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;
153 }
154
155 for(i=0; i<SIZE; i++){
156 put_cabac_bypass(&c, r[i]&1);
157 }
158
159 for(i=0; i<SIZE; i++){
160 put_cabac(&c, state, r[i]&1);
161 }
162
163 i= put_cabac_terminate(&c, 1);
164 b[i++] = av_lfg_get(&prng);
165 b[i ] = av_lfg_get(&prng);
166
168
169 memset(state, 0, sizeof(state));
170
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);
174 ret = 1;
175 }
176 }
177
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);
181 ret = 1;
182 }
183 }
184 if (!get_cabac_terminate(&c.dec)) {
185 av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
186 ret = 1;
187 }
188
189 return ret;
190}
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition avassert.h:42
#define SIZE
Context Adaptive Binary Arithmetic Coder.
int ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size)
Definition cabac.c:162
Context Adaptive Binary Arithmetic Coder inline functions.
static av_unused int get_cabac_terminate(CABACContext *c)
av_unused static av_noinline int get_cabac_noinline(CABACContext *c, uint8_t *const state)
static const uint8_t *const ff_h264_lps_range
static const uint8_t *const ff_h264_mlps_state
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define bit(string, value)
Definition cbs_mpeg2.c:56
#define NULL
Definition coverity.c:32
static struct @346255127015250356166251341105367306144006377143 state
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
#define r
Definition input.c:42
#define b
Definition input.c:43
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition j2kenc.c:154
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition lfg.c:32
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition lfg.h:53
#define get_cabac_bypass
Definition cabac.h:149
bitstream writer API
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition put_bits.h:62
static int put_bytes_count(const PutBitContext *s, int round_up)
Definition put_bits.h:110
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition put_bits.h:153
Context structure for the Lagged Fibonacci PRNG.
Definition lfg.h:33
PutBitContext pb
Definition cabac.c:32
CABACContext dec
Definition cabac.c:30
int outstanding_count
Definition cabac.c:31
#define av_log(a,...)
static void init_cabac_encoder(CABACTestContext *c, uint8_t *buf, int buf_size)
Definition cabac.c:129
static void renorm_cabac_encoder(CABACTestContext *c)
Definition cabac.c:43
static void put_cabac(CABACTestContext *c, uint8_t *const state, int bit)
Definition cabac.c:62
static void put_cabac_bypass(CABACTestContext *c, int bit)
Definition cabac.c:81
static void put_cabac_bit(CABACTestContext *c, int b)
Definition cabac.c:35
int main(void)
Definition cabac.c:139
static int put_cabac_terminate(CABACTestContext *c, int bit)
Definition cabac.c:104
static void prng(CheckasmRand *restrict xs, uint8_t *restrict buf, size_t size)
Definition utils.c:154
static double c[64]