GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavcodec/dirac_vlc.c Lines: 128 129 99.2 %
Date: 2019-11-20 04:07:19 Branches: 69 70 98.6 %

Line Branch Exec Source
1
/*
2
 * Copyright (C) 2016 Open Broadcast Systems Ltd.
3
 * Author        2016 Rostislav Pehlivanov <rpehlivanov@obe.tv>
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#include "dirac_vlc.h"
23
24
#define LUT_SIZE   (1 << LUT_BITS)
25
#define RSIZE_BITS (CHAR_BIT*sizeof(residual))
26
27
#define CONVERT_TO_RESIDUE(a, b)                                               \
28
    (((residual)(a)) << (RSIZE_BITS - (b)))
29
30
#define INIT_RESIDUE(N)                                                        \
31
    residual N = 0;                                                            \
32
    av_unused int32_t N ## _bits  = 0
33
34
#define SET_RESIDUE(N, I, B)                                                   \
35
    N          = CONVERT_TO_RESIDUE(I, B);                                     \
36
    N ## _bits = B
37
38
#define APPEND_RESIDUE(N, M)                                                   \
39
    N          |= M >> (N ## _bits);                                           \
40
    N ## _bits  = (N ## _bits + (M ## _bits)) & 0x3F
41
42
85536
int ff_dirac_golomb_read_32bit(DiracGolombLUT *lut_ctx, const uint8_t *buf,
43
                               int bytes, uint8_t *_dst, int coeffs)
44
{
45
85536
    int i, b, c_idx = 0;
46
85536
    int32_t *dst = (int32_t *)_dst;
47
85536
    DiracGolombLUT *future[4], *l = &lut_ctx[2*LUT_SIZE + buf[0]];
48
85536
    INIT_RESIDUE(res);
49
50
38713622
    for (b = 1; b <= bytes; b++) {
51
38713228
        future[0] = &lut_ctx[buf[b]];
52
38713228
        future[1] = future[0] + 1*LUT_SIZE;
53
38713228
        future[2] = future[0] + 2*LUT_SIZE;
54
38713228
        future[3] = future[0] + 3*LUT_SIZE;
55
56
38713228
        if ((c_idx + 1) > coeffs)
57
85142
            return c_idx;
58
59
        /* res_bits is a hint for better branch prediction */
60

38628086
        if (res_bits && l->sign) {
61
23986889
            int32_t coeff = 1;
62
23986889
            APPEND_RESIDUE(res, l->preamble);
63
140278948
            for (i = 0; i < (res_bits >> 1) - 1; i++) {
64
116292059
                coeff <<= 1;
65
116292059
                coeff |= (res >> (RSIZE_BITS - 2*i - 2)) & 1;
66
            }
67
23986889
            dst[c_idx++] = l->sign * (coeff - 1);
68
23986889
            res_bits = res = 0;
69
        }
70
71
38628086
        memcpy(&dst[c_idx], l->ready, LUT_BITS*sizeof(int32_t));
72
38628086
        c_idx += l->ready_num;
73
74
38628086
        APPEND_RESIDUE(res, l->leftover);
75
76

38628086
        l = future[l->need_s ? 3 : !res_bits ? 2 : res_bits & 1];
77
    }
78
79
394
    return c_idx;
80
}
81
82
32076
int ff_dirac_golomb_read_16bit(DiracGolombLUT *lut_ctx, const uint8_t *buf,
83
                               int bytes, uint8_t *_dst, int coeffs)
