FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavcodec/proresenc_anatoliy.c
Date: 2021-09-26 18:22:30
Exec Total Coverage
Lines: 340 437 77.8%
Branches: 135 198 68.2%

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_internal.h"
31 #include "libavutil/opt.h"
32 #include "avcodec.h"
33 #include "dct.h"
34 #include "encode.h"
35 #include "internal.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 { FF_PROFILE_PRORES_PROXY, "apco"},
46 { FF_PROFILE_PRORES_LT, "apcs"},
47 { FF_PROFILE_PRORES_STANDARD, "apcn"},
48 { FF_PROFILE_PRORES_HQ, "apch"},
49 { FF_PROFILE_PRORES_4444, "ap4h"},
50 { FF_PROFILE_PRORES_XQ, "ap4x"},
51 { FF_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 182338360 static void encode_codeword(PutBitContext *pb, int val, int codebook)
202 {
203 unsigned int rice_order, exp_order, switch_bits, first_exp, exp, zeros;
204
205 /* number of bits to switch between rice and exp golomb */
206 182338360 switch_bits = codebook & 3;
207 182338360 rice_order = codebook >> 5;
208 182338360 exp_order = (codebook >> 2) & 7;
209
210 182338360 first_exp = ((switch_bits + 1) << rice_order);
211
212
2/2
✓ Branch 0 taken 60600805 times.
✓ Branch 1 taken 121737555 times.
182338360 if (val >= first_exp) { /* exp golomb */
213 60600805 val -= first_exp;
214 60600805 val += (1 << exp_order);
215 60600805 exp = av_log2(val);
216 60600805 zeros = exp - exp_order + switch_bits + 1;
217 60600805 put_bits(pb, zeros, 0);
218 60600805 put_bits(pb, exp + 1, val);
219
2/2
✓ Branch 0 taken 12633930 times.
✓ Branch 1 taken 109103625 times.
121737555 } else if (rice_order) {
220 12633930 put_bits(pb, (val >> rice_order), 0);
221 12633930 put_bits(pb, 1, 1);
222 12633930 put_sbits(pb, rice_order, val);
223 } else {
224 109103625 put_bits(pb, val, 0);
225 109103625 put_bits(pb, 1, 1);
226 }
227 182338360 }
228
229 #define QSCALE(qmat,ind,val) ((val) / ((qmat)[ind]))
230 #define TO_GOLOMB(val) (((val) * 2) ^ ((val) >> 31))
231 #define DIFF_SIGN(val, sign) (((val) >> 31) ^ (sign))
232 #define IS_NEGATIVE(val) ((((val) >> 31) ^ -1) + 1)
233 #define TO_GOLOMB2(val,sign) ((val)==0 ? 0 : ((val) << 1) + (sign))
234
235 95520236 static av_always_inline int get_level(int val)
236 {
237 95520236 int sign = (val >> 31);
238 95520236 return (val ^ sign) - sign;
239 }
240
241 #define FIRST_DC_CB 0xB8
242
243 static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70};
244
245 174174 static void encode_dc_coeffs(PutBitContext *pb, int16_t *in,
246 int blocks_per_slice, int *qmat)
247 {
248 int prev_dc, code;
249 int i, sign, idx;
250 int new_dc, delta, diff_sign, new_code;
251
252 174174 prev_dc = QSCALE(qmat, 0, in[0] - 16384);
253 174174 code = TO_GOLOMB(prev_dc);
254 174174 encode_codeword(pb, code, FIRST_DC_CB);
255
256 174174 code = 5; sign = 0; idx = 64;
257
2/2
✓ Branch 0 taken 2975050 times.
✓ Branch 1 taken 174174 times.
3149224 for (i = 1; i < blocks_per_slice; i++, idx += 64) {
258 2975050 new_dc = QSCALE(qmat, 0, in[idx] - 16384);
259 2975050 delta = new_dc - prev_dc;
260 2975050 diff_sign = DIFF_SIGN(delta, sign);
261
2/2
✓ Branch 1 taken 2950618 times.
✓ Branch 2 taken 24432 times.
2975050 new_code = TO_GOLOMB2(get_level(delta), diff_sign);
262
263 2975050 encode_codeword(pb, new_code, dc_codebook[FFMIN(code, 6)]);
264
265 2975050 code = new_code;
266 2975050 sign = delta >> 31;
267 2975050 prev_dc = new_dc;
268 }
269 174174 }
270
271 static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29,
272 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C };
273 static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28,
274 0x28, 0x28, 0x28, 0x4C };
275
276 174174 static void encode_ac_coeffs(PutBitContext *pb,
277 int16_t *in, int blocks_per_slice, int *qmat, const uint8_t ff_prores_scan[64])
278 {
279 174174 int prev_run = 4;
280 174174 int prev_level = 2;
281
282 174174 int run = 0, level, code, i, j;
283
2/2
✓ Branch 0 taken 10972962 times.
✓ Branch 1 taken 174174 times.
11147136 for (i = 1; i < 64; i++) {
284 10972962 int indp = ff_prores_scan[i];
285
2/2
✓ Branch 0 taken 198401112 times.
✓ Branch 1 taken 10972962 times.
209374074 for (j = 0; j < blocks_per_slice; j++) {
286 198401112 int val = QSCALE(qmat, indp, in[(j << 6) + indp]);
287
2/2
✓ Branch 0 taken 89594568 times.
✓ Branch 1 taken 108806544 times.
198401112 if (val) {
288 89594568 encode_codeword(pb, run, run_to_cb[FFMIN(prev_run, 15)]);
289
290 89594568 prev_run = run;
291 89594568 run = 0;
292 89594568 level = get_level(val);
293 89594568 code = level - 1;
294
295 89594568 encode_codeword(pb, code, lev_to_cb[FFMIN(prev_level, 9)]);
296
297 89594568 prev_level = level;
298
299 89594568 put_bits(pb, 1, IS_NEGATIVE(val));
300 } else {
301 108806544 ++run;
302 }
303 }
304 }
305 174174 }
306
307 2397000 static void get(uint8_t *pixels, int stride, int16_t* block)
308 {
309 int i;
310
311
2/2
✓ Branch 0 taken 19176000 times.
✓ Branch 1 taken 2397000 times.
21573000 for (i = 0; i < 8; i++) {
312 19176000 AV_WN64(block, AV_RN64(pixels));
313 19176000 AV_WN64(block+4, AV_RN64(pixels+8));
314 19176000 pixels += stride;
315 19176000 block += 8;
316 }
317 2397000 }
318
319 2397000 static void fdct_get(FDCTDSPContext *fdsp, uint8_t *pixels, int stride, int16_t* block)
320 {
321 2397000 get(pixels, stride, block);
322 2397000 fdsp->fdct(block);
323 2397000 }
324
325 133800 static void calc_plane_dct(FDCTDSPContext *fdsp, uint8_t *src, int16_t * blocks, int src_stride, int mb_count, int chroma, int is_422)
326 {
327 int16_t *block;
328 int i;
329
330 133800 block = blocks;
331
332
2/2
✓ Branch 0 taken 44600 times.
✓ Branch 1 taken 89200 times.
133800 if (!chroma) { /* Luma plane */
333
2/2
✓ Branch 0 taken 239700 times.
✓ Branch 1 taken 44600 times.
284300 for (i = 0; i < mb_count; i++) {
334 239700 fdct_get(fdsp, src, src_stride, block + (0 << 6));
335 239700 fdct_get(fdsp, src + 16, src_stride, block + (1 << 6));
336 239700 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (2 << 6));
337 239700 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
338
339 239700 block += 256;
340 239700 src += 32;
341 }
342
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 */
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 + 8 * src_stride, src_stride, block + (1 << 6));
346 239700 block += (256 >> 1);
347 239700 src += (32 >> 1);
348 }
349 } else { /* chroma plane 444 */
350
2/2
✓ Branch 0 taken 239700 times.
✓ Branch 1 taken 44600 times.
284300 for (i = 0; i < mb_count; i++) {
351 239700 fdct_get(fdsp, src, src_stride, block + (0 << 6));
352 239700 fdct_get(fdsp, src + 8 * src_stride, src_stride, block + (1 << 6));
353 239700 fdct_get(fdsp, src + 16, src_stride, block + (2 << 6));
354 239700 fdct_get(fdsp, src + 16 + 8 * src_stride, src_stride, block + (3 << 6));
355
356 239700 block += 256;
357 239700 src += 32;
358 }
359 }
360 133800 }
361
362 174174 static int encode_slice_plane(int16_t *blocks, int mb_count, uint8_t *buf, unsigned buf_size, int *qmat, int sub_sample_chroma,
363 const uint8_t ff_prores_scan[64])
364 {
365 int blocks_per_slice;
366 PutBitContext pb;
367
368 174174 blocks_per_slice = mb_count << (2 - sub_sample_chroma);
369 174174 init_put_bits(&pb, buf, buf_size);
370
371 174174 encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat);
372 174174 encode_ac_coeffs(&pb, blocks, blocks_per_slice, qmat, ff_prores_scan);
373
374 174174 flush_put_bits(&pb);
375 174174 return put_bits_ptr(&pb) - pb.buf;
376 }
377
378 58058 static av_always_inline unsigned encode_slice_data(AVCodecContext *avctx,
379 int16_t * blocks_y, int16_t * blocks_u, int16_t * blocks_v,
380 unsigned mb_count, uint8_t *buf, unsigned data_size,
381 unsigned* y_data_size, unsigned* u_data_size, unsigned* v_data_size,
382 int qp)
383 {
384 58058 ProresContext* ctx = avctx->priv_data;
385
386 116116 *y_data_size = encode_slice_plane(blocks_y, mb_count,
387 58058 buf, data_size, ctx->qmat_luma[qp - 1], 0, ctx->scantable);
388
389
1/2
✓ Branch 0 taken 58058 times.
✗ Branch 1 not taken.
58058 if (!(avctx->flags & AV_CODEC_FLAG_GRAY)) {
390 116116 *u_data_size = encode_slice_plane(blocks_u, mb_count, buf + *y_data_size, data_size - *y_data_size,
391 58058 ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
392
393 58058 *v_data_size = encode_slice_plane(blocks_v, mb_count, buf + *y_data_size + *u_data_size,
394 58058 data_size - *y_data_size - *u_data_size,
395 58058 ctx->qmat_chroma[qp - 1], ctx->is_422, ctx->scantable);
396 }
397
398 58058 return *y_data_size + *u_data_size + *v_data_size;
399 }
400
401 static void put_alpha_diff(PutBitContext *pb, int cur, int prev)
402 {
403 const int abits = 16;
404 const int dbits = 7;
405 const int dsize = 1 << dbits - 1;
406 int diff = cur - prev;
407
408 diff = av_mod_uintp2(diff, abits);
409 if (diff >= (1 << abits) - dsize)
410 diff -= 1 << abits;
411 if (diff < -dsize || diff > dsize || !diff) {
412 put_bits(pb, 1, 1);
413 put_bits(pb, abits, diff);
414 } else {
415 put_bits(pb, 1, 0);
416 put_bits(pb, dbits - 1, FFABS(diff) - 1);
417 put_bits(pb, 1, diff < 0);
418 }
419 }
420
421 static inline void put_alpha_run(PutBitContext *pb, int run)
422 {
423 if (run) {
424 put_bits(pb, 1, 0);
425 if (run < 0x10)
426 put_bits(pb, 4, run);
427 else
428 put_bits(pb, 15, run);
429 } else {
430 put_bits(pb, 1, 1);
431 }
432 }
433
434 static av_always_inline int encode_alpha_slice_data(AVCodecContext *avctx, int8_t * src_a,
435 unsigned mb_count, uint8_t *buf, unsigned data_size, unsigned* a_data_size)
436 {
437 const int abits = 16;
438 const int mask = (1 << abits) - 1;
439 const int num_coeffs = mb_count * 256;
440 int prev = mask, cur;
441 int idx = 0;
442 int run = 0;
443 int16_t * blocks = (int16_t *)src_a;
444 PutBitContext pb;
445 init_put_bits(&pb, buf, data_size);
446
447 cur = blocks[idx++];
448 put_alpha_diff(&pb, cur, prev);
449 prev = cur;
450 do {
451 cur = blocks[idx++];
452 if (cur != prev) {
453 put_alpha_run (&pb, run);
454 put_alpha_diff(&pb, cur, prev);
455 prev = cur;
456 run = 0;
457 } else {
458 run++;
459 }
460 } while (idx < num_coeffs);
461 if (run)
462 put_alpha_run(&pb, run);
463 flush_put_bits(&pb);
464 *a_data_size = put_bytes_output(&pb);
465
466 if (put_bits_left(&pb) < 0) {
467 av_log(avctx, AV_LOG_ERROR,
468 "Underestimated required buffer size.\n");
469 return AVERROR_BUG;
470 } else {
471 return 0;
472 }
473 }
474
475 3000 static inline void subimage_with_fill_template(uint16_t *src, unsigned x, unsigned y,
476 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
477 unsigned dst_width, unsigned dst_height, int is_alpha_plane,
478 int is_interlaced, int is_top_field)
479 {
480 3000 int box_width = FFMIN(width - x, dst_width);
481 int i, j, src_stride, box_height;
482 uint16_t last_pix, *last_line;
483
484
2/2
✓ Branch 0 taken 1200 times.
✓ Branch 1 taken 1800 times.
3000 if (!is_interlaced) {
485 1200 src_stride = stride >> 1;
486 1200 src += y * src_stride + x;
487 1200 box_height = FFMIN(height - y, dst_height);
488 } else {
489 1800 src_stride = stride; /* 2 lines stride */
490 1800 src += y * src_stride + x;
491 1800 box_height = FFMIN(height/2 - y, dst_height);
492
2/2
✓ Branch 0 taken 900 times.
✓ Branch 1 taken 900 times.
1800 if (!is_top_field)
493 900 src += stride >> 1;
494 }
495
496
2/2
✓ Branch 0 taken 21600 times.
✓ Branch 1 taken 3000 times.
24600 for (i = 0; i < box_height; ++i) {
497
2/2
✓ Branch 0 taken 66000 times.
✓ Branch 1 taken 21600 times.
87600 for (j = 0; j < box_width; ++j) {
498
1/2
✓ Branch 0 taken 66000 times.
✗ Branch 1 not taken.
66000 if (!is_alpha_plane) {
499 66000 dst[j] = src[j];
500 } else {
501 dst[j] = src[j] << 6; /* alpha 10b to 16b */
502 }
503 }
504
1/2
✓ Branch 0 taken 21600 times.
✗ Branch 1 not taken.
21600 if (!is_alpha_plane) {
505 21600 last_pix = dst[j - 1];
506 } else {
507 last_pix = dst[j - 1] << 6; /* alpha 10b to 16b */
508 }
509
2/2
✓ Branch 0 taken 238000 times.
✓ Branch 1 taken 21600 times.
259600 for (; j < dst_width; j++)
510 238000 dst[j] = last_pix;
511 21600 src += src_stride;
512 21600 dst += dst_width;
513 }
514 3000 last_line = dst - dst_width;
515
2/2
✓ Branch 0 taken 26400 times.
✓ Branch 1 taken 3000 times.
29400 for (; i < dst_height; i++) {
516
2/2
✓ Branch 0 taken 528000 times.
✓ Branch 1 taken 26400 times.
554400 for (j = 0; j < dst_width; ++j) {
517 528000 dst[j] = last_line[j];
518 }
519 26400 dst += dst_width;
520 }
521 3000 }
522
523 3000 static void subimage_with_fill(uint16_t *src, unsigned x, unsigned y,
524 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
525 unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
526 {
527 3000 subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 0, is_interlaced, is_top_field);
528 3000 }
529
530 /* reorganize alpha data and convert 10b -> 16b */
531 static void subimage_alpha_with_fill(uint16_t *src, unsigned x, unsigned y,
532 unsigned stride, unsigned width, unsigned height, uint16_t *dst,
533 unsigned dst_width, unsigned dst_height, int is_interlaced, int is_top_field)
534 {
535 subimage_with_fill_template(src, x, y, stride, width, height, dst, dst_width, dst_height, 1, is_interlaced, is_top_field);
536 }
537
538 44600 static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, int mb_x,
539 int mb_y, unsigned mb_count, uint8_t *buf, unsigned data_size,
540 int unsafe, int *qp, int is_interlaced, int is_top_field)
541 {
542 44600 int luma_stride, chroma_stride, alpha_stride = 0;
543 44600 ProresContext* ctx = avctx->priv_data;
544 44600 int hdr_size = 6 + (ctx->need_alpha * 2); /* v data size is write when there is alpha */
545 44600 int ret = 0, slice_size;
546 uint8_t *dest_y, *dest_u, *dest_v;
547 44600 unsigned y_data_size = 0, u_data_size = 0, v_data_size = 0, a_data_size = 0;
548 44600 FDCTDSPContext *fdsp = &ctx->fdsp;
549 44600 int tgt_bits = (mb_count * bitrate_table[avctx->profile]) >> 2;
550 44600 int low_bytes = (tgt_bits - (tgt_bits >> 3)) >> 3; // 12% bitrate fluctuation
551 44600 int high_bytes = (tgt_bits + (tgt_bits >> 3)) >> 3;
552
553 44600 LOCAL_ALIGNED(16, int16_t, blocks_y, [DEFAULT_SLICE_MB_WIDTH << 8]);
554 44600 LOCAL_ALIGNED(16, int16_t, blocks_u, [DEFAULT_SLICE_MB_WIDTH << 8]);
555 44600 LOCAL_ALIGNED(16, int16_t, blocks_v, [DEFAULT_SLICE_MB_WIDTH << 8]);
556
557 44600 luma_stride = pic->linesize[0];
558 44600 chroma_stride = pic->linesize[1];
559
560
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44600 times.
44600 if (ctx->need_alpha)
561 alpha_stride = pic->linesize[3];
562
563
2/2
✓ Branch 0 taken 22200 times.
✓ Branch 1 taken 22400 times.
44600 if (!is_interlaced) {
564 22200 dest_y = pic->data[0] + (mb_y << 4) * luma_stride + (mb_x << 5);
565 22200 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
566 22200 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride + (mb_x << (5 - ctx->is_422));
567 } else {
568 22400 dest_y = pic->data[0] + (mb_y << 4) * luma_stride * 2 + (mb_x << 5);
569 22400 dest_u = pic->data[1] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
570 22400 dest_v = pic->data[2] + (mb_y << 4) * chroma_stride * 2 + (mb_x << (5 - ctx->is_422));
571
2/2
✓ Branch 0 taken 11200 times.
✓ Branch 1 taken 11200 times.
22400 if (!is_top_field){ /* bottom field, offset dest */
572 11200 dest_y += luma_stride;
573 11200 dest_u += chroma_stride;
574 11200 dest_v += chroma_stride;
575 }
576 }
577
578
2/2
✓ Branch 0 taken 1000 times.
✓ Branch 1 taken 43600 times.
44600 if (unsafe) {
579 1000 subimage_with_fill((uint16_t *) pic->data[0], mb_x << 4, mb_y << 4,
580 1000 luma_stride, avctx->width, avctx->height,
581 1000 (uint16_t *) ctx->fill_y, mb_count << 4, 16, is_interlaced, is_top_field);
582 1000 subimage_with_fill((uint16_t *) pic->data[1], mb_x << (4 - ctx->is_422), mb_y << 4,
583 1000 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
584 1000 (uint16_t *) ctx->fill_u, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
585 1000 subimage_with_fill((uint16_t *) pic->data[2], mb_x << (4 - ctx->is_422), mb_y << 4,
586 1000 chroma_stride, avctx->width >> ctx->is_422, avctx->height,
587 1000 (uint16_t *) ctx->fill_v, mb_count << (4 - ctx->is_422), 16, is_interlaced, is_top_field);
588
589 /* no need for interlaced special case, data already reorganized in subimage_with_fill */
590 1000 calc_plane_dct(fdsp, ctx->fill_y, blocks_y, mb_count << 5, mb_count, 0, 0);
591 1000 calc_plane_dct(fdsp, ctx->fill_u, blocks_u, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
592 1000 calc_plane_dct(fdsp, ctx->fill_v, blocks_v, mb_count << (5 - ctx->is_422), mb_count, 1, ctx->is_422);
593
594 1000 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
595 mb_count, buf + hdr_size, data_size - hdr_size,
596 &y_data_size, &u_data_size, &v_data_size,
597 *qp);
598 } else {
599
2/2
✓ Branch 0 taken 21800 times.
✓ Branch 1 taken 21800 times.
43600 if (!is_interlaced) {
600 21800 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride, mb_count, 0, 0);
601 21800 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride, mb_count, 1, ctx->is_422);
602 21800 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride, mb_count, 1, ctx->is_422);
603 } else {
604 21800 calc_plane_dct(fdsp, dest_y, blocks_y, luma_stride * 2, mb_count, 0, 0);
605 21800 calc_plane_dct(fdsp, dest_u, blocks_u, chroma_stride * 2, mb_count, 1, ctx->is_422);
606 21800 calc_plane_dct(fdsp, dest_v, blocks_v, chroma_stride * 2, mb_count, 1, ctx->is_422);
607 }
608
609 43600 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
610 mb_count, buf + hdr_size, data_size - hdr_size,
611 &y_data_size, &u_data_size, &v_data_size,
612 *qp);
613
614
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]) {
615 do {
616 8982 *qp += 1;
617 8982 slice_size = encode_slice_data(avctx, blocks_y, blocks_u, blocks_v,
618 mb_count, buf + hdr_size, data_size - hdr_size,
619 &y_data_size, &u_data_size, &v_data_size,
620 *qp);
621
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]);
622
2/2
✓ Branch 0 taken 2317 times.
✓ Branch 1 taken 37631 times.
39948 } else if (slice_size < low_bytes && *qp
623
2/2
✓ Branch 0 taken 2312 times.
✓ Branch 1 taken 5 times.
2317 > qp_start_table[avctx->profile]) {
624 do {
625 4476 *qp -= 1;
626 4476 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 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]);
631 }
632 }
633
634 44600 buf[0] = hdr_size << 3;
635 44600 buf[1] = *qp;
636 44600 AV_WB16(buf + 2, y_data_size);
637 44600 AV_WB16(buf + 4, u_data_size);
638
639
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44600 times.
44600 if (ctx->need_alpha) {
640 AV_WB16(buf + 6, v_data_size); /* write v data size only if there is alpha */
641
642 subimage_alpha_with_fill((uint16_t *) pic->data[3], mb_x << 4, mb_y << 4,
643 alpha_stride, avctx->width, avctx->height,
644 (uint16_t *) ctx->fill_a, mb_count << 4, 16, is_interlaced, is_top_field);
645 ret = encode_alpha_slice_data(avctx, ctx->fill_a, mb_count,
646 buf + hdr_size + slice_size,
647 data_size - hdr_size - slice_size, &a_data_size);
648 }
649
650
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44600 times.
44600 if (ret != 0) {
651 return ret;
652 }
653 44600 return hdr_size + y_data_size + u_data_size + v_data_size + a_data_size;
654 }
655
656 1200 static int prores_encode_picture(AVCodecContext *avctx, const AVFrame *pic,
657 uint8_t *buf, const int buf_size, const int picture_index, const int is_top_field)
658 {
659 1200 ProresContext *ctx = avctx->priv_data;
660 1200 int mb_width = (avctx->width + 15) >> 4;
661 int hdr_size, sl_size, i;
662 int mb_y, sl_data_size, qp, mb_height, picture_height, unsafe_mb_height_limit;
663 int unsafe_bot, unsafe_right;
664 uint8_t *sl_data, *sl_data_sizes;
665 1200 int slice_per_line = 0, rem = mb_width;
666
667
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 800 times.
1200 if (!ctx->is_interlaced) { /* progressive encoding */
668 400 mb_height = (avctx->height + 15) >> 4;
669 400 unsafe_mb_height_limit = mb_height;
670 } else {
671
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 400 times.
800 if (is_top_field) {
672 400 picture_height = (avctx->height + 1) / 2;
673 } else {
674 400 picture_height = avctx->height / 2;
675 }
676 800 mb_height = (picture_height + 15) >> 4;
677 800 unsafe_mb_height_limit = mb_height;
678 }
679
680
2/2
✓ Branch 0 taken 4800 times.
✓ Branch 1 taken 1200 times.
6000 for (i = av_log2(DEFAULT_SLICE_MB_WIDTH); i >= 0; --i) {
681 4800 slice_per_line += rem >> i;
682 4800 rem &= (1 << i) - 1;
683 }
684
685 1200 qp = qp_start_table[avctx->profile];
686 1200 hdr_size = 8; sl_data_size = buf_size - hdr_size;
687 1200 sl_data_sizes = buf + hdr_size;
688 1200 sl_data = sl_data_sizes + (slice_per_line * mb_height * 2);
689
2/2
✓ Branch 0 taken 11500 times.
✓ Branch 1 taken 1200 times.
12700 for (mb_y = 0; mb_y < mb_height; mb_y++) {
690 11500 int mb_x = 0;
691 11500 int slice_mb_count = DEFAULT_SLICE_MB_WIDTH;
692
2/2
✓ Branch 0 taken 44600 times.
✓ Branch 1 taken 11500 times.
56100 while (mb_x < mb_width) {
693
2/2
✓ Branch 0 taken 23700 times.
✓ Branch 1 taken 44600 times.
68300 while (mb_width - mb_x < slice_mb_count)
694 23700 slice_mb_count >>= 1;
695
696
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);
697
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);
698
699
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,
700 sl_data, sl_data_size, unsafe_bot || unsafe_right, &qp, ctx->is_interlaced, is_top_field);
701
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 44600 times.
44600 if (sl_size < 0){
702 return sl_size;
703 }
704
705 44600 bytestream_put_be16(&sl_data_sizes, sl_size);
706 44600 sl_data += sl_size;
707 44600 sl_data_size -= sl_size;
708 44600 mb_x += slice_mb_count;
709 }
710 }
711
712 1200 buf[0] = hdr_size << 3;
713 1200 AV_WB32(buf + 1, sl_data - buf);
714 1200 AV_WB16(buf + 5, slice_per_line * mb_height); /* picture size */
715 1200 buf[7] = av_log2(DEFAULT_SLICE_MB_WIDTH) << 4; /* number of slices */
716
717 1200 return sl_data - buf;
718 }
719
720 800 static int prores_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
721 const AVFrame *pict, int *got_packet)
722 {
723 800 ProresContext *ctx = avctx->priv_data;
724 800 int header_size = 148;
725 uint8_t *buf;
726 800 int compress_frame_size, pic_size, ret, is_top_field_first = 0;
727 uint8_t frame_flags;
728 800 int frame_size = FFALIGN(avctx->width, 16) * FFALIGN(avctx->height, 16)*16 + 500 + AV_INPUT_BUFFER_MIN_SIZE; //FIXME choose tighter limit
729
730
731
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 800 times.
800 if ((ret = ff_alloc_packet(avctx, pkt, frame_size + AV_INPUT_BUFFER_MIN_SIZE)) < 0)
732 return ret;
733
734 800 buf = pkt->data;
735 800 compress_frame_size = 8 + header_size;
736
737 800 bytestream_put_be32(&buf, compress_frame_size);/* frame size will be update after picture(s) encoding */
738 800 bytestream_put_buffer(&buf, "icpf", 4);
739
740 800 bytestream_put_be16(&buf, header_size);
741 800 bytestream_put_be16(&buf, 0); /* version */
742 800 bytestream_put_buffer(&buf, ctx->vendor, 4);
743 800 bytestream_put_be16(&buf, avctx->width);
744 800 bytestream_put_be16(&buf, avctx->height);
745 800 frame_flags = 0x82; /* 422 not interlaced */
746
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 400 times.
800 if (avctx->profile >= FF_PROFILE_PRORES_4444) /* 4444 or 4444 Xq */
747 400 frame_flags |= 0x40; /* 444 chroma */
748
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 400 times.
800 if (ctx->is_interlaced) {
749
2/4
✓ Branch 0 taken 400 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 400 times.
✗ Branch 3 not taken.
400 if (pict->top_field_first || !pict->interlaced_frame) { /* tff frame or progressive frame interpret as tff */
750 400 av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, top field first\n");
751 400 frame_flags |= 0x04; /* interlaced tff */
752 400 is_top_field_first = 1;
753 } else {
754 av_log(avctx, AV_LOG_DEBUG, "use interlaced encoding, bottom field first\n");
755 frame_flags |= 0x08; /* interlaced bff */
756 }
757 } else {
758 400 av_log(avctx, AV_LOG_DEBUG, "use progressive encoding\n");
759 }
760 800 *buf++ = frame_flags;
761 800 *buf++ = 0; /* reserved */
762 /* only write color properties, if valid value. set to unspecified otherwise */
763 800 *buf++ = ff_int_from_list_or_default(avctx, "frame color primaries", pict->color_primaries, valid_primaries, 0);
764 800 *buf++ = ff_int_from_list_or_default(avctx, "frame color trc", pict->color_trc, valid_trc, 0);
765 800 *buf++ = ff_int_from_list_or_default(avctx, "frame colorspace", pict->colorspace, valid_colorspace, 0);
766
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 400 times.
800 if (avctx->profile >= FF_PROFILE_PRORES_4444) {
767
1/2
✓ Branch 0 taken 400 times.
✗ Branch 1 not taken.
400 if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
768 400 *buf++ = 0xA0;/* src b64a and no alpha */
769 } else {
770 *buf++ = 0xA2;/* src b64a and 16b alpha */
771 }
772 } else {
773 400 *buf++ = 32;/* src v210 and no alpha */
774 }
775 800 *buf++ = 0; /* reserved */
776 800 *buf++ = 3; /* luma and chroma matrix present */
777
778 800 bytestream_put_buffer(&buf, QMAT_LUMA[avctx->profile], 64);
779 800 bytestream_put_buffer(&buf, QMAT_CHROMA[avctx->profile], 64);
780
781 800 pic_size = prores_encode_picture(avctx, pict, buf,
782 800 pkt->size - compress_frame_size, 0, is_top_field_first);/* encode progressive or first field */
783
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 800 times.
800 if (pic_size < 0) {
784 return pic_size;
785 }
786 800 compress_frame_size += pic_size;
787
788
2/2
✓ Branch 0 taken 400 times.
✓ Branch 1 taken 400 times.
800 if (ctx->is_interlaced) { /* encode second field */
789 400 pic_size = prores_encode_picture(avctx, pict, pkt->data + compress_frame_size,
790 400 pkt->size - compress_frame_size, 1, !is_top_field_first);
791
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 400 times.
400 if (pic_size < 0) {
792 return pic_size;
793 }
794 400 compress_frame_size += pic_size;
795 }
796
797 800 AV_WB32(pkt->data, compress_frame_size);/* update frame size */
798 800 pkt->flags |= AV_PKT_FLAG_KEY;
799 800 pkt->size = compress_frame_size;
800 800 *got_packet = 1;
801
802 800 return 0;
803 }
804
805 512 static void scale_mat(const uint8_t* src, int* dst, int scale)
806 {
807 int i;
808
2/2
✓ Branch 0 taken 32768 times.
✓ Branch 1 taken 512 times.
33280 for (i = 0; i < 64; i++)
809 32768 dst[i] = src[i] * scale;
810 512 }
811
812 16 static av_cold int prores_encode_init(AVCodecContext *avctx)
813 {
814 int i;
815 16 ProresContext* ctx = avctx->priv_data;
816
817 16 avctx->bits_per_raw_sample = 10;
818 16 ctx->need_alpha = 0;
819 16 ctx->is_interlaced = !!(avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT);
820
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (ctx->is_interlaced) {
821 8 ctx->scantable = ff_prores_interlaced_scan;
822 } else {
823 8 ctx->scantable = ff_prores_progressive_scan;
824 }
825
826
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (avctx->width & 0x1) {
827 av_log(avctx, AV_LOG_ERROR,
828 "frame width needs to be multiple of 2\n");
829 return AVERROR(EINVAL);
830 }
831
832
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) {
833 av_log(avctx, AV_LOG_ERROR,
834 "The maximum dimensions are 65534x65535\n");
835 return AVERROR(EINVAL);
836 }
837
838
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (strlen(ctx->vendor) != 4) {
839 av_log(avctx, AV_LOG_ERROR, "vendor ID should be 4 bytes\n");
840 return AVERROR(EINVAL);
841 }
842
843
1/2
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
16 if (avctx->profile == FF_PROFILE_UNKNOWN) {
844
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (avctx->pix_fmt == AV_PIX_FMT_YUV422P10) {
845 8 avctx->profile = FF_PROFILE_PRORES_STANDARD;
846 8 av_log(avctx, AV_LOG_INFO,
847 "encoding with ProRes standard (apcn) profile\n");
848
1/2
✓ Branch 0 taken 8 times.
✗ Branch 1 not taken.
8 } else if (avctx->pix_fmt == AV_PIX_FMT_YUV444P10) {
849 8 avctx->profile = FF_PROFILE_PRORES_4444;
850 8 av_log(avctx, AV_LOG_INFO,
851 "encoding with ProRes 4444 (ap4h) profile\n");
852 } else if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
853 avctx->profile = FF_PROFILE_PRORES_4444;
854 av_log(avctx, AV_LOG_INFO,
855 "encoding with ProRes 4444+ (ap4h) profile\n");
856 } else {
857 av_log(avctx, AV_LOG_ERROR, "Unknown pixel format\n");
858 return AVERROR(EINVAL);
859 }
860 } else if (avctx->profile < FF_PROFILE_PRORES_PROXY
861 || avctx->profile > FF_PROFILE_PRORES_XQ) {
862 av_log(
863 avctx,
864 AV_LOG_ERROR,
865 "unknown profile %d, use [0 - apco, 1 - apcs, 2 - apcn (default), 3 - apch, 4 - ap4h, 5 - ap4x]\n",
866 avctx->profile);
867 return AVERROR(EINVAL);
868 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV422P10) && (avctx->profile > FF_PROFILE_PRORES_HQ)){
869 av_log(avctx, AV_LOG_ERROR,
870 "encoding with ProRes 444/Xq (ap4h/ap4x) profile, need YUV444P10 input\n");
871 return AVERROR(EINVAL);
872 } else if ((avctx->pix_fmt == AV_PIX_FMT_YUV444P10 || avctx->pix_fmt == AV_PIX_FMT_YUVA444P10)
873 && (avctx->profile < FF_PROFILE_PRORES_4444)){
874 av_log(avctx, AV_LOG_ERROR,
875 "encoding with ProRes Proxy/LT/422/422 HQ (apco, apcs, apcn, ap4h) profile, need YUV422P10 input\n");
876 return AVERROR(EINVAL);
877 }
878
879
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 8 times.
16 if (avctx->profile < FF_PROFILE_PRORES_4444) { /* 422 versions */
880 8 ctx->is_422 = 1;
881
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)) {
882 2 ctx->fill_y = av_malloc(4 * (DEFAULT_SLICE_MB_WIDTH << 8));
883
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!ctx->fill_y)
884 return AVERROR(ENOMEM);
885 2 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
886 2 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 8);
887 }
888 } else { /* 444 */
889 8 ctx->is_422 = 0;
890
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)) {
891 2 ctx->fill_y = av_malloc(3 * (DEFAULT_SLICE_MB_WIDTH << 9));
892
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!ctx->fill_y)
893 return AVERROR(ENOMEM);
894 2 ctx->fill_u = ctx->fill_y + (DEFAULT_SLICE_MB_WIDTH << 9);
895 2 ctx->fill_v = ctx->fill_u + (DEFAULT_SLICE_MB_WIDTH << 9);
896 }
897
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (avctx->pix_fmt == AV_PIX_FMT_YUVA444P10) {
898 ctx->need_alpha = 1;
899 ctx->fill_a = av_malloc(DEFAULT_SLICE_MB_WIDTH << 9); /* 8 blocks x 16px x 16px x sizeof (uint16) */
900 if (!ctx->fill_a)
901 return AVERROR(ENOMEM);
902 }
903 }
904
905 16 ff_fdctdsp_init(&ctx->fdsp, avctx);
906
907 16 avctx->codec_tag = AV_RL32((const uint8_t*)profiles[avctx->profile].name);
908
909
2/2
✓ Branch 0 taken 256 times.
✓ Branch 1 taken 16 times.
272 for (i = 1; i <= 16; i++) {
910 256 scale_mat(QMAT_LUMA[avctx->profile] , ctx->qmat_luma[i - 1] , i);
911 256 scale_mat(QMAT_CHROMA[avctx->profile], ctx->qmat_chroma[i - 1], i);
912 }
913
914 16 return 0;
915 }
916
917 16 static av_cold int prores_encode_close(AVCodecContext *avctx)
918 {
919 16 ProresContext* ctx = avctx->priv_data;
920 16 av_freep(&ctx->fill_y);
921 16 av_freep(&ctx->fill_a);
922
923 16 return 0;
924 }
925
926 #define OFFSET(x) offsetof(ProresContext, x)
927 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
928
929 static const AVOption options[] = {
930 { "vendor", "vendor ID", OFFSET(vendor), AV_OPT_TYPE_STRING, { .str = "fmpg" }, 0, 0, VE },
931 { NULL }
932 };
933
934 static const AVClass prores_enc_class = {
935 .class_name = "ProRes encoder",
936 .item_name = av_default_item_name,
937 .option = options,
938 .version = LIBAVUTIL_VERSION_INT,
939 };
940
941 static const enum AVPixelFormat pix_fmts[] = {
942 AV_PIX_FMT_YUV422P10, AV_PIX_FMT_YUV444P10,
943 AV_PIX_FMT_YUVA444P10, AV_PIX_FMT_NONE
944 };
945
946 const AVCodec ff_prores_aw_encoder = {
947 .name = "prores_aw",
948 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
949 .type = AVMEDIA_TYPE_VIDEO,
950 .id = AV_CODEC_ID_PRORES,
951 .pix_fmts = pix_fmts,
952 .priv_data_size = sizeof(ProresContext),
953 .init = prores_encode_init,
954 .close = prores_encode_close,
955 .encode2 = prores_encode_frame,
956 .capabilities = AV_CODEC_CAP_FRAME_THREADS,
957 .priv_class = &prores_enc_class,
958 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
959 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
960 };
961
962 const AVCodec ff_prores_encoder = {
963 .name = "prores",
964 .long_name = NULL_IF_CONFIG_SMALL("Apple ProRes"),
965 .type = AVMEDIA_TYPE_VIDEO,
966 .id = AV_CODEC_ID_PRORES,
967 .pix_fmts = pix_fmts,
968 .priv_data_size = sizeof(ProresContext),
969 .init = prores_encode_init,
970 .close = prores_encode_close,
971 .encode2 = prores_encode_frame,
972 .capabilities = AV_CODEC_CAP_FRAME_THREADS,
973 .priv_class = &prores_enc_class,
974 .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles),
975 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP,
976 };
977