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/mem_internal.h"
27 #include "libavutil/opt.h"
28 #include "libavutil/pixdesc.h"
33 #include "bytestream.h"
35 #include "proresdata.h"
37 #define CFACTOR_Y422 2
38 #define CFACTOR_Y444 3
40 #define MAX_MBS_PER_SLICE 8
45 PRORES_PROFILE_AUTO = -1,
46 PRORES_PROFILE_PROXY = 0,
48 PRORES_PROFILE_STANDARD,
51 PRORES_PROFILE_4444XQ,
56 QUANT_MAT_PROXY_CHROMA,
64 static const uint8_t prores_quant_matrices[][64] = {
66 4, 7, 9, 11, 13, 14, 15, 63,
67 7, 7, 11, 12, 14, 15, 63, 63,
68 9, 11, 13, 14, 15, 63, 63, 63,
69 11, 11, 13, 14, 63, 63, 63, 63,
70 11, 13, 14, 63, 63, 63, 63, 63,
71 13, 14, 63, 63, 63, 63, 63, 63,
72 13, 63, 63, 63, 63, 63, 63, 63,
73 63, 63, 63, 63, 63, 63, 63, 63,
76 4, 7, 9, 11, 13, 14, 63, 63,
77 7, 7, 11, 12, 14, 63, 63, 63,
78 9, 11, 13, 14, 63, 63, 63, 63,
79 11, 11, 13, 14, 63, 63, 63, 63,
80 11, 13, 14, 63, 63, 63, 63, 63,
81 13, 14, 63, 63, 63, 63, 63, 63,
82 13, 63, 63, 63, 63, 63, 63, 63,
83 63, 63, 63, 63, 63, 63, 63, 63
86 4, 5, 6, 7, 9, 11, 13, 15,
87 5, 5, 7, 8, 11, 13, 15, 17,
88 6, 7, 9, 11, 13, 15, 15, 17,
89 7, 7, 9, 11, 13, 15, 17, 19,
90 7, 9, 11, 13, 14, 16, 19, 23,
91 9, 11, 13, 14, 16, 19, 23, 29,
92 9, 11, 13, 15, 17, 21, 28, 35,
93 11, 13, 16, 17, 21, 28, 35, 41,
96 4, 4, 5, 5, 6, 7, 7, 9,
97 4, 4, 5, 6, 7, 7, 9, 9,
98 5, 5, 6, 7, 7, 9, 9, 10,
99 5, 5, 6, 7, 7, 9, 9, 10,
100 5, 6, 7, 7, 8, 9, 10, 12,
101 6, 7, 7, 8, 9, 10, 12, 15,
102 6, 7, 7, 9, 10, 11, 14, 17,
103 7, 7, 9, 10, 11, 14, 17, 21,
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, 4,
109 4, 4, 4, 4, 4, 4, 4, 5,
110 4, 4, 4, 4, 4, 4, 5, 5,
111 4, 4, 4, 4, 4, 5, 5, 6,
112 4, 4, 4, 4, 5, 5, 6, 7,
113 4, 4, 4, 4, 5, 6, 7, 7,
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, 2,
119 2, 2, 2, 2, 2, 2, 2, 3,
120 2, 2, 2, 2, 2, 2, 3, 3,
121 2, 2, 2, 2, 2, 3, 3, 3,
122 2, 2, 2, 2, 3, 3, 3, 4,
123 2, 2, 2, 2, 3, 3, 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,
133 4, 4, 4, 4, 4, 4, 4, 4,
137 #define NUM_MB_LIMITS 4
138 static const int prores_mb_limits[NUM_MB_LIMITS] = {
139 1620, // up to 720x576
140 2700, // up to 960x720
141 6075, // up to 1440x1080
142 9216, // up to 2048x1152
145 static const struct prores_profile {
146 const char *full_name;
150 int br_tab[NUM_MB_LIMITS];
153 } prores_profile_info[6] = {
155 .full_name = "proxy",
156 .tag = MKTAG('a', 'p', 'c', 'o'),
159 .br_tab = { 300, 242, 220, 194 },
160 .quant = QUANT_MAT_PROXY,
161 .quant_chroma = QUANT_MAT_PROXY_CHROMA,
165 .tag = MKTAG('a', 'p', 'c', 's'),
168 .br_tab = { 720, 560, 490, 440 },
169 .quant = QUANT_MAT_LT,
170 .quant_chroma = QUANT_MAT_LT,
173 .full_name = "standard",
174 .tag = MKTAG('a', 'p', 'c', 'n'),
177 .br_tab = { 1050, 808, 710, 632 },
178 .quant = QUANT_MAT_STANDARD,
179 .quant_chroma = QUANT_MAT_STANDARD,
182 .full_name = "high quality",
183 .tag = MKTAG('a', 'p', 'c', 'h'),
186 .br_tab = { 1566, 1216, 1070, 950 },
187 .quant = QUANT_MAT_HQ,
188 .quant_chroma = QUANT_MAT_HQ,
192 .tag = MKTAG('a', 'p', '4', 'h'),
195 .br_tab = { 2350, 1828, 1600, 1425 },
196 .quant = QUANT_MAT_HQ,
197 .quant_chroma = QUANT_MAT_HQ,
200 .full_name = "4444XQ",
201 .tag = MKTAG('a', 'p', '4', 'x'),
204 .br_tab = { 3525, 2742, 2400, 2137 },
205 .quant = QUANT_MAT_HQ, /* Fix me : use QUANT_MAT_XQ_LUMA */
206 .quant_chroma = QUANT_MAT_HQ,
210 #define TRELLIS_WIDTH 16
211 #define SCORE_LIMIT INT_MAX / 2
220 #define MAX_STORED_Q 16
222 typedef struct ProresThreadData {
223 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
224 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
225 int16_t custom_q[64];
226 int16_t custom_chroma_q[64];
227 struct TrellisNode *nodes;
230 typedef struct ProresContext {
232 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
233 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
234 int16_t quants[MAX_STORED_Q][64];
235 int16_t quants_chroma[MAX_STORED_Q][64];
236 int16_t custom_q[64];
237 int16_t custom_chroma_q[64];
238 const uint8_t *quant_mat;
239 const uint8_t *quant_chroma_mat;
240 const uint8_t *scantable;
242 void (*fdct)(FDCTDSPContext *fdsp, const uint16_t *src,
243 ptrdiff_t linesize, int16_t *block);
247 int mb_width, mb_height;
249 int num_chroma_blocks, chroma_factor;
251 int slices_per_picture;
252 int pictures_per_frame; // 1 for progressive, 2 for interlaced
263 int frame_size_upper_bound;
266 const struct prores_profile *profile_info;
270 ProresThreadData *tdata;
273 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
274 ptrdiff_t linesize, int x, int y, int w, int h,
275 int16_t *blocks, uint16_t *emu_buf,
276 int mbs_per_slice, int blocks_per_mb, int is_chroma)
278 const uint16_t *esrc;
279 const int mb_width = 4 * blocks_per_mb;
283 for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
285 memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
289 if (x + mb_width <= w && y + 16 <= h) {
291 elinesize = linesize;
296 elinesize = 16 * sizeof(*emu_buf);
298 bw = FFMIN(w - x, mb_width);
299 bh = FFMIN(h - y, 16);
301 for (j = 0; j < bh; j++) {
302 memcpy(emu_buf + j * 16,
303 (const uint8_t*)src + j * linesize,
305 pix = emu_buf[j * 16 + bw - 1];
306 for (k = bw; k < mb_width; k++)
307 emu_buf[j * 16 + k] = pix;
310 memcpy(emu_buf + j * 16,
311 emu_buf + (bh - 1) * 16,
312 mb_width * sizeof(*emu_buf));
315 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
317 if (blocks_per_mb > 2) {
318 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
321 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
323 if (blocks_per_mb > 2) {
324 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
328 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
330 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
332 if (blocks_per_mb > 2) {
333 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
335 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
344 static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
345 ptrdiff_t linesize, int x, int y, int w, int h,
346 int16_t *blocks, int mbs_per_slice, int abits)
348 const int slice_width = 16 * mbs_per_slice;
349 int i, j, copy_w, copy_h;
351 copy_w = FFMIN(w - x, slice_width);
352 copy_h = FFMIN(h - y, 16);
353 for (i = 0; i < copy_h; i++) {
354 memcpy(blocks, src, copy_w * sizeof(*src));
356 for (j = 0; j < copy_w; j++)
359 for (j = 0; j < copy_w; j++)
360 blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
361 for (j = copy_w; j < slice_width; j++)
362 blocks[j] = blocks[copy_w - 1];
363 blocks += slice_width;
364 src += linesize >> 1;
366 for (; i < 16; i++) {
367 memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
368 blocks += slice_width;
373 * Write an unsigned rice/exp golomb codeword.
375 static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
377 unsigned int rice_order, exp_order, switch_bits, switch_val;
380 /* number of prefix bits to switch between Rice and expGolomb */
381 switch_bits = (codebook & 3) + 1;
382 rice_order = codebook >> 5; /* rice code order */
383 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
385 switch_val = switch_bits << rice_order;
387 if (val >= switch_val) {
388 val -= switch_val - (1 << exp_order);
389 exponent = av_log2(val);
391 put_bits(pb, exponent - exp_order + switch_bits, 0);
392 put_bits(pb, exponent + 1, val);
394 exponent = val >> rice_order;
397 put_bits(pb, exponent, 0);
400 put_sbits(pb, rice_order, val);
404 #define GET_SIGN(x) ((x) >> 31)
405 #define MAKE_CODE(x) ((((x)) * 2) ^ GET_SIGN(x))
407 static void encode_dcs(PutBitContext *pb, int16_t *blocks,
408 int blocks_per_slice, int scale)
411 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
413 prev_dc = (blocks[0] - 0x4000) / scale;
414 encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
419 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
420 dc = (blocks[0] - 0x4000) / scale;
421 delta = dc - prev_dc;
422 new_sign = GET_SIGN(delta);
423 delta = (delta ^ sign) - sign;
424 code = MAKE_CODE(delta);
425 encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
426 codebook = (code + (code & 1)) >> 1;
427 codebook = FFMIN(codebook, 3);
433 static void encode_acs(PutBitContext *pb, int16_t *blocks,
434 int blocks_per_slice,
435 int plane_size_factor,
436 const uint8_t *scan, const int16_t *qmat)
439 int run, level, run_cb, lev_cb;
440 int max_coeffs, abs_level;
442 max_coeffs = blocks_per_slice << 6;
443 run_cb = ff_prores_run_to_cb_index[4];
444 lev_cb = ff_prores_lev_to_cb_index[2];
447 for (i = 1; i < 64; i++) {
448 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
449 level = blocks[idx] / qmat[scan[i]];
451 abs_level = FFABS(level);
452 encode_vlc_codeword(pb, ff_prores_ac_codebook[run_cb], run);
453 encode_vlc_codeword(pb, ff_prores_ac_codebook[lev_cb],
455 put_sbits(pb, 1, GET_SIGN(level));
457 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
458 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
467 static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
468 const uint16_t *src, ptrdiff_t linesize,
469 int mbs_per_slice, int16_t *blocks,
470 int blocks_per_mb, int plane_size_factor,
473 int blocks_per_slice, saved_pos;
475 saved_pos = put_bits_count(pb);
476 blocks_per_slice = mbs_per_slice * blocks_per_mb;
478 encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
479 encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
480 ctx->scantable, qmat);
483 return (put_bits_count(pb) - saved_pos) >> 3;
486 static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
488 const int dbits = (abits == 8) ? 4 : 7;
489 const int dsize = 1 << dbits - 1;
490 int diff = cur - prev;
492 diff = av_mod_uintp2(diff, abits);
493 if (diff >= (1 << abits) - dsize)
495 if (diff < -dsize || diff > dsize || !diff) {
497 put_bits(pb, abits, diff);
500 put_bits(pb, dbits - 1, FFABS(diff) - 1);
501 put_bits(pb, 1, diff < 0);
505 static void put_alpha_run(PutBitContext *pb, int run)
510 put_bits(pb, 4, run);
512 put_bits(pb, 15, run);
518 // todo alpha quantisation for high quants
519 static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
520 int mbs_per_slice, uint16_t *blocks,
523 const int abits = ctx->alpha_bits;
524 const int mask = (1 << abits) - 1;
525 const int num_coeffs = mbs_per_slice * 256;
526 int saved_pos = put_bits_count(pb);
527 int prev = mask, cur;
532 put_alpha_diff(pb, cur, prev, abits);
537 put_alpha_run (pb, run);
538 put_alpha_diff(pb, cur, prev, abits);
544 } while (idx < num_coeffs);
546 put_alpha_run(pb, run);
548 return (put_bits_count(pb) - saved_pos) >> 3;
551 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
553 int sizes[4], int x, int y, int quant,
556 ProresContext *ctx = avctx->priv_data;
560 int slice_width_factor = av_log2(mbs_per_slice);
561 int num_cblocks, pwidth, line_add;
563 int plane_factor, is_chroma;
565 uint16_t *qmat_chroma;
567 if (ctx->pictures_per_frame == 1)
570 line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
572 if (ctx->force_quant) {
573 qmat = ctx->quants[0];
574 qmat_chroma = ctx->quants_chroma[0];
575 } else if (quant < MAX_STORED_Q) {
576 qmat = ctx->quants[quant];
577 qmat_chroma = ctx->quants_chroma[quant];
579 qmat = ctx->custom_q;
580 qmat_chroma = ctx->custom_chroma_q;
581 for (i = 0; i < 64; i++) {
582 qmat[i] = ctx->quant_mat[i] * quant;
583 qmat_chroma[i] = ctx->quant_chroma_mat[i] * quant;
587 for (i = 0; i < ctx->num_planes; i++) {
588 is_chroma = (i == 1 || i == 2);
589 plane_factor = slice_width_factor + 2;
591 plane_factor += ctx->chroma_factor - 3;
592 if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
596 pwidth = avctx->width;
601 pwidth = avctx->width >> 1;
604 linesize = pic->linesize[i] * ctx->pictures_per_frame;
605 src = (const uint16_t*)(pic->data[i] + yp * linesize +
606 line_add * pic->linesize[i]) + xp;
609 get_slice_data(ctx, src, linesize, xp, yp,
610 pwidth, avctx->height / ctx->pictures_per_frame,
611 ctx->blocks[0], ctx->emu_buf,
612 mbs_per_slice, num_cblocks, is_chroma);
613 if (!is_chroma) {/* luma quant */
614 sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
615 mbs_per_slice, ctx->blocks[0],
616 num_cblocks, plane_factor,
618 } else { /* chroma plane */
619 sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
620 mbs_per_slice, ctx->blocks[0],
621 num_cblocks, plane_factor,
625 get_alpha_data(ctx, src, linesize, xp, yp,
626 pwidth, avctx->height / ctx->pictures_per_frame,
627 ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
628 sizes[i] = encode_alpha_plane(ctx, pb, mbs_per_slice,
629 ctx->blocks[0], quant);
631 total_size += sizes[i];
632 if (put_bits_left(pb) < 0) {
633 av_log(avctx, AV_LOG_ERROR,
634 "Underestimated required buffer size.\n");
641 static inline int estimate_vlc(unsigned codebook, int val)
643 unsigned int rice_order, exp_order, switch_bits, switch_val;
646 /* number of prefix bits to switch between Rice and expGolomb */
647 switch_bits = (codebook & 3) + 1;
648 rice_order = codebook >> 5; /* rice code order */
649 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
651 switch_val = switch_bits << rice_order;
653 if (val >= switch_val) {
654 val -= switch_val - (1 << exp_order);
655 exponent = av_log2(val);
657 return exponent * 2 - exp_order + switch_bits + 1;
659 return (val >> rice_order) + rice_order + 1;
663 static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
667 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
670 prev_dc = (blocks[0] - 0x4000) / scale;
671 bits = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
675 *error += FFABS(blocks[0] - 0x4000) % scale;
677 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
678 dc = (blocks[0] - 0x4000) / scale;
679 *error += FFABS(blocks[0] - 0x4000) % scale;
680 delta = dc - prev_dc;
681 new_sign = GET_SIGN(delta);
682 delta = (delta ^ sign) - sign;
683 code = MAKE_CODE(delta);
684 bits += estimate_vlc(ff_prores_dc_codebook[codebook], code);
685 codebook = (code + (code & 1)) >> 1;
686 codebook = FFMIN(codebook, 3);
694 static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
695 int plane_size_factor,
696 const uint8_t *scan, const int16_t *qmat)
699 int run, level, run_cb, lev_cb;
700 int max_coeffs, abs_level;
703 max_coeffs = blocks_per_slice << 6;
704 run_cb = ff_prores_run_to_cb_index[4];
705 lev_cb = ff_prores_lev_to_cb_index[2];
708 for (i = 1; i < 64; i++) {
709 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
710 level = blocks[idx] / qmat[scan[i]];
711 *error += FFABS(blocks[idx]) % qmat[scan[i]];
713 abs_level = FFABS(level);
714 bits += estimate_vlc(ff_prores_ac_codebook[run_cb], run);
715 bits += estimate_vlc(ff_prores_ac_codebook[lev_cb],
718 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
719 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
730 static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
731 const uint16_t *src, ptrdiff_t linesize,
733 int blocks_per_mb, int plane_size_factor,
734 const int16_t *qmat, ProresThreadData *td)
736 int blocks_per_slice;
739 blocks_per_slice = mbs_per_slice * blocks_per_mb;
741 bits = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
742 bits += estimate_acs(error, td->blocks[plane], blocks_per_slice,
743 plane_size_factor, ctx->scantable, qmat);
745 return FFALIGN(bits, 8);
748 static int est_alpha_diff(int cur, int prev, int abits)
750 const int dbits = (abits == 8) ? 4 : 7;
751 const int dsize = 1 << dbits - 1;
752 int diff = cur - prev;
754 diff = av_mod_uintp2(diff, abits);
755 if (diff >= (1 << abits) - dsize)
757 if (diff < -dsize || diff > dsize || !diff)
763 static int estimate_alpha_plane(ProresContext *ctx,
764 const uint16_t *src, ptrdiff_t linesize,
765 int mbs_per_slice, int16_t *blocks)
767 const int abits = ctx->alpha_bits;
768 const int mask = (1 << abits) - 1;
769 const int num_coeffs = mbs_per_slice * 256;
770 int prev = mask, cur;
776 bits = est_alpha_diff(cur, prev, abits);
787 bits += est_alpha_diff(cur, prev, abits);
793 } while (idx < num_coeffs);
805 static int find_slice_quant(AVCodecContext *avctx,
806 int trellis_node, int x, int y, int mbs_per_slice,
807 ProresThreadData *td)
809 ProresContext *ctx = avctx->priv_data;
810 int i, q, pq, xp, yp;
812 int slice_width_factor = av_log2(mbs_per_slice);
813 int num_cblocks[MAX_PLANES], pwidth;
814 int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];
815 const int min_quant = ctx->profile_info->min_quant;
816 const int max_quant = ctx->profile_info->max_quant;
817 int error, bits, bits_limit;
818 int mbs, prev, cur, new_score;
819 int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
822 uint16_t *qmat_chroma;
823 int linesize[4], line_add;
826 if (ctx->pictures_per_frame == 1)
829 line_add = ctx->cur_picture_idx ^ !ctx->pic->top_field_first;
830 mbs = x + mbs_per_slice;
832 for (i = 0; i < ctx->num_planes; i++) {
833 is_chroma[i] = (i == 1 || i == 2);
834 plane_factor[i] = slice_width_factor + 2;
836 plane_factor[i] += ctx->chroma_factor - 3;
837 if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
841 pwidth = avctx->width;
846 pwidth = avctx->width >> 1;
849 linesize[i] = ctx->pic->linesize[i] * ctx->pictures_per_frame;
850 src = (const uint16_t *)(ctx->pic->data[i] + yp * linesize[i] +
851 line_add * ctx->pic->linesize[i]) + xp;
854 get_slice_data(ctx, src, linesize[i], xp, yp,
855 pwidth, avctx->height / ctx->pictures_per_frame,
856 td->blocks[i], td->emu_buf,
857 mbs_per_slice, num_cblocks[i], is_chroma[i]);
859 get_alpha_data(ctx, src, linesize[i], xp, yp,
860 pwidth, avctx->height / ctx->pictures_per_frame,
861 td->blocks[i], mbs_per_slice, ctx->alpha_bits);
865 for (q = min_quant; q < max_quant + 2; q++) {
866 td->nodes[trellis_node + q].prev_node = -1;
867 td->nodes[trellis_node + q].quant = q;
871 alpha_bits = estimate_alpha_plane(ctx, src, linesize[3],
872 mbs_per_slice, td->blocks[3]);
873 // todo: maybe perform coarser quantising to fit into frame size when needed
874 for (q = min_quant; q <= max_quant; q++) {
877 bits += estimate_slice_plane(ctx, &error, 0,
880 num_cblocks[0], plane_factor[0],
881 ctx->quants[q], td); /* estimate luma plane */
882 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
883 bits += estimate_slice_plane(ctx, &error, i,
886 num_cblocks[i], plane_factor[i],
887 ctx->quants_chroma[q], td);
889 if (bits > 65000 * 8)
892 slice_bits[q] = bits;
893 slice_score[q] = error;
895 if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
896 slice_bits[max_quant + 1] = slice_bits[max_quant];
897 slice_score[max_quant + 1] = slice_score[max_quant] + 1;
898 overquant = max_quant;
900 for (q = max_quant + 1; q < 128; q++) {
903 if (q < MAX_STORED_Q) {
904 qmat = ctx->quants[q];
905 qmat_chroma = ctx->quants_chroma[q];
908 qmat_chroma = td->custom_chroma_q;
909 for (i = 0; i < 64; i++) {
910 qmat[i] = ctx->quant_mat[i] * q;
911 qmat_chroma[i] = ctx->quant_chroma_mat[i] * q;
914 bits += estimate_slice_plane(ctx, &error, 0,
917 num_cblocks[0], plane_factor[0],
918 qmat, td);/* estimate luma plane */
919 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
920 bits += estimate_slice_plane(ctx, &error, i,
923 num_cblocks[i], plane_factor[i],
926 if (bits <= ctx->bits_per_mb * mbs_per_slice)
930 slice_bits[max_quant + 1] = bits;
931 slice_score[max_quant + 1] = error;
934 td->nodes[trellis_node + max_quant + 1].quant = overquant;
936 bits_limit = mbs * ctx->bits_per_mb;
937 for (pq = min_quant; pq < max_quant + 2; pq++) {
938 prev = trellis_node - TRELLIS_WIDTH + pq;
940 for (q = min_quant; q < max_quant + 2; q++) {
941 cur = trellis_node + q;
943 bits = td->nodes[prev].bits + slice_bits[q];
944 error = slice_score[q];
945 if (bits > bits_limit)
948 if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
949 new_score = td->nodes[prev].score + error;
951 new_score = SCORE_LIMIT;
952 if (td->nodes[cur].prev_node == -1 ||
953 td->nodes[cur].score >= new_score) {
955 td->nodes[cur].bits = bits;
956 td->nodes[cur].score = new_score;
957 td->nodes[cur].prev_node = prev;
962 error = td->nodes[trellis_node + min_quant].score;
963 pq = trellis_node + min_quant;
964 for (q = min_quant + 1; q < max_quant + 2; q++) {
965 if (td->nodes[trellis_node + q].score <= error) {
966 error = td->nodes[trellis_node + q].score;
967 pq = trellis_node + q;
974 static int find_quant_thread(AVCodecContext *avctx, void *arg,
975 int jobnr, int threadnr)
977 ProresContext *ctx = avctx->priv_data;
978 ProresThreadData *td = ctx->tdata + threadnr;
979 int mbs_per_slice = ctx->mbs_per_slice;
980 int x, y = jobnr, mb, q = 0;
982 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
983 while (ctx->mb_width - x < mbs_per_slice)
985 q = find_slice_quant(avctx,
986 (mb + 1) * TRELLIS_WIDTH, x, y,
990 for (x = ctx->slices_width - 1; x >= 0; x--) {
991 ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
992 q = td->nodes[q].prev_node;
998 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
999 const AVFrame *pic, int *got_packet)
1001 ProresContext *ctx = avctx->priv_data;
1002 uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
1003 uint8_t *picture_size_pos;
1005 int x, y, i, mb, q = 0;
1006 int sizes[4] = { 0 };
1007 int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
1008 int frame_size, picture_size, slice_size;
1010 int max_slice_size = (ctx->frame_size_upper_bound - 200) / (ctx->pictures_per_frame * ctx->slices_per_picture + 1);
1011 uint8_t frame_flags;
1014 pkt_size = ctx->frame_size_upper_bound;
1016 if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
1019 orig_buf = pkt->data;
1022 orig_buf += 4; // frame size
1023 bytestream_put_be32 (&orig_buf, FRAME_ID); // frame container ID
1028 buf += 2; // frame header size will be stored here
1029 bytestream_put_be16 (&buf, 0); // version 1
1030 bytestream_put_buffer(&buf, ctx->vendor, 4);
1031 bytestream_put_be16 (&buf, avctx->width);
1032 bytestream_put_be16 (&buf, avctx->height);
1034 frame_flags = ctx->chroma_factor << 6;
1035 if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
1036 frame_flags |= pic->top_field_first ? 0x04 : 0x08;
1037 bytestream_put_byte (&buf, frame_flags);
1039 bytestream_put_byte (&buf, 0); // reserved
1040 bytestream_put_byte (&buf, pic->color_primaries);
1041 bytestream_put_byte (&buf, pic->color_trc);
1042 bytestream_put_byte (&buf, pic->colorspace);
1043 bytestream_put_byte (&buf, 0x40 | (ctx->alpha_bits >> 3));
1044 bytestream_put_byte (&buf, 0); // reserved
1045 if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
1046 bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present
1047 // luma quantisation matrix
1048 for (i = 0; i < 64; i++)
1049 bytestream_put_byte(&buf, ctx->quant_mat[i]);
1050 // chroma quantisation matrix
1051 for (i = 0; i < 64; i++)
1052 bytestream_put_byte(&buf, ctx->quant_mat[i]);
1054 bytestream_put_byte (&buf, 0x00); // matrix flags - default matrices are used
1056 bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
1058 for (ctx->cur_picture_idx = 0;
1059 ctx->cur_picture_idx < ctx->pictures_per_frame;
1060 ctx->cur_picture_idx++) {
1062 picture_size_pos = buf + 1;
1063 bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
1064 buf += 4; // picture data size will be stored here
1065 bytestream_put_be16 (&buf, ctx->slices_per_picture);
1066 bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
1068 // seek table - will be filled during slice encoding
1070 buf += ctx->slices_per_picture * 2;
1073 if (!ctx->force_quant) {
1074 ret = avctx->execute2(avctx, find_quant_thread, (void*)pic, NULL,
1080 for (y = 0; y < ctx->mb_height; y++) {
1081 int mbs_per_slice = ctx->mbs_per_slice;
1082 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
1083 q = ctx->force_quant ? ctx->force_quant
1084 : ctx->slice_q[mb + y * ctx->slices_width];
1086 while (ctx->mb_width - x < mbs_per_slice)
1087 mbs_per_slice >>= 1;
1089 bytestream_put_byte(&buf, slice_hdr_size << 3);
1091 buf += slice_hdr_size - 1;
1092 if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
1093 uint8_t *start = pkt->data;
1094 // Recompute new size according to max_slice_size
1096 int delta = 200 + (ctx->pictures_per_frame *
1097 ctx->slices_per_picture + 1) *
1098 max_slice_size - pkt_size;
1100 delta = FFMAX(delta, 2 * max_slice_size);
1101 ctx->frame_size_upper_bound += delta;
1104 avpriv_request_sample(avctx,
1105 "Packet too small: is %i,"
1106 " needs %i (slice: %i). "
1107 "Correct allocation",
1108 pkt_size, delta, max_slice_size);
1112 ret = av_grow_packet(pkt, delta);
1118 orig_buf = pkt->data + (orig_buf - start);
1119 buf = pkt->data + (buf - start);
1120 picture_size_pos = pkt->data + (picture_size_pos - start);
1121 slice_sizes = pkt->data + (slice_sizes - start);
1122 slice_hdr = pkt->data + (slice_hdr - start);
1123 tmp = pkt->data + (tmp - start);
1125 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)));
1126 ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
1131 bytestream_put_byte(&slice_hdr, q);
1132 slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
1133 for (i = 0; i < ctx->num_planes - 1; i++) {
1134 bytestream_put_be16(&slice_hdr, sizes[i]);
1135 slice_size += sizes[i];
1137 bytestream_put_be16(&slice_sizes, slice_size);
1138 buf += slice_size - slice_hdr_size;
1139 if (max_slice_size < slice_size)
1140 max_slice_size = slice_size;
1144 picture_size = buf - (picture_size_pos - 1);
1145 bytestream_put_be32(&picture_size_pos, picture_size);
1149 frame_size = buf - orig_buf;
1150 bytestream_put_be32(&orig_buf, frame_size);
1152 pkt->size = frame_size;
1153 pkt->flags |= AV_PKT_FLAG_KEY;
1159 static av_cold int encode_close(AVCodecContext *avctx)
1161 ProresContext *ctx = avctx->priv_data;
1165 for (i = 0; i < avctx->thread_count; i++)
1166 av_freep(&ctx->tdata[i].nodes);
1168 av_freep(&ctx->tdata);
1169 av_freep(&ctx->slice_q);
1174 static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src,
1175 ptrdiff_t linesize, int16_t *block)
1178 const uint16_t *tsrc = src;
1180 for (y = 0; y < 8; y++) {
1181 for (x = 0; x < 8; x++)
1182 block[y * 8 + x] = tsrc[x];
1183 tsrc += linesize >> 1;
1188 static av_cold int encode_init(AVCodecContext *avctx)
1190 ProresContext *ctx = avctx->priv_data;
1193 int min_quant, max_quant;
1194 int interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
1196 avctx->bits_per_raw_sample = 10;
1197 #if FF_API_CODED_FRAME
1198 FF_DISABLE_DEPRECATION_WARNINGS
1199 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
1200 avctx->coded_frame->key_frame = 1;
1201 FF_ENABLE_DEPRECATION_WARNINGS
1204 ctx->fdct = prores_fdct;
1205 ctx->scantable = interlaced ? ff_prores_interlaced_scan
1206 : ff_prores_progressive_scan;
1207 ff_fdctdsp_init(&ctx->fdsp, avctx);
1209 mps = ctx->mbs_per_slice;
1210 if (mps & (mps - 1)) {
1211 av_log(avctx, AV_LOG_ERROR,
1212 "there should be an integer power of two MBs per slice\n");
1213 return AVERROR(EINVAL);
1215 if (ctx->profile == PRORES_PROFILE_AUTO) {
1216 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1217 ctx->profile = (desc->flags & AV_PIX_FMT_FLAG_ALPHA ||
1218 !(desc->log2_chroma_w + desc->log2_chroma_h))
1219 ? PRORES_PROFILE_4444 : PRORES_PROFILE_HQ;
1220 av_log(avctx, AV_LOG_INFO, "Autoselected %s. It can be overridden "
1221 "through -profile option.\n", ctx->profile == PRORES_PROFILE_4444
1222 ? "4:4:4:4 profile because of the used input colorspace"
1223 : "HQ profile to keep best quality");
1225 if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
1226 if (ctx->profile != PRORES_PROFILE_4444 &&
1227 ctx->profile != PRORES_PROFILE_4444XQ) {
1228 // force alpha and warn
1229 av_log(avctx, AV_LOG_WARNING, "Profile selected will not "
1230 "encode alpha. Override with -profile if needed.\n");
1231 ctx->alpha_bits = 0;
1233 if (ctx->alpha_bits & 7) {
1234 av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
1235 return AVERROR(EINVAL);
1237 avctx->bits_per_coded_sample = 32;
1239 ctx->alpha_bits = 0;
1242 ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
1245 ctx->profile_info = prores_profile_info + ctx->profile;
1246 ctx->num_planes = 3 + !!ctx->alpha_bits;
1248 ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
1251 ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
1253 ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
1255 ctx->slices_width = ctx->mb_width / mps;
1256 ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
1257 ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
1258 ctx->pictures_per_frame = 1 + interlaced;
1260 if (ctx->quant_sel == -1) {
1261 ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
1262 ctx->quant_chroma_mat = prores_quant_matrices[ctx->profile_info->quant_chroma];
1264 ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
1265 ctx->quant_chroma_mat = prores_quant_matrices[ctx->quant_sel];
1268 if (strlen(ctx->vendor) != 4) {
1269 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
1270 return AVERROR_INVALIDDATA;
1273 ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
1274 if (!ctx->force_quant) {
1275 if (!ctx->bits_per_mb) {
1276 for (i = 0; i < NUM_MB_LIMITS - 1; i++)
1277 if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
1278 ctx->pictures_per_frame)
1280 ctx->bits_per_mb = ctx->profile_info->br_tab[i];
1281 if (ctx->alpha_bits)
1282 ctx->bits_per_mb *= 20;
1283 } else if (ctx->bits_per_mb < 128) {
1284 av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
1285 return AVERROR_INVALIDDATA;
1288 min_quant = ctx->profile_info->min_quant;
1289 max_quant = ctx->profile_info->max_quant;
1290 for (i = min_quant; i < MAX_STORED_Q; i++) {
1291 for (j = 0; j < 64; j++) {
1292 ctx->quants[i][j] = ctx->quant_mat[j] * i;
1293 ctx->quants_chroma[i][j] = ctx->quant_chroma_mat[j] * i;
1297 ctx->slice_q = av_malloc(ctx->slices_per_picture * sizeof(*ctx->slice_q));
1298 if (!ctx->slice_q) {
1299 encode_close(avctx);
1300 return AVERROR(ENOMEM);
1303 ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
1305 encode_close(avctx);
1306 return AVERROR(ENOMEM);
1309 for (j = 0; j < avctx->thread_count; j++) {
1310 ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
1312 * sizeof(*ctx->tdata->nodes));
1313 if (!ctx->tdata[j].nodes) {
1314 encode_close(avctx);
1315 return AVERROR(ENOMEM);
1317 for (i = min_quant; i < max_quant + 2; i++) {
1318 ctx->tdata[j].nodes[i].prev_node = -1;
1319 ctx->tdata[j].nodes[i].bits = 0;
1320 ctx->tdata[j].nodes[i].score = 0;
1327 if (ctx->force_quant > 64) {
1328 av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
1329 return AVERROR_INVALIDDATA;
1332 for (j = 0; j < 64; j++) {
1333 ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
1334 ctx->quants_chroma[0][j] = ctx->quant_chroma_mat[j] * ctx->force_quant;
1335 ls += av_log2((1 << 11) / ctx->quants[0][j]) * 2 + 1;
1336 ls_chroma += av_log2((1 << 11) / ctx->quants_chroma[0][j]) * 2 + 1;
1339 ctx->bits_per_mb = ls * 4 + ls_chroma * 4;
1340 if (ctx->chroma_factor == CFACTOR_Y444)
1341 ctx->bits_per_mb += ls_chroma * 4;
1344 ctx->frame_size_upper_bound = (ctx->pictures_per_frame *
1345 ctx->slices_per_picture + 1) *
1346 (2 + 2 * ctx->num_planes +
1347 (mps * ctx->bits_per_mb) / 8)
1350 if (ctx->alpha_bits) {
1351 // The alpha plane is run-coded and might exceed the bit budget.
1352 ctx->frame_size_upper_bound += (ctx->pictures_per_frame *
1353 ctx->slices_per_picture + 1) *
1354 /* num pixels per slice */ (ctx->mbs_per_slice * 256 *
1355 /* bits per pixel */ (1 + ctx->alpha_bits + 1) + 7 >> 3);
1358 avctx->codec_tag = ctx->profile_info->tag;
1360 av_log(avctx, AV_LOG_DEBUG,
1361 "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
1362 ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
1363 interlaced ? "yes" : "no", ctx->bits_per_mb);
1364 av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
1365 ctx->frame_size_upper_bound);
1370 #define OFFSET(x) offsetof(ProresContext, x)
1371 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1373 static const AVOption options[] = {
1374 { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
1375 AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
1376 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
1377 { .i64 = PRORES_PROFILE_AUTO },
1378 PRORES_PROFILE_AUTO, PRORES_PROFILE_4444XQ, VE, "profile" },
1379 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_AUTO },
1380 0, 0, VE, "profile" },
1381 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
1382 0, 0, VE, "profile" },
1383 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
1384 0, 0, VE, "profile" },
1385 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
1386 0, 0, VE, "profile" },
1387 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
1388 0, 0, VE, "profile" },
1389 { "4444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
1390 0, 0, VE, "profile" },
1391 { "4444xq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444XQ },
1392 0, 0, VE, "profile" },
1393 { "vendor", "vendor ID", OFFSET(vendor),
1394 AV_OPT_TYPE_STRING, { .str = "Lavc" }, 0, 0, VE },
1395 { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
1396 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
1397 { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
1398 { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, "quant_mat" },
1399 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
1400 0, 0, VE, "quant_mat" },
1401 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
1402 0, 0, VE, "quant_mat" },
1403 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
1404 0, 0, VE, "quant_mat" },
1405 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
1406 0, 0, VE, "quant_mat" },
1407 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
1408 0, 0, VE, "quant_mat" },
1409 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
1410 0, 0, VE, "quant_mat" },
1411 { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
1412 { .i64 = 16 }, 0, 16, VE },
1416 static const AVClass proresenc_class = {
1417 .class_name = "ProRes encoder",
1418 .item_name = av_default_item_name,
1420 .version = LIBAVUTIL_VERSION_INT,
1423 AVCodec ff_prores_ks_encoder = {
1424 .name = "prores_ks",
1425 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
1426 .type = AVMEDIA_TYPE_VIDEO,
1427 .id = AV_CODEC_ID_PRORES,
1428 .priv_data_size = sizeof(ProresContext),
1429 .init = encode_init,
1430 .close = encode_close,
1431 .encode2 = encode_frame,
1432 .capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
1433 .pix_fmts = (const enum AVPixelFormat[]) {
1434 AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
1435 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
1437 .priv_class = &proresenc_class,
1438 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),