proresenc: Drop unnecessary DCT permutation bits
[libav.git] / libavcodec / proresenc.c
1 /*
2 * Apple ProRes encoder
3 *
4 * Copyright (c) 2012 Konstantin Shishkov
5 *
6 * This file is part of Libav.
7 *
8 * Libav is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * Libav is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with Libav; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include "libavutil/opt.h"
24 #include "libavutil/pixdesc.h"
25 #include "avcodec.h"
26 #include "dsputil.h"
27 #include "put_bits.h"
28 #include "bytestream.h"
29 #include "internal.h"
30 #include "proresdsp.h"
31 #include "proresdata.h"
32
33 #define CFACTOR_Y422 2
34 #define CFACTOR_Y444 3
35
36 #define MAX_MBS_PER_SLICE 8
37
38 #define MAX_PLANES 4
39
40 enum {
41 PRORES_PROFILE_PROXY = 0,
42 PRORES_PROFILE_LT,
43 PRORES_PROFILE_STANDARD,
44 PRORES_PROFILE_HQ,
45 PRORES_PROFILE_4444,
46 };
47
48 enum {
49 QUANT_MAT_PROXY = 0,
50 QUANT_MAT_LT,
51 QUANT_MAT_STANDARD,
52 QUANT_MAT_HQ,
53 QUANT_MAT_DEFAULT,
54 };
55
56 static const uint8_t prores_quant_matrices[][64] = {
57 { // proxy
58 4, 7, 9, 11, 13, 14, 15, 63,
59 7, 7, 11, 12, 14, 15, 63, 63,
60 9, 11, 13, 14, 15, 63, 63, 63,
61 11, 11, 13, 14, 63, 63, 63, 63,
62 11, 13, 14, 63, 63, 63, 63, 63,
63 13, 14, 63, 63, 63, 63, 63, 63,
64 13, 63, 63, 63, 63, 63, 63, 63,
65 63, 63, 63, 63, 63, 63, 63, 63,
66 },
67 { // LT
68 4, 5, 6, 7, 9, 11, 13, 15,
69 5, 5, 7, 8, 11, 13, 15, 17,
70 6, 7, 9, 11, 13, 15, 15, 17,
71 7, 7, 9, 11, 13, 15, 17, 19,
72 7, 9, 11, 13, 14, 16, 19, 23,
73 9, 11, 13, 14, 16, 19, 23, 29,
74 9, 11, 13, 15, 17, 21, 28, 35,
75 11, 13, 16, 17, 21, 28, 35, 41,
76 },
77 { // standard
78 4, 4, 5, 5, 6, 7, 7, 9,
79 4, 4, 5, 6, 7, 7, 9, 9,
80 5, 5, 6, 7, 7, 9, 9, 10,
81 5, 5, 6, 7, 7, 9, 9, 10,
82 5, 6, 7, 7, 8, 9, 10, 12,
83 6, 7, 7, 8, 9, 10, 12, 15,
84 6, 7, 7, 9, 10, 11, 14, 17,
85 7, 7, 9, 10, 11, 14, 17, 21,
86 },
87 { // high quality
88 4, 4, 4, 4, 4, 4, 4, 4,
89 4, 4, 4, 4, 4, 4, 4, 4,
90 4, 4, 4, 4, 4, 4, 4, 4,
91 4, 4, 4, 4, 4, 4, 4, 5,
92 4, 4, 4, 4, 4, 4, 5, 5,
93 4, 4, 4, 4, 4, 5, 5, 6,
94 4, 4, 4, 4, 5, 5, 6, 7,
95 4, 4, 4, 4, 5, 6, 7, 7,
96 },
97 { // codec default
98 4, 4, 4, 4, 4, 4, 4, 4,
99 4, 4, 4, 4, 4, 4, 4, 4,
100 4, 4, 4, 4, 4, 4, 4, 4,
101 4, 4, 4, 4, 4, 4, 4, 4,
102 4, 4, 4, 4, 4, 4, 4, 4,
103 4, 4, 4, 4, 4, 4, 4, 4,
104 4, 4, 4, 4, 4, 4, 4, 4,
105 4, 4, 4, 4, 4, 4, 4, 4,
106 },
107 };
108
109 #define NUM_MB_LIMITS 4
110 static const int prores_mb_limits[NUM_MB_LIMITS] = {
111 1620, // up to 720x576
112 2700, // up to 960x720
113 6075, // up to 1440x1080
114 9216, // up to 2048x1152
115 };
116
117 static const struct prores_profile {
118 const char *full_name;
119 uint32_t tag;
120 int min_quant;
121 int max_quant;
122 int br_tab[NUM_MB_LIMITS];
123 int quant;
124 } prores_profile_info[5] = {
125 {
126 .full_name = "proxy",
127 .tag = MKTAG('a', 'p', 'c', 'o'),
128 .min_quant = 4,
129 .max_quant = 8,
130 .br_tab = { 300, 242, 220, 194 },
131 .quant = QUANT_MAT_PROXY,
132 },
133 {
134 .full_name = "LT",
135 .tag = MKTAG('a', 'p', 'c', 's'),
136 .min_quant = 1,
137 .max_quant = 9,
138 .br_tab = { 720, 560, 490, 440 },
139 .quant = QUANT_MAT_LT,
140 },
141 {
142 .full_name = "standard",
143 .tag = MKTAG('a', 'p', 'c', 'n'),
144 .min_quant = 1,
145 .max_quant = 6,
146 .br_tab = { 1050, 808, 710, 632 },
147 .quant = QUANT_MAT_STANDARD,
148 },
149 {
150 .full_name = "high quality",
151 .tag = MKTAG('a', 'p', 'c', 'h'),
152 .min_quant = 1,
153 .max_quant = 6,
154 .br_tab = { 1566, 1216, 1070, 950 },
155 .quant = QUANT_MAT_HQ,
156 },
157 {
158 .full_name = "4444",
159 .tag = MKTAG('a', 'p', '4', 'h'),
160 .min_quant = 1,
161 .max_quant = 6,
162 .br_tab = { 2350, 1828, 1600, 1425 },
163 .quant = QUANT_MAT_HQ,
164 }
165 };
166
167 #define TRELLIS_WIDTH 16
168 #define SCORE_LIMIT INT_MAX / 2
169
170 struct TrellisNode {
171 int prev_node;
172 int quant;
173 int bits;
174 int score;
175 };
176
177 #define MAX_STORED_Q 16
178
179 typedef struct ProresThreadData {
180 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
181 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
182 int16_t custom_q[64];
183 struct TrellisNode *nodes;
184 } ProresThreadData;
185
186 typedef struct ProresContext {
187 AVClass *class;
188 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
189 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
190 int16_t quants[MAX_STORED_Q][64];
191 int16_t custom_q[64];
192 const uint8_t *quant_mat;
193 const uint8_t *scantable;
194
195 ProresDSPContext dsp;
196
197 int mb_width, mb_height;
198 int mbs_per_slice;
199 int num_chroma_blocks, chroma_factor;
200 int slices_width;
201 int slices_per_picture;
202 int pictures_per_frame; // 1 for progressive, 2 for interlaced
203 int cur_picture_idx;
204 int num_planes;
205 int bits_per_mb;
206 int force_quant;
207 int alpha_bits;
208
209 char *vendor;
210 int quant_sel;
211
212 int frame_size_upper_bound;
213
214 int profile;
215 const struct prores_profile *profile_info;
216
217 int *slice_q;
218
219 ProresThreadData *tdata;
220 } ProresContext;
221
222 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
223 int linesize, int x, int y, int w, int h,
224 int16_t *blocks, uint16_t *emu_buf,
225 int mbs_per_slice, int blocks_per_mb, int is_chroma)
226 {
227 const uint16_t *esrc;
228 const int mb_width = 4 * blocks_per_mb;
229 int elinesize;
230 int i, j, k;
231
232 for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
233 if (x >= w) {
234 memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
235 * sizeof(*blocks));
236 return;
237 }
238 if (x + mb_width <= w && y + 16 <= h) {
239 esrc = src;
240 elinesize = linesize;
241 } else {
242 int bw, bh, pix;
243
244 esrc = emu_buf;
245 elinesize = 16 * sizeof(*emu_buf);
246
247 bw = FFMIN(w - x, mb_width);
248 bh = FFMIN(h - y, 16);
249
250 for (j = 0; j < bh; j++) {
251 memcpy(emu_buf + j * 16,
252 (const uint8_t*)src + j * linesize,
253 bw * sizeof(*src));
254 pix = emu_buf[j * 16 + bw - 1];
255 for (k = bw; k < mb_width; k++)
256 emu_buf[j * 16 + k] = pix;
257 }
258 for (; j < 16; j++)
259 memcpy(emu_buf + j * 16,
260 emu_buf + (bh - 1) * 16,
261 mb_width * sizeof(*emu_buf));
262 }
263 if (!is_chroma) {
264 ctx->dsp.fdct(esrc, elinesize, blocks);
265 blocks += 64;
266 if (blocks_per_mb > 2) {
267 ctx->dsp.fdct(esrc + 8, elinesize, blocks);
268 blocks += 64;
269 }
270 ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
271 blocks += 64;
272 if (blocks_per_mb > 2) {
273 ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
274 blocks += 64;
275 }
276 } else {
277 ctx->dsp.fdct(esrc, elinesize, blocks);
278 blocks += 64;
279 ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
280 blocks += 64;
281 if (blocks_per_mb > 2) {
282 ctx->dsp.fdct(esrc + 8, elinesize, blocks);
283 blocks += 64;
284 ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
285 blocks += 64;
286 }
287 }
288
289 x += mb_width;
290 }
291 }
292
293 static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
294 int linesize, int x, int y, int w, int h,
295 int16_t *blocks, int mbs_per_slice, int abits)
296 {
297 const int slice_width = 16 * mbs_per_slice;
298 int i, j, copy_w, copy_h;
299
300 copy_w = FFMIN(w - x, slice_width);
301 copy_h = FFMIN(h - y, 16);
302 for (i = 0; i < copy_h; i++) {
303 memcpy(blocks, src, copy_w * sizeof(*src));
304 if (abits == 8)
305 for (j = 0; j < copy_w; j++)
306 blocks[j] >>= 2;
307 else
308 for (j = 0; j < copy_w; j++)
309 blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
310 for (j = copy_w; j < slice_width; j++)
311 blocks[j] = blocks[copy_w - 1];
312 blocks += slice_width;
313 src += linesize >> 1;
314 }
315 for (; i < 16; i++) {
316 memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
317 blocks += slice_width;
318 }
319 }
320
321 /**
322 * Write an unsigned rice/exp golomb codeword.
323 */
324 static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
325 {
326 unsigned int rice_order, exp_order, switch_bits, switch_val;
327 int exponent;
328
329 /* number of prefix bits to switch between Rice and expGolomb */
330 switch_bits = (codebook & 3) + 1;
331 rice_order = codebook >> 5; /* rice code order */
332 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
333
334 switch_val = switch_bits << rice_order;
335
336 if (val >= switch_val) {
337 val -= switch_val - (1 << exp_order);
338 exponent = av_log2(val);
339
340 put_bits(pb, exponent - exp_order + switch_bits, 0);
341 put_bits(pb, exponent + 1, val);
342 } else {
343 exponent = val >> rice_order;
344
345 if (exponent)
346 put_bits(pb, exponent, 0);
347 put_bits(pb, 1, 1);
348 if (rice_order)
349 put_sbits(pb, rice_order, val);
350 }
351 }
352
353 #define GET_SIGN(x) ((x) >> 31)
354 #define MAKE_CODE(x) (((x) << 1) ^ GET_SIGN(x))
355
356 static void encode_dcs(PutBitContext *pb, int16_t *blocks,
357 int blocks_per_slice, int scale)
358 {
359 int i;
360 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
361
362 prev_dc = (blocks[0] - 0x4000) / scale;
363 encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
364 sign = 0;
365 codebook = 3;
366 blocks += 64;
367
368 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
369 dc = (blocks[0] - 0x4000) / scale;
370 delta = dc - prev_dc;
371 new_sign = GET_SIGN(delta);
372 delta = (delta ^ sign) - sign;
373 code = MAKE_CODE(delta);
374 encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
375 codebook = (code + (code & 1)) >> 1;
376 codebook = FFMIN(codebook, 3);
377 sign = new_sign;
378 prev_dc = dc;
379 }
380 }
381
382 static void encode_acs(PutBitContext *pb, int16_t *blocks,
383 int blocks_per_slice,
384 int plane_size_factor,
385 const uint8_t *scan, const int16_t *qmat)
386 {
387 int idx, i;
388 int run, level, run_cb, lev_cb;
389 int max_coeffs, abs_level;
390
391 max_coeffs = blocks_per_slice << 6;
392 run_cb = ff_prores_run_to_cb_index[4];
393 lev_cb = ff_prores_lev_to_cb_index[2];
394 run = 0;
395
396 for (i = 1; i < 64; i++) {
397 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
398 level = blocks[idx] / qmat[scan[i]];
399 if (level) {
400 abs_level = FFABS(level);
401 encode_vlc_codeword(pb, ff_prores_ac_codebook[run_cb], run);
402 encode_vlc_codeword(pb, ff_prores_ac_codebook[lev_cb],
403 abs_level - 1);
404 put_sbits(pb, 1, GET_SIGN(level));
405
406 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
407 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
408 run = 0;
409 } else {
410 run++;
411 }
412 }
413 }
414 }
415
416 static int encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
417 const uint16_t *src, int linesize,
418 int mbs_per_slice, int16_t *blocks,
419 int blocks_per_mb, int plane_size_factor,
420 const int16_t *qmat)
421 {
422 int blocks_per_slice, saved_pos;
423
424 saved_pos = put_bits_count(pb);
425 blocks_per_slice = mbs_per_slice * blocks_per_mb;
426
427 encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
428 encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
429 ctx->scantable, qmat);
430 flush_put_bits(pb);
431
432 return (put_bits_count(pb) - saved_pos) >> 3;
433 }
434
435 static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
436 {
437 const int mask = (1 << abits) - 1;
438 const int dbits = (abits == 8) ? 4 : 7;
439 const int dsize = 1 << dbits - 1;
440 int diff = cur - prev;
441
442 diff &= mask;
443 if (diff >= (1 << abits) - dsize)
444 diff -= 1 << abits;
445 if (diff < -dsize || diff > dsize || !diff) {
446 put_bits(pb, 1, 1);
447 put_bits(pb, abits, diff);
448 } else {
449 put_bits(pb, 1, 0);
450 put_bits(pb, dbits - 1, FFABS(diff) - 1);
451 put_bits(pb, 1, diff < 0);
452 }
453 }
454
455 static void put_alpha_run(PutBitContext *pb, int run)
456 {
457 if (run) {
458 put_bits(pb, 1, 0);
459 if (run < 0x10)
460 put_bits(pb, 4, run);
461 else
462 put_bits(pb, 15, run);
463 } else {
464 put_bits(pb, 1, 1);
465 }
466 }
467
468 // todo alpha quantisation for high quants
469 static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
470 const uint16_t *src, int linesize,
471 int mbs_per_slice, uint16_t *blocks,
472 int quant)
473 {
474 const int abits = ctx->alpha_bits;
475 const int mask = (1 << abits) - 1;
476 const int num_coeffs = mbs_per_slice * 256;
477 int saved_pos = put_bits_count(pb);
478 int prev = mask, cur;
479 int idx = 0;
480 int run = 0;
481
482 cur = blocks[idx++];
483 put_alpha_diff(pb, cur, prev, abits);
484 prev = cur;
485 do {
486 cur = blocks[idx++];
487 if (cur != prev) {
488 put_alpha_run (pb, run);
489 put_alpha_diff(pb, cur, prev, abits);
490 prev = cur;
491 run = 0;
492 } else {
493 run++;
494 }
495 } while (idx < num_coeffs);
496 if (run)
497 put_alpha_run(pb, run);
498 flush_put_bits(pb);
499 return (put_bits_count(pb) - saved_pos) >> 3;
500 }
501
502 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
503 PutBitContext *pb,
504 int sizes[4], int x, int y, int quant,
505 int mbs_per_slice)
506 {
507 ProresContext *ctx = avctx->priv_data;
508 int i, xp, yp;
509 int total_size = 0;
510 const uint16_t *src;
511 int slice_width_factor = av_log2(mbs_per_slice);
512 int num_cblocks, pwidth, linesize, line_add;
513 int plane_factor, is_chroma;
514 uint16_t *qmat;
515
516 if (ctx->pictures_per_frame == 1)
517 line_add = 0;
518 else
519 line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
520
521 if (ctx->force_quant) {
522 qmat = ctx->quants[0];
523 } else if (quant < MAX_STORED_Q) {
524 qmat = ctx->quants[quant];
525 } else {
526 qmat = ctx->custom_q;
527 for (i = 0; i < 64; i++)
528 qmat[i] = ctx->quant_mat[i] * quant;
529 }
530
531 for (i = 0; i < ctx->num_planes; i++) {
532 is_chroma = (i == 1 || i == 2);
533 plane_factor = slice_width_factor + 2;
534 if (is_chroma)
535 plane_factor += ctx->chroma_factor - 3;
536 if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
537 xp = x << 4;
538 yp = y << 4;
539 num_cblocks = 4;
540 pwidth = avctx->width;
541 } else {
542 xp = x << 3;
543 yp = y << 4;
544 num_cblocks = 2;
545 pwidth = avctx->width >> 1;
546 }
547
548 linesize = pic->linesize[i] * ctx->pictures_per_frame;
549 src = (const uint16_t*)(pic->data[i] + yp * linesize +
550 line_add * pic->linesize[i]) + xp;
551
552 if (i < 3) {
553 get_slice_data(ctx, src, linesize, xp, yp,
554 pwidth, avctx->height / ctx->pictures_per_frame,
555 ctx->blocks[0], ctx->emu_buf,
556 mbs_per_slice, num_cblocks, is_chroma);
557 sizes[i] = encode_slice_plane(ctx, pb, src, linesize,
558 mbs_per_slice, ctx->blocks[0],
559 num_cblocks, plane_factor,
560 qmat);
561 } else {
562 get_alpha_data(ctx, src, linesize, xp, yp,
563 pwidth, avctx->height / ctx->pictures_per_frame,
564 ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
565 sizes[i] = encode_alpha_plane(ctx, pb, src, linesize,
566 mbs_per_slice, ctx->blocks[0],
567 quant);
568 }
569 total_size += sizes[i];
570 }
571 return total_size;
572 }
573
574 static inline int estimate_vlc(unsigned codebook, int val)
575 {
576 unsigned int rice_order, exp_order, switch_bits, switch_val;
577 int exponent;
578
579 /* number of prefix bits to switch between Rice and expGolomb */
580 switch_bits = (codebook & 3) + 1;
581 rice_order = codebook >> 5; /* rice code order */
582 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
583
584 switch_val = switch_bits << rice_order;
585
586 if (val >= switch_val) {
587 val -= switch_val - (1 << exp_order);
588 exponent = av_log2(val);
589
590 return exponent * 2 - exp_order + switch_bits + 1;
591 } else {
592 return (val >> rice_order) + rice_order + 1;
593 }
594 }
595
596 static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
597 int scale)
598 {
599 int i;
600 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
601 int bits;
602
603 prev_dc = (blocks[0] - 0x4000) / scale;
604 bits = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
605 sign = 0;
606 codebook = 3;
607 blocks += 64;
608 *error += FFABS(blocks[0] - 0x4000) % scale;
609
610 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
611 dc = (blocks[0] - 0x4000) / scale;
612 *error += FFABS(blocks[0] - 0x4000) % scale;
613 delta = dc - prev_dc;
614 new_sign = GET_SIGN(delta);
615 delta = (delta ^ sign) - sign;
616 code = MAKE_CODE(delta);
617 bits += estimate_vlc(ff_prores_dc_codebook[codebook], code);
618 codebook = (code + (code & 1)) >> 1;
619 codebook = FFMIN(codebook, 3);
620 sign = new_sign;
621 prev_dc = dc;
622 }
623
624 return bits;
625 }
626
627 static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
628 int plane_size_factor,
629 const uint8_t *scan, const int16_t *qmat)
630 {
631 int idx, i;
632 int run, level, run_cb, lev_cb;
633 int max_coeffs, abs_level;
634 int bits = 0;
635
636 max_coeffs = blocks_per_slice << 6;
637 run_cb = ff_prores_run_to_cb_index[4];
638 lev_cb = ff_prores_lev_to_cb_index[2];
639 run = 0;
640
641 for (i = 1; i < 64; i++) {
642 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
643 level = blocks[idx] / qmat[scan[i]];
644 *error += FFABS(blocks[idx]) % qmat[scan[i]];
645 if (level) {
646 abs_level = FFABS(level);
647 bits += estimate_vlc(ff_prores_ac_codebook[run_cb], run);
648 bits += estimate_vlc(ff_prores_ac_codebook[lev_cb],
649 abs_level - 1) + 1;
650
651 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
652 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
653 run = 0;
654 } else {
655 run++;
656 }
657 }
658 }
659
660 return bits;
661 }
662
663 static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
664 const uint16_t *src, int linesize,
665 int mbs_per_slice,
666 int blocks_per_mb, int plane_size_factor,
667 const int16_t *qmat, ProresThreadData *td)
668 {
669 int blocks_per_slice;
670 int bits;
671
672 blocks_per_slice = mbs_per_slice * blocks_per_mb;
673
674 bits = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
675 bits += estimate_acs(error, td->blocks[plane], blocks_per_slice,
676 plane_size_factor, ctx->scantable, qmat);
677
678 return FFALIGN(bits, 8);
679 }
680
681 static int est_alpha_diff(int cur, int prev, int abits)
682 {
683 const int mask = (1 << abits) - 1;
684 const int dbits = (abits == 8) ? 4 : 7;
685 const int dsize = 1 << dbits - 1;
686 int diff = cur - prev;
687
688 diff &= mask;
689 if (diff >= (1 << abits) - dsize)
690 diff -= 1 << abits;
691 if (diff < -dsize || diff > dsize || !diff)
692 return abits + 1;
693 else
694 return dbits + 1;
695 }
696
697 static int estimate_alpha_plane(ProresContext *ctx, int *error,
698 const uint16_t *src, int linesize,
699 int mbs_per_slice, int quant,
700 int16_t *blocks)
701 {
702 const int abits = ctx->alpha_bits;
703 const int mask = (1 << abits) - 1;
704 const int num_coeffs = mbs_per_slice * 256;
705 int prev = mask, cur;
706 int idx = 0;
707 int run = 0;
708 int bits;
709
710 *error = 0;
711 cur = blocks[idx++];
712 bits = est_alpha_diff(cur, prev, abits);
713 prev = cur;
714 do {
715 cur = blocks[idx++];
716 if (cur != prev) {
717 if (!run)
718 bits++;
719 else if (run < 0x10)
720 bits += 4;
721 else
722 bits += 15;
723 bits += est_alpha_diff(cur, prev, abits);
724 prev = cur;
725 run = 0;
726 } else {
727 run++;
728 }
729 } while (idx < num_coeffs);
730
731 if (run) {
732 if (run < 0x10)
733 bits += 4;
734 else
735 bits += 15;
736 }
737
738 return bits;
739 }
740
741 static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
742 int trellis_node, int x, int y, int mbs_per_slice,
743 ProresThreadData *td)
744 {
745 ProresContext *ctx = avctx->priv_data;
746 int i, q, pq, xp, yp;
747 const uint16_t *src;
748 int slice_width_factor = av_log2(mbs_per_slice);
749 int num_cblocks[MAX_PLANES], pwidth;
750 int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];
751 const int min_quant = ctx->profile_info->min_quant;
752 const int max_quant = ctx->profile_info->max_quant;
753 int error, bits, bits_limit;
754 int mbs, prev, cur, new_score;
755 int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
756 int overquant;
757 uint16_t *qmat;
758 int linesize[4], line_add;
759
760 if (ctx->pictures_per_frame == 1)
761 line_add = 0;
762 else
763 line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
764 mbs = x + mbs_per_slice;
765
766 for (i = 0; i < ctx->num_planes; i++) {
767 is_chroma[i] = (i == 1 || i == 2);
768 plane_factor[i] = slice_width_factor + 2;
769 if (is_chroma[i])
770 plane_factor[i] += ctx->chroma_factor - 3;
771 if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
772 xp = x << 4;
773 yp = y << 4;
774 num_cblocks[i] = 4;
775 pwidth = avctx->width;
776 } else {
777 xp = x << 3;
778 yp = y << 4;
779 num_cblocks[i] = 2;
780 pwidth = avctx->width >> 1;
781 }
782
783 linesize[i] = pic->linesize[i] * ctx->pictures_per_frame;
784 src = (const uint16_t*)(pic->data[i] + yp * linesize[i] +
785 line_add * pic->linesize[i]) + xp;
786
787 if (i < 3) {
788 get_slice_data(ctx, src, linesize[i], xp, yp,
789 pwidth, avctx->height / ctx->pictures_per_frame,
790 td->blocks[i], td->emu_buf,
791 mbs_per_slice, num_cblocks[i], is_chroma[i]);
792 } else {
793 get_alpha_data(ctx, src, linesize[i], xp, yp,
794 pwidth, avctx->height / ctx->pictures_per_frame,
795 td->blocks[i], mbs_per_slice, ctx->alpha_bits);
796 }
797 }
798
799 for (q = min_quant; q < max_quant + 2; q++) {
800 td->nodes[trellis_node + q].prev_node = -1;
801 td->nodes[trellis_node + q].quant = q;
802 }
803
804 // todo: maybe perform coarser quantising to fit into frame size when needed
805 for (q = min_quant; q <= max_quant; q++) {
806 bits = 0;
807 error = 0;
808 for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) {
809 bits += estimate_slice_plane(ctx, &error, i,
810 src, linesize[i],
811 mbs_per_slice,
812 num_cblocks[i], plane_factor[i],
813 ctx->quants[q], td);
814 }
815 if (ctx->alpha_bits)
816 bits += estimate_alpha_plane(ctx, &error, src, linesize[3],
817 mbs_per_slice, q, td->blocks[3]);
818 if (bits > 65000 * 8) {
819 error = SCORE_LIMIT;
820 break;
821 }
822 slice_bits[q] = bits;
823 slice_score[q] = error;
824 }
825 if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
826 slice_bits[max_quant + 1] = slice_bits[max_quant];
827 slice_score[max_quant + 1] = slice_score[max_quant] + 1;
828 overquant = max_quant;
829 } else {
830 for (q = max_quant + 1; q < 128; q++) {
831 bits = 0;
832 error = 0;
833 if (q < MAX_STORED_Q) {
834 qmat = ctx->quants[q];
835 } else {
836 qmat = td->custom_q;
837 for (i = 0; i < 64; i++)
838 qmat[i] = ctx->quant_mat[i] * q;
839 }
840 for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) {
841 bits += estimate_slice_plane(ctx, &error, i,
842 src, linesize[i],
843 mbs_per_slice,
844 num_cblocks[i], plane_factor[i],
845 qmat, td);
846 }
847 if (ctx->alpha_bits)
848 bits += estimate_alpha_plane(ctx, &error, src, linesize[3],
849 mbs_per_slice, q, td->blocks[3]);
850 if (bits <= ctx->bits_per_mb * mbs_per_slice)
851 break;
852 }
853
854 slice_bits[max_quant + 1] = bits;
855 slice_score[max_quant + 1] = error;
856 overquant = q;
857 }
858 td->nodes[trellis_node + max_quant + 1].quant = overquant;
859
860 bits_limit = mbs * ctx->bits_per_mb;
861 for (pq = min_quant; pq < max_quant + 2; pq++) {
862 prev = trellis_node - TRELLIS_WIDTH + pq;
863
864 for (q = min_quant; q < max_quant + 2; q++) {
865 cur = trellis_node + q;
866
867 bits = td->nodes[prev].bits + slice_bits[q];
868 error = slice_score[q];
869 if (bits > bits_limit)
870 error = SCORE_LIMIT;
871
872 if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
873 new_score = td->nodes[prev].score + error;
874 else
875 new_score = SCORE_LIMIT;
876 if (td->nodes[cur].prev_node == -1 ||
877 td->nodes[cur].score >= new_score) {
878
879 td->nodes[cur].bits = bits;
880 td->nodes[cur].score = new_score;
881 td->nodes[cur].prev_node = prev;
882 }
883 }
884 }
885
886 error = td->nodes[trellis_node + min_quant].score;
887 pq = trellis_node + min_quant;
888 for (q = min_quant + 1; q < max_quant + 2; q++) {
889 if (td->nodes[trellis_node + q].score <= error) {
890 error = td->nodes[trellis_node + q].score;
891 pq = trellis_node + q;
892 }
893 }
894
895 return pq;
896 }
897
898 static int find_quant_thread(AVCodecContext *avctx, void *arg,
899 int jobnr, int threadnr)
900 {
901 ProresContext *ctx = avctx->priv_data;
902 ProresThreadData *td = ctx->tdata + threadnr;
903 int mbs_per_slice = ctx->mbs_per_slice;
904 int x, y = jobnr, mb, q = 0;
905
906 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
907 while (ctx->mb_width - x < mbs_per_slice)
908 mbs_per_slice >>= 1;
909 q = find_slice_quant(avctx, avctx->coded_frame,
910 (mb + 1) * TRELLIS_WIDTH, x, y,
911 mbs_per_slice, td);
912 }
913
914 for (x = ctx->slices_width - 1; x >= 0; x--) {
915 ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
916 q = td->nodes[q].prev_node;
917 }
918
919 return 0;
920 }
921
922 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
923 const AVFrame *pic, int *got_packet)
924 {
925 ProresContext *ctx = avctx->priv_data;
926 uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
927 uint8_t *picture_size_pos;
928 PutBitContext pb;
929 int x, y, i, mb, q = 0;
930 int sizes[4] = { 0 };
931 int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
932 int frame_size, picture_size, slice_size;
933 int pkt_size, ret;
934 uint8_t frame_flags;
935
936 *avctx->coded_frame = *pic;
937 avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
938 avctx->coded_frame->key_frame = 1;
939
940 pkt_size = ctx->frame_size_upper_bound + FF_MIN_BUFFER_SIZE;
941
942 if ((ret = ff_alloc_packet(pkt, pkt_size)) < 0) {
943 av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
944 return ret;
945 }
946
947 orig_buf = pkt->data;
948
949 // frame atom
950 orig_buf += 4; // frame size
951 bytestream_put_be32 (&orig_buf, FRAME_ID); // frame container ID
952 buf = orig_buf;
953
954 // frame header
955 tmp = buf;
956 buf += 2; // frame header size will be stored here
957 bytestream_put_be16 (&buf, 0); // version 1
958 bytestream_put_buffer(&buf, ctx->vendor, 4);
959 bytestream_put_be16 (&buf, avctx->width);
960 bytestream_put_be16 (&buf, avctx->height);
961
962 frame_flags = ctx->chroma_factor << 6;
963 if (avctx->flags & CODEC_FLAG_INTERLACED_DCT)
964 frame_flags |= pic->top_field_first ? 0x04 : 0x08;
965 bytestream_put_byte (&buf, frame_flags);
966
967 bytestream_put_byte (&buf, 0); // reserved
968 bytestream_put_byte (&buf, avctx->color_primaries);
969 bytestream_put_byte (&buf, avctx->color_trc);
970 bytestream_put_byte (&buf, avctx->colorspace);
971 bytestream_put_byte (&buf, 0x40 | (ctx->alpha_bits >> 3));
972 bytestream_put_byte (&buf, 0); // reserved
973 if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
974 bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present
975 // luma quantisation matrix
976 for (i = 0; i < 64; i++)
977 bytestream_put_byte(&buf, ctx->quant_mat[i]);
978 // chroma quantisation matrix
979 for (i = 0; i < 64; i++)
980 bytestream_put_byte(&buf, ctx->quant_mat[i]);
981 } else {
982 bytestream_put_byte (&buf, 0x00); // matrix flags - default matrices are used
983 }
984 bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
985
986 for (ctx->cur_picture_idx = 0;
987 ctx->cur_picture_idx < ctx->pictures_per_frame;
988 ctx->cur_picture_idx++) {
989 // picture header
990 picture_size_pos = buf + 1;
991 bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
992 buf += 4; // picture data size will be stored here
993 bytestream_put_be16 (&buf, ctx->slices_per_picture);
994 bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
995
996 // seek table - will be filled during slice encoding
997 slice_sizes = buf;
998 buf += ctx->slices_per_picture * 2;
999
1000 // slices
1001 if (!ctx->force_quant) {
1002 ret = avctx->execute2(avctx, find_quant_thread, NULL, NULL,
1003 ctx->mb_height);
1004 if (ret)
1005 return ret;
1006 }
1007
1008 for (y = 0; y < ctx->mb_height; y++) {
1009 int mbs_per_slice = ctx->mbs_per_slice;
1010 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
1011 q = ctx->force_quant ? ctx->force_quant
1012 : ctx->slice_q[mb + y * ctx->slices_width];
1013
1014 while (ctx->mb_width - x < mbs_per_slice)
1015 mbs_per_slice >>= 1;
1016
1017 bytestream_put_byte(&buf, slice_hdr_size << 3);
1018 slice_hdr = buf;
1019 buf += slice_hdr_size - 1;
1020 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)) * 8);
1021 encode_slice(avctx, pic, &pb, sizes, x, y, q, mbs_per_slice);
1022
1023 bytestream_put_byte(&slice_hdr, q);
1024 slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
1025 for (i = 0; i < ctx->num_planes - 1; i++) {
1026 bytestream_put_be16(&slice_hdr, sizes[i]);
1027 slice_size += sizes[i];
1028 }
1029 bytestream_put_be16(&slice_sizes, slice_size);
1030 buf += slice_size - slice_hdr_size;
1031 }
1032 }
1033
1034 if (ctx->pictures_per_frame == 1)
1035 picture_size = buf - picture_size_pos - 6;
1036 else
1037 picture_size = buf - picture_size_pos + 1;
1038 bytestream_put_be32(&picture_size_pos, picture_size);
1039 }
1040
1041 orig_buf -= 8;
1042 frame_size = buf - orig_buf;
1043 bytestream_put_be32(&orig_buf, frame_size);
1044
1045 pkt->size = frame_size;
1046 pkt->flags |= AV_PKT_FLAG_KEY;
1047 *got_packet = 1;
1048
1049 return 0;
1050 }
1051
1052 static av_cold int encode_close(AVCodecContext *avctx)
1053 {
1054 ProresContext *ctx = avctx->priv_data;
1055 int i;
1056
1057 av_freep(&avctx->coded_frame);
1058
1059 if (ctx->tdata) {
1060 for (i = 0; i < avctx->thread_count; i++)
1061 av_free(ctx->tdata[i].nodes);
1062 }
1063 av_freep(&ctx->tdata);
1064 av_freep(&ctx->slice_q);
1065
1066 return 0;
1067 }
1068
1069 static av_cold int encode_init(AVCodecContext *avctx)
1070 {
1071 ProresContext *ctx = avctx->priv_data;
1072 int mps;
1073 int i, j;
1074 int min_quant, max_quant;
1075 int interlaced = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
1076
1077 avctx->bits_per_raw_sample = 10;
1078 avctx->coded_frame = av_frame_alloc();
1079 if (!avctx->coded_frame)
1080 return AVERROR(ENOMEM);
1081
1082 ff_proresdsp_init(&ctx->dsp);
1083 ctx->scantable = interlaced ? ff_prores_interlaced_scan
1084 : ff_prores_progressive_scan;
1085
1086 mps = ctx->mbs_per_slice;
1087 if (mps & (mps - 1)) {
1088 av_log(avctx, AV_LOG_ERROR,
1089 "there should be an integer power of two MBs per slice\n");
1090 return AVERROR(EINVAL);
1091 }
1092 if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
1093 if (ctx->alpha_bits & 7) {
1094 av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
1095 return AVERROR(EINVAL);
1096 }
1097 } else {
1098 ctx->alpha_bits = 0;
1099 }
1100
1101 ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
1102 ? CFACTOR_Y422
1103 : CFACTOR_Y444;
1104 ctx->profile_info = prores_profile_info + ctx->profile;
1105 ctx->num_planes = 3 + !!ctx->alpha_bits;
1106
1107 ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
1108
1109 if (interlaced)
1110 ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
1111 else
1112 ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
1113
1114 ctx->slices_width = ctx->mb_width / mps;
1115 ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
1116 ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
1117 ctx->pictures_per_frame = 1 + interlaced;
1118
1119 if (ctx->quant_sel == -1)
1120 ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
1121 else
1122 ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
1123
1124 if (strlen(ctx->vendor) != 4) {
1125 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
1126 return AVERROR_INVALIDDATA;
1127 }
1128
1129 ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
1130 if (!ctx->force_quant) {
1131 if (!ctx->bits_per_mb) {
1132 for (i = 0; i < NUM_MB_LIMITS - 1; i++)
1133 if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
1134 ctx->pictures_per_frame)
1135 break;
1136 ctx->bits_per_mb = ctx->profile_info->br_tab[i];
1137 } else if (ctx->bits_per_mb < 128) {
1138 av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
1139 return AVERROR_INVALIDDATA;
1140 }
1141
1142 min_quant = ctx->profile_info->min_quant;
1143 max_quant = ctx->profile_info->max_quant;
1144 for (i = min_quant; i < MAX_STORED_Q; i++) {
1145 for (j = 0; j < 64; j++)
1146 ctx->quants[i][j] = ctx->quant_mat[j] * i;
1147 }
1148
1149 ctx->slice_q = av_malloc(ctx->slices_per_picture * sizeof(*ctx->slice_q));
1150 if (!ctx->slice_q) {
1151 encode_close(avctx);
1152 return AVERROR(ENOMEM);
1153 }
1154
1155 ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
1156 if (!ctx->tdata) {
1157 encode_close(avctx);
1158 return AVERROR(ENOMEM);
1159 }
1160
1161 for (j = 0; j < avctx->thread_count; j++) {
1162 ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
1163 * TRELLIS_WIDTH
1164 * sizeof(*ctx->tdata->nodes));
1165 if (!ctx->tdata[j].nodes) {
1166 encode_close(avctx);
1167 return AVERROR(ENOMEM);
1168 }
1169 for (i = min_quant; i < max_quant + 2; i++) {
1170 ctx->tdata[j].nodes[i].prev_node = -1;
1171 ctx->tdata[j].nodes[i].bits = 0;
1172 ctx->tdata[j].nodes[i].score = 0;
1173 }
1174 }
1175 } else {
1176 int ls = 0;
1177
1178 if (ctx->force_quant > 64) {
1179 av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
1180 return AVERROR_INVALIDDATA;
1181 }
1182
1183 for (j = 0; j < 64; j++) {
1184 ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
1185 ls += av_log2((1 << 11) / ctx->quants[0][j]) * 2 + 1;
1186 }
1187
1188 ctx->bits_per_mb = ls * 8;
1189 if (ctx->chroma_factor == CFACTOR_Y444)
1190 ctx->bits_per_mb += ls * 4;
1191 if (ctx->num_planes == 4)
1192 ctx->bits_per_mb += ls * 4;
1193 }
1194
1195 ctx->frame_size_upper_bound = ctx->pictures_per_frame *
1196 ctx->slices_per_picture *
1197 (2 + 2 * ctx->num_planes +
1198 (mps * ctx->bits_per_mb) / 8)
1199 + 200;
1200
1201 avctx->codec_tag = ctx->profile_info->tag;
1202
1203 av_log(avctx, AV_LOG_DEBUG,
1204 "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
1205 ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
1206 interlaced ? "yes" : "no", ctx->bits_per_mb);
1207 av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
1208 ctx->frame_size_upper_bound);
1209
1210 return 0;
1211 }
1212
1213 #define OFFSET(x) offsetof(ProresContext, x)
1214 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1215
1216 static const AVOption options[] = {
1217 { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
1218 AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
1219 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
1220 { .i64 = PRORES_PROFILE_STANDARD },
1221 PRORES_PROFILE_PROXY, PRORES_PROFILE_4444, VE, "profile" },
1222 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
1223 0, 0, VE, "profile" },
1224 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
1225 0, 0, VE, "profile" },
1226 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
1227 0, 0, VE, "profile" },
1228 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
1229 0, 0, VE, "profile" },
1230 { "4444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
1231 0, 0, VE, "profile" },
1232 { "vendor", "vendor ID", OFFSET(vendor),
1233 AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE },
1234 { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
1235 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
1236 { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
1237 { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, "quant_mat" },
1238 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
1239 0, 0, VE, "quant_mat" },
1240 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
1241 0, 0, VE, "quant_mat" },
1242 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
1243 0, 0, VE, "quant_mat" },
1244 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
1245 0, 0, VE, "quant_mat" },
1246 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
1247 0, 0, VE, "quant_mat" },
1248 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
1249 0, 0, VE, "quant_mat" },
1250 { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
1251 { .i64 = 16 }, 0, 16, VE },
1252 { NULL }
1253 };
1254
1255 static const AVClass proresenc_class = {
1256 .class_name = "ProRes encoder",
1257 .item_name = av_default_item_name,
1258 .option = options,
1259 .version = LIBAVUTIL_VERSION_INT,
1260 };
1261
1262 AVCodec ff_prores_encoder = {
1263 .name = "prores",
1264 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
1265 .type = AVMEDIA_TYPE_VIDEO,
1266 .id = AV_CODEC_ID_PRORES,
1267 .priv_data_size = sizeof(ProresContext),
1268 .init = encode_init,
1269 .close = encode_close,
1270 .encode2 = encode_frame,
1271 .capabilities = CODEC_CAP_SLICE_THREADS,
1272 .pix_fmts = (const enum AVPixelFormat[]) {
1273 AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
1274 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
1275 },
1276 .priv_class = &proresenc_class,
1277 };