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)
33 #include "proresdata.h"
35 #include "bytestream.h"
38 #define DEFAULT_SLICE_MB_WIDTH 8
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
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 }
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};
59 static const uint8_t QMAT_LUMA[5][64] = {
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
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
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
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
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
108 static const uint8_t QMAT_CHROMA[5][64] = {
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
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
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
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
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
164 int qmat_luma[16][64];
165 int qmat_chroma[16][64];
170 static void encode_codeword(PutBitContext *pb, int val, int codebook)
172 unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
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;
179 first_exp = ((switch_bits + 1) << rice_order);
181 if (val >= first_exp) { /* exp golomb */
183 val += (1 << exp_order);
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);
191 put_sbits(pb, rice_order, val);
193 put_bits(pb, val, 0);
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))
204 static av_always_inline int get_level(int val)
206 int sign = (val >> 31);
207 return (val ^ sign) - sign;
210 #define FIRST_DC_CB 0xB8
212 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
214 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
215 int blocks_per_slice, int *qmat)
219 int new_dc, delta, diff_sign, new_code;
221 prev_dc = QSCALE(qmat, 0, in[0] - 16384);
222 code = TO_GOLOMB(prev_dc);
223 encode_codeword(pb, code, FIRST_DC_CB);
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);
232 encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
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 };
245 static void encode_ac_coeffs(PutBitContext *pb,
246 int16_t *in, int blocks_per_slice, int *qmat)
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]);
257 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
261 level = get_level(val);
264 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
268 put_bits(pb, 1, IS_NEGATIVE(val));
276 static void get(uint8_t *pixels, int stride, int16_t* block)
280 for (i = 0; i < 8; i++) {
281 AV_WN64(block, AV_RN64(pixels));
282 AV_WN64(block+4, AV_RN64(pixels+8));
288 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
290 get(pixels, stride, block);
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)
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));
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));
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));
331 static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int sub_sample_chroma)
333 int blocks_per_slice;
336 blocks_per_slice = mb_count << (2 - sub_sample_chroma);
337 init_put_bits(&pb, buf, buf_size);
339 encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
340 encode_ac_coeffs(&pb, blocks, blocks_per_slice, qmat);
343 return put_bits_ptr(&pb) - pb.buf;
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,
352 ProresContext* ctx = avctx->priv_data;
354 *y_data_size = encode_slice_plane(blocks_y, mb_count,
355 buf, data_size, ctx->qmat_luma[qp - 1], 0);
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);
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);
366 return *y_data_size + *u_data_size + *v_data_size;
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)
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;
379 src += y * src_stride + x;
380 for (i = 0; i < box_height; ++i) {
381 for (j = 0; j < box_width; ++j) {
384 last_pix = dst[j - 1];
385 for (; j < dst_width; j++)
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];
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,
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;
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]);
417 luma_stride = pic->linesize[0];
418 chroma_stride = pic->linesize[1];
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));
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);
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);
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,
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);
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,
453 if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
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,
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]) {
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,
469 } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
473 buf[0] = hdr_size << 3;
475 AV_WB16(buf + 2, y_data_size);
476 AV_WB16(buf + 4, u_data_size);
478 return hdr_size + y_data_size + u_data_size + v_data_size;
481 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
482 uint8_t *buf, const int buf_size)
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;
492 for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
493 slice_per_line += rem >> i;
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++) {
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;
508 unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
509 unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
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);
514 bytestream_put_be16(&sl_data_sizes, sl_size);
516 sl_data_size -= sl_size;
517 mb_x += slice_mb_count;
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;
526 return sl_data - buf;
529 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
530 const AVFrame *pict, int *got_packet)
532 int header_size = 148;
535 int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
538 if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
542 pic_size = prores_encode_picture(avctx, pict, buf + header_size + 8,
543 pkt->size - header_size - 8);
545 bytestream_put_be32(&buf, pic_size + 8 + header_size);
546 bytestream_put_buffer(&buf, "icpf", 4);
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
556 *buf++ = 0x83; // 422, not interlaced
559 *buf++ = pict->color_primaries;
560 *buf++ = pict->color_trc;
561 *buf++ = pict->colorspace;
566 bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64);
567 bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
569 pkt->flags |= AV_PKT_FLAG_KEY;
570 pkt->size = pic_size + 8 + header_size;
576 static void scale_mat(const uint8_t* src, int* dst, int scale)
579 for (i = 0; i < 64; i++)
580 dst[i] = src[i] * scale;
583 static av_cold int prores_encode_init(AVCodecContext *avctx)
586 ProresContext* ctx = avctx->priv_data;
588 avctx->bits_per_raw_sample = 10;
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);
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);
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");
613 } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
614 || avctx->profile > FF_PROFILE_PRORES_444) {
618 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch, 4 - ap4h]\n",
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);
631 if (avctx->profile < FF_PROFILE_PRORES_444) { /* 422 versions */
633 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
634 ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
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);
642 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
643 ctx->fill_y = av_malloc(3 * (DEFAULT_SLICE_MB_WIDTH << 9));
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);
651 ff_fdctdsp_init(&ctx->fdsp, avctx);
653 avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
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);
663 static av_cold int prores_encode_close(AVCodecContext *avctx)
665 ProresContext* ctx = avctx->priv_data;
666 av_freep(&ctx->fill_y);
671 AVCodec ff_prores_aw_encoder = {
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,
685 AVCodec ff_prores_encoder = {
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,