4 * Copyright (c) 2012 Konstantin Shishkov
6 * This encoder appears to be based on Anatoliy Wassermans considering
7 * similarities in the bugs.
9 * This file is part of FFmpeg.
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26 #include "libavutil/opt.h"
27 #include "libavutil/pixdesc.h"
32 #include "bytestream.h"
34 #include "proresdata.h"
36 #define CFACTOR_Y422 2
37 #define CFACTOR_Y444 3
39 #define MAX_MBS_PER_SLICE 8
44 PRORES_PROFILE_AUTO = -1,
45 PRORES_PROFILE_PROXY = 0,
47 PRORES_PROFILE_STANDARD,
50 PRORES_PROFILE_4444XQ,
55 QUANT_MAT_PROXY_CHROMA,
63 static const uint8_t prores_quant_matrices[][64] = {
65 4, 7, 9, 11, 13, 14, 15, 63,
66 7, 7, 11, 12, 14, 15, 63, 63,
67 9, 11, 13, 14, 15, 63, 63, 63,
68 11, 11, 13, 14, 63, 63, 63, 63,
69 11, 13, 14, 63, 63, 63, 63, 63,
70 13, 14, 63, 63, 63, 63, 63, 63,
71 13, 63, 63, 63, 63, 63, 63, 63,
72 63, 63, 63, 63, 63, 63, 63, 63,
75 4, 7, 9, 11, 13, 14, 63, 63,
76 7, 7, 11, 12, 14, 63, 63, 63,
77 9, 11, 13, 14, 63, 63, 63, 63,
78 11, 11, 13, 14, 63, 63, 63, 63,
79 11, 13, 14, 63, 63, 63, 63, 63,
80 13, 14, 63, 63, 63, 63, 63, 63,
81 13, 63, 63, 63, 63, 63, 63, 63,
82 63, 63, 63, 63, 63, 63, 63, 63
85 4, 5, 6, 7, 9, 11, 13, 15,
86 5, 5, 7, 8, 11, 13, 15, 17,
87 6, 7, 9, 11, 13, 15, 15, 17,
88 7, 7, 9, 11, 13, 15, 17, 19,
89 7, 9, 11, 13, 14, 16, 19, 23,
90 9, 11, 13, 14, 16, 19, 23, 29,
91 9, 11, 13, 15, 17, 21, 28, 35,
92 11, 13, 16, 17, 21, 28, 35, 41,
95 4, 4, 5, 5, 6, 7, 7, 9,
96 4, 4, 5, 6, 7, 7, 9, 9,
97 5, 5, 6, 7, 7, 9, 9, 10,
98 5, 5, 6, 7, 7, 9, 9, 10,
99 5, 6, 7, 7, 8, 9, 10, 12,
100 6, 7, 7, 8, 9, 10, 12, 15,
101 6, 7, 7, 9, 10, 11, 14, 17,
102 7, 7, 9, 10, 11, 14, 17, 21,
105 4, 4, 4, 4, 4, 4, 4, 4,
106 4, 4, 4, 4, 4, 4, 4, 4,
107 4, 4, 4, 4, 4, 4, 4, 4,
108 4, 4, 4, 4, 4, 4, 4, 5,
109 4, 4, 4, 4, 4, 4, 5, 5,
110 4, 4, 4, 4, 4, 5, 5, 6,
111 4, 4, 4, 4, 5, 5, 6, 7,
112 4, 4, 4, 4, 5, 6, 7, 7,
115 2, 2, 2, 2, 2, 2, 2, 2,
116 2, 2, 2, 2, 2, 2, 2, 2,
117 2, 2, 2, 2, 2, 2, 2, 2,
118 2, 2, 2, 2, 2, 2, 2, 3,
119 2, 2, 2, 2, 2, 2, 3, 3,
120 2, 2, 2, 2, 2, 3, 3, 3,
121 2, 2, 2, 2, 3, 3, 3, 4,
122 2, 2, 2, 2, 3, 3, 4, 4,
125 4, 4, 4, 4, 4, 4, 4, 4,
126 4, 4, 4, 4, 4, 4, 4, 4,
127 4, 4, 4, 4, 4, 4, 4, 4,
128 4, 4, 4, 4, 4, 4, 4, 4,
129 4, 4, 4, 4, 4, 4, 4, 4,
130 4, 4, 4, 4, 4, 4, 4, 4,
131 4, 4, 4, 4, 4, 4, 4, 4,
132 4, 4, 4, 4, 4, 4, 4, 4,
136 #define NUM_MB_LIMITS 4
137 static const int prores_mb_limits[NUM_MB_LIMITS] = {
138 1620, // up to 720x576
139 2700, // up to 960x720
140 6075, // up to 1440x1080
141 9216, // up to 2048x1152
144 static const struct prores_profile {
145 const char *full_name;
149 int br_tab[NUM_MB_LIMITS];
152 } prores_profile_info[6] = {
154 .full_name = "proxy",
155 .tag = MKTAG('a', 'p', 'c', 'o'),
158 .br_tab = { 300, 242, 220, 194 },
159 .quant = QUANT_MAT_PROXY,
160 .quant_chroma = QUANT_MAT_PROXY_CHROMA,
164 .tag = MKTAG('a', 'p', 'c', 's'),
167 .br_tab = { 720, 560, 490, 440 },
168 .quant = QUANT_MAT_LT,
169 .quant_chroma = QUANT_MAT_LT,
172 .full_name = "standard",
173 .tag = MKTAG('a', 'p', 'c', 'n'),
176 .br_tab = { 1050, 808, 710, 632 },
177 .quant = QUANT_MAT_STANDARD,
178 .quant_chroma = QUANT_MAT_STANDARD,
181 .full_name = "high quality",
182 .tag = MKTAG('a', 'p', 'c', 'h'),
185 .br_tab = { 1566, 1216, 1070, 950 },
186 .quant = QUANT_MAT_HQ,
187 .quant_chroma = QUANT_MAT_HQ,
191 .tag = MKTAG('a', 'p', '4', 'h'),
194 .br_tab = { 2350, 1828, 1600, 1425 },
195 .quant = QUANT_MAT_HQ,
196 .quant_chroma = QUANT_MAT_HQ,
199 .full_name = "4444XQ",
200 .tag = MKTAG('a', 'p', '4', 'x'),
203 .br_tab = { 3525, 2742, 2400, 2137 },
204 .quant = QUANT_MAT_HQ, /* Fix me : use QUANT_MAT_XQ_LUMA */
205 .quant_chroma = QUANT_MAT_HQ,
209 #define TRELLIS_WIDTH 16
210 #define SCORE_LIMIT INT_MAX / 2
219 #define MAX_STORED_Q 16
221 typedef struct ProresThreadData {
222 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
223 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
224 int16_t custom_q[64];
225 struct TrellisNode *nodes;
228 typedef struct ProresContext {
230 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
231 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
232 int16_t quants[MAX_STORED_Q][64];
233 int16_t quants_chroma[MAX_STORED_Q][64];
234 int16_t custom_q[64];
235 const uint8_t *quant_mat;
236 const uint8_t *quant_chroma_mat;
237 const uint8_t *scantable;
239 void (*fdct)(FDCTDSPContext *fdsp, const uint16_t *src,
240 ptrdiff_t linesize, int16_t *block);
244 int mb_width, mb_height;
246 int num_chroma_blocks, chroma_factor;
248 int slices_per_picture;
249 int pictures_per_frame; // 1 for progressive, 2 for interlaced
260 int frame_size_upper_bound;
263 const struct prores_profile *profile_info;
267 ProresThreadData *tdata;
270 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
271 ptrdiff_t linesize, int x, int y, int w, int h,
272 int16_t *blocks, uint16_t *emu_buf,
273 int mbs_per_slice, int blocks_per_mb, int is_chroma)
275 const uint16_t *esrc;
276 const int mb_width = 4 * blocks_per_mb;
280 for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
282 memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
286 if (x + mb_width <= w && y + 16 <= h) {
288 elinesize = linesize;
293 elinesize = 16 * sizeof(*emu_buf);
295 bw = FFMIN(w - x, mb_width);
296 bh = FFMIN(h - y, 16);
298 for (j = 0; j < bh; j++) {
299 memcpy(emu_buf + j * 16,
300 (const uint8_t*)src + j * linesize,
302 pix = emu_buf[j * 16 + bw - 1];
303 for (k = bw; k < mb_width; k++)
304 emu_buf[j * 16 + k] = pix;
307 memcpy(emu_buf + j * 16,
308 emu_buf + (bh - 1) * 16,
309 mb_width * sizeof(*emu_buf));
312 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
314 if (blocks_per_mb > 2) {
315 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
318 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
320 if (blocks_per_mb > 2) {
321 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
325 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
327 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
329 if (blocks_per_mb > 2) {
330 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
332 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
341 static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
342 ptrdiff_t linesize, int x, int y, int w, int h,
343 int16_t *blocks, int mbs_per_slice, int abits)
345 const int slice_width = 16 * mbs_per_slice;
346 int i, j, copy_w, copy_h;
348 copy_w = FFMIN(w - x, slice_width);
349 copy_h = FFMIN(h - y, 16);
350 for (i = 0; i < copy_h; i++) {
351 memcpy(blocks, src, copy_w * sizeof(*src));
353 for (j = 0; j < copy_w; j++)
356 for (j = 0; j < copy_w; j++)
357 blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
358 for (j = copy_w; j < slice_width; j++)
359 blocks[j] = blocks[copy_w - 1];
360 blocks += slice_width;
361 src += linesize >> 1;
363 for (; i < 16; i++) {
364 memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
365 blocks += slice_width;
370 * Write an unsigned rice/exp golomb codeword.
372 static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
374 unsigned int rice_order, exp_order, switch_bits, switch_val;
377 /* number of prefix bits to switch between Rice and expGolomb */
378 switch_bits = (codebook & 3) + 1;
379 rice_order = codebook >> 5; /* rice code order */
380 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
382 switch_val = switch_bits << rice_order;
384 if (val >= switch_val) {
385 val -= switch_val - (1 << exp_order);
386 exponent = av_log2(val);
388 put_bits(pb, exponent - exp_order + switch_bits, 0);
389 put_bits(pb, exponent + 1, val);
391 exponent = val >> rice_order;
394 put_bits(pb, exponent, 0);
397 put_sbits(pb, rice_order, val);
401 #define GET_SIGN(x) ((x) >> 31)
402 #define MAKE_CODE(x) ((((x)) * 2) ^ GET_SIGN(x))
404 static void encode_dcs(PutBitContext *pb, int16_t *blocks,
405 int blocks_per_slice, int scale)
408 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
410 prev_dc = (blocks[0] - 0x4000) / scale;
411 encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
416 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
417 dc = (blocks[0] - 0x4000) / scale;
418 delta = dc - prev_dc;
419 new_sign = GET_SIGN(delta);
420 delta = (delta ^ sign) - sign;
421 code = MAKE_CODE(delta);
422 encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
423 codebook = (code + (code & 1)) >> 1;
424 codebook = FFMIN(codebook, 3);
430 static void encode_acs(PutBitContext *pb, int16_t *blocks,
431 int blocks_per_slice,
432 int plane_size_factor,
433 const uint8_t *scan, const int16_t *qmat)
436 int run, level, run_cb, lev_cb;
437 int max_coeffs, abs_level;
439 max_coeffs = blocks_per_slice << 6;
440 run_cb = ff_prores_run_to_cb_index[4];
441 lev_cb = ff_prores_lev_to_cb_index[2];
444 for (i = 1; i < 64; i++) {
445 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
446 level = blocks[idx] / qmat[scan[i]];
448 abs_level = FFABS(level);
449 encode_vlc_codeword(pb, ff_prores_ac_codebook[run_cb], run);
450 encode_vlc_codeword(pb, ff_prores_ac_codebook[lev_cb],
452 put_sbits(pb, 1, GET_SIGN(level));
454 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
455 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
464 static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
465 const uint16_t *src, ptrdiff_t linesize,
466 int mbs_per_slice, int16_t *blocks,
467 int blocks_per_mb, int plane_size_factor,
470 int blocks_per_slice, saved_pos;
472 saved_pos = put_bits_count(pb);
473 blocks_per_slice = mbs_per_slice * blocks_per_mb;
475 encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
476 encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
477 ctx->scantable, qmat);
480 return (put_bits_count(pb) - saved_pos) >> 3;
483 static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
485 const int dbits = (abits == 8) ? 4 : 7;
486 const int dsize = 1 << dbits - 1;
487 int diff = cur - prev;
489 diff = av_mod_uintp2(diff, abits);
490 if (diff >= (1 << abits) - dsize)
492 if (diff < -dsize || diff > dsize || !diff) {
494 put_bits(pb, abits, diff);
497 put_bits(pb, dbits - 1, FFABS(diff) - 1);
498 put_bits(pb, 1, diff < 0);
502 static void put_alpha_run(PutBitContext *pb, int run)
507 put_bits(pb, 4, run);
509 put_bits(pb, 15, run);
515 // todo alpha quantisation for high quants
516 static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
517 int mbs_per_slice, uint16_t *blocks,
520 const int abits = ctx->alpha_bits;
521 const int mask = (1 << abits) - 1;
522 const int num_coeffs = mbs_per_slice * 256;
523 int saved_pos = put_bits_count(pb);
524 int prev = mask, cur;
529 put_alpha_diff(pb, cur, prev, abits);
534 put_alpha_run (pb, run);
535 put_alpha_diff(pb, cur, prev, abits);
541 } while (idx < num_coeffs);
543 put_alpha_run(pb, run);
545 return (put_bits_count(pb) - saved_pos) >> 3;
548 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
550 int sizes[4], int x, int y, int quant,
553 ProresContext *ctx = avctx->priv_data;
557 int slice_width_factor = av_log2(mbs_per_slice);
558 int num_cblocks, pwidth, line_add;
560 int plane_factor, is_chroma;
562 uint16_t *qmat_chroma;
564 if (ctx->pictures_per_frame == 1)
567 line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
569 if (ctx->force_quant) {
570 qmat = ctx->quants[0];
571 qmat_chroma = ctx->quants_chroma[0];
572 } else if (quant < MAX_STORED_Q) {
573 qmat = ctx->quants[quant];
574 qmat_chroma = ctx->quants_chroma[quant];
576 qmat = ctx->custom_q;
577 qmat_chroma = ctx->custom_q;
578 for (i = 0; i < 64; i++) {
579 qmat[i] = ctx->quant_mat[i] * quant;
580 qmat_chroma[i] = ctx->quant_chroma_mat[i] * quant;
584 for (i = 0; i < ctx->num_planes; i++) {
585 is_chroma = (i == 1 || i == 2);
586 plane_factor = slice_width_factor + 2;
588 plane_factor += ctx->chroma_factor - 3;
589 if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
593 pwidth = avctx->width;
598 pwidth = avctx->width >> 1;
601 linesize = pic->linesize[i] * ctx->pictures_per_frame;
602 src = (const uint16_t*)(pic->data[i] + yp * linesize +
603 line_add * pic->linesize[i]) + xp;
606 get_slice_data(ctx, src, linesize, xp, yp,
607 pwidth, avctx->height / ctx->pictures_per_frame,
608 ctx->blocks[0], ctx->emu_buf,
609 mbs_per_slice, num_cblocks, is_chroma);
610 if (!is_chroma) {/* luma quant */
611 sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
612 mbs_per_slice, ctx->blocks[0],
613 num_cblocks, plane_factor,
615 } else { /* chroma plane */
616 sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
617 mbs_per_slice, ctx->blocks[0],
618 num_cblocks, plane_factor,
622 get_alpha_data(ctx, src, linesize, xp, yp,
623 pwidth, avctx->height / ctx->pictures_per_frame,
624 ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
625 sizes[i] = encode_alpha_plane(ctx, pb, mbs_per_slice,
626 ctx->blocks[0], quant);
628 total_size += sizes[i];
629 if (put_bits_left(pb) < 0) {
630 av_log(avctx, AV_LOG_ERROR,
631 "Underestimated required buffer size.\n");
638 static inline int estimate_vlc(unsigned codebook, int val)
640 unsigned int rice_order, exp_order, switch_bits, switch_val;
643 /* number of prefix bits to switch between Rice and expGolomb */
644 switch_bits = (codebook & 3) + 1;
645 rice_order = codebook >> 5; /* rice code order */
646 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
648 switch_val = switch_bits << rice_order;
650 if (val >= switch_val) {
651 val -= switch_val - (1 << exp_order);
652 exponent = av_log2(val);
654 return exponent * 2 - exp_order + switch_bits + 1;
656 return (val >> rice_order) + rice_order + 1;
660 static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
664 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
667 prev_dc = (blocks[0] - 0x4000) / scale;
668 bits = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
672 *error += FFABS(blocks[0] - 0x4000) % scale;
674 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
675 dc = (blocks[0] - 0x4000) / scale;
676 *error += FFABS(blocks[0] - 0x4000) % scale;
677 delta = dc - prev_dc;
678 new_sign = GET_SIGN(delta);
679 delta = (delta ^ sign) - sign;
680 code = MAKE_CODE(delta);
681 bits += estimate_vlc(ff_prores_dc_codebook[codebook], code);
682 codebook = (code + (code & 1)) >> 1;
683 codebook = FFMIN(codebook, 3);
691 static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
692 int plane_size_factor,
693 const uint8_t *scan, const int16_t *qmat)
696 int run, level, run_cb, lev_cb;
697 int max_coeffs, abs_level;
700 max_coeffs = blocks_per_slice << 6;
701 run_cb = ff_prores_run_to_cb_index[4];
702 lev_cb = ff_prores_lev_to_cb_index[2];
705 for (i = 1; i < 64; i++) {
706 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
707 level = blocks[idx] / qmat[scan[i]];
708 *error += FFABS(blocks[idx]) % qmat[scan[i]];
710 abs_level = FFABS(level);
711 bits += estimate_vlc(ff_prores_ac_codebook[run_cb], run);
712 bits += estimate_vlc(ff_prores_ac_codebook[lev_cb],
715 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
716 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
727 static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
728 const uint16_t *src, ptrdiff_t linesize,
730 int blocks_per_mb, int plane_size_factor,
731 const int16_t *qmat, ProresThreadData *td)
733 int blocks_per_slice;
736 blocks_per_slice = mbs_per_slice * blocks_per_mb;
738 bits = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
739 bits += estimate_acs(error, td->blocks[plane], blocks_per_slice,
740 plane_size_factor, ctx->scantable, qmat);
742 return FFALIGN(bits, 8);
745 static int est_alpha_diff(int cur, int prev, int abits)
747 const int dbits = (abits == 8) ? 4 : 7;
748 const int dsize = 1 << dbits - 1;
749 int diff = cur - prev;
751 diff = av_mod_uintp2(diff, abits);
752 if (diff >= (1 << abits) - dsize)
754 if (diff < -dsize || diff > dsize || !diff)
760 static int estimate_alpha_plane(ProresContext *ctx,
761 const uint16_t *src, ptrdiff_t linesize,
762 int mbs_per_slice, int16_t *blocks)
764 const int abits = ctx->alpha_bits;
765 const int mask = (1 << abits) - 1;
766 const int num_coeffs = mbs_per_slice * 256;
767 int prev = mask, cur;
773 bits = est_alpha_diff(cur, prev, abits);
784 bits += est_alpha_diff(cur, prev, abits);
790 } while (idx < num_coeffs);
802 static int find_slice_quant(AVCodecContext *avctx,
803 int trellis_node, int x, int y, int mbs_per_slice,
804 ProresThreadData *td)
806 ProresContext *ctx = avctx->priv_data;
807 int i, q, pq, xp, yp;
809 int slice_width_factor = av_log2(mbs_per_slice);
810 int num_cblocks[MAX_PLANES], pwidth;
811 int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];
812 const int min_quant = ctx->profile_info->min_quant;
813 const int max_quant = ctx->profile_info->max_quant;
814 int error, bits, bits_limit;
815 int mbs, prev, cur, new_score;
816 int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
819 uint16_t *qmat_chroma;
820 int linesize[4], line_add;
823 if (ctx->pictures_per_frame == 1)
826 line_add = ctx->cur_picture_idx ^ !ctx->pic->top_field_first;
827 mbs = x + mbs_per_slice;
829 for (i = 0; i < ctx->num_planes; i++) {
830 is_chroma[i] = (i == 1 || i == 2);
831 plane_factor[i] = slice_width_factor + 2;
833 plane_factor[i] += ctx->chroma_factor - 3;
834 if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
838 pwidth = avctx->width;
843 pwidth = avctx->width >> 1;
846 linesize[i] = ctx->pic->linesize[i] * ctx->pictures_per_frame;
847 src = (const uint16_t *)(ctx->pic->data[i] + yp * linesize[i] +
848 line_add * ctx->pic->linesize[i]) + xp;
851 get_slice_data(ctx, src, linesize[i], xp, yp,
852 pwidth, avctx->height / ctx->pictures_per_frame,
853 td->blocks[i], td->emu_buf,
854 mbs_per_slice, num_cblocks[i], is_chroma[i]);
856 get_alpha_data(ctx, src, linesize[i], xp, yp,
857 pwidth, avctx->height / ctx->pictures_per_frame,
858 td->blocks[i], mbs_per_slice, ctx->alpha_bits);
862 for (q = min_quant; q < max_quant + 2; q++) {
863 td->nodes[trellis_node + q].prev_node = -1;
864 td->nodes[trellis_node + q].quant = q;
868 alpha_bits = estimate_alpha_plane(ctx, src, linesize[3],
869 mbs_per_slice, td->blocks[3]);
870 // todo: maybe perform coarser quantising to fit into frame size when needed
871 for (q = min_quant; q <= max_quant; q++) {
874 bits += estimate_slice_plane(ctx, &error, 0,
877 num_cblocks[0], plane_factor[0],
878 ctx->quants[q], td); /* estimate luma plane */
879 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
880 bits += estimate_slice_plane(ctx, &error, i,
883 num_cblocks[i], plane_factor[i],
884 ctx->quants_chroma[q], td);
886 if (bits > 65000 * 8)
889 slice_bits[q] = bits;
890 slice_score[q] = error;
892 if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
893 slice_bits[max_quant + 1] = slice_bits[max_quant];
894 slice_score[max_quant + 1] = slice_score[max_quant] + 1;
895 overquant = max_quant;
897 for (q = max_quant + 1; q < 128; q++) {
900 if (q < MAX_STORED_Q) {
901 qmat = ctx->quants[q];
902 qmat_chroma = ctx->quants_chroma[q];
905 qmat_chroma = td->custom_q;
906 for (i = 0; i < 64; i++) {
907 qmat[i] = ctx->quant_mat[i] * q;
908 qmat_chroma[i] = ctx->quant_chroma_mat[i] * q;
911 bits += estimate_slice_plane(ctx, &error, 0,
914 num_cblocks[0], plane_factor[0],
915 qmat, td);/* estimate luma plane */
916 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
917 bits += estimate_slice_plane(ctx, &error, i,
920 num_cblocks[i], plane_factor[i],
923 if (bits <= ctx->bits_per_mb * mbs_per_slice)
927 slice_bits[max_quant + 1] = bits;
928 slice_score[max_quant + 1] = error;
931 td->nodes[trellis_node + max_quant + 1].quant = overquant;
933 bits_limit = mbs * ctx->bits_per_mb;
934 for (pq = min_quant; pq < max_quant + 2; pq++) {
935 prev = trellis_node - TRELLIS_WIDTH + pq;
937 for (q = min_quant; q < max_quant + 2; q++) {
938 cur = trellis_node + q;
940 bits = td->nodes[prev].bits + slice_bits[q];
941 error = slice_score[q];
942 if (bits > bits_limit)
945 if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
946 new_score = td->nodes[prev].score + error;
948 new_score = SCORE_LIMIT;
949 if (td->nodes[cur].prev_node == -1 ||
950 td->nodes[cur].score >= new_score) {
952 td->nodes[cur].bits = bits;
953 td->nodes[cur].score = new_score;
954 td->nodes[cur].prev_node = prev;
959 error = td->nodes[trellis_node + min_quant].score;
960 pq = trellis_node + min_quant;
961 for (q = min_quant + 1; q < max_quant + 2; q++) {
962 if (td->nodes[trellis_node + q].score <= error) {
963 error = td->nodes[trellis_node + q].score;
964 pq = trellis_node + q;
971 static int find_quant_thread(AVCodecContext *avctx, void *arg,
972 int jobnr, int threadnr)
974 ProresContext *ctx = avctx->priv_data;
975 ProresThreadData *td = ctx->tdata + threadnr;
976 int mbs_per_slice = ctx->mbs_per_slice;
977 int x, y = jobnr, mb, q = 0;
979 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
980 while (ctx->mb_width - x < mbs_per_slice)
982 q = find_slice_quant(avctx,
983 (mb + 1) * TRELLIS_WIDTH, x, y,
987 for (x = ctx->slices_width - 1; x >= 0; x--) {
988 ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
989 q = td->nodes[q].prev_node;
995 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
996 const AVFrame *pic, int *got_packet)
998 ProresContext *ctx = avctx->priv_data;
999 uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
1000 uint8_t *picture_size_pos;
1002 int x, y, i, mb, q = 0;
1003 int sizes[4] = { 0 };
1004 int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
1005 int frame_size, picture_size, slice_size;
1007 int max_slice_size = (ctx->frame_size_upper_bound - 200) / (ctx->pictures_per_frame * ctx->slices_per_picture + 1);
1008 uint8_t frame_flags;
1011 pkt_size = ctx->frame_size_upper_bound;
1013 if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
1016 orig_buf = pkt->data;
1019 orig_buf += 4; // frame size
1020 bytestream_put_be32 (&orig_buf, FRAME_ID); // frame container ID
1025 buf += 2; // frame header size will be stored here
1026 bytestream_put_be16 (&buf, 0); // version 1
1027 bytestream_put_buffer(&buf, ctx->vendor, 4);
1028 bytestream_put_be16 (&buf, avctx->width);
1029 bytestream_put_be16 (&buf, avctx->height);
1031 frame_flags = ctx->chroma_factor << 6;
1032 if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
1033 frame_flags |= pic->top_field_first ? 0x04 : 0x08;
1034 bytestream_put_byte (&buf, frame_flags);
1036 bytestream_put_byte (&buf, 0); // reserved
1037 bytestream_put_byte (&buf, pic->color_primaries);
1038 bytestream_put_byte (&buf, pic->color_trc);
1039 bytestream_put_byte (&buf, pic->colorspace);
1040 bytestream_put_byte (&buf, 0x40 | (ctx->alpha_bits >> 3));
1041 bytestream_put_byte (&buf, 0); // reserved
1042 if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
1043 bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present
1044 // luma quantisation matrix
1045 for (i = 0; i < 64; i++)
1046 bytestream_put_byte(&buf, ctx->quant_mat[i]);
1047 // chroma quantisation matrix
1048 for (i = 0; i < 64; i++)
1049 bytestream_put_byte(&buf, ctx->quant_mat[i]);
1051 bytestream_put_byte (&buf, 0x00); // matrix flags - default matrices are used
1053 bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
1055 for (ctx->cur_picture_idx = 0;
1056 ctx->cur_picture_idx < ctx->pictures_per_frame;
1057 ctx->cur_picture_idx++) {
1059 picture_size_pos = buf + 1;
1060 bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
1061 buf += 4; // picture data size will be stored here
1062 bytestream_put_be16 (&buf, ctx->slices_per_picture);
1063 bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
1065 // seek table - will be filled during slice encoding
1067 buf += ctx->slices_per_picture * 2;
1070 if (!ctx->force_quant) {
1071 ret = avctx->execute2(avctx, find_quant_thread, (void*)pic, NULL,
1077 for (y = 0; y < ctx->mb_height; y++) {
1078 int mbs_per_slice = ctx->mbs_per_slice;
1079 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
1080 q = ctx->force_quant ? ctx->force_quant
1081 : ctx->slice_q[mb + y * ctx->slices_width];
1083 while (ctx->mb_width - x < mbs_per_slice)
1084 mbs_per_slice >>= 1;
1086 bytestream_put_byte(&buf, slice_hdr_size << 3);
1088 buf += slice_hdr_size - 1;
1089 if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
1090 uint8_t *start = pkt->data;
1091 // Recompute new size according to max_slice_size
1093 int delta = 200 + (ctx->pictures_per_frame *
1094 ctx->slices_per_picture + 1) *
1095 max_slice_size - pkt_size;
1097 delta = FFMAX(delta, 2 * max_slice_size);
1098 ctx->frame_size_upper_bound += delta;
1101 avpriv_request_sample(avctx,
1102 "Packet too small: is %i,"
1103 " needs %i (slice: %i). "
1104 "Correct allocation",
1105 pkt_size, delta, max_slice_size);
1109 ret = av_grow_packet(pkt, delta);
1115 orig_buf = pkt->data + (orig_buf - start);
1116 buf = pkt->data + (buf - start);
1117 picture_size_pos = pkt->data + (picture_size_pos - start);
1118 slice_sizes = pkt->data + (slice_sizes - start);
1119 slice_hdr = pkt->data + (slice_hdr - start);
1120 tmp = pkt->data + (tmp - start);
1122 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)));
1123 ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
1128 bytestream_put_byte(&slice_hdr, q);
1129 slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
1130 for (i = 0; i < ctx->num_planes - 1; i++) {
1131 bytestream_put_be16(&slice_hdr, sizes[i]);
1132 slice_size += sizes[i];
1134 bytestream_put_be16(&slice_sizes, slice_size);
1135 buf += slice_size - slice_hdr_size;
1136 if (max_slice_size < slice_size)
1137 max_slice_size = slice_size;
1141 picture_size = buf - (picture_size_pos - 1);
1142 bytestream_put_be32(&picture_size_pos, picture_size);
1146 frame_size = buf - orig_buf;
1147 bytestream_put_be32(&orig_buf, frame_size);
1149 pkt->size = frame_size;
1150 pkt->flags |= AV_PKT_FLAG_KEY;
1156 static av_cold int encode_close(AVCodecContext *avctx)
1158 ProresContext *ctx = avctx->priv_data;
1162 for (i = 0; i < avctx->thread_count; i++)
1163 av_freep(&ctx->tdata[i].nodes);
1165 av_freep(&ctx->tdata);
1166 av_freep(&ctx->slice_q);
1171 static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src,
1172 ptrdiff_t linesize, int16_t *block)
1175 const uint16_t *tsrc = src;
1177 for (y = 0; y < 8; y++) {
1178 for (x = 0; x < 8; x++)
1179 block[y * 8 + x] = tsrc[x];
1180 tsrc += linesize >> 1;
1185 static av_cold int encode_init(AVCodecContext *avctx)
1187 ProresContext *ctx = avctx->priv_data;
1190 int min_quant, max_quant;
1191 int interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
1193 avctx->bits_per_raw_sample = 10;
1194 #if FF_API_CODED_FRAME
1195 FF_DISABLE_DEPRECATION_WARNINGS
1196 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
1197 avctx->coded_frame->key_frame = 1;
1198 FF_ENABLE_DEPRECATION_WARNINGS
1201 ctx->fdct = prores_fdct;
1202 ctx->scantable = interlaced ? ff_prores_interlaced_scan
1203 : ff_prores_progressive_scan;
1204 ff_fdctdsp_init(&ctx->fdsp, avctx);
1206 mps = ctx->mbs_per_slice;
1207 if (mps & (mps - 1)) {
1208 av_log(avctx, AV_LOG_ERROR,
1209 "there should be an integer power of two MBs per slice\n");
1210 return AVERROR(EINVAL);
1212 if (ctx->profile == PRORES_PROFILE_AUTO) {
1213 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1214 ctx->profile = (desc->flags & AV_PIX_FMT_FLAG_ALPHA ||
1215 !(desc->log2_chroma_w + desc->log2_chroma_h))
1216 ? PRORES_PROFILE_4444 : PRORES_PROFILE_HQ;
1217 av_log(avctx, AV_LOG_INFO, "Autoselected %s. It can be overridden "
1218 "through -profile option.\n", ctx->profile == PRORES_PROFILE_4444
1219 ? "4:4:4:4 profile because of the used input colorspace"
1220 : "HQ profile to keep best quality");
1222 if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
1223 if (ctx->profile != PRORES_PROFILE_4444 &&
1224 ctx->profile != PRORES_PROFILE_4444XQ) {
1225 // force alpha and warn
1226 av_log(avctx, AV_LOG_WARNING, "Profile selected will not "
1227 "encode alpha. Override with -profile if needed.\n");
1228 ctx->alpha_bits = 0;
1230 if (ctx->alpha_bits & 7) {
1231 av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
1232 return AVERROR(EINVAL);
1234 avctx->bits_per_coded_sample = 32;
1236 ctx->alpha_bits = 0;
1239 ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
1242 ctx->profile_info = prores_profile_info + ctx->profile;
1243 ctx->num_planes = 3 + !!ctx->alpha_bits;
1245 ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
1248 ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
1250 ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
1252 ctx->slices_width = ctx->mb_width / mps;
1253 ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
1254 ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
1255 ctx->pictures_per_frame = 1 + interlaced;
1257 if (ctx->quant_sel == -1) {
1258 ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
1259 ctx->quant_chroma_mat = prores_quant_matrices[ctx->profile_info->quant_chroma];
1261 ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
1262 ctx->quant_chroma_mat = prores_quant_matrices[ctx->quant_sel];
1265 if (strlen(ctx->vendor) != 4) {
1266 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
1267 return AVERROR_INVALIDDATA;
1270 ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
1271 if (!ctx->force_quant) {
1272 if (!ctx->bits_per_mb) {
1273 for (i = 0; i < NUM_MB_LIMITS - 1; i++)
1274 if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
1275 ctx->pictures_per_frame)
1277 ctx->bits_per_mb = ctx->profile_info->br_tab[i];
1278 if (ctx->alpha_bits)
1279 ctx->bits_per_mb *= 20;
1280 } else if (ctx->bits_per_mb < 128) {
1281 av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
1282 return AVERROR_INVALIDDATA;
1285 min_quant = ctx->profile_info->min_quant;
1286 max_quant = ctx->profile_info->max_quant;
1287 for (i = min_quant; i < MAX_STORED_Q; i++) {
1288 for (j = 0; j < 64; j++) {
1289 ctx->quants[i][j] = ctx->quant_mat[j] * i;
1290 ctx->quants_chroma[i][j] = ctx->quant_chroma_mat[j] * i;
1294 ctx->slice_q = av_malloc(ctx->slices_per_picture * sizeof(*ctx->slice_q));
1295 if (!ctx->slice_q) {
1296 encode_close(avctx);
1297 return AVERROR(ENOMEM);
1300 ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
1302 encode_close(avctx);
1303 return AVERROR(ENOMEM);
1306 for (j = 0; j < avctx->thread_count; j++) {
1307 ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
1309 * sizeof(*ctx->tdata->nodes));
1310 if (!ctx->tdata[j].nodes) {
1311 encode_close(avctx);
1312 return AVERROR(ENOMEM);
1314 for (i = min_quant; i < max_quant + 2; i++) {
1315 ctx->tdata[j].nodes[i].prev_node = -1;
1316 ctx->tdata[j].nodes[i].bits = 0;
1317 ctx->tdata[j].nodes[i].score = 0;
1324 if (ctx->force_quant > 64) {
1325 av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
1326 return AVERROR_INVALIDDATA;
1329 for (j = 0; j < 64; j++) {
1330 ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
1331 ctx->quants_chroma[0][j] = ctx->quant_chroma_mat[j] * ctx->force_quant;
1332 ls += av_log2((1 << 11) / ctx->quants[0][j]) * 2 + 1;
1333 ls_chroma += av_log2((1 << 11) / ctx->quants_chroma[0][j]) * 2 + 1;
1336 ctx->bits_per_mb = ls * 4 + ls_chroma * 4;
1337 if (ctx->chroma_factor == CFACTOR_Y444)
1338 ctx->bits_per_mb += ls_chroma * 4;
1341 ctx->frame_size_upper_bound = (ctx->pictures_per_frame *
1342 ctx->slices_per_picture + 1) *
1343 (2 + 2 * ctx->num_planes +
1344 (mps * ctx->bits_per_mb) / 8)
1347 if (ctx->alpha_bits) {
1348 // The alpha plane is run-coded and might exceed the bit budget.
1349 ctx->frame_size_upper_bound += (ctx->pictures_per_frame *
1350 ctx->slices_per_picture + 1) *
1351 /* num pixels per slice */ (ctx->mbs_per_slice * 256 *
1352 /* bits per pixel */ (1 + ctx->alpha_bits + 1) + 7 >> 3);
1355 avctx->codec_tag = ctx->profile_info->tag;
1357 av_log(avctx, AV_LOG_DEBUG,
1358 "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
1359 ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
1360 interlaced ? "yes" : "no", ctx->bits_per_mb);
1361 av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
1362 ctx->frame_size_upper_bound);
1367 #define OFFSET(x) offsetof(ProresContext, x)
1368 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1370 static const AVOption options[] = {
1371 { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
1372 AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
1373 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
1374 { .i64 = PRORES_PROFILE_AUTO },
1375 PRORES_PROFILE_AUTO, PRORES_PROFILE_4444XQ, VE, "profile" },
1376 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_AUTO },
1377 0, 0, VE, "profile" },
1378 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
1379 0, 0, VE, "profile" },
1380 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
1381 0, 0, VE, "profile" },
1382 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
1383 0, 0, VE, "profile" },
1384 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
1385 0, 0, VE, "profile" },
1386 { "4444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
1387 0, 0, VE, "profile" },
1388 { "4444xq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444XQ },
1389 0, 0, VE, "profile" },
1390 { "vendor", "vendor ID", OFFSET(vendor),
1391 AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE },
1392 { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
1393 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
1394 { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
1395 { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, "quant_mat" },
1396 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
1397 0, 0, VE, "quant_mat" },
1398 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
1399 0, 0, VE, "quant_mat" },
1400 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
1401 0, 0, VE, "quant_mat" },
1402 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
1403 0, 0, VE, "quant_mat" },
1404 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
1405 0, 0, VE, "quant_mat" },
1406 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
1407 0, 0, VE, "quant_mat" },
1408 { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
1409 { .i64 = 16 }, 0, 16, VE },
1413 static const AVClass proresenc_class = {
1414 .class_name = "ProRes encoder",
1415 .item_name = av_default_item_name,
1417 .version = LIBAVUTIL_VERSION_INT,
1420 AVCodec ff_prores_ks_encoder = {
1421 .name = "prores_ks",
1422 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
1423 .type = AVMEDIA_TYPE_VIDEO,
1424 .id = AV_CODEC_ID_PRORES,
1425 .priv_data_size = sizeof(ProresContext),
1426 .init = encode_init,
1427 .close = encode_close,
1428 .encode2 = encode_frame,
1429 .capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
1430 .pix_fmts = (const enum AVPixelFormat[]) {
1431 AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
1432 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
1434 .priv_class = &proresenc_class,
1435 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),