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
159 int qmat_luma[16][64];
160 int qmat_chroma[16][64];
165 static void encode_codeword(PutBitContext *pb, int val, int codebook)
167 unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
169 /* number of bits to switch between rice and exp golomb */
170 switch_bits = codebook & 3;
171 rice_order = codebook >> 5;
172 exp_order = (codebook >> 2) & 7;
174 first_exp = ((switch_bits + 1) << rice_order);
176 if (val >= first_exp) { /* exp golomb */
178 val += (1 << exp_order);
180 zeros = exp - exp_order + switch_bits + 1;
181 put_bits(pb, zeros, 0);
182 put_bits(pb, exp + 1, val);
183 } else if (rice_order) {
184 put_bits(pb, (val >> rice_order), 0);
186 put_sbits(pb, rice_order, val);
188 put_bits(pb, val, 0);
193 #define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
194 #define TO_GOLOMB(val) (((val) << 1) ^ ((val) >> 31))
195 #define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
196 #define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
197 #define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
199 static av_always_inline int get_level(int val)
201 int sign = (val >> 31);
202 return (val ^ sign) - sign;
205 #define FIRST_DC_CB 0xB8
207 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
209 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
210 int blocks_per_slice, int *qmat)
214 int new_dc, delta, diff_sign, new_code;
216 prev_dc = QSCALE(qmat, 0, in[0] - 16384);
217 code = TO_GOLOMB(prev_dc);
218 encode_codeword(pb, code, FIRST_DC_CB);
220 code = 5; sign = 0; idx = 64;
221 for (i = 1; i < blocks_per_slice; i++, idx += 64) {
222 new_dc = QSCALE(qmat, 0, in[idx] - 16384);
223 delta = new_dc - prev_dc;
224 diff_sign = DIFF_SIGN(delta, sign);
225 new_code = TO_GOLOMB2(get_level(delta), diff_sign);
227 encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
235 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
236 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
237 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
238 0x28, 0x28, 0x28, 0x4C };
240 static void encode_ac_coeffs(PutBitContext *pb,
241 int16_t *in, int blocks_per_slice, int *qmat)
246 int run = 0, level, code, i, j;
247 for (i = 1; i < 64; i++) {
248 int indp = ff_prores_progressive_scan[i];
249 for (j = 0; j < blocks_per_slice; j++) {
250 int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
252 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
256 level = get_level(val);
259 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
263 put_bits(pb, 1, IS_NEGATIVE(val));
271 static void get(uint8_t *pixels, int stride, int16_t* block)
275 for (i = 0; i < 8; i++) {
276 AV_WN64(block, AV_RN64(pixels));
277 AV_WN64(block+4, AV_RN64(pixels+8));
283 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
285 get(pixels, stride, block);
289 static void calc_plane_dct(FDCTDSPContext *fdsp, uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma, int is_422)
296 if (!chroma) { /* Luma plane */
297 for (i = 0; i < mb_count; i++) {
298 fdct_get(fdsp, src, src_stride, block + (0 << 6));
299 fdct_get(fdsp, src + 16, src_stride, block + (1 << 6));
300 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (2 << 6));
301 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
306 } else if (chroma && is_422){ /* chroma plane 422 */
307 for (i = 0; i < mb_count; i++) {
308 fdct_get(fdsp, src, src_stride, block + (0 << 6));
309 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
313 } else { /* chroma plane 444 */
314 for (i = 0; i < mb_count; i++) {
315 fdct_get(fdsp, src, src_stride, block + (0 << 6));
316 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
317 fdct_get(fdsp, src + 16, src_stride, block + (2 << 6));
318 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
326 static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int sub_sample_chroma)
328 int blocks_per_slice;
331 blocks_per_slice = mb_count << (2 - sub_sample_chroma);
332 init_put_bits(&pb, buf, buf_size);
334 encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
335 encode_ac_coeffs(&pb, blocks, blocks_per_slice, qmat);
338 return put_bits_ptr(&pb) - pb.buf;
341 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
342 int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
343 unsigned mb_count, uint8_t *buf, unsigned data_size,
344 unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
347 ProresContext* ctx = avctx->priv_data;
349 *y_data_size = encode_slice_plane(blocks_y, mb_count,
350 buf, data_size, ctx->qmat_luma[qp - 1], 0);
352 if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
353 *u_data_size = encode_slice_plane(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
354 ctx->qmat_chroma[qp - 1], ctx->is_422);
356 *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
357 data_size - *y_data_size - *u_data_size,
358 ctx->qmat_chroma[qp - 1], ctx->is_422);
361 return *y_data_size + *u_data_size + *v_data_size;
364 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
365 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
366 unsigned dst_width, unsigned dst_height)
369 int box_width = FFMIN(width - x, dst_width);
370 int box_height = FFMIN(height - y, dst_height);
371 int i, j, src_stride = stride >> 1;
372 uint16_t last_pix, *last_line;
374 src += y * src_stride + x;
375 for (i = 0; i < box_height; ++i) {
376 for (j = 0; j < box_width; ++j) {
379 last_pix = dst[j - 1];
380 for (; j < dst_width; j++)
385 last_line = dst - dst_width;
386 for (; i < dst_height; i++) {
387 for (j = 0; j < dst_width; ++j) {
388 dst[j] = last_line[j];
394 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
395 int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
398 int luma_stride, chroma_stride;
399 int hdr_size = 6, slice_size;
400 uint8_t *dest_y, *dest_u, *dest_v;
401 unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0;
402 ProresContext* ctx = avctx->priv_data;
403 FDCTDSPContext *fdsp = &ctx->fdsp;
404 int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2;
405 int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
406 int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
408 LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
409 LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
410 LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
412 luma_stride = pic->linesize[0];
413 chroma_stride = pic->linesize[1];
415 dest_y = pic->data[0] + (mb_y << 4) * luma_stride + (mb_x << 5);
416 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
417 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
420 subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
421 luma_stride, avctx->width, avctx->height,
422 (uint16_t *) ctx->fill_y, mb_count << 4, 16);
423 subimage_with_fill((uint16_t *) pic->data[1], mb_x << (4 - ctx->is_422), mb_y << 4,
424 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
425 (uint16_t *) ctx->fill_u, mb_count << (4 - ctx->is_422), 16);
426 subimage_with_fill((uint16_t *) pic->data[2], mb_x << (4 - ctx->is_422), mb_y << 4,
427 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
428 (uint16_t *) ctx->fill_v, mb_count << (4 - ctx->is_422), 16);
430 calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count << 5, mb_count, 0, 0);
431 calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
432 calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
434 encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
435 mb_count, buf + hdr_size, data_size - hdr_size,
436 &y_data_size, &u_data_size, &v_data_size,
439 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0, 0);
440 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1, ctx->is_422);
441 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1, ctx->is_422);
443 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
444 mb_count, buf + hdr_size, data_size - hdr_size,
445 &y_data_size, &u_data_size, &v_data_size,
448 if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
451 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
452 mb_count, buf + hdr_size, data_size - hdr_size,
453 &y_data_size, &u_data_size, &v_data_size,
455 } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
456 } else if (slice_size < low_bytes && *qp
457 > qp_start_table[avctx->profile]) {
460 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
461 mb_count, buf + hdr_size, data_size - hdr_size,
462 &y_data_size, &u_data_size, &v_data_size,
464 } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
468 buf[0] = hdr_size << 3;
470 AV_WB16(buf + 2, y_data_size);
471 AV_WB16(buf + 4, u_data_size);
473 return hdr_size + y_data_size + u_data_size + v_data_size;
476 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
477 uint8_t *buf, const int buf_size)
479 int mb_width = (avctx->width + 15) >> 4;
480 int mb_height = (avctx->height + 15) >> 4;
481 int hdr_size, sl_size, i;
482 int mb_y, sl_data_size, qp;
483 int unsafe_bot, unsafe_right;
484 uint8_t *sl_data, *sl_data_sizes;
485 int slice_per_line = 0, rem = mb_width;
487 for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
488 slice_per_line += rem >> i;
492 qp = qp_start_table[avctx->profile];
493 hdr_size = 8; sl_data_size = buf_size - hdr_size;
494 sl_data_sizes = buf + hdr_size;
495 sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
496 for (mb_y = 0; mb_y < mb_height; mb_y++) {
498 int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
499 while (mb_x < mb_width) {
500 while (mb_width - mb_x < slice_mb_count)
501 slice_mb_count >>= 1;
503 unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
504 unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
506 sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
507 sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
509 bytestream_put_be16(&sl_data_sizes, sl_size);
511 sl_data_size -= sl_size;
512 mb_x += slice_mb_count;
516 buf[0] = hdr_size << 3;
517 AV_WB32(buf + 1, sl_data - buf);
518 AV_WB16(buf + 5, slice_per_line * mb_height);
519 buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
521 return sl_data - buf;
524 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
525 const AVFrame *pict, int *got_packet)
527 int header_size = 148;
530 int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
533 if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
537 pic_size = prores_encode_picture(avctx, pict, buf + header_size + 8,
538 pkt->size - header_size - 8);
540 bytestream_put_be32(&buf, pic_size + 8 + header_size);
541 bytestream_put_buffer(&buf, "icpf", 4);
543 bytestream_put_be16(&buf, header_size);
544 bytestream_put_be16(&buf, 0);
545 bytestream_put_buffer(&buf, "fmpg", 4);
546 bytestream_put_be16(&buf, avctx->width);
547 bytestream_put_be16(&buf, avctx->height);
548 if (avctx->profile == FF_PROFILE_PRORES_4444) {
549 *buf++ = 0xC2; // 444, not interlaced
551 *buf++ = 0x82; // 422, not interlaced
554 *buf++ = pict->color_primaries;
555 *buf++ = pict->color_trc;
556 *buf++ = pict->colorspace;
561 bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64);
562 bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
564 pkt->flags |= AV_PKT_FLAG_KEY;
565 pkt->size = pic_size + 8 + header_size;
571 static void scale_mat(const uint8_t* src, int* dst, int scale)
574 for (i = 0; i < 64; i++)
575 dst[i] = src[i] * scale;
578 static av_cold int prores_encode_init(AVCodecContext *avctx)
581 ProresContext* ctx = avctx->priv_data;
583 avctx->bits_per_raw_sample = 10;
585 if (avctx->width & 0x1) {
586 av_log(avctx, AV_LOG_ERROR,
587 "frame width needs to be multiple of 2\n");
588 return AVERROR(EINVAL);
591 if (avctx->width > 65534 || avctx->height > 65535) {
592 av_log(avctx, AV_LOG_ERROR,
593 "The maximum dimensions are 65534x65535\n");
594 return AVERROR(EINVAL);
597 if (avctx->profile == FF_PROFILE_UNKNOWN) {
598 if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) {
599 avctx->profile = FF_PROFILE_PRORES_STANDARD;
600 av_log(avctx, AV_LOG_INFO,
601 "encoding with ProRes standard (apcn) profile\n");
602 } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
603 avctx->profile = FF_PROFILE_PRORES_4444;
604 av_log(avctx, AV_LOG_INFO,
605 "encoding with ProRes 4444 (ap4h) profile\n");
608 } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
609 || avctx->profile > FF_PROFILE_PRORES_4444) {
613 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch, 4 - ap4h]\n",
615 return AVERROR(EINVAL);
616 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P10) && (avctx->profile > FF_PROFILE_PRORES_HQ)){
617 av_log(avctx, AV_LOG_ERROR,
618 "encoding with ProRes 444 (ap4h) profile, need YUV444P10 input\n");
619 return AVERROR(EINVAL);
620 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV444P10) && (avctx->profile < FF_PROFILE_PRORES_4444)){
621 av_log(avctx, AV_LOG_ERROR,
622 "encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input\n");
623 return AVERROR(EINVAL);
626 if (avctx->profile < FF_PROFILE_PRORES_4444) { /* 422 versions */
628 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
629 ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
631 return AVERROR(ENOMEM);
632 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
633 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
637 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
638 ctx->fill_y = av_malloc(3 * (DEFAULT_SLICE_MB_WIDTH << 9));
640 return AVERROR(ENOMEM);
641 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
642 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 9);
646 ff_fdctdsp_init(&ctx->fdsp, avctx);
648 avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
650 for (i = 1; i <= 16; i++) {
651 scale_mat(QMAT_LUMA[avctx->profile] , ctx->qmat_luma[i - 1] , i);
652 scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
658 static av_cold int prores_encode_close(AVCodecContext *avctx)
660 ProresContext* ctx = avctx->priv_data;
661 av_freep(&ctx->fill_y);
666 AVCodec ff_prores_aw_encoder = {
668 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
669 .type = AVMEDIA_TYPE_VIDEO,
670 .id = AV_CODEC_ID_PRORES,
671 .priv_data_size = sizeof(ProresContext),
672 .init = prores_encode_init,
673 .close = prores_encode_close,
674 .encode2 = prores_encode_frame,
675 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE},
676 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
677 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
680 AVCodec ff_prores_encoder = {
682 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
683 .type = AVMEDIA_TYPE_VIDEO,
684 .id = AV_CODEC_ID_PRORES,
685 .priv_data_size = sizeof(ProresContext),
686 .init = prores_encode_init,
687 .close = prores_encode_close,
688 .encode2 = prores_encode_frame,
689 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_NONE},
690 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
691 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),