FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/proresenc_anatoliy.c
Date: 2025-06-01 09:29:47
Exec Total Coverage
Lines: 347 450 77.1%
Functions: 17 21 81.0%
Branches: 139 202 68.8%

Line Branch Exec Source
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 /**
25 * @file
26 * Apple ProRes encoder (Anatoliy Wasserman version)
27 * Known FOURCCs: 'ap4h' (444), 'apch' (HQ), 'apcn' (422), 'apcs' (LT), 'acpo' (Proxy)
28 */
29
30 #include "libavutil/avassert.h"
31 #include "libavutil/mem.h"
32 #include "libavutil/mem_internal.h"
33 #include "libavutil/opt.h"
34 #include "avcodec.h"
35 #include "codec_internal.h"
36 #include "encode.h"
37 #include "profiles.h"
38 #include "proresdata.h"
39 #include "put_bits.h"
40 #include "bytestream.h"
41 #include "fdctdsp.h"
42
43 #define DEFAULT_SLICE_MB_WIDTH 8
44
45 static const AVProfile profiles[] = {
46 { AV_PROFILE_PRORES_PROXY, "apco"},
47 { AV_PROFILE_PRORES_LT, "apcs"},
48 { AV_PROFILE_PRORES_STANDARD, "apcn"},
49 { AV_PROFILE_PRORES_HQ, "apch"},
50 { AV_PROFILE_PRORES_4444, "ap4h"},
51 { AV_PROFILE_PRORES_XQ, "ap4x"},
52 { AV_PROFILE_UNKNOWN }
53 };
54
55 static const int qp_start_table[] = { 8, 3, 2, 1, 1, 1};
56 static const int qp_end_table[] = { 13, 9, 6, 6, 5, 4};
57 static const int bitrate_table[] = { 1000, 2100, 3500, 5400, 7000, 10000};
58
59 static const int valid_primaries[] = { AVCOL_PRI_RESERVED0, AVCOL_PRI_BT709, AVCOL_PRI_UNSPECIFIED, AVCOL_PRI_BT470BG,
60 AVCOL_PRI_SMPTE170M, AVCOL_PRI_BT2020, AVCOL_PRI_SMPTE431, AVCOL_PRI_SMPTE432, INT_MAX };
61 static const int valid_trc[] = { AVCOL_TRC_RESERVED0, AVCOL_TRC_BT709, AVCOL_TRC_UNSPECIFIED, AVCOL_TRC_SMPTE2084,
62 AVCOL_TRC_ARIB_STD_B67, INT_MAX };
63 static const int valid_colorspace[] = { AVCOL_SPC_BT709, AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_SMPTE170M,
64 AVCOL_SPC_BT2020_NCL, INT_MAX };
65
66 static const uint8_t QMAT_LUMA[6][64] = {
67 {
68 4, 7, 9, 11, 13, 14, 15, 63,
69 7, 7, 11, 12, 14, 15, 63, 63,
70 9, 11, 13, 14, 15, 63, 63, 63,
71 11, 11, 13, 14, 63, 63, 63, 63,
72 11, 13, 14, 63, 63, 63, 63, 63,
73 13, 14, 63, 63, 63, 63, 63, 63,
74 13, 63, 63, 63, 63, 63, 63, 63,
75 63, 63, 63, 63, 63, 63, 63, 63
76 }, {
77 4, 5, 6, 7, 9, 11, 13, 15,
78 5, 5, 7, 8, 11, 13, 15, 17,
79 6, 7, 9, 11, 13, 15, 15, 17,
80 7, 7, 9, 11, 13, 15, 17, 19,
81 7, 9, 11, 13, 14, 16, 19, 23,
82 9, 11, 13, 14, 16, 19, 23, 29,
83 9, 11, 13, 15, 17, 21, 28, 35,
84 11, 13, 16, 17, 21, 28, 35, 41
85 }, {
86 4, 4, 5, 5, 6, 7, 7, 9,
87 4, 4, 5, 6, 7, 7, 9, 9,
88 5, 5, 6, 7, 7, 9, 9, 10,
89 5, 5, 6, 7, 7, 9, 9, 10,
90 5, 6, 7, 7, 8, 9, 10, 12,
91 6, 7, 7, 8, 9, 10, 12, 15,
92 6, 7, 7, 9, 10, 11, 14, 17,
93 7, 7, 9, 10, 11, 14, 17, 21
94 }, {
95 4, 4, 4, 4, 4, 4, 4, 4,
96 4, 4, 4, 4, 4, 4, 4, 4,
97 4, 4, 4, 4, 4, 4, 4, 4,
98 4, 4, 4, 4, 4, 4, 4, 5,
99 4, 4, 4, 4, 4, 4, 5, 5,
100 4, 4, 4, 4, 4, 5, 5, 6,
101 4, 4, 4, 4, 5, 5, 6, 7,
102 4, 4, 4, 4, 5, 6, 7, 7
103 }, { /* 444 */
104 4, 4, 4, 4, 4, 4, 4, 4,
105 4, 4, 4, 4, 4, 4, 4, 4,
106 4, 4, 4, 4, 4, 4, 4, 4,
107 4, 4, 4, 4, 4, 4, 4, 5,
108 4, 4, 4, 4, 4, 4, 5, 5,
109 4, 4, 4, 4, 4, 5, 5, 6,
110 4, 4, 4, 4, 5, 5, 6, 7,
111 4, 4, 4, 4, 5, 6, 7, 7
112 }, { /* 444 XQ */
113 2, 2, 2, 2, 2, 2, 2, 2,
114 2, 2, 2, 2, 2, 2, 2, 2,
115 2, 2, 2, 2, 2, 2, 2, 2,
116 2, 2, 2, 2, 2, 2, 2, 3,
117 2, 2, 2, 2, 2, 2, 3, 3,
118 2, 2, 2, 2, 2, 3, 3, 3,
119 2, 2, 2, 2, 3, 3, 3, 4,
120 2, 2, 2, 2, 3, 3, 4, 4,
121 }
122 };
123
124 static const uint8_t QMAT_CHROMA[6][64] = {
125 {
126 4, 7, 9, 11, 13, 14, 63, 63,
127 7, 7, 11, 12, 14, 63, 63, 63,
128 9, 11, 13, 14, 63, 63, 63, 63,
129 11, 11, 13, 14, 63, 63, 63, 63,
130 11, 13, 14, 63, 63, 63, 63, 63,
131 13, 14, 63, 63, 63, 63, 63, 63,
132 13, 63, 63, 63, 63, 63, 63, 63,
133 63, 63, 63, 63, 63, 63, 63, 63
134 }, {
135 4, 5, 6, 7, 9, 11, 13, 15,
136 5, 5, 7, 8, 11, 13, 15, 17,
137 6, 7, 9, 11, 13, 15, 15, 17,
138 7, 7, 9, 11, 13, 15, 17, 19,
139 7, 9, 11, 13, 14, 16, 19, 23,
140 9, 11, 13, 14, 16, 19, 23, 29,
141 9, 11, 13, 15, 17, 21, 28, 35,
142 11, 13, 16, 17, 21, 28, 35, 41
143 }, {
144 4, 4, 5, 5, 6, 7, 7, 9,
145 4, 4, 5, 6, 7, 7, 9, 9,
146 5, 5, 6, 7, 7, 9, 9, 10,
147 5, 5, 6, 7, 7, 9, 9, 10,
148 5, 6, 7, 7, 8, 9, 10, 12,
149 6, 7, 7, 8, 9, 10, 12, 15,
150 6, 7, 7, 9, 10, 11, 14, 17,
151 7, 7, 9, 10, 11, 14, 17, 21
152 }, {
153 4, 4, 4, 4, 4, 4, 4, 4,
154 4, 4, 4, 4, 4, 4, 4, 4,
155 4, 4, 4, 4, 4, 4, 4, 4,
156 4, 4, 4, 4, 4, 4, 4, 5,
157 4, 4, 4, 4, 4, 4, 5, 5,
158 4, 4, 4, 4, 4, 5, 5, 6,
159 4, 4, 4, 4, 5, 5, 6, 7,
160 4, 4, 4, 4, 5, 6, 7, 7
161 }, { /* 444 */
162 4, 4, 4, 4, 4, 4, 4, 4,
163 4, 4, 4, 4, 4, 4, 4, 4,
164 4, 4, 4, 4, 4, 4, 4, 4,
165 4, 4, 4, 4, 4, 4, 4, 5,
166 4, 4, 4, 4, 4, 4, 5, 5,
167 4, 4, 4, 4, 4, 5, 5, 6,
168 4, 4, 4, 4, 5, 5, 6, 7,
169 4, 4, 4, 4, 5, 6, 7, 7
170 }, { /* 444 xq */
171 4, 4, 4, 4, 4, 4, 4, 4,
172 4, 4, 4, 4, 4, 4, 4, 4,
173 4, 4, 4, 4, 4, 4, 4, 4,
174 4, 4, 4, 4, 4, 4, 4, 5,
175 4, 4, 4, 4, 4, 4, 5, 5,
176 4, 4, 4, 4, 4, 5, 5, 6,
177 4, 4, 4, 4, 5, 5, 6, 7,
178 4, 4, 4, 4, 5, 6, 7, 7
179 }
180 };
181
182
183 typedef struct {
184 AVClass *class;
185 FDCTDSPContext fdsp;
186 uint8_t* fill_y;
187 uint8_t* fill_u;
188 uint8_t* fill_v;
189 uint8_t* fill_a;
190
191 int qmat_luma[16][64];
192 int qmat_chroma[16][64];
193 const uint8_t *scantable;
194
195 int is_422;
196 int need_alpha;
197 int is_interlaced;
198
199 char *vendor;
200 } ProresContext;
201
202 /**
203 * Check if a value is in the list. If not, return the default value
204 *
205 * @param ctx Context for the log msg
206 * @param val_name Name of the checked value, for log msg
207 * @param array_valid_values Array of valid int, ended with INT_MAX
208 * @param default_value Value return if checked value is not in the array
209 * @return Value or default_value.
210 */
211 2400 static int int_from_list_or_default(void *ctx, const char *val_name, int val,
212 const int *array_valid_values, int default_value)
213 {
214 2400 int i = 0;
215
216 4000 while (1) {
217 6400 int ref_val = array_valid_values[i];
218
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6400 times.
6400 if (ref_val == INT_MAX)
219 break;
220
2/2
✓ Branch 0 taken 2400 times.
✓ Branch 1 taken 4000 times.
6400 if (val == ref_val)
221 2400 return val;
222 4000 i++;
223 }
224 /* val is not a valid value */
225 av_log(ctx, AV_LOG_DEBUG,
226 "%s %d are not supported. Set to default value : %d\n",
227 val_name, val, default_value);
228 return default_value;
229 }
230
231 182338360 static void encode_vlc_codeword(PutBitContext *pb, unsigned codebook, int val)
232 {
233 unsigned int rice_order, exp_order, switch_bits, switch_val;
234 int exponent;
235
236 /* number of prefix bits to switch between Rice and expGolomb */
237 182338360 switch_bits = (codebook & 3) + 1;
238 182338360 rice_order = codebook >> 5; /* rice code order */
239 182338360 exp_order = (codebook >> 2) & 7; /* exp golomb code order */
240
241 182338360 switch_val = switch_bits << rice_order;
242
243
2/2
✓ Branch 0 taken 60600805 times.
✓ Branch 1 taken 121737555 times.
182338360 if (val >= switch_val) {
244 60600805 val -= switch_val - (1 << exp_order);
245 60600805 exponent = av_log2(val);
246
247 60600805 put_bits(pb, exponent - exp_order + switch_bits, 0);
248 60600805 put_bits(pb, exponent + 1, val);
249 } else {
250 121737555 exponent = val >> rice_order;
251
252
2/2
✓ Branch 0 taken 27389069 times.
✓ Branch 1 taken 94348486 times.
121737555 if (exponent)
253 27389069 put_bits(pb, exponent, 0);
254 121737555 put_bits(pb, 1, 1);
255
2/2
✓ Branch 0 taken 12633930 times.
✓ Branch 1 taken 109103625 times.
121737555 if (rice_order)
256 12633930 put_sbits(pb, rice_order, val);
257 }
258 182338360 }
259
260 #define GET_SIGN(x) ((x) >> 31)
261 #define MAKE_CODE(x) (((x) * 2) ^ GET_SIGN(x))
262
263 174174 static void encode_dcs(PutBitContext *pb, int16_t *blocks,
264 int blocks_per_slice, int scale)
265 {
266 int i;
267 174174 int codebook = 5, code, dc, prev_dc, delta, sign, new_sign;
268
269 174174 prev_dc = (blocks[0] - 0x4000) / scale;
270 174174 encode_vlc_codeword(pb, FIRST_DC_CB, MAKE_CODE(prev_dc));
271 174174 sign = 0;
272 174174 blocks += 64;
273
274
2/2
✓ Branch 0 taken 2975050 times.
✓ Branch 1 taken 174174 times.
3149224 for (i = 1; i < blocks_per_slice; i++, blocks += 64) {
275 2975050 dc = (blocks[0] - 0x4000) / scale;
276 2975050 delta = dc - prev_dc;
277 2975050 new_sign = GET_SIGN(delta);
278 2975050 delta = (delta ^ sign) - sign;
279 2975050 code = MAKE_CODE(delta);
280 2975050 encode_vlc_codeword(pb, ff_prores_dc_codebook[codebook], code);
281 2975050 codebook = FFMIN(code, 6);
282 2975050 sign = new_sign;
283 2975050 prev_dc = dc;
284 }
285 174174 }
286
287 174174 static void encode_acs(PutBitContext *pb, int16_t *blocks,
288 int blocks_per_slice,
289 int *qmat, const uint8_t *scan)
290 {
291 int idx, i;
292 174174 int prev_run = 4;
293 174174 int prev_level = 2;
294 174174 int run = 0, level;
295 int max_coeffs, abs_level;
296
297 174174 max_coeffs = blocks_per_slice << 6;
298
299
2/2
✓ Branch 0 taken 10972962 times.
✓ Branch 1 taken 174174 times.
11147136 for (i = 1; i < 64; i++) {
300
2/2
✓ Branch 0 taken 198401112 times.
✓ Branch 1 taken 10972962 times.
209374074 for (idx = scan[i]; idx < max_coeffs; idx += 64) {
301 198401112 level = blocks[idx] / qmat[scan[i]];
302
2/2
✓ Branch 0 taken 89594568 times.
✓ Branch 1 taken 108806544 times.
198401112 if (level) {
303 89594568 abs_level = FFABS(level);
304 89594568 encode_vlc_codeword(pb, ff_prores_run_to_cb[prev_run], run);
305 89594568 encode_vlc_codeword(pb, ff_prores_level_to_cb[prev_level], abs_level - 1);
306 89594568 put_sbits(pb, 1, GET_SIGN(level));
307
308 89594568 prev_run = FFMIN(run, 15);
309 89594568 prev_level = FFMIN(abs_level, 9);
310 89594568 run = 0;
311 } else {
312 108806544 run++;
313 }
314 }
315 }
316 174174 }
317
318 2397000 static void get(const uint8_t *pixels, int stride, int16_t* block)
319 {
320 int i;
321
322
2/2
✓ Branch 0 taken 19176000 times.
✓ Branch 1 taken 2397000 times.
21573000 for (i = 0; i < 8; i++) {
323 19176000 AV_WN64(block, AV_RN64(pixels));
324 19176000 AV_WN64(block+4, AV_RN64(pixels+8));
325 19176000 pixels += stride;
326 19176000 block += 8;
327 }
328 2397000 }
329
330 2397000 static void fdct_get(FDCTDSPContext *fdsp, const uint8_t *pixels, int stride, int16_t* block)
331 {
332 2397000 get(pixels, stride, block);
333 2397000 fdsp->fdct(block);
334 2397000 }
335
336 133800 static void calc_plane_dct(FDCTDSPContext *fdsp, const uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma, int is_422)
337 {
338 int16_t *block;
339 int i;
340
341 133800 block = blocks;
342
343
2/2
✓ Branch 0 taken 44600 times.
✓ Branch 1 taken 89200 times.
133800 if (!chroma) { /* Luma plane */
344
2/2
✓ Branch 0 taken 239700 times.
✓ Branch 1 taken 44600 times.
284300 for (i = 0; i < mb_count; i++) {
345 239700 fdct_get(fdsp, src, src_stride, block + (0 << 6));
346 239700 fdct_get(fdsp, src + 16, src_stride, block + (1 << 6));
347 239700 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (2 << 6));
348 239700 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
349
350 239700 block += 256;
351 239700 src += 32;
352 }
353
3/4
✓ Branch 0 taken 89200 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 44600 times.
✓ Branch 3 taken 44600 times.
89200 } else if (chroma && is_422){ /* chroma plane 422 */
354
2/2
✓ Branch 0 taken 239700 times.
✓ Branch 1 taken 44600 times.
284300 for (i = 0; i < mb_count; i++) {
355 239700 fdct_get(fdsp, src, src_stride, block + (0 << 6));
356 239700 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
357 239700 block += (256 >> 1);
358 239700 src += (32 >> 1);
359 }
360 } else { /* chroma plane 444 */
361
2/2
✓ Branch 0 taken 239700 times.
✓ Branch 1 taken 44600 times.
284300 for (i = 0; i < mb_count; i++) {
362 239700 fdct_get(fdsp, src, src_stride, block + (0 << 6));
363 239700 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
364 239700 fdct_get(fdsp, src + 16, src_stride, block + (2 << 6));
365 239700 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
366
367 239700 block += 256;
368 239700 src += 32;
369 }
370 }
371 133800 }
372
373 174174 static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int sub_sample_chroma,
374 const uint8_t *scan)
375 {
376 int blocks_per_slice;
377 PutBitContext pb;
378
379 174174 blocks_per_slice = mb_count << (2 - sub_sample_chroma);
380 174174 init_put_bits(&pb, buf, buf_size);
381
382 174174 encode_dcs(&pb, blocks, blocks_per_slice, qmat[0]);
383 174174 encode_acs(&pb, blocks, blocks_per_slice, qmat, scan);
384
385 174174 flush_put_bits(&pb);
386 174174 return put_bytes_output(&pb);
387 }
388
389 58058 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
390 int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
391 unsigned mb_count, uint8_t *buf, unsigned data_size,
392 unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
393 int qp)
394 {
395 58058 ProresContext* ctx = avctx->priv_data;
396
397 116116 *y_data_size = encode_slice_plane(blocks_y, mb_count,
398 58058 buf, data_size, ctx->qmat_luma[qp - 1], 0, ctx->scantable);
399
400
1/2
✓ Branch 0 taken 58058 times.
✗ Branch 1 not taken.
58058 if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
401 116116 *u_data_size = encode_slice_plane(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
402 58058 ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
403
404 58058 *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
405 58058 data_size - *y_data_size - *u_data_size,
406 58058 ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
407 }
408
409 58058 return *y_data_size + *u_data_size + *v_data_size;
410 }
411
412 static void put_alpha_diff(PutBitContext *pb, int cur, int prev)
413 {
414 const int abits = 16;
415 const int dbits = 7;
416 const int dsize = 1 << dbits - 1;
417 int diff = cur - prev;
418
419 diff = av_zero_extend(diff, abits);
420 if (diff >= (1 << abits) - dsize)
421 diff -= 1 << abits;
422 if (diff < -dsize || diff > dsize || !diff) {
423 put_bits(pb, 1, 1);
424 put_bits(pb, abits, diff);
425 } else {
426 put_bits(pb, 1, 0);
427 put_bits(pb, dbits - 1, FFABS(diff) - 1);
428 put_bits(pb, 1, diff < 0);
429 }
430 }
431
432 static inline void put_alpha_run(PutBitContext *pb, int run)
433 {
434 if (run) {
435 put_bits(pb, 1, 0);
436 if (run < 0x10)
437 put_bits(pb, 4, run);
438 else
439 put_bits(pb, 15, run);
440 } else {
441 put_bits(pb, 1, 1);
442 }
443 }
444
445 static av_always_inline int encode_alpha_slice_data(AVCodecContext *avctx, int8_t * src_a,
446 unsigned mb_count, uint8_t *buf, unsigned data_size, unsigned* a_data_size)
447 {
448 const int abits = 16;
449 const int mask = (1 << abits) - 1;
450 const int num_coeffs = mb_count * 256;
451 int prev = mask, cur;
452 int idx = 0;
453 int run = 0;
454 int16_t * blocks = (int16_t *)src_a;
455 PutBitContext pb;
456 init_put_bits(&pb, buf, data_size);
457
458 cur = blocks[idx++];
459 put_alpha_diff(&pb, cur, prev);
460 prev = cur;
461 do {
462 cur = blocks[idx++];
463 if (cur != prev) {
464 put_alpha_run (&pb, run);
465 put_alpha_diff(&pb, cur, prev);
466 prev = cur;
467 run = 0;
468 } else {
469 run++;
470 }
471 } while (idx < num_coeffs);
472 put_alpha_run(&pb, run);
473 flush_put_bits(&pb);
474 *a_data_size = put_bytes_output(&pb);
475
476 if (put_bits_left(&pb) < 0) {
477 av_log(avctx, AV_LOG_ERROR,
478 "Underestimated required buffer size.\n");
479 return AVERROR_BUG;
480 } else {
481 return 0;
482 }
483 }
484
485 3000 static inline void subimage_with_fill_template(const uint16_t *src, unsigned x, unsigned y,
486 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
487 unsigned dst_width, unsigned dst_height, int is_alpha_plane,
488 int is_interlaced, int is_top_field)
489 {
490 3000 int box_width = FFMIN(width - x, dst_width);
491 int i, j, src_stride, box_height;
492 uint16_t last_pix, *last_line;
493
494
2/2
✓ Branch 0 taken 1200 times.
✓ Branch 1 taken 1800 times.
3000 if (!is_interlaced) {
495 1200 src_stride = stride >> 1;
496 1200 src += y * src_stride + x;
497 1200 box_height = FFMIN(height - y, dst_height);
498 } else {
499 1800 src_stride = stride; /* 2 lines stride */
500 1800 src += y * src_stride + x;
501 1800 box_height = FFMIN(height/2 - y, dst_height);
502
2/2
✓ Branch 0 taken 900 times.
✓ Branch 1 taken 900 times.
1800 if (!is_top_field)
503 900 src += stride >> 1;
504 }
505
506
2/2
✓ Branch 0 taken 21600 times.
✓ Branch 1 taken 3000 times.
24600 for (i = 0; i < box_height; ++i) {
507
2/2
✓ Branch 0 taken 66000 times.
✓ Branch 1 taken 21600 times.
87600 for (j = 0; j < box_width; ++j) {
508
1/2
✓ Branch 0 taken 66000 times.
✗ Branch 1 not taken.
66000 if (!is_alpha_plane) {
509 66000 dst[j] = src[j];
510 } else {
511 dst[j] = src[j] << 6; /* alpha 10b to 16b */
512 }
513 }
514
1/2
✓ Branch 0 taken 21600 times.
✗ Branch 1 not taken.
21600 if (!is_alpha_plane) {
515 21600 last_pix = dst[j - 1];
516 } else {
517 last_pix = dst[j - 1] << 6; /* alpha 10b to 16b */
518 }
519
2/2
✓ Branch 0 taken 238000 times.
✓ Branch 1 taken 21600 times.
259600 for (; j < dst_width; j++)
520 238000 dst[j] = last_pix;
521 21600 src += src_stride;
522 21600 dst += dst_width;
523 }
524 3000 last_line = dst - dst_width;
525
2/2
✓ Branch 0 taken 26400 times.
✓ Branch 1 taken 3000 times.
29400 for (; i < dst_height; i++) {
526
2/2
✓ Branch 0 taken 528000 times.
✓ Branch 1 taken 26400 times.
554400 for (j = 0; j < dst_width; ++j) {
527 528000 dst[j] = last_line[j];
528 }
529 26400 dst += dst_width;
530 }
531 3000 }
532
533 3000 static void subimage_with_fill(const uint16_t *src, unsigned x, unsigned y,
534 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
535 unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
536 {
537 3000 subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 0, is_interlaced, is_top_field);
538 3000 }
539
540 /* reorganize alpha data and convert 10b -> 16b */
541 static void subimage_alpha_with_fill(const uint16_t *src, unsigned x, unsigned y,
542 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
543 unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
544 {
545 subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 1, is_interlaced, is_top_field);
546 }
547
548 44600 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
549 int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
550 int unsafe, int *qp, int is_interlaced, int is_top_field)
551 {
552 44600 int luma_stride, chroma_stride, alpha_stride = 0;
553 44600 ProresContext* ctx = avctx->priv_data;
554 44600 int hdr_size = 6 + (ctx->need_alpha * 2); /* v data size is write when there is alpha */
555 44600 int ret = 0, slice_size;
556 const uint8_t *dest_y, *dest_u, *dest_v;
557 44600 unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0, a_data_size = 0;
558 44600 FDCTDSPContext *fdsp = &ctx->fdsp;
559 44600 int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2;
560 44600 int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
561 44600 int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
562
563 44600 LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
564 44600 LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
565 44600 LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
566
567 44600 luma_stride = pic->linesize[0];
568 44600 chroma_stride = pic->linesize[1];
569
570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44600 times.
44600 if (ctx->need_alpha)
571 alpha_stride = pic->linesize[3];
572
573
2/2
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 22400 times.
44600 if (!is_interlaced) {
574 22200 dest_y = pic->data[0] + (mb_y << 4) * luma_stride + (mb_x << 5);
575 22200 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
576 22200 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
577 } else {
578 22400 dest_y = pic->data[0] + (mb_y << 4) * luma_stride * 2 + (mb_x << 5);
579 22400 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
580 22400 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
581
2/2
✓ Branch 0 taken 11200 times.
✓ Branch 1 taken 11200 times.
22400 if (!is_top_field){ /* bottom field, offset dest */
582 11200 dest_y += luma_stride;
583 11200 dest_u += chroma_stride;
584 11200 dest_v += chroma_stride;
585 }
586 }
587
588
2/2
✓ Branch 0 taken 1000 times.
✓ Branch 1 taken 43600 times.
44600 if (unsafe) {
589 1000 subimage_with_fill((const uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
590 1000 luma_stride, avctx->width, avctx->height,
591 1000 (uint16_t *) ctx->fill_y, mb_count << 4, 16, is_interlaced, is_top_field);
592 1000 subimage_with_fill((const uint16_t *) pic->data[1], mb_x << (4 - ctx->is_422), mb_y << 4,
593 1000 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
594 1000 (uint16_t *) ctx->fill_u, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
595 1000 subimage_with_fill((const uint16_t *) pic->data[2], mb_x << (4 - ctx->is_422), mb_y << 4,
596 1000 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
597 1000 (uint16_t *) ctx->fill_v, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
598
599 /* no need for interlaced special case, data already reorganized in subimage_with_fill */
600 1000 calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count << 5, mb_count, 0, 0);
601 1000 calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
602 1000 calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
603
604 1000 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
605 mb_count, buf + hdr_size, data_size - hdr_size,
606 &y_data_size, &u_data_size, &v_data_size,
607 *qp);
608 } else {
609
2/2
✓ Branch 0 taken 21800 times.
✓ Branch 1 taken 21800 times.
43600 if (!is_interlaced) {
610 21800 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0, 0);
611 21800 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1, ctx->is_422);
612 21800 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1, ctx->is_422);
613 } else {
614 21800 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride * 2, mb_count, 0, 0);
615 21800 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride * 2, mb_count, 1, ctx->is_422);
616 21800 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride * 2, mb_count, 1, ctx->is_422);
617 }
618
619 43600 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
620 mb_count, buf + hdr_size, data_size - hdr_size,
621 &y_data_size, &u_data_size, &v_data_size,
622 *qp);
623
624
4/4
✓ Branch 0 taken 37072 times.
✓ Branch 1 taken 6528 times.
✓ Branch 2 taken 3652 times.
✓ Branch 3 taken 33420 times.
43600 if (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]) {
625 do {
626 8982 *qp += 1;
627 8982 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
628 mb_count, buf + hdr_size, data_size - hdr_size,
629 &y_data_size, &u_data_size, &v_data_size,
630 *qp);
631
4/4
✓ Branch 0 taken 7793 times.
✓ Branch 1 taken 1189 times.
✓ Branch 2 taken 5330 times.
✓ Branch 3 taken 2463 times.
8982 } while (slice_size > high_bytes && *qp < qp_end_table[avctx->profile]);
632
2/2
✓ Branch 0 taken 2317 times.
✓ Branch 1 taken 37631 times.
39948 } else if (slice_size < low_bytes && *qp
633
2/2
✓ Branch 0 taken 2312 times.
✓ Branch 1 taken 5 times.
2317 > qp_start_table[avctx->profile]) {
634 do {
635 4476 *qp -= 1;
636 4476 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
637 mb_count, buf + hdr_size, data_size - hdr_size,
638 &y_data_size, &u_data_size, &v_data_size,
639 *qp);
640
4/4
✓ Branch 0 taken 2195 times.
✓ Branch 1 taken 2281 times.
✓ Branch 2 taken 2164 times.
✓ Branch 3 taken 31 times.
4476 } while (slice_size < low_bytes && *qp > qp_start_table[avctx->profile]);
641 }
642 }
643
644 44600 buf[0] = hdr_size << 3;
645 44600 buf[1] = *qp;
646 44600 AV_WB16(buf + 2, y_data_size);
647 44600 AV_WB16(buf + 4, u_data_size);
648
649
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44600 times.
44600 if (ctx->need_alpha) {
650 AV_WB16(buf + 6, v_data_size); /* write v data size only if there is alpha */
651
652 subimage_alpha_with_fill((const uint16_t *) pic->data[3], mb_x << 4, mb_y << 4,
653 alpha_stride, avctx->width, avctx->height,
654 (uint16_t *) ctx->fill_a, mb_count << 4, 16, is_interlaced, is_top_field);
655 ret = encode_alpha_slice_data(avctx, ctx->fill_a, mb_count,
656 buf + hdr_size + slice_size,
657 data_size - hdr_size - slice_size, &a_data_size);
658 }
659
660
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44600 times.
44600 if (ret != 0) {
661 return ret;
662 }
663 44600 return hdr_size + y_data_size + u_data_size + v_data_size + a_data_size;
664 }
665
666 1200 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
667 uint8_t *buf, const int buf_size, const int picture_index, const int is_top_field)
668 {
669 1200 ProresContext *ctx = avctx->priv_data;
670 1200 int mb_width = (avctx->width + 15) >> 4;
671 int hdr_size, sl_size, i;
672 int mb_y, sl_data_size, qp, mb_height, picture_height, unsafe_mb_height_limit;
673 int unsafe_bot, unsafe_right;
674 uint8_t *sl_data, *sl_data_sizes;
675 1200 int slice_per_line = 0, rem = mb_width;
676
677
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 800 times.
1200 if (!ctx->is_interlaced) { /* progressive encoding */
678 400 mb_height = (avctx->height + 15) >> 4;
679 400 unsafe_mb_height_limit = mb_height;
680 } else {
681
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 400 times.
800 if (is_top_field) {
682 400 picture_height = (avctx->height + 1) / 2;
683 } else {
684 400 picture_height = avctx->height / 2;
685 }
686 800 mb_height = (picture_height + 15) >> 4;
687 800 unsafe_mb_height_limit = mb_height;
688 }
689
690
2/2
✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 1200 times.
6000 for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
691 4800 slice_per_line += rem >> i;
692 4800 rem &= (1 << i) - 1;
693 }
694
695 1200 qp = qp_start_table[avctx->profile];
696 1200 hdr_size = 8; sl_data_size = buf_size - hdr_size;
697 1200 sl_data_sizes = buf + hdr_size;
698 1200 sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
699
2/2
✓ Branch 0 taken 11500 times.
✓ Branch 1 taken 1200 times.
12700 for (mb_y = 0; mb_y < mb_height; mb_y++) {
700 11500 int mb_x = 0;
701 11500 int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
702
2/2
✓ Branch 0 taken 44600 times.
✓ Branch 1 taken 11500 times.
56100 while (mb_x < mb_width) {
703
2/2
✓ Branch 0 taken 23700 times.
✓ Branch 1 taken 44600 times.
68300 while (mb_width - mb_x < slice_mb_count)
704 23700 slice_mb_count >>= 1;
705
706
4/4
✓ Branch 0 taken 1400 times.
✓ Branch 1 taken 43200 times.
✓ Branch 2 taken 600 times.
✓ Branch 3 taken 800 times.
44600 unsafe_bot = (avctx->height & 0xf) && (mb_y == unsafe_mb_height_limit - 1);
707
4/4
✓ Branch 0 taken 1400 times.
✓ Branch 1 taken 43200 times.
✓ Branch 2 taken 700 times.
✓ Branch 3 taken 700 times.
44600 unsafe_right = (avctx->width & 0xf) && (mb_x + slice_mb_count == mb_width);
708
709
4/4
✓ Branch 0 taken 44000 times.
✓ Branch 1 taken 600 times.
✓ Branch 2 taken 400 times.
✓ Branch 3 taken 43600 times.
44600 sl_size = encode_slice(avctx, pic, mb_x, mb_y, slice_mb_count,
710 sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp, ctx->is_interlaced, is_top_field);
711
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44600 times.
44600 if (sl_size < 0){
712 return sl_size;
713 }
714
715 44600 bytestream_put_be16(&sl_data_sizes, sl_size);
716 44600 sl_data += sl_size;
717 44600 sl_data_size -= sl_size;
718 44600 mb_x += slice_mb_count;
719 }
720 }
721
722 1200 buf[0] = hdr_size << 3;
723 1200 AV_WB32(buf + 1, sl_data - buf);
724 1200 AV_WB16(buf + 5, slice_per_line * mb_height); /* picture size */
725 1200 buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4; /* number of slices */
726
727 1200 return sl_data - buf;
728 }
729
730 800 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
731 const AVFrame *pict, int *got_packet)
732 {
733 800 ProresContext *ctx = avctx->priv_data;
734 800 int header_size = 148;
735 uint8_t *buf;
736 800 int compress_frame_size, pic_size, ret, is_top_field_first = 0;
737 uint8_t frame_flags;
738 800 int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + FF_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
739
740
741
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 800 times.
800 if ((ret = ff_alloc_packet(avctx, pkt, frame_size + FF_INPUT_BUFFER_MIN_SIZE)) < 0)
742 return ret;
743
744 800 buf = pkt->data;
745 800 compress_frame_size = 8 + header_size;
746
747 800 bytestream_put_be32(&buf, compress_frame_size);/* frame size will be update after picture(s) encoding */
748 800 bytestream_put_be32(&buf, FRAME_ID);
749
750 800 bytestream_put_be16(&buf, header_size);
751
3/4
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 400 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 400 times.
800 bytestream_put_be16(&buf, avctx->pix_fmt != AV_PIX_FMT_YUV422P10 || ctx->need_alpha ? 1 : 0); /* version */
752 800 bytestream_put_buffer(&buf, ctx->vendor, 4);
753 800 bytestream_put_be16(&buf, avctx->width);
754 800 bytestream_put_be16(&buf, avctx->height);
755 800 frame_flags = 0x80; /* 422 not interlaced */
756
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 400 times.
800 if (avctx->profile >= AV_PROFILE_PRORES_4444) /* 4444 or 4444 Xq */
757 400 frame_flags |= 0x40; /* 444 chroma */
758
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 400 times.
800 if (ctx->is_interlaced) {
759
2/4
✓ Branch 0 taken 400 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
400 if ((pict->flags & AV_FRAME_FLAG_TOP_FIELD_FIRST) || !(pict->flags & AV_FRAME_FLAG_INTERLACED)) {
760 /* tff frame or progressive frame interpret as tff */
761 400 av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, top field first\n");
762 400 frame_flags |= 0x04; /* interlaced tff */
763 400 is_top_field_first = 1;
764 } else {
765 av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, bottom field first\n");
766 frame_flags |= 0x08; /* interlaced bff */
767 }
768 } else {
769 400 av_log(avctx, AV_LOG_DEBUG, "use progressive encoding\n");
770 }
771 800 *buf++ = frame_flags;
772 800 *buf++ = 0; /* reserved */
773 /* only write color properties, if valid value. set to unspecified otherwise */
774 1600 *buf++ = int_from_list_or_default(avctx, "frame color primaries",
775 800 pict->color_primaries, valid_primaries, 0);
776 1600 *buf++ = int_from_list_or_default(avctx, "frame color trc",
777 800 pict->color_trc, valid_trc, 0);
778 1600 *buf++ = int_from_list_or_default(avctx, "frame colorspace",
779 800 pict->colorspace, valid_colorspace, 0);
780
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 800 times.
800 *buf++ = ctx->need_alpha ? 0x2 /* 16-bit alpha */ : 0;
781 800 *buf++ = 0; /* reserved */
782 800 *buf++ = 3; /* luma and chroma matrix present */
783
784 800 bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64);
785 800 bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
786
787 800 pic_size = prores_encode_picture(avctx, pict, buf,
788 800 pkt->size - compress_frame_size, 0, is_top_field_first);/* encode progressive or first field */
789
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 800 times.
800 if (pic_size < 0) {
790 return pic_size;
791 }
792 800 compress_frame_size += pic_size;
793
794
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 400 times.
800 if (ctx->is_interlaced) { /* encode second field */
795 400 pic_size = prores_encode_picture(avctx, pict, pkt->data + compress_frame_size,
796 400 pkt->size - compress_frame_size, 1, !is_top_field_first);
797
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 400 times.
400 if (pic_size < 0) {
798 return pic_size;
799 }
800 400 compress_frame_size += pic_size;
801 }
802
803 800 AV_WB32(pkt->data, compress_frame_size);/* update frame size */
804 800 pkt->size = compress_frame_size;
805 800 *got_packet = 1;
806
807 800 return 0;
808 }
809
810 512 static void scale_mat(const uint8_t* src, int* dst, int scale)
811 {
812 int i;
813
2/2
✓ Branch 0 taken 32768 times.
✓ Branch 1 taken 512 times.
33280 for (i = 0; i < 64; i++)
814 32768 dst[i] = src[i] * scale;
815 512 }
816
817 16 static av_cold int prores_encode_init(AVCodecContext *avctx)
818 {
819 int i;
820 16 ProresContext* ctx = avctx->priv_data;
821
822 16 avctx->bits_per_raw_sample = 10;
823 16 ctx->need_alpha = 0;
824 16 ctx->is_interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
825
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (ctx->is_interlaced) {
826 8 ctx->scantable = ff_prores_interlaced_scan;
827 } else {
828 8 ctx->scantable = ff_prores_progressive_scan;
829 }
830
831
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (avctx->width & 0x1) {
832 av_log(avctx, AV_LOG_ERROR,
833 "frame width needs to be multiple of 2\n");
834 return AVERROR(EINVAL);
835 }
836
837
2/4
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16 times.
16 if (avctx->width > 65534 || avctx->height > 65535) {
838 av_log(avctx, AV_LOG_ERROR,
839 "The maximum dimensions are 65534x65535\n");
840 return AVERROR(EINVAL);
841 }
842
843
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (strlen(ctx->vendor) != 4) {
844 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
845 return AVERROR(EINVAL);
846 }
847
848
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (avctx->profile == AV_PROFILE_UNKNOWN) {
849
2/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
16 switch (avctx->pix_fmt) {
850 8 case AV_PIX_FMT_YUV422P10:
851 8 avctx->profile = AV_PROFILE_PRORES_STANDARD;
852 8 av_log(avctx, AV_LOG_INFO,
853 "encoding with ProRes standard (apcn) profile\n");
854 8 break;
855 8 case AV_PIX_FMT_YUV444P10:
856 8 avctx->profile = AV_PROFILE_PRORES_4444;
857 8 av_log(avctx, AV_LOG_INFO,
858 "encoding with ProRes 4444 (ap4h) profile\n");
859 8 break;
860 case AV_PIX_FMT_YUVA444P10:
861 avctx->profile = AV_PROFILE_PRORES_4444;
862 av_log(avctx, AV_LOG_INFO,
863 "encoding with ProRes 4444+ (ap4h) profile\n");
864 break;
865 default:
866 av_unreachable("Already checked via CODEC_PIXFMTS");
867 }
868 } else if (avctx->profile < AV_PROFILE_PRORES_PROXY
869 || avctx->profile > AV_PROFILE_PRORES_XQ) {
870 av_log(
871 avctx,
872 AV_LOG_ERROR,
873 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch, 4 - ap4h, 5 - ap4x]\n",
874 avctx->profile);
875 return AVERROR(EINVAL);
876 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P10) && (avctx->profile > AV_PROFILE_PRORES_HQ)){
877 av_log(avctx, AV_LOG_ERROR,
878 "encoding with ProRes 444/Xq (ap4h/ap4x) profile, need YUV444P10 input\n");
879 return AVERROR(EINVAL);
880 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10)
881 && (avctx->profile < AV_PROFILE_PRORES_4444)){
882 av_log(avctx, AV_LOG_ERROR,
883 "encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input\n");
884 return AVERROR(EINVAL);
885 }
886
887
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (avctx->profile < AV_PROFILE_PRORES_4444) { /* 422 versions */
888 8 ctx->is_422 = 1;
889
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
8 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
890 2 ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!ctx->fill_y)
892 return AVERROR(ENOMEM);
893 2 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
894 2 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
895 }
896 } else { /* 444 */
897 8 ctx->is_422 = 0;
898
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
8 if ((avctx->height & 0xf) || (avctx->width & 0xf)) {
899 2 ctx->fill_y = av_malloc(3 * (DEFAULT_SLICE_MB_WIDTH << 9));
900
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!ctx->fill_y)
901 return AVERROR(ENOMEM);
902 2 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
903 2 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 9);
904 }
905
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
906 ctx->need_alpha = 1;
907 ctx->fill_a = av_malloc(DEFAULT_SLICE_MB_WIDTH << 9); /* 8 blocks x 16px x 16px x sizeof (uint16) */
908 if (!ctx->fill_a)
909 return AVERROR(ENOMEM);
910 }
911 }
912
913
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (ctx->need_alpha)
914 avctx->bits_per_coded_sample = 32;
915
916 16 ff_fdctdsp_init(&ctx->fdsp, avctx);
917
918 16 avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
919
920
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 16 times.
272 for (i = 1; i <= 16; i++) {
921 256 scale_mat(QMAT_LUMA[avctx->profile] , ctx->qmat_luma[i - 1] , i);
922 256 scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
923 }
924
925 16 return 0;
926 }
927
928 16 static av_cold int prores_encode_close(AVCodecContext *avctx)
929 {
930 16 ProresContext* ctx = avctx->priv_data;
931 16 av_freep(&ctx->fill_y);
932 16 av_freep(&ctx->fill_a);
933
934 16 return 0;
935 }
936
937 #define OFFSET(x) offsetof(ProresContext, x)
938 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
939
940 static const AVOption options[] = {
941 { "vendor", "vendor ID", OFFSET(vendor), AV_OPT_TYPE_STRING, { .str = "fmpg" }, 0, 0, VE },
942 { NULL }
943 };
944
945 static const AVClass prores_enc_class = {
946 .class_name = "ProRes encoder",
947 .item_name = av_default_item_name,
948 .option = options,
949 .version = LIBAVUTIL_VERSION_INT,
950 };
951
952 static const enum AVPixelFormat pix_fmts[] = {
953 AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
954 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
955 };
956
957 const FFCodec ff_prores_aw_encoder = {
958 .p.name = "prores_aw",
959 CODEC_LONG_NAME("Apple ProRes"),
960 .p.type = AVMEDIA_TYPE_VIDEO,
961 .p.id = AV_CODEC_ID_PRORES,
962 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
963 AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
964 CODEC_PIXFMTS_ARRAY(pix_fmts),
965 .color_ranges = AVCOL_RANGE_MPEG,
966 .priv_data_size = sizeof(ProresContext),
967 .init = prores_encode_init,
968 .close = prores_encode_close,
969 FF_CODEC_ENCODE_CB(prores_encode_frame),
970 .p.priv_class = &prores_enc_class,
971 .p.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
972 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
973 };
974
975 const FFCodec ff_prores_encoder = {
976 .p.name = "prores",
977 CODEC_LONG_NAME("Apple ProRes"),
978 .p.type = AVMEDIA_TYPE_VIDEO,
979 .p.id = AV_CODEC_ID_PRORES,
980 .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
981 AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE,
982 CODEC_PIXFMTS_ARRAY(pix_fmts),
983 .color_ranges = AVCOL_RANGE_MPEG,
984 .priv_data_size = sizeof(ProresContext),
985 .init = prores_encode_init,
986 .close = prores_encode_close,
987 FF_CODEC_ENCODE_CB(prores_encode_frame),
988 .p.priv_class = &prores_enc_class,
989 .p.profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
990 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
991 };
992