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 int16_t custom_chroma_q[64];
226 struct TrellisNode *nodes;
229 typedef struct ProresContext {
231 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
232 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
233 int16_t quants[MAX_STORED_Q][64];
234 int16_t quants_chroma[MAX_STORED_Q][64];
235 int16_t custom_q[64];
236 int16_t custom_chroma_q[64];
237 const uint8_t *quant_mat;
238 const uint8_t *quant_chroma_mat;
239 const uint8_t *scantable;
241 void (*fdct)(FDCTDSPContext *fdsp, const uint16_t *src,
242 ptrdiff_t linesize, int16_t *block);
246 int mb_width, mb_height;
248 int num_chroma_blocks, chroma_factor;
250 int slices_per_picture;
251 int pictures_per_frame; // 1 for progressive, 2 for interlaced
262 int frame_size_upper_bound;
265 const struct prores_profile *profile_info;
269 ProresThreadData *tdata;
272 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
273 ptrdiff_t linesize, int x, int y, int w, int h,
274 int16_t *blocks, uint16_t *emu_buf,
275 int mbs_per_slice, int blocks_per_mb, int is_chroma)
277 const uint16_t *esrc;
278 const int mb_width = 4 * blocks_per_mb;
282 for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
284 memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
288 if (x + mb_width <= w && y + 16 <= h) {
290 elinesize = linesize;
295 elinesize = 16 * sizeof(*emu_buf);
297 bw = FFMIN(w - x, mb_width);
298 bh = FFMIN(h - y, 16);
300 for (j = 0; j < bh; j++) {
301 memcpy(emu_buf + j * 16,
302 (const uint8_t*)src + j * linesize,
304 pix = emu_buf[j * 16 + bw - 1];
305 for (k = bw; k < mb_width; k++)
306 emu_buf[j * 16 + k] = pix;
309 memcpy(emu_buf + j * 16,
310 emu_buf + (bh - 1) * 16,
311 mb_width * sizeof(*emu_buf));
314 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
316 if (blocks_per_mb > 2) {
317 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
320 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
322 if (blocks_per_mb > 2) {
323 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
327 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
329 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
331 if (blocks_per_mb > 2) {
332 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
334 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
343 static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
344 ptrdiff_t linesize, int x, int y, int w, int h,
345 int16_t *blocks, int mbs_per_slice, int abits)
347 const int slice_width = 16 * mbs_per_slice;
348 int i, j, copy_w, copy_h;
350 copy_w = FFMIN(w - x, slice_width);
351 copy_h = FFMIN(h - y, 16);
352 for (i = 0; i < copy_h; i++) {
353 memcpy(blocks, src, copy_w * sizeof(*src));
355 for (j = 0; j < copy_w; j++)
358 for (j = 0; j < copy_w; j++)
359 blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
360 for (j = copy_w; j < slice_width; j++)
361 blocks[j] = blocks[copy_w - 1];
362 blocks += slice_width;
363 src += linesize >> 1;
365 for (; i < 16; i++) {
366 memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
367 blocks += slice_width;
372 * Write an unsigned rice/exp golomb codeword.
374 static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
376 unsigned int rice_order, exp_order, switch_bits, switch_val;
379 /* number of prefix bits to switch between Rice and expGolomb */
380 switch_bits = (codebook & 3) + 1;
381 rice_order = codebook >> 5; /* rice code order */
382 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
384 switch_val = switch_bits << rice_order;
386 if (val >= switch_val) {
387 val -= switch_val - (1 << exp_order);
388 exponent = av_log2(val);
390 put_bits(pb, exponent - exp_order + switch_bits, 0);
391 put_bits(pb, exponent + 1, val);
393 exponent = val >> rice_order;
396 put_bits(pb, exponent, 0);
399 put_sbits(pb, rice_order, val);
403 #define GET_SIGN(x) ((x) >> 31)
404 #define MAKE_CODE(x) ((((x)) * 2) ^ GET_SIGN(x))
406 static void encode_dcs(PutBitContext *pb, int16_t *blocks,
407 int blocks_per_slice, int scale)
410 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
412 prev_dc = (blocks[0] - 0x4000) / scale;
413 encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
418 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
419 dc = (blocks[0] - 0x4000) / scale;
420 delta = dc - prev_dc;
421 new_sign = GET_SIGN(delta);
422 delta = (delta ^ sign) - sign;
423 code = MAKE_CODE(delta);
424 encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
425 codebook = (code + (code & 1)) >> 1;
426 codebook = FFMIN(codebook, 3);
432 static void encode_acs(PutBitContext *pb, int16_t *blocks,
433 int blocks_per_slice,
434 int plane_size_factor,
435 const uint8_t *scan, const int16_t *qmat)
438 int run, level, run_cb, lev_cb;
439 int max_coeffs, abs_level;
441 max_coeffs = blocks_per_slice << 6;
442 run_cb = ff_prores_run_to_cb_index[4];
443 lev_cb = ff_prores_lev_to_cb_index[2];
446 for (i = 1; i < 64; i++) {
447 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
448 level = blocks[idx] / qmat[scan[i]];
450 abs_level = FFABS(level);
451 encode_vlc_codeword(pb, ff_prores_ac_codebook[run_cb], run);
452 encode_vlc_codeword(pb, ff_prores_ac_codebook[lev_cb],
454 put_sbits(pb, 1, GET_SIGN(level));
456 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
457 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
466 static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
467 const uint16_t *src, ptrdiff_t linesize,
468 int mbs_per_slice, int16_t *blocks,
469 int blocks_per_mb, int plane_size_factor,
472 int blocks_per_slice, saved_pos;
474 saved_pos = put_bits_count(pb);
475 blocks_per_slice = mbs_per_slice * blocks_per_mb;
477 encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
478 encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
479 ctx->scantable, qmat);
482 return (put_bits_count(pb) - saved_pos) >> 3;
485 static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
487 const int dbits = (abits == 8) ? 4 : 7;
488 const int dsize = 1 << dbits - 1;
489 int diff = cur - prev;
491 diff = av_mod_uintp2(diff, abits);
492 if (diff >= (1 << abits) - dsize)
494 if (diff < -dsize || diff > dsize || !diff) {
496 put_bits(pb, abits, diff);
499 put_bits(pb, dbits - 1, FFABS(diff) - 1);
500 put_bits(pb, 1, diff < 0);
504 static void put_alpha_run(PutBitContext *pb, int run)
509 put_bits(pb, 4, run);
511 put_bits(pb, 15, run);
517 // todo alpha quantisation for high quants
518 static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
519 int mbs_per_slice, uint16_t *blocks,
522 const int abits = ctx->alpha_bits;
523 const int mask = (1 << abits) - 1;
524 const int num_coeffs = mbs_per_slice * 256;
525 int saved_pos = put_bits_count(pb);
526 int prev = mask, cur;
531 put_alpha_diff(pb, cur, prev, abits);
536 put_alpha_run (pb, run);
537 put_alpha_diff(pb, cur, prev, abits);
543 } while (idx < num_coeffs);
545 put_alpha_run(pb, run);
547 return (put_bits_count(pb) - saved_pos) >> 3;
550 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
552 int sizes[4], int x, int y, int quant,
555 ProresContext *ctx = avctx->priv_data;
559 int slice_width_factor = av_log2(mbs_per_slice);
560 int num_cblocks, pwidth, line_add;
562 int plane_factor, is_chroma;
564 uint16_t *qmat_chroma;
566 if (ctx->pictures_per_frame == 1)
569 line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
571 if (ctx->force_quant) {
572 qmat = ctx->quants[0];
573 qmat_chroma = ctx->quants_chroma[0];
574 } else if (quant < MAX_STORED_Q) {
575 qmat = ctx->quants[quant];
576 qmat_chroma = ctx->quants_chroma[quant];
578 qmat = ctx->custom_q;
579 qmat_chroma = ctx->custom_chroma_q;
580 for (i = 0; i < 64; i++) {
581 qmat[i] = ctx->quant_mat[i] * quant;
582 qmat_chroma[i] = ctx->quant_chroma_mat[i] * quant;
586 for (i = 0; i < ctx->num_planes; i++) {
587 is_chroma = (i == 1 || i == 2);
588 plane_factor = slice_width_factor + 2;
590 plane_factor += ctx->chroma_factor - 3;
591 if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
595 pwidth = avctx->width;
600 pwidth = avctx->width >> 1;
603 linesize = pic->linesize[i] * ctx->pictures_per_frame;
604 src = (const uint16_t*)(pic->data[i] + yp * linesize +
605 line_add * pic->linesize[i]) + xp;
608 get_slice_data(ctx, src, linesize, xp, yp,
609 pwidth, avctx->height / ctx->pictures_per_frame,
610 ctx->blocks[0], ctx->emu_buf,
611 mbs_per_slice, num_cblocks, is_chroma);
612 if (!is_chroma) {/* luma quant */
613 sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
614 mbs_per_slice, ctx->blocks[0],
615 num_cblocks, plane_factor,
617 } else { /* chroma plane */
618 sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
619 mbs_per_slice, ctx->blocks[0],
620 num_cblocks, plane_factor,
624 get_alpha_data(ctx, src, linesize, xp, yp,
625 pwidth, avctx->height / ctx->pictures_per_frame,
626 ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
627 sizes[i] = encode_alpha_plane(ctx, pb, mbs_per_slice,
628 ctx->blocks[0], quant);
630 total_size += sizes[i];
631 if (put_bits_left(pb) < 0) {
632 av_log(avctx, AV_LOG_ERROR,
633 "Underestimated required buffer size.\n");
640 static inline int estimate_vlc(unsigned codebook, int val)
642 unsigned int rice_order, exp_order, switch_bits, switch_val;
645 /* number of prefix bits to switch between Rice and expGolomb */
646 switch_bits = (codebook & 3) + 1;
647 rice_order = codebook >> 5; /* rice code order */
648 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
650 switch_val = switch_bits << rice_order;
652 if (val >= switch_val) {
653 val -= switch_val - (1 << exp_order);
654 exponent = av_log2(val);
656 return exponent * 2 - exp_order + switch_bits + 1;
658 return (val >> rice_order) + rice_order + 1;
662 static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
666 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
669 prev_dc = (blocks[0] - 0x4000) / scale;
670 bits = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
674 *error += FFABS(blocks[0] - 0x4000) % scale;
676 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
677 dc = (blocks[0] - 0x4000) / scale;
678 *error += FFABS(blocks[0] - 0x4000) % scale;
679 delta = dc - prev_dc;
680 new_sign = GET_SIGN(delta);
681 delta = (delta ^ sign) - sign;
682 code = MAKE_CODE(delta);
683 bits += estimate_vlc(ff_prores_dc_codebook[codebook], code);
684 codebook = (code + (code & 1)) >> 1;
685 codebook = FFMIN(codebook, 3);
693 static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
694 int plane_size_factor,
695 const uint8_t *scan, const int16_t *qmat)
698 int run, level, run_cb, lev_cb;
699 int max_coeffs, abs_level;
702 max_coeffs = blocks_per_slice << 6;
703 run_cb = ff_prores_run_to_cb_index[4];
704 lev_cb = ff_prores_lev_to_cb_index[2];
707 for (i = 1; i < 64; i++) {
708 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
709 level = blocks[idx] / qmat[scan[i]];
710 *error += FFABS(blocks[idx]) % qmat[scan[i]];
712 abs_level = FFABS(level);
713 bits += estimate_vlc(ff_prores_ac_codebook[run_cb], run);
714 bits += estimate_vlc(ff_prores_ac_codebook[lev_cb],
717 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
718 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
729 static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
730 const uint16_t *src, ptrdiff_t linesize,
732 int blocks_per_mb, int plane_size_factor,
733 const int16_t *qmat, ProresThreadData *td)
735 int blocks_per_slice;
738 blocks_per_slice = mbs_per_slice * blocks_per_mb;
740 bits = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
741 bits += estimate_acs(error, td->blocks[plane], blocks_per_slice,
742 plane_size_factor, ctx->scantable, qmat);
744 return FFALIGN(bits, 8);
747 static int est_alpha_diff(int cur, int prev, int abits)
749 const int dbits = (abits == 8) ? 4 : 7;
750 const int dsize = 1 << dbits - 1;
751 int diff = cur - prev;
753 diff = av_mod_uintp2(diff, abits);
754 if (diff >= (1 << abits) - dsize)
756 if (diff < -dsize || diff > dsize || !diff)
762 static int estimate_alpha_plane(ProresContext *ctx,
763 const uint16_t *src, ptrdiff_t linesize,
764 int mbs_per_slice, int16_t *blocks)
766 const int abits = ctx->alpha_bits;
767 const int mask = (1 << abits) - 1;
768 const int num_coeffs = mbs_per_slice * 256;
769 int prev = mask, cur;
775 bits = est_alpha_diff(cur, prev, abits);
786 bits += est_alpha_diff(cur, prev, abits);
792 } while (idx < num_coeffs);
804 static int find_slice_quant(AVCodecContext *avctx,
805 int trellis_node, int x, int y, int mbs_per_slice,
806 ProresThreadData *td)
808 ProresContext *ctx = avctx->priv_data;
809 int i, q, pq, xp, yp;
811 int slice_width_factor = av_log2(mbs_per_slice);
812 int num_cblocks[MAX_PLANES], pwidth;
813 int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];
814 const int min_quant = ctx->profile_info->min_quant;
815 const int max_quant = ctx->profile_info->max_quant;
816 int error, bits, bits_limit;
817 int mbs, prev, cur, new_score;
818 int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
821 uint16_t *qmat_chroma;
822 int linesize[4], line_add;
825 if (ctx->pictures_per_frame == 1)
828 line_add = ctx->cur_picture_idx ^ !ctx->pic->top_field_first;
829 mbs = x + mbs_per_slice;
831 for (i = 0; i < ctx->num_planes; i++) {
832 is_chroma[i] = (i == 1 || i == 2);
833 plane_factor[i] = slice_width_factor + 2;
835 plane_factor[i] += ctx->chroma_factor - 3;
836 if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
840 pwidth = avctx->width;
845 pwidth = avctx->width >> 1;
848 linesize[i] = ctx->pic->linesize[i] * ctx->pictures_per_frame;
849 src = (const uint16_t *)(ctx->pic->data[i] + yp * linesize[i] +
850 line_add * ctx->pic->linesize[i]) + xp;
853 get_slice_data(ctx, src, linesize[i], xp, yp,
854 pwidth, avctx->height / ctx->pictures_per_frame,
855 td->blocks[i], td->emu_buf,
856 mbs_per_slice, num_cblocks[i], is_chroma[i]);
858 get_alpha_data(ctx, src, linesize[i], xp, yp,
859 pwidth, avctx->height / ctx->pictures_per_frame,
860 td->blocks[i], mbs_per_slice, ctx->alpha_bits);
864 for (q = min_quant; q < max_quant + 2; q++) {
865 td->nodes[trellis_node + q].prev_node = -1;
866 td->nodes[trellis_node + q].quant = q;
870 alpha_bits = estimate_alpha_plane(ctx, src, linesize[3],
871 mbs_per_slice, td->blocks[3]);
872 // todo: maybe perform coarser quantising to fit into frame size when needed
873 for (q = min_quant; q <= max_quant; q++) {
876 bits += estimate_slice_plane(ctx, &error, 0,
879 num_cblocks[0], plane_factor[0],
880 ctx->quants[q], td); /* estimate luma plane */
881 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
882 bits += estimate_slice_plane(ctx, &error, i,
885 num_cblocks[i], plane_factor[i],
886 ctx->quants_chroma[q], td);
888 if (bits > 65000 * 8)
891 slice_bits[q] = bits;
892 slice_score[q] = error;
894 if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
895 slice_bits[max_quant + 1] = slice_bits[max_quant];
896 slice_score[max_quant + 1] = slice_score[max_quant] + 1;
897 overquant = max_quant;
899 for (q = max_quant + 1; q < 128; q++) {
902 if (q < MAX_STORED_Q) {
903 qmat = ctx->quants[q];
904 qmat_chroma = ctx->quants_chroma[q];
907 qmat_chroma = td->custom_chroma_q;
908 for (i = 0; i < 64; i++) {
909 qmat[i] = ctx->quant_mat[i] * q;
910 qmat_chroma[i] = ctx->quant_chroma_mat[i] * q;
913 bits += estimate_slice_plane(ctx, &error, 0,
916 num_cblocks[0], plane_factor[0],
917 qmat, td);/* estimate luma plane */
918 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
919 bits += estimate_slice_plane(ctx, &error, i,
922 num_cblocks[i], plane_factor[i],
925 if (bits <= ctx->bits_per_mb * mbs_per_slice)
929 slice_bits[max_quant + 1] = bits;
930 slice_score[max_quant + 1] = error;
933 td->nodes[trellis_node + max_quant + 1].quant = overquant;
935 bits_limit = mbs * ctx->bits_per_mb;
936 for (pq = min_quant; pq < max_quant + 2; pq++) {
937 prev = trellis_node - TRELLIS_WIDTH + pq;
939 for (q = min_quant; q < max_quant + 2; q++) {
940 cur = trellis_node + q;
942 bits = td->nodes[prev].bits + slice_bits[q];
943 error = slice_score[q];
944 if (bits > bits_limit)
947 if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
948 new_score = td->nodes[prev].score + error;
950 new_score = SCORE_LIMIT;
951 if (td->nodes[cur].prev_node == -1 ||
952 td->nodes[cur].score >= new_score) {
954 td->nodes[cur].bits = bits;
955 td->nodes[cur].score = new_score;
956 td->nodes[cur].prev_node = prev;
961 error = td->nodes[trellis_node + min_quant].score;
962 pq = trellis_node + min_quant;
963 for (q = min_quant + 1; q < max_quant + 2; q++) {
964 if (td->nodes[trellis_node + q].score <= error) {
965 error = td->nodes[trellis_node + q].score;
966 pq = trellis_node + q;
973 static int find_quant_thread(AVCodecContext *avctx, void *arg,
974 int jobnr, int threadnr)
976 ProresContext *ctx = avctx->priv_data;
977 ProresThreadData *td = ctx->tdata + threadnr;
978 int mbs_per_slice = ctx->mbs_per_slice;
979 int x, y = jobnr, mb, q = 0;
981 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
982 while (ctx->mb_width - x < mbs_per_slice)
984 q = find_slice_quant(avctx,
985 (mb + 1) * TRELLIS_WIDTH, x, y,
989 for (x = ctx->slices_width - 1; x >= 0; x--) {
990 ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
991 q = td->nodes[q].prev_node;
997 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
998 const AVFrame *pic, int *got_packet)
1000 ProresContext *ctx = avctx->priv_data;
1001 uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
1002 uint8_t *picture_size_pos;
1004 int x, y, i, mb, q = 0;
1005 int sizes[4] = { 0 };
1006 int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
1007 int frame_size, picture_size, slice_size;
1009 int max_slice_size = (ctx->frame_size_upper_bound - 200) / (ctx->pictures_per_frame * ctx->slices_per_picture + 1);
1010 uint8_t frame_flags;
1013 pkt_size = ctx->frame_size_upper_bound;
1015 if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
1018 orig_buf = pkt->data;
1021 orig_buf += 4; // frame size
1022 bytestream_put_be32 (&orig_buf, FRAME_ID); // frame container ID
1027 buf += 2; // frame header size will be stored here
1028 bytestream_put_be16 (&buf, 0); // version 1
1029 bytestream_put_buffer(&buf, ctx->vendor, 4);
1030 bytestream_put_be16 (&buf, avctx->width);
1031 bytestream_put_be16 (&buf, avctx->height);
1033 frame_flags = ctx->chroma_factor << 6;
1034 if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
1035 frame_flags |= pic->top_field_first ? 0x04 : 0x08;
1036 bytestream_put_byte (&buf, frame_flags);
1038 bytestream_put_byte (&buf, 0); // reserved
1039 bytestream_put_byte (&buf, pic->color_primaries);
1040 bytestream_put_byte (&buf, pic->color_trc);
1041 bytestream_put_byte (&buf, pic->colorspace);
1042 bytestream_put_byte (&buf, 0x40 | (ctx->alpha_bits >> 3));
1043 bytestream_put_byte (&buf, 0); // reserved
1044 if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
1045 bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present
1046 // luma quantisation matrix
1047 for (i = 0; i < 64; i++)
1048 bytestream_put_byte(&buf, ctx->quant_mat[i]);
1049 // chroma quantisation matrix
1050 for (i = 0; i < 64; i++)
1051 bytestream_put_byte(&buf, ctx->quant_mat[i]);
1053 bytestream_put_byte (&buf, 0x00); // matrix flags - default matrices are used
1055 bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
1057 for (ctx->cur_picture_idx = 0;
1058 ctx->cur_picture_idx < ctx->pictures_per_frame;
1059 ctx->cur_picture_idx++) {
1061 picture_size_pos = buf + 1;
1062 bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
1063 buf += 4; // picture data size will be stored here
1064 bytestream_put_be16 (&buf, ctx->slices_per_picture);
1065 bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
1067 // seek table - will be filled during slice encoding
1069 buf += ctx->slices_per_picture * 2;
1072 if (!ctx->force_quant) {
1073 ret = avctx->execute2(avctx, find_quant_thread, (void*)pic, NULL,
1079 for (y = 0; y < ctx->mb_height; y++) {
1080 int mbs_per_slice = ctx->mbs_per_slice;
1081 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
1082 q = ctx->force_quant ? ctx->force_quant
1083 : ctx->slice_q[mb + y * ctx->slices_width];
1085 while (ctx->mb_width - x < mbs_per_slice)
1086 mbs_per_slice >>= 1;
1088 bytestream_put_byte(&buf, slice_hdr_size << 3);
1090 buf += slice_hdr_size - 1;
1091 if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
1092 uint8_t *start = pkt->data;
1093 // Recompute new size according to max_slice_size
1095 int delta = 200 + (ctx->pictures_per_frame *
1096 ctx->slices_per_picture + 1) *
1097 max_slice_size - pkt_size;
1099 delta = FFMAX(delta, 2 * max_slice_size);
1100 ctx->frame_size_upper_bound += delta;
1103 avpriv_request_sample(avctx,
1104 "Packet too small: is %i,"
1105 " needs %i (slice: %i). "
1106 "Correct allocation",
1107 pkt_size, delta, max_slice_size);
1111 ret = av_grow_packet(pkt, delta);
1117 orig_buf = pkt->data + (orig_buf - start);
1118 buf = pkt->data + (buf - start);
1119 picture_size_pos = pkt->data + (picture_size_pos - start);
1120 slice_sizes = pkt->data + (slice_sizes - start);
1121 slice_hdr = pkt->data + (slice_hdr - start);
1122 tmp = pkt->data + (tmp - start);
1124 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)));
1125 ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
1130 bytestream_put_byte(&slice_hdr, q);
1131 slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
1132 for (i = 0; i < ctx->num_planes - 1; i++) {
1133 bytestream_put_be16(&slice_hdr, sizes[i]);
1134 slice_size += sizes[i];
1136 bytestream_put_be16(&slice_sizes, slice_size);
1137 buf += slice_size - slice_hdr_size;
1138 if (max_slice_size < slice_size)
1139 max_slice_size = slice_size;
1143 picture_size = buf - (picture_size_pos - 1);
1144 bytestream_put_be32(&picture_size_pos, picture_size);
1148 frame_size = buf - orig_buf;
1149 bytestream_put_be32(&orig_buf, frame_size);
1151 pkt->size = frame_size;
1152 pkt->flags |= AV_PKT_FLAG_KEY;
1158 static av_cold int encode_close(AVCodecContext *avctx)
1160 ProresContext *ctx = avctx->priv_data;
1164 for (i = 0; i < avctx->thread_count; i++)
1165 av_freep(&ctx->tdata[i].nodes);
1167 av_freep(&ctx->tdata);
1168 av_freep(&ctx->slice_q);
1173 static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src,
1174 ptrdiff_t linesize, int16_t *block)
1177 const uint16_t *tsrc = src;
1179 for (y = 0; y < 8; y++) {
1180 for (x = 0; x < 8; x++)
1181 block[y * 8 + x] = tsrc[x];
1182 tsrc += linesize >> 1;
1187 static av_cold int encode_init(AVCodecContext *avctx)
1189 ProresContext *ctx = avctx->priv_data;
1192 int min_quant, max_quant;
1193 int interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
1195 avctx->bits_per_raw_sample = 10;
1196 #if FF_API_CODED_FRAME
1197 FF_DISABLE_DEPRECATION_WARNINGS
1198 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
1199 avctx->coded_frame->key_frame = 1;
1200 FF_ENABLE_DEPRECATION_WARNINGS
1203 ctx->fdct = prores_fdct;
1204 ctx->scantable = interlaced ? ff_prores_interlaced_scan
1205 : ff_prores_progressive_scan;
1206 ff_fdctdsp_init(&ctx->fdsp, avctx);
1208 mps = ctx->mbs_per_slice;
1209 if (mps & (mps - 1)) {
1210 av_log(avctx, AV_LOG_ERROR,
1211 "there should be an integer power of two MBs per slice\n");
1212 return AVERROR(EINVAL);
1214 if (ctx->profile == PRORES_PROFILE_AUTO) {
1215 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1216 ctx->profile = (desc->flags & AV_PIX_FMT_FLAG_ALPHA ||
1217 !(desc->log2_chroma_w + desc->log2_chroma_h))
1218 ? PRORES_PROFILE_4444 : PRORES_PROFILE_HQ;
1219 av_log(avctx, AV_LOG_INFO, "Autoselected %s. It can be overridden "
1220 "through -profile option.\n", ctx->profile == PRORES_PROFILE_4444
1221 ? "4:4:4:4 profile because of the used input colorspace"
1222 : "HQ profile to keep best quality");
1224 if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
1225 if (ctx->profile != PRORES_PROFILE_4444 &&
1226 ctx->profile != PRORES_PROFILE_4444XQ) {
1227 // force alpha and warn
1228 av_log(avctx, AV_LOG_WARNING, "Profile selected will not "
1229 "encode alpha. Override with -profile if needed.\n");
1230 ctx->alpha_bits = 0;
1232 if (ctx->alpha_bits & 7) {
1233 av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
1234 return AVERROR(EINVAL);
1236 avctx->bits_per_coded_sample = 32;
1238 ctx->alpha_bits = 0;
1241 ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
1244 ctx->profile_info = prores_profile_info + ctx->profile;
1245 ctx->num_planes = 3 + !!ctx->alpha_bits;
1247 ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
1250 ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
1252 ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
1254 ctx->slices_width = ctx->mb_width / mps;
1255 ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
1256 ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
1257 ctx->pictures_per_frame = 1 + interlaced;
1259 if (ctx->quant_sel == -1) {
1260 ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
1261 ctx->quant_chroma_mat = prores_quant_matrices[ctx->profile_info->quant_chroma];
1263 ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
1264 ctx->quant_chroma_mat = prores_quant_matrices[ctx->quant_sel];
1267 if (strlen(ctx->vendor) != 4) {
1268 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
1269 return AVERROR_INVALIDDATA;
1272 ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
1273 if (!ctx->force_quant) {
1274 if (!ctx->bits_per_mb) {
1275 for (i = 0; i < NUM_MB_LIMITS - 1; i++)
1276 if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
1277 ctx->pictures_per_frame)
1279 ctx->bits_per_mb = ctx->profile_info->br_tab[i];
1280 if (ctx->alpha_bits)
1281 ctx->bits_per_mb *= 20;
1282 } else if (ctx->bits_per_mb < 128) {
1283 av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
1284 return AVERROR_INVALIDDATA;
1287 min_quant = ctx->profile_info->min_quant;
1288 max_quant = ctx->profile_info->max_quant;
1289 for (i = min_quant; i < MAX_STORED_Q; i++) {
1290 for (j = 0; j < 64; j++) {
1291 ctx->quants[i][j] = ctx->quant_mat[j] * i;
1292 ctx->quants_chroma[i][j] = ctx->quant_chroma_mat[j] * i;
1296 ctx->slice_q = av_malloc(ctx->slices_per_picture * sizeof(*ctx->slice_q));
1297 if (!ctx->slice_q) {
1298 encode_close(avctx);
1299 return AVERROR(ENOMEM);
1302 ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
1304 encode_close(avctx);
1305 return AVERROR(ENOMEM);
1308 for (j = 0; j < avctx->thread_count; j++) {
1309 ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
1311 * sizeof(*ctx->tdata->nodes));
1312 if (!ctx->tdata[j].nodes) {
1313 encode_close(avctx);
1314 return AVERROR(ENOMEM);
1316 for (i = min_quant; i < max_quant + 2; i++) {
1317 ctx->tdata[j].nodes[i].prev_node = -1;
1318 ctx->tdata[j].nodes[i].bits = 0;
1319 ctx->tdata[j].nodes[i].score = 0;
1326 if (ctx->force_quant > 64) {
1327 av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
1328 return AVERROR_INVALIDDATA;
1331 for (j = 0; j < 64; j++) {
1332 ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
1333 ctx->quants_chroma[0][j] = ctx->quant_chroma_mat[j] * ctx->force_quant;
1334 ls += av_log2((1 << 11) / ctx->quants[0][j]) * 2 + 1;
1335 ls_chroma += av_log2((1 << 11) / ctx->quants_chroma[0][j]) * 2 + 1;
1338 ctx->bits_per_mb = ls * 4 + ls_chroma * 4;
1339 if (ctx->chroma_factor == CFACTOR_Y444)
1340 ctx->bits_per_mb += ls_chroma * 4;
1343 ctx->frame_size_upper_bound = (ctx->pictures_per_frame *
1344 ctx->slices_per_picture + 1) *
1345 (2 + 2 * ctx->num_planes +
1346 (mps * ctx->bits_per_mb) / 8)
1349 if (ctx->alpha_bits) {
1350 // The alpha plane is run-coded and might exceed the bit budget.
1351 ctx->frame_size_upper_bound += (ctx->pictures_per_frame *
1352 ctx->slices_per_picture + 1) *
1353 /* num pixels per slice */ (ctx->mbs_per_slice * 256 *
1354 /* bits per pixel */ (1 + ctx->alpha_bits + 1) + 7 >> 3);
1357 avctx->codec_tag = ctx->profile_info->tag;
1359 av_log(avctx, AV_LOG_DEBUG,
1360 "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
1361 ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
1362 interlaced ? "yes" : "no", ctx->bits_per_mb);
1363 av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
1364 ctx->frame_size_upper_bound);
1369 #define OFFSET(x) offsetof(ProresContext, x)
1370 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1372 static const AVOption options[] = {
1373 { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
1374 AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
1375 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
1376 { .i64 = PRORES_PROFILE_AUTO },
1377 PRORES_PROFILE_AUTO, PRORES_PROFILE_4444XQ, VE, "profile" },
1378 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_AUTO },
1379 0, 0, VE, "profile" },
1380 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
1381 0, 0, VE, "profile" },
1382 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
1383 0, 0, VE, "profile" },
1384 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
1385 0, 0, VE, "profile" },
1386 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
1387 0, 0, VE, "profile" },
1388 { "4444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
1389 0, 0, VE, "profile" },
1390 { "4444xq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444XQ },
1391 0, 0, VE, "profile" },
1392 { "vendor", "vendor ID", OFFSET(vendor),
1393 AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE },
1394 { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
1395 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
1396 { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
1397 { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, "quant_mat" },
1398 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
1399 0, 0, VE, "quant_mat" },
1400 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
1401 0, 0, VE, "quant_mat" },
1402 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
1403 0, 0, VE, "quant_mat" },
1404 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
1405 0, 0, VE, "quant_mat" },
1406 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
1407 0, 0, VE, "quant_mat" },
1408 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
1409 0, 0, VE, "quant_mat" },
1410 { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
1411 { .i64 = 16 }, 0, 16, VE },
1415 static const AVClass proresenc_class = {
1416 .class_name = "ProRes encoder",
1417 .item_name = av_default_item_name,
1419 .version = LIBAVUTIL_VERSION_INT,
1422 AVCodec ff_prores_ks_encoder = {
1423 .name = "prores_ks",
1424 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
1425 .type = AVMEDIA_TYPE_VIDEO,
1426 .id = AV_CODEC_ID_PRORES,
1427 .priv_data_size = sizeof(ProresContext),
1428 .init = encode_init,
1429 .close = encode_close,
1430 .encode2 = encode_frame,
1431 .capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
1432 .pix_fmts = (const enum AVPixelFormat[]) {
1433 AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
1434 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
1436 .priv_class = &proresenc_class,
1437 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),