GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/tests/cabac.c Lines: 80 87 92.0 %
Date: 2021-04-22 14:24:15 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.c"
22
23
#define SIZE 10240
24
25
#include "libavutil/lfg.h"
26
#include "libavcodec/avcodec.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
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
16404
    while (c->dec.range < 0x100) {
46
        //FIXME optimize
47
6163
        if (c->dec.low < 0x100) {
48
2370
            put_cabac_bit(c, 0);
49
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
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
10240
    if(bit){
86
4761
        c->dec.low += c->dec.range;
87
    }
88
//FIXME optimize
89
10240
    if (c->dec.low < 0x200) {
90
3869
        put_cabac_bit(c, 0);
91
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
    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
        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
10241
    for(i=0; i<SIZE; i++){
151
10240
        if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7;
152
5120
        else         r[i] = (i>>8)&1;
153
    }
154
155
10241
    for(i=0; i<SIZE; i++){
156
10240
        put_cabac_bypass(&c, r[i]&1);
157
    }
158
159
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
10241
    for(i=0; i<SIZE; i++){
172
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
10241
    for(i=0; i<SIZE; i++){
179
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
    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
}