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