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"
31 #include "bytestream.h"
33 #include "proresdata.h"
35 #define CFACTOR_Y422 2
36 #define CFACTOR_Y444 3
38 #define MAX_MBS_PER_SLICE 8
43 PRORES_PROFILE_AUTO = -1,
44 PRORES_PROFILE_PROXY = 0,
46 PRORES_PROFILE_STANDARD,
49 PRORES_PROFILE_4444XQ,
54 QUANT_MAT_PROXY_CHROMA,
62 static const uint8_t prores_quant_matrices[][64] = {
64 4, 7, 9, 11, 13, 14, 15, 63,
65 7, 7, 11, 12, 14, 15, 63, 63,
66 9, 11, 13, 14, 15, 63, 63, 63,
67 11, 11, 13, 14, 63, 63, 63, 63,
68 11, 13, 14, 63, 63, 63, 63, 63,
69 13, 14, 63, 63, 63, 63, 63, 63,
70 13, 63, 63, 63, 63, 63, 63, 63,
71 63, 63, 63, 63, 63, 63, 63, 63,
74 4, 7, 9, 11, 13, 14, 63, 63,
75 7, 7, 11, 12, 14, 63, 63, 63,
76 9, 11, 13, 14, 63, 63, 63, 63,
77 11, 11, 13, 14, 63, 63, 63, 63,
78 11, 13, 14, 63, 63, 63, 63, 63,
79 13, 14, 63, 63, 63, 63, 63, 63,
80 13, 63, 63, 63, 63, 63, 63, 63,
81 63, 63, 63, 63, 63, 63, 63, 63
84 4, 5, 6, 7, 9, 11, 13, 15,
85 5, 5, 7, 8, 11, 13, 15, 17,
86 6, 7, 9, 11, 13, 15, 15, 17,
87 7, 7, 9, 11, 13, 15, 17, 19,
88 7, 9, 11, 13, 14, 16, 19, 23,
89 9, 11, 13, 14, 16, 19, 23, 29,
90 9, 11, 13, 15, 17, 21, 28, 35,
91 11, 13, 16, 17, 21, 28, 35, 41,
94 4, 4, 5, 5, 6, 7, 7, 9,
95 4, 4, 5, 6, 7, 7, 9, 9,
96 5, 5, 6, 7, 7, 9, 9, 10,
97 5, 5, 6, 7, 7, 9, 9, 10,
98 5, 6, 7, 7, 8, 9, 10, 12,
99 6, 7, 7, 8, 9, 10, 12, 15,
100 6, 7, 7, 9, 10, 11, 14, 17,
101 7, 7, 9, 10, 11, 14, 17, 21,
104 4, 4, 4, 4, 4, 4, 4, 4,
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, 5,
108 4, 4, 4, 4, 4, 4, 5, 5,
109 4, 4, 4, 4, 4, 5, 5, 6,
110 4, 4, 4, 4, 5, 5, 6, 7,
111 4, 4, 4, 4, 5, 6, 7, 7,
114 2, 2, 2, 2, 2, 2, 2, 2,
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, 3,
118 2, 2, 2, 2, 2, 2, 3, 3,
119 2, 2, 2, 2, 2, 3, 3, 3,
120 2, 2, 2, 2, 3, 3, 3, 4,
121 2, 2, 2, 2, 3, 3, 4, 4,
124 4, 4, 4, 4, 4, 4, 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,
135 #define NUM_MB_LIMITS 4
136 static const int prores_mb_limits[NUM_MB_LIMITS] = {
137 1620, // up to 720x576
138 2700, // up to 960x720
139 6075, // up to 1440x1080
140 9216, // up to 2048x1152
143 static const struct prores_profile {
144 const char *full_name;
148 int br_tab[NUM_MB_LIMITS];
151 } prores_profile_info[6] = {
153 .full_name = "proxy",
154 .tag = MKTAG('a', 'p', 'c', 'o'),
157 .br_tab = { 300, 242, 220, 194 },
158 .quant = QUANT_MAT_PROXY,
159 .quant_chroma = QUANT_MAT_PROXY_CHROMA,
163 .tag = MKTAG('a', 'p', 'c', 's'),
166 .br_tab = { 720, 560, 490, 440 },
167 .quant = QUANT_MAT_LT,
168 .quant_chroma = QUANT_MAT_LT,
171 .full_name = "standard",
172 .tag = MKTAG('a', 'p', 'c', 'n'),
175 .br_tab = { 1050, 808, 710, 632 },
176 .quant = QUANT_MAT_STANDARD,
177 .quant_chroma = QUANT_MAT_STANDARD,
180 .full_name = "high quality",
181 .tag = MKTAG('a', 'p', 'c', 'h'),
184 .br_tab = { 1566, 1216, 1070, 950 },
185 .quant = QUANT_MAT_HQ,
186 .quant_chroma = QUANT_MAT_HQ,
190 .tag = MKTAG('a', 'p', '4', 'h'),
193 .br_tab = { 2350, 1828, 1600, 1425 },
194 .quant = QUANT_MAT_HQ,
195 .quant_chroma = QUANT_MAT_HQ,
198 .full_name = "4444XQ",
199 .tag = MKTAG('a', 'p', '4', 'x'),
202 .br_tab = { 3525, 2742, 2400, 2137 },
203 .quant = QUANT_MAT_HQ, /* Fix me : use QUANT_MAT_XQ_LUMA */
204 .quant_chroma = QUANT_MAT_HQ,
208 #define TRELLIS_WIDTH 16
209 #define SCORE_LIMIT INT_MAX / 2
218 #define MAX_STORED_Q 16
220 typedef struct ProresThreadData {
221 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
222 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
223 int16_t custom_q[64];
224 struct TrellisNode *nodes;
227 typedef struct ProresContext {
229 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
230 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
231 int16_t quants[MAX_STORED_Q][64];
232 int16_t quants_chroma[MAX_STORED_Q][64];
233 int16_t custom_q[64];
234 const uint8_t *quant_mat;
235 const uint8_t *quant_chroma_mat;
236 const uint8_t *scantable;
238 void (*fdct)(FDCTDSPContext *fdsp, const uint16_t *src,
239 ptrdiff_t linesize, int16_t *block);
243 int mb_width, mb_height;
245 int num_chroma_blocks, chroma_factor;
247 int slices_per_picture;
248 int pictures_per_frame; // 1 for progressive, 2 for interlaced
259 int frame_size_upper_bound;
262 const struct prores_profile *profile_info;
266 ProresThreadData *tdata;
269 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
270 ptrdiff_t linesize, int x, int y, int w, int h,
271 int16_t *blocks, uint16_t *emu_buf,
272 int mbs_per_slice, int blocks_per_mb, int is_chroma)
274 const uint16_t *esrc;
275 const int mb_width = 4 * blocks_per_mb;
279 for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
281 memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
285 if (x + mb_width <= w && y + 16 <= h) {
287 elinesize = linesize;
292 elinesize = 16 * sizeof(*emu_buf);
294 bw = FFMIN(w - x, mb_width);
295 bh = FFMIN(h - y, 16);
297 for (j = 0; j < bh; j++) {
298 memcpy(emu_buf + j * 16,
299 (const uint8_t*)src + j * linesize,
301 pix = emu_buf[j * 16 + bw - 1];
302 for (k = bw; k < mb_width; k++)
303 emu_buf[j * 16 + k] = pix;
306 memcpy(emu_buf + j * 16,
307 emu_buf + (bh - 1) * 16,
308 mb_width * sizeof(*emu_buf));
311 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
313 if (blocks_per_mb > 2) {
314 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
317 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
319 if (blocks_per_mb > 2) {
320 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
324 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
326 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
328 if (blocks_per_mb > 2) {
329 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
331 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
340 static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
341 ptrdiff_t linesize, int x, int y, int w, int h,
342 int16_t *blocks, int mbs_per_slice, int abits)
344 const int slice_width = 16 * mbs_per_slice;
345 int i, j, copy_w, copy_h;
347 copy_w = FFMIN(w - x, slice_width);
348 copy_h = FFMIN(h - y, 16);
349 for (i = 0; i < copy_h; i++) {
350 memcpy(blocks, src, copy_w * sizeof(*src));
352 for (j = 0; j < copy_w; j++)
355 for (j = 0; j < copy_w; j++)
356 blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
357 for (j = copy_w; j < slice_width; j++)
358 blocks[j] = blocks[copy_w - 1];
359 blocks += slice_width;
360 src += linesize >> 1;
362 for (; i < 16; i++) {
363 memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
364 blocks += slice_width;
369 * Write an unsigned rice/exp golomb codeword.
371 static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
373 unsigned int rice_order, exp_order, switch_bits, switch_val;
376 /* number of prefix bits to switch between Rice and expGolomb */
377 switch_bits = (codebook & 3) + 1;
378 rice_order = codebook >> 5; /* rice code order */
379 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
381 switch_val = switch_bits << rice_order;
383 if (val >= switch_val) {
384 val -= switch_val - (1 << exp_order);
385 exponent = av_log2(val);
387 put_bits(pb, exponent - exp_order + switch_bits, 0);
388 put_bits(pb, exponent + 1, val);
390 exponent = val >> rice_order;
393 put_bits(pb, exponent, 0);
396 put_sbits(pb, rice_order, val);
400 #define GET_SIGN(x) ((x) >> 31)
401 #define MAKE_CODE(x) ((((x)) * 2) ^ GET_SIGN(x))
403 static void encode_dcs(PutBitContext *pb, int16_t *blocks,
404 int blocks_per_slice, int scale)
407 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
409 prev_dc = (blocks[0] - 0x4000) / scale;
410 encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
415 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
416 dc = (blocks[0] - 0x4000) / scale;
417 delta = dc - prev_dc;
418 new_sign = GET_SIGN(delta);
419 delta = (delta ^ sign) - sign;
420 code = MAKE_CODE(delta);
421 encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
422 codebook = (code + (code & 1)) >> 1;
423 codebook = FFMIN(codebook, 3);
429 static void encode_acs(PutBitContext *pb, int16_t *blocks,
430 int blocks_per_slice,
431 int plane_size_factor,
432 const uint8_t *scan, const int16_t *qmat)
435 int run, level, run_cb, lev_cb;
436 int max_coeffs, abs_level;
438 max_coeffs = blocks_per_slice << 6;
439 run_cb = ff_prores_run_to_cb_index[4];
440 lev_cb = ff_prores_lev_to_cb_index[2];
443 for (i = 1; i < 64; i++) {
444 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
445 level = blocks[idx] / qmat[scan[i]];
447 abs_level = FFABS(level);
448 encode_vlc_codeword(pb, ff_prores_ac_codebook[run_cb], run);
449 encode_vlc_codeword(pb, ff_prores_ac_codebook[lev_cb],
451 put_sbits(pb, 1, GET_SIGN(level));
453 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
454 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
463 static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
464 const uint16_t *src, ptrdiff_t linesize,
465 int mbs_per_slice, int16_t *blocks,
466 int blocks_per_mb, int plane_size_factor,
469 int blocks_per_slice, saved_pos;
471 saved_pos = put_bits_count(pb);
472 blocks_per_slice = mbs_per_slice * blocks_per_mb;
474 encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
475 encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
476 ctx->scantable, qmat);
479 return (put_bits_count(pb) - saved_pos) >> 3;
482 static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
484 const int dbits = (abits == 8) ? 4 : 7;
485 const int dsize = 1 << dbits - 1;
486 int diff = cur - prev;
488 diff = av_mod_uintp2(diff, abits);
489 if (diff >= (1 << abits) - dsize)
491 if (diff < -dsize || diff > dsize || !diff) {
493 put_bits(pb, abits, diff);
496 put_bits(pb, dbits - 1, FFABS(diff) - 1);
497 put_bits(pb, 1, diff < 0);
501 static void put_alpha_run(PutBitContext *pb, int run)
506 put_bits(pb, 4, run);
508 put_bits(pb, 15, run);
514 // todo alpha quantisation for high quants
515 static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
516 int mbs_per_slice, uint16_t *blocks,
519 const int abits = ctx->alpha_bits;
520 const int mask = (1 << abits) - 1;
521 const int num_coeffs = mbs_per_slice * 256;
522 int saved_pos = put_bits_count(pb);
523 int prev = mask, cur;
528 put_alpha_diff(pb, cur, prev, abits);
533 put_alpha_run (pb, run);
534 put_alpha_diff(pb, cur, prev, abits);
540 } while (idx < num_coeffs);
542 put_alpha_run(pb, run);
544 return (put_bits_count(pb) - saved_pos) >> 3;
547 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
549 int sizes[4], int x, int y, int quant,
552 ProresContext *ctx = avctx->priv_data;
556 int slice_width_factor = av_log2(mbs_per_slice);
557 int num_cblocks, pwidth, line_add;
559 int plane_factor, is_chroma;
561 uint16_t *qmat_chroma;
563 if (ctx->pictures_per_frame == 1)
566 line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
568 if (ctx->force_quant) {
569 qmat = ctx->quants[0];
570 qmat_chroma = ctx->quants_chroma[0];
571 } else if (quant < MAX_STORED_Q) {
572 qmat = ctx->quants[quant];
573 qmat_chroma = ctx->quants_chroma[quant];
575 qmat = ctx->custom_q;
576 qmat_chroma = ctx->custom_q;
577 for (i = 0; i < 64; i++) {
578 qmat[i] = ctx->quant_mat[i] * quant;
579 qmat_chroma[i] = ctx->quant_chroma_mat[i] * quant;
583 for (i = 0; i < ctx->num_planes; i++) {
584 is_chroma = (i == 1 || i == 2);
585 plane_factor = slice_width_factor + 2;
587 plane_factor += ctx->chroma_factor - 3;
588 if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
592 pwidth = avctx->width;
597 pwidth = avctx->width >> 1;
600 linesize = pic->linesize[i] * ctx->pictures_per_frame;
601 src = (const uint16_t*)(pic->data[i] + yp * linesize +
602 line_add * pic->linesize[i]) + xp;
605 get_slice_data(ctx, src, linesize, xp, yp,
606 pwidth, avctx->height / ctx->pictures_per_frame,
607 ctx->blocks[0], ctx->emu_buf,
608 mbs_per_slice, num_cblocks, is_chroma);
609 if (!is_chroma) {/* luma quant */
610 sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
611 mbs_per_slice, ctx->blocks[0],
612 num_cblocks, plane_factor,
614 } else { /* chroma plane */
615 sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
616 mbs_per_slice, ctx->blocks[0],
617 num_cblocks, plane_factor,
621 get_alpha_data(ctx, src, linesize, xp, yp,
622 pwidth, avctx->height / ctx->pictures_per_frame,
623 ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
624 sizes[i] = encode_alpha_plane(ctx, pb, mbs_per_slice,
625 ctx->blocks[0], quant);
627 total_size += sizes[i];
628 if (put_bits_left(pb) < 0) {
629 av_log(avctx, AV_LOG_ERROR,
630 "Underestimated required buffer size.\n");
637 static inline int estimate_vlc(unsigned codebook, int val)
639 unsigned int rice_order, exp_order, switch_bits, switch_val;
642 /* number of prefix bits to switch between Rice and expGolomb */
643 switch_bits = (codebook & 3) + 1;
644 rice_order = codebook >> 5; /* rice code order */
645 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
647 switch_val = switch_bits << rice_order;
649 if (val >= switch_val) {
650 val -= switch_val - (1 << exp_order);
651 exponent = av_log2(val);
653 return exponent * 2 - exp_order + switch_bits + 1;
655 return (val >> rice_order) + rice_order + 1;
659 static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
663 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
666 prev_dc = (blocks[0] - 0x4000) / scale;
667 bits = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
671 *error += FFABS(blocks[0] - 0x4000) % scale;
673 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
674 dc = (blocks[0] - 0x4000) / scale;
675 *error += FFABS(blocks[0] - 0x4000) % scale;
676 delta = dc - prev_dc;
677 new_sign = GET_SIGN(delta);
678 delta = (delta ^ sign) - sign;
679 code = MAKE_CODE(delta);
680 bits += estimate_vlc(ff_prores_dc_codebook[codebook], code);
681 codebook = (code + (code & 1)) >> 1;
682 codebook = FFMIN(codebook, 3);
690 static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
691 int plane_size_factor,
692 const uint8_t *scan, const int16_t *qmat)
695 int run, level, run_cb, lev_cb;
696 int max_coeffs, abs_level;
699 max_coeffs = blocks_per_slice << 6;
700 run_cb = ff_prores_run_to_cb_index[4];
701 lev_cb = ff_prores_lev_to_cb_index[2];
704 for (i = 1; i < 64; i++) {
705 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
706 level = blocks[idx] / qmat[scan[i]];
707 *error += FFABS(blocks[idx]) % qmat[scan[i]];
709 abs_level = FFABS(level);
710 bits += estimate_vlc(ff_prores_ac_codebook[run_cb], run);
711 bits += estimate_vlc(ff_prores_ac_codebook[lev_cb],
714 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
715 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
726 static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
727 const uint16_t *src, ptrdiff_t linesize,
729 int blocks_per_mb, int plane_size_factor,
730 const int16_t *qmat, ProresThreadData *td)
732 int blocks_per_slice;
735 blocks_per_slice = mbs_per_slice * blocks_per_mb;
737 bits = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
738 bits += estimate_acs(error, td->blocks[plane], blocks_per_slice,
739 plane_size_factor, ctx->scantable, qmat);
741 return FFALIGN(bits, 8);
744 static int est_alpha_diff(int cur, int prev, int abits)
746 const int dbits = (abits == 8) ? 4 : 7;
747 const int dsize = 1 << dbits - 1;
748 int diff = cur - prev;
750 diff = av_mod_uintp2(diff, abits);
751 if (diff >= (1 << abits) - dsize)
753 if (diff < -dsize || diff > dsize || !diff)
759 static int estimate_alpha_plane(ProresContext *ctx,
760 const uint16_t *src, ptrdiff_t linesize,
761 int mbs_per_slice, int16_t *blocks)
763 const int abits = ctx->alpha_bits;
764 const int mask = (1 << abits) - 1;
765 const int num_coeffs = mbs_per_slice * 256;
766 int prev = mask, cur;
772 bits = est_alpha_diff(cur, prev, abits);
783 bits += est_alpha_diff(cur, prev, abits);
789 } while (idx < num_coeffs);
801 static int find_slice_quant(AVCodecContext *avctx,
802 int trellis_node, int x, int y, int mbs_per_slice,
803 ProresThreadData *td)
805 ProresContext *ctx = avctx->priv_data;
806 int i, q, pq, xp, yp;
808 int slice_width_factor = av_log2(mbs_per_slice);
809 int num_cblocks[MAX_PLANES], pwidth;
810 int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];
811 const int min_quant = ctx->profile_info->min_quant;
812 const int max_quant = ctx->profile_info->max_quant;
813 int error, bits, bits_limit;
814 int mbs, prev, cur, new_score;
815 int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
818 uint16_t *qmat_chroma;
819 int linesize[4], line_add;
822 if (ctx->pictures_per_frame == 1)
825 line_add = ctx->cur_picture_idx ^ !ctx->pic->top_field_first;
826 mbs = x + mbs_per_slice;
828 for (i = 0; i < ctx->num_planes; i++) {
829 is_chroma[i] = (i == 1 || i == 2);
830 plane_factor[i] = slice_width_factor + 2;
832 plane_factor[i] += ctx->chroma_factor - 3;
833 if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
837 pwidth = avctx->width;
842 pwidth = avctx->width >> 1;
845 linesize[i] = ctx->pic->linesize[i] * ctx->pictures_per_frame;
846 src = (const uint16_t *)(ctx->pic->data[i] + yp * linesize[i] +
847 line_add * ctx->pic->linesize[i]) + xp;
850 get_slice_data(ctx, src, linesize[i], xp, yp,
851 pwidth, avctx->height / ctx->pictures_per_frame,
852 td->blocks[i], td->emu_buf,
853 mbs_per_slice, num_cblocks[i], is_chroma[i]);
855 get_alpha_data(ctx, src, linesize[i], xp, yp,
856 pwidth, avctx->height / ctx->pictures_per_frame,
857 td->blocks[i], mbs_per_slice, ctx->alpha_bits);
861 for (q = min_quant; q < max_quant + 2; q++) {
862 td->nodes[trellis_node + q].prev_node = -1;
863 td->nodes[trellis_node + q].quant = q;
867 alpha_bits = estimate_alpha_plane(ctx, src, linesize[3],
868 mbs_per_slice, td->blocks[3]);
869 // todo: maybe perform coarser quantising to fit into frame size when needed
870 for (q = min_quant; q <= max_quant; q++) {
873 bits += estimate_slice_plane(ctx, &error, 0,
876 num_cblocks[0], plane_factor[0],
877 ctx->quants[q], td); /* estimate luma plane */
878 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
879 bits += estimate_slice_plane(ctx, &error, i,
882 num_cblocks[i], plane_factor[i],
883 ctx->quants_chroma[q], td);
885 if (bits > 65000 * 8)
888 slice_bits[q] = bits;
889 slice_score[q] = error;
891 if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
892 slice_bits[max_quant + 1] = slice_bits[max_quant];
893 slice_score[max_quant + 1] = slice_score[max_quant] + 1;
894 overquant = max_quant;
896 for (q = max_quant + 1; q < 128; q++) {
899 if (q < MAX_STORED_Q) {
900 qmat = ctx->quants[q];
901 qmat_chroma = ctx->quants_chroma[q];
904 qmat_chroma = td->custom_q;
905 for (i = 0; i < 64; i++) {
906 qmat[i] = ctx->quant_mat[i] * q;
907 qmat_chroma[i] = ctx->quant_chroma_mat[i] * q;
910 bits += estimate_slice_plane(ctx, &error, 0,
913 num_cblocks[0], plane_factor[0],
914 qmat, td);/* estimate luma plane */
915 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
916 bits += estimate_slice_plane(ctx, &error, i,
919 num_cblocks[i], plane_factor[i],
922 if (bits <= ctx->bits_per_mb * mbs_per_slice)
926 slice_bits[max_quant + 1] = bits;
927 slice_score[max_quant + 1] = error;
930 td->nodes[trellis_node + max_quant + 1].quant = overquant;
932 bits_limit = mbs * ctx->bits_per_mb;
933 for (pq = min_quant; pq < max_quant + 2; pq++) {
934 prev = trellis_node - TRELLIS_WIDTH + pq;
936 for (q = min_quant; q < max_quant + 2; q++) {
937 cur = trellis_node + q;
939 bits = td->nodes[prev].bits + slice_bits[q];
940 error = slice_score[q];
941 if (bits > bits_limit)
944 if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
945 new_score = td->nodes[prev].score + error;
947 new_score = SCORE_LIMIT;
948 if (td->nodes[cur].prev_node == -1 ||
949 td->nodes[cur].score >= new_score) {
951 td->nodes[cur].bits = bits;
952 td->nodes[cur].score = new_score;
953 td->nodes[cur].prev_node = prev;
958 error = td->nodes[trellis_node + min_quant].score;
959 pq = trellis_node + min_quant;
960 for (q = min_quant + 1; q < max_quant + 2; q++) {
961 if (td->nodes[trellis_node + q].score <= error) {
962 error = td->nodes[trellis_node + q].score;
963 pq = trellis_node + q;
970 static int find_quant_thread(AVCodecContext *avctx, void *arg,
971 int jobnr, int threadnr)
973 ProresContext *ctx = avctx->priv_data;
974 ProresThreadData *td = ctx->tdata + threadnr;
975 int mbs_per_slice = ctx->mbs_per_slice;
976 int x, y = jobnr, mb, q = 0;
978 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
979 while (ctx->mb_width - x < mbs_per_slice)
981 q = find_slice_quant(avctx,
982 (mb + 1) * TRELLIS_WIDTH, x, y,
986 for (x = ctx->slices_width - 1; x >= 0; x--) {
987 ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
988 q = td->nodes[q].prev_node;
994 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
995 const AVFrame *pic, int *got_packet)
997 ProresContext *ctx = avctx->priv_data;
998 uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
999 uint8_t *picture_size_pos;
1001 int x, y, i, mb, q = 0;
1002 int sizes[4] = { 0 };
1003 int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
1004 int frame_size, picture_size, slice_size;
1006 int max_slice_size = (ctx->frame_size_upper_bound - 200) / (ctx->pictures_per_frame * ctx->slices_per_picture + 1);
1007 uint8_t frame_flags;
1010 pkt_size = ctx->frame_size_upper_bound;
1012 if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
1015 orig_buf = pkt->data;
1018 orig_buf += 4; // frame size
1019 bytestream_put_be32 (&orig_buf, FRAME_ID); // frame container ID
1024 buf += 2; // frame header size will be stored here
1025 bytestream_put_be16 (&buf, 0); // version 1
1026 bytestream_put_buffer(&buf, ctx->vendor, 4);
1027 bytestream_put_be16 (&buf, avctx->width);
1028 bytestream_put_be16 (&buf, avctx->height);
1030 frame_flags = ctx->chroma_factor << 6;
1031 if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
1032 frame_flags |= pic->top_field_first ? 0x04 : 0x08;
1033 bytestream_put_byte (&buf, frame_flags);
1035 bytestream_put_byte (&buf, 0); // reserved
1036 bytestream_put_byte (&buf, pic->color_primaries);
1037 bytestream_put_byte (&buf, pic->color_trc);
1038 bytestream_put_byte (&buf, pic->colorspace);
1039 bytestream_put_byte (&buf, 0x40 | (ctx->alpha_bits >> 3));
1040 bytestream_put_byte (&buf, 0); // reserved
1041 if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
1042 bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present
1043 // luma quantisation matrix
1044 for (i = 0; i < 64; i++)
1045 bytestream_put_byte(&buf, ctx->quant_mat[i]);
1046 // chroma quantisation matrix
1047 for (i = 0; i < 64; i++)
1048 bytestream_put_byte(&buf, ctx->quant_mat[i]);
1050 bytestream_put_byte (&buf, 0x00); // matrix flags - default matrices are used
1052 bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
1054 for (ctx->cur_picture_idx = 0;
1055 ctx->cur_picture_idx < ctx->pictures_per_frame;
1056 ctx->cur_picture_idx++) {
1058 picture_size_pos = buf + 1;
1059 bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
1060 buf += 4; // picture data size will be stored here
1061 bytestream_put_be16 (&buf, ctx->slices_per_picture);
1062 bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
1064 // seek table - will be filled during slice encoding
1066 buf += ctx->slices_per_picture * 2;
1069 if (!ctx->force_quant) {
1070 ret = avctx->execute2(avctx, find_quant_thread, (void*)pic, NULL,
1076 for (y = 0; y < ctx->mb_height; y++) {
1077 int mbs_per_slice = ctx->mbs_per_slice;
1078 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
1079 q = ctx->force_quant ? ctx->force_quant
1080 : ctx->slice_q[mb + y * ctx->slices_width];
1082 while (ctx->mb_width - x < mbs_per_slice)
1083 mbs_per_slice >>= 1;
1085 bytestream_put_byte(&buf, slice_hdr_size << 3);
1087 buf += slice_hdr_size - 1;
1088 if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
1089 uint8_t *start = pkt->data;
1090 // Recompute new size according to max_slice_size
1092 int delta = 200 + (ctx->pictures_per_frame *
1093 ctx->slices_per_picture + 1) *
1094 max_slice_size - pkt_size;
1096 delta = FFMAX(delta, 2 * max_slice_size);
1097 ctx->frame_size_upper_bound += delta;
1100 avpriv_request_sample(avctx,
1101 "Packet too small: is %i,"
1102 " needs %i (slice: %i). "
1103 "Correct allocation",
1104 pkt_size, delta, max_slice_size);
1108 ret = av_grow_packet(pkt, delta);
1114 orig_buf = pkt->data + (orig_buf - start);
1115 buf = pkt->data + (buf - start);
1116 picture_size_pos = pkt->data + (picture_size_pos - start);
1117 slice_sizes = pkt->data + (slice_sizes - start);
1118 slice_hdr = pkt->data + (slice_hdr - start);
1119 tmp = pkt->data + (tmp - start);
1121 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)));
1122 ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
1127 bytestream_put_byte(&slice_hdr, q);
1128 slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
1129 for (i = 0; i < ctx->num_planes - 1; i++) {
1130 bytestream_put_be16(&slice_hdr, sizes[i]);
1131 slice_size += sizes[i];
1133 bytestream_put_be16(&slice_sizes, slice_size);
1134 buf += slice_size - slice_hdr_size;
1135 if (max_slice_size < slice_size)
1136 max_slice_size = slice_size;
1140 picture_size = buf - (picture_size_pos - 1);
1141 bytestream_put_be32(&picture_size_pos, picture_size);
1145 frame_size = buf - orig_buf;
1146 bytestream_put_be32(&orig_buf, frame_size);
1148 pkt->size = frame_size;
1149 pkt->flags |= AV_PKT_FLAG_KEY;
1155 static av_cold int encode_close(AVCodecContext *avctx)
1157 ProresContext *ctx = avctx->priv_data;
1161 for (i = 0; i < avctx->thread_count; i++)
1162 av_freep(&ctx->tdata[i].nodes);
1164 av_freep(&ctx->tdata);
1165 av_freep(&ctx->slice_q);
1170 static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src,
1171 ptrdiff_t linesize, int16_t *block)
1174 const uint16_t *tsrc = src;
1176 for (y = 0; y < 8; y++) {
1177 for (x = 0; x < 8; x++)
1178 block[y * 8 + x] = tsrc[x];
1179 tsrc += linesize >> 1;
1184 static av_cold int encode_init(AVCodecContext *avctx)
1186 ProresContext *ctx = avctx->priv_data;
1189 int min_quant, max_quant;
1190 int interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
1192 avctx->bits_per_raw_sample = 10;
1193 #if FF_API_CODED_FRAME
1194 FF_DISABLE_DEPRECATION_WARNINGS
1195 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
1196 avctx->coded_frame->key_frame = 1;
1197 FF_ENABLE_DEPRECATION_WARNINGS
1200 ctx->fdct = prores_fdct;
1201 ctx->scantable = interlaced ? ff_prores_interlaced_scan
1202 : ff_prores_progressive_scan;
1203 ff_fdctdsp_init(&ctx->fdsp, avctx);
1205 mps = ctx->mbs_per_slice;
1206 if (mps & (mps - 1)) {
1207 av_log(avctx, AV_LOG_ERROR,
1208 "there should be an integer power of two MBs per slice\n");
1209 return AVERROR(EINVAL);
1211 if (ctx->profile == PRORES_PROFILE_AUTO) {
1212 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1213 ctx->profile = (desc->flags & AV_PIX_FMT_FLAG_ALPHA ||
1214 !(desc->log2_chroma_w + desc->log2_chroma_h))
1215 ? PRORES_PROFILE_4444 : PRORES_PROFILE_HQ;
1216 av_log(avctx, AV_LOG_INFO, "Autoselected %s. It can be overridden "
1217 "through -profile option.\n", ctx->profile == PRORES_PROFILE_4444
1218 ? "4:4:4:4 profile because of the used input colorspace"
1219 : "HQ profile to keep best quality");
1221 if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
1222 if (ctx->profile != PRORES_PROFILE_4444 &&
1223 ctx->profile != PRORES_PROFILE_4444XQ) {
1224 // force alpha and warn
1225 av_log(avctx, AV_LOG_WARNING, "Profile selected will not "
1226 "encode alpha. Override with -profile if needed.\n");
1227 ctx->alpha_bits = 0;
1229 if (ctx->alpha_bits & 7) {
1230 av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
1231 return AVERROR(EINVAL);
1233 avctx->bits_per_coded_sample = 32;
1235 ctx->alpha_bits = 0;
1238 ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
1241 ctx->profile_info = prores_profile_info + ctx->profile;
1242 ctx->num_planes = 3 + !!ctx->alpha_bits;
1244 ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
1247 ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
1249 ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
1251 ctx->slices_width = ctx->mb_width / mps;
1252 ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
1253 ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
1254 ctx->pictures_per_frame = 1 + interlaced;
1256 if (ctx->quant_sel == -1) {
1257 ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
1258 ctx->quant_chroma_mat = prores_quant_matrices[ctx->profile_info->quant_chroma];
1260 ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
1261 ctx->quant_chroma_mat = prores_quant_matrices[ctx->quant_sel];
1264 if (strlen(ctx->vendor) != 4) {
1265 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
1266 return AVERROR_INVALIDDATA;
1269 ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
1270 if (!ctx->force_quant) {
1271 if (!ctx->bits_per_mb) {
1272 for (i = 0; i < NUM_MB_LIMITS - 1; i++)
1273 if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
1274 ctx->pictures_per_frame)
1276 ctx->bits_per_mb = ctx->profile_info->br_tab[i];
1277 if (ctx->alpha_bits)
1278 ctx->bits_per_mb *= 20;
1279 } else if (ctx->bits_per_mb < 128) {
1280 av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
1281 return AVERROR_INVALIDDATA;
1284 min_quant = ctx->profile_info->min_quant;
1285 max_quant = ctx->profile_info->max_quant;
1286 for (i = min_quant; i < MAX_STORED_Q; i++) {
1287 for (j = 0; j < 64; j++) {
1288 ctx->quants[i][j] = ctx->quant_mat[j] * i;
1289 ctx->quants_chroma[i][j] = ctx->quant_chroma_mat[j] * i;
1293 ctx->slice_q = av_malloc(ctx->slices_per_picture * sizeof(*ctx->slice_q));
1294 if (!ctx->slice_q) {
1295 encode_close(avctx);
1296 return AVERROR(ENOMEM);
1299 ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
1301 encode_close(avctx);
1302 return AVERROR(ENOMEM);
1305 for (j = 0; j < avctx->thread_count; j++) {
1306 ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
1308 * sizeof(*ctx->tdata->nodes));
1309 if (!ctx->tdata[j].nodes) {
1310 encode_close(avctx);
1311 return AVERROR(ENOMEM);
1313 for (i = min_quant; i < max_quant + 2; i++) {
1314 ctx->tdata[j].nodes[i].prev_node = -1;
1315 ctx->tdata[j].nodes[i].bits = 0;
1316 ctx->tdata[j].nodes[i].score = 0;
1323 if (ctx->force_quant > 64) {
1324 av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
1325 return AVERROR_INVALIDDATA;
1328 for (j = 0; j < 64; j++) {
1329 ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
1330 ctx->quants_chroma[0][j] = ctx->quant_chroma_mat[j] * ctx->force_quant;
1331 ls += av_log2((1 << 11) / ctx->quants[0][j]) * 2 + 1;
1332 ls_chroma += av_log2((1 << 11) / ctx->quants_chroma[0][j]) * 2 + 1;
1335 ctx->bits_per_mb = ls * 4 + ls_chroma * 4;
1336 if (ctx->chroma_factor == CFACTOR_Y444)
1337 ctx->bits_per_mb += ls_chroma * 4;
1340 ctx->frame_size_upper_bound = (ctx->pictures_per_frame *
1341 ctx->slices_per_picture + 1) *
1342 (2 + 2 * ctx->num_planes +
1343 (mps * ctx->bits_per_mb) / 8)
1346 if (ctx->alpha_bits) {
1347 // The alpha plane is run-coded and might exceed the bit budget.
1348 ctx->frame_size_upper_bound += (ctx->pictures_per_frame *
1349 ctx->slices_per_picture + 1) *
1350 /* num pixels per slice */ (ctx->mbs_per_slice * 256 *
1351 /* bits per pixel */ (1 + ctx->alpha_bits + 1) + 7 >> 3);
1354 avctx->codec_tag = ctx->profile_info->tag;
1356 av_log(avctx, AV_LOG_DEBUG,
1357 "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
1358 ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
1359 interlaced ? "yes" : "no", ctx->bits_per_mb);
1360 av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
1361 ctx->frame_size_upper_bound);
1366 #define OFFSET(x) offsetof(ProresContext, x)
1367 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1369 static const AVOption options[] = {
1370 { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
1371 AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
1372 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
1373 { .i64 = PRORES_PROFILE_AUTO },
1374 PRORES_PROFILE_AUTO, PRORES_PROFILE_4444XQ, VE, "profile" },
1375 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_AUTO },
1376 0, 0, VE, "profile" },
1377 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
1378 0, 0, VE, "profile" },
1379 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
1380 0, 0, VE, "profile" },
1381 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
1382 0, 0, VE, "profile" },
1383 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
1384 0, 0, VE, "profile" },
1385 { "4444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
1386 0, 0, VE, "profile" },
1387 { "4444xq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444XQ },
1388 0, 0, VE, "profile" },
1389 { "vendor", "vendor ID", OFFSET(vendor),
1390 AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE },
1391 { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
1392 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
1393 { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
1394 { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, "quant_mat" },
1395 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
1396 0, 0, VE, "quant_mat" },
1397 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
1398 0, 0, VE, "quant_mat" },
1399 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
1400 0, 0, VE, "quant_mat" },
1401 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
1402 0, 0, VE, "quant_mat" },
1403 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
1404 0, 0, VE, "quant_mat" },
1405 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
1406 0, 0, VE, "quant_mat" },
1407 { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
1408 { .i64 = 16 }, 0, 16, VE },
1412 static const AVClass proresenc_class = {
1413 .class_name = "ProRes encoder",
1414 .item_name = av_default_item_name,
1416 .version = LIBAVUTIL_VERSION_INT,
1419 AVCodec ff_prores_ks_encoder = {
1420 .name = "prores_ks",
1421 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
1422 .type = AVMEDIA_TYPE_VIDEO,
1423 .id = AV_CODEC_ID_PRORES,
1424 .priv_data_size = sizeof(ProresContext),
1425 .init = encode_init,
1426 .close = encode_close,
1427 .encode2 = encode_frame,
1428 .capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
1429 .pix_fmts = (const enum AVPixelFormat[]) {
1430 AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
1431 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
1433 .priv_class = &proresenc_class,