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