]> git.sesse.net Git - ffmpeg/blob - libavcodec/proresenc_anatoliy.c
Merge commit '8c76bfacf663ff71cee5264a74d0f9c86addd325'
[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 "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"},
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     FDCTDSPContext fdsp;
149     uint8_t* fill_y;
150     uint8_t* fill_u;
151     uint8_t* fill_v;
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
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         put_bits(pb, (val >> rice_order), 0);
177         put_bits(pb, 1, 1);
178         put_sbits(pb, rice_order, val);
179     } else {
180         put_bits(pb, val, 0);
181         put_bits(pb, 1, 1);
182     }
183 }
184
185 #define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
186 #define TO_GOLOMB(val) (((val) << 1) ^ ((val) >> 31))
187 #define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
188 #define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
189 #define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
190
191 static av_always_inline int get_level(int val)
192 {
193     int sign = (val >> 31);
194     return (val ^ sign) - sign;
195 }
196
197 #define FIRST_DC_CB 0xB8
198
199 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
200
201 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
202         int blocks_per_slice, int *qmat)
203 {
204     int prev_dc, code;
205     int i, sign, idx;
206     int new_dc, delta, diff_sign, new_code;
207
208     prev_dc = QSCALE(qmat, 0, in[0] - 16384);
209     code = TO_GOLOMB(prev_dc);
210     encode_codeword(pb, code, FIRST_DC_CB);
211
212     code = 5; sign = 0; idx = 64;
213     for (i = 1; i < blocks_per_slice; i++, idx += 64) {
214         new_dc    = QSCALE(qmat, 0, in[idx] - 16384);
215         delta     = new_dc - prev_dc;
216         diff_sign = DIFF_SIGN(delta, sign);
217         new_code  = TO_GOLOMB2(get_level(delta), diff_sign);
218
219         encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
220
221         code      = new_code;
222         sign      = delta >> 31;
223         prev_dc   = new_dc;
224     }
225 }
226
227 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
228         0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
229 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
230         0x28, 0x28, 0x28, 0x4C };
231
232 static void encode_ac_coeffs(AVCodecContext *avctx, PutBitContext *pb,
233         int16_t *in, int blocks_per_slice, int *qmat)
234 {
235     int prev_run = 4;
236     int prev_level = 2;
237
238     int run = 0, level, code, i, j;
239     for (i = 1; i < 64; i++) {
240         int indp = progressive_scan[i];
241         for (j = 0; j < blocks_per_slice; j++) {
242             int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
243             if (val) {
244                 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
245
246                 prev_run   = run;
247                 run        = 0;
248                 level      = get_level(val);
249                 code       = level - 1;
250
251                 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
252
253                 prev_level = level;
254
255                 put_bits(pb, 1, IS_NEGATIVE(val));
256             } else {
257                 ++run;
258             }
259         }
260     }
261 }
262
263 static void get(uint8_t *pixels, int stride, int16_t* block)
264 {
265     int i;
266
267     for (i = 0; i < 8; i++) {
268         AV_WN64(block, AV_RN64(pixels));
269         AV_WN64(block+4, AV_RN64(pixels+8));
270         pixels += stride;
271         block += 8;
272     }
273 }
274
275 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
276 {
277     get(pixels, stride, block);
278     fdsp->fdct(block);
279 }
280
281 static int encode_slice_plane(AVCodecContext *avctx, int mb_count,
282         uint8_t *src, int src_stride, uint8_t *buf, unsigned buf_size,
283         int *qmat, int chroma)
284 {
285     ProresContext* ctx = avctx->priv_data;
286     FDCTDSPContext *fdsp = &ctx->fdsp;
287     LOCAL_ALIGNED(16, int16_t, blocks, [DEFAULT_SLICE_MB_WIDTH << 8]);
288     int16_t *block;
289     int i, blocks_per_slice;
290     PutBitContext pb;
291
292     block = blocks;
293     for (i = 0; i < mb_count; i++) {
294         fdct_get(fdsp, src,                  src_stride, block + (0 << 6));
295         fdct_get(fdsp, src + 8 * src_stride, src_stride, block + ((2 - chroma) << 6));
296         if (!chroma) {
297             fdct_get(fdsp, src + 16,                  src_stride, block + (1 << 6));
298             fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
299         }
300
301         block += (256 >> chroma);
302         src   += (32  >> chroma);
303     }
304
305     blocks_per_slice = mb_count << (2 - chroma);
306     init_put_bits(&pb, buf, buf_size);
307
308     encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
309     encode_ac_coeffs(avctx, &pb, blocks, blocks_per_slice, qmat);
310
311     flush_put_bits(&pb);
312     return put_bits_ptr(&pb) - pb.buf;
313 }
314
315 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
316         uint8_t *dest_y, uint8_t *dest_u, uint8_t *dest_v, int luma_stride,
317         int chroma_stride, unsigned mb_count, uint8_t *buf, unsigned data_size,
318         unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
319         int qp)
320 {
321     ProresContext* ctx = avctx->priv_data;
322
323     *y_data_size = encode_slice_plane(avctx, mb_count, dest_y, luma_stride,
324             buf, data_size, ctx->qmat_luma[qp - 1], 0);
325
326     if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
327         *u_data_size = encode_slice_plane(avctx, mb_count, dest_u,
328                 chroma_stride, buf + *y_data_size, data_size - *y_data_size,
329                 ctx->qmat_chroma[qp - 1], 1);
330
331         *v_data_size = encode_slice_plane(avctx, mb_count, dest_v,
332                 chroma_stride, buf + *y_data_size + *u_data_size,
333                 data_size - *y_data_size - *u_data_size,
334                 ctx->qmat_chroma[qp - 1], 1);
335     }
336
337     return *y_data_size + *u_data_size + *v_data_size;
338 }
339
340 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
341         unsigned stride, unsigned width, unsigned height, uint16_t *dst,
342         unsigned dst_width, unsigned dst_height)
343 {
344
345     int box_width = FFMIN(width - x, dst_width);
346     int box_height = FFMIN(height - y, dst_height);
347     int i, j, src_stride = stride >> 1;
348     uint16_t last_pix, *last_line;
349
350     src += y * src_stride + x;
351     for (i = 0; i < box_height; ++i) {
352         for (j = 0; j < box_width; ++j) {
353             dst[j] = src[j];
354         }
355         last_pix = dst[j - 1];
356         for (; j < dst_width; j++)
357             dst[j] = last_pix;
358         src += src_stride;
359         dst += dst_width;
360     }
361     last_line = dst - dst_width;
362     for (; i < dst_height; i++) {
363         for (j = 0; j < dst_width; ++j) {
364             dst[j] = last_line[j];
365         }
366         dst += dst_width;
367     }
368 }
369
370 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
371         int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
372         int unsafe, int *qp)
373 {
374     int luma_stride, chroma_stride;
375     int hdr_size = 6, slice_size;
376     uint8_t *dest_y, *dest_u, *dest_v;
377     unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
378     ProresContext* ctx = avctx->priv_data;
379     int tgt_bits   = (mb_count * bitrate_table[avctx->profile]) >> 2;
380     int low_bytes  = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
381     int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
382
383     luma_stride   = pic->linesize[0];
384     chroma_stride = pic->linesize[1];
385
386     dest_y = pic->data[0] + (mb_y << 4) * luma_stride   + (mb_x << 5);
387     dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << 4);
388     dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << 4);
389
390     if (unsafe) {
391
392         subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
393                 luma_stride, avctx->width, avctx->height,
394                 (uint16_t *) ctx->fill_y, mb_count << 4, 16);
395         subimage_with_fill((uint16_t *) pic->data[1], mb_x << 3, mb_y << 4,
396                 chroma_stride, avctx->width >> 1, avctx->height,
397                 (uint16_t *) ctx->fill_u, mb_count << 3, 16);
398         subimage_with_fill((uint16_t *) pic->data[2], mb_x << 3, mb_y << 4,
399                 chroma_stride, avctx->width >> 1, avctx->height,
400                 (uint16_t *) ctx->fill_v, mb_count << 3, 16);
401
402         encode_slice_data(avctx, ctx->fill_y, ctx->fill_u, ctx->fill_v,
403                 mb_count << 5, mb_count << 4, mb_count, buf + hdr_size,
404                 data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
405                 *qp);
406     } else {
407         slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
408                 luma_stride, chroma_stride, mb_count, buf + hdr_size,
409                 data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
410                 *qp);
411
412         if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
413             do {
414                 *qp += 1;
415                 slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
416                         luma_stride, chroma_stride, mb_count, buf + hdr_size,
417                         data_size - hdr_size, &y_data_size, &u_data_size,
418                         &v_data_size, *qp);
419             } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
420         } else if (slice_size < low_bytes && *qp
421                 > qp_start_table[avctx->profile]) {
422             do {
423                 *qp -= 1;
424                 slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
425                         luma_stride, chroma_stride, mb_count, buf + hdr_size,
426                         data_size - hdr_size, &y_data_size, &u_data_size,
427                         &v_data_size, *qp);
428             } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
429         }
430     }
431
432     buf[0] = hdr_size << 3;
433     buf[1] = *qp;
434     AV_WB16(buf + 2, y_data_size);
435     AV_WB16(buf + 4, u_data_size);
436
437     return hdr_size + y_data_size + u_data_size + v_data_size;
438 }
439
440 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
441         uint8_t *buf, const int buf_size)
442 {
443     int mb_width = (avctx->width + 15) >> 4;
444     int mb_height = (avctx->height + 15) >> 4;
445     int hdr_size, sl_size, i;
446     int mb_y, sl_data_size, qp;
447     int unsafe_bot, unsafe_right;
448     uint8_t *sl_data, *sl_data_sizes;
449     int slice_per_line = 0, rem = mb_width;
450
451     for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
452         slice_per_line += rem >> i;
453         rem &= (1 << i) - 1;
454     }
455
456     qp = qp_start_table[avctx->profile];
457     hdr_size = 8; sl_data_size = buf_size - hdr_size;
458     sl_data_sizes = buf + hdr_size;
459     sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
460     for (mb_y = 0; mb_y < mb_height; mb_y++) {
461         int mb_x = 0;
462         int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
463         while (mb_x < mb_width) {
464             while (mb_width - mb_x < slice_mb_count)
465                 slice_mb_count >>= 1;
466
467             unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
468             unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
469
470             sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
471                     sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
472
473             bytestream_put_be16(&sl_data_sizes, sl_size);
474             sl_data           += sl_size;
475             sl_data_size      -= sl_size;
476             mb_x              += slice_mb_count;
477         }
478     }
479
480     buf[0] = hdr_size << 3;
481     AV_WB32(buf + 1, sl_data - buf);
482     AV_WB16(buf + 5, slice_per_line * mb_height);
483     buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
484
485     return sl_data - buf;
486 }
487
488 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
489                                const AVFrame *pict, int *got_packet)
490 {
491     int header_size = 148;
492     uint8_t *buf;
493     int pic_size, ret;
494     int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
495
496
497     if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
498         return ret;
499
500     buf = pkt->data;
501     pic_size = prores_encode_picture(avctx, pict, buf + header_size + 8,
502             pkt->size - header_size - 8);
503
504     bytestream_put_be32(&buf, pic_size + 8 + header_size);
505     bytestream_put_buffer(&buf, "icpf", 4);
506
507     bytestream_put_be16(&buf, header_size);
508     bytestream_put_be16(&buf, 0);
509     bytestream_put_buffer(&buf, "fmpg", 4);
510     bytestream_put_be16(&buf, avctx->width);
511     bytestream_put_be16(&buf, avctx->height);
512     *buf++ = 0x83; // {10}(422){00}{00}(frame){11}
513     *buf++ = 0;
514     *buf++ = 2;
515     *buf++ = 2;
516     *buf++ = 6;
517     *buf++ = 32;
518     *buf++ = 0;
519     *buf++ = 3;
520
521     bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile],   64);
522     bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
523
524     pkt->flags |= AV_PKT_FLAG_KEY;
525     pkt->size = pic_size + 8 + header_size;
526     *got_packet = 1;
527
528     return 0;
529 }
530
531 static void scale_mat(const uint8_t* src, int* dst, int scale)
532 {
533     int i;
534     for (i = 0; i < 64; i++)
535         dst[i] = src[i] * scale;
536 }
537
538 static av_cold int prores_encode_init(AVCodecContext *avctx)
539 {
540     int i;
541     ProresContext* ctx = avctx->priv_data;
542
543     if (avctx->pix_fmt != AV_PIX_FMT_YUV422P10) {
544         av_log(avctx, AV_LOG_ERROR, "need YUV422P10\n");
545         return AVERROR_PATCHWELCOME;
546     }
547     avctx->bits_per_raw_sample = 10;
548
549     if (avctx->width & 0x1) {
550         av_log(avctx, AV_LOG_ERROR,
551                 "frame width needs to be multiple of 2\n");
552         return AVERROR(EINVAL);
553     }
554
555     if (avctx->width > 65534 || avctx->height > 65535) {
556         av_log(avctx, AV_LOG_ERROR,
557                 "The maximum dimensions are 65534x65535\n");
558         return AVERROR(EINVAL);
559     }
560
561     if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
562         ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
563         if (!ctx->fill_y)
564             return AVERROR(ENOMEM);
565         ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
566         ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
567     }
568
569     if (avctx->profile == FF_PROFILE_UNKNOWN) {
570         avctx->profile = FF_PROFILE_PRORES_STANDARD;
571         av_log(avctx, AV_LOG_INFO,
572                 "encoding with ProRes standard (apcn) profile\n");
573
574     } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
575             || avctx->profile > FF_PROFILE_PRORES_HQ) {
576         av_log(
577                 avctx,
578                 AV_LOG_ERROR,
579                 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch]\n",
580                 avctx->profile);
581         return AVERROR(EINVAL);
582     }
583
584     ff_fdctdsp_init(&ctx->fdsp, avctx);
585
586     avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
587
588     for (i = 1; i <= 16; i++) {
589         scale_mat(QMAT_LUMA[avctx->profile]  , ctx->qmat_luma[i - 1]  , i);
590         scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
591     }
592
593     return 0;
594 }
595
596 static av_cold int prores_encode_close(AVCodecContext *avctx)
597 {
598     ProresContext* ctx = avctx->priv_data;
599     av_freep(&ctx->fill_y);
600
601     return 0;
602 }
603
604 AVCodec ff_prores_aw_encoder = {
605     .name           = "prores_aw",
606     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
607     .type           = AVMEDIA_TYPE_VIDEO,
608     .id             = AV_CODEC_ID_PRORES,
609     .priv_data_size = sizeof(ProresContext),
610     .init           = prores_encode_init,
611     .close          = prores_encode_close,
612     .encode2        = prores_encode_frame,
613     .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
614     .capabilities   = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
615     .profiles       = profiles
616 };
617
618 AVCodec ff_prores_encoder = {
619     .name           = "prores",
620     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
621     .type           = AVMEDIA_TYPE_VIDEO,
622     .id             = AV_CODEC_ID_PRORES,
623     .priv_data_size = sizeof(ProresContext),
624     .init           = prores_encode_init,
625     .close          = prores_encode_close,
626     .encode2        = prores_encode_frame,
627     .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
628     .capabilities   = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
629     .profiles       = profiles
630 };