GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/tests/cabac.c Lines: 73 80 91.2 %
Date: 2020-10-23 17:01:47 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
28
8410
static inline void put_cabac_bit(CABACContext *c, int b){
29
8410
    put_bits(&c->pb, 1, b);
30
16404
    for(;c->outstanding_count; c->outstanding_count--){
31
7994
        put_bits(&c->pb, 1, 1-b);
32
    }
33
8410
}
34
35
10241
static inline void renorm_cabac_encoder(CABACContext *c){
36
16404
    while(c->range < 0x100){
37
        //FIXME optimize
38
6163
        if(c->low<0x100){
39
2370
            put_cabac_bit(c, 0);
40
3793
        }else if(c->low<0x200){
41
2944
            c->outstanding_count++;
42
2944
            c->low -= 0x100;
43
        }else{
44
849
            put_cabac_bit(c, 1);
45
849
            c->low -= 0x200;
46
        }
47
48
6163
        c->range+= c->range;
49
6163
        c->low += c->low;
50
    }
51
10241
}
52
53
10240
static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
54
10240
    int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
55
56
10240
    if(bit == ((*state)&1)){
57
7637
        c->range -= RangeLPS;
58
7637
        *state    = ff_h264_mlps_state[128 + *state];
59
    }else{
60
2603
        c->low += c->range - RangeLPS;
61
2603
        c->range = RangeLPS;
62
2603
        *state= ff_h264_mlps_state[127 - *state];
63
    }
64
65
10240
    renorm_cabac_encoder(c);
66
10240
}
67
68
/**
69
 * @param bit 0 -> write zero bit, !=0 write one bit
70
 */
71
10240
static void put_cabac_bypass(CABACContext *c, int bit){
72
10240
    c->low += c->low;
73
74
10240
    if(bit){
75
4761
        c->low += c->range;
76
    }
77
//FIXME optimize
78
10240
    if(c->low<0x200){
79
3869
        put_cabac_bit(c, 0);
80
6371
    }else if(c->low<0x400){
81
5050
        c->outstanding_count++;
82
5050
        c->low -= 0x200;
83
    }else{
84
1321
        put_cabac_bit(c, 1);
85
1321
        c->low -= 0x400;
86
    }
87
10240
}
88
89
/**
90
 *
91
 * @return the number of bytes written
92
 */
93
1
static int put_cabac_terminate(CABACContext *c, int bit){
94
1
    c->range -= 2;
95
96
1
    if(!bit){
97
        renorm_cabac_encoder(c);
98
    }else{
99
1
        c->low += c->range;
100
1
        c->range= 2;
101
102
1
        renorm_cabac_encoder(c);
103
104
1
        av_assert0(c->low <= 0x1FF);
105
1
        put_cabac_bit(c, c->low>>9);
106
1
        put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
107
108
1
        flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
109
    }
110
111
1
    return (put_bits_count(&c->pb)+7)>>3;
112
}
113
114
1
int main(void){
115
    CABACContext c;
116
    uint8_t b[9*SIZE];
117
    uint8_t r[9*SIZE];
118
1
    int i, ret = 0;
119
1
    uint8_t state[10]= {0};
120
    AVLFG prng;
121
122
1
    av_lfg_init(&prng, 1);
123
1
    ff_init_cabac_encoder(&c, b, SIZE);
124
125
10241
    for(i=0; i<SIZE; i++){
126
10240
        if(2*i<SIZE) r[i] = av_lfg_get(&prng) % 7;
127
5120
        else         r[i] = (i>>8)&1;
128
    }
129
130
10241
    for(i=0; i<SIZE; i++){
131
10240
        put_cabac_bypass(&c, r[i]&1);
132
    }
133
134
10241
    for(i=0; i<SIZE; i++){
135
10240
        put_cabac(&c, state, r[i]&1);
136
    }
137
138
1
    i= put_cabac_terminate(&c, 1);
139
1
    b[i++] = av_lfg_get(&prng);
140
1
    b[i  ] = av_lfg_get(&prng);
141
142
1
    ff_init_cabac_decoder(&c, b, SIZE);
143
144
1
    memset(state, 0, sizeof(state));
145
146
10241
    for(i=0; i<SIZE; i++){
147
10240
        if( (r[i]&1) != get_cabac_bypass(&c) ) {
148
            av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i);
149
            ret = 1;
150
        }
151
    }
152
153
10241
    for(i=0; i<SIZE; i++){
154
10240
        if( (r[i]&1) != get_cabac_noinline(&c, state) ) {
155
            av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i);
156
            ret = 1;
157
        }
158
    }
159
1
    if(!get_cabac_terminate(&c)) {
160
        av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n");
161
        ret = 1;
162
    }
163
164
1
    return ret;
165
}