FFmpeg
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
proresenc_anatoliy.c
Go to the documentation of this file.
1 /*
2  * Apple ProRes encoder
3  *
4  * Copyright (c) 2011 Anatoliy Wasserman
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg 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  * FFmpeg 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 FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /**
24  * @file
25  * Apple ProRes encoder (Anatoliy Wasserman version)
26  * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy)
27  */
28 
29 #include "avcodec.h"
30 #include "internal.h"
31 #include "put_bits.h"
32 #include "bytestream.h"
33 #include "dsputil.h"
34 
35 #define DEFAULT_SLICE_MB_WIDTH 8
36 
37 #define FF_PROFILE_PRORES_PROXY 0
38 #define FF_PROFILE_PRORES_LT 1
39 #define FF_PROFILE_PRORES_STANDARD 2
40 #define FF_PROFILE_PRORES_HQ 3
41 
42 static const AVProfile profiles[] = {
43  { FF_PROFILE_PRORES_PROXY, "apco"},
44  { FF_PROFILE_PRORES_LT, "apcs"},
45  { FF_PROFILE_PRORES_STANDARD, "apcn"},
46  { FF_PROFILE_PRORES_HQ, "apch"},
48 };
49 
50 static const int qp_start_table[4] = { 4, 1, 1, 1 };
51 static const int qp_end_table[4] = { 8, 9, 6, 6 };
52 static const int bitrate_table[5] = { 1000, 2100, 3500, 5400 };
53 
54 static const uint8_t progressive_scan[64] = {
55  0, 1, 8, 9, 2, 3, 10, 11,
56  16, 17, 24, 25, 18, 19, 26, 27,
57  4, 5, 12, 20, 13, 6, 7, 14,
58  21, 28, 29, 22, 15, 23, 30, 31,
59  32, 33, 40, 48, 41, 34, 35, 42,
60  49, 56, 57, 50, 43, 36, 37, 44,
61  51, 58, 59, 52, 45, 38, 39, 46,
62  53, 60, 61, 54, 47, 55, 62, 63
63 };
64 
65 static const uint8_t QMAT_LUMA[4][64] = {
66  {
67  4, 7, 9, 11, 13, 14, 15, 63,
68  7, 7, 11, 12, 14, 15, 63, 63,
69  9, 11, 13, 14, 15, 63, 63, 63,
70  11, 11, 13, 14, 63, 63, 63, 63,
71  11, 13, 14, 63, 63, 63, 63, 63,
72  13, 14, 63, 63, 63, 63, 63, 63,
73  13, 63, 63, 63, 63, 63, 63, 63,
74  63, 63, 63, 63, 63, 63, 63, 63
75  }, {
76  4, 5, 6, 7, 9, 11, 13, 15,
77  5, 5, 7, 8, 11, 13, 15, 17,
78  6, 7, 9, 11, 13, 15, 15, 17,
79  7, 7, 9, 11, 13, 15, 17, 19,
80  7, 9, 11, 13, 14, 16, 19, 23,
81  9, 11, 13, 14, 16, 19, 23, 29,
82  9, 11, 13, 15, 17, 21, 28, 35,
83  11, 13, 16, 17, 21, 28, 35, 41
84  }, {
85  4, 4, 5, 5, 6, 7, 7, 9,
86  4, 4, 5, 6, 7, 7, 9, 9,
87  5, 5, 6, 7, 7, 9, 9, 10,
88  5, 5, 6, 7, 7, 9, 9, 10,
89  5, 6, 7, 7, 8, 9, 10, 12,
90  6, 7, 7, 8, 9, 10, 12, 15,
91  6, 7, 7, 9, 10, 11, 14, 17,
92  7, 7, 9, 10, 11, 14, 17, 21
93  }, {
94  4, 4, 4, 4, 4, 4, 4, 4,
95  4, 4, 4, 4, 4, 4, 4, 4,
96  4, 4, 4, 4, 4, 4, 4, 4,
97  4, 4, 4, 4, 4, 4, 4, 5,
98  4, 4, 4, 4, 4, 4, 5, 5,
99  4, 4, 4, 4, 4, 5, 5, 6,
100  4, 4, 4, 4, 5, 5, 6, 7,
101  4, 4, 4, 4, 5, 6, 7, 7
102  }
103 };
104 
105 static const uint8_t QMAT_CHROMA[4][64] = {
106  {
107  4, 7, 9, 11, 13, 14, 63, 63,
108  7, 7, 11, 12, 14, 63, 63, 63,
109  9, 11, 13, 14, 63, 63, 63, 63,
110  11, 11, 13, 14, 63, 63, 63, 63,
111  11, 13, 14, 63, 63, 63, 63, 63,
112  13, 14, 63, 63, 63, 63, 63, 63,
113  13, 63, 63, 63, 63, 63, 63, 63,
114  63, 63, 63, 63, 63, 63, 63, 63
115  }, {
116  4, 5, 6, 7, 9, 11, 13, 15,
117  5, 5, 7, 8, 11, 13, 15, 17,
118  6, 7, 9, 11, 13, 15, 15, 17,
119  7, 7, 9, 11, 13, 15, 17, 19,
120  7, 9, 11, 13, 14, 16, 19, 23,
121  9, 11, 13, 14, 16, 19, 23, 29,
122  9, 11, 13, 15, 17, 21, 28, 35,
123  11, 13, 16, 17, 21, 28, 35, 41
124  }, {
125  4, 4, 5, 5, 6, 7, 7, 9,
126  4, 4, 5, 6, 7, 7, 9, 9,
127  5, 5, 6, 7, 7, 9, 9, 10,
128  5, 5, 6, 7, 7, 9, 9, 10,
129  5, 6, 7, 7, 8, 9, 10, 12,
130  6, 7, 7, 8, 9, 10, 12, 15,
131  6, 7, 7, 9, 10, 11, 14, 17,
132  7, 7, 9, 10, 11, 14, 17, 21
133  }, {
134  4, 4, 4, 4, 4, 4, 4, 4,
135  4, 4, 4, 4, 4, 4, 4, 4,
136  4, 4, 4, 4, 4, 4, 4, 4,
137  4, 4, 4, 4, 4, 4, 4, 5,
138  4, 4, 4, 4, 4, 4, 5, 5,
139  4, 4, 4, 4, 4, 5, 5, 6,
140  4, 4, 4, 4, 5, 5, 6, 7,
141  4, 4, 4, 4, 5, 6, 7, 7
142  }
143 };
144 
145 
146 typedef struct {
150 
151  int qmat_luma[16][64];
152  int qmat_chroma[16][64];
153 } ProresContext;
154 
155 static void encode_codeword(PutBitContext *pb, int val, int codebook)
156 {
157  unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros,
158  mask;
159 
160  /* number of bits to switch between rice and exp golomb */
161  switch_bits = codebook & 3;
162  rice_order = codebook >> 5;
163  exp_order = (codebook >> 2) & 7;
164 
165  first_exp = ((switch_bits + 1) << rice_order);
166 
167  if (val >= first_exp) { /* exp golomb */
168  val -= first_exp;
169  val += (1 << exp_order);
170  exp = av_log2(val);
171  zeros = exp - exp_order + switch_bits + 1;
172  put_bits(pb, zeros, 0);
173  put_bits(pb, exp + 1, val);
174  } else if (rice_order) {
175  mask = (1 << rice_order) - 1;
176  put_bits(pb, (val >> rice_order), 0);
177  put_bits(pb, 1, 1);
178  put_bits(pb, rice_order, val & mask);
179  } else {
180  put_bits(pb, val, 0);
181  put_bits(pb, 1, 1);
182  }
183 }
184 
185 #define QSCALE(qmat,ind,val) ((val) / (qmat[ind]))
186 #define TO_GOLOMB(val) ((val << 1) ^ (val >> 31))
187 #define DIFF_SIGN(val, sign) ((val >> 31) ^ sign)
188 #define IS_NEGATIVE(val) (((val >> 31) ^ -1) + 1)
189 #define TO_GOLOMB2(val,sign) (val==0 ? 0 : (val << 1) + sign)
190 
191 static av_always_inline int get_level(int val)
192 {
193  int sign = (val >> 31);
194  return (val ^ sign) - sign;
195 }
196 
197 #define FIRST_DC_CB 0xB8
198 
199 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
200 
202  int blocks_per_slice, int *qmat)
203 {
204  int prev_dc, code;
205  int i, sign, idx;
206  int new_dc, delta, diff_sign, new_code;
207 
208  prev_dc = QSCALE(qmat, 0, in[0] - 16384);
209  code = TO_GOLOMB(prev_dc);
210  encode_codeword(pb, code, FIRST_DC_CB);
211 
212  code = 5; sign = 0; idx = 64;
213  for (i = 1; i < blocks_per_slice; i++, idx += 64) {
214  new_dc = QSCALE(qmat, 0, in[idx] - 16384);
215  delta = new_dc - prev_dc;
216  diff_sign = DIFF_SIGN(delta, sign);
217  new_code = TO_GOLOMB2(get_level(delta), diff_sign);
218 
219  encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
220 
221  code = new_code;
222  sign = delta >> 31;
223  prev_dc = new_dc;
224  }
225 }
226 
227 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
228  0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
229 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
230  0x28, 0x28, 0x28, 0x4C };
231 
233  DCTELEM *in, int blocks_per_slice, int *qmat)
234 {
235  int prev_run = 4;
236  int prev_level = 2;
237 
238  int run = 0, level, code, i, j;
239  for (i = 1; i < 64; i++) {
240  int indp = progressive_scan[i];
241  for (j = 0; j < blocks_per_slice; j++) {
242  int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
243  if (val) {
244  encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
245 
246  prev_run = run;
247  run = 0;
248  level = get_level(val);
249  code = level - 1;
250 
251  encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
252 
253  prev_level = level;
254 
255  put_bits(pb, 1, IS_NEGATIVE(val));
256  } else {
257  ++run;
258  }
259  }
260  }
261 }
262 
263 static void get(uint8_t *pixels, int stride, DCTELEM* block)
264 {
265  int16_t *p = (int16_t*)pixels;
266  int i, j;
267 
268  stride >>= 1;
269  for (i = 0; i < 8; i++) {
270  for (j = 0; j < 8; j++) {
271  block[j] = p[j];
272  }
273  p += stride;
274  block += 8;
275  }
276 }
277 
278 static void fdct_get(uint8_t *pixels, int stride, DCTELEM* block)
279 {
280  get(pixels, stride, block);
281  ff_jpeg_fdct_islow_10(block);
282 }
283 
284 static int encode_slice_plane(AVCodecContext *avctx, int mb_count,
285  uint8_t *src, int src_stride, uint8_t *buf, unsigned buf_size,
286  int *qmat, int chroma)
287 {
289  int i, blocks_per_slice;
290  PutBitContext pb;
291 
292  block = blocks;
293  for (i = 0; i < mb_count; i++) {
294  fdct_get(src, src_stride, block + (0 << 6));
295  fdct_get(src + 8 * src_stride, src_stride, block + ((2 - chroma) << 6));
296  if (!chroma) {
297  fdct_get(src + 16, src_stride, block + (1 << 6));
298  fdct_get(src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
299  }
300 
301  block += (256 >> chroma);
302  src += (32 >> chroma);
303  }
304 
305  blocks_per_slice = mb_count << (2 - chroma);
306  init_put_bits(&pb, buf, buf_size << 3);
307 
308  encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
309  encode_ac_coeffs(avctx, &pb, blocks, blocks_per_slice, qmat);
310 
311  flush_put_bits(&pb);
312  return put_bits_ptr(&pb) - pb.buf;
313 }
314 
316  uint8_t *dest_y, uint8_t *dest_u, uint8_t *dest_v, int luma_stride,
317  int chroma_stride, unsigned mb_count, uint8_t *buf, unsigned data_size,
318  unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
319  int qp)
320 {
321  ProresContext* ctx = avctx->priv_data;
322 
323  *y_data_size = encode_slice_plane(avctx, mb_count, dest_y, luma_stride,
324  buf, data_size, ctx->qmat_luma[qp - 1], 0);
325 
326  if (!(avctx->flags & CODEC_FLAG_GRAY)) {
327  *u_data_size = encode_slice_plane(avctx, mb_count, dest_u,
328  chroma_stride, buf + *y_data_size, data_size - *y_data_size,
329  ctx->qmat_chroma[qp - 1], 1);
330 
331  *v_data_size = encode_slice_plane(avctx, mb_count, dest_v,
332  chroma_stride, buf + *y_data_size + *u_data_size,
333  data_size - *y_data_size - *u_data_size,
334  ctx->qmat_chroma[qp - 1], 1);
335  }
336 
337  return *y_data_size + *u_data_size + *v_data_size;
338 }
339 
340 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
341  unsigned stride, unsigned width, unsigned height, uint16_t *dst,
342  unsigned dst_width, unsigned dst_height)
343 {
344 
345  int box_width = FFMIN(width - x, dst_width);
346  int box_height = FFMIN(height - y, dst_height);
347  int i, j, src_stride = stride >> 1;
348  uint16_t last_pix, *last_line;
349 
350  src += y * src_stride + x;
351  for (i = 0; i < box_height; ++i) {
352  for (j = 0; j < box_width; ++j) {
353  dst[j] = src[j];
354  }
355  last_pix = dst[j - 1];
356  for (; j < dst_width; j++)
357  dst[j] = last_pix;
358  src += src_stride;
359  dst += dst_width;
360  }
361  last_line = dst - dst_width;
362  for (; i < dst_height; i++) {
363  for (j = 0; j < dst_width; ++j) {
364  dst[j] = last_line[j];
365  }
366  dst += dst_width;
367  }
368 }
369 
370 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
371  int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
372  int unsafe, int *qp)
373 {
374  int luma_stride, chroma_stride;
375  int hdr_size = 6, slice_size;
376  uint8_t *dest_y, *dest_u, *dest_v;
377  unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
378  ProresContext* ctx = avctx->priv_data;
379  int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2;
380  int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
381  int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
382 
383  luma_stride = pic->linesize[0];
384  chroma_stride = pic->linesize[1];
385 
386  dest_y = pic->data[0] + (mb_y << 4) * luma_stride + (mb_x << 5);
387  dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << 4);
388  dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << 4);
389 
390  if (unsafe) {
391 
392  subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
393  luma_stride, avctx->width, avctx->height,
394  (uint16_t *) ctx->fill_y, mb_count << 4, 16);
395  subimage_with_fill((uint16_t *) pic->data[1], mb_x << 3, mb_y << 4,
396  chroma_stride, avctx->width >> 1, avctx->height,
397  (uint16_t *) ctx->fill_u, mb_count << 3, 16);
398  subimage_with_fill((uint16_t *) pic->data[2], mb_x << 3, mb_y << 4,
399  chroma_stride, avctx->width >> 1, avctx->height,
400  (uint16_t *) ctx->fill_v, mb_count << 3, 16);
401 
402  encode_slice_data(avctx, ctx->fill_y, ctx->fill_u, ctx->fill_v,
403  mb_count << 5, mb_count << 4, mb_count, buf + hdr_size,
404  data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
405  *qp);
406  } else {
407  slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
408  luma_stride, chroma_stride, mb_count, buf + hdr_size,
409  data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
410  *qp);
411 
412  if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
413  do {
414  *qp += 1;
415  slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
416  luma_stride, chroma_stride, mb_count, buf + hdr_size,
417  data_size - hdr_size, &y_data_size, &u_data_size,
418  &v_data_size, *qp);
419  } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
420  } else if (slice_size < low_bytes && *qp
421  > qp_start_table[avctx->profile]) {
422  do {
423  *qp -= 1;
424  slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
425  luma_stride, chroma_stride, mb_count, buf + hdr_size,
426  data_size - hdr_size, &y_data_size, &u_data_size,
427  &v_data_size, *qp);
428  } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
429  }
430  }
431 
432  buf[0] = hdr_size << 3;
433  buf[1] = *qp;
434  AV_WB16(buf + 2, y_data_size);
435  AV_WB16(buf + 4, u_data_size);
436 
437  return hdr_size + y_data_size + u_data_size + v_data_size;
438 }
439 
440 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
441  uint8_t *buf, const int buf_size)
442 {
443  int mb_width = (avctx->width + 15) >> 4;
444  int mb_height = (avctx->height + 15) >> 4;
445  int hdr_size, sl_size, i;
446  int mb_y, sl_data_size, qp;
447  int unsafe_bot, unsafe_right;
448  uint8_t *sl_data, *sl_data_sizes;
449  int slice_per_line = 0, rem = mb_width;
450 
451  for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
452  slice_per_line += rem >> i;
453  rem &= (1 << i) - 1;
454  }
455 
456  qp = qp_start_table[avctx->profile];
457  hdr_size = 8; sl_data_size = buf_size - hdr_size;
458  sl_data_sizes = buf + hdr_size;
459  sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
460  for (mb_y = 0; mb_y < mb_height; mb_y++) {
461  int mb_x = 0;
462  int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
463  while (mb_x < mb_width) {
464  while (mb_width - mb_x < slice_mb_count)
465  slice_mb_count >>= 1;
466 
467  unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
468  unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
469 
470  sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
471  sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
472 
473  bytestream_put_be16(&sl_data_sizes, sl_size);
474  sl_data += sl_size;
475  sl_data_size -= sl_size;
476  mb_x += slice_mb_count;
477  }
478  }
479 
480  buf[0] = hdr_size << 3;
481  AV_WB32(buf + 1, sl_data - buf);
482  AV_WB16(buf + 5, slice_per_line * mb_height);
483  buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
484 
485  return sl_data - buf;
486 }
487 
489  const AVFrame *pict, int *got_packet)
490 {
491  int header_size = 148;
492  uint8_t *buf;
493  int pic_size, ret;
494  int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + FF_MIN_BUFFER_SIZE; //FIXME choose tighter limit
495 
496 
497  if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + FF_MIN_BUFFER_SIZE)) < 0)
498  return ret;
499 
500  buf = pkt->data;
501  pic_size = prores_encode_picture(avctx, pict, buf + header_size + 8,
502  pkt->size - header_size - 8);
503 
504  bytestream_put_be32(&buf, pic_size + 8 + header_size);
505  bytestream_put_buffer(&buf, "icpf", 4);
506 
507  bytestream_put_be16(&buf, header_size);
508  bytestream_put_be16(&buf, 0);
509  bytestream_put_buffer(&buf, "fmpg", 4);
510  bytestream_put_be16(&buf, avctx->width);
511  bytestream_put_be16(&buf, avctx->height);
512  *buf++ = 0x83; // {10}(422){00}{00}(frame){11}
513  *buf++ = 0;
514  *buf++ = 2;
515  *buf++ = 2;
516  *buf++ = 6;
517  *buf++ = 32;
518  *buf++ = 0;
519  *buf++ = 3;
520 
521  bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64);
522  bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
523 
524  pkt->flags |= AV_PKT_FLAG_KEY;
525  pkt->size = pic_size + 8 + header_size;
526  *got_packet = 1;
527 
528  return 0;
529 }
530 
531 static void scale_mat(const uint8_t* src, int* dst, int scale)
532 {
533  int i;
534  for (i = 0; i < 64; i++)
535  dst[i] = src[i] * scale;
536 }
537 
539 {
540  int i;
541  ProresContext* ctx = avctx->priv_data;
542 
543  if (avctx->pix_fmt != AV_PIX_FMT_YUV422P10) {
544  av_log(avctx, AV_LOG_ERROR, "need YUV422P10\n");
545  return -1;
546  }
547  if (avctx->width & 0x1) {
548  av_log(avctx, AV_LOG_ERROR,
549  "frame width needs to be multiple of 2\n");
550  return -1;
551  }
552 
553  if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
554  ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
555  if (!ctx->fill_y)
556  return AVERROR(ENOMEM);
557  ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
558  ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
559  }
560 
561  if (avctx->profile == FF_PROFILE_UNKNOWN) {
563  av_log(avctx, AV_LOG_INFO,
564  "encoding with ProRes standard (apcn) profile\n");
565 
566  } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
567  || avctx->profile > FF_PROFILE_PRORES_HQ) {
568  av_log(
569  avctx,
570  AV_LOG_ERROR,
571  "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch]\n",
572  avctx->profile);
573  return -1;
574  }
575 
576  avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
577 
578  for (i = 1; i <= 16; i++) {
579  scale_mat(QMAT_LUMA[avctx->profile] , ctx->qmat_luma[i - 1] , i);
580  scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
581  }
582 
583  avctx->coded_frame = avcodec_alloc_frame();
584  avctx->coded_frame->key_frame = 1;
586 
587  return 0;
588 }
589 
591 {
592  ProresContext* ctx = avctx->priv_data;
593  av_freep(&avctx->coded_frame);
594  av_freep(&ctx->fill_y);
595 
596  return 0;
597 }
598 
600  .name = "prores_anatoliy",
601  .type = AVMEDIA_TYPE_VIDEO,
602  .id = AV_CODEC_ID_PRORES,
603  .priv_data_size = sizeof(ProresContext),
606  .encode2 = prores_encode_frame,
607  .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
608  .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
610  .profiles = profiles
611 };
612 
614  .name = "prores",
615  .type = AVMEDIA_TYPE_VIDEO,
616  .id = AV_CODEC_ID_PRORES,
617  .priv_data_size = sizeof(ProresContext),
620  .encode2 = prores_encode_frame,
621  .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
622  .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
624  .profiles = profiles
625 };