FFmpeg
Loading...
Searching...
No Matches
proresenc_kostya.c
Go to the documentation of this file.
1/*
2 * Apple ProRes encoder
3 *
4 * Copyright (c) 2011 Anatoliy Wasserman
5 * Copyright (c) 2012 Konstantin Shishkov
6 *
7 * This file is part of FFmpeg.
8 *
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.
13 *
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.
18 *
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
22 */
23
24#include "libavutil/mem.h"
26#include "libavutil/opt.h"
27#include "libavutil/pixdesc.h"
28#include "avcodec.h"
29#include "codec_internal.h"
30#include "encode.h"
31#include "fdctdsp.h"
32#include "put_bits.h"
33#include "profiles.h"
34#include "bytestream.h"
35#include "proresdata.h"
37
38#define TRELLIS_WIDTH 16
39#define SCORE_LIMIT INT_MAX / 2
40
41struct TrellisNode {
43 int quant;
44 int bits;
45 int score;
46};
47
48typedef struct ProresThreadData {
50 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
51 int16_t custom_q[64];
52 int16_t custom_chroma_q[64];
55
56static void get_slice_data(ProresContext *ctx, const uint16_t *src,
57 ptrdiff_t linesize, int x, int y, int w, int h,
58 int16_t *blocks, uint16_t *emu_buf,
59 int mbs_per_slice, int blocks_per_mb, int is_chroma)
60{
61 const uint16_t *esrc;
62 const int mb_width = 4 * blocks_per_mb;
63 ptrdiff_t elinesize;
64 int i, j, k;
65
66 for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
67 if (x >= w) {
68 memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
69 * sizeof(*blocks));
70 return;
71 }
72 if (x + mb_width <= w && y + 16 <= h) {
73 esrc = src;
74 elinesize = linesize;
75 } else {
76 int bw, bh, pix;
77
78 esrc = emu_buf;
79 elinesize = 16 * sizeof(*emu_buf);
80
81 bw = FFMIN(w - x, mb_width);
82 bh = FFMIN(h - y, 16);
83
84 for (j = 0; j < bh; j++) {
85 memcpy(emu_buf + j * 16,
86 (const uint8_t*)src + j * linesize,
87 bw * sizeof(*src));
88 pix = emu_buf[j * 16 + bw - 1];
89 for (k = bw; k < mb_width; k++)
90 emu_buf[j * 16 + k] = pix;
91 }
92 for (; j < 16; j++)
93 memcpy(emu_buf + j * 16,
94 emu_buf + (bh - 1) * 16,
95 mb_width * sizeof(*emu_buf));
96 }
97 if (!is_chroma) {
98 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
99 blocks += 64;
100 if (blocks_per_mb > 2) {
101 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
102 blocks += 64;
103 }
104 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
105 blocks += 64;
106 if (blocks_per_mb > 2) {
107 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
108 blocks += 64;
109 }
110 } else {
111 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
112 blocks += 64;
113 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
114 blocks += 64;
115 if (blocks_per_mb > 2) {
116 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
117 blocks += 64;
118 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
119 blocks += 64;
120 }
121 }
122
123 x += mb_width;
124 }
125}
126
127static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
128 ptrdiff_t linesize, int x, int y, int w, int h,
129 uint16_t *blocks, int mbs_per_slice, int abits)
130{
131 const int slice_width = 16 * mbs_per_slice;
132 int i, j, copy_w, copy_h;
133
134 copy_w = FFMIN(w - x, slice_width);
135 copy_h = FFMIN(h - y, 16);
136 for (i = 0; i < copy_h; i++) {
137 memcpy(blocks, src, copy_w * sizeof(*src));
138 if (abits == 8)
139 for (j = 0; j < copy_w; j++)
140 blocks[j] >>= 2;
141 else
142 for (j = 0; j < copy_w; j++)
143 blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
144 for (j = copy_w; j < slice_width; j++)
145 blocks[j] = blocks[copy_w - 1];
146 blocks += slice_width;
147 src += linesize >> 1;
148 }
149 for (; i < 16; i++) {
150 memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
151 blocks += slice_width;
152 }
153}
154
155/**
156 * Write an unsigned rice/exp golomb codeword.
157 */
158static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
159{
160 unsigned int rice_order, exp_order, switch_bits, switch_val;
161 int exponent;
162
163 /* number of prefix bits to switch between Rice and expGolomb */
164 switch_bits = (codebook & 3) + 1;
165 rice_order = codebook >> 5; /* rice code order */
166 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
167
168 switch_val = switch_bits << rice_order;
169
170 if (val >= switch_val) {
171 val -= switch_val - (1 << exp_order);
172 exponent = av_log2(val);
173
174 put_bits(pb, exponent - exp_order + switch_bits, 0);
175 put_bits(pb, exponent + 1, val);
176 } else {
177 exponent = val >> rice_order;
178
179 if (exponent)
180 put_bits(pb, exponent, 0);
181 put_bits(pb, 1, 1);
182 if (rice_order)
183 put_sbits(pb, rice_order, val);
184 }
185}
186
187#define GET_SIGN(x) ((x) >> 31)
188#define MAKE_CODE(x) (((x) * 2) ^ GET_SIGN(x))
189
190static void encode_dcs(PutBitContext *pb, int16_t *blocks,
191 int blocks_per_slice, int scale)
192{
193 int i;
194 int codebook = 5, code, dc, prev_dc, delta, sign, new_sign;
195
196 prev_dc = (blocks[0] - 0x4000) / scale;
198 sign = 0;
199 blocks += 64;
200
201 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
202 dc = (blocks[0] - 0x4000) / scale;
203 delta = dc - prev_dc;
204 new_sign = GET_SIGN(delta);
205 delta = (delta ^ sign) - sign;
208 codebook = FFMIN(code, 6);
209 sign = new_sign;
210 prev_dc = dc;
211 }
212}
213
214static void encode_acs(PutBitContext *pb, int16_t *blocks,
215 int blocks_per_slice,
216 const uint8_t *scan, const int16_t *qmat)
217{
218 int idx, i;
219 int prev_run = 4;
220 int prev_level = 2;
221 int run = 0, level;
222 int max_coeffs, abs_level;
223 max_coeffs = blocks_per_slice << 6;
224
225 for (i = 1; i < 64; i++) {
226 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
227 level = blocks[idx] / qmat[scan[i]];
228 if (level) {
229 abs_level = FFABS(level);
231 encode_vlc_codeword(pb, ff_prores_level_to_cb[prev_level], abs_level - 1);
232 put_sbits(pb, 1, GET_SIGN(level));
233
234 prev_run = FFMIN(run, 15);
235 prev_level = FFMIN(abs_level, 9);
236 run = 0;
237 } else {
238 run++;
239 }
240 }
241 }
242}
243
245 const uint16_t *src, ptrdiff_t linesize,
246 int mbs_per_slice, int16_t *blocks,
247 int blocks_per_mb,
248 const int16_t *qmat)
249{
250 int blocks_per_slice = mbs_per_slice * blocks_per_mb;
251
252 encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
253 encode_acs(pb, blocks, blocks_per_slice, ctx->scantable, qmat);
254}
255
256static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
257{
258 const int dbits = (abits == 8) ? 4 : 7;
259 const int dsize = 1 << dbits - 1;
260 int diff = cur - prev;
261
262 diff = av_zero_extend(diff, abits);
263 if (diff >= (1 << abits) - dsize)
264 diff -= 1 << abits;
265 if (diff < -dsize || diff > dsize || !diff) {
266 put_bits(pb, 1, 1);
267 put_bits(pb, abits, diff);
268 } else {
269 put_bits(pb, 1, 0);
270 put_bits(pb, dbits - 1, FFABS(diff) - 1);
271 put_bits(pb, 1, diff < 0);
272 }
273}
274
275static void put_alpha_run(PutBitContext *pb, int run)
276{
277 if (run) {
278 put_bits(pb, 1, 0);
279 if (run < 0x10)
280 put_bits(pb, 4, run);
281 else
282 put_bits(pb, 15, run);
283 } else {
284 put_bits(pb, 1, 1);
285 }
286}
287
288// todo alpha quantisation for high quants
290 int mbs_per_slice, uint16_t *blocks,
291 int quant)
292{
293 const int abits = ctx->alpha_bits;
294 const int mask = (1 << abits) - 1;
295 const int num_coeffs = mbs_per_slice * 256;
296 int prev = mask, cur;
297 int idx = 0;
298 int run = 0;
299
300 cur = blocks[idx++];
301 put_alpha_diff(pb, cur, prev, abits);
302 prev = cur;
303 do {
304 cur = blocks[idx++];
305 if (cur != prev) {
306 put_alpha_run (pb, run);
307 put_alpha_diff(pb, cur, prev, abits);
308 prev = cur;
309 run = 0;
310 } else {
311 run++;
312 }
313 } while (idx < num_coeffs);
314 put_alpha_run(pb, run);
315}
316
317static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
318 PutBitContext *pb,
319 int sizes[4], int x, int y, int quant,
320 int mbs_per_slice)
321{
322 ProresContext *ctx = avctx->priv_data;
323 int i, xp, yp;
324 int total_size = 0;
325 const uint16_t *src;
326 int num_cblocks, pwidth, line_add;
327 ptrdiff_t linesize;
328 int is_chroma;
329 uint16_t *qmat;
330 uint16_t *qmat_chroma;
331
332 if (ctx->pictures_per_frame == 1)
333 line_add = 0;
334 else
335 line_add = ctx->cur_picture_idx ^ !(pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
336
337 if (ctx->force_quant) {
338 qmat = ctx->quants[0];
339 qmat_chroma = ctx->quants_chroma[0];
340 } else if (quant < MAX_STORED_Q) {
341 qmat = ctx->quants[quant];
342 qmat_chroma = ctx->quants_chroma[quant];
343 } else {
344 qmat = ctx->custom_q;
345 qmat_chroma = ctx->custom_chroma_q;
346 for (i = 0; i < 64; i++) {
347 qmat[i] = ctx->quant_mat[i] * quant;
348 qmat_chroma[i] = ctx->quant_chroma_mat[i] * quant;
349 }
350 }
351
352 for (i = 0; i < ctx->num_planes; i++) {
353 is_chroma = (i == 1 || i == 2);
354 if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
355 xp = x << 4;
356 yp = y << 4;
357 num_cblocks = 4;
358 pwidth = avctx->width;
359 } else {
360 xp = x << 3;
361 yp = y << 4;
362 num_cblocks = 2;
363 pwidth = avctx->width >> 1;
364 }
365
366 linesize = pic->linesize[i] * ctx->pictures_per_frame;
367 src = (const uint16_t*)(pic->data[i] + yp * linesize +
368 line_add * pic->linesize[i]) + xp;
369
370 if (i < 3) {
371 get_slice_data(ctx, src, linesize, xp, yp,
372 pwidth, avctx->height / ctx->pictures_per_frame,
373 ctx->blocks[0], ctx->emu_buf,
374 mbs_per_slice, num_cblocks, is_chroma);
375 if (!is_chroma) {/* luma quant */
376 encode_slice_plane(ctx, pb, src, linesize,
377 mbs_per_slice, ctx->blocks[0],
378 num_cblocks, qmat);
379 } else { /* chroma plane */
380 encode_slice_plane(ctx, pb, src, linesize,
381 mbs_per_slice, ctx->blocks[0],
382 num_cblocks, qmat_chroma);
383 }
384 } else {
385 get_alpha_data(ctx, src, linesize, xp, yp,
386 pwidth, avctx->height / ctx->pictures_per_frame,
387 ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
388 encode_alpha_plane(ctx, pb, mbs_per_slice, ctx->blocks[0], quant);
389 }
390 flush_put_bits(pb);
391 sizes[i] = put_bytes_output(pb) - total_size;
392 total_size = put_bytes_output(pb);
393 }
394 return total_size;
395}
396
397static inline int estimate_vlc(unsigned codebook, int val)
398{
399 unsigned int rice_order, exp_order, switch_bits, switch_val;
400 int exponent;
401
402 /* number of prefix bits to switch between Rice and expGolomb */
403 switch_bits = (codebook & 3) + 1;
404 rice_order = codebook >> 5; /* rice code order */
405 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
406
407 switch_val = switch_bits << rice_order;
408
409 if (val >= switch_val) {
410 val -= switch_val - (1 << exp_order);
411 exponent = av_log2(val);
412
413 return exponent * 2 - exp_order + switch_bits + 1;
414 } else {
415 return (val >> rice_order) + rice_order + 1;
416 }
417}
418
419static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
420 int scale)
421{
422 int i;
423 int codebook = 5, code, dc, prev_dc, delta, sign, new_sign;
424 int bits;
425
426 prev_dc = (blocks[0] - 0x4000) / scale;
428 sign = 0;
429 blocks += 64;
430 *error += FFABS(blocks[0] - 0x4000) % scale;
431
432 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
433 dc = (blocks[0] - 0x4000) / scale;
434 *error += FFABS(blocks[0] - 0x4000) % scale;
435 delta = dc - prev_dc;
436 new_sign = GET_SIGN(delta);
437 delta = (delta ^ sign) - sign;
440 codebook = FFMIN(code, 6);
441 sign = new_sign;
442 prev_dc = dc;
443 }
444
445 return bits;
446}
447
448static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
449 const uint8_t *scan, const int16_t *qmat)
450{
451 int idx, i;
452 int prev_run = 4;
453 int prev_level = 2;
454 int run, level;
455 int max_coeffs, abs_level;
456 int bits = 0;
457
458 max_coeffs = blocks_per_slice << 6;
459 run = 0;
460
461 for (i = 1; i < 64; i++) {
462 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
463 level = blocks[idx] / qmat[scan[i]];
464 *error += FFABS(blocks[idx]) % qmat[scan[i]];
465 if (level) {
466 abs_level = FFABS(level);
469 abs_level - 1) + 1;
470 prev_run = FFMIN(run, 15);
471 prev_level = FFMIN(abs_level, 9);
472 run = 0;
473 } else {
474 run++;
475 }
476 }
477 }
478
479 return bits;
480}
481
482static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
483 const uint16_t *src, ptrdiff_t linesize,
484 int mbs_per_slice,
485 int blocks_per_mb,
486 const int16_t *qmat, ProresThreadData *td)
487{
488 int blocks_per_slice;
489 int bits;
490
491 blocks_per_slice = mbs_per_slice * blocks_per_mb;
492
493 bits = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
494 bits += estimate_acs(error, td->blocks[plane], blocks_per_slice, ctx->scantable, qmat);
495
496 return FFALIGN(bits, 8);
497}
498
499static int est_alpha_diff(int cur, int prev, int abits)
500{
501 const int dbits = (abits == 8) ? 4 : 7;
502 const int dsize = 1 << dbits - 1;
503 int diff = cur - prev;
504
505 diff = av_zero_extend(diff, abits);
506 if (diff >= (1 << abits) - dsize)
507 diff -= 1 << abits;
508 if (diff < -dsize || diff > dsize || !diff)
509 return abits + 1;
510 else
511 return dbits + 1;
512}
513
515 const uint16_t *src, ptrdiff_t linesize,
516 int mbs_per_slice, int16_t *blocks)
517{
518 const int abits = ctx->alpha_bits;
519 const int mask = (1 << abits) - 1;
520 const int num_coeffs = mbs_per_slice * 256;
521 int prev = mask, cur;
522 int idx = 0;
523 int run = 0;
524 int bits;
525
526 cur = blocks[idx++];
527 bits = est_alpha_diff(cur, prev, abits);
528 prev = cur;
529 do {
530 cur = blocks[idx++];
531 if (cur != prev) {
532 if (!run)
533 bits++;
534 else if (run < 0x10)
535 bits += 4;
536 else
537 bits += 15;
538 bits += est_alpha_diff(cur, prev, abits);
539 prev = cur;
540 run = 0;
541 } else {
542 run++;
543 }
544 } while (idx < num_coeffs);
545
546 if (run) {
547 if (run < 0x10)
548 bits += 4;
549 else
550 bits += 15;
551 }
552
553 return bits;
554}
555
557 int trellis_node, int x, int y, int mbs_per_slice,
559{
560 ProresContext *ctx = avctx->priv_data;
561 int i, q, pq, xp, yp;
562 const uint16_t *src;
563 int num_cblocks[MAX_PLANES], pwidth;
564 int is_chroma[MAX_PLANES];
565 const int min_quant = ctx->profile_info->min_quant;
566 const int max_quant = ctx->profile_info->max_quant;
567 int error, bits, bits_limit;
568 int mbs, prev, cur, new_score;
569 int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
570 int overquant;
571 uint16_t *qmat;
572 uint16_t *qmat_chroma;
573 int linesize[4], line_add;
574 int alpha_bits = 0;
575
576 if (ctx->pictures_per_frame == 1)
577 line_add = 0;
578 else
579 line_add = ctx->cur_picture_idx ^ !(ctx->pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST);
580 mbs = x + mbs_per_slice;
581
582 for (i = 0; i < ctx->num_planes; i++) {
583 is_chroma[i] = (i == 1 || i == 2);
584 if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
585 xp = x << 4;
586 yp = y << 4;
587 num_cblocks[i] = 4;
588 pwidth = avctx->width;
589 } else {
590 xp = x << 3;
591 yp = y << 4;
592 num_cblocks[i] = 2;
593 pwidth = avctx->width >> 1;
594 }
595
596 linesize[i] = ctx->pic->linesize[i] * ctx->pictures_per_frame;
597 src = (const uint16_t *)(ctx->pic->data[i] + yp * linesize[i] +
598 line_add * ctx->pic->linesize[i]) + xp;
599
600 if (i < 3) {
601 get_slice_data(ctx, src, linesize[i], xp, yp,
602 pwidth, avctx->height / ctx->pictures_per_frame,
603 td->blocks[i], td->emu_buf,
604 mbs_per_slice, num_cblocks[i], is_chroma[i]);
605 } else {
606 get_alpha_data(ctx, src, linesize[i], xp, yp,
607 pwidth, avctx->height / ctx->pictures_per_frame,
608 td->blocks[i], mbs_per_slice, ctx->alpha_bits);
609 }
610 }
611
612 for (q = min_quant; q < max_quant + 2; q++) {
613 td->nodes[trellis_node + q].prev_node = -1;
614 td->nodes[trellis_node + q].quant = q;
615 }
616
617 if (ctx->alpha_bits)
618 alpha_bits = estimate_alpha_plane(ctx, src, linesize[3],
619 mbs_per_slice, td->blocks[3]);
620 // todo: maybe perform coarser quantising to fit into frame size when needed
621 for (q = min_quant; q <= max_quant; q++) {
622 bits = alpha_bits;
623 error = 0;
625 src, linesize[0],
626 mbs_per_slice,
627 num_cblocks[0],
628 ctx->quants[q], td); /* estimate luma plane */
629 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
631 src, linesize[i],
632 mbs_per_slice,
633 num_cblocks[i],
634 ctx->quants_chroma[q], td);
635 }
636 if (bits > 65000 * 8)
638
639 slice_bits[q] = bits;
640 slice_score[q] = error;
641 }
642 if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
643 slice_bits[max_quant + 1] = slice_bits[max_quant];
644 slice_score[max_quant + 1] = slice_score[max_quant] + 1;
645 overquant = max_quant;
646 } else {
647 for (q = max_quant + 1; q < 128; q++) {
648 bits = alpha_bits;
649 error = 0;
650 if (q < MAX_STORED_Q) {
651 qmat = ctx->quants[q];
652 qmat_chroma = ctx->quants_chroma[q];
653 } else {
654 qmat = td->custom_q;
655 qmat_chroma = td->custom_chroma_q;
656 for (i = 0; i < 64; i++) {
657 qmat[i] = ctx->quant_mat[i] * q;
658 qmat_chroma[i] = ctx->quant_chroma_mat[i] * q;
659 }
660 }
662 src, linesize[0],
663 mbs_per_slice,
664 num_cblocks[0],
665 qmat, td);/* estimate luma plane */
666 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
668 src, linesize[i],
669 mbs_per_slice,
670 num_cblocks[i],
671 qmat_chroma, td);
672 }
673 if (bits <= ctx->bits_per_mb * mbs_per_slice)
674 break;
675 }
676
677 slice_bits[max_quant + 1] = bits;
678 slice_score[max_quant + 1] = error;
679 overquant = q;
680 }
681 td->nodes[trellis_node + max_quant + 1].quant = overquant;
682
683 bits_limit = mbs * ctx->bits_per_mb;
684 for (pq = min_quant; pq < max_quant + 2; pq++) {
685 prev = trellis_node - TRELLIS_WIDTH + pq;
686
687 for (q = min_quant; q < max_quant + 2; q++) {
688 cur = trellis_node + q;
689 bits = td->nodes[prev].bits + slice_bits[q];
690 error = slice_score[q];
691 if (bits > bits_limit)
693
694 if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
695 new_score = td->nodes[prev].score + error;
696 else
697 new_score = SCORE_LIMIT;
698 if (td->nodes[cur].prev_node == -1 ||
699 td->nodes[cur].score >= new_score) {
700
701 td->nodes[cur].bits = bits;
702 td->nodes[cur].score = new_score;
703 td->nodes[cur].prev_node = prev;
704 }
705 }
706 }
707
708 error = td->nodes[trellis_node + min_quant].score;
709 pq = trellis_node + min_quant;
710 for (q = min_quant + 1; q < max_quant + 2; q++) {
711 if (td->nodes[trellis_node + q].score <= error) {
712 error = td->nodes[trellis_node + q].score;
713 pq = trellis_node + q;
714 }
715 }
716
717 return pq;
718}
719
720static int find_quant_thread(AVCodecContext *avctx, void *arg,
721 int jobnr, int threadnr)
722{
723 ProresContext *ctx = avctx->priv_data;
724 ProresThreadData *td = ctx->tdata + threadnr;
725 int mbs_per_slice = ctx->mbs_per_slice;
726 int x, y = jobnr, mb, q = 0;
727
728 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
729 while (ctx->mb_width - x < mbs_per_slice)
730 mbs_per_slice >>= 1;
731 q = find_slice_quant(avctx,
732 (mb + 1) * TRELLIS_WIDTH, x, y,
733 mbs_per_slice, td);
734 }
735
736 for (x = ctx->slices_width - 1; x >= 0; x--) {
737 ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
738 q = td->nodes[q].prev_node;
739 }
740
741 return 0;
742}
743
745 const AVFrame *pic, int *got_packet)
746{
747 ProresContext *ctx = avctx->priv_data;
748 uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
749 uint8_t *picture_size_pos;
750 PutBitContext pb;
751 int x, y, i, mb, q = 0;
752 int sizes[4] = { 0 };
753 int slice_hdr_size = 2 * ctx->num_planes;
754 int frame_size, picture_size, slice_size;
755 int pkt_size, ret;
756 int max_slice_size = (ctx->frame_size_upper_bound - 200) / (ctx->pictures_per_frame * ctx->slices_per_picture + 1);
757 uint8_t frame_flags;
758
759 ctx->pic = pic;
760 pkt_size = ctx->frame_size_upper_bound;
761
762 if ((ret = ff_alloc_packet(avctx, pkt, pkt_size + FF_INPUT_BUFFER_MIN_SIZE)) < 0)
763 return ret;
764
765 orig_buf = pkt->data;
766
767 // frame atom
768 orig_buf += 4; // frame size
769 bytestream_put_be32 (&orig_buf, FRAME_ID); // frame container ID
770 buf = orig_buf;
771
772 // frame header
773 tmp = buf;
774 buf += 2; // frame header size will be stored here
775 bytestream_put_be16 (&buf, ctx->chroma_factor != CFACTOR_Y422 || ctx->alpha_bits ? 1 : 0);
776 bytestream_put_buffer(&buf, ctx->vendor, 4);
777 bytestream_put_be16 (&buf, avctx->width);
778 bytestream_put_be16 (&buf, avctx->height);
779
780 frame_flags = ctx->chroma_factor << 6;
782 frame_flags |= (pic->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) ? 0x04 : 0x08;
783 bytestream_put_byte (&buf, frame_flags);
784
785 bytestream_put_byte (&buf, 0); // reserved
786 bytestream_put_byte (&buf, pic->color_primaries);
787 bytestream_put_byte (&buf, pic->color_trc);
788 bytestream_put_byte (&buf, pic->colorspace);
789 bytestream_put_byte (&buf, ctx->alpha_bits >> 3);
790 bytestream_put_byte (&buf, 0); // reserved
791 if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
792 bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present
793 bytestream_put_buffer(&buf, ctx->quant_mat, 64); // luma quantisation matrix
794 bytestream_put_buffer(&buf, ctx->quant_chroma_mat, 64); // chroma quantisation matrix
795 } else {
796 bytestream_put_byte (&buf, 0x00); // matrix flags - default matrices are used
797 }
798 bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
799
800 for (ctx->cur_picture_idx = 0;
801 ctx->cur_picture_idx < ctx->pictures_per_frame;
802 ctx->cur_picture_idx++) {
803 // picture header
804 picture_size_pos = buf + 1;
805 bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
806 buf += 4; // picture data size will be stored here
807 bytestream_put_be16 (&buf, ctx->slices_per_picture);
808 bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
809
810 // seek table - will be filled during slice encoding
811 slice_sizes = buf;
812 buf += ctx->slices_per_picture * 2;
813
814 // slices
815 if (!ctx->force_quant) {
816 ret = avctx->execute2(avctx, find_quant_thread, NULL, NULL,
817 ctx->mb_height);
818 if (ret)
819 return ret;
820 }
821
822 for (y = 0; y < ctx->mb_height; y++) {
823 int mbs_per_slice = ctx->mbs_per_slice;
824 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
825 q = ctx->force_quant ? ctx->force_quant
826 : ctx->slice_q[mb + y * ctx->slices_width];
827
828 while (ctx->mb_width - x < mbs_per_slice)
829 mbs_per_slice >>= 1;
830
831 bytestream_put_byte(&buf, slice_hdr_size << 3);
832 slice_hdr = buf;
833 buf += slice_hdr_size - 1;
834 if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
835 uint8_t *start = pkt->data;
836 // Recompute new size according to max_slice_size
837 // and deduce delta
838 int delta = 200 + (ctx->pictures_per_frame *
839 ctx->slices_per_picture + 1) *
840 max_slice_size - pkt_size;
841
842 delta = FFMAX(delta, 2 * max_slice_size);
843 ctx->frame_size_upper_bound += delta;
844
845 if (!ctx->warn) {
847 "Packet too small: is %i,"
848 " needs %i (slice: %i). "
849 "Correct allocation",
850 pkt_size, delta, max_slice_size);
851 ctx->warn = 1;
852 }
853
854 ret = av_grow_packet(pkt, delta);
855 if (ret < 0)
856 return ret;
857
858 pkt_size += delta;
859 orig_buf = pkt->data + (orig_buf - start);
860 buf = pkt->data + (buf - start);
861 picture_size_pos = pkt->data + (picture_size_pos - start);
862 slice_sizes = pkt->data + (slice_sizes - start);
863 slice_hdr = pkt->data + (slice_hdr - start);
864 tmp = pkt->data + (tmp - start);
865 }
866 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)));
867 ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
868 mbs_per_slice);
869 if (ret < 0)
870 return ret;
871
872 bytestream_put_byte(&slice_hdr, q);
873 slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
874 for (i = 0; i < ctx->num_planes - 1; i++) {
875 bytestream_put_be16(&slice_hdr, sizes[i]);
876 slice_size += sizes[i];
877 }
878 bytestream_put_be16(&slice_sizes, slice_size);
879 buf += slice_size - slice_hdr_size;
880 if (max_slice_size < slice_size)
881 max_slice_size = slice_size;
882 }
883 }
884
885 picture_size = buf - (picture_size_pos - 1);
886 bytestream_put_be32(&picture_size_pos, picture_size);
887 }
888
889 orig_buf -= 8;
890 frame_size = buf - orig_buf;
891 bytestream_put_be32(&orig_buf, frame_size);
892
893 pkt->size = frame_size;
894 *got_packet = 1;
895
896 return 0;
897}
898
900{
901 ProresContext *ctx = avctx->priv_data;
902 int i;
903
904 if (ctx->tdata) {
905 for (i = 0; i < avctx->thread_count; i++)
906 av_freep(&ctx->tdata[i].nodes);
907 }
908 av_freep(&ctx->tdata);
909 av_freep(&ctx->slice_q);
910
911 return 0;
912}
913
914static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src,
915 ptrdiff_t linesize, int16_t *block)
916{
917 int x, y;
918 const uint16_t *tsrc = src;
919
920 for (y = 0; y < 8; y++) {
921 for (x = 0; x < 8; x++)
922 block[y * 8 + x] = tsrc[x];
923 tsrc += linesize >> 1;
924 }
925 fdsp->fdct(block);
926}
927
929{
930 ProresContext *ctx = avctx->priv_data;
931 int err = 0, i, j, min_quant, max_quant;
932
933 err = ff_prores_kostya_encode_init(avctx, ctx, avctx->pix_fmt);
934 if (err < 0)
935 return err;
936
937 ctx->fdct = prores_fdct;
938 ff_fdctdsp_init(&ctx->fdsp, avctx);
939
940 if (!ctx->force_quant) {
941 min_quant = ctx->profile_info->min_quant;
942 max_quant = ctx->profile_info->max_quant;
943
944 ctx->slice_q = av_malloc_array(ctx->slices_per_picture, sizeof(*ctx->slice_q));
945 if (!ctx->slice_q)
946 return AVERROR(ENOMEM);
947
948 ctx->tdata = av_calloc(avctx->thread_count, sizeof(*ctx->tdata));
949 if (!ctx->tdata)
950 return AVERROR(ENOMEM);
951
952 for (j = 0; j < avctx->thread_count; j++) {
953 ctx->tdata[j].nodes = av_malloc_array(ctx->slices_width + 1,
955 * sizeof(*ctx->tdata->nodes));
956 if (!ctx->tdata[j].nodes)
957 return AVERROR(ENOMEM);
958 for (i = min_quant; i < max_quant + 2; i++) {
959 ctx->tdata[j].nodes[i].prev_node = -1;
960 ctx->tdata[j].nodes[i].bits = 0;
961 ctx->tdata[j].nodes[i].score = 0;
962 }
963 }
964 }
965
966 return 0;
967}
968
969#define OFFSET(x) offsetof(ProresContext, x)
970#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
971
972static const AVOption options[] = {
973 { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
974 AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
975 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
976 { .i64 = PRORES_PROFILE_AUTO },
977 PRORES_PROFILE_AUTO, PRORES_PROFILE_4444XQ, VE, .unit = "profile" },
978 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_AUTO },
979 0, 0, VE, .unit = "profile" },
980 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
981 0, 0, VE, .unit = "profile" },
982 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
983 0, 0, VE, .unit = "profile" },
984 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
985 0, 0, VE, .unit = "profile" },
986 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
987 0, 0, VE, .unit = "profile" },
988 { "4444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
989 0, 0, VE, .unit = "profile" },
990 { "4444xq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444XQ },
991 0, 0, VE, .unit = "profile" },
992 { "vendor", "vendor ID", OFFSET(vendor),
993 AV_OPT_TYPE_STRING, { .str = "Lavc" }, 0, 0, VE },
994 { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
995 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
996 { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
997 { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, .unit = "quant_mat" },
998 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
999 0, 0, VE, .unit = "quant_mat" },
1000 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
1001 0, 0, VE, .unit = "quant_mat" },
1002 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
1003 0, 0, VE, .unit = "quant_mat" },
1004 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
1005 0, 0, VE, .unit = "quant_mat" },
1006 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
1007 0, 0, VE, .unit = "quant_mat" },
1008 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
1009 0, 0, VE, .unit = "quant_mat" },
1010 { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
1011 { .i64 = 16 }, 0, 16, VE },
1012 { NULL }
1013};
1014
1015static const AVClass proresenc_class = {
1016 .class_name = "ProRes encoder",
1017 .item_name = av_default_item_name,
1018 .option = options,
1019 .version = LIBAVUTIL_VERSION_INT,
1020};
1021
1023 .p.name = "prores_ks",
1024 CODEC_LONG_NAME("Apple ProRes (iCodec Pro)"),
1025 .p.type = AVMEDIA_TYPE_VIDEO,
1026 .p.id = AV_CODEC_ID_PRORES,
1027 .priv_data_size = sizeof(ProresContext),
1028 .init = encode_init,
1034 .color_ranges = AVCOL_RANGE_MPEG,
1035 .p.priv_class = &proresenc_class,
1037 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
1038};
static double val(void *priv, double ch)
Definition aeval.c:77
const FFCodec ff_prores_ks_encoder
#define VE
Definition amfenc_av1.c:30
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
static av_cold int encode_init(AVCodecContext *avctx)
Definition asvenc.c:373
Libavcodec external API header.
static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size)
Definition bytestream.h:372
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define mb(name)
Definition cbs_lcevc.c:95
static const unsigned codebook[256][2]
Definition cfhdenc.c:41
#define CODEC_PIXFMTS(...)
#define FF_CODEC_ENCODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define av_zero_extend
Definition common.h:151
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition common.h:74
#define NULL
Definition coverity.c:32
static av_cold int encode_close(AVCodecContext *avctx)
Definition dcaenc.c:354
static int16_t block[64]
Definition dct.c:125
static AVPacket * pkt
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int ff_alloc_packet(AVCodecContext *avctx, AVPacket *avpkt, int64_t size)
Check AVPacket size and allocate data.
Definition encode.c:62
#define FF_INPUT_BUFFER_MIN_SIZE
Used by some encoders as upper bound for the length of headers.
Definition encode.h:34
static const uint8_t bits[8]
Definition fastaudio.c:100
static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame, AVPacket *pkt)
Definition ffmpeg_enc.c:694
#define MAX_PLANES
Definition ffv1.h:44
static const uint8_t frame_size[4]
Definition g723_1.h:222
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
Definition opt.h:298
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
Definition opt.h:275
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition codec.h:147
#define AV_CODEC_FLAG_INTERLACED_DCT
Use interlaced DCT.
Definition avcodec.h:310
#define AV_CODEC_CAP_SLICE_THREADS
Codec supports slice-based (or partition-based) multithreading.
Definition codec.h:102
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition codec.h:98
@ AV_CODEC_ID_PRORES
Definition codec_id.h:198
int av_grow_packet(AVPacket *pkt, int grow_by)
Increase packet size, correctly zeroing padding.
Definition packet.c:121
#define AVERROR(e)
Definition error.h:45
#define AV_FRAME_FLAG_TOP_FIELD_FIRST
A flag to mark frames where the top field is displayed first if the content is interlaced.
Definition frame.h:700
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
static const int sizes[][2]
Definition img2dec.c:62
#define av_log2
Definition intmath.h:84
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition intra.c:278
static void put_bits(Jpeg2000EncoderContext *s, int val, int n)
put n times val bit
Definition j2kenc.c:154
av_cold void ff_fdctdsp_init(FDCTDSPContext *c, AVCodecContext *avctx)
Definition fdctdsp.c:25
const char * arg
Definition jacosubdec.c:65
#define av_cold
Definition attributes.h:117
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
uint8_t w
Definition llvidencdsp.c:39
static const uint16_t mask[17]
Definition lzw.c:38
#define FFMIN(a, b)
Definition macros.h:49
#define FFMAX(a, b)
Definition macros.h:47
#define FFALIGN(x, a)
Definition macros.h:78
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
#define DECLARE_ALIGNED(n, t, v)
Declare a variable that is aligned in memory.
int profile
Definition mxfenc.c:2299
enum AVPixelFormat pix
Definition ohcodec.c:55
AVOptions.
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
#define AV_PIX_FMT_YUVA444P10
Definition pixfmt.h:598
#define AV_PIX_FMT_YUV422P10
Definition pixfmt.h:546
#define AV_PIX_FMT_YUV444P10
Definition pixfmt.h:548
const AVProfile ff_prores_profiles[]
Definition profiles.c:175
const uint8_t ff_prores_dc_codebook[7]
Definition proresdata.c:47
const uint8_t ff_prores_run_to_cb[16]
Definition proresdata.c:49
const uint8_t ff_prores_level_to_cb[10]
Definition proresdata.c:52
#define FIRST_DC_CB
Definition proresdata.h:36
#define FRAME_ID
Definition proresdata.h:28
static int est_alpha_diff(int cur, int prev, int abits)
static int estimate_slice_plane(ProresContext *ctx, int *error, int plane, const uint16_t *src, ptrdiff_t linesize, int mbs_per_slice, int blocks_per_mb, const int16_t *qmat, ProresThreadData *td)
static const AVClass proresenc_class
static int estimate_alpha_plane(ProresContext *ctx, const uint16_t *src, ptrdiff_t linesize, int mbs_per_slice, int16_t *blocks)
#define GET_SIGN(x)
static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice, const uint8_t *scan, const int16_t *qmat)
static void encode_alpha_plane(ProresContext *ctx, PutBitContext *pb, int mbs_per_slice, uint16_t *blocks, int quant)
static av_cold int encode_init(AVCodecContext *avctx)
static av_cold int encode_close(AVCodecContext *avctx)
static void encode_acs(PutBitContext *pb, int16_t *blocks, int blocks_per_slice, const uint8_t *scan, const int16_t *qmat)
static void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
Write an unsigned rice/exp golomb codeword.
static void put_alpha_run(PutBitContext *pb, int run)
static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, PutBitContext *pb, int sizes[4], int x, int y, int quant, int mbs_per_slice)
static void get_alpha_data(ProresContext *ctx, const uint16_t *src, ptrdiff_t linesize, int x, int y, int w, int h, uint16_t *blocks, int mbs_per_slice, int abits)
static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet)
static int estimate_vlc(unsigned codebook, int val)
static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice, int scale)
static int find_slice_quant(AVCodecContext *avctx, int trellis_node, int x, int y, int mbs_per_slice, ProresThreadData *td)
static void get_slice_data(ProresContext *ctx, const uint16_t *src, ptrdiff_t linesize, int x, int y, int w, int h, int16_t *blocks, uint16_t *emu_buf, int mbs_per_slice, int blocks_per_mb, int is_chroma)
#define MAKE_CODE(x)
#define OFFSET(x)
static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
#define TRELLIS_WIDTH
static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src, ptrdiff_t linesize, int16_t *block)
static void encode_slice_plane(ProresContext *ctx, PutBitContext *pb, const uint16_t *src, ptrdiff_t linesize, int mbs_per_slice, int16_t *blocks, int blocks_per_mb, const int16_t *qmat)
static void encode_dcs(PutBitContext *pb, int16_t *blocks, int blocks_per_slice, int scale)
#define SCORE_LIMIT
static int find_quant_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr)
av_cold int ff_prores_kostya_encode_init(AVCodecContext *avctx, ProresContext *ctx, enum AVPixelFormat pix_fmt)
@ QUANT_MAT_STANDARD
@ QUANT_MAT_DEFAULT
#define CFACTOR_Y444
#define CFACTOR_Y422
@ PRORES_PROFILE_4444
@ PRORES_PROFILE_STANDARD
@ PRORES_PROFILE_LT
@ PRORES_PROFILE_4444XQ
@ PRORES_PROFILE_AUTO
@ PRORES_PROFILE_HQ
@ PRORES_PROFILE_PROXY
#define MAX_MBS_PER_SLICE
#define MAX_STORED_Q
bitstream writer API
static void put_sbits(PutBitContext *pb, int n, int32_t value)
Definition put_bits.h:291
static void init_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size)
Initialize the PutBitContext s.
Definition put_bits.h:62
static void flush_put_bits(PutBitContext *s)
Pad the end of the output stream with zeros.
Definition put_bits.h:153
static int put_bytes_output(const PutBitContext *s)
Definition put_bits.h:99
const uint8_t * code
Definition spdifenc.c:433
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition avcodec.h:1579
int flags
AV_CODEC_FLAG_*.
Definition avcodec.h:500
int(* execute2)(struct AVCodecContext *c, int(*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count)
The codec may call this to execute several independent things.
Definition avcodec.h:1628
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int flags
Frame flags, a combination of AV_FRAME_FLAGS.
Definition frame.h:716
enum AVColorPrimaries color_primaries
Definition frame.h:725
enum AVColorSpace colorspace
YUV colorspace type.
Definition frame.h:734
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition frame.h:517
enum AVColorTransferCharacteristic color_trc
Definition frame.h:727
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
void(* fdct)(int16_t *block)
Definition fdctdsp.h:29
int16_t blocks[MAX_PLANES][64 *4 *MAX_MBS_PER_SLICE]
int16_t custom_chroma_q[64]
struct TrellisNode * nodes
uint16_t emu_buf[16 *16]
uint8_t run
Definition svq3.c:207
uint8_t level
Definition svq3.c:208
#define av_malloc_array(a, b)
#define avpriv_request_sample(...)
#define av_freep(p)
static void error(const char *err)
static uint8_t tmp[40]
Definition aes_ctr.c:52
#define src
Definition vp8dsp.c:248
static AVFormatContext * ctx
Definition movenc.c:49
static av_always_inline int diff(const struct color_info *a, const struct color_info *b, const int trans_thresh)
static const uint8_t quant[64]
Definition vmixdec.c:71
float delta