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