]> git.sesse.net Git - ffmpeg/blob - libavcodec/proresenc_anatoliy.c
avcodec/hevc: check slice_header_extension data length
[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 #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 progressive_scan[64] = {
57      0,  1,  8,  9,  2,  3, 10, 11,
58     16, 17, 24, 25, 18, 19, 26, 27,
59      4,  5, 12, 20, 13,  6,  7, 14,
60     21, 28, 29, 22, 15, 23, 30, 31,
61     32, 33, 40, 48, 41, 34, 35, 42,
62     49, 56, 57, 50, 43, 36, 37, 44,
63     51, 58, 59, 52, 45, 38, 39, 46,
64     53, 60, 61, 54, 47, 55, 62, 63
65 };
66
67 static const uint8_t QMAT_LUMA[4][64] = {
68     {
69          4,  7,  9, 11, 13, 14, 15, 63,
70          7,  7, 11, 12, 14, 15, 63, 63,
71          9, 11, 13, 14, 15, 63, 63, 63,
72         11, 11, 13, 14, 63, 63, 63, 63,
73         11, 13, 14, 63, 63, 63, 63, 63,
74         13, 14, 63, 63, 63, 63, 63, 63,
75         13, 63, 63, 63, 63, 63, 63, 63,
76         63, 63, 63, 63, 63, 63, 63, 63
77     }, {
78          4,  5,  6,  7,  9, 11, 13, 15,
79          5,  5,  7,  8, 11, 13, 15, 17,
80          6,  7,  9, 11, 13, 15, 15, 17,
81          7,  7,  9, 11, 13, 15, 17, 19,
82          7,  9, 11, 13, 14, 16, 19, 23,
83          9, 11, 13, 14, 16, 19, 23, 29,
84          9, 11, 13, 15, 17, 21, 28, 35,
85         11, 13, 16, 17, 21, 28, 35, 41
86     }, {
87          4,  4,  5,  5,  6,  7,  7,  9,
88          4,  4,  5,  6,  7,  7,  9,  9,
89          5,  5,  6,  7,  7,  9,  9, 10,
90          5,  5,  6,  7,  7,  9,  9, 10,
91          5,  6,  7,  7,  8,  9, 10, 12,
92          6,  7,  7,  8,  9, 10, 12, 15,
93          6,  7,  7,  9, 10, 11, 14, 17,
94          7,  7,  9, 10, 11, 14, 17, 21
95     }, {
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,  4,
99          4,  4,  4,  4,  4,  4,  4,  5,
100          4,  4,  4,  4,  4,  4,  5,  5,
101          4,  4,  4,  4,  4,  5,  5,  6,
102          4,  4,  4,  4,  5,  5,  6,  7,
103          4,  4,  4,  4,  5,  6,  7,  7
104     }
105 };
106
107 static const uint8_t QMAT_CHROMA[4][64] = {
108     {
109          4,  7,  9, 11, 13, 14, 63, 63,
110          7,  7, 11, 12, 14, 63, 63, 63,
111          9, 11, 13, 14, 63, 63, 63, 63,
112         11, 11, 13, 14, 63, 63, 63, 63,
113         11, 13, 14, 63, 63, 63, 63, 63,
114         13, 14, 63, 63, 63, 63, 63, 63,
115         13, 63, 63, 63, 63, 63, 63, 63,
116         63, 63, 63, 63, 63, 63, 63, 63
117     }, {
118          4,  5,  6,  7,  9, 11, 13, 15,
119          5,  5,  7,  8, 11, 13, 15, 17,
120          6,  7,  9, 11, 13, 15, 15, 17,
121          7,  7,  9, 11, 13, 15, 17, 19,
122          7,  9, 11, 13, 14, 16, 19, 23,
123          9, 11, 13, 14, 16, 19, 23, 29,
124          9, 11, 13, 15, 17, 21, 28, 35,
125         11, 13, 16, 17, 21, 28, 35, 41
126     }, {
127          4,  4,  5,  5,  6,  7,  7,  9,
128          4,  4,  5,  6,  7,  7,  9,  9,
129          5,  5,  6,  7,  7,  9,  9, 10,
130          5,  5,  6,  7,  7,  9,  9, 10,
131          5,  6,  7,  7,  8,  9, 10, 12,
132          6,  7,  7,  8,  9, 10, 12, 15,
133          6,  7,  7,  9, 10, 11, 14, 17,
134          7,  7,  9, 10, 11, 14, 17, 21
135     }, {
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,  4,
139          4,  4,  4,  4,  4,  4,  4,  5,
140          4,  4,  4,  4,  4,  4,  5,  5,
141          4,  4,  4,  4,  4,  5,  5,  6,
142          4,  4,  4,  4,  5,  5,  6,  7,
143          4,  4,  4,  4,  5,  6,  7,  7
144     }
145 };
146
147
148 typedef struct {
149     FDCTDSPContext fdsp;
150     uint8_t* fill_y;
151     uint8_t* fill_u;
152     uint8_t* fill_v;
153
154     int qmat_luma[16][64];
155     int qmat_chroma[16][64];
156 } ProresContext;
157
158 static void encode_codeword(PutBitContext *pb, int val, int codebook)
159 {
160     unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros,
161             mask;
162
163     /* number of bits to switch between rice and exp golomb */
164     switch_bits = codebook & 3;
165     rice_order  = codebook >> 5;
166     exp_order   = (codebook >> 2) & 7;
167
168     first_exp = ((switch_bits + 1) << rice_order);
169
170     if (val >= first_exp) { /* exp golomb */
171         val -= first_exp;
172         val += (1 << exp_order);
173         exp = av_log2(val);
174         zeros = exp - exp_order + switch_bits + 1;
175         put_bits(pb, zeros, 0);
176         put_bits(pb, exp + 1, val);
177     } else if (rice_order) {
178         mask = (1 << rice_order) - 1;
179         put_bits(pb, (val >> rice_order), 0);
180         put_bits(pb, 1, 1);
181         put_bits(pb, rice_order, val & mask);
182     } else {
183         put_bits(pb, val, 0);
184         put_bits(pb, 1, 1);
185     }
186 }
187
188 #define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
189 #define TO_GOLOMB(val) (((val) << 1) ^ ((val) >> 31))
190 #define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
191 #define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
192 #define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
193
194 static av_always_inline int get_level(int val)
195 {
196     int sign = (val >> 31);
197     return (val ^ sign) - sign;
198 }
199
200 #define FIRST_DC_CB 0xB8
201
202 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
203
204 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
205         int blocks_per_slice, int *qmat)
206 {
207     int prev_dc, code;
208     int i, sign, idx;
209     int new_dc, delta, diff_sign, new_code;
210
211     prev_dc = QSCALE(qmat, 0, in[0] - 16384);
212     code = TO_GOLOMB(prev_dc);
213     encode_codeword(pb, code, FIRST_DC_CB);
214
215     code = 5; sign = 0; idx = 64;
216     for (i = 1; i < blocks_per_slice; i++, idx += 64) {
217         new_dc    = QSCALE(qmat, 0, in[idx] - 16384);
218         delta     = new_dc - prev_dc;
219         diff_sign = DIFF_SIGN(delta, sign);
220         new_code  = TO_GOLOMB2(get_level(delta), diff_sign);
221
222         encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
223
224         code      = new_code;
225         sign      = delta >> 31;
226         prev_dc   = new_dc;
227     }
228 }
229
230 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
231         0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
232 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
233         0x28, 0x28, 0x28, 0x4C };
234
235 static void encode_ac_coeffs(AVCodecContext *avctx, PutBitContext *pb,
236         int16_t *in, int blocks_per_slice, int *qmat)
237 {
238     int prev_run = 4;
239     int prev_level = 2;
240
241     int run = 0, level, code, i, j;
242     for (i = 1; i < 64; i++) {
243         int indp = progressive_scan[i];
244         for (j = 0; j < blocks_per_slice; j++) {
245             int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
246             if (val) {
247                 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
248
249                 prev_run   = run;
250                 run        = 0;
251                 level      = get_level(val);
252                 code       = level - 1;
253
254                 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
255
256                 prev_level = level;
257
258                 put_bits(pb, 1, IS_NEGATIVE(val));
259             } else {
260                 ++run;
261             }
262         }
263     }
264 }
265
266 static void get(uint8_t *pixels, int stride, int16_t* block)
267 {
268     int i;
269
270     for (i = 0; i < 8; i++) {
271         AV_WN64(block, AV_RN64(pixels));
272         AV_WN64(block+4, AV_RN64(pixels+8));
273         pixels += stride;
274         block += 8;
275     }
276 }
277
278 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
279 {
280     get(pixels, stride, block);
281     fdsp->fdct(block);
282 }
283
284 static int encode_slice_plane(AVCodecContext *avctx, int mb_count,
285         uint8_t *src, int src_stride, uint8_t *buf, unsigned buf_size,
286         int *qmat, int chroma)
287 {
288     ProresContext* ctx = avctx->priv_data;
289     FDCTDSPContext *fdsp = &ctx->fdsp;
290     DECLARE_ALIGNED(16, int16_t, blocks)[DEFAULT_SLICE_MB_WIDTH << 8], *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 << 3);
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_freep(&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 };