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