FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/ffv1enc_template.c
Date: 2024-11-20 23:03:26
Exec Total Coverage
Lines: 100 121 82.6%
Functions: 2 2 100.0%
Branches: 33 40 82.5%

Line Branch Exec Source
1 /*
2 * FFV1 encoder template
3 *
4 * Copyright (c) 2003-2016 Michael Niedermayer <michaelni@gmx.at>
5 *
6 * This file is part of FFmpeg.
7 *
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include "ffv1_template.c"
24
25 static av_always_inline int
26 5426400 RENAME(encode_line)(FFV1Context *f, FFV1SliceContext *sc,
27 void *logctx,
28 int w, TYPE *sample[3], int plane_index, int bits,
29 int ac, int pass1)
30 {
31 5426400 PlaneContext *const p = &sc->plane[plane_index];
32 5426400 RangeCoder *const c = &sc->c;
33 int x;
34 5426400 int run_index = sc->run_index;
35 5426400 int run_count = 0;
36 5426400 int run_mode = 0;
37
38
2/2
✓ Branch 0 taken 1728200 times.
✓ Branch 1 taken 985000 times.
5426400 if (ac != AC_GOLOMB_RICE) {
39
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1728200 times.
3456400 if (c->bytestream_end - c->bytestream < w * 35) {
40 av_log(logctx, AV_LOG_ERROR, "encoded frame too large\n");
41 return AVERROR_INVALIDDATA;
42 }
43 } else {
44
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 985000 times.
1970000 if (put_bytes_left(&sc->pb, 0) < w * 4) {
45 av_log(logctx, AV_LOG_ERROR, "encoded frame too large\n");
46 return AVERROR_INVALIDDATA;
47 }
48 }
49
50
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2713200 times.
5426400 if (sc->slice_coding_mode == 1) {
51 for (x = 0; x < w; x++) {
52 int i;
53 int v = sample[0][x];
54 for (i = bits-1; i>=0; i--) {
55 uint8_t state = 128;
56 put_rac(c, &state, (v>>i) & 1);
57 }
58 }
59 return 0;
60 }
61
62
2/2
✓ Branch 0 taken 406342900 times.
✓ Branch 1 taken 2713200 times.
818112200 for (x = 0; x < w; x++) {
63 int diff, context;
64
65 812685800 context = RENAME(get_context)(f->quant_tables[p->quant_table_index],
66 812685800 sample[0] + x, sample[1] + x, sample[2] + x);
67 812685800 diff = sample[0][x] - RENAME(predict)(sample[0] + x, sample[1] + x);
68
69
2/2
✓ Branch 0 taken 184035764 times.
✓ Branch 1 taken 222307136 times.
812685800 if (context < 0) {
70 368071528 context = -context;
71 368071528 diff = -diff;
72 }
73
74 812685800 diff = fold(diff, bits);
75
76
2/2
✓ Branch 0 taken 238196200 times.
✓ Branch 1 taken 168146700 times.
812685800 if (ac != AC_GOLOMB_RICE) {
77
2/2
✓ Branch 0 taken 53431600 times.
✓ Branch 1 taken 184764600 times.
476392400 if (pass1) {
78 106863200 put_symbol_inline(c, p->state[context], diff, 1, sc->rc_stat,
79 106863200 sc->rc_stat2[p->quant_table_index][context]);
80 } else {
81 369529200 put_symbol_inline(c, p->state[context], diff, 1, NULL, NULL);
82 }
83 } else {
84
2/2
✓ Branch 0 taken 3890578 times.
✓ Branch 1 taken 164256122 times.
336293400 if (context == 0)
85 7781156 run_mode = 1;
86
87
2/2
✓ Branch 0 taken 6062299 times.
✓ Branch 1 taken 162084401 times.
336293400 if (run_mode) {
88
2/2
✓ Branch 0 taken 1575440 times.
✓ Branch 1 taken 4486859 times.
12124598 if (diff) {
89
2/2
✓ Branch 0 taken 1412264 times.
✓ Branch 1 taken 1575440 times.
5975408 while (run_count >= 1 << ff_log2_run[run_index]) {
90 2824528 run_count -= 1 << ff_log2_run[run_index];
91 2824528 run_index++;
92 2824528 put_bits(&sc->pb, 1, 1);
93 }
94
95 3150880 put_bits(&sc->pb, 1 + ff_log2_run[run_index], run_count);
96
2/2
✓ Branch 0 taken 1439695 times.
✓ Branch 1 taken 135745 times.
3150880 if (run_index)
97 2879390 run_index--;
98 3150880 run_count = 0;
99 3150880 run_mode = 0;
100
2/2
✓ Branch 0 taken 740448 times.
✓ Branch 1 taken 834992 times.
3150880 if (diff > 0)
101 1480896 diff--;
102 } else {
103 8973718 run_count++;
104 }
105 }
106
107 ff_dlog(logctx, "count:%d index:%d, mode:%d, x:%d pos:%d\n",
108 run_count, run_index, run_mode, x,
109 (int)put_bits_count(&sc->pb));
110
111
2/2
✓ Branch 0 taken 163659841 times.
✓ Branch 1 taken 4486859 times.
336293400 if (run_mode == 0)
112 327319682 put_vlc_symbol(&sc->pb, &p->vlc_state[context], diff, bits);
113 }
114 }
115
2/2
✓ Branch 0 taken 57502 times.
✓ Branch 1 taken 2655698 times.
5426400 if (run_mode) {
116
2/2
✓ Branch 0 taken 43437 times.
✓ Branch 1 taken 57502 times.
201878 while (run_count >= 1 << ff_log2_run[run_index]) {
117 86874 run_count -= 1 << ff_log2_run[run_index];
118 86874 run_index++;
119 86874 put_bits(&sc->pb, 1, 1);
120 }
121
122
2/2
✓ Branch 0 taken 37708 times.
✓ Branch 1 taken 19794 times.
115004 if (run_count)
123 75416 put_bits(&sc->pb, 1, 1);
124 }
125 5426400 sc->run_index = run_index;
126
127 5426400 return 0;
128 }
129
130 1600 static int RENAME(encode_rgb_frame)(FFV1Context *f, FFV1SliceContext *sc,
131 const uint8_t *src[4],
132 int w, int h, const int stride[4])
133 {
134 int x, y, p, i;
135 1600 const int ring_size = f->context_model ? 3 : 2;
136 TYPE *sample[4][3];
137 1600 const int ac = f->ac;
138 1600 const int pass1 = !!(f->avctx->flags & AV_CODEC_FLAG_PASS1);
139 1600 int lbd = f->bits_per_raw_sample <= 8;
140 1600 int packed = !src[1];
141 1600 int bits = f->bits_per_raw_sample > 0 ? f->bits_per_raw_sample : 8;
142 1600 int offset = 1 << bits;
143 1600 int transparency = f->transparency;
144 1600 int packed_size = (3 + transparency)*2;
145
146 1600 sc->run_index = 0;
147
148 1600 memset(RENAME(sc->sample_buffer), 0, ring_size * MAX_PLANES *
149 1600 (w + 6) * sizeof(*RENAME(sc->sample_buffer)));
150
151 181200 for (y = 0; y < h; y++) {
152 538800 for (i = 0; i < ring_size; i++)
153 1796000 for (p = 0; p < MAX_PLANES; p++)
154 1436800 sample[p][i]= RENAME(sc->sample_buffer) + p*ring_size*(w+6) + ((h+i-y)%ring_size)*(w+6) + 3;
155
156 30708000 for (x = 0; x < w; x++) {
157 30528400 int b, g, r, av_uninit(a);
158 30528400 if (lbd) {
159 15264200 unsigned v = *((const uint32_t*)(src[0] + x*4 + stride[0]*y));
160 15264200 b = v & 0xFF;
161 15264200 g = (v >> 8) & 0xFF;
162 15264200 r = (v >> 16) & 0xFF;
163 15264200 a = v >> 24;
164 15264200 } else if (packed) {
165 15264200 const uint16_t *p = ((const uint16_t*)(src[0] + x*packed_size + stride[0]*y));
166 15264200 r = p[0];
167 15264200 g = p[1];
168 15264200 b = p[2];
169 15264200 if (transparency)
170 a = p[3];
171 } else if (sizeof(TYPE) == 4 || transparency) {
172 g = *((const uint16_t *)(src[0] + x*2 + stride[0]*y));
173 b = *((const uint16_t *)(src[1] + x*2 + stride[1]*y));
174 r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y));
175 if (transparency)
176 a = *((const uint16_t *)(src[3] + x*2 + stride[3]*y));
177 } else {
178 b = *((const uint16_t *)(src[0] + x*2 + stride[0]*y));
179 g = *((const uint16_t *)(src[1] + x*2 + stride[1]*y));
180 r = *((const uint16_t *)(src[2] + x*2 + stride[2]*y));
181 }
182
183 30528400 if (sc->slice_coding_mode != 1) {
184 30528400 b -= g;
185 30528400 r -= g;
186 30528400 g += (b * sc->slice_rct_by_coef + r * sc->slice_rct_ry_coef) >> 2;
187 30528400 b += offset;
188 30528400 r += offset;
189 }
190
191 30528400 sample[0][0][x] = g;
192 30528400 sample[1][0][x] = b;
193 30528400 sample[2][0][x] = r;
194 30528400 sample[3][0][x] = a;
195 }
196 718400 for (p = 0; p < 3 + transparency; p++) {
197 int ret;
198 538800 sample[p][0][-1] = sample[p][1][0 ];
199 538800 sample[p][1][ w] = sample[p][1][w-1];
200 538800 if (lbd && sc->slice_coding_mode == 0)
201 269400 ret = RENAME(encode_line)(f, sc, f->avctx, w, sample[p], (p + 1) / 2, 9, ac, pass1);
202 else
203 269400 ret = RENAME(encode_line)(f, sc, f->avctx, w, sample[p], (p + 1) / 2,
204 269400 bits + (sc->slice_coding_mode != 1), ac, pass1);
205 538800 if (ret < 0)
206 return ret;
207 }
208 }
209 1600 return 0;
210 }
211
212