84
{
85
32076
    int i, b, c_idx = 0;
86
32076
    int16_t *dst = (int16_t *)_dst;
87
32076
    DiracGolombLUT *future[4], *l = &lut_ctx[2*LUT_SIZE + buf[0]];
88
32076
    INIT_RESIDUE(res);
89
90
8864044
    for (b = 1; b <= bytes; b++) {
91
8863882
        future[0] = &lut_ctx[buf[b]];
92
8863882
        future[1] = future[0] + 1*LUT_SIZE;
93
8863882
        future[2] = future[0] + 2*LUT_SIZE;
94
8863882
        future[3] = future[0] + 3*LUT_SIZE;
95
96
8863882
        if ((c_idx + 1) > coeffs)
97
31914
            return c_idx;
98
99

8831968
        if (res_bits && l->sign) {
100
6215465
            int32_t coeff = 1;
101
6215465
            APPEND_RESIDUE(res, l->preamble);
102
26090422
            for (i = 0; i < (res_bits >> 1) - 1; i++) {
103
19874957
                coeff <<= 1;
104
19874957
                coeff |= (res >> (RSIZE_BITS - 2*i - 2)) & 1;
105
            }
106
6215465
            dst[c_idx++] = l->sign * (coeff - 1);
107
6215465
            res_bits = res = 0;
108
        }
109
110
79487712
        for (i = 0; i < LUT_BITS; i++)
111
70655744
            dst[c_idx + i] = l->ready[i];
112
8831968
        c_idx += l->ready_num;
113
114
8831968
        APPEND_RESIDUE(res, l->leftover);
115
116

8831968
        l = future[l->need_s ? 3 : !res_bits ? 2 : res_bits & 1];
117
    }
118
119
162
    return c_idx;
120
}
121
122
/* Searches for golomb codes in a residue */
123
68320
static inline void search_for_golomb(DiracGolombLUT *l, residual r, int bits)
124
{
125
68320
    int r_count = RSIZE_BITS - 1;
126
68320
    int bits_start, bits_tot = bits, need_sign = 0;
127
128
#define READ_BIT(N) (((N) >> (N ## _count--)) & 1)
129
130
101220
    while (1) {
131
169540
        int32_t coef = 1;
132
169540
        bits_start = (RSIZE_BITS - 1) - r_count;
133
134
        while (1) {
135
279440
            if (!bits--)
136
20020
                goto leftover;
137
259420
            if (READ_BIT(r))
138
129710
                break;
139
140
129710
            coef <<= 1;
141
142
129710
            if (!bits--)
143
19810
                goto leftover;
144
109900
            coef |= READ_BIT(r);
145
        }
146
147
129710
        l->ready[l->ready_num] = coef - 1;
148
129710
        if (l->ready[l->ready_num]) {
149
45500
            if (!bits--) {
150
9380
                need_sign = 1;
151
9380
                goto leftover;
152
            }
153
36120
            l->ready[l->ready_num] *= READ_BIT(r) ? -1 : +1;
154
        }
155
120330
        l->ready_num++;
156
157
120330
        if (!bits)
158
19110
            return;
159
    }
160
161
49210
    leftover:
162
49210
        l->leftover      = r << bits_start;
163
49210
        l->leftover_bits = bits_tot - bits_start;
164
49210
        l->need_s        = need_sign;
165
}
166
167
/* Parity LUTs - even and odd bit end positions */
168
140
static void generate_parity_lut(DiracGolombLUT *lut, int even)
169
{
170
    int idx;
171
35980
    for (idx = 0; idx < LUT_SIZE; idx++) {
172
35840
        DiracGolombLUT *l = &lut[idx];
173
35840
        int symbol_end_loc = -1;
174
        uint32_t code;
175
        int i;
176
177
35840
        INIT_RESIDUE(res);
178
35840
        SET_RESIDUE(res, idx, LUT_BITS);
179
180
119840
        for (i = 0; i < LUT_BITS; i++) {
181
117600
            const int cond = even ? (i & 1) : !(i & 1);
182

117600
            if (((res >> (RSIZE_BITS - i - 1)) & 1) && cond) {
183
33600
                symbol_end_loc = i + 2;
184
33600
                break;
185
            }
186
        }
187
188

35840
        if (symbol_end_loc < 0 || symbol_end_loc > LUT_BITS) {
189
3360
            l->preamble      = 0;
190
3360
            l->preamble_bits = 0;
191
3360
            l->leftover_bits = LUT_BITS;
192
3360
            l->leftover      = CONVERT_TO_RESIDUE(idx, l->leftover_bits);
193
3360
            if (even)
194
2240
                l->need_s    = idx & 1;
195
3360
            continue;
196
        }
197
198
        /* Gets bits 0 through to (symbol_end_loc - 1) inclusive */
199
32480
        code  = idx >> ((LUT_BITS - 1) - (symbol_end_loc - 1));
200
32480
        code &= ((1 << LUT_BITS) - 1) >> (LUT_BITS - symbol_end_loc);
201
32480
        l->preamble_bits = symbol_end_loc;
202
32480
        l->preamble      = CONVERT_TO_RESIDUE(code, l->preamble_bits);
203
32480
        l->sign = ((l->preamble >> (RSIZE_BITS - l->preamble_bits)) & 1) ? -1 : +1;
204
205
32480
        search_for_golomb(l, res << symbol_end_loc, LUT_BITS - symbol_end_loc);
206
    }
207
140
}
208
209
/* Reset (off == 0) and needs-one-more-bit (off == 1) LUTs */
210
140
static void generate_offset_lut(DiracGolombLUT *lut, int off)
211
{
212
    int idx;
213
35980
    for (idx = 0; idx < LUT_SIZE; idx++) {
214
35840
        DiracGolombLUT *l = &lut[idx];
215
216
35840
        INIT_RESIDUE(res);
217
35840
        SET_RESIDUE(res, idx, LUT_BITS);
218
219
35840
        l->preamble_bits = off;
220
35840
        if (off) {
221
17920
            l->preamble  = CONVERT_TO_RESIDUE(res >> (RSIZE_BITS - off), off);
222
17920
            l->sign      = ((l->preamble >> (RSIZE_BITS - l->preamble_bits)) & 1) ? -1 : +1;
223
        } else {
224
17920
            l->preamble  = 0;
225
17920
            l->sign = 1;
226
        }
227
228
35840
        search_for_golomb(l, res << off, LUT_BITS - off);
229
    }
230
140
}
231
232
70
av_cold int ff_dirac_golomb_reader_init(DiracGolombLUT **lut_ctx)
233
{
234
    DiracGolombLUT *lut;
235
236
70
    if (!(lut = av_calloc(4*LUT_SIZE, sizeof(DiracGolombLUT))))
237
        return AVERROR(ENOMEM);
238
239
70
    generate_parity_lut(&lut[0*LUT_SIZE], 0);
240
70
    generate_parity_lut(&lut[1*LUT_SIZE], 1);
241
70
    generate_offset_lut(&lut[2*LUT_SIZE], 0);
242
70
    generate_offset_lut(&lut[3*LUT_SIZE], 1);
243
244
70
    *lut_ctx = lut;
245
246
70
    return 0;
247
}
248
249
70
av_cold void ff_dirac_golomb_reader_end(DiracGolombLUT **lut_ctx)
250
{
251
70
    av_freep(lut_ctx);
252
70
}