FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/proresenc_anatoliy.c
Date: 2024-04-19 17:50:32
Exec Total Coverage
Lines: 344 444 77.5%
Functions: 17 21 81.0%
Branches: 140 204 68.6%

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