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