4 * Copyright (c) 2011 Anatoliy Wasserman
5 * Copyright (c) 2012 Konstantin Shishkov
7 * This file is part of FFmpeg.
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.
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.
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
26 * Apple ProRes encoder (Anatoliy Wasserman version)
27 * Known FOURCCs: 'ap4h' (444), 'apch' (HQ), 'apcn' (422), 'apcs' (LT), 'acpo' (Proxy)
34 #include "proresdata.h"
36 #include "bytestream.h"
39 #define DEFAULT_SLICE_MB_WIDTH 8
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 }
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};
54 static const uint8_t QMAT_LUMA[5][64] = {
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
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
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
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
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
103 static const uint8_t QMAT_CHROMA[5][64] = {
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
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
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
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
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
160 int qmat_luma[16][64];
161 int qmat_chroma[16][64];
167 static void encode_codeword(PutBitContext *pb, int val, int codebook)
169 unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
171 /* number of bits to switch between rice and exp golomb */
172 switch_bits = codebook & 3;
173 rice_order = codebook >> 5;
174 exp_order = (codebook >> 2) & 7;
176 first_exp = ((switch_bits + 1) << rice_order);
178 if (val >= first_exp) { /* exp golomb */
180 val += (1 << exp_order);
182 zeros = exp - exp_order + switch_bits + 1;
183 put_bits(pb, zeros, 0);
184 put_bits(pb, exp + 1, val);
185 } else if (rice_order) {
186 put_bits(pb, (val >> rice_order), 0);
188 put_sbits(pb, rice_order, val);
190 put_bits(pb, val, 0);
195 #define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
196 #define TO_GOLOMB(val) (((val) << 1) ^ ((val) >> 31))
197 #define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
198 #define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
199 #define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
201 static av_always_inline int get_level(int val)
203 int sign = (val >> 31);
204 return (val ^ sign) - sign;
207 #define FIRST_DC_CB 0xB8
209 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
211 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
212 int blocks_per_slice, int *qmat)
216 int new_dc, delta, diff_sign, new_code;
218 prev_dc = QSCALE(qmat, 0, in[0] - 16384);
219 code = TO_GOLOMB(prev_dc);
220 encode_codeword(pb, code, FIRST_DC_CB);
222 code = 5; sign = 0; idx = 64;
223 for (i = 1; i < blocks_per_slice; i++, idx += 64) {
224 new_dc = QSCALE(qmat, 0, in[idx] - 16384);
225 delta = new_dc - prev_dc;
226 diff_sign = DIFF_SIGN(delta, sign);
227 new_code = TO_GOLOMB2(get_level(delta), diff_sign);
229 encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
237 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
238 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
239 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
240 0x28, 0x28, 0x28, 0x4C };
242 static void encode_ac_coeffs(PutBitContext *pb,
243 int16_t *in, int blocks_per_slice, int *qmat)
248 int run = 0, level, code, i, j;
249 for (i = 1; i < 64; i++) {
250 int indp = ff_prores_progressive_scan[i];
251 for (j = 0; j < blocks_per_slice; j++) {
252 int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
254 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
258 level = get_level(val);
261 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
265 put_bits(pb, 1, IS_NEGATIVE(val));
273 static void get(uint8_t *pixels, int stride, int16_t* block)
277 for (i = 0; i < 8; i++) {
278 AV_WN64(block, AV_RN64(pixels));
279 AV_WN64(block+4, AV_RN64(pixels+8));
285 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
287 get(pixels, stride, block);
291 static void calc_plane_dct(FDCTDSPContext *fdsp, uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma, int is_422)
298 if (!chroma) { /* Luma plane */
299 for (i = 0; i < mb_count; i++) {
300 fdct_get(fdsp, src, src_stride, block + (0 << 6));
301 fdct_get(fdsp, src + 16, src_stride, block + (1 << 6));
302 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (2 << 6));
303 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
308 } else if (chroma && is_422){ /* chroma plane 422 */
309 for (i = 0; i < mb_count; i++) {
310 fdct_get(fdsp, src, src_stride, block + (0 << 6));
311 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
315 } else { /* chroma plane 444 */
316 for (i = 0; i < mb_count; i++) {
317 fdct_get(fdsp, src, src_stride, block + (0 << 6));
318 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
319 fdct_get(fdsp, src + 16, src_stride, block + (2 << 6));
320 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
328 static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int sub_sample_chroma)
330 int blocks_per_slice;
333 blocks_per_slice = mb_count << (2 - sub_sample_chroma);
334 init_put_bits(&pb, buf, buf_size);
336 encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
337 encode_ac_coeffs(&pb, blocks, blocks_per_slice, qmat);
340 return put_bits_ptr(&pb) - pb.buf;
343 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
344 int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
345 unsigned mb_count, uint8_t *buf, unsigned data_size,
346 unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
349 ProresContext* ctx = avctx->priv_data;
351 *y_data_size = encode_slice_plane(blocks_y, mb_count,
352 buf, data_size, ctx->qmat_luma[qp - 1], 0);
354 if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
355 *u_data_size = encode_slice_plane(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
356 ctx->qmat_chroma[qp - 1], ctx->is_422);
358 *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
359 data_size - *y_data_size - *u_data_size,
360 ctx->qmat_chroma[qp - 1], ctx->is_422);
363 return *y_data_size + *u_data_size + *v_data_size;
366 static void put_alpha_diff(PutBitContext *pb, int cur, int prev)
368 const int abits = 16;
370 const int dsize = 1 << dbits - 1;
371 int diff = cur - prev;
373 diff = av_mod_uintp2(diff, abits);
374 if (diff >= (1 << abits) - dsize)
376 if (diff < -dsize || diff > dsize || !diff) {
378 put_bits(pb, abits, diff);
381 put_bits(pb, dbits - 1, FFABS(diff) - 1);
382 put_bits(pb, 1, diff < 0);
386 static inline void put_alpha_run(PutBitContext *pb, int run)
391 put_bits(pb, 4, run);
393 put_bits(pb, 15, run);
399 static av_always_inline int encode_alpha_slice_data(AVCodecContext *avctx, int8_t * src_a,
400 unsigned mb_count, uint8_t *buf, unsigned data_size, unsigned* a_data_size)
402 const int abits = 16;
403 const int mask = (1 << abits) - 1;
404 const int num_coeffs = mb_count * 256;
405 int prev = mask, cur;
408 int16_t * blocks = (int16_t *)src_a;
410 init_put_bits(&pb, buf, data_size);
413 put_alpha_diff(&pb, cur, prev);
418 put_alpha_run (&pb, run);
419 put_alpha_diff(&pb, cur, prev);
425 } while (idx < num_coeffs);
427 put_alpha_run(&pb, run);
429 *a_data_size = put_bits_count(&pb) >> 3;
431 if (put_bits_left(&pb) < 0) {
432 av_log(avctx, AV_LOG_ERROR,
433 "Underestimated required buffer size.\n");
440 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
441 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
442 unsigned dst_width, unsigned dst_height)
445 int box_width = FFMIN(width - x, dst_width);
446 int box_height = FFMIN(height - y, dst_height);
447 int i, j, src_stride = stride >> 1;
448 uint16_t last_pix, *last_line;
450 src += y * src_stride + x;
451 for (i = 0; i < box_height; ++i) {
452 for (j = 0; j < box_width; ++j) {
455 last_pix = dst[j - 1];
456 for (; j < dst_width; j++)
461 last_line = dst - dst_width;
462 for (; i < dst_height; i++) {
463 for (j = 0; j < dst_width; ++j) {
464 dst[j] = last_line[j];
470 /* reorganize alpha data and convert 10b -> 16b */
471 static void subimage_alpha_with_fill(uint16_t *src, unsigned x, unsigned y,
472 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
473 unsigned dst_width, unsigned dst_height)
475 int box_width = FFMIN(width - x, dst_width);
476 int box_height = FFMIN(height - y, dst_height);
477 int i, j, src_stride = stride >> 1;
478 uint16_t last_pix, *last_line;
480 src += y * src_stride + x;
481 for (i = 0; i < box_height; ++i) {
482 for (j = 0; j < box_width; ++j) {
483 dst[j] = src[j] << 6; /* 10b to 16b */
485 last_pix = dst[j - 1] << 6; /* 10b to 16b */
486 for (; j < dst_width; j++)
491 last_line = dst - dst_width;
492 for (; i < dst_height; i++) {
493 for (j = 0; j < dst_width; ++j) {
494 dst[j] = last_line[j];
500 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
501 int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
504 int luma_stride, chroma_stride, alpha_stride = 0;
505 ProresContext* ctx = avctx->priv_data;
506 int hdr_size = 6 + (ctx->need_alpha * 2); /* v data size is write when there is alpha */
507 int ret = 0, slice_size;
508 uint8_t *dest_y, *dest_u, *dest_v;
509 unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0, a_data_size = 0;
510 FDCTDSPContext *fdsp = &ctx->fdsp;
511 int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2;
512 int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
513 int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
515 LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
516 LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
517 LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
519 luma_stride = pic->linesize[0];
520 chroma_stride = pic->linesize[1];
523 alpha_stride = pic->linesize[3];
525 dest_y = pic->data[0] + (mb_y << 4) * luma_stride + (mb_x << 5);
526 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
527 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
530 subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
531 luma_stride, avctx->width, avctx->height,
532 (uint16_t *) ctx->fill_y, mb_count << 4, 16);
533 subimage_with_fill((uint16_t *) pic->data[1], mb_x << (4 - ctx->is_422), mb_y << 4,
534 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
535 (uint16_t *) ctx->fill_u, mb_count << (4 - ctx->is_422), 16);
536 subimage_with_fill((uint16_t *) pic->data[2], mb_x << (4 - ctx->is_422), mb_y << 4,
537 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
538 (uint16_t *) ctx->fill_v, mb_count << (4 - ctx->is_422), 16);
540 calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count << 5, mb_count, 0, 0);
541 calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
542 calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
544 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
545 mb_count, buf + hdr_size, data_size - hdr_size,
546 &y_data_size, &u_data_size, &v_data_size,
549 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0, 0);
550 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1, ctx->is_422);
551 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1, ctx->is_422);
553 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
554 mb_count, buf + hdr_size, data_size - hdr_size,
555 &y_data_size, &u_data_size, &v_data_size,
558 if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
561 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
562 mb_count, buf + hdr_size, data_size - hdr_size,
563 &y_data_size, &u_data_size, &v_data_size,
565 } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
566 } else if (slice_size < low_bytes && *qp
567 > qp_start_table[avctx->profile]) {
570 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
571 mb_count, buf + hdr_size, data_size - hdr_size,
572 &y_data_size, &u_data_size, &v_data_size,
574 } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
578 buf[0] = hdr_size << 3;
580 AV_WB16(buf + 2, y_data_size);
581 AV_WB16(buf + 4, u_data_size);
583 if (ctx->need_alpha) {
584 AV_WB16(buf + 6, v_data_size); /* write v data size only if there is alpha */
586 subimage_alpha_with_fill((uint16_t *) pic->data[3], mb_x << 4, mb_y << 4,
587 alpha_stride, avctx->width, avctx->height,
588 (uint16_t *) ctx->fill_a, mb_count << 4, 16);
589 ret = encode_alpha_slice_data(avctx, ctx->fill_a, mb_count,
590 buf + hdr_size + slice_size,
591 data_size - hdr_size - slice_size, &a_data_size);
597 return hdr_size + y_data_size + u_data_size + v_data_size + a_data_size;
600 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
601 uint8_t *buf, const int buf_size)
603 int mb_width = (avctx->width + 15) >> 4;
604 int mb_height = (avctx->height + 15) >> 4;
605 int hdr_size, sl_size, i;
606 int mb_y, sl_data_size, qp;
607 int unsafe_bot, unsafe_right;
608 uint8_t *sl_data, *sl_data_sizes;
609 int slice_per_line = 0, rem = mb_width;
611 for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
612 slice_per_line += rem >> i;
616 qp = qp_start_table[avctx->profile];
617 hdr_size = 8; sl_data_size = buf_size - hdr_size;
618 sl_data_sizes = buf + hdr_size;
619 sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
620 for (mb_y = 0; mb_y < mb_height; mb_y++) {
622 int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
623 while (mb_x < mb_width) {
624 while (mb_width - mb_x < slice_mb_count)
625 slice_mb_count >>= 1;
627 unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
628 unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
630 sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
631 sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
636 bytestream_put_be16(&sl_data_sizes, sl_size);
638 sl_data_size -= sl_size;
639 mb_x += slice_mb_count;
643 buf[0] = hdr_size << 3;
644 AV_WB32(buf + 1, sl_data - buf);
645 AV_WB16(buf + 5, slice_per_line * mb_height);
646 buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
648 return sl_data - buf;
651 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
652 const AVFrame *pict, int *got_packet)
654 int header_size = 148;
657 int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
660 if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
664 pic_size = prores_encode_picture(avctx, pict, buf + header_size + 8,
665 pkt->size - header_size - 8);
670 bytestream_put_be32(&buf, pic_size + 8 + header_size);
671 bytestream_put_buffer(&buf, "icpf", 4);
673 bytestream_put_be16(&buf, header_size);
674 bytestream_put_be16(&buf, 0); /* version */
675 bytestream_put_buffer(&buf, "fmpg", 4);
676 bytestream_put_be16(&buf, avctx->width);
677 bytestream_put_be16(&buf, avctx->height);
678 if (avctx->profile == FF_PROFILE_PRORES_4444) {
679 *buf++ = 0xC2; // 444, not interlaced
681 *buf++ = 0x82; // 422, not interlaced
683 *buf++ = 0; /* reserved */
684 *buf++ = pict->color_primaries;
685 *buf++ = pict->color_trc;
686 *buf++ = pict->colorspace;
687 if (avctx->profile >= FF_PROFILE_PRORES_4444) {
688 if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
689 *buf++ = 0xA0;/* src b64a and no alpha */
691 *buf++ = 0xA2;/* src b64a and 16b alpha */
694 *buf++ = 32;/* src v210 and no alpha */
696 *buf++ = 0; /* reserved */
697 *buf++ = 3; /* luma and chroma matrix present */
699 bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64);
700 bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
702 pkt->flags |= AV_PKT_FLAG_KEY;
703 pkt->size = pic_size + 8 + header_size;
709 static void scale_mat(const uint8_t* src, int* dst, int scale)
712 for (i = 0; i < 64; i++)
713 dst[i] = src[i] * scale;
716 static av_cold int prores_encode_init(AVCodecContext *avctx)
719 ProresContext* ctx = avctx->priv_data;
721 avctx->bits_per_raw_sample = 10;
724 if (avctx->width & 0x1) {
725 av_log(avctx, AV_LOG_ERROR,
726 "frame width needs to be multiple of 2\n");
727 return AVERROR(EINVAL);
730 if (avctx->width > 65534 || avctx->height > 65535) {
731 av_log(avctx, AV_LOG_ERROR,
732 "The maximum dimensions are 65534x65535\n");
733 return AVERROR(EINVAL);
736 if (avctx->profile == FF_PROFILE_UNKNOWN) {
737 if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) {
738 avctx->profile = FF_PROFILE_PRORES_STANDARD;
739 av_log(avctx, AV_LOG_INFO,
740 "encoding with ProRes standard (apcn) profile\n");
741 } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
742 avctx->profile = FF_PROFILE_PRORES_4444;
743 av_log(avctx, AV_LOG_INFO,
744 "encoding with ProRes 4444 (ap4h) profile\n");
745 } else if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
746 avctx->profile = FF_PROFILE_PRORES_4444;
747 av_log(avctx, AV_LOG_INFO,
748 "encoding with ProRes 4444+ (ap4h) profile\n");
750 av_log(avctx, AV_LOG_ERROR, "Unknown pixel format\n");
751 return AVERROR(EINVAL);
753 } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
754 || avctx->profile > FF_PROFILE_PRORES_4444) {
758 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch, 4 - ap4h]\n",
760 return AVERROR(EINVAL);
761 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P10) && (avctx->profile > FF_PROFILE_PRORES_HQ)){
762 av_log(avctx, AV_LOG_ERROR,
763 "encoding with ProRes 444 (ap4h) profile, need YUV444P10 input\n");
764 return AVERROR(EINVAL);
765 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10)
766 && (avctx->profile < FF_PROFILE_PRORES_4444)){
767 av_log(avctx, AV_LOG_ERROR,
768 "encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input\n");
769 return AVERROR(EINVAL);
772 if (avctx->profile < FF_PROFILE_PRORES_4444) { /* 422 versions */
774 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
775 ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
777 return AVERROR(ENOMEM);
778 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
779 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
783 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
784 ctx->fill_y = av_malloc(3 * (DEFAULT_SLICE_MB_WIDTH << 9));
786 return AVERROR(ENOMEM);
787 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
788 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 9);
790 if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
792 ctx->fill_a = av_malloc(DEFAULT_SLICE_MB_WIDTH << 9); /* 8 blocks x 16px x 16px x sizeof (uint16) */
794 return AVERROR(ENOMEM);
798 ff_fdctdsp_init(&ctx->fdsp, avctx);
800 avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
802 for (i = 1; i <= 16; i++) {
803 scale_mat(QMAT_LUMA[avctx->profile] , ctx->qmat_luma[i - 1] , i);
804 scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
810 static av_cold int prores_encode_close(AVCodecContext *avctx)
812 ProresContext* ctx = avctx->priv_data;
813 av_freep(&ctx->fill_y);
814 av_freep(&ctx->fill_a);
819 AVCodec ff_prores_aw_encoder = {
821 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
822 .type = AVMEDIA_TYPE_VIDEO,
823 .id = AV_CODEC_ID_PRORES,
824 .priv_data_size = sizeof(ProresContext),
825 .init = prores_encode_init,
826 .close = prores_encode_close,
827 .encode2 = prores_encode_frame,
828 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE},
829 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
830 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
833 AVCodec ff_prores_encoder = {
835 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
836 .type = AVMEDIA_TYPE_VIDEO,
837 .id = AV_CODEC_ID_PRORES,
838 .priv_data_size = sizeof(ProresContext),
839 .init = prores_encode_init,
840 .close = prores_encode_close,
841 .encode2 = prores_encode_frame,
842 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE},
843 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
844 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),