FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/apv_entropy.c
Date: 2025-05-09 06:10:30
Exec Total Coverage
Lines: 85 94 90.4%
Functions: 3 4 75.0%
Branches: 32 38 84.2%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "apv.h"
20 #include "apv_decode.h"
21
22
23 2 void ff_apv_entropy_build_decode_lut(APVVLCLUT *decode_lut)
24 {
25 2 const int code_len = APV_VLC_LUT_BITS;
26 2 const int lut_size = APV_VLC_LUT_SIZE;
27
28
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
14 for (int k = 0; k <= 5; k++) {
29
2/2
✓ Branch 0 taken 6144 times.
✓ Branch 1 taken 12 times.
6156 for (unsigned int code = 0; code < lut_size; code++) {
30 6144 APVVLCLUTEntry *ent = &decode_lut->lut[k][code];
31 6144 unsigned int first_bit = code & (1 << code_len - 1);
32 6144 unsigned int remaining_bits = code ^ first_bit;
33
34
2/2
✓ Branch 0 taken 3072 times.
✓ Branch 1 taken 3072 times.
6144 if (first_bit) {
35 3072 ent->consume = 1 + k;
36 3072 ent->result = remaining_bits >> (code_len - k - 1);
37 3072 ent->more = 0;
38 } else {
39 3072 unsigned int second_bit = code & (1 << code_len - 2);
40 3072 remaining_bits ^= second_bit;
41
42
2/2
✓ Branch 0 taken 1536 times.
✓ Branch 1 taken 1536 times.
3072 if (second_bit) {
43 1536 unsigned int bits_left = code_len - 2;
44 1536 unsigned int first_set = bits_left - av_log2(remaining_bits);
45 1536 unsigned int last_bits = first_set - 1 + k;
46
47
2/2
✓ Branch 0 taken 1200 times.
✓ Branch 1 taken 336 times.
1536 if (first_set + last_bits <= bits_left) {
48 // Whole code fits here.
49 1200 ent->consume = 2 + first_set + last_bits;
50 1200 ent->result = ((2 << k) +
51 1200 (((1 << first_set - 1) - 1) << k) +
52 1200 ((code >> bits_left - first_set - last_bits) & (1 << last_bits) - 1));
53 1200 ent->more = 0;
54 } else {
55 // Need to read more, collapse to default.
56 336 ent->consume = 2;
57 336 ent->more = 1;
58 }
59 } else {
60 1536 ent->consume = 2 + k;
61 1536 ent->result = (1 << k) + (remaining_bits >> (code_len - k - 2));
62 1536 ent->more = 0;
63 }
64 }
65 }
66 }
67 2 }
68
69 av_always_inline
70 543447 static unsigned int apv_read_vlc(GetBitContext *gbc, int k_param,
71 const APVVLCLUT *lut)
72 {
73 unsigned int next_bits;
74 const APVVLCLUTEntry *ent;
75
76 543447 next_bits = show_bits(gbc, APV_VLC_LUT_BITS);
77 543447 ent = &lut->lut[k_param][next_bits];
78
79
2/2
✓ Branch 0 taken 7053 times.
✓ Branch 1 taken 536394 times.
543447 if (ent->more) {
80 unsigned int leading_zeroes;
81
82 7053 skip_bits(gbc, ent->consume);
83
84 7053 next_bits = show_bits(gbc, 16);
85 7053 leading_zeroes = 15 - av_log2(next_bits);
86
87
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7053 times.
7053 if (leading_zeroes == 0) {
88 // This can't happen mid-stream because the lookup would
89 // have resolved a leading one into a shorter code, but it
90 // can happen if we are hitting the end of the buffer.
91 // Return an invalid code to propagate as an error.
92 return APV_MAX_TRANS_COEFF + 1;
93 }
94
95 7053 skip_bits(gbc, leading_zeroes + 1);
96
97 7053 return (2 << k_param) +
98 7053 ((1 << leading_zeroes) - 1) * (1 << k_param) +
99 7053 get_bits(gbc, leading_zeroes + k_param);
100 } else {
101 536394 skip_bits(gbc, ent->consume);
102 536394 return ent->result;
103 }
104 }
105
106 unsigned int ff_apv_read_vlc(GetBitContext *gbc, int k_param,
107 const APVVLCLUT *lut)
108 {
109 return apv_read_vlc(gbc, k_param, lut);
110 }
111
112 9600 int ff_apv_entropy_decode_block(int16_t *coeff,
113 GetBitContext *gbc,
114 APVEntropyState *state)
115 {
116 9600 const APVVLCLUT *lut = state->decode_lut;
117 int k_param;
118
119 // DC coefficient.
120 {
121 int abs_dc_coeff_diff;
122 int sign_dc_coeff_diff;
123 int dc_coeff;
124
125 9600 k_param = av_clip(state->prev_dc_diff >> 1, 0, 5);
126 9600 abs_dc_coeff_diff = apv_read_vlc(gbc, k_param, lut);
127
128
2/2
✓ Branch 0 taken 8825 times.
✓ Branch 1 taken 775 times.
9600 if (abs_dc_coeff_diff > 0)
129 8825 sign_dc_coeff_diff = get_bits1(gbc);
130 else
131 775 sign_dc_coeff_diff = 0;
132
133
2/2
✓ Branch 0 taken 4496 times.
✓ Branch 1 taken 5104 times.
9600 if (sign_dc_coeff_diff)
134 4496 dc_coeff = state->prev_dc - abs_dc_coeff_diff;
135 else
136 5104 dc_coeff = state->prev_dc + abs_dc_coeff_diff;
137
138
2/4
✓ Branch 0 taken 9600 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9600 times.
9600 if (dc_coeff < APV_MIN_TRANS_COEFF ||
139 dc_coeff > APV_MAX_TRANS_COEFF) {
140 av_log(state->log_ctx, AV_LOG_ERROR,
141 "Out-of-range DC coefficient value: %d "
142 "(from prev_dc %d abs_dc_coeff_diff %d sign_dc_coeff_diff %d)\n",
143 dc_coeff, state->prev_dc, abs_dc_coeff_diff, sign_dc_coeff_diff);
144 return AVERROR_INVALIDDATA;
145 }
146
147 9600 coeff[0] = dc_coeff;
148
149 9600 state->prev_dc = dc_coeff;
150 9600 state->prev_dc_diff = abs_dc_coeff_diff;
151 }
152
153 // AC coefficients.
154 {
155 9600 int scan_pos = 1;
156 9600 int first_ac = 1;
157 9600 int prev_level = state->prev_1st_ac_level;
158 9600 int prev_run = 0;
159
160 do {
161 int coeff_zero_run;
162
163 270611 k_param = av_clip(prev_run >> 2, 0, 2);
164 270611 coeff_zero_run = apv_read_vlc(gbc, k_param, lut);
165
166
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 270611 times.
270611 if (coeff_zero_run > APV_BLK_COEFFS - scan_pos) {
167 av_log(state->log_ctx, AV_LOG_ERROR,
168 "Out-of-range zero-run value: %d (at scan pos %d)\n",
169 coeff_zero_run, scan_pos);
170 return AVERROR_INVALIDDATA;
171 }
172
173
2/2
✓ Branch 0 taken 341564 times.
✓ Branch 1 taken 270611 times.
612175 for (int i = 0; i < coeff_zero_run; i++) {
174 341564 coeff[ff_zigzag_direct[scan_pos]] = 0;
175 341564 ++scan_pos;
176 }
177 270611 prev_run = coeff_zero_run;
178
179
2/2
✓ Branch 0 taken 263236 times.
✓ Branch 1 taken 7375 times.
270611 if (scan_pos < APV_BLK_COEFFS) {
180 int abs_ac_coeff_minus1;
181 int sign_ac_coeff;
182 int level;
183
184 263236 k_param = av_clip(prev_level >> 2, 0, 4);
185 263236 abs_ac_coeff_minus1 = apv_read_vlc(gbc, k_param, lut);
186 263236 sign_ac_coeff = get_bits(gbc, 1);
187
188
2/2
✓ Branch 0 taken 131067 times.
✓ Branch 1 taken 132169 times.
263236 if (sign_ac_coeff)
189 131067 level = -abs_ac_coeff_minus1 - 1;
190 else
191 132169 level = abs_ac_coeff_minus1 + 1;
192
193
2/4
✓ Branch 0 taken 263236 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 263236 times.
263236 if (level < APV_MIN_TRANS_COEFF ||
194 level > APV_MAX_TRANS_COEFF) {
195 av_log(state->log_ctx, AV_LOG_ERROR,
196 "Out-of-range AC coefficient value: %d "
197 "(from prev_level %d abs_ac_coeff_minus1 %d sign_ac_coeff %d)\n",
198 level, prev_level, abs_ac_coeff_minus1, sign_ac_coeff);
199 }
200
201 263236 coeff[ff_zigzag_direct[scan_pos]] = level;
202
203 263236 prev_level = abs_ac_coeff_minus1 + 1;
204
2/2
✓ Branch 0 taken 8944 times.
✓ Branch 1 taken 254292 times.
263236 if (first_ac) {
205 8944 state->prev_1st_ac_level = prev_level;
206 8944 first_ac = 0;
207 }
208
209 263236 ++scan_pos;
210 }
211
212
2/2
✓ Branch 0 taken 261011 times.
✓ Branch 1 taken 9600 times.
270611 } while (scan_pos < APV_BLK_COEFFS);
213 }
214
215 9600 return 0;
216 }
217