Libav
proresenc.c
Go to the documentation of this file.
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 {
46 };
47 
48 enum {
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;
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 {
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];
185 
186 typedef struct ProresContext {
187  AVClass *class;
189  DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
190  int16_t quants[MAX_STORED_Q][64];
191  int16_t custom_q[64];
193 
196 
202  int pictures_per_frame; // 1 for progressive, 2 for interlaced
208  int warn;
209 
210  char *vendor;
212 
214 
215  int profile;
217 
218  int *slice_q;
219 
221 } ProresContext;
222 
223 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
224  int linesize, int x, int y, int w, int h,
225  int16_t *blocks, uint16_t *emu_buf,
226  int mbs_per_slice, int blocks_per_mb, int is_chroma)
227 {
228  const uint16_t *esrc;
229  const int mb_width = 4 * blocks_per_mb;
230  int elinesize;
231  int i, j, k;
232 
233  for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
234  if (x >= w) {
235  memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
236  * sizeof(*blocks));
237  return;
238  }
239  if (x + mb_width <= w && y + 16 <= h) {
240  esrc = src;
241  elinesize = linesize;
242  } else {
243  int bw, bh, pix;
244 
245  esrc = emu_buf;
246  elinesize = 16 * sizeof(*emu_buf);
247 
248  bw = FFMIN(w - x, mb_width);
249  bh = FFMIN(h - y, 16);
250 
251  for (j = 0; j < bh; j++) {
252  memcpy(emu_buf + j * 16,
253  (const uint8_t*)src + j * linesize,
254  bw * sizeof(*src));
255  pix = emu_buf[j * 16 + bw - 1];
256  for (k = bw; k < mb_width; k++)
257  emu_buf[j * 16 + k] = pix;
258  }
259  for (; j < 16; j++)
260  memcpy(emu_buf + j * 16,
261  emu_buf + (bh - 1) * 16,
262  mb_width * sizeof(*emu_buf));
263  }
264  if (!is_chroma) {
265  ctx->dsp.fdct(esrc, elinesize, blocks);
266  blocks += 64;
267  if (blocks_per_mb > 2) {
268  ctx->dsp.fdct(esrc + 8, elinesize, blocks);
269  blocks += 64;
270  }
271  ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
272  blocks += 64;
273  if (blocks_per_mb > 2) {
274  ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
275  blocks += 64;
276  }
277  } else {
278  ctx->dsp.fdct(esrc, elinesize, blocks);
279  blocks += 64;
280  ctx->dsp.fdct(esrc + elinesize * 4, elinesize, blocks);
281  blocks += 64;
282  if (blocks_per_mb > 2) {
283  ctx->dsp.fdct(esrc + 8, elinesize, blocks);
284  blocks += 64;
285  ctx->dsp.fdct(esrc + elinesize * 4 + 8, elinesize, blocks);
286  blocks += 64;
287  }
288  }
289 
290  x += mb_width;
291  }
292 }
293 
294 static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
295  int linesize, int x, int y, int w, int h,
296  int16_t *blocks, int mbs_per_slice, int abits)
297 {
298  const int slice_width = 16 * mbs_per_slice;
299  int i, j, copy_w, copy_h;
300 
301  copy_w = FFMIN(w - x, slice_width);
302  copy_h = FFMIN(h - y, 16);
303  for (i = 0; i < copy_h; i++) {
304  memcpy(blocks, src, copy_w * sizeof(*src));
305  if (abits == 8)
306  for (j = 0; j < copy_w; j++)
307  blocks[j] >>= 2;
308  else
309  for (j = 0; j < copy_w; j++)
310  blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
311  for (j = copy_w; j < slice_width; j++)
312  blocks[j] = blocks[copy_w - 1];
313  blocks += slice_width;
314  src += linesize >> 1;
315  }
316  for (; i < 16; i++) {
317  memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
318  blocks += slice_width;
319  }
320 }
321 
325 static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
326 {
327  unsigned int rice_order, exp_order, switch_bits, switch_val;
328  int exponent;
329 
330  /* number of prefix bits to switch between Rice and expGolomb */
331  switch_bits = (codebook & 3) + 1;
332  rice_order = codebook >> 5; /* rice code order */
333  exp_order = (codebook >> 2) & 7; /* exp golomb code order */
334 
335  switch_val = switch_bits << rice_order;
336 
337  if (val >= switch_val) {
338  val -= switch_val - (1 << exp_order);
339  exponent = av_log2(val);
340 
341  put_bits(pb, exponent - exp_order + switch_bits, 0);
342  put_bits(pb, exponent + 1, val);
343  } else {
344  exponent = val >> rice_order;
345 
346  if (exponent)
347  put_bits(pb, exponent, 0);
348  put_bits(pb, 1, 1);
349  if (rice_order)
350  put_sbits(pb, rice_order, val);
351  }
352 }
353 
354 #define GET_SIGN(x) ((x) >> 31)
355 #define MAKE_CODE(x) (((x) << 1) ^ GET_SIGN(x))
356 
357 static void encode_dcs(PutBitContext *pb, int16_t *blocks,
358  int blocks_per_slice, int scale)
359 {
360  int i;
361  int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
362 
363  prev_dc = (blocks[0] - 0x4000) / scale;
365  sign = 0;
366  codebook = 3;
367  blocks += 64;
368 
369  for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
370  dc = (blocks[0] - 0x4000) / scale;
371  delta = dc - prev_dc;
372  new_sign = GET_SIGN(delta);
373  delta = (delta ^ sign) - sign;
374  code = MAKE_CODE(delta);
375  encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
376  codebook = (code + (code & 1)) >> 1;
377  codebook = FFMIN(codebook, 3);
378  sign = new_sign;
379  prev_dc = dc;
380  }
381 }
382 
383 static void encode_acs(PutBitContext *pb, int16_t *blocks,
384  int blocks_per_slice,
385  int plane_size_factor,
386  const uint8_t *scan, const int16_t *qmat)
387 {
388  int idx, i;
389  int run, level, run_cb, lev_cb;
390  int max_coeffs, abs_level;
391 
392  max_coeffs = blocks_per_slice << 6;
393  run_cb = ff_prores_run_to_cb_index[4];
394  lev_cb = ff_prores_lev_to_cb_index[2];
395  run = 0;
396 
397  for (i = 1; i < 64; i++) {
398  for (idx = scan[i]; idx < max_coeffs; idx += 64) {
399  level = blocks[idx] / qmat[scan[i]];
400  if (level) {
401  abs_level = FFABS(level);
402  encode_vlc_codeword(pb, ff_prores_ac_codebook[run_cb], run);
404  abs_level - 1);
405  put_sbits(pb, 1, GET_SIGN(level));
406 
407  run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
408  lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
409  run = 0;
410  } else {
411  run++;
412  }
413  }
414  }
415 }
416 
418  const uint16_t *src, int linesize,
419  int mbs_per_slice, int16_t *blocks,
420  int blocks_per_mb, int plane_size_factor,
421  const int16_t *qmat)
422 {
423  int blocks_per_slice, saved_pos;
424 
425  saved_pos = put_bits_count(pb);
426  blocks_per_slice = mbs_per_slice * blocks_per_mb;
427 
428  encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
429  encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
430  ctx->scantable.permutated, qmat);
431  flush_put_bits(pb);
432 
433  return (put_bits_count(pb) - saved_pos) >> 3;
434 }
435 
436 static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
437 {
438  const int mask = (1 << abits) - 1;
439  const int dbits = (abits == 8) ? 4 : 7;
440  const int dsize = 1 << dbits - 1;
441  int diff = cur - prev;
442 
443  diff &= mask;
444  if (diff >= (1 << abits) - dsize)
445  diff -= 1 << abits;
446  if (diff < -dsize || diff > dsize || !diff) {
447  put_bits(pb, 1, 1);
448  put_bits(pb, abits, diff);
449  } else {
450  put_bits(pb, 1, 0);
451  put_bits(pb, dbits - 1, FFABS(diff) - 1);
452  put_bits(pb, 1, diff < 0);
453  }
454 }
455 
456 static void put_alpha_run(PutBitContext *pb, int run)
457 {
458  if (run) {
459  put_bits(pb, 1, 0);
460  if (run < 0x10)
461  put_bits(pb, 4, run);
462  else
463  put_bits(pb, 15, run);
464  } else {
465  put_bits(pb, 1, 1);
466  }
467 }
468 
469 // todo alpha quantisation for high quants
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, mbs_per_slice,
566  ctx->blocks[0], quant);
567  }
568  total_size += sizes[i];
569  if (put_bits_left(pb) < 0) {
570  av_log(avctx, AV_LOG_ERROR,
571  "Underestimated required buffer size.\n");
572  return AVERROR_BUG;
573  }
574  }
575  return total_size;
576 }
577 
578 static inline int estimate_vlc(unsigned codebook, int val)
579 {
580  unsigned int rice_order, exp_order, switch_bits, switch_val;
581  int exponent;
582 
583  /* number of prefix bits to switch between Rice and expGolomb */
584  switch_bits = (codebook & 3) + 1;
585  rice_order = codebook >> 5; /* rice code order */
586  exp_order = (codebook >> 2) & 7; /* exp golomb code order */
587 
588  switch_val = switch_bits << rice_order;
589 
590  if (val >= switch_val) {
591  val -= switch_val - (1 << exp_order);
592  exponent = av_log2(val);
593 
594  return exponent * 2 - exp_order + switch_bits + 1;
595  } else {
596  return (val >> rice_order) + rice_order + 1;
597  }
598 }
599 
600 static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
601  int scale)
602 {
603  int i;
604  int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
605  int bits;
606 
607  prev_dc = (blocks[0] - 0x4000) / scale;
608  bits = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
609  sign = 0;
610  codebook = 3;
611  blocks += 64;
612  *error += FFABS(blocks[0] - 0x4000) % scale;
613 
614  for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
615  dc = (blocks[0] - 0x4000) / scale;
616  *error += FFABS(blocks[0] - 0x4000) % scale;
617  delta = dc - prev_dc;
618  new_sign = GET_SIGN(delta);
619  delta = (delta ^ sign) - sign;
620  code = MAKE_CODE(delta);
621  bits += estimate_vlc(ff_prores_dc_codebook[codebook], code);
622  codebook = (code + (code & 1)) >> 1;
623  codebook = FFMIN(codebook, 3);
624  sign = new_sign;
625  prev_dc = dc;
626  }
627 
628  return bits;
629 }
630 
631 static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
632  int plane_size_factor,
633  const uint8_t *scan, const int16_t *qmat)
634 {
635  int idx, i;
636  int run, level, run_cb, lev_cb;
637  int max_coeffs, abs_level;
638  int bits = 0;
639 
640  max_coeffs = blocks_per_slice << 6;
641  run_cb = ff_prores_run_to_cb_index[4];
642  lev_cb = ff_prores_lev_to_cb_index[2];
643  run = 0;
644 
645  for (i = 1; i < 64; i++) {
646  for (idx = scan[i]; idx < max_coeffs; idx += 64) {
647  level = blocks[idx] / qmat[scan[i]];
648  *error += FFABS(blocks[idx]) % qmat[scan[i]];
649  if (level) {
650  abs_level = FFABS(level);
651  bits += estimate_vlc(ff_prores_ac_codebook[run_cb], run);
652  bits += estimate_vlc(ff_prores_ac_codebook[lev_cb],
653  abs_level - 1) + 1;
654 
655  run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
656  lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
657  run = 0;
658  } else {
659  run++;
660  }
661  }
662  }
663 
664  return bits;
665 }
666 
667 static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
668  const uint16_t *src, int linesize,
669  int mbs_per_slice,
670  int blocks_per_mb, int plane_size_factor,
671  const int16_t *qmat, ProresThreadData *td)
672 {
673  int blocks_per_slice;
674  int bits;
675 
676  blocks_per_slice = mbs_per_slice * blocks_per_mb;
677 
678  bits = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
679  bits += estimate_acs(error, td->blocks[plane], blocks_per_slice,
680  plane_size_factor, ctx->scantable.permutated, qmat);
681 
682  return FFALIGN(bits, 8);
683 }
684 
685 static int est_alpha_diff(int cur, int prev, int abits)
686 {
687  const int mask = (1 << abits) - 1;
688  const int dbits = (abits == 8) ? 4 : 7;
689  const int dsize = 1 << dbits - 1;
690  int diff = cur - prev;
691 
692  diff &= mask;
693  if (diff >= (1 << abits) - dsize)
694  diff -= 1 << abits;
695  if (diff < -dsize || diff > dsize || !diff)
696  return abits + 1;
697  else
698  return dbits + 1;
699 }
700 
701 static int estimate_alpha_plane(ProresContext *ctx, int *error,
702  const uint16_t *src, int linesize,
703  int mbs_per_slice, int quant,
704  int16_t *blocks)
705 {
706  const int abits = ctx->alpha_bits;
707  const int mask = (1 << abits) - 1;
708  const int num_coeffs = mbs_per_slice * 256;
709  int prev = mask, cur;
710  int idx = 0;
711  int run = 0;
712  int bits;
713 
714  *error = 0;
715  cur = blocks[idx++];
716  bits = est_alpha_diff(cur, prev, abits);
717  prev = cur;
718  do {
719  cur = blocks[idx++];
720  if (cur != prev) {
721  if (!run)
722  bits++;
723  else if (run < 0x10)
724  bits += 4;
725  else
726  bits += 15;
727  bits += est_alpha_diff(cur, prev, abits);
728  prev = cur;
729  run = 0;
730  } else {
731  run++;
732  }
733  } while (idx < num_coeffs);
734 
735  if (run) {
736  if (run < 0x10)
737  bits += 4;
738  else
739  bits += 15;
740  }
741 
742  return bits;
743 }
744 
745 static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
746  int trellis_node, int x, int y, int mbs_per_slice,
747  ProresThreadData *td)
748 {
749  ProresContext *ctx = avctx->priv_data;
750  int i, q, pq, xp, yp;
751  const uint16_t *src;
752  int slice_width_factor = av_log2(mbs_per_slice);
753  int num_cblocks[MAX_PLANES], pwidth;
754  int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];
755  const int min_quant = ctx->profile_info->min_quant;
756  const int max_quant = ctx->profile_info->max_quant;
757  int error, bits, bits_limit;
758  int mbs, prev, cur, new_score;
759  int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
760  int overquant;
761  uint16_t *qmat;
762  int linesize[4], line_add;
763 
764  if (ctx->pictures_per_frame == 1)
765  line_add = 0;
766  else
767  line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
768  mbs = x + mbs_per_slice;
769 
770  for (i = 0; i < ctx->num_planes; i++) {
771  is_chroma[i] = (i == 1 || i == 2);
772  plane_factor[i] = slice_width_factor + 2;
773  if (is_chroma[i])
774  plane_factor[i] += ctx->chroma_factor - 3;
775  if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
776  xp = x << 4;
777  yp = y << 4;
778  num_cblocks[i] = 4;
779  pwidth = avctx->width;
780  } else {
781  xp = x << 3;
782  yp = y << 4;
783  num_cblocks[i] = 2;
784  pwidth = avctx->width >> 1;
785  }
786 
787  linesize[i] = pic->linesize[i] * ctx->pictures_per_frame;
788  src = (const uint16_t*)(pic->data[i] + yp * linesize[i] +
789  line_add * pic->linesize[i]) + xp;
790 
791  if (i < 3) {
792  get_slice_data(ctx, src, linesize[i], xp, yp,
793  pwidth, avctx->height / ctx->pictures_per_frame,
794  td->blocks[i], td->emu_buf,
795  mbs_per_slice, num_cblocks[i], is_chroma[i]);
796  } else {
797  get_alpha_data(ctx, src, linesize[i], xp, yp,
798  pwidth, avctx->height / ctx->pictures_per_frame,
799  td->blocks[i], mbs_per_slice, ctx->alpha_bits);
800  }
801  }
802 
803  for (q = min_quant; q < max_quant + 2; q++) {
804  td->nodes[trellis_node + q].prev_node = -1;
805  td->nodes[trellis_node + q].quant = q;
806  }
807 
808  // todo: maybe perform coarser quantising to fit into frame size when needed
809  for (q = min_quant; q <= max_quant; q++) {
810  bits = 0;
811  error = 0;
812  for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) {
813  bits += estimate_slice_plane(ctx, &error, i,
814  src, linesize[i],
815  mbs_per_slice,
816  num_cblocks[i], plane_factor[i],
817  ctx->quants[q], td);
818  }
819  if (ctx->alpha_bits)
820  bits += estimate_alpha_plane(ctx, &error, src, linesize[3],
821  mbs_per_slice, q, td->blocks[3]);
822  if (bits > 65000 * 8) {
823  error = SCORE_LIMIT;
824  break;
825  }
826  slice_bits[q] = bits;
827  slice_score[q] = error;
828  }
829  if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
830  slice_bits[max_quant + 1] = slice_bits[max_quant];
831  slice_score[max_quant + 1] = slice_score[max_quant] + 1;
832  overquant = max_quant;
833  } else {
834  for (q = max_quant + 1; q < 128; q++) {
835  bits = 0;
836  error = 0;
837  if (q < MAX_STORED_Q) {
838  qmat = ctx->quants[q];
839  } else {
840  qmat = td->custom_q;
841  for (i = 0; i < 64; i++)
842  qmat[i] = ctx->quant_mat[i] * q;
843  }
844  for (i = 0; i < ctx->num_planes - !!ctx->alpha_bits; i++) {
845  bits += estimate_slice_plane(ctx, &error, i,
846  src, linesize[i],
847  mbs_per_slice,
848  num_cblocks[i], plane_factor[i],
849  qmat, td);
850  }
851  if (ctx->alpha_bits)
852  bits += estimate_alpha_plane(ctx, &error, src, linesize[3],
853  mbs_per_slice, q, td->blocks[3]);
854  if (bits <= ctx->bits_per_mb * mbs_per_slice)
855  break;
856  }
857 
858  slice_bits[max_quant + 1] = bits;
859  slice_score[max_quant + 1] = error;
860  overquant = q;
861  }
862  td->nodes[trellis_node + max_quant + 1].quant = overquant;
863 
864  bits_limit = mbs * ctx->bits_per_mb;
865  for (pq = min_quant; pq < max_quant + 2; pq++) {
866  prev = trellis_node - TRELLIS_WIDTH + pq;
867 
868  for (q = min_quant; q < max_quant + 2; q++) {
869  cur = trellis_node + q;
870 
871  bits = td->nodes[prev].bits + slice_bits[q];
872  error = slice_score[q];
873  if (bits > bits_limit)
874  error = SCORE_LIMIT;
875 
876  if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
877  new_score = td->nodes[prev].score + error;
878  else
879  new_score = SCORE_LIMIT;
880  if (td->nodes[cur].prev_node == -1 ||
881  td->nodes[cur].score >= new_score) {
882 
883  td->nodes[cur].bits = bits;
884  td->nodes[cur].score = new_score;
885  td->nodes[cur].prev_node = prev;
886  }
887  }
888  }
889 
890  error = td->nodes[trellis_node + min_quant].score;
891  pq = trellis_node + min_quant;
892  for (q = min_quant + 1; q < max_quant + 2; q++) {
893  if (td->nodes[trellis_node + q].score <= error) {
894  error = td->nodes[trellis_node + q].score;
895  pq = trellis_node + q;
896  }
897  }
898 
899  return pq;
900 }
901 
902 static int find_quant_thread(AVCodecContext *avctx, void *arg,
903  int jobnr, int threadnr)
904 {
905  ProresContext *ctx = avctx->priv_data;
906  ProresThreadData *td = ctx->tdata + threadnr;
907  int mbs_per_slice = ctx->mbs_per_slice;
908  int x, y = jobnr, mb, q = 0;
909 
910  for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
911  while (ctx->mb_width - x < mbs_per_slice)
912  mbs_per_slice >>= 1;
913  q = find_slice_quant(avctx, avctx->coded_frame,
914  (mb + 1) * TRELLIS_WIDTH, x, y,
915  mbs_per_slice, td);
916  }
917 
918  for (x = ctx->slices_width - 1; x >= 0; x--) {
919  ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
920  q = td->nodes[q].prev_node;
921  }
922 
923  return 0;
924 }
925 
926 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
927  const AVFrame *pic, int *got_packet)
928 {
929  ProresContext *ctx = avctx->priv_data;
930  uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
931  uint8_t *picture_size_pos;
932  PutBitContext pb;
933  int x, y, i, mb, q = 0;
934  int sizes[4] = { 0 };
935  int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
936  int frame_size, picture_size, slice_size;
937  int pkt_size, ret, max_slice_size = 0;
938  uint8_t frame_flags;
939 
940  *avctx->coded_frame = *pic;
942  avctx->coded_frame->key_frame = 1;
943 
944  pkt_size = ctx->frame_size_upper_bound;
945 
946  if ((ret = ff_alloc_packet(pkt, pkt_size + FF_MIN_BUFFER_SIZE)) < 0) {
947  av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
948  return ret;
949  }
950 
951  orig_buf = pkt->data;
952 
953  // frame atom
954  orig_buf += 4; // frame size
955  bytestream_put_be32 (&orig_buf, FRAME_ID); // frame container ID
956  buf = orig_buf;
957 
958  // frame header
959  tmp = buf;
960  buf += 2; // frame header size will be stored here
961  bytestream_put_be16 (&buf, 0); // version 1
962  bytestream_put_buffer(&buf, ctx->vendor, 4);
963  bytestream_put_be16 (&buf, avctx->width);
964  bytestream_put_be16 (&buf, avctx->height);
965 
966  frame_flags = ctx->chroma_factor << 6;
967  if (avctx->flags & CODEC_FLAG_INTERLACED_DCT)
968  frame_flags |= pic->top_field_first ? 0x04 : 0x08;
969  bytestream_put_byte (&buf, frame_flags);
970 
971  bytestream_put_byte (&buf, 0); // reserved
972  bytestream_put_byte (&buf, avctx->color_primaries);
973  bytestream_put_byte (&buf, avctx->color_trc);
974  bytestream_put_byte (&buf, avctx->colorspace);
975  bytestream_put_byte (&buf, 0x40 | (ctx->alpha_bits >> 3));
976  bytestream_put_byte (&buf, 0); // reserved
977  if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
978  bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present
979  // luma quantisation matrix
980  for (i = 0; i < 64; i++)
981  bytestream_put_byte(&buf, ctx->quant_mat[i]);
982  // chroma quantisation matrix
983  for (i = 0; i < 64; i++)
984  bytestream_put_byte(&buf, ctx->quant_mat[i]);
985  } else {
986  bytestream_put_byte (&buf, 0x00); // matrix flags - default matrices are used
987  }
988  bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
989 
990  for (ctx->cur_picture_idx = 0;
992  ctx->cur_picture_idx++) {
993  // picture header
994  picture_size_pos = buf + 1;
995  bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
996  buf += 4; // picture data size will be stored here
997  bytestream_put_be16 (&buf, ctx->slices_per_picture);
998  bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
999 
1000  // seek table - will be filled during slice encoding
1001  slice_sizes = buf;
1002  buf += ctx->slices_per_picture * 2;
1003 
1004  // slices
1005  if (!ctx->force_quant) {
1006  ret = avctx->execute2(avctx, find_quant_thread, NULL, NULL,
1007  ctx->mb_height);
1008  if (ret)
1009  return ret;
1010  }
1011 
1012  for (y = 0; y < ctx->mb_height; y++) {
1013  int mbs_per_slice = ctx->mbs_per_slice;
1014  for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
1015  q = ctx->force_quant ? ctx->force_quant
1016  : ctx->slice_q[mb + y * ctx->slices_width];
1017 
1018  while (ctx->mb_width - x < mbs_per_slice)
1019  mbs_per_slice >>= 1;
1020 
1021  bytestream_put_byte(&buf, slice_hdr_size << 3);
1022  slice_hdr = buf;
1023  buf += slice_hdr_size - 1;
1024  if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
1025  uint8_t *start = pkt->data;
1026  // Recompute new size according to max_slice_size
1027  // and deduce delta
1028  int delta = 200 + ctx->pictures_per_frame *
1029  ctx->slices_per_picture * max_slice_size -
1030  pkt_size;
1031 
1032  delta = FFMAX(delta, 2 * max_slice_size);
1033  ctx->frame_size_upper_bound += delta;
1034 
1035  if (!ctx->warn) {
1036  avpriv_request_sample(avctx,
1037  "Packet too small: is %i,"
1038  " needs %i (slice: %i). "
1039  "Correct allocation",
1040  pkt_size, delta, max_slice_size);
1041  ctx->warn = 1;
1042  }
1043 
1044  ret = av_grow_packet(pkt, delta);
1045  if (ret < 0)
1046  return ret;
1047 
1048  pkt_size += delta;
1049  // restore pointers
1050  orig_buf = pkt->data + (orig_buf - start);
1051  buf = pkt->data + (buf - start);
1052  picture_size_pos = pkt->data + (picture_size_pos - start);
1053  slice_sizes = pkt->data + (slice_sizes - start);
1054  slice_hdr = pkt->data + (slice_hdr - start);
1055  tmp = pkt->data + (tmp - start);
1056  }
1057  init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)) * 8);
1058  ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
1059  mbs_per_slice);
1060  if (ret < 0)
1061  return ret;
1062 
1063  bytestream_put_byte(&slice_hdr, q);
1064  slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
1065  for (i = 0; i < ctx->num_planes - 1; i++) {
1066  bytestream_put_be16(&slice_hdr, sizes[i]);
1067  slice_size += sizes[i];
1068  }
1069  bytestream_put_be16(&slice_sizes, slice_size);
1070  buf += slice_size - slice_hdr_size;
1071  if (max_slice_size < slice_size)
1072  max_slice_size = slice_size;
1073  }
1074  }
1075 
1076  if (ctx->pictures_per_frame == 1)
1077  picture_size = buf - picture_size_pos - 6;
1078  else
1079  picture_size = buf - picture_size_pos + 1;
1080  bytestream_put_be32(&picture_size_pos, picture_size);
1081  }
1082 
1083  orig_buf -= 8;
1084  frame_size = buf - orig_buf;
1085  bytestream_put_be32(&orig_buf, frame_size);
1086 
1087  pkt->size = frame_size;
1088  pkt->flags |= AV_PKT_FLAG_KEY;
1089  *got_packet = 1;
1090 
1091  return 0;
1092 }
1093 
1095 {
1096  ProresContext *ctx = avctx->priv_data;
1097  int i;
1098 
1099  av_freep(&avctx->coded_frame);
1100 
1101  if (ctx->tdata) {
1102  for (i = 0; i < avctx->thread_count; i++)
1103  av_free(ctx->tdata[i].nodes);
1104  }
1105  av_freep(&ctx->tdata);
1106  av_freep(&ctx->slice_q);
1107 
1108  return 0;
1109 }
1110 
1112 {
1113  ProresContext *ctx = avctx->priv_data;
1114  int mps;
1115  int i, j;
1116  int min_quant, max_quant;
1117  int interlaced = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT);
1118 
1119  avctx->bits_per_raw_sample = 10;
1120  avctx->coded_frame = av_frame_alloc();
1121  if (!avctx->coded_frame)
1122  return AVERROR(ENOMEM);
1123 
1124  ff_proresdsp_init(&ctx->dsp);
1126  interlaced ? ff_prores_interlaced_scan
1128 
1129  mps = ctx->mbs_per_slice;
1130  if (mps & (mps - 1)) {
1131  av_log(avctx, AV_LOG_ERROR,
1132  "there should be an integer power of two MBs per slice\n");
1133  return AVERROR(EINVAL);
1134  }
1136  if (ctx->alpha_bits & 7) {
1137  av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
1138  return AVERROR(EINVAL);
1139  }
1140  } else {
1141  ctx->alpha_bits = 0;
1142  }
1143 
1144  ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
1145  ? CFACTOR_Y422
1146  : CFACTOR_Y444;
1148  ctx->num_planes = 3 + !!ctx->alpha_bits;
1149 
1150  ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
1151 
1152  if (interlaced)
1153  ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
1154  else
1155  ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
1156 
1157  ctx->slices_width = ctx->mb_width / mps;
1158  ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
1159  ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
1160  ctx->pictures_per_frame = 1 + interlaced;
1161 
1162  if (ctx->quant_sel == -1)
1164  else
1166 
1167  if (strlen(ctx->vendor) != 4) {
1168  av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
1169  return AVERROR_INVALIDDATA;
1170  }
1171 
1172  ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
1173  if (!ctx->force_quant) {
1174  if (!ctx->bits_per_mb) {
1175  for (i = 0; i < NUM_MB_LIMITS - 1; i++)
1176  if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
1177  ctx->pictures_per_frame)
1178  break;
1179  ctx->bits_per_mb = ctx->profile_info->br_tab[i];
1180  } else if (ctx->bits_per_mb < 128) {
1181  av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
1182  return AVERROR_INVALIDDATA;
1183  }
1184 
1185  min_quant = ctx->profile_info->min_quant;
1186  max_quant = ctx->profile_info->max_quant;
1187  for (i = min_quant; i < MAX_STORED_Q; i++) {
1188  for (j = 0; j < 64; j++)
1189  ctx->quants[i][j] = ctx->quant_mat[j] * i;
1190  }
1191 
1192  ctx->slice_q = av_malloc(ctx->slices_per_picture * sizeof(*ctx->slice_q));
1193  if (!ctx->slice_q) {
1194  encode_close(avctx);
1195  return AVERROR(ENOMEM);
1196  }
1197 
1198  ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
1199  if (!ctx->tdata) {
1200  encode_close(avctx);
1201  return AVERROR(ENOMEM);
1202  }
1203 
1204  for (j = 0; j < avctx->thread_count; j++) {
1205  ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
1206  * TRELLIS_WIDTH
1207  * sizeof(*ctx->tdata->nodes));
1208  if (!ctx->tdata[j].nodes) {
1209  encode_close(avctx);
1210  return AVERROR(ENOMEM);
1211  }
1212  for (i = min_quant; i < max_quant + 2; i++) {
1213  ctx->tdata[j].nodes[i].prev_node = -1;
1214  ctx->tdata[j].nodes[i].bits = 0;
1215  ctx->tdata[j].nodes[i].score = 0;
1216  }
1217  }
1218  } else {
1219  int ls = 0;
1220 
1221  if (ctx->force_quant > 64) {
1222  av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
1223  return AVERROR_INVALIDDATA;
1224  }
1225 
1226  for (j = 0; j < 64; j++) {
1227  ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
1228  ls += av_log2((1 << 11) / ctx->quants[0][j]) * 2 + 1;
1229  }
1230 
1231  ctx->bits_per_mb = ls * 8;
1232  if (ctx->chroma_factor == CFACTOR_Y444)
1233  ctx->bits_per_mb += ls * 4;
1234  }
1235 
1237  ctx->slices_per_picture *
1238  (2 + 2 * ctx->num_planes +
1239  (mps * ctx->bits_per_mb) / 8)
1240  + 200;
1241 
1242  if (ctx->alpha_bits) {
1243  // The alpha plane is run-coded and might exceed the bit budget.
1245  ctx->slices_per_picture *
1246  /* num pixels per slice */ (ctx->mbs_per_slice * 256 *
1247  /* bits per pixel */ (1 + ctx->alpha_bits + 1) + 7 >> 3);
1248  }
1249 
1250  avctx->codec_tag = ctx->profile_info->tag;
1251 
1252  av_log(avctx, AV_LOG_DEBUG,
1253  "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
1254  ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
1255  interlaced ? "yes" : "no", ctx->bits_per_mb);
1256  av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
1257  ctx->frame_size_upper_bound);
1258 
1259  return 0;
1260 }
1261 
1262 #define OFFSET(x) offsetof(ProresContext, x)
1263 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1264 
1265 static const AVOption options[] = {
1266  { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
1267  AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
1268  { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
1269  { .i64 = PRORES_PROFILE_STANDARD },
1271  { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
1272  0, 0, VE, "profile" },
1273  { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
1274  0, 0, VE, "profile" },
1275  { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
1276  0, 0, VE, "profile" },
1277  { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
1278  0, 0, VE, "profile" },
1279  { "4444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
1280  0, 0, VE, "profile" },
1281  { "vendor", "vendor ID", OFFSET(vendor),
1282  AV_OPT_TYPE_STRING, { .str = "Lavc" }, CHAR_MIN, CHAR_MAX, VE },
1283  { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
1284  AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
1285  { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
1286  { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, "quant_mat" },
1287  { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
1288  0, 0, VE, "quant_mat" },
1289  { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
1290  0, 0, VE, "quant_mat" },
1291  { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
1292  0, 0, VE, "quant_mat" },
1293  { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
1294  0, 0, VE, "quant_mat" },
1295  { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
1296  0, 0, VE, "quant_mat" },
1297  { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
1298  0, 0, VE, "quant_mat" },
1299  { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
1300  { .i64 = 16 }, 0, 16, VE },
1301  { NULL }
1302 };
1303 
1304 static const AVClass proresenc_class = {
1305  .class_name = "ProRes encoder",
1306  .item_name = av_default_item_name,
1307  .option = options,
1308  .version = LIBAVUTIL_VERSION_INT,
1309 };
1310 
1312  .name = "prores",
1313  .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
1314  .type = AVMEDIA_TYPE_VIDEO,
1315  .id = AV_CODEC_ID_PRORES,
1316  .priv_data_size = sizeof(ProresContext),
1317  .init = encode_init,
1318  .close = encode_close,
1319  .encode2 = encode_frame,
1320  .capabilities = CODEC_CAP_SLICE_THREADS,
1321  .pix_fmts = (const enum AVPixelFormat[]) {
1324  },
1325  .priv_class = &proresenc_class,
1326 };