FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/proresenc_kostya.c
Date: 2026-09-28 23:39:34
Exec Total Coverage
Lines: 413 558 74.0%
Functions: 16 22 72.7%
Branches: 158 248 63.7%

Line Branch Exec Source
1 /*
2 * Apple ProRes encoder
3 *
4 * Copyright (c) 2011 Anatoliy Wasserman
5 * Copyright (c) 2012 Konstantin Shishkov
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
24 #include "libavutil/mem.h"
25 #include "libavutil/mem_internal.h"
26 #include "libavutil/opt.h"
27 #include "libavutil/pixdesc.h"
28 #include "avcodec.h"
29 #include "codec_internal.h"
30 #include "encode.h"
31 #include "fdctdsp.h"
32 #include "put_bits.h"
33 #include "profiles.h"
34 #include "bytestream.h"
35 #include "proresdata.h"
36 #include "proresenc_kostya_common.h"
37
38 #define TRELLIS_WIDTH 16
39 #define SCORE_LIMIT INT_MAX / 2
40
41 struct TrellisNode {
42 int prev_node;
43 int quant;
44 int bits;
45 int score;
46 };
47
48 typedef struct ProresThreadData {
49 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
50 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
51 int16_t custom_q[64];
52 int16_t custom_chroma_q[64];
53 struct TrellisNode *nodes;
54 } ProresThreadData;
55
56 66600 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
57 ptrdiff_t linesize, int x, int y, int w, int h,
58 int16_t *blocks, uint16_t *emu_buf,
59 int mbs_per_slice, int blocks_per_mb, int is_chroma)
60 {
61 const uint16_t *esrc;
62 66600 const int mb_width = 4 * blocks_per_mb;
63 ptrdiff_t elinesize;
64 int i, j, k;
65
66
2/2
✓ Branch 0 taken 359100 times.
✓ Branch 1 taken 66600 times.
425700 for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
67
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 359100 times.
359100 if (x >= w) {
68 ✗ memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
69 * sizeof(*blocks));
70 ✗ return;
71 }
72
4/4
✓ Branch 0 taken 358200 times.
✓ Branch 1 taken 900 times.
✓ Branch 2 taken 357600 times.
✓ Branch 3 taken 600 times.
359100 if (x + mb_width <= w && y + 16 <= h) {
73 357600 esrc = src;
74 357600 elinesize = linesize;
75 } else {
76 int bw, bh, pix;
77
78 1500 esrc = emu_buf;
79 1500 elinesize = 16 * sizeof(*emu_buf);
80
81 1500 bw = FFMIN(w - x, mb_width);
82 1500 bh = FFMIN(h - y, 16);
83
84
2/2
✓ Branch 0 taken 11400 times.
✓ Branch 1 taken 1500 times.
12900 for (j = 0; j < bh; j++) {
85 11400 memcpy(emu_buf + j * 16,
86 11400 (const uint8_t*)src + j * linesize,
87 bw * sizeof(*src));
88 11400 pix = emu_buf[j * 16 + bw - 1];
89
2/2
✓ Branch 0 taken 95200 times.
✓ Branch 1 taken 11400 times.
106600 for (k = bw; k < mb_width; k++)
90 95200 emu_buf[j * 16 + k] = pix;
91 }
92
2/2
✓ Branch 0 taken 12600 times.
✓ Branch 1 taken 1500 times.
14100 for (; j < 16; j++)
93 12600 memcpy(emu_buf + j * 16,
94 12600 emu_buf + (bh - 1) * 16,
95 mb_width * sizeof(*emu_buf));
96 }
97
2/2
✓ Branch 0 taken 119700 times.
✓ Branch 1 taken 239400 times.
359100 if (!is_chroma) {
98 119700 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
99 119700 blocks += 64;
100
1/2
✓ Branch 0 taken 119700 times.
✗ Branch 1 not taken.
119700 if (blocks_per_mb > 2) {
101 119700 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
102 119700 blocks += 64;
103 }
104 119700 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
105 119700 blocks += 64;
106
1/2
✓ Branch 0 taken 119700 times.
✗ Branch 1 not taken.
119700 if (blocks_per_mb > 2) {
107 119700 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
108 119700 blocks += 64;
109 }
110 } else {
111 239400 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
112 239400 blocks += 64;
113 239400 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
114 239400 blocks += 64;
115
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239400 times.
239400 if (blocks_per_mb > 2) {
116 ✗ ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
117 ✗ blocks += 64;
118 ✗ ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
119 ✗ blocks += 64;
120 }
121 }
122
123 359100 x += mb_width;
124 }
125 }
126
127 ✗ static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
128 ptrdiff_t linesize, int x, int y, int w, int h,
129 uint16_t *blocks, int mbs_per_slice, int abits)
130 {
131 ✗ const int slice_width = 16 * mbs_per_slice;
132 int i, j, copy_w, copy_h;
133
134 ✗ copy_w = FFMIN(w - x, slice_width);
135 ✗ copy_h = FFMIN(h - y, 16);
136 ✗ for (i = 0; i < copy_h; i++) {
137 ✗ memcpy(blocks, src, copy_w * sizeof(*src));
138 ✗ if (abits == 8)
139 ✗ for (j = 0; j < copy_w; j++)
140 ✗ blocks[j] >>= 2;
141 else
142 ✗ for (j = 0; j < copy_w; j++)
143 ✗ blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
144 ✗ for (j = copy_w; j < slice_width; j++)
145 ✗ blocks[j] = blocks[copy_w - 1];
146 ✗ blocks += slice_width;
147 ✗ src += linesize >> 1;
148 }
149 ✗ for (; i < 16; i++) {
150 ✗ memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
151 ✗ blocks += slice_width;
152 }
153 ✗ }
154
155 /**
156 * Write an unsigned rice/exp golomb codeword.
157 */
158 26885174 static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
159 {
160 unsigned int rice_order, exp_order, switch_bits, switch_val;
161 int exponent;
162
163 /* number of prefix bits to switch between Rice and expGolomb */
164 26885174 switch_bits = (codebook & 3) + 1;
165 26885174 rice_order = codebook >> 5; /* rice code order */
166 26885174 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
167
168 26885174 switch_val = switch_bits << rice_order;
169
170
2/2
✓ Branch 0 taken 8074309 times.
✓ Branch 1 taken 18810865 times.
26885174 if (val >= switch_val) {
171 8074309 val -= switch_val - (1 << exp_order);
172 8074309 exponent = av_log2(val);
173
174 8074309 put_bits(pb, exponent - exp_order + switch_bits, 0);
175 8074309 put_bits(pb, exponent + 1, val);
176 } else {
177 18810865 exponent = val >> rice_order;
178
179
2/2
✓ Branch 0 taken 4838901 times.
✓ Branch 1 taken 13971964 times.
18810865 if (exponent)
180 4838901 put_bits(pb, exponent, 0);
181 18810865 put_bits(pb, 1, 1);
182
2/2
✓ Branch 0 taken 1904515 times.
✓ Branch 1 taken 16906350 times.
18810865 if (rice_order)
183 1904515 put_sbits(pb, rice_order, val);
184 }
185 26885174 }
186
187 #define GET_SIGN(x) ((x) >> 31)
188 #define MAKE_CODE(x) (((x) * 2) ^ GET_SIGN(x))
189
190 33300 static void encode_dcs(PutBitContext *pb, int16_t *blocks,
191 int blocks_per_slice, int scale)
192 {
193 int i;
194 33300 int codebook = 5, code, dc, prev_dc, delta, sign, new_sign;
195
196 33300 prev_dc = (blocks[0] - 0x4000) / scale;
197 33300 encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
198 33300 sign = 0;
199 33300 blocks += 64;
200
201
2/2
✓ Branch 0 taken 445500 times.
✓ Branch 1 taken 33300 times.
478800 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
202 445500 dc = (blocks[0] - 0x4000) / scale;
203 445500 delta = dc - prev_dc;
204 445500 new_sign = GET_SIGN(delta);
205 445500 delta = (delta ^ sign) - sign;
206 445500 code = MAKE_CODE(delta);
207 445500 encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
208 445500 codebook = FFMIN(code, 6);
209 445500 sign = new_sign;
210 445500 prev_dc = dc;
211 }
212 33300 }
213
214 33300 static void encode_acs(PutBitContext *pb, int16_t *blocks,
215 int blocks_per_slice,
216 const uint8_t *scan, const int16_t *qmat)
217 {
218 int idx, i;
219 33300 int prev_run = 4;
220 33300 int prev_level = 2;
221 33300 int run = 0, level;
222 int max_coeffs, abs_level;
223 33300 max_coeffs = blocks_per_slice << 6;
224
225
2/2
✓ Branch 0 taken 2097900 times.
✓ Branch 1 taken 33300 times.
2131200 for (i = 1; i < 64; i++) {
226
2/2
✓ Branch 0 taken 30164400 times.
✓ Branch 1 taken 2097900 times.
32262300 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
227 30164400 level = blocks[idx] / qmat[scan[i]];
228
2/2
✓ Branch 0 taken 13203187 times.
✓ Branch 1 taken 16961213 times.
30164400 if (level) {
229 13203187 abs_level = FFABS(level);
230 13203187 encode_vlc_codeword(pb, ff_prores_run_to_cb[prev_run], run);
231 13203187 encode_vlc_codeword(pb, ff_prores_level_to_cb[prev_level], abs_level - 1);
232 13203187 put_sbits(pb, 1, GET_SIGN(level));
233
234 13203187 prev_run = FFMIN(run, 15);
235 13203187 prev_level = FFMIN(abs_level, 9);
236 13203187 run = 0;
237 } else {
238 16961213 run++;
239 }
240 }
241 }
242 33300 }
243
244 33300 static void encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
245 const uint16_t *src, ptrdiff_t linesize,
246 int mbs_per_slice, int16_t *blocks,
247 int blocks_per_mb,
248 const int16_t *qmat)
249 {
250 33300 int blocks_per_slice = mbs_per_slice * blocks_per_mb;
251
252 33300 encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
253 33300 encode_acs(pb, blocks, blocks_per_slice, ctx->scantable, qmat);
254 33300 }
255
256 ✗ static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
257 {
258 ✗ const int dbits = (abits == 8) ? 4 : 7;
259 ✗ const int dsize = 1 << dbits - 1;
260 ✗ int diff = cur - prev;
261
262 ✗ diff = av_zero_extend(diff, abits);
263 ✗ if (diff >= (1 << abits) - dsize)
264 ✗ diff -= 1 << abits;
265 ✗ if (diff < -dsize || diff > dsize || !diff) {
266 ✗ put_bits(pb, 1, 1);
267 ✗ put_bits(pb, abits, diff);
268 } else {
269 ✗ put_bits(pb, 1, 0);
270 ✗ put_bits(pb, dbits - 1, FFABS(diff) - 1);
271 ✗ put_bits(pb, 1, diff < 0);
272 }
273 ✗ }
274
275 ✗ static void put_alpha_run(PutBitContext *pb, int run)
276 {
277 ✗ if (run) {
278 ✗ put_bits(pb, 1, 0);
279 ✗ if (run < 0x10)
280 ✗ put_bits(pb, 4, run);
281 else
282 ✗ put_bits(pb, 15, run);
283 } else {
284 ✗ put_bits(pb, 1, 1);
285 }
286 ✗ }
287
288 // todo alpha quantisation for high quants
289 ✗ static void encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
290 int mbs_per_slice, uint16_t *blocks,
291 int quant)
292 {
293 ✗ const int abits = ctx->alpha_bits;
294 ✗ const int mask = (1 << abits) - 1;
295 ✗ const int num_coeffs = mbs_per_slice * 256;
296 ✗ int prev = mask, cur;
297 ✗ int idx = 0;
298 ✗ int run = 0;
299
300 ✗ cur = blocks[idx++];
301 ✗ put_alpha_diff(pb, cur, prev, abits);
302 ✗ prev = cur;
303 do {
304 ✗ cur = blocks[idx++];
305 ✗ if (cur != prev) {
306 ✗ put_alpha_run (pb, run);
307 ✗ put_alpha_diff(pb, cur, prev, abits);
308 ✗ prev = cur;
309 ✗ run = 0;
310 } else {
311 ✗ run++;
312 }
313 ✗ } while (idx < num_coeffs);
314 ✗ put_alpha_run(pb, run);
315 ✗ }
316
317 11100 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
318 PutBitContext *pb,
319 int sizes[4], int x, int y, int quant,
320 int mbs_per_slice)
321 {
322 11100 ProresContext *ctx = avctx->priv_data;
323 int i, xp, yp;
324 11100 int total_size = 0;
325 const uint16_t *src;
326 int num_cblocks, pwidth, line_add, picture_height;
327 ptrdiff_t linesize;
328 int is_chroma;
329 uint16_t *qmat;
330 uint16_t *qmat_chroma;
331
332
1/2
✓ Branch 0 taken 11100 times.
✗ Branch 1 not taken.
11100 if (ctx->pictures_per_frame == 1)
333 11100 line_add = 0;
334 else
335 ✗ line_add = ctx->cur_picture_idx ^ !(pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
336
337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if ((y << 4) * ctx->pictures_per_frame + line_add >= avctx->height)
338 ✗ line_add = 0;
339 11100 picture_height = (avctx->height - line_add + ctx->pictures_per_frame - 1) / ctx->pictures_per_frame;
340
341
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if (ctx->force_quant) {
342 ✗ qmat = ctx->quants[0];
343 ✗ qmat_chroma = ctx->quants_chroma[0];
344
2/2
✓ Branch 0 taken 8353 times.
✓ Branch 1 taken 2747 times.
11100 } else if (quant < MAX_STORED_Q) {
345 8353 qmat = ctx->quants[quant];
346 8353 qmat_chroma = ctx->quants_chroma[quant];
347 } else {
348 2747 qmat = ctx->custom_q;
349 2747 qmat_chroma = ctx->custom_chroma_q;
350
2/2
✓ Branch 0 taken 175808 times.
✓ Branch 1 taken 2747 times.
178555 for (i = 0; i < 64; i++) {
351 175808 qmat[i] = ctx->quant_mat[i] * quant;
352 175808 qmat_chroma[i] = ctx->quant_chroma_mat[i] * quant;
353 }
354 }
355
356
2/2
✓ Branch 0 taken 33300 times.
✓ Branch 1 taken 11100 times.
44400 for (i = 0; i < ctx->num_planes; i++) {
357
4/4
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
✓ Branch 2 taken 11100 times.
✓ Branch 3 taken 11100 times.
33300 is_chroma = (i == 1 || i == 2);
358
3/4
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22200 times.
33300 if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
359 11100 xp = x << 4;
360 11100 yp = y << 4;
361 11100 num_cblocks = 4;
362 11100 pwidth = avctx->width;
363 } else {
364 22200 xp = x << 3;
365 22200 yp = y << 4;
366 22200 num_cblocks = 2;
367 22200 pwidth = avctx->width >> 1;
368 }
369
370 33300 linesize = pic->linesize[i] * ctx->pictures_per_frame;
371 33300 src = (const uint16_t*)(pic->data[i] + yp * linesize +
372 33300 line_add * pic->linesize[i]) + xp;
373
374
1/2
✓ Branch 0 taken 33300 times.
✗ Branch 1 not taken.
33300 if (i < 3) {
375 33300 get_slice_data(ctx, src, linesize, xp, yp,
376 pwidth, picture_height,
377 33300 ctx->blocks[0], ctx->emu_buf,
378 mbs_per_slice, num_cblocks, is_chroma);
379
2/2
✓ Branch 0 taken 11100 times.
✓ Branch 1 taken 22200 times.
33300 if (!is_chroma) {/* luma quant */
380 11100 encode_slice_plane(ctx, pb, src, linesize,
381 11100 mbs_per_slice, ctx->blocks[0],
382 num_cblocks, qmat);
383 } else { /* chroma plane */
384 22200 encode_slice_plane(ctx, pb, src, linesize,
385 22200 mbs_per_slice, ctx->blocks[0],
386 num_cblocks, qmat_chroma);
387 }
388 } else {
389 ✗ get_alpha_data(ctx, src, linesize, xp, yp,
390 pwidth, picture_height,
391 ✗ ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
392 ✗ encode_alpha_plane(ctx, pb, mbs_per_slice, ctx->blocks[0], quant);
393 }
394 33300 flush_put_bits(pb);
395 33300 sizes[i] = put_bytes_output(pb) - total_size;
396 33300 total_size = put_bytes_output(pb);
397 }
398 11100 return total_size;
399 }
400
401 390320122 static inline int estimate_vlc(unsigned codebook, int val)
402 {
403 unsigned int rice_order, exp_order, switch_bits, switch_val;
404 int exponent;
405
406 /* number of prefix bits to switch between Rice and expGolomb */
407 390320122 switch_bits = (codebook & 3) + 1;
408 390320122 rice_order = codebook >> 5; /* rice code order */
409 390320122 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
410
411 390320122 switch_val = switch_bits << rice_order;
412
413
2/2
✓ Branch 0 taken 135366530 times.
✓ Branch 1 taken 254953592 times.
390320122 if (val >= switch_val) {
414 135366530 val -= switch_val - (1 << exp_order);
415 135366530 exponent = av_log2(val);
416
417 135366530 return exponent * 2 - exp_order + switch_bits + 1;
418 } else {
419 254953592 return (val >> rice_order) + rice_order + 1;
420 }
421 }
422
423 379686 static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
424 int scale)
425 {
426 int i;
427 379686 int codebook = 5, code, dc, prev_dc, delta, sign, new_sign;
428 int bits;
429
430 379686 prev_dc = (blocks[0] - 0x4000) / scale;
431 379686 bits = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
432 379686 sign = 0;
433 379686 blocks += 64;
434
2/2
✓ Branch 0 taken 199846 times.
✓ Branch 1 taken 179840 times.
379686 *error += FFABS(blocks[0] - 0x4000) % scale;
435
436
2/2
✓ Branch 0 taken 5069986 times.
✓ Branch 1 taken 379686 times.
5449672 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
437 5069986 dc = (blocks[0] - 0x4000) / scale;
438
2/2
✓ Branch 0 taken 2618934 times.
✓ Branch 1 taken 2451052 times.
5069986 *error += FFABS(blocks[0] - 0x4000) % scale;
439 5069986 delta = dc - prev_dc;
440 5069986 new_sign = GET_SIGN(delta);
441 5069986 delta = (delta ^ sign) - sign;
442 5069986 code = MAKE_CODE(delta);
443 5069986 bits += estimate_vlc(ff_prores_dc_codebook[codebook], code);
444 5069986 codebook = FFMIN(code, 6);
445 5069986 sign = new_sign;
446 5069986 prev_dc = dc;
447 }
448
449 379686 return bits;
450 }
451
452 379686 static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
453 const uint8_t *scan, const int16_t *qmat)
454 {
455 int idx, i;
456 379686 int prev_run = 4;
457 379686 int prev_level = 2;
458 int run, level;
459 int max_coeffs, abs_level;
460 379686 int bits = 0;
461
462 379686 max_coeffs = blocks_per_slice << 6;
463 379686 run = 0;
464
465
2/2
✓ Branch 0 taken 23920218 times.
✓ Branch 1 taken 379686 times.
24299904 for (i = 1; i < 64; i++) {
466
2/2
✓ Branch 0 taken 343329336 times.
✓ Branch 1 taken 23920218 times.
367249554 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
467 343329336 level = blocks[idx] / qmat[scan[i]];
468 343329336 *error += FFABS(blocks[idx]) % qmat[scan[i]];
469
2/2
✓ Branch 0 taken 192435225 times.
✓ Branch 1 taken 150894111 times.
343329336 if (level) {
470 192435225 abs_level = FFABS(level);
471 192435225 bits += estimate_vlc(ff_prores_run_to_cb[prev_run], run);
472 192435225 bits += estimate_vlc(ff_prores_level_to_cb[prev_level],
473 192435225 abs_level - 1) + 1;
474 192435225 prev_run = FFMIN(run, 15);
475 192435225 prev_level = FFMIN(abs_level, 9);
476 192435225 run = 0;
477 } else {
478 150894111 run++;
479 }
480 }
481 }
482
483 379686 return bits;
484 }
485
486 379686 static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
487 const uint16_t *src, ptrdiff_t linesize,
488 int mbs_per_slice,
489 int blocks_per_mb,
490 const int16_t *qmat, ProresThreadData *td)
491 {
492 int blocks_per_slice;
493 int bits;
494
495 379686 blocks_per_slice = mbs_per_slice * blocks_per_mb;
496
497 379686 bits = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
498 379686 bits += estimate_acs(error, td->blocks[plane], blocks_per_slice, ctx->scantable, qmat);
499
500 379686 return FFALIGN(bits, 8);
501 }
502
503 ✗ static int est_alpha_diff(int cur, int prev, int abits)
504 {
505 ✗ const int dbits = (abits == 8) ? 4 : 7;
506 ✗ const int dsize = 1 << dbits - 1;
507 ✗ int diff = cur - prev;
508
509 ✗ diff = av_zero_extend(diff, abits);
510 ✗ if (diff >= (1 << abits) - dsize)
511 ✗ diff -= 1 << abits;
512 ✗ if (diff < -dsize || diff > dsize || !diff)
513 ✗ return abits + 1;
514 else
515 ✗ return dbits + 1;
516 }
517
518 ✗ static int estimate_alpha_plane(ProresContext *ctx,
519 const uint16_t *src, ptrdiff_t linesize,
520 int mbs_per_slice, int16_t *blocks)
521 {
522 ✗ const int abits = ctx->alpha_bits;
523 ✗ const int mask = (1 << abits) - 1;
524 ✗ const int num_coeffs = mbs_per_slice * 256;
525 ✗ int prev = mask, cur;
526 ✗ int idx = 0;
527 ✗ int run = 0;
528 int bits;
529
530 ✗ cur = blocks[idx++];
531 ✗ bits = est_alpha_diff(cur, prev, abits);
532 ✗ prev = cur;
533 do {
534 ✗ cur = blocks[idx++];
535 ✗ if (cur != prev) {
536 ✗ if (!run)
537 ✗ bits++;
538 ✗ else if (run < 0x10)
539 ✗ bits += 4;
540 else
541 ✗ bits += 15;
542 ✗ bits += est_alpha_diff(cur, prev, abits);
543 ✗ prev = cur;
544 ✗ run = 0;
545 } else {
546 ✗ run++;
547 }
548 ✗ } while (idx < num_coeffs);
549
550 ✗ if (run) {
551 ✗ if (run < 0x10)
552 ✗ bits += 4;
553 else
554 ✗ bits += 15;
555 }
556
557 ✗ return bits;
558 }
559
560 11100 static int find_slice_quant(AVCodecContext *avctx,
561 int trellis_node, int x, int y, int mbs_per_slice,
562 ProresThreadData *td)
563 {
564 11100 ProresContext *ctx = avctx->priv_data;
565 int i, q, pq, xp, yp;
566 const uint16_t *src;
567 int num_cblocks[MAX_PLANES], pwidth;
568 int is_chroma[MAX_PLANES];
569 11100 const int min_quant = ctx->profile_info->min_quant;
570 11100 const int max_quant = ctx->profile_info->max_quant;
571 int error, bits, bits_limit;
572 int mbs, prev, cur, new_score;
573 int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
574 int overquant;
575 uint16_t *qmat;
576 uint16_t *qmat_chroma;
577 int linesize[4], line_add, picture_height;
578 11100 int alpha_bits = 0;
579
580
1/2
✓ Branch 0 taken 11100 times.
✗ Branch 1 not taken.
11100 if (ctx->pictures_per_frame == 1)
581 11100 line_add = 0;
582 else
583 ✗ line_add = ctx->cur_picture_idx ^ !(ctx->pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
584
585
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if ((y << 4) * ctx->pictures_per_frame + line_add >= avctx->height)
586 ✗ line_add = 0;
587 11100 picture_height = (avctx->height - line_add + ctx->pictures_per_frame - 1) / ctx->pictures_per_frame;
588 11100 mbs = x + mbs_per_slice;
589
590
2/2
✓ Branch 0 taken 33300 times.
✓ Branch 1 taken 11100 times.
44400 for (i = 0; i < ctx->num_planes; i++) {
591
4/4
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
✓ Branch 2 taken 11100 times.
✓ Branch 3 taken 11100 times.
33300 is_chroma[i] = (i == 1 || i == 2);
592
3/4
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22200 times.
33300 if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
593 11100 xp = x << 4;
594 11100 yp = y << 4;
595 11100 num_cblocks[i] = 4;
596 11100 pwidth = avctx->width;
597 } else {
598 22200 xp = x << 3;
599 22200 yp = y << 4;
600 22200 num_cblocks[i] = 2;
601 22200 pwidth = avctx->width >> 1;
602 }
603
604 33300 linesize[i] = ctx->pic->linesize[i] * ctx->pictures_per_frame;
605 33300 src = (const uint16_t *)(ctx->pic->data[i] + yp * linesize[i] +
606 33300 line_add * ctx->pic->linesize[i]) + xp;
607
608
1/2
✓ Branch 0 taken 33300 times.
✗ Branch 1 not taken.
33300 if (i < 3) {
609 33300 get_slice_data(ctx, src, linesize[i], xp, yp,
610 pwidth, picture_height,
611 33300 td->blocks[i], td->emu_buf,
612 mbs_per_slice, num_cblocks[i], is_chroma[i]);
613 } else {
614 ✗ get_alpha_data(ctx, src, linesize[i], xp, yp,
615 pwidth, picture_height,
616 ✗ td->blocks[i], mbs_per_slice, ctx->alpha_bits);
617 }
618 }
619
620
2/2
✓ Branch 0 taken 77700 times.
✓ Branch 1 taken 11100 times.
88800 for (q = min_quant; q < max_quant + 2; q++) {
621 77700 td->nodes[trellis_node + q].prev_node = -1;
622 77700 td->nodes[trellis_node + q].quant = q;
623 }
624
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if (ctx->alpha_bits)
626 ✗ alpha_bits = estimate_alpha_plane(ctx, src, linesize[3],
627 ✗ mbs_per_slice, td->blocks[3]);
628 // todo: maybe perform coarser quantising to fit into frame size when needed
629
2/2
✓ Branch 0 taken 66600 times.
✓ Branch 1 taken 11100 times.
77700 for (q = min_quant; q <= max_quant; q++) {
630 66600 bits = alpha_bits;
631 66600 error = 0;
632 133200 bits += estimate_slice_plane(ctx, &error, 0,
633 66600 src, linesize[0],
634 mbs_per_slice,
635 num_cblocks[0],
636 66600 ctx->quants[q], td); /* estimate luma plane */
637
2/2
✓ Branch 0 taken 133200 times.
✓ Branch 1 taken 66600 times.
199800 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
638 133200 bits += estimate_slice_plane(ctx, &error, i,
639 133200 src, linesize[i],
640 mbs_per_slice,
641 num_cblocks[i],
642 133200 ctx->quants_chroma[q], td);
643 }
644
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66600 times.
66600 if (bits > 65000 * 8)
645 ✗ error = SCORE_LIMIT;
646
647 66600 slice_bits[q] = bits;
648 66600 slice_score[q] = error;
649 }
650
2/2
✓ Branch 0 taken 3643 times.
✓ Branch 1 taken 7457 times.
11100 if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
651 3643 slice_bits[max_quant + 1] = slice_bits[max_quant];
652 3643 slice_score[max_quant + 1] = slice_score[max_quant] + 1;
653 3643 overquant = max_quant;
654 } else {
655
1/2
✓ Branch 0 taken 59962 times.
✗ Branch 1 not taken.
59962 for (q = max_quant + 1; q < 128; q++) {
656 59962 bits = alpha_bits;
657 59962 error = 0;
658
2/2
✓ Branch 0 taken 44939 times.
✓ Branch 1 taken 15023 times.
59962 if (q < MAX_STORED_Q) {
659 44939 qmat = ctx->quants[q];
660 44939 qmat_chroma = ctx->quants_chroma[q];
661 } else {
662 15023 qmat = td->custom_q;
663 15023 qmat_chroma = td->custom_chroma_q;
664
2/2
✓ Branch 0 taken 961472 times.
✓ Branch 1 taken 15023 times.
976495 for (i = 0; i < 64; i++) {
665 961472 qmat[i] = ctx->quant_mat[i] * q;
666 961472 qmat_chroma[i] = ctx->quant_chroma_mat[i] * q;
667 }
668 }
669 119924 bits += estimate_slice_plane(ctx, &error, 0,
670 59962 src, linesize[0],
671 mbs_per_slice,
672 num_cblocks[0],
673 qmat, td);/* estimate luma plane */
674
2/2
✓ Branch 0 taken 119924 times.
✓ Branch 1 taken 59962 times.
179886 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
675 119924 bits += estimate_slice_plane(ctx, &error, i,
676 119924 src, linesize[i],
677 mbs_per_slice,
678 num_cblocks[i],
679 qmat_chroma, td);
680 }
681
2/2
✓ Branch 0 taken 7457 times.
✓ Branch 1 taken 52505 times.
59962 if (bits <= ctx->bits_per_mb * mbs_per_slice)
682 7457 break;
683 }
684
685 7457 slice_bits[max_quant + 1] = bits;
686 7457 slice_score[max_quant + 1] = error;
687 7457 overquant = q;
688 }
689 11100 td->nodes[trellis_node + max_quant + 1].quant = overquant;
690
691 11100 bits_limit = mbs * ctx->bits_per_mb;
692
2/2
✓ Branch 0 taken 77700 times.
✓ Branch 1 taken 11100 times.
88800 for (pq = min_quant; pq < max_quant + 2; pq++) {
693 77700 prev = trellis_node - TRELLIS_WIDTH + pq;
694
695
2/2
✓ Branch 0 taken 543900 times.
✓ Branch 1 taken 77700 times.
621600 for (q = min_quant; q < max_quant + 2; q++) {
696 543900 cur = trellis_node + q;
697 543900 bits = td->nodes[prev].bits + slice_bits[q];
698 543900 error = slice_score[q];
699
2/2
✓ Branch 0 taken 438632 times.
✓ Branch 1 taken 105268 times.
543900 if (bits > bits_limit)
700 438632 error = SCORE_LIMIT;
701
702
4/4
✓ Branch 0 taken 268352 times.
✓ Branch 1 taken 275548 times.
✓ Branch 2 taken 98480 times.
✓ Branch 3 taken 169872 times.
543900 if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
703 98480 new_score = td->nodes[prev].score + error;
704 else
705 445420 new_score = SCORE_LIMIT;
706
2/2
✓ Branch 0 taken 466200 times.
✓ Branch 1 taken 77700 times.
543900 if (td->nodes[cur].prev_node == -1 ||
707
2/2
✓ Branch 0 taken 427864 times.
✓ Branch 1 taken 38336 times.
466200 td->nodes[cur].score >= new_score) {
708
709 505564 td->nodes[cur].bits = bits;
710 505564 td->nodes[cur].score = new_score;
711 505564 td->nodes[cur].prev_node = prev;
712 }
713 }
714 }
715
716 11100 error = td->nodes[trellis_node + min_quant].score;
717 11100 pq = trellis_node + min_quant;
718
2/2
✓ Branch 0 taken 66600 times.
✓ Branch 1 taken 11100 times.
77700 for (q = min_quant + 1; q < max_quant + 2; q++) {
719
2/2
✓ Branch 0 taken 52033 times.
✓ Branch 1 taken 14567 times.
66600 if (td->nodes[trellis_node + q].score <= error) {
720 52033 error = td->nodes[trellis_node + q].score;
721 52033 pq = trellis_node + q;
722 }
723 }
724
725 11100 return pq;
726 }
727
728 2850 static int find_quant_thread(AVCodecContext *avctx, void *arg,
729 int jobnr, int threadnr)
730 {
731 2850 ProresContext *ctx = avctx->priv_data;
732 2850 ProresThreadData *td = ctx->tdata + threadnr;
733 2850 int mbs_per_slice = ctx->mbs_per_slice;
734 2850 int x, y = jobnr, mb, q = 0;
735
736
2/2
✓ Branch 0 taken 11100 times.
✓ Branch 1 taken 2850 times.
13950 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
737
2/2
✓ Branch 0 taken 5850 times.
✓ Branch 1 taken 11100 times.
16950 while (ctx->mb_width - x < mbs_per_slice)
738 5850 mbs_per_slice >>= 1;
739 11100 q = find_slice_quant(avctx,
740 11100 (mb + 1) * TRELLIS_WIDTH, x, y,
741 mbs_per_slice, td);
742 }
743
744
2/2
✓ Branch 0 taken 11100 times.
✓ Branch 1 taken 2850 times.
13950 for (x = ctx->slices_width - 1; x >= 0; x--) {
745 11100 ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
746 11100 q = td->nodes[q].prev_node;
747 }
748
749 2850 return 0;
750 }
751
752 200 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
753 const AVFrame *pic, int *got_packet)
754 {
755 200 ProresContext *ctx = avctx->priv_data;
756 uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
757 uint8_t *picture_size_pos;
758 PutBitContext pb;
759 200 int x, y, i, mb, q = 0;
760 200 int sizes[4] = { 0 };
761 200 int slice_hdr_size = 2 * ctx->num_planes;
762 int frame_size, picture_size, slice_size;
763 int pkt_size, ret;
764 200 int max_slice_size = (ctx->frame_size_upper_bound - 200) / (ctx->pictures_per_frame * ctx->slices_per_picture + 1);
765 uint8_t frame_flags;
766
767 200 ctx->pic = pic;
768 200 pkt_size = ctx->frame_size_upper_bound;
769
770
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 200 times.
200 if ((ret = ff_alloc_packet(avctx, pkt, pkt_size + FF_INPUT_BUFFER_MIN_SIZE)) < 0)
771 ✗ return ret;
772
773 200 orig_buf = pkt->data;
774
775 // frame atom
776 200 orig_buf += 4; // frame size
777 200 bytestream_put_be32 (&orig_buf, FRAME_ID); // frame container ID
778 200 buf = orig_buf;
779
780 // frame header
781 200 tmp = buf;
782 200 buf += 2; // frame header size will be stored here
783
2/4
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 200 times.
200 bytestream_put_be16 (&buf, ctx->chroma_factor != CFACTOR_Y422 || ctx->alpha_bits ? 1 : 0);
784 200 bytestream_put_buffer(&buf, ctx->vendor, 4);
785 200 bytestream_put_be16 (&buf, avctx->width);
786 200 bytestream_put_be16 (&buf, avctx->height);
787
788 200 frame_flags = ctx->chroma_factor << 6;
789
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
200 if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
790 ✗ frame_flags |= (pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 0x04 : 0x08;
791 200 bytestream_put_byte (&buf, frame_flags);
792
793 200 bytestream_put_byte (&buf, 0); // reserved
794 200 bytestream_put_byte (&buf, pic->color_primaries);
795 200 bytestream_put_byte (&buf, pic->color_trc);
796 200 bytestream_put_byte (&buf, pic->colorspace);
797 200 bytestream_put_byte (&buf, ctx->alpha_bits >> 3);
798 200 bytestream_put_byte (&buf, 0); // reserved
799
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
800 200 bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present
801 200 bytestream_put_buffer(&buf, ctx->quant_mat, 64); // luma quantisation matrix
802 200 bytestream_put_buffer(&buf, ctx->quant_chroma_mat, 64); // chroma quantisation matrix
803 } else {
804 ✗ bytestream_put_byte (&buf, 0x00); // matrix flags - default matrices are used
805 }
806 200 bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
807
808 200 for (ctx->cur_picture_idx = 0;
809
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 200 times.
400 ctx->cur_picture_idx < ctx->pictures_per_frame;
810 200 ctx->cur_picture_idx++) {
811 // picture header
812 200 picture_size_pos = buf + 1;
813 200 bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
814 200 buf += 4; // picture data size will be stored here
815 200 bytestream_put_be16 (&buf, ctx->slices_per_picture);
816 200 bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
817
818 // seek table - will be filled during slice encoding
819 200 slice_sizes = buf;
820 200 buf += ctx->slices_per_picture * 2;
821
822 // slices
823
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 if (!ctx->force_quant) {
824 200 ret = avctx->execute2(avctx, find_quant_thread, NULL, NULL,
825 ctx->mb_height);
826
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
200 if (ret)
827 ✗ return ret;
828 }
829
830
2/2
✓ Branch 0 taken 2850 times.
✓ Branch 1 taken 200 times.
3050 for (y = 0; y < ctx->mb_height; y++) {
831 2850 int mbs_per_slice = ctx->mbs_per_slice;
832
2/2
✓ Branch 0 taken 11100 times.
✓ Branch 1 taken 2850 times.
13950 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
833 22200 q = ctx->force_quant ? ctx->force_quant
834
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 : ctx->slice_q[mb + y * ctx->slices_width];
835
836
2/2
✓ Branch 0 taken 5850 times.
✓ Branch 1 taken 11100 times.
16950 while (ctx->mb_width - x < mbs_per_slice)
837 5850 mbs_per_slice >>= 1;
838
839 11100 bytestream_put_byte(&buf, slice_hdr_size << 3);
840 11100 slice_hdr = buf;
841 11100 buf += slice_hdr_size - 1;
842
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
843 ✗ uint8_t *start = pkt->data;
844 // Recompute new size according to max_slice_size
845 // and deduce delta
846 ✗ int delta = 200 + (ctx->pictures_per_frame *
847 ✗ ctx->slices_per_picture + 1) *
848 max_slice_size - pkt_size;
849
850 ✗ delta = FFMAX(delta, 2 * max_slice_size);
851 ✗ ctx->frame_size_upper_bound += delta;
852
853 ✗ if (!ctx->warn) {
854 ✗ avpriv_request_sample(avctx,
855 "Packet too small: is %i,"
856 " needs %i (slice: %i). "
857 "Correct allocation",
858 pkt_size, delta, max_slice_size);
859 ✗ ctx->warn = 1;
860 }
861
862 ✗ ret = av_grow_packet(pkt, delta);
863 ✗ if (ret < 0)
864 ✗ return ret;
865
866 ✗ pkt_size += delta;
867 ✗ orig_buf = pkt->data + (orig_buf - start);
868 ✗ buf = pkt->data + (buf - start);
869 ✗ picture_size_pos = pkt->data + (picture_size_pos - start);
870 ✗ slice_sizes = pkt->data + (slice_sizes - start);
871 ✗ slice_hdr = pkt->data + (slice_hdr - start);
872 ✗ tmp = pkt->data + (tmp - start);
873 }
874 11100 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)));
875 11100 ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
876 mbs_per_slice);
877
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if (ret < 0)
878 ✗ return ret;
879
880 11100 bytestream_put_byte(&slice_hdr, q);
881 11100 slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
882
2/2
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
33300 for (i = 0; i < ctx->num_planes - 1; i++) {
883 22200 bytestream_put_be16(&slice_hdr, sizes[i]);
884 22200 slice_size += sizes[i];
885 }
886 11100 bytestream_put_be16(&slice_sizes, slice_size);
887 11100 buf += slice_size - slice_hdr_size;
888
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 10884 times.
11100 if (max_slice_size < slice_size)
889 216 max_slice_size = slice_size;
890 }
891 }
892
893 200 picture_size = buf - (picture_size_pos - 1);
894 200 bytestream_put_be32(&picture_size_pos, picture_size);
895 }
896
897 200 orig_buf -= 8;
898 200 frame_size = buf - orig_buf;
899 200 bytestream_put_be32(&orig_buf, frame_size);
900
901 200 pkt->size = frame_size;
902 200 *got_packet = 1;
903
904 200 return 0;
905 }
906
907 4 static av_cold int encode_close(AVCodecContext *avctx)
908 {
909 4 ProresContext *ctx = avctx->priv_data;
910 int i;
911
912
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ctx->tdata) {
913
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (i = 0; i < avctx->thread_count; i++)
914 4 av_freep(&ctx->tdata[i].nodes);
915 }
916 4 av_freep(&ctx->tdata);
917 4 av_freep(&ctx->slice_q);
918
919 4 return 0;
920 }
921
922 957600 static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src,
923 ptrdiff_t linesize, int16_t *block)
924 {
925 int x, y;
926 957600 const uint16_t *tsrc = src;
927
928
2/2
✓ Branch 0 taken 7660800 times.
✓ Branch 1 taken 957600 times.
8618400 for (y = 0; y < 8; y++) {
929
2/2
✓ Branch 0 taken 61286400 times.
✓ Branch 1 taken 7660800 times.
68947200 for (x = 0; x < 8; x++)
930 61286400 block[y * 8 + x] = tsrc[x];
931 7660800 tsrc += linesize >> 1;
932 }
933 957600 fdsp->fdct(block);
934 957600 }
935
936 4 static av_cold int encode_init(AVCodecContext *avctx)
937 {
938 4 ProresContext *ctx = avctx->priv_data;
939 4 int err = 0, i, j, min_quant, max_quant;
940
941 4 err = ff_prores_kostya_encode_init(avctx, ctx, avctx->pix_fmt);
942
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (err < 0)
943 ✗ return err;
944
945 4 ctx->fdct = prores_fdct;
946 4 ff_fdctdsp_init(&ctx->fdsp, avctx);
947
948
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!ctx->force_quant) {
949 4 min_quant = ctx->profile_info->min_quant;
950 4 max_quant = ctx->profile_info->max_quant;
951
952 4 ctx->slice_q = av_malloc_array(ctx->slices_per_picture, sizeof(*ctx->slice_q));
953
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!ctx->slice_q)
954 ✗ return AVERROR(ENOMEM);
955
956 4 ctx->tdata = av_calloc(avctx->thread_count, sizeof(*ctx->tdata));
957
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!ctx->tdata)
958 ✗ return AVERROR(ENOMEM);
959
960
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (j = 0; j < avctx->thread_count; j++) {
961 4 ctx->tdata[j].nodes = av_malloc_array(ctx->slices_width + 1,
962 TRELLIS_WIDTH
963 * sizeof(*ctx->tdata->nodes));
964
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!ctx->tdata[j].nodes)
965 ✗ return AVERROR(ENOMEM);
966
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 4 times.
32 for (i = min_quant; i < max_quant + 2; i++) {
967 28 ctx->tdata[j].nodes[i].prev_node = -1;
968 28 ctx->tdata[j].nodes[i].bits = 0;
969 28 ctx->tdata[j].nodes[i].score = 0;
970 }
971 }
972 }
973
974 4 return 0;
975 }
976
977 #define OFFSET(x) offsetof(ProresContext, x)
978 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
979
980 static const AVOption options[] = {
981 { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
982 AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
983 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
984 { .i64 = PRORES_PROFILE_AUTO },
985 PRORES_PROFILE_AUTO, PRORES_PROFILE_4444XQ, VE, .unit = "profile" },
986 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_AUTO },
987 0, 0, VE, .unit = "profile" },
988 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
989 0, 0, VE, .unit = "profile" },
990 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
991 0, 0, VE, .unit = "profile" },
992 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
993 0, 0, VE, .unit = "profile" },
994 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
995 0, 0, VE, .unit = "profile" },
996 { "4444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
997 0, 0, VE, .unit = "profile" },
998 { "4444xq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444XQ },
999 0, 0, VE, .unit = "profile" },
1000 { "vendor", "vendor ID", OFFSET(vendor),
1001 AV_OPT_TYPE_STRING, { .str = "Lavc" }, 0, 0, VE },
1002 { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
1003 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
1004 { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
1005 { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, .unit = "quant_mat" },
1006 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
1007 0, 0, VE, .unit = "quant_mat" },
1008 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
1009 0, 0, VE, .unit = "quant_mat" },
1010 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
1011 0, 0, VE, .unit = "quant_mat" },
1012 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
1013 0, 0, VE, .unit = "quant_mat" },
1014 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
1015 0, 0, VE, .unit = "quant_mat" },
1016 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
1017 0, 0, VE, .unit = "quant_mat" },
1018 { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
1019 { .i64 = 16 }, 0, 16, VE },
1020 { NULL }
1021 };
1022
1023 static const AVClass proresenc_class = {
1024 .class_name = "ProRes encoder",
1025 .item_name = av_default_item_name,
1026 .option = options,
1027 .version = LIBAVUTIL_VERSION_INT,
1028 };
1029
1030 const FFCodec ff_prores_ks_encoder = {
1031 .p.name = "prores_ks",
1032 CODEC_LONG_NAME("Apple ProRes (iCodec Pro)"),
1033 .p.type = AVMEDIA_TYPE_VIDEO,
1034 .p.id = AV_CODEC_ID_PRORES,
1035 .priv_data_size = sizeof(ProresContext),
1036 .init = encode_init,
1037 .close = encode_close,
1038 FF_CODEC_ENCODE_CB(encode_frame),
1039 .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS |
1040 AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
1041 CODEC_PIXFMTS(AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10),
1042 .color_ranges = AVCOL_RANGE_MPEG,
1043 .p.priv_class = &proresenc_class,
1044 .p.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
1045 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1046 };
1047