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)
30 #include "libavutil/opt.h"
35 #include "proresdata.h"
37 #include "bytestream.h"
40 #define DEFAULT_SLICE_MB_WIDTH 8
42 static const AVProfile profiles[] = {
43 { FF_PROFILE_PRORES_PROXY, "apco"},
44 { FF_PROFILE_PRORES_LT, "apcs"},
45 { FF_PROFILE_PRORES_STANDARD, "apcn"},
46 { FF_PROFILE_PRORES_HQ, "apch"},
47 { FF_PROFILE_PRORES_4444, "ap4h"},
48 { FF_PROFILE_PRORES_XQ, "ap4x"},
49 { FF_PROFILE_UNKNOWN }
52 static const int qp_start_table[6] = { 8, 3, 2, 1, 1, 1};
53 static const int qp_end_table[6] = { 13, 9, 6, 6, 5, 4};
54 static const int bitrate_table[6] = { 1000, 2100, 3500, 5400, 7000, 10000};
56 static const int valid_primaries[9] = { AVCOL_PRI_RESERVED0, AVCOL_PRI_BT709, AVCOL_PRI_UNSPECIFIED, AVCOL_PRI_BT470BG,
57 AVCOL_PRI_SMPTE170M, AVCOL_PRI_BT2020, AVCOL_PRI_SMPTE431, AVCOL_PRI_SMPTE432,INT_MAX };
58 static const int valid_trc[4] = { AVCOL_TRC_RESERVED0, AVCOL_TRC_BT709, AVCOL_TRC_UNSPECIFIED, INT_MAX };
59 static const int valid_colorspace[5] = { AVCOL_SPC_BT709, AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_SMPTE170M,
60 AVCOL_SPC_BT2020_NCL, INT_MAX };
62 static const uint8_t QMAT_LUMA[6][64] = {
64 4, 7, 9, 11, 13, 14, 15, 63,
65 7, 7, 11, 12, 14, 15, 63, 63,
66 9, 11, 13, 14, 15, 63, 63, 63,
67 11, 11, 13, 14, 63, 63, 63, 63,
68 11, 13, 14, 63, 63, 63, 63, 63,
69 13, 14, 63, 63, 63, 63, 63, 63,
70 13, 63, 63, 63, 63, 63, 63, 63,
71 63, 63, 63, 63, 63, 63, 63, 63
73 4, 5, 6, 7, 9, 11, 13, 15,
74 5, 5, 7, 8, 11, 13, 15, 17,
75 6, 7, 9, 11, 13, 15, 15, 17,
76 7, 7, 9, 11, 13, 15, 17, 19,
77 7, 9, 11, 13, 14, 16, 19, 23,
78 9, 11, 13, 14, 16, 19, 23, 29,
79 9, 11, 13, 15, 17, 21, 28, 35,
80 11, 13, 16, 17, 21, 28, 35, 41
82 4, 4, 5, 5, 6, 7, 7, 9,
83 4, 4, 5, 6, 7, 7, 9, 9,
84 5, 5, 6, 7, 7, 9, 9, 10,
85 5, 5, 6, 7, 7, 9, 9, 10,
86 5, 6, 7, 7, 8, 9, 10, 12,
87 6, 7, 7, 8, 9, 10, 12, 15,
88 6, 7, 7, 9, 10, 11, 14, 17,
89 7, 7, 9, 10, 11, 14, 17, 21
91 4, 4, 4, 4, 4, 4, 4, 4,
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, 5,
95 4, 4, 4, 4, 4, 4, 5, 5,
96 4, 4, 4, 4, 4, 5, 5, 6,
97 4, 4, 4, 4, 5, 5, 6, 7,
98 4, 4, 4, 4, 5, 6, 7, 7
100 4, 4, 4, 4, 4, 4, 4, 4,
101 4, 4, 4, 4, 4, 4, 4, 4,
102 4, 4, 4, 4, 4, 4, 4, 4,
103 4, 4, 4, 4, 4, 4, 4, 5,
104 4, 4, 4, 4, 4, 4, 5, 5,
105 4, 4, 4, 4, 4, 5, 5, 6,
106 4, 4, 4, 4, 5, 5, 6, 7,
107 4, 4, 4, 4, 5, 6, 7, 7
109 2, 2, 2, 2, 2, 2, 2, 2,
110 2, 2, 2, 2, 2, 2, 2, 2,
111 2, 2, 2, 2, 2, 2, 2, 2,
112 2, 2, 2, 2, 2, 2, 2, 3,
113 2, 2, 2, 2, 2, 2, 3, 3,
114 2, 2, 2, 2, 2, 3, 3, 3,
115 2, 2, 2, 2, 3, 3, 3, 4,
116 2, 2, 2, 2, 3, 3, 4, 4,
120 static const uint8_t QMAT_CHROMA[6][64] = {
122 4, 7, 9, 11, 13, 14, 63, 63,
123 7, 7, 11, 12, 14, 63, 63, 63,
124 9, 11, 13, 14, 63, 63, 63, 63,
125 11, 11, 13, 14, 63, 63, 63, 63,
126 11, 13, 14, 63, 63, 63, 63, 63,
127 13, 14, 63, 63, 63, 63, 63, 63,
128 13, 63, 63, 63, 63, 63, 63, 63,
129 63, 63, 63, 63, 63, 63, 63, 63
131 4, 5, 6, 7, 9, 11, 13, 15,
132 5, 5, 7, 8, 11, 13, 15, 17,
133 6, 7, 9, 11, 13, 15, 15, 17,
134 7, 7, 9, 11, 13, 15, 17, 19,
135 7, 9, 11, 13, 14, 16, 19, 23,
136 9, 11, 13, 14, 16, 19, 23, 29,
137 9, 11, 13, 15, 17, 21, 28, 35,
138 11, 13, 16, 17, 21, 28, 35, 41
140 4, 4, 5, 5, 6, 7, 7, 9,
141 4, 4, 5, 6, 7, 7, 9, 9,
142 5, 5, 6, 7, 7, 9, 9, 10,
143 5, 5, 6, 7, 7, 9, 9, 10,
144 5, 6, 7, 7, 8, 9, 10, 12,
145 6, 7, 7, 8, 9, 10, 12, 15,
146 6, 7, 7, 9, 10, 11, 14, 17,
147 7, 7, 9, 10, 11, 14, 17, 21
149 4, 4, 4, 4, 4, 4, 4, 4,
150 4, 4, 4, 4, 4, 4, 4, 4,
151 4, 4, 4, 4, 4, 4, 4, 4,
152 4, 4, 4, 4, 4, 4, 4, 5,
153 4, 4, 4, 4, 4, 4, 5, 5,
154 4, 4, 4, 4, 4, 5, 5, 6,
155 4, 4, 4, 4, 5, 5, 6, 7,
156 4, 4, 4, 4, 5, 6, 7, 7
158 4, 4, 4, 4, 4, 4, 4, 4,
159 4, 4, 4, 4, 4, 4, 4, 4,
160 4, 4, 4, 4, 4, 4, 4, 4,
161 4, 4, 4, 4, 4, 4, 4, 5,
162 4, 4, 4, 4, 4, 4, 5, 5,
163 4, 4, 4, 4, 4, 5, 5, 6,
164 4, 4, 4, 4, 5, 5, 6, 7,
165 4, 4, 4, 4, 5, 6, 7, 7
167 4, 4, 4, 4, 4, 4, 4, 4,
168 4, 4, 4, 4, 4, 4, 4, 4,
169 4, 4, 4, 4, 4, 4, 4, 4,
170 4, 4, 4, 4, 4, 4, 4, 5,
171 4, 4, 4, 4, 4, 4, 5, 5,
172 4, 4, 4, 4, 4, 5, 5, 6,
173 4, 4, 4, 4, 5, 5, 6, 7,
174 4, 4, 4, 4, 5, 6, 7, 7
187 int qmat_luma[16][64];
188 int qmat_chroma[16][64];
189 const uint8_t *scantable;
198 static void encode_codeword(PutBitContext *pb, int val, int codebook)
200 unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
202 /* number of bits to switch between rice and exp golomb */
203 switch_bits = codebook & 3;
204 rice_order = codebook >> 5;
205 exp_order = (codebook >> 2) & 7;
207 first_exp = ((switch_bits + 1) << rice_order);
209 if (val >= first_exp) { /* exp golomb */
211 val += (1 << exp_order);
213 zeros = exp - exp_order + switch_bits + 1;
214 put_bits(pb, zeros, 0);
215 put_bits(pb, exp + 1, val);
216 } else if (rice_order) {
217 put_bits(pb, (val >> rice_order), 0);
219 put_sbits(pb, rice_order, val);
221 put_bits(pb, val, 0);
226 #define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
227 #define TO_GOLOMB(val) (((val) * 2) ^ ((val) >> 31))
228 #define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
229 #define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
230 #define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
232 static av_always_inline int get_level(int val)
234 int sign = (val >> 31);
235 return (val ^ sign) - sign;
238 #define FIRST_DC_CB 0xB8
240 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
242 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
243 int blocks_per_slice, int *qmat)
247 int new_dc, delta, diff_sign, new_code;
249 prev_dc = QSCALE(qmat, 0, in[0] - 16384);
250 code = TO_GOLOMB(prev_dc);
251 encode_codeword(pb, code, FIRST_DC_CB);
253 code = 5; sign = 0; idx = 64;
254 for (i = 1; i < blocks_per_slice; i++, idx += 64) {
255 new_dc = QSCALE(qmat, 0, in[idx] - 16384);
256 delta = new_dc - prev_dc;
257 diff_sign = DIFF_SIGN(delta, sign);
258 new_code = TO_GOLOMB2(get_level(delta), diff_sign);
260 encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
268 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
269 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
270 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
271 0x28, 0x28, 0x28, 0x4C };
273 static void encode_ac_coeffs(PutBitContext *pb,
274 int16_t *in, int blocks_per_slice, int *qmat, const uint8_t ff_prores_scan[64])
279 int run = 0, level, code, i, j;
280 for (i = 1; i < 64; i++) {
281 int indp = ff_prores_scan[i];
282 for (j = 0; j < blocks_per_slice; j++) {
283 int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
285 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
289 level = get_level(val);
292 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
296 put_bits(pb, 1, IS_NEGATIVE(val));
304 static void get(uint8_t *pixels, int stride, int16_t* block)
308 for (i = 0; i < 8; i++) {
309 AV_WN64(block, AV_RN64(pixels));
310 AV_WN64(block+4, AV_RN64(pixels+8));
316 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
318 get(pixels, stride, block);
322 static void calc_plane_dct(FDCTDSPContext *fdsp, uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma, int is_422)
329 if (!chroma) { /* Luma plane */
330 for (i = 0; i < mb_count; i++) {
331 fdct_get(fdsp, src, src_stride, block + (0 << 6));
332 fdct_get(fdsp, src + 16, src_stride, block + (1 << 6));
333 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (2 << 6));
334 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
339 } else if (chroma && is_422){ /* chroma plane 422 */
340 for (i = 0; i < mb_count; i++) {
341 fdct_get(fdsp, src, src_stride, block + (0 << 6));
342 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
346 } else { /* chroma plane 444 */
347 for (i = 0; i < mb_count; i++) {
348 fdct_get(fdsp, src, src_stride, block + (0 << 6));
349 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
350 fdct_get(fdsp, src + 16, src_stride, block + (2 << 6));
351 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
359 static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int sub_sample_chroma,
360 const uint8_t ff_prores_scan[64])
362 int blocks_per_slice;
365 blocks_per_slice = mb_count << (2 - sub_sample_chroma);
366 init_put_bits(&pb, buf, buf_size);
368 encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
369 encode_ac_coeffs(&pb, blocks, blocks_per_slice, qmat, ff_prores_scan);
372 return put_bits_ptr(&pb) - pb.buf;
375 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
376 int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
377 unsigned mb_count, uint8_t *buf, unsigned data_size,
378 unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
381 ProresContext* ctx = avctx->priv_data;
383 *y_data_size = encode_slice_plane(blocks_y, mb_count,
384 buf, data_size, ctx->qmat_luma[qp - 1], 0, ctx->scantable);
386 if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
387 *u_data_size = encode_slice_plane(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
388 ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
390 *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
391 data_size - *y_data_size - *u_data_size,
392 ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
395 return *y_data_size + *u_data_size + *v_data_size;
398 static void put_alpha_diff(PutBitContext *pb, int cur, int prev)
400 const int abits = 16;
402 const int dsize = 1 << dbits - 1;
403 int diff = cur - prev;
405 diff = av_mod_uintp2(diff, abits);
406 if (diff >= (1 << abits) - dsize)
408 if (diff < -dsize || diff > dsize || !diff) {
410 put_bits(pb, abits, diff);
413 put_bits(pb, dbits - 1, FFABS(diff) - 1);
414 put_bits(pb, 1, diff < 0);
418 static inline void put_alpha_run(PutBitContext *pb, int run)
423 put_bits(pb, 4, run);
425 put_bits(pb, 15, run);
431 static av_always_inline int encode_alpha_slice_data(AVCodecContext *avctx, int8_t * src_a,
432 unsigned mb_count, uint8_t *buf, unsigned data_size, unsigned* a_data_size)
434 const int abits = 16;
435 const int mask = (1 << abits) - 1;
436 const int num_coeffs = mb_count * 256;
437 int prev = mask, cur;
440 int16_t * blocks = (int16_t *)src_a;
442 init_put_bits(&pb, buf, data_size);
445 put_alpha_diff(&pb, cur, prev);
450 put_alpha_run (&pb, run);
451 put_alpha_diff(&pb, cur, prev);
457 } while (idx < num_coeffs);
459 put_alpha_run(&pb, run);
461 *a_data_size = put_bits_count(&pb) >> 3;
463 if (put_bits_left(&pb) < 0) {
464 av_log(avctx, AV_LOG_ERROR,
465 "Underestimated required buffer size.\n");
472 static inline void subimage_with_fill_template(uint16_t *src, unsigned x, unsigned y,
473 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
474 unsigned dst_width, unsigned dst_height, int is_alpha_plane,
475 int is_interlaced, int is_top_field)
477 int box_width = FFMIN(width - x, dst_width);
478 int i, j, src_stride, box_height;
479 uint16_t last_pix, *last_line;
481 if (!is_interlaced) {
482 src_stride = stride >> 1;
483 src += y * src_stride + x;
484 box_height = FFMIN(height - y, dst_height);
486 src_stride = stride; /* 2 lines stride */
487 src += y * src_stride + x;
488 box_height = FFMIN(height/2 - y, dst_height);
493 for (i = 0; i < box_height; ++i) {
494 for (j = 0; j < box_width; ++j) {
495 if (!is_alpha_plane) {
498 dst[j] = src[j] << 6; /* alpha 10b to 16b */
501 if (!is_alpha_plane) {
502 last_pix = dst[j - 1];
504 last_pix = dst[j - 1] << 6; /* alpha 10b to 16b */
506 for (; j < dst_width; j++)
511 last_line = dst - dst_width;
512 for (; i < dst_height; i++) {
513 for (j = 0; j < dst_width; ++j) {
514 dst[j] = last_line[j];
520 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
521 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
522 unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
524 subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 0, is_interlaced, is_top_field);
527 /* reorganize alpha data and convert 10b -> 16b */
528 static void subimage_alpha_with_fill(uint16_t *src, unsigned x, unsigned y,
529 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
530 unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
532 subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 1, is_interlaced, is_top_field);
535 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
536 int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
537 int unsafe, int *qp, int is_interlaced, int is_top_field)
539 int luma_stride, chroma_stride, alpha_stride = 0;
540 ProresContext* ctx = avctx->priv_data;
541 int hdr_size = 6 + (ctx->need_alpha * 2); /* v data size is write when there is alpha */
542 int ret = 0, slice_size;
543 uint8_t *dest_y, *dest_u, *dest_v;
544 unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0, a_data_size = 0;
545 FDCTDSPContext *fdsp = &ctx->fdsp;
546 int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2;
547 int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
548 int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
550 LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
551 LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
552 LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
554 luma_stride = pic->linesize[0];
555 chroma_stride = pic->linesize[1];
558 alpha_stride = pic->linesize[3];
560 if (!is_interlaced) {
561 dest_y = pic->data[0] + (mb_y << 4) * luma_stride + (mb_x << 5);
562 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
563 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
565 dest_y = pic->data[0] + (mb_y << 4) * luma_stride * 2 + (mb_x << 5);
566 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
567 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
568 if (!is_top_field){ /* bottom field, offset dest */
569 dest_y += luma_stride;
570 dest_u += chroma_stride;
571 dest_v += chroma_stride;
576 subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
577 luma_stride, avctx->width, avctx->height,
578 (uint16_t *) ctx->fill_y, mb_count << 4, 16, is_interlaced, is_top_field);
579 subimage_with_fill((uint16_t *) pic->data[1], mb_x << (4 - ctx->is_422), mb_y << 4,
580 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
581 (uint16_t *) ctx->fill_u, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
582 subimage_with_fill((uint16_t *) pic->data[2], mb_x << (4 - ctx->is_422), mb_y << 4,
583 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
584 (uint16_t *) ctx->fill_v, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
586 /* no need for interlaced special case, data already reorganized in subimage_with_fill */
587 calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count << 5, mb_count, 0, 0);
588 calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
589 calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
591 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
592 mb_count, buf + hdr_size, data_size - hdr_size,
593 &y_data_size, &u_data_size, &v_data_size,
596 if (!is_interlaced) {
597 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0, 0);
598 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1, ctx->is_422);
599 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1, ctx->is_422);
601 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride * 2, mb_count, 0, 0);
602 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride * 2, mb_count, 1, ctx->is_422);
603 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride * 2, mb_count, 1, ctx->is_422);
606 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
607 mb_count, buf + hdr_size, data_size - hdr_size,
608 &y_data_size, &u_data_size, &v_data_size,
611 if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
614 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
615 mb_count, buf + hdr_size, data_size - hdr_size,
616 &y_data_size, &u_data_size, &v_data_size,
618 } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
619 } else if (slice_size < low_bytes && *qp
620 > qp_start_table[avctx->profile]) {
623 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
624 mb_count, buf + hdr_size, data_size - hdr_size,
625 &y_data_size, &u_data_size, &v_data_size,
627 } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
631 buf[0] = hdr_size << 3;
633 AV_WB16(buf + 2, y_data_size);
634 AV_WB16(buf + 4, u_data_size);
636 if (ctx->need_alpha) {
637 AV_WB16(buf + 6, v_data_size); /* write v data size only if there is alpha */
639 subimage_alpha_with_fill((uint16_t *) pic->data[3], mb_x << 4, mb_y << 4,
640 alpha_stride, avctx->width, avctx->height,
641 (uint16_t *) ctx->fill_a, mb_count << 4, 16, is_interlaced, is_top_field);
642 ret = encode_alpha_slice_data(avctx, ctx->fill_a, mb_count,
643 buf + hdr_size + slice_size,
644 data_size - hdr_size - slice_size, &a_data_size);
650 return hdr_size + y_data_size + u_data_size + v_data_size + a_data_size;
653 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
654 uint8_t *buf, const int buf_size, const int picture_index, const int is_top_field)
656 ProresContext *ctx = avctx->priv_data;
657 int mb_width = (avctx->width + 15) >> 4;
658 int hdr_size, sl_size, i;
659 int mb_y, sl_data_size, qp, mb_height, picture_height, unsafe_mb_height_limit;
660 int unsafe_bot, unsafe_right;
661 uint8_t *sl_data, *sl_data_sizes;
662 int slice_per_line = 0, rem = mb_width;
664 if (!ctx->is_interlaced) { /* progressive encoding */
665 mb_height = (avctx->height + 15) >> 4;
666 unsafe_mb_height_limit = mb_height;
669 picture_height = (avctx->height + 1) / 2;
671 picture_height = avctx->height / 2;
673 mb_height = (picture_height + 15) >> 4;
674 unsafe_mb_height_limit = mb_height;
677 for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
678 slice_per_line += rem >> i;
682 qp = qp_start_table[avctx->profile];
683 hdr_size = 8; sl_data_size = buf_size - hdr_size;
684 sl_data_sizes = buf + hdr_size;
685 sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
686 for (mb_y = 0; mb_y < mb_height; mb_y++) {
688 int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
689 while (mb_x < mb_width) {
690 while (mb_width - mb_x < slice_mb_count)
691 slice_mb_count >>= 1;
693 unsafe_bot = (avctx->height & 0xf) && (mb_y == unsafe_mb_height_limit - 1);
694 unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
696 sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
697 sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp, ctx->is_interlaced, is_top_field);
702 bytestream_put_be16(&sl_data_sizes, sl_size);
704 sl_data_size -= sl_size;
705 mb_x += slice_mb_count;
709 buf[0] = hdr_size << 3;
710 AV_WB32(buf + 1, sl_data - buf);
711 AV_WB16(buf + 5, slice_per_line * mb_height); /* picture size */
712 buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4; /* number of slices */
714 return sl_data - buf;
717 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
718 const AVFrame *pict, int *got_packet)
720 ProresContext *ctx = avctx->priv_data;
721 int header_size = 148;
723 int compress_frame_size, pic_size, ret, is_top_field_first = 0;
725 int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
728 if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
732 compress_frame_size = 8 + header_size;
734 bytestream_put_be32(&buf, compress_frame_size);/* frame size will be update after picture(s) encoding */
735 bytestream_put_buffer(&buf, "icpf", 4);
737 bytestream_put_be16(&buf, header_size);
738 bytestream_put_be16(&buf, 0); /* version */
739 bytestream_put_buffer(&buf, ctx->vendor, 4);
740 bytestream_put_be16(&buf, avctx->width);
741 bytestream_put_be16(&buf, avctx->height);
742 frame_flags = 0x82; /* 422 not interlaced */
743 if (avctx->profile >= FF_PROFILE_PRORES_4444) /* 4444 or 4444 Xq */
744 frame_flags |= 0x40; /* 444 chroma */
745 if (ctx->is_interlaced) {
746 if (pict->top_field_first || !pict->interlaced_frame) { /* tff frame or progressive frame interpret as tff */
747 av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, top field first\n");
748 frame_flags |= 0x04; /* interlaced tff */
749 is_top_field_first = 1;
751 av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, bottom field first\n");
752 frame_flags |= 0x08; /* interlaced bff */
755 av_log(avctx, AV_LOG_DEBUG, "use progressive encoding\n");
757 *buf++ = frame_flags;
758 *buf++ = 0; /* reserved */
759 /* only write color properties, if valid value. set to unspecified otherwise */
760 *buf++ = ff_int_from_list_or_default(avctx, "frame color primaries", pict->color_primaries, valid_primaries, 0);
761 *buf++ = ff_int_from_list_or_default(avctx, "frame color trc", pict->color_trc, valid_trc, 0);
762 *buf++ = ff_int_from_list_or_default(avctx, "frame colorspace", pict->colorspace, valid_colorspace, 0);
763 if (avctx->profile >= FF_PROFILE_PRORES_4444) {
764 if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
765 *buf++ = 0xA0;/* src b64a and no alpha */
767 *buf++ = 0xA2;/* src b64a and 16b alpha */
770 *buf++ = 32;/* src v210 and no alpha */
772 *buf++ = 0; /* reserved */
773 *buf++ = 3; /* luma and chroma matrix present */
775 bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64);
776 bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
778 pic_size = prores_encode_picture(avctx, pict, buf,
779 pkt->size - compress_frame_size, 0, is_top_field_first);/* encode progressive or first field */
783 compress_frame_size += pic_size;
785 if (ctx->is_interlaced) { /* encode second field */
786 pic_size = prores_encode_picture(avctx, pict, pkt->data + compress_frame_size,
787 pkt->size - compress_frame_size, 1, !is_top_field_first);
791 compress_frame_size += pic_size;
794 AV_WB32(pkt->data, compress_frame_size);/* update frame size */
795 pkt->flags |= AV_PKT_FLAG_KEY;
796 pkt->size = compress_frame_size;
802 static void scale_mat(const uint8_t* src, int* dst, int scale)
805 for (i = 0; i < 64; i++)
806 dst[i] = src[i] * scale;
809 static av_cold int prores_encode_init(AVCodecContext *avctx)
812 ProresContext* ctx = avctx->priv_data;
814 avctx->bits_per_raw_sample = 10;
816 ctx->is_interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
817 if (ctx->is_interlaced) {
818 ctx->scantable = ff_prores_interlaced_scan;
820 ctx->scantable = ff_prores_progressive_scan;
823 if (avctx->width & 0x1) {
824 av_log(avctx, AV_LOG_ERROR,
825 "frame width needs to be multiple of 2\n");
826 return AVERROR(EINVAL);
829 if (avctx->width > 65534 || avctx->height > 65535) {
830 av_log(avctx, AV_LOG_ERROR,
831 "The maximum dimensions are 65534x65535\n");
832 return AVERROR(EINVAL);
835 if (strlen(ctx->vendor) != 4) {
836 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
837 return AVERROR(EINVAL);
840 if (avctx->profile == FF_PROFILE_UNKNOWN) {
841 if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) {
842 avctx->profile = FF_PROFILE_PRORES_STANDARD;
843 av_log(avctx, AV_LOG_INFO,
844 "encoding with ProRes standard (apcn) profile\n");
845 } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
846 avctx->profile = FF_PROFILE_PRORES_4444;
847 av_log(avctx, AV_LOG_INFO,
848 "encoding with ProRes 4444 (ap4h) profile\n");
849 } else if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
850 avctx->profile = FF_PROFILE_PRORES_4444;
851 av_log(avctx, AV_LOG_INFO,
852 "encoding with ProRes 4444+ (ap4h) profile\n");
854 av_log(avctx, AV_LOG_ERROR, "Unknown pixel format\n");
855 return AVERROR(EINVAL);
857 } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
858 || avctx->profile > FF_PROFILE_PRORES_XQ) {
862 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch, 4 - ap4h, 5 - ap4x]\n",
864 return AVERROR(EINVAL);
865 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P10) && (avctx->profile > FF_PROFILE_PRORES_HQ)){
866 av_log(avctx, AV_LOG_ERROR,
867 "encoding with ProRes 444/Xq (ap4h/ap4x) profile, need YUV444P10 input\n");
868 return AVERROR(EINVAL);
869 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10)
870 && (avctx->profile < FF_PROFILE_PRORES_4444)){
871 av_log(avctx, AV_LOG_ERROR,
872 "encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input\n");
873 return AVERROR(EINVAL);
876 if (avctx->profile < FF_PROFILE_PRORES_4444) { /* 422 versions */
878 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
879 ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
881 return AVERROR(ENOMEM);
882 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
883 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
887 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
888 ctx->fill_y = av_malloc(3 * (DEFAULT_SLICE_MB_WIDTH << 9));
890 return AVERROR(ENOMEM);
891 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
892 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 9);
894 if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
896 ctx->fill_a = av_malloc(DEFAULT_SLICE_MB_WIDTH << 9); /* 8 blocks x 16px x 16px x sizeof (uint16) */
898 return AVERROR(ENOMEM);
902 ff_fdctdsp_init(&ctx->fdsp, avctx);
904 avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
906 for (i = 1; i <= 16; i++) {
907 scale_mat(QMAT_LUMA[avctx->profile] , ctx->qmat_luma[i - 1] , i);
908 scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
914 static av_cold int prores_encode_close(AVCodecContext *avctx)
916 ProresContext* ctx = avctx->priv_data;
917 av_freep(&ctx->fill_y);
918 av_freep(&ctx->fill_a);
923 #define OFFSET(x) offsetof(ProresContext, x)
924 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
926 static const AVOption options[] = {
927 { "vendor", "vendor ID", OFFSET(vendor), AV_OPT_TYPE_STRING, { .str = "fmpg" }, CHAR_MIN, CHAR_MAX, VE },
931 static const AVClass proresaw_enc_class = {
932 .class_name = "ProResAw encoder",
933 .item_name = av_default_item_name,
935 .version = LIBAVUTIL_VERSION_INT,
938 static const AVClass prores_enc_class = {
939 .class_name = "ProRes encoder",
940 .item_name = av_default_item_name,
942 .version = LIBAVUTIL_VERSION_INT,
945 AVCodec ff_prores_aw_encoder = {
947 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
948 .type = AVMEDIA_TYPE_VIDEO,
949 .id = AV_CODEC_ID_PRORES,
950 .priv_data_size = sizeof(ProresContext),
951 .init = prores_encode_init,
952 .close = prores_encode_close,
953 .encode2 = prores_encode_frame,
954 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE},
955 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
956 .priv_class = &proresaw_enc_class,
957 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
960 AVCodec ff_prores_encoder = {
962 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
963 .type = AVMEDIA_TYPE_VIDEO,
964 .id = AV_CODEC_ID_PRORES,
965 .priv_data_size = sizeof(ProresContext),
966 .init = prores_encode_init,
967 .close = prores_encode_close,
968 .encode2 = prores_encode_frame,
969 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE},
970 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
971 .priv_class = &prores_enc_class,
972 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),