1 /*
2  * Apple ProRes encoder
3  *
4  * Copyright (c) 2011 Anatoliy Wasserman
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /**
24  * @file
25  * Apple ProRes encoder (Anatoliy Wasserman version)
26  * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy)
27  */
28 
29 #include "avcodec.h"
30 #include "dct.h"
31 #include "internal.h"
32 #include "put_bits.h"
33 #include "bytestream.h"
34 #include "fdctdsp.h"
35 
36 #define DEFAULT_SLICE_MB_WIDTH 8
37 
38 #define FF_PROFILE_PRORES_PROXY     0
39 #define FF_PROFILE_PRORES_LT        1
40 #define FF_PROFILE_PRORES_STANDARD  2
41 #define FF_PROFILE_PRORES_HQ        3
42 
43 static const AVProfile profiles[] = {
44     { FF_PROFILE_PRORES_PROXY,    "apco"},
45     { FF_PROFILE_PRORES_LT,       "apcs"},
46     { FF_PROFILE_PRORES_STANDARD, "apcn"},
47     { FF_PROFILE_PRORES_HQ,       "apch"},
48     { FF_PROFILE_UNKNOWN }
49 };
50 
51 static const int qp_start_table[4] = { 4, 1, 1, 1 };
52 static const int qp_end_table[4]   = { 8, 9, 6, 6 };
53 static const int bitrate_table[5]  = { 1000, 2100, 3500, 5400 };
54 
55 static const uint8_t progressive_scan[64] = {
56      0,  1,  8,  9,  2,  3, 10, 11,
57     16, 17, 24, 25, 18, 19, 26, 27,
58      4,  5, 12, 20, 13,  6,  7, 14,
59     21, 28, 29, 22, 15, 23, 30, 31,
60     32, 33, 40, 48, 41, 34, 35, 42,
61     49, 56, 57, 50, 43, 36, 37, 44,
62     51, 58, 59, 52, 45, 38, 39, 46,
63     53, 60, 61, 54, 47, 55, 62, 63
64 };
65 
66 static const uint8_t QMAT_LUMA[4][64] = {
67     {
68          4,  7,  9, 11, 13, 14, 15, 63,
69          7,  7, 11, 12, 14, 15, 63, 63,
70          9, 11, 13, 14, 15, 63, 63, 63,
71         11, 11, 13, 14, 63, 63, 63, 63,
72         11, 13, 14, 63, 63, 63, 63, 63,
73         13, 14, 63, 63, 63, 63, 63, 63,
74         13, 63, 63, 63, 63, 63, 63, 63,
75         63, 63, 63, 63, 63, 63, 63, 63
76     }, {
77          4,  5,  6,  7,  9, 11, 13, 15,
78          5,  5,  7,  8, 11, 13, 15, 17,
79          6,  7,  9, 11, 13, 15, 15, 17,
80          7,  7,  9, 11, 13, 15, 17, 19,
81          7,  9, 11, 13, 14, 16, 19, 23,
82          9, 11, 13, 14, 16, 19, 23, 29,
83          9, 11, 13, 15, 17, 21, 28, 35,
84         11, 13, 16, 17, 21, 28, 35, 41
85     }, {
86          4,  4,  5,  5,  6,  7,  7,  9,
87          4,  4,  5,  6,  7,  7,  9,  9,
88          5,  5,  6,  7,  7,  9,  9, 10,
89          5,  5,  6,  7,  7,  9,  9, 10,
90          5,  6,  7,  7,  8,  9, 10, 12,
91          6,  7,  7,  8,  9, 10, 12, 15,
92          6,  7,  7,  9, 10, 11, 14, 17,
93          7,  7,  9, 10, 11, 14, 17, 21
94     }, {
95          4,  4,  4,  4,  4,  4,  4,  4,
96          4,  4,  4,  4,  4,  4,  4,  4,
97          4,  4,  4,  4,  4,  4,  4,  4,
98          4,  4,  4,  4,  4,  4,  4,  5,
99          4,  4,  4,  4,  4,  4,  5,  5,
100          4,  4,  4,  4,  4,  5,  5,  6,
101          4,  4,  4,  4,  5,  5,  6,  7,
102          4,  4,  4,  4,  5,  6,  7,  7
103     }
104 };
105 
106 static const uint8_t QMAT_CHROMA[4][64] = {
107     {
108          4,  7,  9, 11, 13, 14, 63, 63,
109          7,  7, 11, 12, 14, 63, 63, 63,
110          9, 11, 13, 14, 63, 63, 63, 63,
111         11, 11, 13, 14, 63, 63, 63, 63,
112         11, 13, 14, 63, 63, 63, 63, 63,
113         13, 14, 63, 63, 63, 63, 63, 63,
114         13, 63, 63, 63, 63, 63, 63, 63,
115         63, 63, 63, 63, 63, 63, 63, 63
116     }, {
117          4,  5,  6,  7,  9, 11, 13, 15,
118          5,  5,  7,  8, 11, 13, 15, 17,
119          6,  7,  9, 11, 13, 15, 15, 17,
120          7,  7,  9, 11, 13, 15, 17, 19,
121          7,  9, 11, 13, 14, 16, 19, 23,
122          9, 11, 13, 14, 16, 19, 23, 29,
123          9, 11, 13, 15, 17, 21, 28, 35,
124         11, 13, 16, 17, 21, 28, 35, 41
125     }, {
126          4,  4,  5,  5,  6,  7,  7,  9,
127          4,  4,  5,  6,  7,  7,  9,  9,
128          5,  5,  6,  7,  7,  9,  9, 10,
129          5,  5,  6,  7,  7,  9,  9, 10,
130          5,  6,  7,  7,  8,  9, 10, 12,
131          6,  7,  7,  8,  9, 10, 12, 15,
132          6,  7,  7,  9, 10, 11, 14, 17,
133          7,  7,  9, 10, 11, 14, 17, 21
134     }, {
135          4,  4,  4,  4,  4,  4,  4,  4,
136          4,  4,  4,  4,  4,  4,  4,  4,
137          4,  4,  4,  4,  4,  4,  4,  4,
138          4,  4,  4,  4,  4,  4,  4,  5,
139          4,  4,  4,  4,  4,  4,  5,  5,
140          4,  4,  4,  4,  4,  5,  5,  6,
141          4,  4,  4,  4,  5,  5,  6,  7,
142          4,  4,  4,  4,  5,  6,  7,  7
143     }
144 };
145 
146 
147 typedef struct {
148     FDCTDSPContext fdsp;
149     uint8_t* fill_y;
150     uint8_t* fill_u;
151     uint8_t* fill_v;
152 
153     int qmat_luma[16][64];
154     int qmat_chroma[16][64];
155 } ProresContext;
156 
encode_codeword(PutBitContext * pb,int val,int codebook)157 static void encode_codeword(PutBitContext *pb, int val, int codebook)
158 {
159     unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros,
160             mask;
161 
162     /* number of bits to switch between rice and exp golomb */
163     switch_bits = codebook & 3;
164     rice_order  = codebook >> 5;
165     exp_order   = (codebook >> 2) & 7;
166 
167     first_exp = ((switch_bits + 1) << rice_order);
168 
169     if (val >= first_exp) { /* exp golomb */
170         val -= first_exp;
171         val += (1 << exp_order);
172         exp = av_log2(val);
173         zeros = exp - exp_order + switch_bits + 1;
174         put_bits(pb, zeros, 0);
175         put_bits(pb, exp + 1, val);
176     } else if (rice_order) {
177         mask = (1 << rice_order) - 1;
178         put_bits(pb, (val >> rice_order), 0);
179         put_bits(pb, 1, 1);
180         put_bits(pb, rice_order, val & mask);
181     } else {
182         put_bits(pb, val, 0);
183         put_bits(pb, 1, 1);
184     }
185 }
186 
187 #define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
188 #define TO_GOLOMB(val) (((val) << 1) ^ ((val) >> 31))
189 #define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
190 #define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
191 #define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
192 
get_level(int val)193 static av_always_inline int get_level(int val)
194 {
195     int sign = (val >> 31);
196     return (val ^ sign) - sign;
197 }
198 
199 #define FIRST_DC_CB 0xB8
200 
201 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
202 
encode_dc_coeffs(PutBitContext * pb,int16_t * in,int blocks_per_slice,int * qmat)203 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
204         int blocks_per_slice, int *qmat)
205 {
206     int prev_dc, code;
207     int i, sign, idx;
208     int new_dc, delta, diff_sign, new_code;
209 
210     prev_dc = QSCALE(qmat, 0, in[0] - 16384);
211     code = TO_GOLOMB(prev_dc);
212     encode_codeword(pb, code, FIRST_DC_CB);
213 
214     code = 5; sign = 0; idx = 64;
215     for (i = 1; i < blocks_per_slice; i++, idx += 64) {
216         new_dc    = QSCALE(qmat, 0, in[idx] - 16384);
217         delta     = new_dc - prev_dc;
218         diff_sign = DIFF_SIGN(delta, sign);
219         new_code  = TO_GOLOMB2(get_level(delta), diff_sign);
220 
221         encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
222 
223         code      = new_code;
224         sign      = delta >> 31;
225         prev_dc   = new_dc;
226     }
227 }
228 
229 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
230         0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
231 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
232         0x28, 0x28, 0x28, 0x4C };
233 
encode_ac_coeffs(AVCodecContext * avctx,PutBitContext * pb,int16_t * in,int blocks_per_slice,int * qmat)234 static void encode_ac_coeffs(AVCodecContext *avctx, PutBitContext *pb,
235         int16_t *in, int blocks_per_slice, int *qmat)
236 {
237     int prev_run = 4;
238     int prev_level = 2;
239 
240     int run = 0, level, code, i, j;
241     for (i = 1; i < 64; i++) {
242         int indp = progressive_scan[i];
243         for (j = 0; j < blocks_per_slice; j++) {
244             int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
245             if (val) {
246                 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
247 
248                 prev_run   = run;
249                 run        = 0;
250                 level      = get_level(val);
251                 code       = level - 1;
252 
253                 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
254 
255                 prev_level = level;
256 
257                 put_bits(pb, 1, IS_NEGATIVE(val));
258             } else {
259                 ++run;
260             }
261         }
262     }
263 }
264 
get(uint8_t * pixels,int stride,int16_t * block)265 static void get(uint8_t *pixels, int stride, int16_t* block)
266 {
267     int i;
268 
269     for (i = 0; i < 8; i++) {
270         AV_WN64(block, AV_RN64(pixels));
271         AV_WN64(block+4, AV_RN64(pixels+8));
272         pixels += stride;
273         block += 8;
274     }
275 }
276 
fdct_get(FDCTDSPContext * fdsp,uint8_t * pixels,int stride,int16_t * block)277 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
278 {
279     get(pixels, stride, block);
280     fdsp->fdct(block);
281 }
282 
encode_slice_plane(AVCodecContext * avctx,int mb_count,uint8_t * src,int src_stride,uint8_t * buf,unsigned buf_size,int * qmat,int chroma)283 static int encode_slice_plane(AVCodecContext *avctx, int mb_count,
284         uint8_t *src, int src_stride, uint8_t *buf, unsigned buf_size,
285         int *qmat, int chroma)
286 {
287     ProresContext* ctx = avctx->priv_data;
288     FDCTDSPContext *fdsp = &ctx->fdsp;
289     DECLARE_ALIGNED(16, int16_t, blocks)[DEFAULT_SLICE_MB_WIDTH << 8], *block;
290     int i, blocks_per_slice;
291     PutBitContext pb;
292 
293     block = blocks;
294     for (i = 0; i < mb_count; i++) {
295         fdct_get(fdsp, src,                  src_stride, block + (0 << 6));
296         fdct_get(fdsp, src + 8 * src_stride, src_stride, block + ((2 - chroma) << 6));
297         if (!chroma) {
298             fdct_get(fdsp, src + 16,                  src_stride, block + (1 << 6));
299             fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
300         }
301 
302         block += (256 >> chroma);
303         src   += (32  >> chroma);
304     }
305 
306     blocks_per_slice = mb_count << (2 - chroma);
307     init_put_bits(&pb, buf, buf_size << 3);
308 
309     encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
310     encode_ac_coeffs(avctx, &pb, blocks, blocks_per_slice, qmat);
311 
312     flush_put_bits(&pb);
313     return put_bits_ptr(&pb) - pb.buf;
314 }
315 
encode_slice_data(AVCodecContext * avctx,uint8_t * dest_y,uint8_t * dest_u,uint8_t * dest_v,int luma_stride,int chroma_stride,unsigned mb_count,uint8_t * buf,unsigned data_size,unsigned * y_data_size,unsigned * u_data_size,unsigned * v_data_size,int qp)316 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
317         uint8_t *dest_y, uint8_t *dest_u, uint8_t *dest_v, int luma_stride,
318         int chroma_stride, unsigned mb_count, uint8_t *buf, unsigned data_size,
319         unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
320         int qp)
321 {
322     ProresContext* ctx = avctx->priv_data;
323 
324     *y_data_size = encode_slice_plane(avctx, mb_count, dest_y, luma_stride,
325             buf, data_size, ctx->qmat_luma[qp - 1], 0);
326 
327     if (!(avctx->flags & CODEC_FLAG_GRAY)) {
328         *u_data_size = encode_slice_plane(avctx, mb_count, dest_u,
329                 chroma_stride, buf + *y_data_size, data_size - *y_data_size,
330                 ctx->qmat_chroma[qp - 1], 1);
331 
332         *v_data_size = encode_slice_plane(avctx, mb_count, dest_v,
333                 chroma_stride, buf + *y_data_size + *u_data_size,
334                 data_size - *y_data_size - *u_data_size,
335                 ctx->qmat_chroma[qp - 1], 1);
336     }
337 
338     return *y_data_size + *u_data_size + *v_data_size;
339 }
340 
subimage_with_fill(uint16_t * src,unsigned x,unsigned y,unsigned stride,unsigned width,unsigned height,uint16_t * dst,unsigned dst_width,unsigned dst_height)341 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
342         unsigned stride, unsigned width, unsigned height, uint16_t *dst,
343         unsigned dst_width, unsigned dst_height)
344 {
345 
346     int box_width = FFMIN(width - x, dst_width);
347     int box_height = FFMIN(height - y, dst_height);
348     int i, j, src_stride = stride >> 1;
349     uint16_t last_pix, *last_line;
350 
351     src += y * src_stride + x;
352     for (i = 0; i < box_height; ++i) {
353         for (j = 0; j < box_width; ++j) {
354             dst[j] = src[j];
355         }
356         last_pix = dst[j - 1];
357         for (; j < dst_width; j++)
358             dst[j] = last_pix;
359         src += src_stride;
360         dst += dst_width;
361     }
362     last_line = dst - dst_width;
363     for (; i < dst_height; i++) {
364         for (j = 0; j < dst_width; ++j) {
365             dst[j] = last_line[j];
366         }
367         dst += dst_width;
368     }
369 }
370 
encode_slice(AVCodecContext * avctx,const AVFrame * pic,int mb_x,int mb_y,unsigned mb_count,uint8_t * buf,unsigned data_size,int unsafe,int * qp)371 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
372         int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
373         int unsafe, int *qp)
374 {
375     int luma_stride, chroma_stride;
376     int hdr_size = 6, slice_size;
377     uint8_t *dest_y, *dest_u, *dest_v;
378     unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
379     ProresContext* ctx = avctx->priv_data;
380     int tgt_bits   = (mb_count * bitrate_table[avctx->profile]) >> 2;
381     int low_bytes  = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
382     int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
383 
384     luma_stride   = pic->linesize[0];
385     chroma_stride = pic->linesize[1];
386 
387     dest_y = pic->data[0] + (mb_y << 4) * luma_stride   + (mb_x << 5);
388     dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << 4);
389     dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << 4);
390 
391     if (unsafe) {
392 
393         subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
394                 luma_stride, avctx->width, avctx->height,
395                 (uint16_t *) ctx->fill_y, mb_count << 4, 16);
396         subimage_with_fill((uint16_t *) pic->data[1], mb_x << 3, mb_y << 4,
397                 chroma_stride, avctx->width >> 1, avctx->height,
398                 (uint16_t *) ctx->fill_u, mb_count << 3, 16);
399         subimage_with_fill((uint16_t *) pic->data[2], mb_x << 3, mb_y << 4,
400                 chroma_stride, avctx->width >> 1, avctx->height,
401                 (uint16_t *) ctx->fill_v, mb_count << 3, 16);
402 
403         encode_slice_data(avctx, ctx->fill_y, ctx->fill_u, ctx->fill_v,
404                 mb_count << 5, mb_count << 4, mb_count, buf + hdr_size,
405                 data_size - hdr_size, &y_data_size, &u_data_size, &v_data_size,
406                 *qp);
407     } else {
408         slice_size = encode_slice_data(avctx, dest_y, dest_u, dest_v,
409                 luma_stride, chroma_stride, mb_count, buf + hdr_size,
410                 data_size - hdr_size, &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, dest_y, dest_u, dest_v,
417                         luma_stride, chroma_stride, mb_count, buf + hdr_size,
418                         data_size - hdr_size, &y_data_size, &u_data_size,
419                         &v_data_size, *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, dest_y, dest_u, dest_v,
426                         luma_stride, chroma_stride, mb_count, buf + hdr_size,
427                         data_size - hdr_size, &y_data_size, &u_data_size,
428                         &v_data_size, *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 
prores_encode_picture(AVCodecContext * avctx,const AVFrame * pic,uint8_t * buf,const int buf_size)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 
prores_encode_frame(AVCodecContext * avctx,AVPacket * pkt,const AVFrame * pict,int * got_packet)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 + FF_MIN_BUFFER_SIZE; //FIXME choose tighter limit
496 
497 
498     if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + FF_MIN_BUFFER_SIZE)) < 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++ = 2;
516     *buf++ = 2;
517     *buf++ = 6;
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 
scale_mat(const uint8_t * src,int * dst,int scale)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 
prores_encode_init(AVCodecContext * avctx)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 -1;
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 -1;
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 -1;
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     avctx->coded_frame = av_frame_alloc();
595     avctx->coded_frame->key_frame = 1;
596     avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
597 
598     return 0;
599 }
600 
prores_encode_close(AVCodecContext * avctx)601 static av_cold int prores_encode_close(AVCodecContext *avctx)
602 {
603     ProresContext* ctx = avctx->priv_data;
604     av_freep(&avctx->coded_frame);
605     av_freep(&ctx->fill_y);
606 
607     return 0;
608 }
609 
610 AVCodec ff_prores_aw_encoder = {
611 	.name           = "prores_aw",
612     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
613     .type           = AVMEDIA_TYPE_VIDEO,
614     .id             = AV_CODEC_ID_PRORES,
615     .priv_data_size = sizeof(ProresContext),
616     .init           = prores_encode_init,
617     .close          = prores_encode_close,
618     .encode2        = prores_encode_frame,
619     .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
620     .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
621     .profiles       = profiles
622 };
623 
624 AVCodec ff_prores_encoder = {
625 	.name           = "prores",
626     .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes"),
627     .type           = AVMEDIA_TYPE_VIDEO,
628     .id             = AV_CODEC_ID_PRORES,
629     .priv_data_size = sizeof(ProresContext),
630     .init           = prores_encode_init,
631     .close          = prores_encode_close,
632     .encode2        = prores_encode_frame,
633     .pix_fmts       = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_NONE},
634     .capabilities   = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY,
635     .profiles       = profiles
636 };
637