FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/proresenc_kostya.c
Date: 2026-05-02 03:33:10
Exec Total Coverage
Lines: 411 556 73.9%
Functions: 16 22 72.7%
Branches: 156 244 63.9%

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;
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 (ctx->force_quant) {
338 qmat = ctx->quants[0];
339 qmat_chroma = ctx->quants_chroma[0];
340
2/2
✓ Branch 0 taken 8353 times.
✓ Branch 1 taken 2747 times.
11100 } else if (quant < MAX_STORED_Q) {
341 8353 qmat = ctx->quants[quant];
342 8353 qmat_chroma = ctx->quants_chroma[quant];
343 } else {
344 2747 qmat = ctx->custom_q;
345 2747 qmat_chroma = ctx->custom_chroma_q;
346
2/2
✓ Branch 0 taken 175808 times.
✓ Branch 1 taken 2747 times.
178555 for (i = 0; i < 64; i++) {
347 175808 qmat[i] = ctx->quant_mat[i] * quant;
348 175808 qmat_chroma[i] = ctx->quant_chroma_mat[i] * quant;
349 }
350 }
351
352
2/2
✓ Branch 0 taken 33300 times.
✓ Branch 1 taken 11100 times.
44400 for (i = 0; i < ctx->num_planes; i++) {
353
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);
354
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) {
355 11100 xp = x << 4;
356 11100 yp = y << 4;
357 11100 num_cblocks = 4;
358 11100 pwidth = avctx->width;
359 } else {
360 22200 xp = x << 3;
361 22200 yp = y << 4;
362 22200 num_cblocks = 2;
363 22200 pwidth = avctx->width >> 1;
364 }
365
366 33300 linesize = pic->linesize[i] * ctx->pictures_per_frame;
367 33300 src = (const uint16_t*)(pic->data[i] + yp * linesize +
368 33300 line_add * pic->linesize[i]) + xp;
369
370
1/2
✓ Branch 0 taken 33300 times.
✗ Branch 1 not taken.
33300 if (i < 3) {
371 33300 get_slice_data(ctx, src, linesize, xp, yp,
372 33300 pwidth, avctx->height / ctx->pictures_per_frame,
373 33300 ctx->blocks[0], ctx->emu_buf,
374 mbs_per_slice, num_cblocks, is_chroma);
375
2/2
✓ Branch 0 taken 11100 times.
✓ Branch 1 taken 22200 times.
33300 if (!is_chroma) {/* luma quant */
376 11100 encode_slice_plane(ctx, pb, src, linesize,
377 11100 mbs_per_slice, ctx->blocks[0],
378 num_cblocks, qmat);
379 } else { /* chroma plane */
380 22200 encode_slice_plane(ctx, pb, src, linesize,
381 22200 mbs_per_slice, ctx->blocks[0],
382 num_cblocks, qmat_chroma);
383 }
384 } else {
385 get_alpha_data(ctx, src, linesize, xp, yp,
386 pwidth, avctx->height / ctx->pictures_per_frame,
387 ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
388 encode_alpha_plane(ctx, pb, mbs_per_slice, ctx->blocks[0], quant);
389 }
390 33300 flush_put_bits(pb);
391 33300 sizes[i] = put_bytes_output(pb) - total_size;
392 33300 total_size = put_bytes_output(pb);
393 }
394 11100 return total_size;
395 }
396
397 390320122 static inline int estimate_vlc(unsigned codebook, int val)
398 {
399 unsigned int rice_order, exp_order, switch_bits, switch_val;
400 int exponent;
401
402 /* number of prefix bits to switch between Rice and expGolomb */
403 390320122 switch_bits = (codebook & 3) + 1;
404 390320122 rice_order = codebook >> 5; /* rice code order */
405 390320122 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
406
407 390320122 switch_val = switch_bits << rice_order;
408
409
2/2
✓ Branch 0 taken 135366530 times.
✓ Branch 1 taken 254953592 times.
390320122 if (val >= switch_val) {
410 135366530 val -= switch_val - (1 << exp_order);
411 135366530 exponent = av_log2(val);
412
413 135366530 return exponent * 2 - exp_order + switch_bits + 1;
414 } else {
415 254953592 return (val >> rice_order) + rice_order + 1;
416 }
417 }
418
419 379686 static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
420 int scale)
421 {
422 int i;
423 379686 int codebook = 5, code, dc, prev_dc, delta, sign, new_sign;
424 int bits;
425
426 379686 prev_dc = (blocks[0] - 0x4000) / scale;
427 379686 bits = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
428 379686 sign = 0;
429 379686 blocks += 64;
430
2/2
✓ Branch 0 taken 199846 times.
✓ Branch 1 taken 179840 times.
379686 *error += FFABS(blocks[0] - 0x4000) % scale;
431
432
2/2
✓ Branch 0 taken 5069986 times.
✓ Branch 1 taken 379686 times.
5449672 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
433 5069986 dc = (blocks[0] - 0x4000) / scale;
434
2/2
✓ Branch 0 taken 2618934 times.
✓ Branch 1 taken 2451052 times.
5069986 *error += FFABS(blocks[0] - 0x4000) % scale;
435 5069986 delta = dc - prev_dc;
436 5069986 new_sign = GET_SIGN(delta);
437 5069986 delta = (delta ^ sign) - sign;
438 5069986 code = MAKE_CODE(delta);
439 5069986 bits += estimate_vlc(ff_prores_dc_codebook[codebook], code);
440 5069986 codebook = FFMIN(code, 6);
441 5069986 sign = new_sign;
442 5069986 prev_dc = dc;
443 }
444
445 379686 return bits;
446 }
447
448 379686 static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
449 const uint8_t *scan, const int16_t *qmat)
450 {
451 int idx, i;
452 379686 int prev_run = 4;
453 379686 int prev_level = 2;
454 int run, level;
455 int max_coeffs, abs_level;
456 379686 int bits = 0;
457
458 379686 max_coeffs = blocks_per_slice << 6;
459 379686 run = 0;
460
461
2/2
✓ Branch 0 taken 23920218 times.
✓ Branch 1 taken 379686 times.
24299904 for (i = 1; i < 64; i++) {
462
2/2
✓ Branch 0 taken 343329336 times.
✓ Branch 1 taken 23920218 times.
367249554 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
463 343329336 level = blocks[idx] / qmat[scan[i]];
464 343329336 *error += FFABS(blocks[idx]) % qmat[scan[i]];
465
2/2
✓ Branch 0 taken 192435225 times.
✓ Branch 1 taken 150894111 times.
343329336 if (level) {
466 192435225 abs_level = FFABS(level);
467 192435225 bits += estimate_vlc(ff_prores_run_to_cb[prev_run], run);
468 192435225 bits += estimate_vlc(ff_prores_level_to_cb[prev_level],
469 192435225 abs_level - 1) + 1;
470 192435225 prev_run = FFMIN(run, 15);
471 192435225 prev_level = FFMIN(abs_level, 9);
472 192435225 run = 0;
473 } else {
474 150894111 run++;
475 }
476 }
477 }
478
479 379686 return bits;
480 }
481
482 379686 static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
483 const uint16_t *src, ptrdiff_t linesize,
484 int mbs_per_slice,
485 int blocks_per_mb,
486 const int16_t *qmat, ProresThreadData *td)
487 {
488 int blocks_per_slice;
489 int bits;
490
491 379686 blocks_per_slice = mbs_per_slice * blocks_per_mb;
492
493 379686 bits = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
494 379686 bits += estimate_acs(error, td->blocks[plane], blocks_per_slice, ctx->scantable, qmat);
495
496 379686 return FFALIGN(bits, 8);
497 }
498
499 static int est_alpha_diff(int cur, int prev, int abits)
500 {
501 const int dbits = (abits == 8) ? 4 : 7;
502 const int dsize = 1 << dbits - 1;
503 int diff = cur - prev;
504
505 diff = av_zero_extend(diff, abits);
506 if (diff >= (1 << abits) - dsize)
507 diff -= 1 << abits;
508 if (diff < -dsize || diff > dsize || !diff)
509 return abits + 1;
510 else
511 return dbits + 1;
512 }
513
514 static int estimate_alpha_plane(ProresContext *ctx,
515 const uint16_t *src, ptrdiff_t linesize,
516 int mbs_per_slice, int16_t *blocks)
517 {
518 const int abits = ctx->alpha_bits;
519 const int mask = (1 << abits) - 1;
520 const int num_coeffs = mbs_per_slice * 256;
521 int prev = mask, cur;
522 int idx = 0;
523 int run = 0;
524 int bits;
525
526 cur = blocks[idx++];
527 bits = est_alpha_diff(cur, prev, abits);
528 prev = cur;
529 do {
530 cur = blocks[idx++];
531 if (cur != prev) {
532 if (!run)
533 bits++;
534 else if (run < 0x10)
535 bits += 4;
536 else
537 bits += 15;
538 bits += est_alpha_diff(cur, prev, abits);
539 prev = cur;
540 run = 0;
541 } else {
542 run++;
543 }
544 } while (idx < num_coeffs);
545
546 if (run) {
547 if (run < 0x10)
548 bits += 4;
549 else
550 bits += 15;
551 }
552
553 return bits;
554 }
555
556 11100 static int find_slice_quant(AVCodecContext *avctx,
557 int trellis_node, int x, int y, int mbs_per_slice,
558 ProresThreadData *td)
559 {
560 11100 ProresContext *ctx = avctx->priv_data;
561 int i, q, pq, xp, yp;
562 const uint16_t *src;
563 int num_cblocks[MAX_PLANES], pwidth;
564 int is_chroma[MAX_PLANES];
565 11100 const int min_quant = ctx->profile_info->min_quant;
566 11100 const int max_quant = ctx->profile_info->max_quant;
567 int error, bits, bits_limit;
568 int mbs, prev, cur, new_score;
569 int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
570 int overquant;
571 uint16_t *qmat;
572 uint16_t *qmat_chroma;
573 int linesize[4], line_add;
574 11100 int alpha_bits = 0;
575
576
1/2
✓ Branch 0 taken 11100 times.
✗ Branch 1 not taken.
11100 if (ctx->pictures_per_frame == 1)
577 11100 line_add = 0;
578 else
579 line_add = ctx->cur_picture_idx ^ !(ctx->pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
580 11100 mbs = x + mbs_per_slice;
581
582
2/2
✓ Branch 0 taken 33300 times.
✓ Branch 1 taken 11100 times.
44400 for (i = 0; i < ctx->num_planes; i++) {
583
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);
584
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) {
585 11100 xp = x << 4;
586 11100 yp = y << 4;
587 11100 num_cblocks[i] = 4;
588 11100 pwidth = avctx->width;
589 } else {
590 22200 xp = x << 3;
591 22200 yp = y << 4;
592 22200 num_cblocks[i] = 2;
593 22200 pwidth = avctx->width >> 1;
594 }
595
596 33300 linesize[i] = ctx->pic->linesize[i] * ctx->pictures_per_frame;
597 33300 src = (const uint16_t *)(ctx->pic->data[i] + yp * linesize[i] +
598 33300 line_add * ctx->pic->linesize[i]) + xp;
599
600
1/2
✓ Branch 0 taken 33300 times.
✗ Branch 1 not taken.
33300 if (i < 3) {
601 33300 get_slice_data(ctx, src, linesize[i], xp, yp,
602 33300 pwidth, avctx->height / ctx->pictures_per_frame,
603 33300 td->blocks[i], td->emu_buf,
604 mbs_per_slice, num_cblocks[i], is_chroma[i]);
605 } else {
606 get_alpha_data(ctx, src, linesize[i], xp, yp,
607 pwidth, avctx->height / ctx->pictures_per_frame,
608 td->blocks[i], mbs_per_slice, ctx->alpha_bits);
609 }
610 }
611
612
2/2
✓ Branch 0 taken 77700 times.
✓ Branch 1 taken 11100 times.
88800 for (q = min_quant; q < max_quant + 2; q++) {
613 77700 td->nodes[trellis_node + q].prev_node = -1;
614 77700 td->nodes[trellis_node + q].quant = q;
615 }
616
617
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if (ctx->alpha_bits)
618 alpha_bits = estimate_alpha_plane(ctx, src, linesize[3],
619 mbs_per_slice, td->blocks[3]);
620 // todo: maybe perform coarser quantising to fit into frame size when needed
621
2/2
✓ Branch 0 taken 66600 times.
✓ Branch 1 taken 11100 times.
77700 for (q = min_quant; q <= max_quant; q++) {
622 66600 bits = alpha_bits;
623 66600 error = 0;
624 133200 bits += estimate_slice_plane(ctx, &error, 0,
625 66600 src, linesize[0],
626 mbs_per_slice,
627 num_cblocks[0],
628 66600 ctx->quants[q], td); /* estimate luma plane */
629
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 */
630 133200 bits += estimate_slice_plane(ctx, &error, i,
631 133200 src, linesize[i],
632 mbs_per_slice,
633 num_cblocks[i],
634 133200 ctx->quants_chroma[q], td);
635 }
636
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66600 times.
66600 if (bits > 65000 * 8)
637 error = SCORE_LIMIT;
638
639 66600 slice_bits[q] = bits;
640 66600 slice_score[q] = error;
641 }
642
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) {
643 3643 slice_bits[max_quant + 1] = slice_bits[max_quant];
644 3643 slice_score[max_quant + 1] = slice_score[max_quant] + 1;
645 3643 overquant = max_quant;
646 } else {
647
1/2
✓ Branch 0 taken 59962 times.
✗ Branch 1 not taken.
59962 for (q = max_quant + 1; q < 128; q++) {
648 59962 bits = alpha_bits;
649 59962 error = 0;
650
2/2
✓ Branch 0 taken 44939 times.
✓ Branch 1 taken 15023 times.
59962 if (q < MAX_STORED_Q) {
651 44939 qmat = ctx->quants[q];
652 44939 qmat_chroma = ctx->quants_chroma[q];
653 } else {
654 15023 qmat = td->custom_q;
655 15023 qmat_chroma = td->custom_chroma_q;
656
2/2
✓ Branch 0 taken 961472 times.
✓ Branch 1 taken 15023 times.
976495 for (i = 0; i < 64; i++) {
657 961472 qmat[i] = ctx->quant_mat[i] * q;
658 961472 qmat_chroma[i] = ctx->quant_chroma_mat[i] * q;
659 }
660 }
661 119924 bits += estimate_slice_plane(ctx, &error, 0,
662 59962 src, linesize[0],
663 mbs_per_slice,
664 num_cblocks[0],
665 qmat, td);/* estimate luma plane */
666
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 */
667 119924 bits += estimate_slice_plane(ctx, &error, i,
668 119924 src, linesize[i],
669 mbs_per_slice,
670 num_cblocks[i],
671 qmat_chroma, td);
672 }
673
2/2
✓ Branch 0 taken 7457 times.
✓ Branch 1 taken 52505 times.
59962 if (bits <= ctx->bits_per_mb * mbs_per_slice)
674 7457 break;
675 }
676
677 7457 slice_bits[max_quant + 1] = bits;
678 7457 slice_score[max_quant + 1] = error;
679 7457 overquant = q;
680 }
681 11100 td->nodes[trellis_node + max_quant + 1].quant = overquant;
682
683 11100 bits_limit = mbs * ctx->bits_per_mb;
684
2/2
✓ Branch 0 taken 77700 times.
✓ Branch 1 taken 11100 times.
88800 for (pq = min_quant; pq < max_quant + 2; pq++) {
685 77700 prev = trellis_node - TRELLIS_WIDTH + pq;
686
687
2/2
✓ Branch 0 taken 543900 times.
✓ Branch 1 taken 77700 times.
621600 for (q = min_quant; q < max_quant + 2; q++) {
688 543900 cur = trellis_node + q;
689 543900 bits = td->nodes[prev].bits + slice_bits[q];
690 543900 error = slice_score[q];
691
2/2
✓ Branch 0 taken 438632 times.
✓ Branch 1 taken 105268 times.
543900 if (bits > bits_limit)
692 438632 error = SCORE_LIMIT;
693
694
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)
695 98480 new_score = td->nodes[prev].score + error;
696 else
697 445420 new_score = SCORE_LIMIT;
698
2/2
✓ Branch 0 taken 466200 times.
✓ Branch 1 taken 77700 times.
543900 if (td->nodes[cur].prev_node == -1 ||
699
2/2
✓ Branch 0 taken 427864 times.
✓ Branch 1 taken 38336 times.
466200 td->nodes[cur].score >= new_score) {
700
701 505564 td->nodes[cur].bits = bits;
702 505564 td->nodes[cur].score = new_score;
703 505564 td->nodes[cur].prev_node = prev;
704 }
705 }
706 }
707
708 11100 error = td->nodes[trellis_node + min_quant].score;
709 11100 pq = trellis_node + min_quant;
710
2/2
✓ Branch 0 taken 66600 times.
✓ Branch 1 taken 11100 times.
77700 for (q = min_quant + 1; q < max_quant + 2; q++) {
711
2/2
✓ Branch 0 taken 52033 times.
✓ Branch 1 taken 14567 times.
66600 if (td->nodes[trellis_node + q].score <= error) {
712 52033 error = td->nodes[trellis_node + q].score;
713 52033 pq = trellis_node + q;
714 }
715 }
716
717 11100 return pq;
718 }
719
720 2850 static int find_quant_thread(AVCodecContext *avctx, void *arg,
721 int jobnr, int threadnr)
722 {
723 2850 ProresContext *ctx = avctx->priv_data;
724 2850 ProresThreadData *td = ctx->tdata + threadnr;
725 2850 int mbs_per_slice = ctx->mbs_per_slice;
726 2850 int x, y = jobnr, mb, q = 0;
727
728
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++) {
729
2/2
✓ Branch 0 taken 5850 times.
✓ Branch 1 taken 11100 times.
16950 while (ctx->mb_width - x < mbs_per_slice)
730 5850 mbs_per_slice >>= 1;
731 11100 q = find_slice_quant(avctx,
732 11100 (mb + 1) * TRELLIS_WIDTH, x, y,
733 mbs_per_slice, td);
734 }
735
736
2/2
✓ Branch 0 taken 11100 times.
✓ Branch 1 taken 2850 times.
13950 for (x = ctx->slices_width - 1; x >= 0; x--) {
737 11100 ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
738 11100 q = td->nodes[q].prev_node;
739 }
740
741 2850 return 0;
742 }
743
744 200 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
745 const AVFrame *pic, int *got_packet)
746 {
747 200 ProresContext *ctx = avctx->priv_data;
748 uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
749 uint8_t *picture_size_pos;
750 PutBitContext pb;
751 200 int x, y, i, mb, q = 0;
752 200 int sizes[4] = { 0 };
753 200 int slice_hdr_size = 2 * ctx->num_planes;
754 int frame_size, picture_size, slice_size;
755 int pkt_size, ret;
756 200 int max_slice_size = (ctx->frame_size_upper_bound - 200) / (ctx->pictures_per_frame * ctx->slices_per_picture + 1);
757 uint8_t frame_flags;
758
759 200 ctx->pic = pic;
760 200 pkt_size = ctx->frame_size_upper_bound;
761
762
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)
763 return ret;
764
765 200 orig_buf = pkt->data;
766
767 // frame atom
768 200 orig_buf += 4; // frame size
769 200 bytestream_put_be32 (&orig_buf, FRAME_ID); // frame container ID
770 200 buf = orig_buf;
771
772 // frame header
773 200 tmp = buf;
774 200 buf += 2; // frame header size will be stored here
775
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);
776 200 bytestream_put_buffer(&buf, ctx->vendor, 4);
777 200 bytestream_put_be16 (&buf, avctx->width);
778 200 bytestream_put_be16 (&buf, avctx->height);
779
780 200 frame_flags = ctx->chroma_factor << 6;
781
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
200 if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
782 frame_flags |= (pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 0x04 : 0x08;
783 200 bytestream_put_byte (&buf, frame_flags);
784
785 200 bytestream_put_byte (&buf, 0); // reserved
786 200 bytestream_put_byte (&buf, pic->color_primaries);
787 200 bytestream_put_byte (&buf, pic->color_trc);
788 200 bytestream_put_byte (&buf, pic->colorspace);
789 200 bytestream_put_byte (&buf, ctx->alpha_bits >> 3);
790 200 bytestream_put_byte (&buf, 0); // reserved
791
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
792 200 bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present
793 200 bytestream_put_buffer(&buf, ctx->quant_mat, 64); // luma quantisation matrix
794 200 bytestream_put_buffer(&buf, ctx->quant_chroma_mat, 64); // chroma quantisation matrix
795 } else {
796 bytestream_put_byte (&buf, 0x00); // matrix flags - default matrices are used
797 }
798 200 bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
799
800 200 for (ctx->cur_picture_idx = 0;
801
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 200 times.
400 ctx->cur_picture_idx < ctx->pictures_per_frame;
802 200 ctx->cur_picture_idx++) {
803 // picture header
804 200 picture_size_pos = buf + 1;
805 200 bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
806 200 buf += 4; // picture data size will be stored here
807 200 bytestream_put_be16 (&buf, ctx->slices_per_picture);
808 200 bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
809
810 // seek table - will be filled during slice encoding
811 200 slice_sizes = buf;
812 200 buf += ctx->slices_per_picture * 2;
813
814 // slices
815
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 if (!ctx->force_quant) {
816 200 ret = avctx->execute2(avctx, find_quant_thread, NULL, NULL,
817 ctx->mb_height);
818
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
200 if (ret)
819 return ret;
820 }
821
822
2/2
✓ Branch 0 taken 2850 times.
✓ Branch 1 taken 200 times.
3050 for (y = 0; y < ctx->mb_height; y++) {
823 2850 int mbs_per_slice = ctx->mbs_per_slice;
824
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++) {
825 22200 q = ctx->force_quant ? ctx->force_quant
826
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 : ctx->slice_q[mb + y * ctx->slices_width];
827
828
2/2
✓ Branch 0 taken 5850 times.
✓ Branch 1 taken 11100 times.
16950 while (ctx->mb_width - x < mbs_per_slice)
829 5850 mbs_per_slice >>= 1;
830
831 11100 bytestream_put_byte(&buf, slice_hdr_size << 3);
832 11100 slice_hdr = buf;
833 11100 buf += slice_hdr_size - 1;
834
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
835 uint8_t *start = pkt->data;
836 // Recompute new size according to max_slice_size
837 // and deduce delta
838 int delta = 200 + (ctx->pictures_per_frame *
839 ctx->slices_per_picture + 1) *
840 max_slice_size - pkt_size;
841
842 delta = FFMAX(delta, 2 * max_slice_size);
843 ctx->frame_size_upper_bound += delta;
844
845 if (!ctx->warn) {
846 avpriv_request_sample(avctx,
847 "Packet too small: is %i,"
848 " needs %i (slice: %i). "
849 "Correct allocation",
850 pkt_size, delta, max_slice_size);
851 ctx->warn = 1;
852 }
853
854 ret = av_grow_packet(pkt, delta);
855 if (ret < 0)
856 return ret;
857
858 pkt_size += delta;
859 orig_buf = pkt->data + (orig_buf - start);
860 buf = pkt->data + (buf - start);
861 picture_size_pos = pkt->data + (picture_size_pos - start);
862 slice_sizes = pkt->data + (slice_sizes - start);
863 slice_hdr = pkt->data + (slice_hdr - start);
864 tmp = pkt->data + (tmp - start);
865 }
866 11100 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)));
867 11100 ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
868 mbs_per_slice);
869
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if (ret < 0)
870 return ret;
871
872 11100 bytestream_put_byte(&slice_hdr, q);
873 11100 slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
874
2/2
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
33300 for (i = 0; i < ctx->num_planes - 1; i++) {
875 22200 bytestream_put_be16(&slice_hdr, sizes[i]);
876 22200 slice_size += sizes[i];
877 }
878 11100 bytestream_put_be16(&slice_sizes, slice_size);
879 11100 buf += slice_size - slice_hdr_size;
880
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 10884 times.
11100 if (max_slice_size < slice_size)
881 216 max_slice_size = slice_size;
882 }
883 }
884
885 200 picture_size = buf - (picture_size_pos - 1);
886 200 bytestream_put_be32(&picture_size_pos, picture_size);
887 }
888
889 200 orig_buf -= 8;
890 200 frame_size = buf - orig_buf;
891 200 bytestream_put_be32(&orig_buf, frame_size);
892
893 200 pkt->size = frame_size;
894 200 *got_packet = 1;
895
896 200 return 0;
897 }
898
899 4 static av_cold int encode_close(AVCodecContext *avctx)
900 {
901 4 ProresContext *ctx = avctx->priv_data;
902 int i;
903
904
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ctx->tdata) {
905
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (i = 0; i < avctx->thread_count; i++)
906 4 av_freep(&ctx->tdata[i].nodes);
907 }
908 4 av_freep(&ctx->tdata);
909 4 av_freep(&ctx->slice_q);
910
911 4 return 0;
912 }
913
914 957600 static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src,
915 ptrdiff_t linesize, int16_t *block)
916 {
917 int x, y;
918 957600 const uint16_t *tsrc = src;
919
920
2/2
✓ Branch 0 taken 7660800 times.
✓ Branch 1 taken 957600 times.
8618400 for (y = 0; y < 8; y++) {
921
2/2
✓ Branch 0 taken 61286400 times.
✓ Branch 1 taken 7660800 times.
68947200 for (x = 0; x < 8; x++)
922 61286400 block[y * 8 + x] = tsrc[x];
923 7660800 tsrc += linesize >> 1;
924 }
925 957600 fdsp->fdct(block);
926 957600 }
927
928 4 static av_cold int encode_init(AVCodecContext *avctx)
929 {
930 4 ProresContext *ctx = avctx->priv_data;
931 4 int err = 0, i, j, min_quant, max_quant;
932
933 4 err = ff_prores_kostya_encode_init(avctx, ctx, avctx->pix_fmt);
934
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (err < 0)
935 return err;
936
937 4 ctx->fdct = prores_fdct;
938 4 ff_fdctdsp_init(&ctx->fdsp, avctx);
939
940
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!ctx->force_quant) {
941 4 min_quant = ctx->profile_info->min_quant;
942 4 max_quant = ctx->profile_info->max_quant;
943
944 4 ctx->slice_q = av_malloc_array(ctx->slices_per_picture, sizeof(*ctx->slice_q));
945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!ctx->slice_q)
946 return AVERROR(ENOMEM);
947
948 4 ctx->tdata = av_calloc(avctx->thread_count, sizeof(*ctx->tdata));
949
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!ctx->tdata)
950 return AVERROR(ENOMEM);
951
952
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (j = 0; j < avctx->thread_count; j++) {
953 4 ctx->tdata[j].nodes = av_malloc_array(ctx->slices_width + 1,
954 TRELLIS_WIDTH
955 * sizeof(*ctx->tdata->nodes));
956
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!ctx->tdata[j].nodes)
957 return AVERROR(ENOMEM);
958
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 4 times.
32 for (i = min_quant; i < max_quant + 2; i++) {
959 28 ctx->tdata[j].nodes[i].prev_node = -1;
960 28 ctx->tdata[j].nodes[i].bits = 0;
961 28 ctx->tdata[j].nodes[i].score = 0;
962 }
963 }
964 }
965
966 4 return 0;
967 }
968
969 #define OFFSET(x) offsetof(ProresContext, x)
970 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
971
972 static const AVOption options[] = {
973 { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
974 AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
975 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
976 { .i64 = PRORES_PROFILE_AUTO },
977 PRORES_PROFILE_AUTO, PRORES_PROFILE_4444XQ, VE, .unit = "profile" },
978 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_AUTO },
979 0, 0, VE, .unit = "profile" },
980 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
981 0, 0, VE, .unit = "profile" },
982 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
983 0, 0, VE, .unit = "profile" },
984 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
985 0, 0, VE, .unit = "profile" },
986 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
987 0, 0, VE, .unit = "profile" },
988 { "4444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
989 0, 0, VE, .unit = "profile" },
990 { "4444xq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444XQ },
991 0, 0, VE, .unit = "profile" },
992 { "vendor", "vendor ID", OFFSET(vendor),
993 AV_OPT_TYPE_STRING, { .str = "Lavc" }, 0, 0, VE },
994 { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
995 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
996 { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
997 { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, .unit = "quant_mat" },
998 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
999 0, 0, VE, .unit = "quant_mat" },
1000 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
1001 0, 0, VE, .unit = "quant_mat" },
1002 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
1003 0, 0, VE, .unit = "quant_mat" },
1004 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
1005 0, 0, VE, .unit = "quant_mat" },
1006 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
1007 0, 0, VE, .unit = "quant_mat" },
1008 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
1009 0, 0, VE, .unit = "quant_mat" },
1010 { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
1011 { .i64 = 16 }, 0, 16, VE },
1012 { NULL }
1013 };
1014
1015 static const AVClass proresenc_class = {
1016 .class_name = "ProRes encoder",
1017 .item_name = av_default_item_name,
1018 .option = options,
1019 .version = LIBAVUTIL_VERSION_INT,
1020 };
1021
1022 const FFCodec ff_prores_ks_encoder = {
1023 .p.name = "prores_ks",
1024 CODEC_LONG_NAME("Apple ProRes (iCodec Pro)"),
1025 .p.type = AVMEDIA_TYPE_VIDEO,
1026 .p.id = AV_CODEC_ID_PRORES,
1027 .priv_data_size = sizeof(ProresContext),
1028 .init = encode_init,
1029 .close = encode_close,
1030 FF_CODEC_ENCODE_CB(encode_frame),
1031 .p.capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS |
1032 AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
1033 CODEC_PIXFMTS(AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10),
1034 .color_ranges = AVCOL_RANGE_MPEG,
1035 .p.priv_class = &proresenc_class,
1036 .p.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
1037 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1038 };
1039