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