FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/formats.c
Date: 2025-06-01 09:29:47
Exec Total Coverage
Lines: 328 399 82.2%
Functions: 62 72 86.1%
Branches: 435 594 73.2%

Line Branch Exec Source
1 /*
2 * Filter layer - format negotiation
3 * Copyright (c) 2007 Bobby Bingham
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "libavutil/avassert.h"
23 #include "libavutil/channel_layout.h"
24 #include "libavutil/common.h"
25 #include "libavutil/mem.h"
26 #include "libavutil/pixdesc.h"
27 #include "avfilter.h"
28 #include "filters.h"
29 #include "formats.h"
30
31 /**
32 * Add all refs from a to ret and destroy a.
33 */
34 #define MERGE_REF(ret, a, fmts, type, fail_statement) \
35 do { \
36 type ***tmp; \
37 int i; \
38 \
39 if (!(tmp = av_realloc_array(ret->refs, ret->refcount + a->refcount, \
40 sizeof(*tmp)))) \
41 { fail_statement } \
42 ret->refs = tmp; \
43 \
44 for (i = 0; i < a->refcount; i ++) { \
45 ret->refs[ret->refcount] = a->refs[i]; \
46 *ret->refs[ret->refcount++] = ret; \
47 } \
48 \
49 av_freep(&a->refs); \
50 av_freep(&a->fmts); \
51 av_freep(&a); \
52 } while (0)
53
54 /**
55 * Add all formats common to a and b to a, add b's refs to a and destroy b.
56 * If check is set, nothing is modified and it is only checked whether
57 * the formats are compatible.
58 * If empty_allowed is set and one of a,b->nb is zero, the lists are
59 * merged; otherwise, 0 (for nonmergeability) is returned.
60 */
61 #define MERGE_FORMATS(a, b, fmts, nb, type, check, empty_allowed) \
62 do { \
63 int i, j, k = 0, skip = 0; \
64 \
65 if (empty_allowed) { \
66 if (!a->nb || !b->nb) { \
67 if (check) \
68 return 1; \
69 if (!a->nb) \
70 FFSWAP(type *, a, b); \
71 skip = 1; \
72 } \
73 } \
74 if (!skip) { \
75 for (i = 0; i < a->nb; i++) \
76 for (j = 0; j < b->nb; j++) \
77 if (a->fmts[i] == b->fmts[j]) { \
78 if (check) \
79 return 1; \
80 a->fmts[k++] = a->fmts[i]; \
81 break; \
82 } \
83 /* Check that there was at least one common format. \
84 * Notice that both a and b are unchanged if not. */ \
85 if (!k) \
86 return 0; \
87 av_assert2(!check); \
88 a->nb = k; \
89 } \
90 \
91 MERGE_REF(a, b, fmts, type, return AVERROR(ENOMEM);); \
92 } while (0)
93
94 70477 static int merge_formats_internal(AVFilterFormats *a, AVFilterFormats *b,
95 enum AVMediaType type, int check)
96 {
97 int i, j;
98 70477 int alpha1=0, alpha2=0;
99 70477 int chroma1=0, chroma2=0;
100
101 av_assert2(check || (a->refcount && b->refcount));
102
103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70477 times.
70477 if (a == b)
104 return 1;
105
106 /* Do not lose chroma or alpha in merging.
107 It happens if both lists have formats with chroma (resp. alpha), but
108 the only formats in common do not have it (e.g. YUV+gray vs.
109 RGB+gray): in that case, the merging would select the gray format,
110 possibly causing a lossy conversion elsewhere in the graph.
111 To avoid that, pretend that there are no common formats to force the
112 insertion of a conversion filter. */
113
2/2
✓ Branch 0 taken 59310 times.
✓ Branch 1 taken 11167 times.
70477 if (type == AVMEDIA_TYPE_VIDEO)
114
2/2
✓ Branch 0 taken 3145832 times.
✓ Branch 1 taken 59310 times.
3205142 for (i = 0; i < a->nb_formats; i++) {
115 3145832 const AVPixFmtDescriptor *const adesc = av_pix_fmt_desc_get(a->formats[i]);
116
2/2
✓ Branch 0 taken 177114807 times.
✓ Branch 1 taken 3145832 times.
180260639 for (j = 0; j < b->nb_formats; j++) {
117 177114807 const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
118 177114807 alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA;
119
4/4
✓ Branch 0 taken 154413230 times.
✓ Branch 1 taken 22701577 times.
✓ Branch 2 taken 133900643 times.
✓ Branch 3 taken 20512587 times.
177114807 chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
120
2/2
✓ Branch 0 taken 702666 times.
✓ Branch 1 taken 176412141 times.
177114807 if (a->formats[i] == b->formats[j]) {
121 702666 alpha1 |= adesc->flags & AV_PIX_FMT_FLAG_ALPHA;
122 702666 chroma1|= adesc->nb_components > 1;
123 }
124 }
125 }
126
127 // If chroma or alpha can be lost through merging then do not merge
128
4/4
✓ Branch 0 taken 70456 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 553 times.
✓ Branch 3 taken 69903 times.
70477 if (alpha2 > alpha1 || chroma2 > chroma1)
129 574 return 0;
130
131
14/16
✓ Branch 0 taken 69903 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 394758 times.
✓ Branch 3 taken 45002373 times.
✓ Branch 4 taken 33367 times.
✓ Branch 5 taken 361391 times.
✓ Branch 6 taken 45397131 times.
✓ Branch 7 taken 1823604 times.
✓ Branch 8 taken 2218362 times.
✓ Branch 9 taken 36536 times.
✓ Branch 10 taken 666 times.
✓ Branch 11 taken 35870 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 35870 times.
✓ Branch 15 taken 79805 times.
✓ Branch 16 taken 35870 times.
47337076 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0);
132
133 35870 return 1;
134 }
135
136
137 /**
138 * Check the formats lists for compatibility for merging without actually
139 * merging.
140 *
141 * @return 1 if they are compatible, 0 if not.
142 */
143 29344 static int can_merge_pix_fmts(const void *a, const void *b)
144 {
145 29344 return merge_formats_internal((AVFilterFormats *)a,
146 (AVFilterFormats *)b, AVMEDIA_TYPE_VIDEO, 1);
147 }
148
149 /**
150 * Merge the formats lists if they are compatible and update all the
151 * references of a and b to point to the combined list and free the old
152 * lists as needed. The combined list usually contains the intersection of
153 * the lists of a and b.
154 *
155 * Both a and b must have owners (i.e. refcount > 0) for these functions.
156 *
157 * @return 1 if merging succeeded, 0 if a and b are incompatible
158 * and negative AVERROR code on failure.
159 * a and b are unmodified if 0 is returned.
160 */
161 29966 static int merge_pix_fmts(void *a, void *b)
162 {
163 29966 return merge_formats_internal(a, b, AVMEDIA_TYPE_VIDEO, 0);
164 }
165
166 /**
167 * See can_merge_pix_fmts().
168 */
169 5263 static int can_merge_sample_fmts(const void *a, const void *b)
170 {
171 5263 return merge_formats_internal((AVFilterFormats *)a,
172 (AVFilterFormats *)b, AVMEDIA_TYPE_AUDIO, 1);
173 }
174
175 /**
176 * See merge_pix_fmts().
177 */
178 5904 static int merge_sample_fmts(void *a, void *b)
179 {
180 5904 return merge_formats_internal(a, b, AVMEDIA_TYPE_AUDIO, 0);
181 }
182
183 11171 static int merge_samplerates_internal(AVFilterFormats *a,
184 AVFilterFormats *b, int check)
185 {
186 av_assert2(check || (a->refcount && b->refcount));
187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11171 times.
11171 if (a == b) return 1;
188
189
23/24
✓ Branch 0 taken 7071 times.
✓ Branch 1 taken 4100 times.
✓ Branch 2 taken 6946 times.
✓ Branch 3 taken 125 times.
✓ Branch 4 taken 5190 times.
✓ Branch 5 taken 5856 times.
✓ Branch 6 taken 2365 times.
✓ Branch 7 taken 3491 times.
✓ Branch 8 taken 125 times.
✓ Branch 9 taken 5856 times.
✓ Branch 10 taken 121 times.
✓ Branch 11 taken 46 times.
✓ Branch 12 taken 73 times.
✓ Branch 13 taken 48 times.
✓ Branch 14 taken 167 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 125 times.
✓ Branch 17 taken 52 times.
✓ Branch 18 taken 4 times.
✓ Branch 19 taken 48 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 5904 times.
✓ Branch 23 taken 26374 times.
✓ Branch 24 taken 5904 times.
37643 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 1);
190 5904 return 1;
191 }
192
193 /**
194 * See can_merge_pix_fmts().
195 */
196 5267 static int can_merge_samplerates(const void *a, const void *b)
197 {
198 5267 return merge_samplerates_internal((AVFilterFormats *)a, (AVFilterFormats *)b, 1);
199 }
200
201 /**
202 * See merge_pix_fmts().
203 */
204 5904 static int merge_samplerates(void *a, void *b)
205 {
206 5904 return merge_samplerates_internal(a, b, 0);
207 }
208
209 /**
210 * See merge_pix_fmts().
211 */
212 6598 static int merge_channel_layouts_internal(AVFilterChannelLayouts *a,
213 AVFilterChannelLayouts *b, int check)
214 {
215 6598 AVChannelLayout *channel_layouts = NULL;
216 6598 unsigned a_all = a->all_layouts + a->all_counts;
217 6598 unsigned b_all = b->all_layouts + b->all_counts;
218 6598 int ret_max, ret_nb = 0, i, j, round;
219
220 av_assert2(a->refcount && b->refcount);
221
222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6598 times.
6598 if (a == b) return 1;
223
224 /* Put the most generic set in a, to avoid doing everything twice */
225
2/2
✓ Branch 0 taken 3325 times.
✓ Branch 1 taken 3273 times.
6598 if (a_all < b_all) {
226 3325 FFSWAP(AVFilterChannelLayouts *, a, b);
227 3325 FFSWAP(unsigned, a_all, b_all);
228 }
229
2/2
✓ Branch 0 taken 6419 times.
✓ Branch 1 taken 179 times.
6598 if (a_all) {
230
3/4
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 6349 times.
✓ Branch 2 taken 70 times.
✗ Branch 3 not taken.
6419 if (a_all == 1 && !b_all) {
231 /* keep only known layouts in b; works also for b_all = 1 */
232
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 70 times.
140 for (i = j = 0; i < b->nb_channel_layouts; i++)
233
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 70 times.
70 if (KNOWN(&b->channel_layouts[i]) && i != j++) {
234 if (check)
235 return 1;
236 av_channel_layout_copy(&b->channel_layouts[j], &b->channel_layouts[i]);
237 }
238 /* Not optimal: the unknown layouts of b may become known after
239 another merge. */
240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
70 if (!j)
241 return 0;
242 70 b->nb_channel_layouts = j;
243 }
244
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 6419 times.
✓ Branch 3 taken 11077 times.
✓ Branch 4 taken 6419 times.
17496 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, return AVERROR(ENOMEM););
245 6419 return 1;
246 }
247
248 179 ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
249
3/4
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 115 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 64 times.
179 if (!check && !(channel_layouts = av_calloc(ret_max, sizeof(*channel_layouts))))
250 return AVERROR(ENOMEM);
251
252 /* a[known] intersect b[known] */
253
2/2
✓ Branch 0 taken 179 times.
✓ Branch 1 taken 72 times.
251 for (i = 0; i < a->nb_channel_layouts; i++) {
254
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 178 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
179 if (!KNOWN(&a->channel_layouts[i]))
255 1 continue;
256
2/2
✓ Branch 0 taken 274 times.
✓ Branch 1 taken 7 times.
281 for (j = 0; j < b->nb_channel_layouts; j++) {
257
2/2
✓ Branch 1 taken 171 times.
✓ Branch 2 taken 103 times.
274 if (!av_channel_layout_compare(&a->channel_layouts[i], &b->channel_layouts[j])) {
258
2/2
✓ Branch 0 taken 107 times.
✓ Branch 1 taken 64 times.
171 if (check)
259 107 return 1;
260 64 av_channel_layout_copy(&channel_layouts[ret_nb++], &a->channel_layouts[i]);
261 64 av_channel_layout_uninit(&a->channel_layouts[i]);
262 64 av_channel_layout_uninit(&b->channel_layouts[j]);
263 64 break;
264 }
265 }
266 }
267 /* 1st round: a[known] intersect b[generic]
268 2nd round: a[generic] intersect b[known] */
269
2/2
✓ Branch 0 taken 144 times.
✓ Branch 1 taken 71 times.
215 for (round = 0; round < 2; round++) {
270
2/2
✓ Branch 0 taken 230 times.
✓ Branch 1 taken 143 times.
373 for (i = 0; i < a->nb_channel_layouts; i++) {
271 230 AVChannelLayout *fmt = &a->channel_layouts[i], bfmt = { 0 };
272
5/6
✓ Branch 1 taken 102 times.
✓ Branch 2 taken 128 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 101 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
230 if (!av_channel_layout_check(fmt) || !KNOWN(fmt))
273 129 continue;
274 101 bfmt = FF_COUNT2LAYOUT(fmt->nb_channels);
275
2/2
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 100 times.
201 for (j = 0; j < b->nb_channel_layouts; j++)
276
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 100 times.
101 if (!av_channel_layout_compare(&b->channel_layouts[j], &bfmt)) {
277
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (check)
278 1 return 1;
279 av_channel_layout_copy(&channel_layouts[ret_nb++], fmt);
280 }
281 }
282 /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
283 143 FFSWAP(AVFilterChannelLayouts *, a, b);
284 }
285 /* a[generic] intersect b[generic] */
286
2/2
✓ Branch 0 taken 71 times.
✓ Branch 1 taken 71 times.
142 for (i = 0; i < a->nb_channel_layouts; i++) {
287
3/4
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 64 times.
✗ Branch 3 not taken.
71 if (KNOWN(&a->channel_layouts[i]))
288 71 continue;
289 for (j = 0; j < b->nb_channel_layouts; j++)
290 if (!av_channel_layout_compare(&a->channel_layouts[i], &b->channel_layouts[j])) {
291 if (check)
292 return 1;
293 av_channel_layout_copy(&channel_layouts[ret_nb++], &a->channel_layouts[i]);
294 }
295 }
296
297
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 64 times.
71 if (!ret_nb) {
298 7 av_free(channel_layouts);
299 7 return 0;
300 }
301
302
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 52 times.
64 if (a->refcount > b->refcount)
303 12 FFSWAP(AVFilterChannelLayouts *, a, b);
304
305
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
✓ Branch 4 taken 130 times.
✓ Branch 5 taken 64 times.
194 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts,
306 { av_free(channel_layouts); return AVERROR(ENOMEM); });
307 64 av_freep(&b->channel_layouts);
308 64 b->channel_layouts = channel_layouts;
309 64 b->nb_channel_layouts = ret_nb;
310 64 return 1;
311 }
312
313 5274 static int can_merge_channel_layouts(const void *a, const void *b)
314 {
315 5274 return merge_channel_layouts_internal((AVFilterChannelLayouts *)a,
316 (AVFilterChannelLayouts *)b, 1);
317 }
318
319 1324 static int merge_channel_layouts(void *a, void *b)
320 {
321 1324 return merge_channel_layouts_internal(a, b, 0);
322 }
323
324 117370 static int merge_generic_internal(AVFilterFormats *a,
325 AVFilterFormats *b, int check)
326 {
327 av_assert2(check || (a->refcount && b->refcount));
328
329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 117370 times.
117370 if (a == b)
330 return 1;
331
332
14/16
✓ Branch 0 taken 117370 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 383430 times.
✓ Branch 3 taken 1653674 times.
✓ Branch 4 taken 57441 times.
✓ Branch 5 taken 325989 times.
✓ Branch 6 taken 2037104 times.
✓ Branch 7 taken 18770 times.
✓ Branch 8 taken 402200 times.
✓ Branch 9 taken 59929 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 59928 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 59928 times.
✓ Branch 15 taken 107436 times.
✓ Branch 16 taken 59928 times.
2223239 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0);
333
334 59928 return 1;
335 }
336
337 57442 static int can_merge_generic(const void *a, const void *b)
338 {
339 57442 return merge_generic_internal((AVFilterFormats *)a,
340 (AVFilterFormats *)b, 1);
341 }
342
343 59928 static int merge_generic(void *a, void *b)
344 {
345 59928 return merge_generic_internal(a, b, 0);
346 }
347
348 static const AVFilterFormatsMerger mergers_video[] = {
349 {
350 .offset = offsetof(AVFilterFormatsConfig, formats),
351 .merge = merge_pix_fmts,
352 .can_merge = can_merge_pix_fmts,
353 },
354 {
355 .offset = offsetof(AVFilterFormatsConfig, color_spaces),
356 .merge = merge_generic,
357 .can_merge = can_merge_generic,
358 },
359 {
360 .offset = offsetof(AVFilterFormatsConfig, color_ranges),
361 .merge = merge_generic,
362 .can_merge = can_merge_generic,
363 },
364 };
365
366 static const AVFilterFormatsMerger mergers_audio[] = {
367 {
368 .offset = offsetof(AVFilterFormatsConfig, channel_layouts),
369 .merge = merge_channel_layouts,
370 .can_merge = can_merge_channel_layouts,
371 },
372 {
373 .offset = offsetof(AVFilterFormatsConfig, samplerates),
374 .merge = merge_samplerates,
375 .can_merge = can_merge_samplerates,
376 },
377 {
378 .offset = offsetof(AVFilterFormatsConfig, formats),
379 .merge = merge_sample_fmts,
380 .can_merge = can_merge_sample_fmts,
381 },
382 };
383
384 static const AVFilterNegotiation negotiate_video = {
385 .nb_mergers = FF_ARRAY_ELEMS(mergers_video),
386 .mergers = mergers_video,
387 .conversion_filter = "scale",
388 .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts),
389 };
390
391 static const AVFilterNegotiation negotiate_audio = {
392 .nb_mergers = FF_ARRAY_ELEMS(mergers_audio),
393 .mergers = mergers_audio,
394 .conversion_filter = "aresample",
395 .conversion_opts_offset = offsetof(AVFilterGraph, aresample_swr_opts),
396 };
397
398 35921 const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link)
399 {
400
2/3
✓ Branch 0 taken 30013 times.
✓ Branch 1 taken 5908 times.
✗ Branch 2 not taken.
35921 switch (link->type) {
401 30013 case AVMEDIA_TYPE_VIDEO: return &negotiate_video;
402 5908 case AVMEDIA_TYPE_AUDIO: return &negotiate_audio;
403 default: return NULL;
404 }
405 }
406
407 174 int ff_fmt_is_in(int fmt, const int *fmts)
408 {
409 const int *p;
410
411
2/2
✓ Branch 0 taken 2105 times.
✓ Branch 1 taken 87 times.
2192 for (p = fmts; *p != -1; p++) {
412
2/2
✓ Branch 0 taken 87 times.
✓ Branch 1 taken 2018 times.
2105 if (fmt == *p)
413 87 return 1;
414 }
415 87 return 0;
416 }
417
418 #define MAKE_FORMAT_LIST(type, field, count_field) \
419 type *formats; \
420 int count = 0; \
421 if (fmts) \
422 for (count = 0; fmts[count] != -1; count++) \
423 ; \
424 formats = av_mallocz(sizeof(*formats)); \
425 if (!formats) \
426 return NULL; \
427 formats->count_field = count; \
428 if (count) { \
429 formats->field = av_malloc_array(count, sizeof(*formats->field)); \
430 if (!formats->field) { \
431 av_freep(&formats); \
432 return NULL; \
433 } \
434 }
435
436 4338 AVFilterFormats *ff_make_format_list(const int *fmts)
437 {
438
6/10
✓ Branch 0 taken 4338 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 46904 times.
✓ Branch 3 taken 4338 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 4338 times.
✓ Branch 7 taken 4338 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 4338 times.
51242 MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
439
2/2
✓ Branch 0 taken 46904 times.
✓ Branch 1 taken 4338 times.
51242 while (count--)
440 46904 formats->formats[count] = fmts[count];
441
442 4338 return formats;
443 }
444
445 213 AVFilterChannelLayouts *ff_make_channel_layout_list(const AVChannelLayout *fmts)
446 {
447 AVFilterChannelLayouts *ch_layouts;
448 213 int count = 0;
449
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 if (fmts)
450
2/2
✓ Branch 0 taken 537 times.
✓ Branch 1 taken 213 times.
750 for (count = 0; fmts[count].nb_channels; count++)
451 ;
452 213 ch_layouts = av_mallocz(sizeof(*ch_layouts));
453
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 213 times.
213 if (!ch_layouts)
454 return NULL;
455 213 ch_layouts->nb_channel_layouts = count;
456
1/2
✓ Branch 0 taken 213 times.
✗ Branch 1 not taken.
213 if (count) {
457 426 ch_layouts->channel_layouts =
458 213 av_calloc(count, sizeof(*ch_layouts->channel_layouts));
459
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 213 times.
213 if (!ch_layouts->channel_layouts) {
460 av_freep(&ch_layouts);
461 return NULL;
462 }
463
2/2
✓ Branch 0 taken 537 times.
✓ Branch 1 taken 213 times.
750 for (int i = 0; i < count; i++) {
464 537 int ret = av_channel_layout_copy(&ch_layouts->channel_layouts[i], &fmts[i]);
465
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 537 times.
537 if (ret < 0)
466 goto fail;
467 }
468 }
469
470 213 return ch_layouts;
471
472 fail:
473 for (int i = 0; i < count; i++)
474 av_channel_layout_uninit(&ch_layouts->channel_layouts[i]);
475 av_free(ch_layouts->channel_layouts);
476 av_freep(&ch_layouts);
477
478 return NULL;
479 }
480
481 #define ADD_FORMAT(f, fmt, unref_fn, type, list, nb) \
482 do { \
483 type *fmts; \
484 \
485 if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) { \
486 return AVERROR(ENOMEM); \
487 } \
488 \
489 fmts = av_realloc_array((*f)->list, (*f)->nb + 1, \
490 sizeof(*(*f)->list)); \
491 if (!fmts) { \
492 unref_fn(f); \
493 return AVERROR(ENOMEM); \
494 } \
495 \
496 (*f)->list = fmts; \
497 ASSIGN_FMT(f, fmt, list, nb); \
498 } while (0)
499
500 #define ASSIGN_FMT(f, fmt, list, nb) \
501 do { \
502 (*f)->list[(*f)->nb++] = fmt; \
503 } while (0)
504
505 4136029 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
506 {
507
4/6
✓ Branch 0 taken 172741 times.
✓ Branch 1 taken 3963288 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 172741 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 4136029 times.
4136029 ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
508 4136029 return 0;
509 }
510
511 #undef ASSIGN_FMT
512 #define ASSIGN_FMT(f, fmt, list, nb) \
513 do { \
514 int ret; \
515 memset((*f)->list + (*f)->nb, 0, sizeof(*(*f)->list)); \
516 ret = av_channel_layout_copy(&(*f)->list[(*f)->nb], fmt); \
517 if (ret < 0) \
518 return ret; \
519 (*f)->nb++; \
520 } while (0)
521
522 2261 int ff_add_channel_layout(AVFilterChannelLayouts **l,
523 const AVChannelLayout *channel_layout)
524 {
525 av_assert1(!(*l && (*l)->all_layouts));
526
5/8
✓ Branch 0 taken 1421 times.
✓ Branch 1 taken 840 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1421 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2261 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2261 times.
2261 ADD_FORMAT(l, channel_layout, ff_channel_layouts_unref, AVChannelLayout, channel_layouts, nb_channel_layouts);
527 2261 return 0;
528 }
529
530 58 AVFilterFormats *ff_make_formats_list_singleton(int fmt)
531 {
532 58 int fmts[2] = { fmt, -1 };
533 58 return ff_make_format_list(fmts);
534 }
535
536 45385 AVFilterFormats *ff_all_formats(enum AVMediaType type)
537 {
538 45385 AVFilterFormats *ret = NULL;
539
540
2/2
✓ Branch 0 taken 35260 times.
✓ Branch 1 taken 10125 times.
45385 if (type == AVMEDIA_TYPE_VIDEO) {
541 35260 return ff_formats_pixdesc_filter(0, 0);
542
1/2
✓ Branch 0 taken 10125 times.
✗ Branch 1 not taken.
10125 } else if (type == AVMEDIA_TYPE_AUDIO) {
543 10125 enum AVSampleFormat fmt = 0;
544
2/2
✓ Branch 1 taken 121500 times.
✓ Branch 2 taken 10125 times.
131625 while (av_get_sample_fmt_name(fmt)) {
545
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 121500 times.
121500 if (ff_add_format(&ret, fmt) < 0)
546 return NULL;
547 121500 fmt++;
548 }
549 }
550
551 10125 return ret;
552 }
553
554 35881 AVFilterFormats *ff_formats_pixdesc_filter(unsigned want, unsigned rej)
555 {
556 unsigned nb_formats, fmt, flags;
557 35881 AVFilterFormats *formats = NULL;
558
559 while (1) {
560 71762 nb_formats = 0;
561 18586358 for (fmt = 0;; fmt++) {
562 18586358 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
563
2/2
✓ Branch 0 taken 71762 times.
✓ Branch 1 taken 18514596 times.
18586358 if (!desc)
564 71762 break;
565 18514596 flags = desc->flags;
566
2/2
✓ Branch 0 taken 17438166 times.
✓ Branch 1 taken 1076430 times.
18514596 if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
567
2/2
✓ Branch 0 taken 8467916 times.
✓ Branch 1 taken 8970250 times.
17438166 !(desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
568
3/4
✓ Branch 0 taken 7750296 times.
✓ Branch 1 taken 717620 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 7750296 times.
8467916 (desc->log2_chroma_w || desc->log2_chroma_h))
569 717620 flags |= FF_PIX_FMT_FLAG_SW_FLAT_SUB;
570
2/2
✓ Branch 0 taken 19804 times.
✓ Branch 1 taken 18494792 times.
18514596 if ((flags & (want | rej)) != want)
571 19804 continue;
572
2/2
✓ Branch 0 taken 9247396 times.
✓ Branch 1 taken 9247396 times.
18494792 if (formats)
573 9247396 formats->formats[nb_formats] = fmt;
574 18494792 nb_formats++;
575 }
576
2/2
✓ Branch 0 taken 35881 times.
✓ Branch 1 taken 35881 times.
71762 if (formats) {
577
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35881 times.
35881 av_assert0(formats->nb_formats == nb_formats);
578 35881 return formats;
579 }
580 35881 formats = av_mallocz(sizeof(*formats));
581
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35881 times.
35881 if (!formats)
582 return NULL;
583 35881 formats->nb_formats = nb_formats;
584
1/2
✓ Branch 0 taken 35881 times.
✗ Branch 1 not taken.
35881 if (nb_formats) {
585 35881 formats->formats = av_malloc_array(nb_formats, sizeof(*formats->formats));
586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35881 times.
35881 if (!formats->formats) {
587 av_freep(&formats);
588 return NULL;
589 }
590 }
591 }
592 }
593
594 61 AVFilterFormats *ff_planar_sample_fmts(void)
595 {
596 61 AVFilterFormats *ret = NULL;
597 int fmt;
598
599
2/2
✓ Branch 1 taken 732 times.
✓ Branch 2 taken 61 times.
793 for (fmt = 0; av_get_bytes_per_sample(fmt)>0; fmt++)
600
2/2
✓ Branch 1 taken 366 times.
✓ Branch 2 taken 366 times.
732 if (av_sample_fmt_is_planar(fmt))
601
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 366 times.
366 if (ff_add_format(&ret, fmt) < 0)
602 return NULL;
603
604 61 return ret;
605 }
606
607 44777 AVFilterFormats *ff_all_samplerates(void)
608 {
609 44777 AVFilterFormats *ret = av_mallocz(sizeof(*ret));
610 44777 return ret;
611 }
612
613 70 AVFilterChannelLayouts *ff_all_channel_layouts(void)
614 {
615 70 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 70 times.
70 if (!ret)
617 return NULL;
618 70 ret->all_layouts = 1;
619 70 return ret;
620 }
621
622 45437 AVFilterChannelLayouts *ff_all_channel_counts(void)
623 {
624 45437 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 45437 times.
45437 if (!ret)
626 return NULL;
627 45437 ret->all_layouts = ret->all_counts = 1;
628 45437 return ret;
629 }
630
631 56751 AVFilterFormats *ff_all_color_spaces(void)
632 {
633 56751 AVFilterFormats *ret = NULL;
634
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 56751 times.
56751 if (ff_add_format(&ret, AVCOL_SPC_UNSPECIFIED) < 0)
635 return NULL;
636
2/2
✓ Branch 0 taken 1021518 times.
✓ Branch 1 taken 56751 times.
1078269 for (int csp = 0; csp < AVCOL_SPC_NB; csp++) {
637
4/4
✓ Branch 0 taken 964767 times.
✓ Branch 1 taken 56751 times.
✓ Branch 2 taken 56751 times.
✓ Branch 3 taken 908016 times.
1021518 if (csp == AVCOL_SPC_RESERVED ||
638 csp == AVCOL_SPC_UNSPECIFIED)
639 113502 continue;
640
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 908016 times.
908016 if (ff_add_format(&ret, csp) < 0)
641 return NULL;
642 }
643
644 56751 return ret;
645 }
646
647 56751 AVFilterFormats *ff_all_color_ranges(void)
648 {
649 56751 AVFilterFormats *ret = NULL;
650
2/2
✓ Branch 0 taken 170253 times.
✓ Branch 1 taken 56751 times.
227004 for (int range = 0; range < AVCOL_RANGE_NB; range++) {
651
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 170253 times.
170253 if (ff_add_format(&ret, range) < 0)
652 return NULL;
653 }
654
655 56751 return ret;
656 }
657
658 #define FORMATS_REF(f, ref, unref_fn) \
659 void *tmp; \
660 \
661 if (!f) \
662 return AVERROR(ENOMEM); \
663 \
664 tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1); \
665 if (!tmp) { \
666 unref_fn(&f); \
667 return AVERROR(ENOMEM); \
668 } \
669 f->refs = tmp; \
670 f->refs[f->refcount++] = ref; \
671 *ref = f; \
672 return 0
673
674 11808 int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
675 {
676
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 11808 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11808 times.
11808 FORMATS_REF(f, ref, ff_channel_layouts_unref);
677 }
678
679 221243 int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
680 {
681
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 221243 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 221243 times.
221243 FORMATS_REF(f, ref, ff_formats_unref);
682 }
683
684 #define FIND_REF_INDEX(ref, idx) \
685 do { \
686 int i; \
687 for (i = 0; i < (*ref)->refcount; i ++) \
688 if((*ref)->refs[i] == ref) { \
689 idx = i; \
690 break; \
691 } \
692 } while (0)
693
694 #define FORMATS_UNREF(ref, list) \
695 do { \
696 int idx = -1; \
697 \
698 if (!*ref) \
699 return; \
700 \
701 FIND_REF_INDEX(ref, idx); \
702 \
703 if (idx >= 0) { \
704 memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
705 sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
706 --(*ref)->refcount; \
707 } \
708 if (!(*ref)->refcount) { \
709 FREE_LIST(ref, list); \
710 av_free((*ref)->list); \
711 av_free((*ref)->refs); \
712 av_free(*ref); \
713 } \
714 *ref = NULL; \
715 } while (0)
716
717 #define FREE_LIST(ref, list) do { } while(0)
718 806758 void ff_formats_unref(AVFilterFormats **ref)
719 {
720
10/10
✓ Branch 0 taken 479642 times.
✓ Branch 1 taken 327116 times.
✓ Branch 2 taken 221243 times.
✓ Branch 3 taken 131400 times.
✓ Branch 4 taken 352643 times.
✓ Branch 5 taken 105873 times.
✓ Branch 6 taken 221243 times.
✓ Branch 7 taken 105873 times.
✓ Branch 8 taken 156035 times.
✓ Branch 9 taken 171081 times.
938158 FORMATS_UNREF(ref, formats);
721 }
722
723 #undef FREE_LIST
724 #define FREE_LIST(ref, list) \
725 do { \
726 for (int i = 0; i < (*ref)->nb_channel_layouts; i++) \
727 av_channel_layout_uninit(&(*ref)->list[i]); \
728 } while(0)
729
730 201992 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
731 {
732
12/12
✓ Branch 0 taken 151936 times.
✓ Branch 1 taken 50056 times.
✓ Branch 2 taken 11808 times.
✓ Branch 3 taken 8848 times.
✓ Branch 4 taken 20656 times.
✓ Branch 5 taken 38248 times.
✓ Branch 6 taken 11808 times.
✓ Branch 7 taken 38248 times.
✓ Branch 8 taken 40658 times.
✓ Branch 9 taken 9398 times.
✓ Branch 11 taken 2410 times.
✓ Branch 12 taken 40658 times.
213250 FORMATS_UNREF(ref, channel_layouts);
733 }
734
735 #define FORMATS_CHANGEREF(oldref, newref) \
736 do { \
737 int idx = -1; \
738 \
739 FIND_REF_INDEX(oldref, idx); \
740 \
741 if (idx >= 0) { \
742 (*oldref)->refs[idx] = newref; \
743 *newref = *oldref; \
744 *oldref = NULL; \
745 } \
746 } while (0)
747
748 630 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
749 AVFilterChannelLayouts **newref)
750 {
751
4/6
✓ Branch 0 taken 630 times.
✓ Branch 1 taken 1637 times.
✓ Branch 2 taken 2267 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 630 times.
✗ Branch 5 not taken.
2267 FORMATS_CHANGEREF(oldref, newref);
752 630 }
753
754 3126 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
755 {
756
4/6
✓ Branch 0 taken 3126 times.
✓ Branch 1 taken 8009 times.
✓ Branch 2 taken 11135 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3126 times.
✗ Branch 5 not taken.
11135 FORMATS_CHANGEREF(oldref, newref);
757 3126 }
758
759 #define SET_COMMON_FORMATS(ctx, fmts, media_type, ref_fn, unref_fn) \
760 int i; \
761 \
762 if (!fmts) \
763 return AVERROR(ENOMEM); \
764 \
765 for (i = 0; i < ctx->nb_inputs; i++) { \
766 AVFilterLink *const link = ctx->inputs[i]; \
767 if (link && !link->outcfg.fmts && \
768 (media_type == AVMEDIA_TYPE_UNKNOWN || link->type == media_type)) { \
769 int ret = ref_fn(fmts, &ctx->inputs[i]->outcfg.fmts); \
770 if (ret < 0) { \
771 return ret; \
772 } \
773 } \
774 } \
775 for (i = 0; i < ctx->nb_outputs; i++) { \
776 AVFilterLink *const link = ctx->outputs[i]; \
777 if (link && !link->incfg.fmts && \
778 (media_type == AVMEDIA_TYPE_UNKNOWN || link->type == media_type)) { \
779 int ret = ref_fn(fmts, &ctx->outputs[i]->incfg.fmts); \
780 if (ret < 0) { \
781 return ret; \
782 } \
783 } \
784 } \
785 \
786 if (!fmts->refcount) \
787 unref_fn(&fmts); \
788 \
789 return 0;
790
791 42442 int ff_set_common_channel_layouts(AVFilterContext *ctx,
792 AVFilterChannelLayouts *channel_layouts)
793 {
794
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 42442 times.
✓ Branch 2 taken 35525 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33823 times.
✓ Branch 5 taken 1702 times.
✓ Branch 6 taken 4202 times.
✓ Branch 7 taken 29621 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4202 times.
✓ Branch 11 taken 35525 times.
✓ Branch 12 taken 42442 times.
✓ Branch 13 taken 34440 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 31323 times.
✓ Branch 16 taken 3117 times.
✓ Branch 17 taken 2787 times.
✓ Branch 18 taken 28536 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 2787 times.
✓ Branch 22 taken 34440 times.
✓ Branch 23 taken 42442 times.
✓ Branch 24 taken 38248 times.
✓ Branch 25 taken 4194 times.
112407 SET_COMMON_FORMATS(ctx, channel_layouts, AVMEDIA_TYPE_AUDIO,
795 ff_channel_layouts_ref, ff_channel_layouts_unref);
796 }
797
798 int ff_set_common_channel_layouts_from_list(AVFilterContext *ctx,
799 const AVChannelLayout *fmts)
800 {
801 return ff_set_common_channel_layouts(ctx, ff_make_channel_layout_list(fmts));
802 }
803
804 42442 int ff_set_common_all_channel_counts(AVFilterContext *ctx)
805 {
806 42442 return ff_set_common_channel_layouts(ctx, ff_all_channel_counts());
807 }
808
809 42443 int ff_set_common_samplerates(AVFilterContext *ctx,
810 AVFilterFormats *samplerates)
811 {
812
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 42443 times.
✓ Branch 2 taken 35527 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 33947 times.
✓ Branch 5 taken 1580 times.
✓ Branch 6 taken 4326 times.
✓ Branch 7 taken 29621 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4326 times.
✓ Branch 11 taken 35527 times.
✓ Branch 12 taken 42443 times.
✓ Branch 13 taken 34441 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 31503 times.
✓ Branch 16 taken 2938 times.
✓ Branch 17 taken 2967 times.
✓ Branch 18 taken 28536 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 2967 times.
✓ Branch 22 taken 34441 times.
✓ Branch 23 taken 42443 times.
✓ Branch 24 taken 38192 times.
✓ Branch 25 taken 4251 times.
112411 SET_COMMON_FORMATS(ctx, samplerates, AVMEDIA_TYPE_AUDIO,
813 ff_formats_ref, ff_formats_unref);
814 }
815
816 int ff_set_common_samplerates_from_list(AVFilterContext *ctx,
817 const int *samplerates)
818 {
819 return ff_set_common_samplerates(ctx, ff_make_format_list(samplerates));
820 }
821
822 42443 int ff_set_common_all_samplerates(AVFilterContext *ctx)
823 {
824 42443 return ff_set_common_samplerates(ctx, ff_all_samplerates());
825 }
826
827 43853 int ff_set_common_color_spaces(AVFilterContext *ctx,
828 AVFilterFormats *color_spaces)
829 {
830
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 43853 times.
✓ Branch 2 taken 35843 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 29418 times.
✓ Branch 5 taken 6425 times.
✓ Branch 6 taken 23555 times.
✓ Branch 7 taken 5863 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 23555 times.
✓ Branch 11 taken 35843 times.
✓ Branch 12 taken 43853 times.
✓ Branch 13 taken 35851 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 24512 times.
✓ Branch 16 taken 11339 times.
✓ Branch 17 taken 18641 times.
✓ Branch 18 taken 5871 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 18641 times.
✓ Branch 22 taken 35851 times.
✓ Branch 23 taken 43853 times.
✓ Branch 24 taken 18491 times.
✓ Branch 25 taken 25362 times.
115547 SET_COMMON_FORMATS(ctx, color_spaces, AVMEDIA_TYPE_VIDEO,
831 ff_formats_ref, ff_formats_unref);
832 }
833
834 int ff_set_common_color_spaces_from_list(AVFilterContext *ctx,
835 const int *color_ranges)
836 {
837 return ff_set_common_color_spaces(ctx, ff_make_format_list(color_ranges));
838 }
839
840 43853 int ff_set_common_all_color_spaces(AVFilterContext *ctx)
841 {
842 43853 return ff_set_common_color_spaces(ctx, ff_all_color_spaces());
843 }
844
845 43853 int ff_set_common_color_ranges(AVFilterContext *ctx,
846 AVFilterFormats *color_ranges)
847 {
848
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 43853 times.
✓ Branch 2 taken 35843 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 27304 times.
✓ Branch 5 taken 8539 times.
✓ Branch 6 taken 21441 times.
✓ Branch 7 taken 5863 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 21441 times.
✓ Branch 11 taken 35843 times.
✓ Branch 12 taken 43853 times.
✓ Branch 13 taken 35851 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 22398 times.
✓ Branch 16 taken 13453 times.
✓ Branch 17 taken 16527 times.
✓ Branch 18 taken 5871 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 16527 times.
✓ Branch 22 taken 35851 times.
✓ Branch 23 taken 43853 times.
✓ Branch 24 taken 20605 times.
✓ Branch 25 taken 23248 times.
115547 SET_COMMON_FORMATS(ctx, color_ranges, AVMEDIA_TYPE_VIDEO,
849 ff_formats_ref, ff_formats_unref);
850 }
851
852 int ff_set_common_color_ranges_from_list(AVFilterContext *ctx,
853 const int *color_ranges)
854 {
855 return ff_set_common_color_ranges(ctx, ff_make_format_list(color_ranges));
856 }
857
858 43853 int ff_set_common_all_color_ranges(AVFilterContext *ctx)
859 {
860 43853 return ff_set_common_color_ranges(ctx, ff_all_color_ranges());
861 }
862
863 /**
864 * A helper for query_formats() which sets all links to the same list of
865 * formats. If there are no links hooked to this filter, the list of formats is
866 * freed.
867 */
868 43887 int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
869 {
870
15/20
✗ Branch 0 not taken.
✓ Branch 1 taken 43887 times.
✓ Branch 2 taken 35886 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 14225 times.
✓ Branch 5 taken 21661 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 14225 times.
✓ Branch 9 taken 35886 times.
✓ Branch 10 taken 43887 times.
✓ Branch 11 taken 35885 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 7256 times.
✓ Branch 14 taken 28629 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 7256 times.
✓ Branch 18 taken 35885 times.
✓ Branch 19 taken 43887 times.
✓ Branch 20 taken 28585 times.
✓ Branch 21 taken 15302 times.
115658 SET_COMMON_FORMATS(ctx, formats, AVMEDIA_TYPE_UNKNOWN,
871 ff_formats_ref, ff_formats_unref);
872 }
873
874 1 int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
875 {
876 1 return ff_set_common_formats(ctx, ff_make_format_list(fmts));
877 }
878
879 #define SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, fmts, media_type, \
880 ref_fn, unref_fn) \
881 if (!fmts) \
882 return AVERROR(ENOMEM); \
883 \
884 for (unsigned i = 0; i < ctx->nb_inputs; i++) { \
885 const AVFilterLink *const link = ctx->inputs[i]; \
886 if (!cfg_in[i]->fmts && \
887 (media_type == AVMEDIA_TYPE_UNKNOWN || \
888 link->type == media_type)) { \
889 int ret = ref_fn(fmts, &cfg_in[i]->fmts); \
890 if (ret < 0) { \
891 return ret; \
892 } \
893 } \
894 } \
895 for (unsigned i = 0; i < ctx->nb_outputs; i++) { \
896 const AVFilterLink *const link = ctx->outputs[i]; \
897 if (!cfg_out[i]->fmts && \
898 (media_type == AVMEDIA_TYPE_UNKNOWN || \
899 link->type == media_type)) { \
900 int ret = ref_fn(fmts, &cfg_out[i]->fmts); \
901 if (ret < 0) { \
902 return ret; \
903 } \
904 } \
905 } \
906 \
907 if (!fmts->refcount) \
908 unref_fn(&fmts); \
909 \
910 return 0;
911
912 1474 int ff_set_common_channel_layouts2(const AVFilterContext *ctx,
913 AVFilterFormatsConfig **cfg_in,
914 AVFilterFormatsConfig **cfg_out,
915 AVFilterChannelLayouts *channel_layouts)
916 {
917
12/20
✗ Branch 0 not taken.
✓ Branch 1 taken 1474 times.
✓ Branch 2 taken 114 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 114 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 114 times.
✓ Branch 9 taken 114 times.
✓ Branch 10 taken 1474 times.
✓ Branch 11 taken 1474 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1474 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 1474 times.
✓ Branch 18 taken 1474 times.
✓ Branch 19 taken 1474 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1474 times.
3062 SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, channel_layouts, AVMEDIA_TYPE_AUDIO,
918 ff_channel_layouts_ref, ff_channel_layouts_unref);
919 }
920
921 210 int ff_set_common_channel_layouts_from_list2(const AVFilterContext *ctx,
922 AVFilterFormatsConfig **cfg_in,
923 AVFilterFormatsConfig **cfg_out,
924 const AVChannelLayout *fmts)
925 {
926 210 return ff_set_common_channel_layouts2(ctx, cfg_in, cfg_out, ff_make_channel_layout_list(fmts));
927 }
928
929 int ff_set_common_all_channel_counts2(const AVFilterContext *ctx,
930 AVFilterFormatsConfig **cfg_in,
931 AVFilterFormatsConfig **cfg_out)
932 {
933 return ff_set_common_channel_layouts2(ctx, cfg_in, cfg_out, ff_all_channel_counts());
934 }
935
936 1446 int ff_set_common_samplerates2(const AVFilterContext *ctx,
937 AVFilterFormatsConfig **cfg_in,
938 AVFilterFormatsConfig **cfg_out,
939 AVFilterFormats *samplerates)
940 {
941
12/20
✗ Branch 0 not taken.
✓ Branch 1 taken 1446 times.
✓ Branch 2 taken 86 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 86 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 86 times.
✓ Branch 9 taken 86 times.
✓ Branch 10 taken 1446 times.
✓ Branch 11 taken 1446 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1446 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 1446 times.
✓ Branch 18 taken 1446 times.
✓ Branch 19 taken 1446 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 1446 times.
2978 SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, samplerates, AVMEDIA_TYPE_AUDIO,
942 ff_formats_ref, ff_formats_unref);
943 }
944
945 182 int ff_set_common_samplerates_from_list2(const AVFilterContext *ctx,
946 AVFilterFormatsConfig **cfg_in,
947 AVFilterFormatsConfig **cfg_out,
948 const int *samplerates)
949 {
950 182 return ff_set_common_samplerates2(ctx, cfg_in, cfg_out, ff_make_format_list(samplerates));
951 }
952
953 int ff_set_common_all_samplerates2(const AVFilterContext *ctx,
954 AVFilterFormatsConfig **cfg_in,
955 AVFilterFormatsConfig **cfg_out)
956 {
957 return ff_set_common_samplerates2(ctx, cfg_in, cfg_out, ff_all_samplerates());
958 }
959
960 4922 int ff_set_common_color_spaces2(const AVFilterContext *ctx,
961 AVFilterFormatsConfig **cfg_in,
962 AVFilterFormatsConfig **cfg_out,
963 AVFilterFormats *color_spaces)
964 {
965
12/20
✗ Branch 0 not taken.
✓ Branch 1 taken 4922 times.
✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 20 times.
✓ Branch 9 taken 20 times.
✓ Branch 10 taken 4922 times.
✓ Branch 11 taken 4922 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4922 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 4922 times.
✓ Branch 18 taken 4922 times.
✓ Branch 19 taken 4922 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 4922 times.
9864 SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, color_spaces, AVMEDIA_TYPE_VIDEO,
966 ff_formats_ref, ff_formats_unref);
967 }
968
969 int ff_set_common_color_spaces_from_list2(const AVFilterContext *ctx,
970 AVFilterFormatsConfig **cfg_in,
971 AVFilterFormatsConfig **cfg_out,
972 const int *color_ranges)
973 {
974 return ff_set_common_color_spaces2(ctx, cfg_in, cfg_out, ff_make_format_list(color_ranges));
975 }
976
977 int ff_set_common_all_color_spaces2(const AVFilterContext *ctx,
978 AVFilterFormatsConfig **cfg_in,
979 AVFilterFormatsConfig **cfg_out)
980 {
981 return ff_set_common_color_spaces2(ctx, cfg_in, cfg_out, ff_all_color_spaces());
982 }
983
984 7036 int ff_set_common_color_ranges2(const AVFilterContext *ctx,
985 AVFilterFormatsConfig **cfg_in,
986 AVFilterFormatsConfig **cfg_out,
987 AVFilterFormats *color_ranges)
988 {
989
12/20
✗ Branch 0 not taken.
✓ Branch 1 taken 7036 times.
✓ Branch 2 taken 2134 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2134 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 2134 times.
✓ Branch 9 taken 2134 times.
✓ Branch 10 taken 7036 times.
✓ Branch 11 taken 7036 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 7036 times.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✓ Branch 17 taken 7036 times.
✓ Branch 18 taken 7036 times.
✓ Branch 19 taken 7036 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 7036 times.
16206 SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, color_ranges, AVMEDIA_TYPE_VIDEO,
990 ff_formats_ref, ff_formats_unref);
991 }
992
993 int ff_set_common_color_ranges_from_list2(const AVFilterContext *ctx,
994 AVFilterFormatsConfig **cfg_in,
995 AVFilterFormatsConfig **cfg_out,
996 const int *color_ranges)
997 {
998 return ff_set_common_color_ranges2(ctx, cfg_in, cfg_out, ff_make_format_list(color_ranges));
999 }
1000
1001 int ff_set_common_all_color_ranges2(const AVFilterContext *ctx,
1002 AVFilterFormatsConfig **cfg_in,
1003 AVFilterFormatsConfig **cfg_out)
1004 {
1005 return ff_set_common_color_ranges2(ctx, cfg_in, cfg_out, ff_all_color_ranges());
1006 }
1007
1008 20622 int ff_set_common_formats2(const AVFilterContext *ctx,
1009 AVFilterFormatsConfig **cfg_in,
1010 AVFilterFormatsConfig **cfg_out,
1011 AVFilterFormats *formats)
1012 {
1013
11/16
✗ Branch 0 not taken.
✓ Branch 1 taken 20622 times.
✓ Branch 2 taken 13668 times.
✓ Branch 3 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 13668 times.
✓ Branch 7 taken 13672 times.
✓ Branch 8 taken 20622 times.
✓ Branch 9 taken 20663 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✓ Branch 13 taken 20663 times.
✓ Branch 14 taken 20663 times.
✓ Branch 15 taken 20622 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 20622 times.
54957 SET_COMMON_FORMATS2(ctx, cfg_in, cfg_out, formats, AVMEDIA_TYPE_UNKNOWN,
1014 ff_formats_ref, ff_formats_unref);
1015 }
1016
1017 1847 int ff_set_common_formats_from_list2(const AVFilterContext *ctx,
1018 AVFilterFormatsConfig **cfg_in,
1019 AVFilterFormatsConfig **cfg_out,
1020 const int *fmts)
1021 {
1022 1847 return ff_set_common_formats2(ctx, cfg_in, cfg_out, ff_make_format_list(fmts));
1023 }
1024
1025
1026 43886 int ff_default_query_formats(AVFilterContext *ctx)
1027 {
1028 43886 const FFFilter *const f = fffilter(ctx->filter);
1029 AVFilterFormats *formats;
1030 enum AVMediaType type;
1031 int ret;
1032
1033
5/5
✓ Branch 0 taken 1411 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 13 times.
✓ Branch 4 taken 42409 times.
43886 switch (f->formats_state) {
1034 1411 case FF_FILTER_FORMATS_PIXFMT_LIST:
1035 1411 type = AVMEDIA_TYPE_VIDEO;
1036 1411 formats = ff_make_format_list(f->formats.pixels_list);
1037 1411 break;
1038 20 case FF_FILTER_FORMATS_SAMPLEFMTS_LIST:
1039 20 type = AVMEDIA_TYPE_AUDIO;
1040 20 formats = ff_make_format_list(f->formats.samples_list);
1041 20 break;
1042 33 case FF_FILTER_FORMATS_SINGLE_PIXFMT:
1043 33 type = AVMEDIA_TYPE_VIDEO;
1044 33 formats = ff_make_formats_list_singleton(f->formats.pix_fmt);
1045 33 break;
1046 13 case FF_FILTER_FORMATS_SINGLE_SAMPLEFMT:
1047 13 type = AVMEDIA_TYPE_AUDIO;
1048 13 formats = ff_make_formats_list_singleton(f->formats.sample_fmt);
1049 13 break;
1050 42409 default:
1051 av_assert2(!"Unreachable");
1052 /* Intended fallthrough */
1053 case FF_FILTER_FORMATS_PASSTHROUGH:
1054 case FF_FILTER_FORMATS_QUERY_FUNC:
1055 case FF_FILTER_FORMATS_QUERY_FUNC2:
1056 42409 type = AVMEDIA_TYPE_UNKNOWN;
1057
2/2
✓ Branch 0 taken 35370 times.
✓ Branch 1 taken 7039 times.
49448 formats = ff_all_formats(ctx->nb_inputs ? ctx->inputs [0]->type :
1058
1/2
✓ Branch 0 taken 7039 times.
✗ Branch 1 not taken.
7039 ctx->nb_outputs ? ctx->outputs[0]->type :
1059 AVMEDIA_TYPE_VIDEO);
1060 42409 break;
1061 }
1062
1063 43886 ret = ff_set_common_formats(ctx, formats);
1064
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43886 times.
43886 if (ret < 0)
1065 return ret;
1066
2/2
✓ Branch 0 taken 43853 times.
✓ Branch 1 taken 33 times.
43886 if (type != AVMEDIA_TYPE_AUDIO) {
1067 43853 ret = ff_set_common_all_color_spaces(ctx);
1068
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43853 times.
43853 if (ret < 0)
1069 return ret;
1070 43853 ret = ff_set_common_all_color_ranges(ctx);
1071
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 43853 times.
43853 if (ret < 0)
1072 return ret;
1073 }
1074
2/2
✓ Branch 0 taken 42442 times.
✓ Branch 1 taken 1444 times.
43886 if (type != AVMEDIA_TYPE_VIDEO) {
1075 42442 ret = ff_set_common_all_channel_counts(ctx);
1076
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42442 times.
42442 if (ret < 0)
1077 return ret;
1078 42442 ret = ff_set_common_all_samplerates(ctx);
1079
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 42442 times.
42442 if (ret < 0)
1080 return ret;
1081 }
1082
1083 43886 return 0;
1084 }
1085
1086 158707 static int check_list(void *log, const char *name, const AVFilterFormats *fmts)
1087 {
1088 unsigned i, j;
1089
1090
2/2
✓ Branch 0 taken 66486 times.
✓ Branch 1 taken 92221 times.
158707 if (!fmts)
1091 66486 return 0;
1092
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 92221 times.
92221 if (!fmts->nb_formats) {
1093 av_log(log, AV_LOG_ERROR, "Empty %s list\n", name);
1094 return AVERROR(EINVAL);
1095 }
1096
2/2
✓ Branch 0 taken 3483205 times.
✓ Branch 1 taken 92221 times.
3575426 for (i = 0; i < fmts->nb_formats; i++) {
1097
2/2
✓ Branch 0 taken 344174539 times.
✓ Branch 1 taken 3483205 times.
347657744 for (j = i + 1; j < fmts->nb_formats; j++) {
1098
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 344174539 times.
344174539 if (fmts->formats[i] == fmts->formats[j]) {
1099 av_log(log, AV_LOG_ERROR, "Duplicated %s\n", name);
1100 return AVERROR(EINVAL);
1101 }
1102 }
1103 }
1104 92221 return 0;
1105 }
1106
1107 49056 int ff_formats_check_pixel_formats(void *log, const AVFilterFormats *fmts)
1108 {
1109 49056 return check_list(log, "pixel format", fmts);
1110 }
1111
1112 9364 int ff_formats_check_sample_formats(void *log, const AVFilterFormats *fmts)
1113 {
1114 9364 return check_list(log, "sample format", fmts);
1115 }
1116
1117 9364 int ff_formats_check_sample_rates(void *log, const AVFilterFormats *fmts)
1118 {
1119
4/4
✓ Branch 0 taken 4518 times.
✓ Branch 1 taken 4846 times.
✓ Branch 2 taken 2343 times.
✓ Branch 3 taken 2175 times.
9364 if (!fmts || !fmts->nb_formats)
1120 7189 return 0;
1121 2175 return check_list(log, "sample rate", fmts);
1122 }
1123
1124 49056 int ff_formats_check_color_spaces(void *log, const AVFilterFormats *fmts)
1125 {
1126
4/4
✓ Branch 0 taken 125184 times.
✓ Branch 1 taken 31292 times.
✓ Branch 2 taken 107420 times.
✓ Branch 3 taken 17764 times.
156476 for (int i = 0; fmts && i < fmts->nb_formats; i++) {
1127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 107420 times.
107420 if (fmts->formats[i] == AVCOL_SPC_RESERVED) {
1128 av_log(log, AV_LOG_ERROR, "Invalid color space\n");
1129 return AVERROR(EINVAL);
1130 }
1131 }
1132 49056 return check_list(log, "color space", fmts);
1133 }
1134
1135 49056 int ff_formats_check_color_ranges(void *log, const AVFilterFormats *fmts)
1136 {
1137 49056 return check_list(log, "color range", fmts);
1138 }
1139
1140 3420 static int layouts_compatible(const AVChannelLayout *a, const AVChannelLayout *b)
1141 {
1142 3420 return !av_channel_layout_compare(a, b) ||
1143
3/12
✓ Branch 0 taken 3420 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3420 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3420 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
6840 (KNOWN(a) && !KNOWN(b) && a->nb_channels == b->nb_channels) ||
1144
2/10
✗ Branch 0 not taken.
✓ Branch 1 taken 3420 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3420 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
3420 (KNOWN(b) && !KNOWN(a) && b->nb_channels == a->nb_channels);
1145 }
1146
1147 9364 int ff_formats_check_channel_layouts(void *log, const AVFilterChannelLayouts *fmts)
1148 {
1149 unsigned i, j;
1150
1151
2/2
✓ Branch 0 taken 4545 times.
✓ Branch 1 taken 4819 times.
9364 if (!fmts)
1152 4545 return 0;
1153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4819 times.
4819 if (fmts->all_layouts < fmts->all_counts) {
1154 av_log(log, AV_LOG_ERROR, "Inconsistent generic list\n");
1155 return AVERROR(EINVAL);
1156 }
1157
3/4
✓ Branch 0 taken 1748 times.
✓ Branch 1 taken 3071 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1748 times.
4819 if (!fmts->all_layouts && !fmts->nb_channel_layouts) {
1158 av_log(log, AV_LOG_ERROR, "Empty channel layout list\n");
1159 return AVERROR(EINVAL);
1160 }
1161
2/2
✓ Branch 0 taken 2396 times.
✓ Branch 1 taken 4819 times.
7215 for (i = 0; i < fmts->nb_channel_layouts; i++) {
1162
2/2
✓ Branch 0 taken 3420 times.
✓ Branch 1 taken 2396 times.
5816 for (j = i + 1; j < fmts->nb_channel_layouts; j++) {
1163
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3420 times.
3420 if (layouts_compatible(&fmts->channel_layouts[i], &fmts->channel_layouts[j])) {
1164 av_log(log, AV_LOG_ERROR, "Duplicated or redundant channel layout\n");
1165 return AVERROR(EINVAL);
1166 }
1167 }
1168 }
1169 4819 return 0;
1170 }
1171