]> git.sesse.net Git - ffmpeg/blob - libavcodec/proresenc_anatoliy.c
prores: Use profile names in the various encoders and decoders
[ffmpeg] / libavcodec / proresenc_anatoliy.c
1 /*
2  * Apple ProRes encoder
3  *
4  * Copyright (c) 2011 Anatoliy Wasserman
5  * Copyright (c) 2012 Konstantin Shishkov
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23
24 /**
25  * @file
26  * Apple ProRes encoder (Anatoliy Wasserman version)
27  * Known FOURCCs: 'ap4h' (444), 'apch' (HQ), 'apcn' (422), 'apcs' (LT), 'acpo' (Proxy)
28  */
29
30 #include "avcodec.h"
31 #include "dct.h"
32 #include "internal.h"
33 #include "profiles.h"
34 #include "proresdata.h"
35 #include "put_bits.h"
36 #include "bytestream.h"
37 #include "fdctdsp.h"
38
39 #define DEFAULT_SLICE_MB_WIDTH 8
40
41 static const AVProfile profiles[] = {
42     { FF_PROFILE_PRORES_PROXY,    "apco"},
43     { FF_PROFILE_PRORES_LT,       "apcs"},
44     { FF_PROFILE_PRORES_STANDARD, "apcn"},
45     { FF_PROFILE_PRORES_HQ,       "apch"},
46     { FF_PROFILE_PRORES_4444,     "ap4h"},
47     { FF_PROFILE_UNKNOWN }
48 };
49
50 static const int qp_start_table[5] = {  8, 3, 2, 1, 1};
51 static const int qp_end_table[5]   = { 13, 9, 6, 6, 5};
52 static const int bitrate_table[5]  = { 1000, 2100, 3500, 5400, 7000};
53
54 static const uint8_t QMAT_LUMA[5][64] = {
55     {
56          4,  7,  9, 11, 13, 14, 15, 63,
57          7,  7, 11, 12, 14, 15, 63, 63,
58          9, 11, 13, 14, 15, 63, 63, 63,
59         11, 11, 13, 14, 63, 63, 63, 63,
60         11, 13, 14, 63, 63, 63, 63, 63,
61         13, 14, 63, 63, 63, 63, 63, 63,
62         13, 63, 63, 63, 63, 63, 63, 63,
63         63, 63, 63, 63, 63, 63, 63, 63
64     }, {
65          4,  5,  6,  7,  9, 11, 13, 15,
66          5,  5,  7,  8, 11, 13, 15, 17,
67          6,  7,  9, 11, 13, 15, 15, 17,
68          7,  7,  9, 11, 13, 15, 17, 19,
69          7,  9, 11, 13, 14, 16, 19, 23,
70          9, 11, 13, 14, 16, 19, 23, 29,
71          9, 11, 13, 15, 17, 21, 28, 35,
72         11, 13, 16, 17, 21, 28, 35, 41
73     }, {
74          4,  4,  5,  5,  6,  7,  7,  9,
75          4,  4,  5,  6,  7,  7,  9,  9,
76          5,  5,  6,  7,  7,  9,  9, 10,
77          5,  5,  6,  7,  7,  9,  9, 10,
78          5,  6,  7,  7,  8,  9, 10, 12,
79          6,  7,  7,  8,  9, 10, 12, 15,
80          6,  7,  7,  9, 10, 11, 14, 17,
81          7,  7,  9, 10, 11, 14, 17, 21
82     }, {
83          4,  4,  4,  4,  4,  4,  4,  4,
84          4,  4,  4,  4,  4,  4,  4,  4,
85          4,  4,  4,  4,  4,  4,  4,  4,
86          4,  4,  4,  4,  4,  4,  4,  5,
87          4,  4,  4,  4,  4,  4,  5,  5,
88          4,  4,  4,  4,  4,  5,  5,  6,
89          4,  4,  4,  4,  5,  5,  6,  7,
90          4,  4,  4,  4,  5,  6,  7,  7
91     }, { /* 444 */
92         4,  4,  4,  4,  4,  4,  4,  4,
93         4,  4,  4,  4,  4,  4,  4,  4,
94         4,  4,  4,  4,  4,  4,  4,  4,
95         4,  4,  4,  4,  4,  4,  4,  5,
96         4,  4,  4,  4,  4,  4,  5,  5,
97         4,  4,  4,  4,  4,  5,  5,  6,
98         4,  4,  4,  4,  5,  5,  6,  7,
99         4,  4,  4,  4,  5,  6,  7,  7
100     }
101 };
102
103 static const uint8_t QMAT_CHROMA[5][64] = {
104     {
105          4,  7,  9, 11, 13, 14, 63, 63,
106          7,  7, 11, 12, 14, 63, 63, 63,
107          9, 11, 13, 14, 63, 63, 63, 63,
108         11, 11, 13, 14, 63, 63, 63, 63,
109         11, 13, 14, 63, 63, 63, 63, 63,
110         13, 14, 63, 63, 63, 63, 63, 63,
111         13, 63, 63, 63, 63, 63, 63, 63,
112         63, 63, 63, 63, 63, 63, 63, 63
113     }, {
114          4,  5,  6,  7,  9, 11, 13, 15,
115          5,  5,  7,  8, 11, 13, 15, 17,
116          6,  7,  9, 11, 13, 15, 15, 17,
117          7,  7,  9, 11, 13, 15, 17, 19,
118          7,  9, 11, 13, 14, 16, 19, 23,
119          9, 11, 13, 14, 16, 19, 23, 29,
120          9, 11, 13, 15, 17, 21, 28, 35,
121         11, 13, 16, 17, 21, 28, 35, 41
122     }, {
123          4,  4,  5,  5,  6,  7,  7,  9,
124          4,  4,  5,  6,  7,  7,  9,  9,
125          5,  5,  6,  7,  7,  9,  9, 10,
126          5,  5,  6,  7,  7,  9,  9, 10,
127          5,  6,  7,  7,  8,  9, 10, 12,
128          6,  7,  7,  8,  9, 10, 12, 15,
129          6,  7,  7,  9, 10, 11, 14, 17,
130          7,  7,  9, 10, 11, 14, 17, 21
131     }, {
132          4,  4,  4,  4,  4,  4,  4,  4,
133          4,  4,  4,  4,  4,  4,  4,  4,
134          4,  4,  4,  4,  4,  4,  4,  4,
135          4,  4,  4,  4,  4,  4,  4,  5,
136          4,  4,  4,  4,  4,  4,  5,  5,
137          4,  4,  4,  4,  4,  5,  5,  6,
138          4,  4,  4,  4,  5,  5,  6,  7,
139          4,  4,  4,  4,  5,  6,  7,  7
140     }, { /* 444 */
141         4,  4,  4,  4,  4,  4,  4,  4,
142         4,  4,  4,  4,  4,  4,  4,  4,
143         4,  4,  4,  4,  4,  4,  4,  4,
144         4,  4,  4,  4,  4,  4,  4,  5,
145         4,  4,  4,  4,  4,  4,  5,  5,
146         4,  4,  4,  4,  4,  5,  5,  6,
147         4,  4,  4,  4,  5,  5,  6,  7,
148         4,  4,  4,  4,  5,  6,  7,  7
149     }
150 };
151
152
153 typedef struct {
154     FDCTDSPContext fdsp;
155     uint8_t* fill_y;
156     uint8_t* fill_u;
157     uint8_t* fill_v;
158
159     int qmat_luma[16][64];
160     int qmat_chroma[16][64];
161
162     int is_422;
163 } ProresContext;
164
165 static void encode_codeword(PutBitContext *pb, int val, int codebook)
166 {
167     unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
168
169     /* number of bits to switch between rice and exp golomb */
170     switch_bits = codebook & 3;
171     rice_order  = codebook >> 5;
172     exp_order   = (codebook >> 2) & 7;
173
174     first_exp = ((switch_bits + 1) << rice_order);
175
176     if (val >= first_exp) { /* exp golomb */
177         val -= first_exp;
178         val += (1 << exp_order);
179         exp = av_log2(val);
180         zeros = exp - exp_order + switch_bits + 1;
181         put_bits(pb, zeros, 0);
182         put_bits(pb, exp + 1, val);
183     } else if (rice_order) {
184         put_bits(pb, (val >> rice_order), 0);
185         put_bits(pb, 1, 1);
186         put_sbits(pb, rice_order, val);
187     } else {
188         put_bits(pb, val, 0);
189         put_bits(pb, 1, 1);
190     }
191 }
192
193 #define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
194 #define TO_GOLOMB(val) (((val) << 1) ^ ((val) >> 31))
195 #define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
196 #define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
197 #define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
198
199 static av_always_inline int get_level(int val)
200 {
201     int sign = (val >> 31);
202     return (val ^ sign) - sign;
203 }
204
205 #define FIRST_DC_CB 0xB8
206
207 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
208
209 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
210         int blocks_per_slice, int *qmat)
211 {
212     int prev_dc, code;
213     int i, sign, idx;
214     int new_dc, delta, diff_sign, new_code;
215
216     prev_dc = QSCALE(qmat, 0, in[0] - 16384);
217     code = TO_GOLOMB(prev_dc);
218     encode_codeword(pb, code, FIRST_DC_CB);
219
220     code = 5; sign = 0; idx = 64;
221     for (i = 1; i < blocks_per_slice; i++, idx += 64) {
222         new_dc    = QSCALE(qmat, 0, in[idx] - 16384);
223         delta     = new_dc - prev_dc;
224         diff_sign = DIFF_SIGN(delta, sign);
225         new_code  = TO_GOLOMB2(get_level(delta), diff_sign);
226
227         encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
228
229         code      = new_code;
230         sign      = delta >> 31;
231         prev_dc   = new_dc;
232     }
233 }
234
235 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
236         0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
237 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
238         0x28, 0x28, 0x28, 0x4C };
239
240 static void encode_ac_coeffs(PutBitContext *pb,
241         int16_t *in, int blocks_per_slice, int *qmat)
242 {
243     int prev_run = 4;
244     int prev_level = 2;
245
246     int run = 0, level, code, i, j;
247     for (i = 1; i < 64; i++) {
248         int indp = ff_prores_progressive_scan[i];
249         for (j = 0; j < blocks_per_slice; j++) {
250             int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
251             if (val) {
252                 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
253
254                 prev_run   = run;
255                 run        = 0;
256                 level      = get_level(val);
257                 code       = level - 1;
258
259                 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
260
261                 prev_level = level;
262
263                 put_bits(pb, 1, IS_NEGATIVE(val));
264             } else {
265                 ++run;
266             }
267         }
268     }
269 }
270
271 static void get(uint8_t *pixels, int stride, int16_t* block)
272 {
273     int i;
274
275     for (i = 0; i < 8; i++) {
276         AV_WN64(block, AV_RN64(pixels));
277         AV_WN64(block+4, AV_RN64(pixels+8));
278         pixels += stride;
279         block += 8;
280     }
281 }
282
283 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
284 {
285     get(pixels, stride, block);
286     fdsp->fdct(block);
287 }
288
289 static void calc_plane_dct(FDCTDSPContext *fdsp, uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma, int is_422)
290 {
291     int16_t *block;
292     int i;
293
294     block = blocks;
295
296     if (!chroma) { /* Luma plane */
297         for (i = 0; i < mb_count; i++) {
298             fdct_get(fdsp, src,                       src_stride, block + (0 << 6));
299             fdct_get(fdsp, src + 16,                  src_stride, block + (1 << 6));
300             fdct_get(fdsp, src +      8 * src_stride, src_stride, block + (2 << 6));
301             fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
302
303             block += 256;
304             src   += 32;
305         }
306     } else if (chroma && is_422){ /* chroma plane 422 */
307         for (i = 0; i < mb_count; i++) {
308             fdct_get(fdsp, src,                  src_stride, block + (0 << 6));
309             fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
310             block += (256 >> 1);
311             src   += (32  >> 1);
312         }
313     } else { /* chroma plane 444 */
314         for (i = 0; i < mb_count; i++) {
315             fdct_get(fdsp, src,                       src_stride, block + (0 << 6));
316             fdct_get(fdsp, src +      8 * src_stride, src_stride, block + (1 << 6));
317             fdct_get(fdsp, src + 16,                  src_stride, block + (2 << 6));
318             fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
319
320             block += 256;
321             src   += 32;
322         }
323     }
324 }
325
326 static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int sub_sample_chroma)
327 {
328     int blocks_per_slice;
329     PutBitContext pb;
330
331     blocks_per_slice = mb_count << (2 - sub_sample_chroma);
332     init_put_bits(&pb, buf, buf_size);
333
334     encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
335     encode_ac_coeffs(&pb, blocks, blocks_per_slice, qmat);
336
337     flush_put_bits(&pb);
338     return put_bits_ptr(&pb) - pb.buf;
339 }
340
341 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
342                                                    int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
343                                                    unsigned mb_count, uint8_t *buf, unsigned data_size,
344                                                    unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
345                                                    int qp)
346 {
347     ProresContext* ctx = avctx->priv_data;
348
349     *y_data_size = encode_slice_plane(blocks_y, mb_count,
350                                       buf, data_size, ctx->qmat_luma[qp - 1], 0);
351
352     if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
353         *u_data_size = encode_slice_plane(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
354                                           ctx->qmat_chroma[qp - 1], ctx->is_422);
355
356         *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
357                                           data_size - *y_data_size - *u_data_size,
358                                           ctx->qmat_chroma[qp - 1], ctx->is_422);
359     }
360
361     return *y_data_size + *u_data_size + *v_data_size;
362 }
363
364 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
365         unsigned stride, unsigned width, unsigned height, uint16_t *dst,
366         unsigned dst_width, unsigned dst_height)
367 {
368
369     int box_width = FFMIN(width - x, dst_width);
370     int box_height = FFMIN(height - y, dst_height);
371     int i, j, src_stride = stride >> 1;
372     uint16_t last_pix, *last_line;
373
374     src += y * src_stride + x;
375     for (i = 0; i < box_height; ++i) {
376         for (j = 0; j < box_width; ++j) {
377             dst[j] = src[j];
378         }
379         last_pix = dst[j - 1];
380         for (; j < dst_width; j++)
381             dst[j] = last_pix;
382         src += src_stride;
383         dst += dst_width;
384     }
385     last_line = dst - dst_width;
386     for (; i < dst_height; i++) {
387         for (j = 0; j < dst_width; ++j) {
388             dst[j] = last_line[j];
389         }
390         dst += dst_width;
391     }
392 }
393
394 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
395         int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
396         int unsafe, int *qp)
397 {
398     int luma_stride, chroma_stride;
399     int hdr_size = 6, slice_size;
400     uint8_t *dest_y, *dest_u, *dest_v;
401     unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
402     ProresContext* ctx = avctx->priv_data;
403     FDCTDSPContext *fdsp = &ctx->fdsp;
404     int tgt_bits   = (mb_count * bitrate_table[avctx->profile]) >> 2;
405     int low_bytes  = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
406     int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
407
408     LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
409     LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
410     LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
411
412     luma_stride   = pic->linesize[0];
413     chroma_stride = pic->linesize[1];
414
415     dest_y = pic->data[0] + (mb_y << 4) * luma_stride   + (mb_x << 5);
416     dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
417     dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
418
419     if (unsafe) {
420         subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
421                 luma_stride, avctx->width, avctx->height,
422                 (uint16_t *) ctx->fill_y, mb_count << 4, 16);
423         subimage_with_fill((uint16_t *) pic->data[1], mb_x << (4 - ctx->is_422), mb_y << 4,
424                            chroma_stride, avctx->width >> ctx->is_422, avctx->height,
425                            (uint16_t *) ctx->fill_u, mb_count << (4 - ctx->is_422), 16);
426         subimage_with_fill((uint16_t *) pic->data[2], mb_x << (4 - ctx->is_422), mb_y << 4,
427                            chroma_stride, avctx->width >> ctx->is_422, avctx->height,
428                            (uint16_t *) ctx->fill_v, mb_count << (4 - ctx->is_422), 16);
429
430         calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count <<  5,                mb_count, 0, 0);
431         calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
432         calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
433
434         encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
435                           mb_count, buf + hdr_size, data_size - hdr_size,
436                           &y_data_size, &u_data_size, &v_data_size,
437                           *qp);
438     } else {
439         calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0, 0);
440         calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1, ctx->is_422);
441         calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1, ctx->is_422);
442
443         slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
444                           mb_count, buf + hdr_size, data_size - hdr_size,
445                           &y_data_size, &u_data_size, &v_data_size,
446                           *qp);
447
448         if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
449             do {
450                 *qp += 1;
451                 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
452                                                mb_count, buf + hdr_size, data_size - hdr_size,
453                                                &y_data_size, &u_data_size, &v_data_size,
454                                                *qp);
455             } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
456         } else if (slice_size < low_bytes && *qp
457                 > qp_start_table[avctx->profile]) {
458             do {
459                 *qp -= 1;
460                 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
461                                                mb_count, buf + hdr_size, data_size - hdr_size,
462                                                &y_data_size, &u_data_size, &v_data_size,
463                                                *qp);
464             } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
465         }
466     }
467
468     buf[0] = hdr_size << 3;
469     buf[1] = *qp;
470     AV_WB16(buf + 2, y_data_size);
471     AV_WB16(buf + 4, u_data_size);
472
473     return hdr_size + y_data_size + u_data_size + v_data_size;
474 }
475
476 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
477         uint8_t *buf, const int buf_size)
478 {
479     int mb_width = (avctx->width + 15) >> 4;
480     int mb_height = (avctx->height + 15) >> 4;
481     int hdr_size, sl_size, i;
482     int mb_y, sl_data_size, qp;
483     int unsafe_bot, unsafe_right;
484     uint8_t *sl_data, *sl_data_sizes;
485     int slice_per_line = 0, rem = mb_width;
486
487     for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
488         slice_per_line += rem >> i;
489         rem &= (1 << i) - 1;
490     }
491
492     qp = qp_start_table[avctx->profile];
493     hdr_size = 8; sl_data_size = buf_size - hdr_size;
494     sl_data_sizes = buf + hdr_size;
495     sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
496     for (mb_y = 0; mb_y < mb_height; mb_y++) {
497         int mb_x = 0;
498         int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
499         while (mb_x < mb_width) {
500             while (mb_width - mb_x < slice_mb_count)
501                 slice_mb_count >>= 1;
502
503             unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
504             unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
505
506             sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
507                     sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
508
509             bytestream_put_be16(&sl_data_sizes, sl_size);
510             sl_data           += sl_size;
511             sl_data_size      -= sl_size;
512             mb_x              += slice_mb_count;
513         }
514     }
515
516     buf[0] = hdr_size << 3;
517     AV_WB32(buf + 1, sl_data - buf);
518     AV_WB16(buf + 5, slice_per_line * mb_height);
519     buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
520
521     return sl_data - buf;
522 }
523
524 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
525                                const AVFrame *pict, int *got_packet)
526 {
527     int header_size = 148;
528     uint8_t *buf;
529     int pic_size, ret;
530     int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
531
532
533     if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
534         return ret;
535
536     buf = pkt->data;
537     pic_size = prores_encode_picture(avctx, pict, buf + header_size + 8,
538             pkt->size - header_size - 8);
539
540     bytestream_put_be32(&buf, pic_size + 8 + header_size);
541     bytestream_put_buffer(&buf, "icpf", 4);
542
543     bytestream_put_be16(&buf, header_size);
544     bytestream_put_be16(&buf, 0);
545     bytestream_put_buffer(&buf, "fmpg", 4);
546     bytestream_put_be16(&buf, avctx->width);
547     bytestream_put_be16(&buf, avctx->height);
548     if (avctx->profile == FF_PROFILE_PRORES_4444) {
549         *buf++ = 0xC2; // 444, not interlaced
550     } else {
551         *buf++ = 0x82; // 422, not interlaced
552     }
553     *buf++ = 0;
554     *buf++ = pict->color_primaries;
555     *buf++ = pict->color_trc;
556     *buf++ = pict->colorspace;
557     *buf++ = 32;
558     *buf++ = 0;
559     *buf++ = 3;
560
561     bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile],   64);
562     bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
563
564     pkt->flags |= AV_PKT_FLAG_KEY;
565     pkt->size = pic_size + 8 + header_size;
566     *got_packet = 1;
567
568     return 0;
569 }
570
571 static void scale_mat(const uint8_t* src, int* dst, int scale)
572 {
573     int i;
574     for (i = 0; i < 64; i++)
575         dst[i] = src[i] * scale;
576 }
577
578 static av_cold int prores_encode_init(AVCodecContext *avctx)
579 {
580     int i;
581     ProresContext* ctx = avctx->priv_data;
582
583     avctx->bits_per_raw_sample = 10;
584
585     if (avctx->width & 0x1) {
586         av_log(avctx, AV_LOG_ERROR,
587                 "frame width needs to be multiple of 2\n");
588         return AVERROR(EINVAL);
589     }
590
591     if (avctx->width > 65534 || avctx->height > 65535) {
592         av_log(avctx, AV_LOG_ERROR,
593                 "The maximum dimensions are 65534x65535\n");
594         return AVERROR(EINVAL);
595     }
596
597     if (avctx->profile == FF_PROFILE_UNKNOWN) {
598         if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) {
599             avctx->profile = FF_PROFILE_PRORES_STANDARD;
600             av_log(avctx, AV_LOG_INFO,
601                 "encoding with ProRes standard (apcn) profile\n");
602         } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
603             avctx->profile = FF_PROFILE_PRORES_4444;
604             av_log(avctx, AV_LOG_INFO,
605                    "encoding with ProRes 4444 (ap4h) profile\n");
606         }
607
608     } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
609             || avctx->profile > FF_PROFILE_PRORES_4444) {
610         av_log(
611                 avctx,
612                 AV_LOG_ERROR,
613                 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch, 4 - ap4h]\n",
614                 avctx->profile);
615         return AVERROR(EINVAL);
616     } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P10) && (avctx->profile > FF_PROFILE_PRORES_HQ)){
617         av_log(avctx, AV_LOG_ERROR,
618                "encoding with ProRes 444 (ap4h) profile, need YUV444P10 input\n");
619         return AVERROR(EINVAL);
620     }  else if ((avctx->pix_fmt == AV_PIX_FMT_YUV444P10) && (avctx->profile < FF_PROFILE_PRORES_4444)){
621         av_log(avctx, AV_LOG_ERROR,
622                "encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input\n");
623         return AVERROR(EINVAL);
624     }
625
626     if (avctx->profile < FF_PROFILE_PRORES_4444) { /* 422 versions */
627         ctx->is_422 = 1;
628         if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
629             ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
630             if (!ctx->fill_y)
631                 return AVERROR(ENOMEM);
632             ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
633             ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
634         }
635     } else { /* 444 */
636         ctx->is_422 = 0;
637         if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
638             ctx->fill_y = av_malloc(3 * (DEFAULT_SLICE_MB_WIDTH << 9));
639             if (!ctx->fill_y)
640                 return AVERROR(ENOMEM);
641             ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
642             ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 9);
643         }
644     }
645
646     ff_fdctdsp_init(&ctx->fdsp, avctx);
647
648     avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
649
650     for (i = 1; i <= 16; i++) {
651         scale_mat(QMAT_LUMA[avctx->profile]  , ctx->qmat_luma[i - 1]  , i);
652         scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
653     }
654
655     return 0;
656 }
657
658 static av_cold int prores_encode_close(AVCodecContext *avctx)
659 {
660     ProresContext* ctx = avctx->priv_data;
661     av_freep(&ctx->fill_y);
662
663     return 0;
664 }
665
666 AVCodec ff_prores_aw_encoder = {
667     .name           = "prores_aw",
668     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
669     .type           = AVMEDIA_TYPE_VIDEO,
670     .id             = AV_CODEC_ID_PRORES,
671     .priv_data_size = sizeof(ProresContext),
672     .init           = prores_encode_init,
673     .close          = prores_encode_close,
674     .encode2        = prores_encode_frame,
675     .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE},
676     .capabilities   = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
677     .profiles       = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
678 };
679
680 AVCodec ff_prores_encoder = {
681     .name           = "prores",
682     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
683     .type           = AVMEDIA_TYPE_VIDEO,
684     .id             = AV_CODEC_ID_PRORES,
685     .priv_data_size = sizeof(ProresContext),
686     .init           = prores_encode_init,
687     .close          = prores_encode_close,
688     .encode2        = prores_encode_frame,
689     .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE},
690     .capabilities   = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
691     .profiles       = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
692 };