]> git.sesse.net Git - ffmpeg/blob - libavcodec/proresenc_anatoliy.c
Merge commit 'ed61f3ca8a0664a697782253b354055136c5d303'
[ffmpeg] / libavcodec / proresenc_anatoliy.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
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
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"},
48     { FF_PROFILE_UNKNOWN }
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 {
148     uint8_t* fill_y;
149     uint8_t* fill_u;
150     uint8_t* fill_v;
151
152     int qmat_luma[16][64];
153     int qmat_chroma[16][64];
154 } ProresContext;
155
156 static void encode_codeword(PutBitContext *pb, int val, int codebook)
157 {
158     unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros,
159             mask;
160
161     /* number of bits to switch between rice and exp golomb */
162     switch_bits = codebook & 3;
163     rice_order  = codebook >> 5;
164     exp_order   = (codebook >> 2) & 7;
165
166     first_exp = ((switch_bits + 1) << rice_order);
167
168     if (val >= first_exp) { /* exp golomb */
169         val -= first_exp;
170         val += (1 << exp_order);
171         exp = av_log2(val);
172         zeros = exp - exp_order + switch_bits + 1;
173         put_bits(pb, zeros, 0);
174         put_bits(pb, exp + 1, val);
175     } else if (rice_order) {
176         mask = (1 << rice_order) - 1;
177         put_bits(pb, (val >> rice_order), 0);
178         put_bits(pb, 1, 1);
179         put_bits(pb, rice_order, val & mask);
180     } else {
181         put_bits(pb, val, 0);
182         put_bits(pb, 1, 1);
183     }
184 }
185
186 #define QSCALE(qmat,ind,val) ((val) / (qmat[ind]))
187 #define TO_GOLOMB(val) ((val << 1) ^ (val >> 31))
188 #define DIFF_SIGN(val, sign) ((val >> 31) ^ sign)
189 #define IS_NEGATIVE(val) (((val >> 31) ^ -1) + 1)
190 #define TO_GOLOMB2(val,sign) (val==0 ? 0 : (val << 1) + sign)
191
192 static av_always_inline int get_level(int val)
193 {
194     int sign = (val >> 31);
195     return (val ^ sign) - sign;
196 }
197
198 #define FIRST_DC_CB 0xB8
199
200 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
201
202 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
203         int blocks_per_slice, int *qmat)
204 {
205     int prev_dc, code;
206     int i, sign, idx;
207     int new_dc, delta, diff_sign, new_code;
208
209     prev_dc = QSCALE(qmat, 0, in[0] - 16384);
210     code = TO_GOLOMB(prev_dc);
211     encode_codeword(pb, code, FIRST_DC_CB);
212
213     code = 5; sign = 0; idx = 64;
214     for (i = 1; i < blocks_per_slice; i++, idx += 64) {
215         new_dc    = QSCALE(qmat, 0, in[idx] - 16384);
216         delta     = new_dc - prev_dc;
217         diff_sign = DIFF_SIGN(delta, sign);
218         new_code  = TO_GOLOMB2(get_level(delta), diff_sign);
219
220         encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
221
222         code      = new_code;
223         sign      = delta >> 31;
224         prev_dc   = new_dc;
225     }
226 }
227
228 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
229         0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
230 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
231         0x28, 0x28, 0x28, 0x4C };
232
233 static void encode_ac_coeffs(AVCodecContext *avctx, PutBitContext *pb,
234         int16_t *in, int blocks_per_slice, int *qmat)
235 {
236     int prev_run = 4;
237     int prev_level = 2;
238
239     int run = 0, level, code, i, j;
240     for (i = 1; i < 64; i++) {
241         int indp = progressive_scan[i];
242         for (j = 0; j < blocks_per_slice; j++) {
243             int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
244             if (val) {
245                 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
246
247                 prev_run   = run;
248                 run        = 0;
249                 level      = get_level(val);
250                 code       = level - 1;
251
252                 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
253
254                 prev_level = level;
255
256                 put_bits(pb, 1, IS_NEGATIVE(val));
257             } else {
258                 ++run;
259             }
260         }
261     }
262 }
263
264 static void get(uint8_t *pixels, int stride, int16_t* block)
265 {
266     int16_t *p = (int16_t*)pixels;
267     int i, j;
268
269     stride >>= 1;
270     for (i = 0; i < 8; i++) {
271         for (j = 0; j < 8; j++) {
272             block[j] = p[j];
273         }
274         p += stride;
275         block += 8;
276     }
277 }
278
279 static void fdct_get(uint8_t *pixels, int stride, int16_t* block)
280 {
281     get(pixels, stride, block);
282     ff_jpeg_fdct_islow_10(block);
283 }
284
285 static int encode_slice_plane(AVCodecContext *avctx, int mb_count,
286         uint8_t *src, int src_stride, uint8_t *buf, unsigned buf_size,
287         int *qmat, int chroma)
288 {
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(src,                  src_stride, block + (0 << 6));
296         fdct_get(src + 8 * src_stride, src_stride, block + ((2 - chroma) << 6));
297         if (!chroma) {
298             fdct_get(src + 16,                  src_stride, block + (1 << 6));
299             fdct_get(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
316 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
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
489 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
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
539 static av_cold int prores_encode_init(AVCodecContext *avctx)
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     if (avctx->width & 0x1) {
549         av_log(avctx, AV_LOG_ERROR,
550                 "frame width needs to be multiple of 2\n");
551         return -1;
552     }
553
554     if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
555         ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
556         if (!ctx->fill_y)
557             return AVERROR(ENOMEM);
558         ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
559         ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
560     }
561
562     if (avctx->profile == FF_PROFILE_UNKNOWN) {
563         avctx->profile = FF_PROFILE_PRORES_STANDARD;
564         av_log(avctx, AV_LOG_INFO,
565                 "encoding with ProRes standard (apcn) profile\n");
566
567     } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
568             || avctx->profile > FF_PROFILE_PRORES_HQ) {
569         av_log(
570                 avctx,
571                 AV_LOG_ERROR,
572                 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch]\n",
573                 avctx->profile);
574         return -1;
575     }
576
577     avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
578
579     for (i = 1; i <= 16; i++) {
580         scale_mat(QMAT_LUMA[avctx->profile]  , ctx->qmat_luma[i - 1]  , i);
581         scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
582     }
583
584     avctx->coded_frame = av_frame_alloc();
585     avctx->coded_frame->key_frame = 1;
586     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
587
588     return 0;
589 }
590
591 static av_cold int prores_encode_close(AVCodecContext *avctx)
592 {
593     ProresContext* ctx = avctx->priv_data;
594     av_freep(&avctx->coded_frame);
595     av_freep(&ctx->fill_y);
596
597     return 0;
598 }
599
600 AVCodec ff_prores_aw_encoder = {
601     .name           = "prores_aw",
602     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
603     .type           = AVMEDIA_TYPE_VIDEO,
604     .id             = AV_CODEC_ID_PRORES,
605     .priv_data_size = sizeof(ProresContext),
606     .init           = prores_encode_init,
607     .close          = prores_encode_close,
608     .encode2        = prores_encode_frame,
609     .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
610     .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
611     .profiles       = profiles
612 };
613
614 AVCodec ff_prores_encoder = {
615     .name           = "prores",
616     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
617     .type           = AVMEDIA_TYPE_VIDEO,
618     .id             = AV_CODEC_ID_PRORES,
619     .priv_data_size = sizeof(ProresContext),
620     .init           = prores_encode_init,
621     .close          = prores_encode_close,
622     .encode2        = prores_encode_frame,
623     .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
624     .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
625     .profiles       = profiles
626 };