]> git.sesse.net Git - ffmpeg/blob - libavcodec/proresenc_anatoliy.c
avcodec/prores_enc : not calculate dct a each quantif search step
[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] = { 8, 3, 2, 1 };
53 static const int qp_end_table[4]   = { 13, 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(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 void calc_plane_dct(FDCTDSPContext *fdsp, uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma)
272 {
273     int16_t *block;
274     int i;
275
276     block = blocks;
277     for (i = 0; i < mb_count; i++) {
278         fdct_get(fdsp, src,                  src_stride, block + (0 << 6));
279         fdct_get(fdsp, src + 8 * src_stride, src_stride, block + ((2 - chroma) << 6));
280         if (!chroma) {
281             fdct_get(fdsp, src + 16,                  src_stride, block + (1 << 6));
282             fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
283         }
284
285         block += (256 >> chroma);
286         src   += (32  >> chroma);
287     }
288 }
289
290 static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int chroma)
291 {
292     int blocks_per_slice;
293     PutBitContext pb;
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(&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                                                    int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
307                                                    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(blocks_y, mb_count,
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(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
318                                           ctx->qmat_chroma[qp - 1], 1);
319
320         *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
321                                           data_size - *y_data_size - *u_data_size,
322                                           ctx->qmat_chroma[qp - 1], 1);
323     }
324
325     return *y_data_size + *u_data_size + *v_data_size;
326 }
327
328 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
329         unsigned stride, unsigned width, unsigned height, uint16_t *dst,
330         unsigned dst_width, unsigned dst_height)
331 {
332
333     int box_width = FFMIN(width - x, dst_width);
334     int box_height = FFMIN(height - y, dst_height);
335     int i, j, src_stride = stride >> 1;
336     uint16_t last_pix, *last_line;
337
338     src += y * src_stride + x;
339     for (i = 0; i < box_height; ++i) {
340         for (j = 0; j < box_width; ++j) {
341             dst[j] = src[j];
342         }
343         last_pix = dst[j - 1];
344         for (; j < dst_width; j++)
345             dst[j] = last_pix;
346         src += src_stride;
347         dst += dst_width;
348     }
349     last_line = dst - dst_width;
350     for (; i < dst_height; i++) {
351         for (j = 0; j < dst_width; ++j) {
352             dst[j] = last_line[j];
353         }
354         dst += dst_width;
355     }
356 }
357
358 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
359         int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
360         int unsafe, int *qp)
361 {
362     int luma_stride, chroma_stride;
363     int hdr_size = 6, slice_size;
364     uint8_t *dest_y, *dest_u, *dest_v;
365     unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
366     ProresContext* ctx = avctx->priv_data;
367     FDCTDSPContext *fdsp = &ctx->fdsp;
368     int tgt_bits   = (mb_count * bitrate_table[avctx->profile]) >> 2;
369     int low_bytes  = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
370     int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
371
372     LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
373     LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
374     LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
375
376     luma_stride   = pic->linesize[0];
377     chroma_stride = pic->linesize[1];
378
379     dest_y = pic->data[0] + (mb_y << 4) * luma_stride   + (mb_x << 5);
380     dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << 4);
381     dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << 4);
382
383     if (unsafe) {
384
385         subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
386                 luma_stride, avctx->width, avctx->height,
387                 (uint16_t *) ctx->fill_y, mb_count << 4, 16);
388         subimage_with_fill((uint16_t *) pic->data[1], mb_x << 3, mb_y << 4,
389                 chroma_stride, avctx->width >> 1, avctx->height,
390                 (uint16_t *) ctx->fill_u, mb_count << 3, 16);
391         subimage_with_fill((uint16_t *) pic->data[2], mb_x << 3, mb_y << 4,
392                 chroma_stride, avctx->width >> 1, avctx->height,
393                 (uint16_t *) ctx->fill_v, mb_count << 3, 16);
394
395         calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count << 5, mb_count, 0);
396         calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << 4, mb_count, 1);
397         calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << 4, mb_count, 1);
398
399         encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
400                           mb_count, buf + hdr_size, data_size - hdr_size,
401                           &y_data_size, &u_data_size, &v_data_size,
402                           *qp);
403     } else {
404         calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0);
405         calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1);
406         calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1);
407
408         slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
409                           mb_count, buf + hdr_size, data_size - hdr_size,
410                           &y_data_size, &u_data_size, &v_data_size,
411                           *qp);
412
413         if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
414             do {
415                 *qp += 1;
416                 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
417                                                mb_count, buf + hdr_size, data_size - hdr_size,
418                                                &y_data_size, &u_data_size, &v_data_size,
419                                                *qp);
420             } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
421         } else if (slice_size < low_bytes && *qp
422                 > qp_start_table[avctx->profile]) {
423             do {
424                 *qp -= 1;
425                 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
426                                                mb_count, buf + hdr_size, data_size - hdr_size,
427                                                &y_data_size, &u_data_size, &v_data_size,
428                                                *qp);
429             } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
430         }
431     }
432
433     buf[0] = hdr_size << 3;
434     buf[1] = *qp;
435     AV_WB16(buf + 2, y_data_size);
436     AV_WB16(buf + 4, u_data_size);
437
438     return hdr_size + y_data_size + u_data_size + v_data_size;
439 }
440
441 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
442         uint8_t *buf, const int buf_size)
443 {
444     int mb_width = (avctx->width + 15) >> 4;
445     int mb_height = (avctx->height + 15) >> 4;
446     int hdr_size, sl_size, i;
447     int mb_y, sl_data_size, qp;
448     int unsafe_bot, unsafe_right;
449     uint8_t *sl_data, *sl_data_sizes;
450     int slice_per_line = 0, rem = mb_width;
451
452     for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
453         slice_per_line += rem >> i;
454         rem &= (1 << i) - 1;
455     }
456
457     qp = qp_start_table[avctx->profile];
458     hdr_size = 8; sl_data_size = buf_size - hdr_size;
459     sl_data_sizes = buf + hdr_size;
460     sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
461     for (mb_y = 0; mb_y < mb_height; mb_y++) {
462         int mb_x = 0;
463         int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
464         while (mb_x < mb_width) {
465             while (mb_width - mb_x < slice_mb_count)
466                 slice_mb_count >>= 1;
467
468             unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
469             unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
470
471             sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
472                     sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
473
474             bytestream_put_be16(&sl_data_sizes, sl_size);
475             sl_data           += sl_size;
476             sl_data_size      -= sl_size;
477             mb_x              += slice_mb_count;
478         }
479     }
480
481     buf[0] = hdr_size << 3;
482     AV_WB32(buf + 1, sl_data - buf);
483     AV_WB16(buf + 5, slice_per_line * mb_height);
484     buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
485
486     return sl_data - buf;
487 }
488
489 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
490                                const AVFrame *pict, int *got_packet)
491 {
492     int header_size = 148;
493     uint8_t *buf;
494     int pic_size, ret;
495     int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
496
497
498     if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
499         return ret;
500
501     buf = pkt->data;
502     pic_size = prores_encode_picture(avctx, pict, buf + header_size + 8,
503             pkt->size - header_size - 8);
504
505     bytestream_put_be32(&buf, pic_size + 8 + header_size);
506     bytestream_put_buffer(&buf, "icpf", 4);
507
508     bytestream_put_be16(&buf, header_size);
509     bytestream_put_be16(&buf, 0);
510     bytestream_put_buffer(&buf, "fmpg", 4);
511     bytestream_put_be16(&buf, avctx->width);
512     bytestream_put_be16(&buf, avctx->height);
513     *buf++ = 0x83; // {10}(422){00}{00}(frame){11}
514     *buf++ = 0;
515     *buf++ = pict->color_primaries;
516     *buf++ = pict->color_trc;
517     *buf++ = pict->colorspace;
518     *buf++ = 32;
519     *buf++ = 0;
520     *buf++ = 3;
521
522     bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile],   64);
523     bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
524
525     pkt->flags |= AV_PKT_FLAG_KEY;
526     pkt->size = pic_size + 8 + header_size;
527     *got_packet = 1;
528
529     return 0;
530 }
531
532 static void scale_mat(const uint8_t* src, int* dst, int scale)
533 {
534     int i;
535     for (i = 0; i < 64; i++)
536         dst[i] = src[i] * scale;
537 }
538
539 static av_cold int prores_encode_init(AVCodecContext *avctx)
540 {
541     int i;
542     ProresContext* ctx = avctx->priv_data;
543
544     if (avctx->pix_fmt != AV_PIX_FMT_YUV422P10) {
545         av_log(avctx, AV_LOG_ERROR, "need YUV422P10\n");
546         return AVERROR_PATCHWELCOME;
547     }
548     avctx->bits_per_raw_sample = 10;
549
550     if (avctx->width & 0x1) {
551         av_log(avctx, AV_LOG_ERROR,
552                 "frame width needs to be multiple of 2\n");
553         return AVERROR(EINVAL);
554     }
555
556     if (avctx->width > 65534 || avctx->height > 65535) {
557         av_log(avctx, AV_LOG_ERROR,
558                 "The maximum dimensions are 65534x65535\n");
559         return AVERROR(EINVAL);
560     }
561
562     if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
563         ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
564         if (!ctx->fill_y)
565             return AVERROR(ENOMEM);
566         ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
567         ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
568     }
569
570     if (avctx->profile == FF_PROFILE_UNKNOWN) {
571         avctx->profile = FF_PROFILE_PRORES_STANDARD;
572         av_log(avctx, AV_LOG_INFO,
573                 "encoding with ProRes standard (apcn) profile\n");
574
575     } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
576             || avctx->profile > FF_PROFILE_PRORES_HQ) {
577         av_log(
578                 avctx,
579                 AV_LOG_ERROR,
580                 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch]\n",
581                 avctx->profile);
582         return AVERROR(EINVAL);
583     }
584
585     ff_fdctdsp_init(&ctx->fdsp, avctx);
586
587     avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
588
589     for (i = 1; i <= 16; i++) {
590         scale_mat(QMAT_LUMA[avctx->profile]  , ctx->qmat_luma[i - 1]  , i);
591         scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
592     }
593
594     return 0;
595 }
596
597 static av_cold int prores_encode_close(AVCodecContext *avctx)
598 {
599     ProresContext* ctx = avctx->priv_data;
600     av_freep(&ctx->fill_y);
601
602     return 0;
603 }
604
605 AVCodec ff_prores_aw_encoder = {
606     .name           = "prores_aw",
607     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
608     .type           = AVMEDIA_TYPE_VIDEO,
609     .id             = AV_CODEC_ID_PRORES,
610     .priv_data_size = sizeof(ProresContext),
611     .init           = prores_encode_init,
612     .close          = prores_encode_close,
613     .encode2        = prores_encode_frame,
614     .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
615     .capabilities   = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
616     .profiles       = profiles
617 };
618
619 AVCodec ff_prores_encoder = {
620     .name           = "prores",
621     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
622     .type           = AVMEDIA_TYPE_VIDEO,
623     .id             = AV_CODEC_ID_PRORES,
624     .priv_data_size = sizeof(ProresContext),
625     .init           = prores_encode_init,
626     .close          = prores_encode_close,
627     .encode2        = prores_encode_frame,
628     .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
629     .capabilities   = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
630     .profiles       = profiles
631 };