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;
197 static void encode_codeword(PutBitContext *pb, int val, int codebook)
199 unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
201 /* number of bits to switch between rice and exp golomb */
202 switch_bits = codebook & 3;
203 rice_order = codebook >> 5;
204 exp_order = (codebook >> 2) & 7;
206 first_exp = ((switch_bits + 1) << rice_order);
208 if (val >= first_exp) { /* exp golomb */
210 val += (1 << exp_order);
212 zeros = exp - exp_order + switch_bits + 1;
213 put_bits(pb, zeros, 0);
214 put_bits(pb, exp + 1, val);
215 } else if (rice_order) {
216 put_bits(pb, (val >> rice_order), 0);
218 put_sbits(pb, rice_order, val);
220 put_bits(pb, val, 0);
225 #define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
226 #define TO_GOLOMB(val) (((val) << 1) ^ ((val) >> 31))
227 #define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
228 #define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
229 #define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
231 static av_always_inline int get_level(int val)
233 int sign = (val >> 31);
234 return (val ^ sign) - sign;
237 #define FIRST_DC_CB 0xB8
239 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
241 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
242 int blocks_per_slice, int *qmat)
246 int new_dc, delta, diff_sign, new_code;
248 prev_dc = QSCALE(qmat, 0, in[0] - 16384);
249 code = TO_GOLOMB(prev_dc);
250 encode_codeword(pb, code, FIRST_DC_CB);
252 code = 5; sign = 0; idx = 64;
253 for (i = 1; i < blocks_per_slice; i++, idx += 64) {
254 new_dc = QSCALE(qmat, 0, in[idx] - 16384);
255 delta = new_dc - prev_dc;
256 diff_sign = DIFF_SIGN(delta, sign);
257 new_code = TO_GOLOMB2(get_level(delta), diff_sign);
259 encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
267 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
268 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
269 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
270 0x28, 0x28, 0x28, 0x4C };
272 static void encode_ac_coeffs(PutBitContext *pb,
273 int16_t *in, int blocks_per_slice, int *qmat, const uint8_t ff_prores_scan[64])
278 int run = 0, level, code, i, j;
279 for (i = 1; i < 64; i++) {
280 int indp = ff_prores_scan[i];
281 for (j = 0; j < blocks_per_slice; j++) {
282 int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
284 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
288 level = get_level(val);
291 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
295 put_bits(pb, 1, IS_NEGATIVE(val));
303 static void get(uint8_t *pixels, int stride, int16_t* block)
307 for (i = 0; i < 8; i++) {
308 AV_WN64(block, AV_RN64(pixels));
309 AV_WN64(block+4, AV_RN64(pixels+8));
315 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
317 get(pixels, stride, block);
321 static void calc_plane_dct(FDCTDSPContext *fdsp, uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma, int is_422)
328 if (!chroma) { /* Luma plane */
329 for (i = 0; i < mb_count; i++) {
330 fdct_get(fdsp, src, src_stride, block + (0 << 6));
331 fdct_get(fdsp, src + 16, src_stride, block + (1 << 6));
332 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (2 << 6));
333 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
338 } else if (chroma && is_422){ /* chroma plane 422 */
339 for (i = 0; i < mb_count; i++) {
340 fdct_get(fdsp, src, src_stride, block + (0 << 6));
341 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
345 } else { /* chroma plane 444 */
346 for (i = 0; i < mb_count; i++) {
347 fdct_get(fdsp, src, src_stride, block + (0 << 6));
348 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
349 fdct_get(fdsp, src + 16, src_stride, block + (2 << 6));
350 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
358 static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int sub_sample_chroma,
359 const uint8_t ff_prores_scan[64])
361 int blocks_per_slice;
364 blocks_per_slice = mb_count << (2 - sub_sample_chroma);
365 init_put_bits(&pb, buf, buf_size);
367 encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
368 encode_ac_coeffs(&pb, blocks, blocks_per_slice, qmat, ff_prores_scan);
371 return put_bits_ptr(&pb) - pb.buf;
374 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
375 int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
376 unsigned mb_count, uint8_t *buf, unsigned data_size,
377 unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
380 ProresContext* ctx = avctx->priv_data;
382 *y_data_size = encode_slice_plane(blocks_y, mb_count,
383 buf, data_size, ctx->qmat_luma[qp - 1], 0, ctx->scantable);
385 if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
386 *u_data_size = encode_slice_plane(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
387 ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
389 *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
390 data_size - *y_data_size - *u_data_size,
391 ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
394 return *y_data_size + *u_data_size + *v_data_size;
397 static void put_alpha_diff(PutBitContext *pb, int cur, int prev)
399 const int abits = 16;
401 const int dsize = 1 << dbits - 1;
402 int diff = cur - prev;
404 diff = av_mod_uintp2(diff, abits);
405 if (diff >= (1 << abits) - dsize)
407 if (diff < -dsize || diff > dsize || !diff) {
409 put_bits(pb, abits, diff);
412 put_bits(pb, dbits - 1, FFABS(diff) - 1);
413 put_bits(pb, 1, diff < 0);
417 static inline void put_alpha_run(PutBitContext *pb, int run)
422 put_bits(pb, 4, run);
424 put_bits(pb, 15, run);
430 static av_always_inline int encode_alpha_slice_data(AVCodecContext *avctx, int8_t * src_a,
431 unsigned mb_count, uint8_t *buf, unsigned data_size, unsigned* a_data_size)
433 const int abits = 16;
434 const int mask = (1 << abits) - 1;
435 const int num_coeffs = mb_count * 256;
436 int prev = mask, cur;
439 int16_t * blocks = (int16_t *)src_a;
441 init_put_bits(&pb, buf, data_size);
444 put_alpha_diff(&pb, cur, prev);
449 put_alpha_run (&pb, run);
450 put_alpha_diff(&pb, cur, prev);
456 } while (idx < num_coeffs);
458 put_alpha_run(&pb, run);
460 *a_data_size = put_bits_count(&pb) >> 3;
462 if (put_bits_left(&pb) < 0) {
463 av_log(avctx, AV_LOG_ERROR,
464 "Underestimated required buffer size.\n");
471 static inline void subimage_with_fill_template(uint16_t *src, unsigned x, unsigned y,
472 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
473 unsigned dst_width, unsigned dst_height, int is_alpha_plane)
475 int box_width = FFMIN(width - x, dst_width);
476 int box_height = FFMIN(height - y, dst_height);
477 int i, j, src_stride = stride >> 1;
478 uint16_t last_pix, *last_line;
480 src += y * src_stride + x;
481 for (i = 0; i < box_height; ++i) {
482 for (j = 0; j < box_width; ++j) {
483 if (!is_alpha_plane) {
486 dst[j] = src[j] << 6; /* alpha 10b to 16b */
489 if (!is_alpha_plane) {
490 last_pix = dst[j - 1];
492 last_pix = dst[j - 1] << 6; /* alpha 10b to 16b */
494 for (; j < dst_width; j++)
499 last_line = dst - dst_width;
500 for (; i < dst_height; i++) {
501 for (j = 0; j < dst_width; ++j) {
502 dst[j] = last_line[j];
508 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
509 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
510 unsigned dst_width, unsigned dst_height)
512 subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 0);
515 /* reorganize alpha data and convert 10b -> 16b */
516 static void subimage_alpha_with_fill(uint16_t *src, unsigned x, unsigned y,
517 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
518 unsigned dst_width, unsigned dst_height)
520 subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 1);
523 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
524 int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
527 int luma_stride, chroma_stride, alpha_stride = 0;
528 ProresContext* ctx = avctx->priv_data;
529 int hdr_size = 6 + (ctx->need_alpha * 2); /* v data size is write when there is alpha */
530 int ret = 0, slice_size;
531 uint8_t *dest_y, *dest_u, *dest_v;
532 unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0, a_data_size = 0;
533 FDCTDSPContext *fdsp = &ctx->fdsp;
534 int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2;
535 int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
536 int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
538 LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
539 LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
540 LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
542 luma_stride = pic->linesize[0];
543 chroma_stride = pic->linesize[1];
546 alpha_stride = pic->linesize[3];
548 dest_y = pic->data[0] + (mb_y << 4) * luma_stride + (mb_x << 5);
549 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
550 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
553 subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
554 luma_stride, avctx->width, avctx->height,
555 (uint16_t *) ctx->fill_y, mb_count << 4, 16);
556 subimage_with_fill((uint16_t *) pic->data[1], mb_x << (4 - ctx->is_422), mb_y << 4,
557 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
558 (uint16_t *) ctx->fill_u, mb_count << (4 - ctx->is_422), 16);
559 subimage_with_fill((uint16_t *) pic->data[2], mb_x << (4 - ctx->is_422), mb_y << 4,
560 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
561 (uint16_t *) ctx->fill_v, mb_count << (4 - ctx->is_422), 16);
563 calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count << 5, mb_count, 0, 0);
564 calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
565 calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
567 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
568 mb_count, buf + hdr_size, data_size - hdr_size,
569 &y_data_size, &u_data_size, &v_data_size,
572 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0, 0);
573 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1, ctx->is_422);
574 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1, ctx->is_422);
576 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
577 mb_count, buf + hdr_size, data_size - hdr_size,
578 &y_data_size, &u_data_size, &v_data_size,
581 if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
584 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
585 mb_count, buf + hdr_size, data_size - hdr_size,
586 &y_data_size, &u_data_size, &v_data_size,
588 } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
589 } else if (slice_size < low_bytes && *qp
590 > qp_start_table[avctx->profile]) {
593 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
594 mb_count, buf + hdr_size, data_size - hdr_size,
595 &y_data_size, &u_data_size, &v_data_size,
597 } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
601 buf[0] = hdr_size << 3;
603 AV_WB16(buf + 2, y_data_size);
604 AV_WB16(buf + 4, u_data_size);
606 if (ctx->need_alpha) {
607 AV_WB16(buf + 6, v_data_size); /* write v data size only if there is alpha */
609 subimage_alpha_with_fill((uint16_t *) pic->data[3], mb_x << 4, mb_y << 4,
610 alpha_stride, avctx->width, avctx->height,
611 (uint16_t *) ctx->fill_a, mb_count << 4, 16);
612 ret = encode_alpha_slice_data(avctx, ctx->fill_a, mb_count,
613 buf + hdr_size + slice_size,
614 data_size - hdr_size - slice_size, &a_data_size);
620 return hdr_size + y_data_size + u_data_size + v_data_size + a_data_size;
623 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
624 uint8_t *buf, const int buf_size)
626 int mb_width = (avctx->width + 15) >> 4;
627 int mb_height = (avctx->height + 15) >> 4;
628 int hdr_size, sl_size, i;
629 int mb_y, sl_data_size, qp;
630 int unsafe_bot, unsafe_right;
631 uint8_t *sl_data, *sl_data_sizes;
632 int slice_per_line = 0, rem = mb_width;
634 for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
635 slice_per_line += rem >> i;
639 qp = qp_start_table[avctx->profile];
640 hdr_size = 8; sl_data_size = buf_size - hdr_size;
641 sl_data_sizes = buf + hdr_size;
642 sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
643 for (mb_y = 0; mb_y < mb_height; mb_y++) {
645 int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
646 while (mb_x < mb_width) {
647 while (mb_width - mb_x < slice_mb_count)
648 slice_mb_count >>= 1;
650 unsafe_bot = (avctx->height & 0xf) && (mb_y == mb_height - 1);
651 unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
653 sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
654 sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp);
659 bytestream_put_be16(&sl_data_sizes, sl_size);
661 sl_data_size -= sl_size;
662 mb_x += slice_mb_count;
666 buf[0] = hdr_size << 3;
667 AV_WB32(buf + 1, sl_data - buf);
668 AV_WB16(buf + 5, slice_per_line * mb_height);
669 buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4;
671 return sl_data - buf;
674 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
675 const AVFrame *pict, int *got_packet)
677 ProresContext *ctx = avctx->priv_data;
678 int header_size = 148;
680 int compress_frame_size, pic_size, ret;
682 int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
685 if ((ret = ff_alloc_packet2(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0)
689 compress_frame_size = 8 + header_size;
691 bytestream_put_be32(&buf, compress_frame_size);/* frame size will be update after picture(s) encoding */
692 bytestream_put_buffer(&buf, "icpf", 4);
694 bytestream_put_be16(&buf, header_size);
695 bytestream_put_be16(&buf, 0); /* version */
696 bytestream_put_buffer(&buf, ctx->vendor, 4);
697 bytestream_put_be16(&buf, avctx->width);
698 bytestream_put_be16(&buf, avctx->height);
699 frame_flags = 0x82; /* 422 not interlaced */
700 if (avctx->profile >= FF_PROFILE_PRORES_4444) /* 4444 or 4444 Xq */
701 frame_flags |= 0x40; /* 444 chroma */
702 *buf++ = frame_flags;
703 *buf++ = 0; /* reserved */
704 /* only write color properties, if valid value. set to unspecified otherwise */
705 *buf++ = ff_int_from_list_or_default(avctx, "frame color primaries", pict->color_primaries, valid_primaries, 0);
706 *buf++ = ff_int_from_list_or_default(avctx, "frame color trc", pict->color_trc, valid_trc, 0);
707 *buf++ = ff_int_from_list_or_default(avctx, "frame colorspace", pict->colorspace, valid_colorspace, 0);
708 if (avctx->profile >= FF_PROFILE_PRORES_4444) {
709 if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
710 *buf++ = 0xA0;/* src b64a and no alpha */
712 *buf++ = 0xA2;/* src b64a and 16b alpha */
715 *buf++ = 32;/* src v210 and no alpha */
717 *buf++ = 0; /* reserved */
718 *buf++ = 3; /* luma and chroma matrix present */
720 bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64);
721 bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
723 pic_size = prores_encode_picture(avctx, pict, buf,
724 pkt->size - compress_frame_size);
728 compress_frame_size += pic_size;
730 AV_WB32(pkt->data, compress_frame_size);/* update frame size */
731 pkt->flags |= AV_PKT_FLAG_KEY;
732 pkt->size = compress_frame_size;
738 static void scale_mat(const uint8_t* src, int* dst, int scale)
741 for (i = 0; i < 64; i++)
742 dst[i] = src[i] * scale;
745 static av_cold int prores_encode_init(AVCodecContext *avctx)
748 ProresContext* ctx = avctx->priv_data;
750 avctx->bits_per_raw_sample = 10;
752 ctx->scantable = ff_prores_progressive_scan;
754 if (avctx->width & 0x1) {
755 av_log(avctx, AV_LOG_ERROR,
756 "frame width needs to be multiple of 2\n");
757 return AVERROR(EINVAL);
760 if (avctx->width > 65534 || avctx->height > 65535) {
761 av_log(avctx, AV_LOG_ERROR,
762 "The maximum dimensions are 65534x65535\n");
763 return AVERROR(EINVAL);
766 if (strlen(ctx->vendor) != 4) {
767 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
768 return AVERROR(EINVAL);
771 if (avctx->profile == FF_PROFILE_UNKNOWN) {
772 if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) {
773 avctx->profile = FF_PROFILE_PRORES_STANDARD;
774 av_log(avctx, AV_LOG_INFO,
775 "encoding with ProRes standard (apcn) profile\n");
776 } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
777 avctx->profile = FF_PROFILE_PRORES_4444;
778 av_log(avctx, AV_LOG_INFO,
779 "encoding with ProRes 4444 (ap4h) profile\n");
780 } else if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
781 avctx->profile = FF_PROFILE_PRORES_4444;
782 av_log(avctx, AV_LOG_INFO,
783 "encoding with ProRes 4444+ (ap4h) profile\n");
785 av_log(avctx, AV_LOG_ERROR, "Unknown pixel format\n");
786 return AVERROR(EINVAL);
788 } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
789 || avctx->profile > FF_PROFILE_PRORES_XQ) {
793 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch, 4 - ap4h, 5 - ap4x]\n",
795 return AVERROR(EINVAL);
796 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P10) && (avctx->profile > FF_PROFILE_PRORES_HQ)){
797 av_log(avctx, AV_LOG_ERROR,
798 "encoding with ProRes 444/Xq (ap4h/ap4x) profile, need YUV444P10 input\n");
799 return AVERROR(EINVAL);
800 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10)
801 && (avctx->profile < FF_PROFILE_PRORES_4444)){
802 av_log(avctx, AV_LOG_ERROR,
803 "encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input\n");
804 return AVERROR(EINVAL);
807 if (avctx->profile < FF_PROFILE_PRORES_4444) { /* 422 versions */
809 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
810 ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
812 return AVERROR(ENOMEM);
813 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
814 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
818 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
819 ctx->fill_y = av_malloc(3 * (DEFAULT_SLICE_MB_WIDTH << 9));
821 return AVERROR(ENOMEM);
822 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
823 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 9);
825 if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
827 ctx->fill_a = av_malloc(DEFAULT_SLICE_MB_WIDTH << 9); /* 8 blocks x 16px x 16px x sizeof (uint16) */
829 return AVERROR(ENOMEM);
833 ff_fdctdsp_init(&ctx->fdsp, avctx);
835 avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
837 for (i = 1; i <= 16; i++) {
838 scale_mat(QMAT_LUMA[avctx->profile] , ctx->qmat_luma[i - 1] , i);
839 scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
845 static av_cold int prores_encode_close(AVCodecContext *avctx)
847 ProresContext* ctx = avctx->priv_data;
848 av_freep(&ctx->fill_y);
849 av_freep(&ctx->fill_a);
854 #define OFFSET(x) offsetof(ProresContext, x)
855 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
857 static const AVOption options[] = {
858 { "vendor", "vendor ID", OFFSET(vendor), AV_OPT_TYPE_STRING, { .str = "fmpg" }, CHAR_MIN, CHAR_MAX, VE },
862 static const AVClass proresaw_enc_class = {
863 .class_name = "ProResAw encoder",
864 .item_name = av_default_item_name,
866 .version = LIBAVUTIL_VERSION_INT,
869 static const AVClass prores_enc_class = {
870 .class_name = "ProRes encoder",
871 .item_name = av_default_item_name,
873 .version = LIBAVUTIL_VERSION_INT,
876 AVCodec ff_prores_aw_encoder = {
878 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
879 .type = AVMEDIA_TYPE_VIDEO,
880 .id = AV_CODEC_ID_PRORES,
881 .priv_data_size = sizeof(ProresContext),
882 .init = prores_encode_init,
883 .close = prores_encode_close,
884 .encode2 = prores_encode_frame,
885 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE},
886 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
887 .priv_class = &proresaw_enc_class,
888 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
891 AVCodec ff_prores_encoder = {
893 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
894 .type = AVMEDIA_TYPE_VIDEO,
895 .id = AV_CODEC_ID_PRORES,
896 .priv_data_size = sizeof(ProresContext),
897 .init = prores_encode_init,
898 .close = prores_encode_close,
899 .encode2 = prores_encode_frame,
900 .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE},
901 .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_INTRA_ONLY,
902 .priv_class = &prores_enc_class,
903 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),