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[] = { 8, 3, 2, 1, 1, 1};
53 static const int qp_end_table[] = { 13, 9, 6, 6, 5, 4};
54 static const int bitrate_table[] = { 1000, 2100, 3500, 5400, 7000, 10000};
56 static const int valid_primaries[] = { 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[] = { AVCOL_TRC_RESERVED0, AVCOL_TRC_BT709, AVCOL_TRC_UNSPECIFIED, AVCOL_TRC_SMPTE2084,
59 AVCOL_TRC_ARIB_STD_B67, INT_MAX };
60 static const int valid_colorspace[] = { AVCOL_SPC_BT709, AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_SMPTE170M,
61 AVCOL_SPC_BT2020_NCL, INT_MAX };
63 static const uint8_t QMAT_LUMA[6][64] = {
65 4, 7, 9, 11, 13, 14, 15, 63,
66 7, 7, 11, 12, 14, 15, 63, 63,
67 9, 11, 13, 14, 15, 63, 63, 63,
68 11, 11, 13, 14, 63, 63, 63, 63,
69 11, 13, 14, 63, 63, 63, 63, 63,
70 13, 14, 63, 63, 63, 63, 63, 63,
71 13, 63, 63, 63, 63, 63, 63, 63,
72 63, 63, 63, 63, 63, 63, 63, 63
74 4, 5, 6, 7, 9, 11, 13, 15,
75 5, 5, 7, 8, 11, 13, 15, 17,
76 6, 7, 9, 11, 13, 15, 15, 17,
77 7, 7, 9, 11, 13, 15, 17, 19,
78 7, 9, 11, 13, 14, 16, 19, 23,
79 9, 11, 13, 14, 16, 19, 23, 29,
80 9, 11, 13, 15, 17, 21, 28, 35,
81 11, 13, 16, 17, 21, 28, 35, 41
83 4, 4, 5, 5, 6, 7, 7, 9,
84 4, 4, 5, 6, 7, 7, 9, 9,
85 5, 5, 6, 7, 7, 9, 9, 10,
86 5, 5, 6, 7, 7, 9, 9, 10,
87 5, 6, 7, 7, 8, 9, 10, 12,
88 6, 7, 7, 8, 9, 10, 12, 15,
89 6, 7, 7, 9, 10, 11, 14, 17,
90 7, 7, 9, 10, 11, 14, 17, 21
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
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, 4,
104 4, 4, 4, 4, 4, 4, 4, 5,
105 4, 4, 4, 4, 4, 4, 5, 5,
106 4, 4, 4, 4, 4, 5, 5, 6,
107 4, 4, 4, 4, 5, 5, 6, 7,
108 4, 4, 4, 4, 5, 6, 7, 7
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, 2,
113 2, 2, 2, 2, 2, 2, 2, 3,
114 2, 2, 2, 2, 2, 2, 3, 3,
115 2, 2, 2, 2, 2, 3, 3, 3,
116 2, 2, 2, 2, 3, 3, 3, 4,
117 2, 2, 2, 2, 3, 3, 4, 4,
121 static const uint8_t QMAT_CHROMA[6][64] = {
123 4, 7, 9, 11, 13, 14, 63, 63,
124 7, 7, 11, 12, 14, 63, 63, 63,
125 9, 11, 13, 14, 63, 63, 63, 63,
126 11, 11, 13, 14, 63, 63, 63, 63,
127 11, 13, 14, 63, 63, 63, 63, 63,
128 13, 14, 63, 63, 63, 63, 63, 63,
129 13, 63, 63, 63, 63, 63, 63, 63,
130 63, 63, 63, 63, 63, 63, 63, 63
132 4, 5, 6, 7, 9, 11, 13, 15,
133 5, 5, 7, 8, 11, 13, 15, 17,
134 6, 7, 9, 11, 13, 15, 15, 17,
135 7, 7, 9, 11, 13, 15, 17, 19,
136 7, 9, 11, 13, 14, 16, 19, 23,
137 9, 11, 13, 14, 16, 19, 23, 29,
138 9, 11, 13, 15, 17, 21, 28, 35,
139 11, 13, 16, 17, 21, 28, 35, 41
141 4, 4, 5, 5, 6, 7, 7, 9,
142 4, 4, 5, 6, 7, 7, 9, 9,
143 5, 5, 6, 7, 7, 9, 9, 10,
144 5, 5, 6, 7, 7, 9, 9, 10,
145 5, 6, 7, 7, 8, 9, 10, 12,
146 6, 7, 7, 8, 9, 10, 12, 15,
147 6, 7, 7, 9, 10, 11, 14, 17,
148 7, 7, 9, 10, 11, 14, 17, 21
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, 4,
153 4, 4, 4, 4, 4, 4, 4, 5,
154 4, 4, 4, 4, 4, 4, 5, 5,
155 4, 4, 4, 4, 4, 5, 5, 6,
156 4, 4, 4, 4, 5, 5, 6, 7,
157 4, 4, 4, 4, 5, 6, 7, 7
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, 4,
162 4, 4, 4, 4, 4, 4, 4, 5,
163 4, 4, 4, 4, 4, 4, 5, 5,
164 4, 4, 4, 4, 4, 5, 5, 6,
165 4, 4, 4, 4, 5, 5, 6, 7,
166 4, 4, 4, 4, 5, 6, 7, 7
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, 4,
171 4, 4, 4, 4, 4, 4, 4, 5,
172 4, 4, 4, 4, 4, 4, 5, 5,
173 4, 4, 4, 4, 4, 5, 5, 6,
174 4, 4, 4, 4, 5, 5, 6, 7,
175 4, 4, 4, 4, 5, 6, 7, 7
188 int qmat_luma[16][64];
189 int qmat_chroma[16][64];
190 const uint8_t *scantable;
199 static void encode_codeword(PutBitContext *pb, int val, int codebook)
201 unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
203 /* number of bits to switch between rice and exp golomb */
204 switch_bits = codebook & 3;
205 rice_order = codebook >> 5;
206 exp_order = (codebook >> 2) & 7;
208 first_exp = ((switch_bits + 1) << rice_order);
210 if (val >= first_exp) { /* exp golomb */
212 val += (1 << exp_order);
214 zeros = exp - exp_order + switch_bits + 1;
215 put_bits(pb, zeros, 0);
216 put_bits(pb, exp + 1, val);
217 } else if (rice_order) {
218 put_bits(pb, (val >> rice_order), 0);
220 put_sbits(pb, rice_order, val);
222 put_bits(pb, val, 0);
227 #define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
228 #define TO_GOLOMB(val) (((val) * 2) ^ ((val) >> 31))
229 #define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
230 #define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
231 #define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
233 static av_always_inline int get_level(int val)
235 int sign = (val >> 31);
236 return (val ^ sign) - sign;
239 #define FIRST_DC_CB 0xB8
241 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
243 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
244 int blocks_per_slice, int *qmat)
248 int new_dc, delta, diff_sign, new_code;
250 prev_dc = QSCALE(qmat, 0, in[0] - 16384);
251 code = TO_GOLOMB(prev_dc);
252 encode_codeword(pb, code, FIRST_DC_CB);
254 code = 5; sign = 0; idx = 64;
255 for (i = 1; i < blocks_per_slice; i++, idx += 64) {
256 new_dc = QSCALE(qmat, 0, in[idx] - 16384);
257 delta = new_dc - prev_dc;
258 diff_sign = DIFF_SIGN(delta, sign);
259 new_code = TO_GOLOMB2(get_level(delta), diff_sign);
261 encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
269 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
270 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
271 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
272 0x28, 0x28, 0x28, 0x4C };
274 static void encode_ac_coeffs(PutBitContext *pb,
275 int16_t *in, int blocks_per_slice, int *qmat, const uint8_t ff_prores_scan[64])
280 int run = 0, level, code, i, j;
281 for (i = 1; i < 64; i++) {
282 int indp = ff_prores_scan[i];
283 for (j = 0; j < blocks_per_slice; j++) {
284 int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
286 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
290 level = get_level(val);
293 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
297 put_bits(pb, 1, IS_NEGATIVE(val));
305 static void get(uint8_t *pixels, int stride, int16_t* block)
309 for (i = 0; i < 8; i++) {
310 AV_WN64(block, AV_RN64(pixels));
311 AV_WN64(block+4, AV_RN64(pixels+8));
317 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
319 get(pixels, stride, block);
323 static void calc_plane_dct(FDCTDSPContext *fdsp, uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma, int is_422)
330 if (!chroma) { /* Luma plane */
331 for (i = 0; i < mb_count; i++) {
332 fdct_get(fdsp, src, src_stride, block + (0 << 6));
333 fdct_get(fdsp, src + 16, src_stride, block + (1 << 6));
334 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (2 << 6));
335 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
340 } else if (chroma && is_422){ /* chroma plane 422 */
341 for (i = 0; i < mb_count; i++) {
342 fdct_get(fdsp, src, src_stride, block + (0 << 6));
343 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
347 } else { /* chroma plane 444 */
348 for (i = 0; i < mb_count; i++) {
349 fdct_get(fdsp, src, src_stride, block + (0 << 6));
350 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
351 fdct_get(fdsp, src + 16, src_stride, block + (2 << 6));
352 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
360 static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int sub_sample_chroma,
361 const uint8_t ff_prores_scan[64])
363 int blocks_per_slice;
366 blocks_per_slice = mb_count << (2 - sub_sample_chroma);
367 init_put_bits(&pb, buf, buf_size);
369 encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
370 encode_ac_coeffs(&pb, blocks, blocks_per_slice, qmat, ff_prores_scan);
373 return put_bits_ptr(&pb) - pb.buf;
376 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
377 int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
378 unsigned mb_count, uint8_t *buf, unsigned data_size,
379 unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
382 ProresContext* ctx = avctx->priv_data;
384 *y_data_size = encode_slice_plane(blocks_y, mb_count,
385 buf, data_size, ctx->qmat_luma[qp - 1], 0, ctx->scantable);
387 if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
388 *u_data_size = encode_slice_plane(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
389 ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
391 *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
392 data_size - *y_data_size - *u_data_size,
393 ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
396 return *y_data_size + *u_data_size + *v_data_size;
399 static void put_alpha_diff(PutBitContext *pb, int cur, int prev)
401 const int abits = 16;
403 const int dsize = 1 << dbits - 1;
404 int diff = cur - prev;
406 diff = av_mod_uintp2(diff, abits);
407 if (diff >= (1 << abits) - dsize)
409 if (diff < -dsize || diff > dsize || !diff) {
411 put_bits(pb, abits, diff);
414 put_bits(pb, dbits - 1, FFABS(diff) - 1);
415 put_bits(pb, 1, diff < 0);
419 static inline void put_alpha_run(PutBitContext *pb, int run)
424 put_bits(pb, 4, run);
426 put_bits(pb, 15, run);
432 static av_always_inline int encode_alpha_slice_data(AVCodecContext *avctx, int8_t * src_a,
433 unsigned mb_count, uint8_t *buf, unsigned data_size, unsigned* a_data_size)
435 const int abits = 16;
436 const int mask = (1 << abits) - 1;
437 const int num_coeffs = mb_count * 256;
438 int prev = mask, cur;
441 int16_t * blocks = (int16_t *)src_a;
443 init_put_bits(&pb, buf, data_size);
446 put_alpha_diff(&pb, cur, prev);
451 put_alpha_run (&pb, run);
452 put_alpha_diff(&pb, cur, prev);
458 } while (idx < num_coeffs);
460 put_alpha_run(&pb, run);
462 *a_data_size = put_bits_count(&pb) >> 3;
464 if (put_bits_left(&pb) < 0) {
465 av_log(avctx, AV_LOG_ERROR,
466 "Underestimated required buffer size.\n");
473 static inline void subimage_with_fill_template(uint16_t *src, unsigned x, unsigned y,
474 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
475 unsigned dst_width, unsigned dst_height, int is_alpha_plane,
476 int is_interlaced, int is_top_field)
478 int box_width = FFMIN(width - x, dst_width);
479 int i, j, src_stride, box_height;
480 uint16_t last_pix, *last_line;
482 if (!is_interlaced) {
483 src_stride = stride >> 1;
484 src += y * src_stride + x;
485 box_height = FFMIN(height - y, dst_height);
487 src_stride = stride; /* 2 lines stride */
488 src += y * src_stride + x;
489 box_height = FFMIN(height/2 - y, dst_height);
494 for (i = 0; i < box_height; ++i) {
495 for (j = 0; j < box_width; ++j) {
496 if (!is_alpha_plane) {
499 dst[j] = src[j] << 6; /* alpha 10b to 16b */
502 if (!is_alpha_plane) {
503 last_pix = dst[j - 1];
505 last_pix = dst[j - 1] << 6; /* alpha 10b to 16b */
507 for (; j < dst_width; j++)
512 last_line = dst - dst_width;
513 for (; i < dst_height; i++) {
514 for (j = 0; j < dst_width; ++j) {
515 dst[j] = last_line[j];
521 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
522 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
523 unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
525 subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 0, is_interlaced, is_top_field);
528 /* reorganize alpha data and convert 10b -> 16b */
529 static void subimage_alpha_with_fill(uint16_t *src, unsigned x, unsigned y,
530 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
531 unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
533 subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 1, is_interlaced, is_top_field);
536 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
537 int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
538 int unsafe, int *qp, int is_interlaced, int is_top_field)
540 int luma_stride, chroma_stride, alpha_stride = 0;
541 ProresContext* ctx = avctx->priv_data;
542 int hdr_size = 6 + (ctx->need_alpha * 2); /* v data size is write when there is alpha */
543 int ret = 0, slice_size;
544 uint8_t *dest_y, *dest_u, *dest_v;
545 unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0, a_data_size = 0;
546 FDCTDSPContext *fdsp = &ctx->fdsp;
547 int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2;
548 int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
549 int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
551 LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
552 LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
553 LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
555 luma_stride = pic->linesize[0];
556 chroma_stride = pic->linesize[1];
559 alpha_stride = pic->linesize[3];
561 if (!is_interlaced) {
562 dest_y = pic->data[0] + (mb_y << 4) * luma_stride + (mb_x << 5);
563 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
564 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
566 dest_y = pic->data[0] + (mb_y << 4) * luma_stride * 2 + (mb_x << 5);
567 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
568 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
569 if (!is_top_field){ /* bottom field, offset dest */
570 dest_y += luma_stride;
571 dest_u += chroma_stride;
572 dest_v += chroma_stride;
577 subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
578 luma_stride, avctx->width, avctx->height,
579 (uint16_t *) ctx->fill_y, mb_count << 4, 16, is_interlaced, is_top_field);
580 subimage_with_fill((uint16_t *) pic->data[1], mb_x << (4 - ctx->is_422), mb_y << 4,
581 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
582 (uint16_t *) ctx->fill_u, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
583 subimage_with_fill((uint16_t *) pic->data[2], mb_x << (4 - ctx->is_422), mb_y << 4,
584 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
585 (uint16_t *) ctx->fill_v, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
587 /* no need for interlaced special case, data already reorganized in subimage_with_fill */
588 calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count << 5, mb_count, 0, 0);
589 calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
590 calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
592 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
593 mb_count, buf + hdr_size, data_size - hdr_size,
594 &y_data_size, &u_data_size, &v_data_size,
597 if (!is_interlaced) {
598 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0, 0);
599 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1, ctx->is_422);
600 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1, ctx->is_422);
602 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride * 2, mb_count, 0, 0);
603 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride * 2, mb_count, 1, ctx->is_422);
604 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride * 2, mb_count, 1, ctx->is_422);
607 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
608 mb_count, buf + hdr_size, data_size - hdr_size,
609 &y_data_size, &u_data_size, &v_data_size,
612 if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
615 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
616 mb_count, buf + hdr_size, data_size - hdr_size,
617 &y_data_size, &u_data_size, &v_data_size,
619 } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
620 } else if (slice_size < low_bytes && *qp
621 > qp_start_table[avctx->profile]) {
624 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
625 mb_count, buf + hdr_size, data_size - hdr_size,
626 &y_data_size, &u_data_size, &v_data_size,
628 } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
632 buf[0] = hdr_size << 3;
634 AV_WB16(buf + 2, y_data_size);
635 AV_WB16(buf + 4, u_data_size);
637 if (ctx->need_alpha) {
638 AV_WB16(buf + 6, v_data_size); /* write v data size only if there is alpha */
640 subimage_alpha_with_fill((uint16_t *) pic->data[3], mb_x << 4, mb_y << 4,
641 alpha_stride, avctx->width, avctx->height,
642 (uint16_t *) ctx->fill_a, mb_count << 4, 16, is_interlaced, is_top_field);
643 ret = encode_alpha_slice_data(avctx, ctx->fill_a, mb_count,
644 buf + hdr_size + slice_size,
645 data_size - hdr_size - slice_size, &a_data_size);
651 return hdr_size + y_data_size + u_data_size + v_data_size + a_data_size;
654 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
655 uint8_t *buf, const int buf_size, const int picture_index, const int is_top_field)
657 ProresContext *ctx = avctx->priv_data;
658 int mb_width = (avctx->width + 15) >> 4;
659 int hdr_size, sl_size, i;
660 int mb_y, sl_data_size, qp, mb_height, picture_height, unsafe_mb_height_limit;
661 int unsafe_bot, unsafe_right;
662 uint8_t *sl_data, *sl_data_sizes;
663 int slice_per_line = 0, rem = mb_width;
665 if (!ctx->is_interlaced) { /* progressive encoding */
666 mb_height = (avctx->height + 15) >> 4;
667 unsafe_mb_height_limit = mb_height;
670 picture_height = (avctx->height + 1) / 2;
672 picture_height = avctx->height / 2;
674 mb_height = (picture_height + 15) >> 4;
675 unsafe_mb_height_limit = mb_height;
678 for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
679 slice_per_line += rem >> i;
683 qp = qp_start_table[avctx->profile];
684 hdr_size = 8; sl_data_size = buf_size - hdr_size;
685 sl_data_sizes = buf + hdr_size;
686 sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
687 for (mb_y = 0; mb_y < mb_height; mb_y++) {
689 int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
690 while (mb_x < mb_width) {
691 while (mb_width - mb_x < slice_mb_count)
692 slice_mb_count >>= 1;
694 unsafe_bot = (avctx->height & 0xf) && (mb_y == unsafe_mb_height_limit - 1);
695 unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
697 sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
698 sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp, ctx->is_interlaced, is_top_field);
703 bytestream_put_be16(&sl_data_sizes, sl_size);
705 sl_data_size -= sl_size;
706 mb_x += slice_mb_count;
710 buf[0] = hdr_size << 3;
711 AV_WB32(buf + 1, sl_data - buf);
712 AV_WB16(buf + 5, slice_per_line * mb_height); /* picture size */
713 buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4; /* number of slices */
715 return sl_data - buf;
718 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
719 const AVFrame *pict, int *got_packet)
721 ProresContext *ctx = avctx->priv_data;
722 int header_size = 148;
724 int compress_frame_size, pic_size, ret, is_top_field_first = 0;
726 int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
729 if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
733 compress_frame_size = 8 + header_size;
735 bytestream_put_be32(&buf, compress_frame_size);/* frame size will be update after picture(s) encoding */
736 bytestream_put_buffer(&buf, "icpf", 4);
738 bytestream_put_be16(&buf, header_size);
739 bytestream_put_be16(&buf, 0); /* version */
740 bytestream_put_buffer(&buf, ctx->vendor, 4);
741 bytestream_put_be16(&buf, avctx->width);
742 bytestream_put_be16(&buf, avctx->height);
743 frame_flags = 0x82; /* 422 not interlaced */
744 if (avctx->profile >= FF_PROFILE_PRORES_4444) /* 4444 or 4444 Xq */
745 frame_flags |= 0x40; /* 444 chroma */
746 if (ctx->is_interlaced) {
747 if (pict->top_field_first || !pict->interlaced_frame) { /* tff frame or progressive frame interpret as tff */
748 av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, top field first\n");
749 frame_flags |= 0x04; /* interlaced tff */
750 is_top_field_first = 1;
752 av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, bottom field first\n");
753 frame_flags |= 0x08; /* interlaced bff */
756 av_log(avctx, AV_LOG_DEBUG, "use progressive encoding\n");
758 *buf++ = frame_flags;
759 *buf++ = 0; /* reserved */
760 /* only write color properties, if valid value. set to unspecified otherwise */
761 *buf++ = ff_int_from_list_or_default(avctx, "frame color primaries", pict->color_primaries, valid_primaries, 0);
762 *buf++ = ff_int_from_list_or_default(avctx, "frame color trc", pict->color_trc, valid_trc, 0);
763 *buf++ = ff_int_from_list_or_default(avctx, "frame colorspace", pict->colorspace, valid_colorspace, 0);
764 if (avctx->profile >= FF_PROFILE_PRORES_4444) {
765 if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
766 *buf++ = 0xA0;/* src b64a and no alpha */
768 *buf++ = 0xA2;/* src b64a and 16b alpha */
771 *buf++ = 32;/* src v210 and no alpha */
773 *buf++ = 0; /* reserved */
774 *buf++ = 3; /* luma and chroma matrix present */
776 bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64);
777 bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
779 pic_size = prores_encode_picture(avctx, pict, buf,
780 pkt->size - compress_frame_size, 0, is_top_field_first);/* encode progressive or first field */
784 compress_frame_size += pic_size;
786 if (ctx->is_interlaced) { /* encode second field */
787 pic_size = prores_encode_picture(avctx, pict, pkt->data + compress_frame_size,
788 pkt->size - compress_frame_size, 1, !is_top_field_first);
792 compress_frame_size += pic_size;
795 AV_WB32(pkt->data, compress_frame_size);/* update frame size */
796 pkt->flags |= AV_PKT_FLAG_KEY;
797 pkt->size = compress_frame_size;
803 static void scale_mat(const uint8_t* src, int* dst, int scale)
806 for (i = 0; i < 64; i++)
807 dst[i] = src[i] * scale;
810 static av_cold int prores_encode_init(AVCodecContext *avctx)
813 ProresContext* ctx = avctx->priv_data;
815 avctx->bits_per_raw_sample = 10;
817 ctx->is_interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
818 if (ctx->is_interlaced) {
819 ctx->scantable = ff_prores_interlaced_scan;
821 ctx->scantable = ff_prores_progressive_scan;
824 if (avctx->width & 0x1) {
825 av_log(avctx, AV_LOG_ERROR,
826 "frame width needs to be multiple of 2\n");
827 return AVERROR(EINVAL);
830 if (avctx->width > 65534 || avctx->height > 65535) {
831 av_log(avctx, AV_LOG_ERROR,
832 "The maximum dimensions are 65534x65535\n");
833 return AVERROR(EINVAL);
836 if (strlen(ctx->vendor) != 4) {
837 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
838 return AVERROR(EINVAL);
841 if (avctx->profile == FF_PROFILE_UNKNOWN) {
842 if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) {
843 avctx->profile = FF_PROFILE_PRORES_STANDARD;
844 av_log(avctx, AV_LOG_INFO,
845 "encoding with ProRes standard (apcn) profile\n");
846 } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
847 avctx->profile = FF_PROFILE_PRORES_4444;
848 av_log(avctx, AV_LOG_INFO,
849 "encoding with ProRes 4444 (ap4h) profile\n");
850 } else if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
851 avctx->profile = FF_PROFILE_PRORES_4444;
852 av_log(avctx, AV_LOG_INFO,
853 "encoding with ProRes 4444+ (ap4h) profile\n");
855 av_log(avctx, AV_LOG_ERROR, "Unknown pixel format\n");
856 return AVERROR(EINVAL);
858 } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
859 || avctx->profile > FF_PROFILE_PRORES_XQ) {
863 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch, 4 - ap4h, 5 - ap4x]\n",
865 return AVERROR(EINVAL);
866 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P10) && (avctx->profile > FF_PROFILE_PRORES_HQ)){
867 av_log(avctx, AV_LOG_ERROR,
868 "encoding with ProRes 444/Xq (ap4h/ap4x) profile, need YUV444P10 input\n");
869 return AVERROR(EINVAL);
870 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10)
871 && (avctx->profile < FF_PROFILE_PRORES_4444)){
872 av_log(avctx, AV_LOG_ERROR,
873 "encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input\n");
874 return AVERROR(EINVAL);
877 if (avctx->profile < FF_PROFILE_PRORES_4444) { /* 422 versions */
879 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
880 ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
882 return AVERROR(ENOMEM);
883 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
884 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
888 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
889 ctx->fill_y = av_malloc(3 * (DEFAULT_SLICE_MB_WIDTH << 9));
891 return AVERROR(ENOMEM);
892 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
893 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 9);
895 if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
897 ctx->fill_a = av_malloc(DEFAULT_SLICE_MB_WIDTH << 9); /* 8 blocks x 16px x 16px x sizeof (uint16) */
899 return AVERROR(ENOMEM);
903 ff_fdctdsp_init(&ctx->fdsp, avctx);
905 avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
907 for (i = 1; i <= 16; i++) {
908 scale_mat(QMAT_LUMA[avctx->profile] , ctx->qmat_luma[i - 1] , i);
909 scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
915 static av_cold int prores_encode_close(AVCodecContext *avctx)
917 ProresContext* ctx = avctx->priv_data;
918 av_freep(&ctx->fill_y);
919 av_freep(&ctx->fill_a);
924 #define OFFSET(x) offsetof(ProresContext, x)
925 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
927 static const AVOption options[] = {
928 { "vendor", "vendor ID", OFFSET(vendor), AV_OPT_TYPE_STRING, { .str = "fmpg" }, 0, 0, VE },
932 static const AVClass proresaw_enc_class = {
933 .class_name = "ProResAw encoder",
934 .item_name = av_default_item_name,
936 .version = LIBAVUTIL_VERSION_INT,
939 static const AVClass prores_enc_class = {
940 .class_name = "ProRes encoder",
941 .item_name = av_default_item_name,
943 .version = LIBAVUTIL_VERSION_INT,
946 AVCodec ff_prores_aw_encoder = {
948 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
949 .type = AVMEDIA_TYPE_VIDEO,
950 .id = AV_CODEC_ID_PRORES,
951 .priv_data_size = sizeof(ProresContext),
952 .init = prores_encode_init,
953 .close = prores_encode_close,
954 .encode2 = prores_encode_frame,
955 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE},
956 .capabilities = AV_CODEC_CAP_FRAME_THREADS,
957 .priv_class = &proresaw_enc_class,
958 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
961 AVCodec ff_prores_encoder = {
963 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
964 .type = AVMEDIA_TYPE_VIDEO,
965 .id = AV_CODEC_ID_PRORES,
966 .priv_data_size = sizeof(ProresContext),
967 .init = prores_encode_init,
968 .close = prores_encode_close,
969 .encode2 = prores_encode_frame,
970 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE},
971 .capabilities = AV_CODEC_CAP_FRAME_THREADS,
972 .priv_class = &prores_enc_class,
973 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),