FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/proresenc_kostya.c
Date: 2021-09-16 08:47:15
Exec Total Coverage
Lines: 470 656 71.6%
Branches: 180 302 59.6%

Line Branch Exec Source
1 /*
2 * Apple ProRes encoder
3 *
4 * Copyright (c) 2012 Konstantin Shishkov
5 *
6 * This encoder appears to be based on Anatoliy Wassermans considering
7 * similarities in the bugs.
8 *
9 * This file is part of FFmpeg.
10 *
11 * FFmpeg is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2.1 of the License, or (at your option) any later version.
15 *
16 * FFmpeg is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with FFmpeg; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 */
25
26 #include "libavutil/mem_internal.h"
27 #include "libavutil/opt.h"
28 #include "libavutil/pixdesc.h"
29 #include "avcodec.h"
30 #include "encode.h"
31 #include "fdctdsp.h"
32 #include "put_bits.h"
33 #include "profiles.h"
34 #include "bytestream.h"
35 #include "internal.h"
36 #include "proresdata.h"
37
38 #define CFACTOR_Y422 2
39 #define CFACTOR_Y444 3
40
41 #define MAX_MBS_PER_SLICE 8
42
43 #define MAX_PLANES 4
44
45 enum {
46 PRORES_PROFILE_AUTO = -1,
47 PRORES_PROFILE_PROXY = 0,
48 PRORES_PROFILE_LT,
49 PRORES_PROFILE_STANDARD,
50 PRORES_PROFILE_HQ,
51 PRORES_PROFILE_4444,
52 PRORES_PROFILE_4444XQ,
53 };
54
55 enum {
56 QUANT_MAT_PROXY = 0,
57 QUANT_MAT_PROXY_CHROMA,
58 QUANT_MAT_LT,
59 QUANT_MAT_STANDARD,
60 QUANT_MAT_HQ,
61 QUANT_MAT_XQ_LUMA,
62 QUANT_MAT_DEFAULT,
63 };
64
65 static const uint8_t prores_quant_matrices[][64] = {
66 { // proxy
67 4, 7, 9, 11, 13, 14, 15, 63,
68 7, 7, 11, 12, 14, 15, 63, 63,
69 9, 11, 13, 14, 15, 63, 63, 63,
70 11, 11, 13, 14, 63, 63, 63, 63,
71 11, 13, 14, 63, 63, 63, 63, 63,
72 13, 14, 63, 63, 63, 63, 63, 63,
73 13, 63, 63, 63, 63, 63, 63, 63,
74 63, 63, 63, 63, 63, 63, 63, 63,
75 },
76 { // proxy chromas
77 4, 7, 9, 11, 13, 14, 63, 63,
78 7, 7, 11, 12, 14, 63, 63, 63,
79 9, 11, 13, 14, 63, 63, 63, 63,
80 11, 11, 13, 14, 63, 63, 63, 63,
81 11, 13, 14, 63, 63, 63, 63, 63,
82 13, 14, 63, 63, 63, 63, 63, 63,
83 13, 63, 63, 63, 63, 63, 63, 63,
84 63, 63, 63, 63, 63, 63, 63, 63
85 },
86 { // LT
87 4, 5, 6, 7, 9, 11, 13, 15,
88 5, 5, 7, 8, 11, 13, 15, 17,
89 6, 7, 9, 11, 13, 15, 15, 17,
90 7, 7, 9, 11, 13, 15, 17, 19,
91 7, 9, 11, 13, 14, 16, 19, 23,
92 9, 11, 13, 14, 16, 19, 23, 29,
93 9, 11, 13, 15, 17, 21, 28, 35,
94 11, 13, 16, 17, 21, 28, 35, 41,
95 },
96 { // standard
97 4, 4, 5, 5, 6, 7, 7, 9,
98 4, 4, 5, 6, 7, 7, 9, 9,
99 5, 5, 6, 7, 7, 9, 9, 10,
100 5, 5, 6, 7, 7, 9, 9, 10,
101 5, 6, 7, 7, 8, 9, 10, 12,
102 6, 7, 7, 8, 9, 10, 12, 15,
103 6, 7, 7, 9, 10, 11, 14, 17,
104 7, 7, 9, 10, 11, 14, 17, 21,
105 },
106 { // high quality
107 4, 4, 4, 4, 4, 4, 4, 4,
108 4, 4, 4, 4, 4, 4, 4, 4,
109 4, 4, 4, 4, 4, 4, 4, 4,
110 4, 4, 4, 4, 4, 4, 4, 5,
111 4, 4, 4, 4, 4, 4, 5, 5,
112 4, 4, 4, 4, 4, 5, 5, 6,
113 4, 4, 4, 4, 5, 5, 6, 7,
114 4, 4, 4, 4, 5, 6, 7, 7,
115 },
116 { // XQ luma
117 2, 2, 2, 2, 2, 2, 2, 2,
118 2, 2, 2, 2, 2, 2, 2, 2,
119 2, 2, 2, 2, 2, 2, 2, 2,
120 2, 2, 2, 2, 2, 2, 2, 3,
121 2, 2, 2, 2, 2, 2, 3, 3,
122 2, 2, 2, 2, 2, 3, 3, 3,
123 2, 2, 2, 2, 3, 3, 3, 4,
124 2, 2, 2, 2, 3, 3, 4, 4,
125 },
126 { // codec default
127 4, 4, 4, 4, 4, 4, 4, 4,
128 4, 4, 4, 4, 4, 4, 4, 4,
129 4, 4, 4, 4, 4, 4, 4, 4,
130 4, 4, 4, 4, 4, 4, 4, 4,
131 4, 4, 4, 4, 4, 4, 4, 4,
132 4, 4, 4, 4, 4, 4, 4, 4,
133 4, 4, 4, 4, 4, 4, 4, 4,
134 4, 4, 4, 4, 4, 4, 4, 4,
135 },
136 };
137
138 #define NUM_MB_LIMITS 4
139 static const int prores_mb_limits[NUM_MB_LIMITS] = {
140 1620, // up to 720x576
141 2700, // up to 960x720
142 6075, // up to 1440x1080
143 9216, // up to 2048x1152
144 };
145
146 static const struct prores_profile {
147 const char *full_name;
148 uint32_t tag;
149 int min_quant;
150 int max_quant;
151 int br_tab[NUM_MB_LIMITS];
152 int quant;
153 int quant_chroma;
154 } prores_profile_info[6] = {
155 {
156 .full_name = "proxy",
157 .tag = MKTAG('a', 'p', 'c', 'o'),
158 .min_quant = 4,
159 .max_quant = 8,
160 .br_tab = { 300, 242, 220, 194 },
161 .quant = QUANT_MAT_PROXY,
162 .quant_chroma = QUANT_MAT_PROXY_CHROMA,
163 },
164 {
165 .full_name = "LT",
166 .tag = MKTAG('a', 'p', 'c', 's'),
167 .min_quant = 1,
168 .max_quant = 9,
169 .br_tab = { 720, 560, 490, 440 },
170 .quant = QUANT_MAT_LT,
171 .quant_chroma = QUANT_MAT_LT,
172 },
173 {
174 .full_name = "standard",
175 .tag = MKTAG('a', 'p', 'c', 'n'),
176 .min_quant = 1,
177 .max_quant = 6,
178 .br_tab = { 1050, 808, 710, 632 },
179 .quant = QUANT_MAT_STANDARD,
180 .quant_chroma = QUANT_MAT_STANDARD,
181 },
182 {
183 .full_name = "high quality",
184 .tag = MKTAG('a', 'p', 'c', 'h'),
185 .min_quant = 1,
186 .max_quant = 6,
187 .br_tab = { 1566, 1216, 1070, 950 },
188 .quant = QUANT_MAT_HQ,
189 .quant_chroma = QUANT_MAT_HQ,
190 },
191 {
192 .full_name = "4444",
193 .tag = MKTAG('a', 'p', '4', 'h'),
194 .min_quant = 1,
195 .max_quant = 6,
196 .br_tab = { 2350, 1828, 1600, 1425 },
197 .quant = QUANT_MAT_HQ,
198 .quant_chroma = QUANT_MAT_HQ,
199 },
200 {
201 .full_name = "4444XQ",
202 .tag = MKTAG('a', 'p', '4', 'x'),
203 .min_quant = 1,
204 .max_quant = 6,
205 .br_tab = { 3525, 2742, 2400, 2137 },
206 .quant = QUANT_MAT_HQ, /* Fix me : use QUANT_MAT_XQ_LUMA */
207 .quant_chroma = QUANT_MAT_HQ,
208 }
209 };
210
211 #define TRELLIS_WIDTH 16
212 #define SCORE_LIMIT INT_MAX / 2
213
214 struct TrellisNode {
215 int prev_node;
216 int quant;
217 int bits;
218 int score;
219 };
220
221 #define MAX_STORED_Q 16
222
223 typedef struct ProresThreadData {
224 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
225 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16 * 16];
226 int16_t custom_q[64];
227 int16_t custom_chroma_q[64];
228 struct TrellisNode *nodes;
229 } ProresThreadData;
230
231 typedef struct ProresContext {
232 AVClass *class;
233 DECLARE_ALIGNED(16, int16_t, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
234 DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
235 int16_t quants[MAX_STORED_Q][64];
236 int16_t quants_chroma[MAX_STORED_Q][64];
237 int16_t custom_q[64];
238 int16_t custom_chroma_q[64];
239 const uint8_t *quant_mat;
240 const uint8_t *quant_chroma_mat;
241 const uint8_t *scantable;
242
243 void (*fdct)(FDCTDSPContext *fdsp, const uint16_t *src,
244 ptrdiff_t linesize, int16_t *block);
245 FDCTDSPContext fdsp;
246
247 const AVFrame *pic;
248 int mb_width, mb_height;
249 int mbs_per_slice;
250 int num_chroma_blocks, chroma_factor;
251 int slices_width;
252 int slices_per_picture;
253 int pictures_per_frame; // 1 for progressive, 2 for interlaced
254 int cur_picture_idx;
255 int num_planes;
256 int bits_per_mb;
257 int force_quant;
258 int alpha_bits;
259 int warn;
260
261 char *vendor;
262 int quant_sel;
263
264 int frame_size_upper_bound;
265
266 int profile;
267 const struct prores_profile *profile_info;
268
269 int *slice_q;
270
271 ProresThreadData *tdata;
272 } ProresContext;
273
274 66600 static void get_slice_data(ProresContext *ctx, const uint16_t *src,
275 ptrdiff_t linesize, int x, int y, int w, int h,
276 int16_t *blocks, uint16_t *emu_buf,
277 int mbs_per_slice, int blocks_per_mb, int is_chroma)
278 {
279 const uint16_t *esrc;
280 66600 const int mb_width = 4 * blocks_per_mb;
281 ptrdiff_t elinesize;
282 int i, j, k;
283
284
2/2
✓ Branch 0 taken 359100 times.
✓ Branch 1 taken 66600 times.
425700 for (i = 0; i < mbs_per_slice; i++, src += mb_width) {
285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 359100 times.
359100 if (x >= w) {
286 memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb
287 * sizeof(*blocks));
288 return;
289 }
290
4/4
✓ Branch 0 taken 358200 times.
✓ Branch 1 taken 900 times.
✓ Branch 2 taken 357600 times.
✓ Branch 3 taken 600 times.
359100 if (x + mb_width <= w && y + 16 <= h) {
291 357600 esrc = src;
292 357600 elinesize = linesize;
293 } else {
294 int bw, bh, pix;
295
296 1500 esrc = emu_buf;
297 1500 elinesize = 16 * sizeof(*emu_buf);
298
299 1500 bw = FFMIN(w - x, mb_width);
300 1500 bh = FFMIN(h - y, 16);
301
302
2/2
✓ Branch 0 taken 11400 times.
✓ Branch 1 taken 1500 times.
12900 for (j = 0; j < bh; j++) {
303 11400 memcpy(emu_buf + j * 16,
304 11400 (const uint8_t*)src + j * linesize,
305 bw * sizeof(*src));
306 11400 pix = emu_buf[j * 16 + bw - 1];
307
2/2
✓ Branch 0 taken 95200 times.
✓ Branch 1 taken 11400 times.
106600 for (k = bw; k < mb_width; k++)
308 95200 emu_buf[j * 16 + k] = pix;
309 }
310
2/2
✓ Branch 0 taken 12600 times.
✓ Branch 1 taken 1500 times.
14100 for (; j < 16; j++)
311 12600 memcpy(emu_buf + j * 16,
312 12600 emu_buf + (bh - 1) * 16,
313 mb_width * sizeof(*emu_buf));
314 }
315
2/2
✓ Branch 0 taken 119700 times.
✓ Branch 1 taken 239400 times.
359100 if (!is_chroma) {
316 119700 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
317 119700 blocks += 64;
318
1/2
✓ Branch 0 taken 119700 times.
✗ Branch 1 not taken.
119700 if (blocks_per_mb > 2) {
319 119700 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
320 119700 blocks += 64;
321 }
322 119700 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
323 119700 blocks += 64;
324
1/2
✓ Branch 0 taken 119700 times.
✗ Branch 1 not taken.
119700 if (blocks_per_mb > 2) {
325 119700 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
326 119700 blocks += 64;
327 }
328 } else {
329 239400 ctx->fdct(&ctx->fdsp, esrc, elinesize, blocks);
330 239400 blocks += 64;
331 239400 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4, elinesize, blocks);
332 239400 blocks += 64;
333
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 239400 times.
239400 if (blocks_per_mb > 2) {
334 ctx->fdct(&ctx->fdsp, esrc + 8, elinesize, blocks);
335 blocks += 64;
336 ctx->fdct(&ctx->fdsp, esrc + elinesize * 4 + 8, elinesize, blocks);
337 blocks += 64;
338 }
339 }
340
341 359100 x += mb_width;
342 }
343 }
344
345 static void get_alpha_data(ProresContext *ctx, const uint16_t *src,
346 ptrdiff_t linesize, int x, int y, int w, int h,
347 int16_t *blocks, int mbs_per_slice, int abits)
348 {
349 const int slice_width = 16 * mbs_per_slice;
350 int i, j, copy_w, copy_h;
351
352 copy_w = FFMIN(w - x, slice_width);
353 copy_h = FFMIN(h - y, 16);
354 for (i = 0; i < copy_h; i++) {
355 memcpy(blocks, src, copy_w * sizeof(*src));
356 if (abits == 8)
357 for (j = 0; j < copy_w; j++)
358 blocks[j] >>= 2;
359 else
360 for (j = 0; j < copy_w; j++)
361 blocks[j] = (blocks[j] << 6) | (blocks[j] >> 4);
362 for (j = copy_w; j < slice_width; j++)
363 blocks[j] = blocks[copy_w - 1];
364 blocks += slice_width;
365 src += linesize >> 1;
366 }
367 for (; i < 16; i++) {
368 memcpy(blocks, blocks - slice_width, slice_width * sizeof(*blocks));
369 blocks += slice_width;
370 }
371 }
372
373 /**
374 * Write an unsigned rice/exp golomb codeword.
375 */
376 26885174 static inline void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
377 {
378 unsigned int rice_order, exp_order, switch_bits, switch_val;
379 int exponent;
380
381 /* number of prefix bits to switch between Rice and expGolomb */
382 26885174 switch_bits = (codebook & 3) + 1;
383 26885174 rice_order = codebook >> 5; /* rice code order */
384 26885174 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
385
386 26885174 switch_val = switch_bits << rice_order;
387
388
2/2
✓ Branch 0 taken 8074309 times.
✓ Branch 1 taken 18810865 times.
26885174 if (val >= switch_val) {
389 8074309 val -= switch_val - (1 << exp_order);
390 8074309 exponent = av_log2(val);
391
392 8074309 put_bits(pb, exponent - exp_order + switch_bits, 0);
393 8074309 put_bits(pb, exponent + 1, val);
394 } else {
395 18810865 exponent = val >> rice_order;
396
397
2/2
✓ Branch 0 taken 4838901 times.
✓ Branch 1 taken 13971964 times.
18810865 if (exponent)
398 4838901 put_bits(pb, exponent, 0);
399 18810865 put_bits(pb, 1, 1);
400
2/2
✓ Branch 0 taken 1904515 times.
✓ Branch 1 taken 16906350 times.
18810865 if (rice_order)
401 1904515 put_sbits(pb, rice_order, val);
402 }
403 26885174 }
404
405 #define GET_SIGN(x) ((x) >> 31)
406 #define MAKE_CODE(x) ((((x)) * 2) ^ GET_SIGN(x))
407
408 33300 static void encode_dcs(PutBitContext *pb, int16_t *blocks,
409 int blocks_per_slice, int scale)
410 {
411 int i;
412 33300 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
413
414 33300 prev_dc = (blocks[0] - 0x4000) / scale;
415 33300 encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
416 33300 sign = 0;
417 33300 codebook = 3;
418 33300 blocks += 64;
419
420
2/2
✓ Branch 0 taken 445500 times.
✓ Branch 1 taken 33300 times.
478800 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
421 445500 dc = (blocks[0] - 0x4000) / scale;
422 445500 delta = dc - prev_dc;
423 445500 new_sign = GET_SIGN(delta);
424 445500 delta = (delta ^ sign) - sign;
425 445500 code = MAKE_CODE(delta);
426 445500 encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
427 445500 codebook = (code + (code & 1)) >> 1;
428 445500 codebook = FFMIN(codebook, 3);
429 445500 sign = new_sign;
430 445500 prev_dc = dc;
431 }
432 33300 }
433
434 33300 static void encode_acs(PutBitContext *pb, int16_t *blocks,
435 int blocks_per_slice,
436 int plane_size_factor,
437 const uint8_t *scan, const int16_t *qmat)
438 {
439 int idx, i;
440 int run, level, run_cb, lev_cb;
441 int max_coeffs, abs_level;
442
443 33300 max_coeffs = blocks_per_slice << 6;
444 33300 run_cb = ff_prores_run_to_cb_index[4];
445 33300 lev_cb = ff_prores_lev_to_cb_index[2];
446 33300 run = 0;
447
448
2/2
✓ Branch 0 taken 2097900 times.
✓ Branch 1 taken 33300 times.
2131200 for (i = 1; i < 64; i++) {
449
2/2
✓ Branch 0 taken 30164400 times.
✓ Branch 1 taken 2097900 times.
32262300 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
450 30164400 level = blocks[idx] / qmat[scan[i]];
451
2/2
✓ Branch 0 taken 13203187 times.
✓ Branch 1 taken 16961213 times.
30164400 if (level) {
452 13203187 abs_level = FFABS(level);
453 13203187 encode_vlc_codeword(pb, ff_prores_ac_codebook[run_cb], run);
454 13203187 encode_vlc_codeword(pb, ff_prores_ac_codebook[lev_cb],
455 abs_level - 1);
456 13203187 put_sbits(pb, 1, GET_SIGN(level));
457
458 13203187 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
459 13203187 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
460 13203187 run = 0;
461 } else {
462 16961213 run++;
463 }
464 }
465 }
466 33300 }
467
468 33300 static void encode_slice_plane(ProresContext *ctx, PutBitContext *pb,
469 const uint16_t *src, ptrdiff_t linesize,
470 int mbs_per_slice, int16_t *blocks,
471 int blocks_per_mb, int plane_size_factor,
472 const int16_t *qmat)
473 {
474 33300 int blocks_per_slice = mbs_per_slice * blocks_per_mb;
475
476 33300 encode_dcs(pb, blocks, blocks_per_slice, qmat[0]);
477 33300 encode_acs(pb, blocks, blocks_per_slice, plane_size_factor,
478 ctx->scantable, qmat);
479 33300 }
480
481 static void put_alpha_diff(PutBitContext *pb, int cur, int prev, int abits)
482 {
483 const int dbits = (abits == 8) ? 4 : 7;
484 const int dsize = 1 << dbits - 1;
485 int diff = cur - prev;
486
487 diff = av_mod_uintp2(diff, abits);
488 if (diff >= (1 << abits) - dsize)
489 diff -= 1 << abits;
490 if (diff < -dsize || diff > dsize || !diff) {
491 put_bits(pb, 1, 1);
492 put_bits(pb, abits, diff);
493 } else {
494 put_bits(pb, 1, 0);
495 put_bits(pb, dbits - 1, FFABS(diff) - 1);
496 put_bits(pb, 1, diff < 0);
497 }
498 }
499
500 static void put_alpha_run(PutBitContext *pb, int run)
501 {
502 if (run) {
503 put_bits(pb, 1, 0);
504 if (run < 0x10)
505 put_bits(pb, 4, run);
506 else
507 put_bits(pb, 15, run);
508 } else {
509 put_bits(pb, 1, 1);
510 }
511 }
512
513 // todo alpha quantisation for high quants
514 static void encode_alpha_plane(ProresContext *ctx, PutBitContext *pb,
515 int mbs_per_slice, uint16_t *blocks,
516 int quant)
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
525 cur = blocks[idx++];
526 put_alpha_diff(pb, cur, prev, abits);
527 prev = cur;
528 do {
529 cur = blocks[idx++];
530 if (cur != prev) {
531 put_alpha_run (pb, run);
532 put_alpha_diff(pb, cur, prev, abits);
533 prev = cur;
534 run = 0;
535 } else {
536 run++;
537 }
538 } while (idx < num_coeffs);
539 if (run)
540 put_alpha_run(pb, run);
541 }
542
543 11100 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
544 PutBitContext *pb,
545 int sizes[4], int x, int y, int quant,
546 int mbs_per_slice)
547 {
548 11100 ProresContext *ctx = avctx->priv_data;
549 int i, xp, yp;
550 11100 int total_size = 0;
551 const uint16_t *src;
552 11100 int slice_width_factor = av_log2(mbs_per_slice);
553 int num_cblocks, pwidth, line_add;
554 ptrdiff_t linesize;
555 int plane_factor, is_chroma;
556 uint16_t *qmat;
557 uint16_t *qmat_chroma;
558
559
1/2
✓ Branch 0 taken 11100 times.
✗ Branch 1 not taken.
11100 if (ctx->pictures_per_frame == 1)
560 11100 line_add = 0;
561 else
562 line_add = ctx->cur_picture_idx ^ !pic->top_field_first;
563
564
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if (ctx->force_quant) {
565 qmat = ctx->quants[0];
566 qmat_chroma = ctx->quants_chroma[0];
567
2/2
✓ Branch 0 taken 8353 times.
✓ Branch 1 taken 2747 times.
11100 } else if (quant < MAX_STORED_Q) {
568 8353 qmat = ctx->quants[quant];
569 8353 qmat_chroma = ctx->quants_chroma[quant];
570 } else {
571 2747 qmat = ctx->custom_q;
572 2747 qmat_chroma = ctx->custom_chroma_q;
573
2/2
✓ Branch 0 taken 175808 times.
✓ Branch 1 taken 2747 times.
178555 for (i = 0; i < 64; i++) {
574 175808 qmat[i] = ctx->quant_mat[i] * quant;
575 175808 qmat_chroma[i] = ctx->quant_chroma_mat[i] * quant;
576 }
577 }
578
579
2/2
✓ Branch 0 taken 33300 times.
✓ Branch 1 taken 11100 times.
44400 for (i = 0; i < ctx->num_planes; i++) {
580
4/4
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
✓ Branch 2 taken 11100 times.
✓ Branch 3 taken 11100 times.
33300 is_chroma = (i == 1 || i == 2);
581 33300 plane_factor = slice_width_factor + 2;
582
2/2
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
33300 if (is_chroma)
583 22200 plane_factor += ctx->chroma_factor - 3;
584
3/4
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22200 times.
33300 if (!is_chroma || ctx->chroma_factor == CFACTOR_Y444) {
585 11100 xp = x << 4;
586 11100 yp = y << 4;
587 11100 num_cblocks = 4;
588 11100 pwidth = avctx->width;
589 } else {
590 22200 xp = x << 3;
591 22200 yp = y << 4;
592 22200 num_cblocks = 2;
593 22200 pwidth = avctx->width >> 1;
594 }
595
596 33300 linesize = pic->linesize[i] * ctx->pictures_per_frame;
597 33300 src = (const uint16_t*)(pic->data[i] + yp * linesize +
598 33300 line_add * pic->linesize[i]) + xp;
599
600
1/2
✓ Branch 0 taken 33300 times.
✗ Branch 1 not taken.
33300 if (i < 3) {
601 33300 get_slice_data(ctx, src, linesize, xp, yp,
602 33300 pwidth, avctx->height / ctx->pictures_per_frame,
603 33300 ctx->blocks[0], ctx->emu_buf,
604 mbs_per_slice, num_cblocks, is_chroma);
605
2/2
✓ Branch 0 taken 11100 times.
✓ Branch 1 taken 22200 times.
33300 if (!is_chroma) {/* luma quant */
606 11100 encode_slice_plane(ctx, pb, src, linesize,
607 11100 mbs_per_slice, ctx->blocks[0],
608 num_cblocks, plane_factor, qmat);
609 } else { /* chroma plane */
610 22200 encode_slice_plane(ctx, pb, src, linesize,
611 22200 mbs_per_slice, ctx->blocks[0],
612 num_cblocks, plane_factor, qmat_chroma);
613 }
614 } else {
615 get_alpha_data(ctx, src, linesize, xp, yp,
616 pwidth, avctx->height / ctx->pictures_per_frame,
617 ctx->blocks[0], mbs_per_slice, ctx->alpha_bits);
618 encode_alpha_plane(ctx, pb, mbs_per_slice, ctx->blocks[0], quant);
619 }
620 33300 flush_put_bits(pb);
621 33300 sizes[i] = put_bytes_output(pb) - total_size;
622 33300 total_size = put_bytes_output(pb);
623 }
624 11100 return total_size;
625 }
626
627 390320122 static inline int estimate_vlc(unsigned codebook, int val)
628 {
629 unsigned int rice_order, exp_order, switch_bits, switch_val;
630 int exponent;
631
632 /* number of prefix bits to switch between Rice and expGolomb */
633 390320122 switch_bits = (codebook & 3) + 1;
634 390320122 rice_order = codebook >> 5; /* rice code order */
635 390320122 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
636
637 390320122 switch_val = switch_bits << rice_order;
638
639
2/2
✓ Branch 0 taken 135366530 times.
✓ Branch 1 taken 254953592 times.
390320122 if (val >= switch_val) {
640 135366530 val -= switch_val - (1 << exp_order);
641 135366530 exponent = av_log2(val);
642
643 135366530 return exponent * 2 - exp_order + switch_bits + 1;
644 } else {
645 254953592 return (val >> rice_order) + rice_order + 1;
646 }
647 }
648
649 379686 static int estimate_dcs(int *error, int16_t *blocks, int blocks_per_slice,
650 int scale)
651 {
652 int i;
653 379686 int codebook = 3, code, dc, prev_dc, delta, sign, new_sign;
654 int bits;
655
656 379686 prev_dc = (blocks[0] - 0x4000) / scale;
657 379686 bits = estimate_vlc(FIRST_DC_CB, MAKE_CODE(prev_dc));
658 379686 sign = 0;
659 379686 codebook = 3;
660 379686 blocks += 64;
661
2/2
✓ Branch 0 taken 199846 times.
✓ Branch 1 taken 179840 times.
379686 *error += FFABS(blocks[0] - 0x4000) % scale;
662
663
2/2
✓ Branch 0 taken 5069986 times.
✓ Branch 1 taken 379686 times.
5449672 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
664 5069986 dc = (blocks[0] - 0x4000) / scale;
665
2/2
✓ Branch 0 taken 2618934 times.
✓ Branch 1 taken 2451052 times.
5069986 *error += FFABS(blocks[0] - 0x4000) % scale;
666 5069986 delta = dc - prev_dc;
667 5069986 new_sign = GET_SIGN(delta);
668 5069986 delta = (delta ^ sign) - sign;
669 5069986 code = MAKE_CODE(delta);
670 5069986 bits += estimate_vlc(ff_prores_dc_codebook[codebook], code);
671 5069986 codebook = (code + (code & 1)) >> 1;
672 5069986 codebook = FFMIN(codebook, 3);
673 5069986 sign = new_sign;
674 5069986 prev_dc = dc;
675 }
676
677 379686 return bits;
678 }
679
680 379686 static int estimate_acs(int *error, int16_t *blocks, int blocks_per_slice,
681 int plane_size_factor,
682 const uint8_t *scan, const int16_t *qmat)
683 {
684 int idx, i;
685 int run, level, run_cb, lev_cb;
686 int max_coeffs, abs_level;
687 379686 int bits = 0;
688
689 379686 max_coeffs = blocks_per_slice << 6;
690 379686 run_cb = ff_prores_run_to_cb_index[4];
691 379686 lev_cb = ff_prores_lev_to_cb_index[2];
692 379686 run = 0;
693
694
2/2
✓ Branch 0 taken 23920218 times.
✓ Branch 1 taken 379686 times.
24299904 for (i = 1; i < 64; i++) {
695
2/2
✓ Branch 0 taken 343329336 times.
✓ Branch 1 taken 23920218 times.
367249554 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
696 343329336 level = blocks[idx] / qmat[scan[i]];
697 343329336 *error += FFABS(blocks[idx]) % qmat[scan[i]];
698
2/2
✓ Branch 0 taken 192435225 times.
✓ Branch 1 taken 150894111 times.
343329336 if (level) {
699 192435225 abs_level = FFABS(level);
700 192435225 bits += estimate_vlc(ff_prores_ac_codebook[run_cb], run);
701 192435225 bits += estimate_vlc(ff_prores_ac_codebook[lev_cb],
702 192435225 abs_level - 1) + 1;
703
704 192435225 run_cb = ff_prores_run_to_cb_index[FFMIN(run, 15)];
705 192435225 lev_cb = ff_prores_lev_to_cb_index[FFMIN(abs_level, 9)];
706 192435225 run = 0;
707 } else {
708 150894111 run++;
709 }
710 }
711 }
712
713 379686 return bits;
714 }
715
716 379686 static int estimate_slice_plane(ProresContext *ctx, int *error, int plane,
717 const uint16_t *src, ptrdiff_t linesize,
718 int mbs_per_slice,
719 int blocks_per_mb, int plane_size_factor,
720 const int16_t *qmat, ProresThreadData *td)
721 {
722 int blocks_per_slice;
723 int bits;
724
725 379686 blocks_per_slice = mbs_per_slice * blocks_per_mb;
726
727 379686 bits = estimate_dcs(error, td->blocks[plane], blocks_per_slice, qmat[0]);
728 379686 bits += estimate_acs(error, td->blocks[plane], blocks_per_slice,
729 plane_size_factor, ctx->scantable, qmat);
730
731 379686 return FFALIGN(bits, 8);
732 }
733
734 static int est_alpha_diff(int cur, int prev, int abits)
735 {
736 const int dbits = (abits == 8) ? 4 : 7;
737 const int dsize = 1 << dbits - 1;
738 int diff = cur - prev;
739
740 diff = av_mod_uintp2(diff, abits);
741 if (diff >= (1 << abits) - dsize)
742 diff -= 1 << abits;
743 if (diff < -dsize || diff > dsize || !diff)
744 return abits + 1;
745 else
746 return dbits + 1;
747 }
748
749 static int estimate_alpha_plane(ProresContext *ctx,
750 const uint16_t *src, ptrdiff_t linesize,
751 int mbs_per_slice, int16_t *blocks)
752 {
753 const int abits = ctx->alpha_bits;
754 const int mask = (1 << abits) - 1;
755 const int num_coeffs = mbs_per_slice * 256;
756 int prev = mask, cur;
757 int idx = 0;
758 int run = 0;
759 int bits;
760
761 cur = blocks[idx++];
762 bits = est_alpha_diff(cur, prev, abits);
763 prev = cur;
764 do {
765 cur = blocks[idx++];
766 if (cur != prev) {
767 if (!run)
768 bits++;
769 else if (run < 0x10)
770 bits += 4;
771 else
772 bits += 15;
773 bits += est_alpha_diff(cur, prev, abits);
774 prev = cur;
775 run = 0;
776 } else {
777 run++;
778 }
779 } while (idx < num_coeffs);
780
781 if (run) {
782 if (run < 0x10)
783 bits += 4;
784 else
785 bits += 15;
786 }
787
788 return bits;
789 }
790
791 11100 static int find_slice_quant(AVCodecContext *avctx,
792 int trellis_node, int x, int y, int mbs_per_slice,
793 ProresThreadData *td)
794 {
795 11100 ProresContext *ctx = avctx->priv_data;
796 int i, q, pq, xp, yp;
797 const uint16_t *src;
798 11100 int slice_width_factor = av_log2(mbs_per_slice);
799 int num_cblocks[MAX_PLANES], pwidth;
800 int plane_factor[MAX_PLANES], is_chroma[MAX_PLANES];
801 11100 const int min_quant = ctx->profile_info->min_quant;
802 11100 const int max_quant = ctx->profile_info->max_quant;
803 int error, bits, bits_limit;
804 int mbs, prev, cur, new_score;
805 int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
806 int overquant;
807 uint16_t *qmat;
808 uint16_t *qmat_chroma;
809 int linesize[4], line_add;
810 11100 int alpha_bits = 0;
811
812
1/2
✓ Branch 0 taken 11100 times.
✗ Branch 1 not taken.
11100 if (ctx->pictures_per_frame == 1)
813 11100 line_add = 0;
814 else
815 line_add = ctx->cur_picture_idx ^ !ctx->pic->top_field_first;
816 11100 mbs = x + mbs_per_slice;
817
818
2/2
✓ Branch 0 taken 33300 times.
✓ Branch 1 taken 11100 times.
44400 for (i = 0; i < ctx->num_planes; i++) {
819
4/4
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
✓ Branch 2 taken 11100 times.
✓ Branch 3 taken 11100 times.
33300 is_chroma[i] = (i == 1 || i == 2);
820 33300 plane_factor[i] = slice_width_factor + 2;
821
2/2
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
33300 if (is_chroma[i])
822 22200 plane_factor[i] += ctx->chroma_factor - 3;
823
3/4
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22200 times.
33300 if (!is_chroma[i] || ctx->chroma_factor == CFACTOR_Y444) {
824 11100 xp = x << 4;
825 11100 yp = y << 4;
826 11100 num_cblocks[i] = 4;
827 11100 pwidth = avctx->width;
828 } else {
829 22200 xp = x << 3;
830 22200 yp = y << 4;
831 22200 num_cblocks[i] = 2;
832 22200 pwidth = avctx->width >> 1;
833 }
834
835 33300 linesize[i] = ctx->pic->linesize[i] * ctx->pictures_per_frame;
836 33300 src = (const uint16_t *)(ctx->pic->data[i] + yp * linesize[i] +
837 33300 line_add * ctx->pic->linesize[i]) + xp;
838
839
1/2
✓ Branch 0 taken 33300 times.
✗ Branch 1 not taken.
33300 if (i < 3) {
840 33300 get_slice_data(ctx, src, linesize[i], xp, yp,
841 33300 pwidth, avctx->height / ctx->pictures_per_frame,
842 33300 td->blocks[i], td->emu_buf,
843 mbs_per_slice, num_cblocks[i], is_chroma[i]);
844 } else {
845 get_alpha_data(ctx, src, linesize[i], xp, yp,
846 pwidth, avctx->height / ctx->pictures_per_frame,
847 td->blocks[i], mbs_per_slice, ctx->alpha_bits);
848 }
849 }
850
851
2/2
✓ Branch 0 taken 77700 times.
✓ Branch 1 taken 11100 times.
88800 for (q = min_quant; q < max_quant + 2; q++) {
852 77700 td->nodes[trellis_node + q].prev_node = -1;
853 77700 td->nodes[trellis_node + q].quant = q;
854 }
855
856
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if (ctx->alpha_bits)
857 alpha_bits = estimate_alpha_plane(ctx, src, linesize[3],
858 mbs_per_slice, td->blocks[3]);
859 // todo: maybe perform coarser quantising to fit into frame size when needed
860
2/2
✓ Branch 0 taken 66600 times.
✓ Branch 1 taken 11100 times.
77700 for (q = min_quant; q <= max_quant; q++) {
861 66600 bits = alpha_bits;
862 66600 error = 0;
863 133200 bits += estimate_slice_plane(ctx, &error, 0,
864 66600 src, linesize[0],
865 mbs_per_slice,
866 num_cblocks[0], plane_factor[0],
867 66600 ctx->quants[q], td); /* estimate luma plane */
868
2/2
✓ Branch 0 taken 133200 times.
✓ Branch 1 taken 66600 times.
199800 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
869 133200 bits += estimate_slice_plane(ctx, &error, i,
870 133200 src, linesize[i],
871 mbs_per_slice,
872 num_cblocks[i], plane_factor[i],
873 133200 ctx->quants_chroma[q], td);
874 }
875
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66600 times.
66600 if (bits > 65000 * 8)
876 error = SCORE_LIMIT;
877
878 66600 slice_bits[q] = bits;
879 66600 slice_score[q] = error;
880 }
881
2/2
✓ Branch 0 taken 3643 times.
✓ Branch 1 taken 7457 times.
11100 if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
882 3643 slice_bits[max_quant + 1] = slice_bits[max_quant];
883 3643 slice_score[max_quant + 1] = slice_score[max_quant] + 1;
884 3643 overquant = max_quant;
885 } else {
886
1/2
✓ Branch 0 taken 59962 times.
✗ Branch 1 not taken.
59962 for (q = max_quant + 1; q < 128; q++) {
887 59962 bits = alpha_bits;
888 59962 error = 0;
889
2/2
✓ Branch 0 taken 44939 times.
✓ Branch 1 taken 15023 times.
59962 if (q < MAX_STORED_Q) {
890 44939 qmat = ctx->quants[q];
891 44939 qmat_chroma = ctx->quants_chroma[q];
892 } else {
893 15023 qmat = td->custom_q;
894 15023 qmat_chroma = td->custom_chroma_q;
895
2/2
✓ Branch 0 taken 961472 times.
✓ Branch 1 taken 15023 times.
976495 for (i = 0; i < 64; i++) {
896 961472 qmat[i] = ctx->quant_mat[i] * q;
897 961472 qmat_chroma[i] = ctx->quant_chroma_mat[i] * q;
898 }
899 }
900 119924 bits += estimate_slice_plane(ctx, &error, 0,
901 59962 src, linesize[0],
902 mbs_per_slice,
903 num_cblocks[0], plane_factor[0],
904 qmat, td);/* estimate luma plane */
905
2/2
✓ Branch 0 taken 119924 times.
✓ Branch 1 taken 59962 times.
179886 for (i = 1; i < ctx->num_planes - !!ctx->alpha_bits; i++) { /* estimate chroma plane */
906 119924 bits += estimate_slice_plane(ctx, &error, i,
907 119924 src, linesize[i],
908 mbs_per_slice,
909 num_cblocks[i], plane_factor[i],
910 qmat_chroma, td);
911 }
912
2/2
✓ Branch 0 taken 7457 times.
✓ Branch 1 taken 52505 times.
59962 if (bits <= ctx->bits_per_mb * mbs_per_slice)
913 7457 break;
914 }
915
916 7457 slice_bits[max_quant + 1] = bits;
917 7457 slice_score[max_quant + 1] = error;
918 7457 overquant = q;
919 }
920 11100 td->nodes[trellis_node + max_quant + 1].quant = overquant;
921
922 11100 bits_limit = mbs * ctx->bits_per_mb;
923
2/2
✓ Branch 0 taken 77700 times.
✓ Branch 1 taken 11100 times.
88800 for (pq = min_quant; pq < max_quant + 2; pq++) {
924 77700 prev = trellis_node - TRELLIS_WIDTH + pq;
925
926
2/2
✓ Branch 0 taken 543900 times.
✓ Branch 1 taken 77700 times.
621600 for (q = min_quant; q < max_quant + 2; q++) {
927 543900 cur = trellis_node + q;
928
929 543900 bits = td->nodes[prev].bits + slice_bits[q];
930 543900 error = slice_score[q];
931
2/2
✓ Branch 0 taken 438632 times.
✓ Branch 1 taken 105268 times.
543900 if (bits > bits_limit)
932 438632 error = SCORE_LIMIT;
933
934
4/4
✓ Branch 0 taken 268352 times.
✓ Branch 1 taken 275548 times.
✓ Branch 2 taken 98480 times.
✓ Branch 3 taken 169872 times.
543900 if (td->nodes[prev].score < SCORE_LIMIT && error < SCORE_LIMIT)
935 98480 new_score = td->nodes[prev].score + error;
936 else
937 445420 new_score = SCORE_LIMIT;
938
2/2
✓ Branch 0 taken 466200 times.
✓ Branch 1 taken 77700 times.
543900 if (td->nodes[cur].prev_node == -1 ||
939
2/2
✓ Branch 0 taken 427864 times.
✓ Branch 1 taken 38336 times.
466200 td->nodes[cur].score >= new_score) {
940
941 505564 td->nodes[cur].bits = bits;
942 505564 td->nodes[cur].score = new_score;
943 505564 td->nodes[cur].prev_node = prev;
944 }
945 }
946 }
947
948 11100 error = td->nodes[trellis_node + min_quant].score;
949 11100 pq = trellis_node + min_quant;
950
2/2
✓ Branch 0 taken 66600 times.
✓ Branch 1 taken 11100 times.
77700 for (q = min_quant + 1; q < max_quant + 2; q++) {
951
2/2
✓ Branch 0 taken 52033 times.
✓ Branch 1 taken 14567 times.
66600 if (td->nodes[trellis_node + q].score <= error) {
952 52033 error = td->nodes[trellis_node + q].score;
953 52033 pq = trellis_node + q;
954 }
955 }
956
957 11100 return pq;
958 }
959
960 2850 static int find_quant_thread(AVCodecContext *avctx, void *arg,
961 int jobnr, int threadnr)
962 {
963 2850 ProresContext *ctx = avctx->priv_data;
964 2850 ProresThreadData *td = ctx->tdata + threadnr;
965 2850 int mbs_per_slice = ctx->mbs_per_slice;
966 2850 int x, y = jobnr, mb, q = 0;
967
968
2/2
✓ Branch 0 taken 11100 times.
✓ Branch 1 taken 2850 times.
13950 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
969
2/2
✓ Branch 0 taken 5850 times.
✓ Branch 1 taken 11100 times.
16950 while (ctx->mb_width - x < mbs_per_slice)
970 5850 mbs_per_slice >>= 1;
971 11100 q = find_slice_quant(avctx,
972 11100 (mb + 1) * TRELLIS_WIDTH, x, y,
973 mbs_per_slice, td);
974 }
975
976
2/2
✓ Branch 0 taken 11100 times.
✓ Branch 1 taken 2850 times.
13950 for (x = ctx->slices_width - 1; x >= 0; x--) {
977 11100 ctx->slice_q[x + y * ctx->slices_width] = td->nodes[q].quant;
978 11100 q = td->nodes[q].prev_node;
979 }
980
981 2850 return 0;
982 }
983
984 200 static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
985 const AVFrame *pic, int *got_packet)
986 {
987 200 ProresContext *ctx = avctx->priv_data;
988 uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;
989 uint8_t *picture_size_pos;
990 PutBitContext pb;
991 200 int x, y, i, mb, q = 0;
992 200 int sizes[4] = { 0 };
993 200 int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);
994 int frame_size, picture_size, slice_size;
995 int pkt_size, ret;
996 200 int max_slice_size = (ctx->frame_size_upper_bound - 200) / (ctx->pictures_per_frame * ctx->slices_per_picture + 1);
997 uint8_t frame_flags;
998
999 200 ctx->pic = pic;
1000 200 pkt_size = ctx->frame_size_upper_bound;
1001
1002
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 200 times.
200 if ((ret = ff_alloc_packet(avctx, pkt, pkt_size + AV_INPUT_BUFFER_MIN_SIZE)) < 0)
1003 return ret;
1004
1005 200 orig_buf = pkt->data;
1006
1007 // frame atom
1008 200 orig_buf += 4; // frame size
1009 200 bytestream_put_be32 (&orig_buf, FRAME_ID); // frame container ID
1010 200 buf = orig_buf;
1011
1012 // frame header
1013 200 tmp = buf;
1014 200 buf += 2; // frame header size will be stored here
1015 200 bytestream_put_be16 (&buf, 0); // version 1
1016 200 bytestream_put_buffer(&buf, ctx->vendor, 4);
1017 200 bytestream_put_be16 (&buf, avctx->width);
1018 200 bytestream_put_be16 (&buf, avctx->height);
1019
1020 200 frame_flags = ctx->chroma_factor << 6;
1021
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
200 if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT)
1022 frame_flags |= pic->top_field_first ? 0x04 : 0x08;
1023 200 bytestream_put_byte (&buf, frame_flags);
1024
1025 200 bytestream_put_byte (&buf, 0); // reserved
1026 200 bytestream_put_byte (&buf, pic->color_primaries);
1027 200 bytestream_put_byte (&buf, pic->color_trc);
1028 200 bytestream_put_byte (&buf, pic->colorspace);
1029 200 bytestream_put_byte (&buf, 0x40 | (ctx->alpha_bits >> 3));
1030 200 bytestream_put_byte (&buf, 0); // reserved
1031
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 if (ctx->quant_sel != QUANT_MAT_DEFAULT) {
1032 200 bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present
1033 // luma quantisation matrix
1034
2/2
✓ Branch 0 taken 12800 times.
✓ Branch 1 taken 200 times.
13000 for (i = 0; i < 64; i++)
1035 12800 bytestream_put_byte(&buf, ctx->quant_mat[i]);
1036 // chroma quantisation matrix
1037
2/2
✓ Branch 0 taken 12800 times.
✓ Branch 1 taken 200 times.
13000 for (i = 0; i < 64; i++)
1038 12800 bytestream_put_byte(&buf, ctx->quant_mat[i]);
1039 } else {
1040 bytestream_put_byte (&buf, 0x00); // matrix flags - default matrices are used
1041 }
1042 200 bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size
1043
1044 200 for (ctx->cur_picture_idx = 0;
1045
2/2
✓ Branch 0 taken 200 times.
✓ Branch 1 taken 200 times.
400 ctx->cur_picture_idx < ctx->pictures_per_frame;
1046 200 ctx->cur_picture_idx++) {
1047 // picture header
1048 200 picture_size_pos = buf + 1;
1049 200 bytestream_put_byte (&buf, 0x40); // picture header size (in bits)
1050 200 buf += 4; // picture data size will be stored here
1051 200 bytestream_put_be16 (&buf, ctx->slices_per_picture);
1052 200 bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs
1053
1054 // seek table - will be filled during slice encoding
1055 200 slice_sizes = buf;
1056 200 buf += ctx->slices_per_picture * 2;
1057
1058 // slices
1059
1/2
✓ Branch 0 taken 200 times.
✗ Branch 1 not taken.
200 if (!ctx->force_quant) {
1060 200 ret = avctx->execute2(avctx, find_quant_thread, (void*)pic, NULL,
1061 ctx->mb_height);
1062
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 200 times.
200 if (ret)
1063 return ret;
1064 }
1065
1066
2/2
✓ Branch 0 taken 2850 times.
✓ Branch 1 taken 200 times.
3050 for (y = 0; y < ctx->mb_height; y++) {
1067 2850 int mbs_per_slice = ctx->mbs_per_slice;
1068
2/2
✓ Branch 0 taken 11100 times.
✓ Branch 1 taken 2850 times.
13950 for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {
1069 22200 q = ctx->force_quant ? ctx->force_quant
1070
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 : ctx->slice_q[mb + y * ctx->slices_width];
1071
1072
2/2
✓ Branch 0 taken 5850 times.
✓ Branch 1 taken 11100 times.
16950 while (ctx->mb_width - x < mbs_per_slice)
1073 5850 mbs_per_slice >>= 1;
1074
1075 11100 bytestream_put_byte(&buf, slice_hdr_size << 3);
1076 11100 slice_hdr = buf;
1077 11100 buf += slice_hdr_size - 1;
1078
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if (pkt_size <= buf - orig_buf + 2 * max_slice_size) {
1079 uint8_t *start = pkt->data;
1080 // Recompute new size according to max_slice_size
1081 // and deduce delta
1082 int delta = 200 + (ctx->pictures_per_frame *
1083 ctx->slices_per_picture + 1) *
1084 max_slice_size - pkt_size;
1085
1086 delta = FFMAX(delta, 2 * max_slice_size);
1087 ctx->frame_size_upper_bound += delta;
1088
1089 if (!ctx->warn) {
1090 avpriv_request_sample(avctx,
1091 "Packet too small: is %i,"
1092 " needs %i (slice: %i). "
1093 "Correct allocation",
1094 pkt_size, delta, max_slice_size);
1095 ctx->warn = 1;
1096 }
1097
1098 ret = av_grow_packet(pkt, delta);
1099 if (ret < 0)
1100 return ret;
1101
1102 pkt_size += delta;
1103 // restore pointers
1104 orig_buf = pkt->data + (orig_buf - start);
1105 buf = pkt->data + (buf - start);
1106 picture_size_pos = pkt->data + (picture_size_pos - start);
1107 slice_sizes = pkt->data + (slice_sizes - start);
1108 slice_hdr = pkt->data + (slice_hdr - start);
1109 tmp = pkt->data + (tmp - start);
1110 }
1111 11100 init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)));
1112 11100 ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,
1113 mbs_per_slice);
1114
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11100 times.
11100 if (ret < 0)
1115 return ret;
1116
1117 11100 bytestream_put_byte(&slice_hdr, q);
1118 11100 slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];
1119
2/2
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 11100 times.
33300 for (i = 0; i < ctx->num_planes - 1; i++) {
1120 22200 bytestream_put_be16(&slice_hdr, sizes[i]);
1121 22200 slice_size += sizes[i];
1122 }
1123 11100 bytestream_put_be16(&slice_sizes, slice_size);
1124 11100 buf += slice_size - slice_hdr_size;
1125
2/2
✓ Branch 0 taken 216 times.
✓ Branch 1 taken 10884 times.
11100 if (max_slice_size < slice_size)
1126 216 max_slice_size = slice_size;
1127 }
1128 }
1129
1130 200 picture_size = buf - (picture_size_pos - 1);
1131 200 bytestream_put_be32(&picture_size_pos, picture_size);
1132 }
1133
1134 200 orig_buf -= 8;
1135 200 frame_size = buf - orig_buf;
1136 200 bytestream_put_be32(&orig_buf, frame_size);
1137
1138 200 pkt->size = frame_size;
1139 200 pkt->flags |= AV_PKT_FLAG_KEY;
1140 200 *got_packet = 1;
1141
1142 200 return 0;
1143 }
1144
1145 4 static av_cold int encode_close(AVCodecContext *avctx)
1146 {
1147 4 ProresContext *ctx = avctx->priv_data;
1148 int i;
1149
1150
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ctx->tdata) {
1151
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (i = 0; i < avctx->thread_count; i++)
1152 4 av_freep(&ctx->tdata[i].nodes);
1153 }
1154 4 av_freep(&ctx->tdata);
1155 4 av_freep(&ctx->slice_q);
1156
1157 4 return 0;
1158 }
1159
1160 957600 static void prores_fdct(FDCTDSPContext *fdsp, const uint16_t *src,
1161 ptrdiff_t linesize, int16_t *block)
1162 {
1163 int x, y;
1164 957600 const uint16_t *tsrc = src;
1165
1166
2/2
✓ Branch 0 taken 7660800 times.
✓ Branch 1 taken 957600 times.
8618400 for (y = 0; y < 8; y++) {
1167
2/2
✓ Branch 0 taken 61286400 times.
✓ Branch 1 taken 7660800 times.
68947200 for (x = 0; x < 8; x++)
1168 61286400 block[y * 8 + x] = tsrc[x];
1169 7660800 tsrc += linesize >> 1;
1170 }
1171 957600 fdsp->fdct(block);
1172 957600 }
1173
1174 4 static av_cold int encode_init(AVCodecContext *avctx)
1175 {
1176 4 ProresContext *ctx = avctx->priv_data;
1177 int mps;
1178 int i, j;
1179 int min_quant, max_quant;
1180 4 int interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
1181
1182 4 avctx->bits_per_raw_sample = 10;
1183
1184 4 ctx->fdct = prores_fdct;
1185 4 ctx->scantable = interlaced ? ff_prores_interlaced_scan
1186
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 : ff_prores_progressive_scan;
1187 4 ff_fdctdsp_init(&ctx->fdsp, avctx);
1188
1189 4 mps = ctx->mbs_per_slice;
1190
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (mps & (mps - 1)) {
1191 av_log(avctx, AV_LOG_ERROR,
1192 "there should be an integer power of two MBs per slice\n");
1193 return AVERROR(EINVAL);
1194 }
1195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (ctx->profile == PRORES_PROFILE_AUTO) {
1196 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
1197 ctx->profile = (desc->flags & AV_PIX_FMT_FLAG_ALPHA ||
1198 !(desc->log2_chroma_w + desc->log2_chroma_h))
1199 ? PRORES_PROFILE_4444 : PRORES_PROFILE_HQ;
1200 av_log(avctx, AV_LOG_INFO, "Autoselected %s. It can be overridden "
1201 "through -profile option.\n", ctx->profile == PRORES_PROFILE_4444
1202 ? "4:4:4:4 profile because of the used input colorspace"
1203 : "HQ profile to keep best quality");
1204 }
1205
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
4 if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_ALPHA) {
1206 if (ctx->profile != PRORES_PROFILE_4444 &&
1207 ctx->profile != PRORES_PROFILE_4444XQ) {
1208 // force alpha and warn
1209 av_log(avctx, AV_LOG_WARNING, "Profile selected will not "
1210 "encode alpha. Override with -profile if needed.\n");
1211 ctx->alpha_bits = 0;
1212 }
1213 if (ctx->alpha_bits & 7) {
1214 av_log(avctx, AV_LOG_ERROR, "alpha bits should be 0, 8 or 16\n");
1215 return AVERROR(EINVAL);
1216 }
1217 avctx->bits_per_coded_sample = 32;
1218 } else {
1219 4 ctx->alpha_bits = 0;
1220 }
1221
1222 8 ctx->chroma_factor = avctx->pix_fmt == AV_PIX_FMT_YUV422P10
1223 ? CFACTOR_Y422
1224
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 : CFACTOR_Y444;
1225 4 ctx->profile_info = prores_profile_info + ctx->profile;
1226
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 ctx->num_planes = 3 + !!ctx->alpha_bits;
1227
1228 4 ctx->mb_width = FFALIGN(avctx->width, 16) >> 4;
1229
1230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (interlaced)
1231 ctx->mb_height = FFALIGN(avctx->height, 32) >> 5;
1232 else
1233 4 ctx->mb_height = FFALIGN(avctx->height, 16) >> 4;
1234
1235 4 ctx->slices_width = ctx->mb_width / mps;
1236 4 ctx->slices_width += av_popcount(ctx->mb_width - ctx->slices_width * mps);
1237 4 ctx->slices_per_picture = ctx->mb_height * ctx->slices_width;
1238 4 ctx->pictures_per_frame = 1 + interlaced;
1239
1240
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (ctx->quant_sel == -1) {
1241 4 ctx->quant_mat = prores_quant_matrices[ctx->profile_info->quant];
1242 4 ctx->quant_chroma_mat = prores_quant_matrices[ctx->profile_info->quant_chroma];
1243 } else {
1244 ctx->quant_mat = prores_quant_matrices[ctx->quant_sel];
1245 ctx->quant_chroma_mat = prores_quant_matrices[ctx->quant_sel];
1246 }
1247
1248
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (strlen(ctx->vendor) != 4) {
1249 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
1250 return AVERROR_INVALIDDATA;
1251 }
1252
1253 4 ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
1254
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!ctx->force_quant) {
1255
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (!ctx->bits_per_mb) {
1256
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 for (i = 0; i < NUM_MB_LIMITS - 1; i++)
1257 4 if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
1258
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 ctx->pictures_per_frame)
1259 4 break;
1260 4 ctx->bits_per_mb = ctx->profile_info->br_tab[i];
1261
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (ctx->alpha_bits)
1262 ctx->bits_per_mb *= 20;
1263 } else if (ctx->bits_per_mb < 128) {
1264 av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
1265 return AVERROR_INVALIDDATA;
1266 }
1267
1268 4 min_quant = ctx->profile_info->min_quant;
1269 4 max_quant = ctx->profile_info->max_quant;
1270
2/2
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 4 times.
64 for (i = min_quant; i < MAX_STORED_Q; i++) {
1271
2/2
✓ Branch 0 taken 3840 times.
✓ Branch 1 taken 60 times.
3900 for (j = 0; j < 64; j++) {
1272 3840 ctx->quants[i][j] = ctx->quant_mat[j] * i;
1273 3840 ctx->quants_chroma[i][j] = ctx->quant_chroma_mat[j] * i;
1274 }
1275 }
1276
1277 4 ctx->slice_q = av_malloc(ctx->slices_per_picture * sizeof(*ctx->slice_q));
1278
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!ctx->slice_q) {
1279 encode_close(avctx);
1280 return AVERROR(ENOMEM);
1281 }
1282
1283 4 ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
1284
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!ctx->tdata) {
1285 encode_close(avctx);
1286 return AVERROR(ENOMEM);
1287 }
1288
1289
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 4 times.
8 for (j = 0; j < avctx->thread_count; j++) {
1290 8 ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
1291 4 * TRELLIS_WIDTH
1292 * sizeof(*ctx->tdata->nodes));
1293
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!ctx->tdata[j].nodes) {
1294 encode_close(avctx);
1295 return AVERROR(ENOMEM);
1296 }
1297
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 4 times.
32 for (i = min_quant; i < max_quant + 2; i++) {
1298 28 ctx->tdata[j].nodes[i].prev_node = -1;
1299 28 ctx->tdata[j].nodes[i].bits = 0;
1300 28 ctx->tdata[j].nodes[i].score = 0;
1301 }
1302 }
1303 } else {
1304 int ls = 0;
1305 int ls_chroma = 0;
1306
1307 if (ctx->force_quant > 64) {
1308 av_log(avctx, AV_LOG_ERROR, "too large quantiser, maximum is 64\n");
1309 return AVERROR_INVALIDDATA;
1310 }
1311
1312 for (j = 0; j < 64; j++) {
1313 ctx->quants[0][j] = ctx->quant_mat[j] * ctx->force_quant;
1314 ctx->quants_chroma[0][j] = ctx->quant_chroma_mat[j] * ctx->force_quant;
1315 ls += av_log2((1 << 11) / ctx->quants[0][j]) * 2 + 1;
1316 ls_chroma += av_log2((1 << 11) / ctx->quants_chroma[0][j]) * 2 + 1;
1317 }
1318
1319 ctx->bits_per_mb = ls * 4 + ls_chroma * 4;
1320 if (ctx->chroma_factor == CFACTOR_Y444)
1321 ctx->bits_per_mb += ls_chroma * 4;
1322 }
1323
1324 4 ctx->frame_size_upper_bound = (ctx->pictures_per_frame *
1325 4 ctx->slices_per_picture + 1) *
1326 4 (2 + 2 * ctx->num_planes +
1327 4 (mps * ctx->bits_per_mb) / 8)
1328 4 + 200;
1329
1330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (ctx->alpha_bits) {
1331 // The alpha plane is run-coded and might exceed the bit budget.
1332 ctx->frame_size_upper_bound += (ctx->pictures_per_frame *
1333 ctx->slices_per_picture + 1) *
1334 /* num pixels per slice */ (ctx->mbs_per_slice * 256 *
1335 /* bits per pixel */ (1 + ctx->alpha_bits + 1) + 7 >> 3);
1336 }
1337
1338 4 avctx->codec_tag = ctx->profile_info->tag;
1339
1340
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 av_log(avctx, AV_LOG_DEBUG,
1341 "profile %d, %d slices, interlacing: %s, %d bits per MB\n",
1342 4 ctx->profile, ctx->slices_per_picture * ctx->pictures_per_frame,
1343 interlaced ? "yes" : "no", ctx->bits_per_mb);
1344 4 av_log(avctx, AV_LOG_DEBUG, "frame size upper bound: %d\n",
1345 ctx->frame_size_upper_bound);
1346
1347 4 return 0;
1348 }
1349
1350 #define OFFSET(x) offsetof(ProresContext, x)
1351 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
1352
1353 static const AVOption options[] = {
1354 { "mbs_per_slice", "macroblocks per slice", OFFSET(mbs_per_slice),
1355 AV_OPT_TYPE_INT, { .i64 = 8 }, 1, MAX_MBS_PER_SLICE, VE },
1356 { "profile", NULL, OFFSET(profile), AV_OPT_TYPE_INT,
1357 { .i64 = PRORES_PROFILE_AUTO },
1358 PRORES_PROFILE_AUTO, PRORES_PROFILE_4444XQ, VE, "profile" },
1359 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_AUTO },
1360 0, 0, VE, "profile" },
1361 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_PROXY },
1362 0, 0, VE, "profile" },
1363 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_LT },
1364 0, 0, VE, "profile" },
1365 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_STANDARD },
1366 0, 0, VE, "profile" },
1367 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_HQ },
1368 0, 0, VE, "profile" },
1369 { "4444", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444 },
1370 0, 0, VE, "profile" },
1371 { "4444xq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = PRORES_PROFILE_4444XQ },
1372 0, 0, VE, "profile" },
1373 { "vendor", "vendor ID", OFFSET(vendor),
1374 AV_OPT_TYPE_STRING, { .str = "Lavc" }, 0, 0, VE },
1375 { "bits_per_mb", "desired bits per macroblock", OFFSET(bits_per_mb),
1376 AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 8192, VE },
1377 { "quant_mat", "quantiser matrix", OFFSET(quant_sel), AV_OPT_TYPE_INT,
1378 { .i64 = -1 }, -1, QUANT_MAT_DEFAULT, VE, "quant_mat" },
1379 { "auto", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = -1 },
1380 0, 0, VE, "quant_mat" },
1381 { "proxy", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_PROXY },
1382 0, 0, VE, "quant_mat" },
1383 { "lt", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_LT },
1384 0, 0, VE, "quant_mat" },
1385 { "standard", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_STANDARD },
1386 0, 0, VE, "quant_mat" },
1387 { "hq", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_HQ },
1388 0, 0, VE, "quant_mat" },
1389 { "default", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = QUANT_MAT_DEFAULT },
1390 0, 0, VE, "quant_mat" },
1391 { "alpha_bits", "bits for alpha plane", OFFSET(alpha_bits), AV_OPT_TYPE_INT,
1392 { .i64 = 16 }, 0, 16, VE },
1393 { NULL }
1394 };
1395
1396 static const AVClass proresenc_class = {
1397 .class_name = "ProRes encoder",
1398 .item_name = av_default_item_name,
1399 .option = options,
1400 .version = LIBAVUTIL_VERSION_INT,
1401 };
1402
1403 const AVCodec ff_prores_ks_encoder = {
1404 .name = "prores_ks",
1405 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)"),
1406 .type = AVMEDIA_TYPE_VIDEO,
1407 .id = AV_CODEC_ID_PRORES,
1408 .priv_data_size = sizeof(ProresContext),
1409 .init = encode_init,
1410 .close = encode_close,
1411 .encode2 = encode_frame,
1412 .capabilities = AV_CODEC_CAP_SLICE_THREADS | AV_CODEC_CAP_FRAME_THREADS,
1413 .pix_fmts = (const enum AVPixelFormat[]) {
1414 AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
1415 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
1416 },
1417 .priv_class = &proresenc_class,
1418 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
1419 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
1420 };
1421