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