FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/tests/cabac.c
Date: 2024-10-04 17:46:48
Exec Total Coverage
Lines: 80 87 92.0%
Functions: 7 7 100.0%
Branches: 33 38 86.8%

Line Branch Exec Source
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_functions.h"
22 #include "libavcodec/cabac.c"
23
24 #define SIZE 10240
25
26 #include "libavutil/lfg.h"
27 #include "libavcodec/put_bits.h"
28
29 typedef struct CABACTestContext {
30 CABACContext dec;
31 int outstanding_count;
32 PutBitContext pb;
33 } CABACTestContext;
34
35 8410 static inline void put_cabac_bit(CABACTestContext *c, int b)
36 {
37 8410 put_bits(&c->pb, 1, b);
38
2/2
✓ Branch 0 taken 7994 times.
✓ Branch 1 taken 8410 times.
16404 for(;c->outstanding_count; c->outstanding_count--){
39 7994 put_bits(&c->pb, 1, 1-b);
40 }
41 8410 }
42
43 10241 static inline void renorm_cabac_encoder(CABACTestContext *c)
44 {
45
2/2
✓ Branch 0 taken 6163 times.
✓ Branch 1 taken 10241 times.
16404 while (c->dec.range < 0x100) {
46 //FIXME optimize
47
2/2
✓ Branch 0 taken 2370 times.
✓ Branch 1 taken 3793 times.
6163 if (c->dec.low < 0x100) {
48 2370 put_cabac_bit(c, 0);
49
2/2
✓ Branch 0 taken 2944 times.
✓ Branch 1 taken 849 times.
3793 } else if (c->dec.low < 0x200) {
50 2944 c->outstanding_count++;
51 2944 c->dec.low -= 0x100;
52 }else{
53 849 put_cabac_bit(c, 1);
54 849 c->dec.low -= 0x200;
55 }
56
57 6163 c->dec.range += c->dec.range;
58 6163 c->dec.low += c->dec.low;
59 }
60 10241 }
61
62 10240 static void put_cabac(CABACTestContext *c, uint8_t * const state, int bit)
63 {
64 10240 int RangeLPS = ff_h264_lps_range[2 * (c->dec.range & 0xC0) + *state];
65
66
2/2
✓ Branch 0 taken 7637 times.
✓ Branch 1 taken 2603 times.
10240 if(bit == ((*state)&1)){
67 7637 c->dec.range -= RangeLPS;
68 7637 *state = ff_h264_mlps_state[128 + *state];
69 }else{
70 2603 c->dec.low += c->dec.range - RangeLPS;
71 2603 c->dec.range = RangeLPS;
72 2603 *state= ff_h264_mlps_state[127 - *state];
73 }
74
75 10240 renorm_cabac_encoder(c);
76 10240 }
77
78 /**
79 * @param bit 0 -> write zero bit, !=0 write one bit
80 */
81 10240 static void put_cabac_bypass(CABACTestContext *c, int bit)
82 {
83 10240 c->dec.low += c->dec.low;
84
85
2/2
✓ Branch 0 taken 4761 times.
✓ Branch 1 taken 5479 times.
10240 if(bit){
86 4761 c->dec.low += c->dec.range;
87 }
88 //FIXME optimize
89
2/2
✓ Branch 0 taken 3869 times.
✓ Branch 1 taken 6371 times.
10240 if (c->dec.low < 0x200) {
90 3869 put_cabac_bit(c, 0);
91
2/2
✓ Branch 0 taken 5050 times.
✓ Branch 1 taken 1321 times.
6371 } else if (c->dec.low < 0x400) {
92 5050 c->outstanding_count++;
93 5050 c->dec.low -= 0x200;
94 }else{
95 1321 put_cabac_bit(c, 1);
96 1321 c->dec.low -= 0x400;
97 }
98 10240 }
99
100 /**
101 *
102 * @return the number of bytes written
103 */
104 1 static int put_cabac_terminate(CABACTestContext *c, int bit)
105 {
106 1 c->dec.range -= 2;
107
108
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(!bit){
109 renorm_cabac_encoder(c);
110 }else{
111 1 c->dec.low += c->dec.range;
112 1 c->dec.range = 2;
113
114 1 renorm_cabac_encoder(c);
115
116
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 av_assert0(c->dec.low <= 0x1FF);
117 1 put_cabac_bit(c, c->dec.low >> 9);
118 1 put_bits(&c->pb, 2, ((c->dec.low >> 7) & 3) | 1);
119
120 1 flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
121 }
122
123 1 return put_bytes_count(&c->pb, 1);
124 }
125
126 /**
127 * @param buf_size size of buf in bits
128 */
129 1 static void init_cabac_encoder(CABACTestContext *c, uint8_t *buf, int buf_size)
130 {
131 1 init_put_bits(&c->pb, buf, buf_size);
132
133 1 c->dec.low = 0;
134 1 c->dec.range = 0x1FE;
135 1 c->outstanding_count = 0;
136 1 c->pb.bit_left++; //avoids firstBitFlag
137 1 }
138
139 1 int main(void){
140 CABACTestContext c;
141 uint8_t b[9*SIZE];
142 uint8_t r[9*SIZE];
143 1 int i, ret = 0;
144 1 uint8_t state[10]= {0};
145 AVLFG prng;
146
147 1 av_lfg_init(&prng, 1);
148 1 init_cabac_encoder(&c, b, SIZE);
149
150
2/2
✓ Branch 0 taken 10240 times.
✓ Branch 1 taken 1 times.
10241 for(i=0; i<SIZE; i++){
151
2/2
✓ Branch 0 taken 5120 times.
✓ Branch 1 taken 5120 times.
10240 if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7;
152 5120 else r[i] = (i>>8)&1;
153 }
154
155
2/2
✓ Branch 0 taken 10240 times.
✓ Branch 1 taken 1 times.
10241 for(i=0; i<SIZE; i++){
156 10240 put_cabac_bypass(&c, r[i]&1);
157 }
158
159
2/2
✓ Branch 0 taken 10240 times.
✓ Branch 1 taken 1 times.
10241 for(i=0; i<SIZE; i++){
160 10240 put_cabac(&c, state, r[i]&1);
161 }
162
163 1 i= put_cabac_terminate(&c, 1);
164 1 b[i++] = av_lfg_get(&prng);
165 1 b[i ] = av_lfg_get(&prng);
166
167 1 ff_init_cabac_decoder(&c.dec, b, SIZE);
168
169 1 memset(state, 0, sizeof(state));
170
171
2/2
✓ Branch 0 taken 10240 times.
✓ Branch 1 taken 1 times.
10241 for(i=0; i<SIZE; i++){
172
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10240 times.
10240 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
2/2
✓ Branch 0 taken 10240 times.
✓ Branch 1 taken 1 times.
10241 for(i=0; i<SIZE; i++){
179
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 10240 times.
10240 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
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 if (!get_cabac_terminate(&c.dec)) {
185 av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
186 ret = 1;
187 }
188
189 1 return ret;
190 }
191