FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/formats.c
Date: 2024-07-26 21:54:09
Exec Total Coverage
Lines: 336 400 84.0%
Functions: 59 61 96.7%
Branches: 385 520 74.0%

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/eval.h"
26 #include "libavutil/mem.h"
27 #include "libavutil/pixdesc.h"
28 #include "avfilter.h"
29 #include "internal.h"
30 #include "formats.h"
31
32 /**
33 * Add all refs from a to ret and destroy a.
34 */
35 #define MERGE_REF(ret, a, fmts, type, fail_statement) \
36 do { \
37 type ***tmp; \
38 int i; \
39 \
40 if (!(tmp = av_realloc_array(ret->refs, ret->refcount + a->refcount, \
41 sizeof(*tmp)))) \
42 { fail_statement } \
43 ret->refs = tmp; \
44 \
45 for (i = 0; i < a->refcount; i ++) { \
46 ret->refs[ret->refcount] = a->refs[i]; \
47 *ret->refs[ret->refcount++] = ret; \
48 } \
49 \
50 av_freep(&a->refs); \
51 av_freep(&a->fmts); \
52 av_freep(&a); \
53 } while (0)
54
55 /**
56 * Add all formats common to a and b to a, add b's refs to a and destroy b.
57 * If check is set, nothing is modified and it is only checked whether
58 * the formats are compatible.
59 * If empty_allowed is set and one of a,b->nb is zero, the lists are
60 * merged; otherwise, 0 (for nonmergeability) is returned.
61 */
62 #define MERGE_FORMATS(a, b, fmts, nb, type, check, empty_allowed) \
63 do { \
64 int i, j, k = 0, skip = 0; \
65 \
66 if (empty_allowed) { \
67 if (!a->nb || !b->nb) { \
68 if (check) \
69 return 1; \
70 if (!a->nb) \
71 FFSWAP(type *, a, b); \
72 skip = 1; \
73 } \
74 } \
75 if (!skip) { \
76 for (i = 0; i < a->nb; i++) \
77 for (j = 0; j < b->nb; j++) \
78 if (a->fmts[i] == b->fmts[j]) { \
79 if (check) \
80 return 1; \
81 a->fmts[k++] = a->fmts[i]; \
82 break; \
83 } \
84 /* Check that there was at least one common format. \
85 * Notice that both a and b are unchanged if not. */ \
86 if (!k) \
87 return 0; \
88 av_assert2(!check); \
89 a->nb = k; \
90 } \
91 \
92 MERGE_REF(a, b, fmts, type, return AVERROR(ENOMEM);); \
93 } while (0)
94
95 51445 static int merge_formats_internal(AVFilterFormats *a, AVFilterFormats *b,
96 enum AVMediaType type, int check)
97 {
98 int i, j;
99 51445 int alpha1=0, alpha2=0;
100 51445 int chroma1=0, chroma2=0;
101
102 av_assert2(check || (a->refcount && b->refcount));
103
104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 51445 times.
51445 if (a == b)
105 return 1;
106
107 /* Do not lose chroma or alpha in merging.
108 It happens if both lists have formats with chroma (resp. alpha), but
109 the only formats in common do not have it (e.g. YUV+gray vs.
110 RGB+gray): in that case, the merging would select the gray format,
111 possibly causing a lossy conversion elsewhere in the graph.
112 To avoid that, pretend that there are no common formats to force the
113 insertion of a conversion filter. */
114
2/2
✓ Branch 0 taken 41006 times.
✓ Branch 1 taken 10439 times.
51445 if (type == AVMEDIA_TYPE_VIDEO)
115
2/2
✓ Branch 0 taken 1453154 times.
✓ Branch 1 taken 41006 times.
1494160 for (i = 0; i < a->nb_formats; i++) {
116 1453154 const AVPixFmtDescriptor *const adesc = av_pix_fmt_desc_get(a->formats[i]);
117
2/2
✓ Branch 0 taken 25775329 times.
✓ Branch 1 taken 1453154 times.
27228483 for (j = 0; j < b->nb_formats; j++) {
118 25775329 const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
119 25775329 alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA;
120
4/4
✓ Branch 0 taken 23208377 times.
✓ Branch 1 taken 2566952 times.
✓ Branch 2 taken 20393480 times.
✓ Branch 3 taken 2814897 times.
25775329 chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
121
2/2
✓ Branch 0 taken 124039 times.
✓ Branch 1 taken 25651290 times.
25775329 if (a->formats[i] == b->formats[j]) {
122 124039 alpha1 |= adesc->flags & AV_PIX_FMT_FLAG_ALPHA;
123 124039 chroma1|= adesc->nb_components > 1;
124 }
125 }
126 }
127
128 // If chroma or alpha can be lost through merging then do not merge
129
4/4
✓ Branch 0 taken 51424 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 528 times.
✓ Branch 3 taken 50896 times.
51445 if (alpha2 > alpha1 || chroma2 > chroma1)
130 549 return 0;
131
132
14/16
✓ Branch 0 taken 50896 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 94599 times.
✓ Branch 3 taken 6733498 times.
✓ Branch 4 taken 24138 times.
✓ Branch 5 taken 70461 times.
✓ Branch 6 taken 6828097 times.
✓ Branch 7 taken 990143 times.
✓ Branch 8 taken 1084742 times.
✓ Branch 9 taken 26758 times.
✓ Branch 10 taken 500 times.
✓ Branch 11 taken 26258 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 26258 times.
✓ Branch 15 taken 52842 times.
✓ Branch 16 taken 26258 times.
7897840 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0);
133
134 26258 return 1;
135 }
136
137
138 /**
139 * Check the formats lists for compatibility for merging without actually
140 * merging.
141 *
142 * @return 1 if they are compatible, 0 if not.
143 */
144 20206 static int can_merge_pix_fmts(const void *a, const void *b)
145 {
146 20206 return merge_formats_internal((AVFilterFormats *)a,
147 (AVFilterFormats *)b, AVMEDIA_TYPE_VIDEO, 1);
148 }
149
150 /**
151 * Merge the formats lists if they are compatible and update all the
152 * references of a and b to point to the combined list and free the old
153 * lists as needed. The combined list usually contains the intersection of
154 * the lists of a and b.
155 *
156 * Both a and b must have owners (i.e. refcount > 0) for these functions.
157 *
158 * @return 1 if merging succeeded, 0 if a and b are incompatible
159 * and negative AVERROR code on failure.
160 * a and b are unmodified if 0 is returned.
161 */
162 20800 static int merge_pix_fmts(void *a, void *b)
163 {
164 20800 return merge_formats_internal(a, b, AVMEDIA_TYPE_VIDEO, 0);
165 }
166
167 /**
168 * See can_merge_pix_fmts().
169 */
170 4981 static int can_merge_sample_fmts(const void *a, const void *b)
171 {
172 4981 return merge_formats_internal((AVFilterFormats *)a,
173 (AVFilterFormats *)b, AVMEDIA_TYPE_AUDIO, 1);
174 }
175
176 /**
177 * See merge_pix_fmts().
178 */
179 5458 static int merge_sample_fmts(void *a, void *b)
180 {
181 5458 return merge_formats_internal(a, b, AVMEDIA_TYPE_AUDIO, 0);
182 }
183
184 10443 static int merge_samplerates_internal(AVFilterFormats *a,
185 AVFilterFormats *b, int check)
186 {
187 av_assert2(check || (a->refcount && b->refcount));
188
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10443 times.
10443 if (a == b) return 1;
189
190
23/24
✓ Branch 0 taken 6893 times.
✓ Branch 1 taken 3550 times.
✓ Branch 2 taken 6767 times.
✓ Branch 3 taken 126 times.
✓ Branch 4 taken 4907 times.
✓ Branch 5 taken 5410 times.
✓ Branch 6 taken 2008 times.
✓ Branch 7 taken 3402 times.
✓ Branch 8 taken 126 times.
✓ Branch 9 taken 5410 times.
✓ Branch 10 taken 122 times.
✓ Branch 11 taken 50 times.
✓ Branch 12 taken 74 times.
✓ Branch 13 taken 48 times.
✓ Branch 14 taken 172 times.
✓ Branch 15 taken 4 times.
✓ Branch 16 taken 126 times.
✓ Branch 17 taken 52 times.
✓ Branch 18 taken 4 times.
✓ Branch 19 taken 48 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 5458 times.
✓ Branch 23 taken 9819 times.
✓ Branch 24 taken 5458 times.
20364 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 1);
191 5458 return 1;
192 }
193
194 /**
195 * See can_merge_pix_fmts().
196 */
197 4985 static int can_merge_samplerates(const void *a, const void *b)
198 {
199 4985 return merge_samplerates_internal((AVFilterFormats *)a, (AVFilterFormats *)b, 1);
200 }
201
202 /**
203 * See merge_pix_fmts().
204 */
205 5458 static int merge_samplerates(void *a, void *b)
206 {
207 5458 return merge_samplerates_internal(a, b, 0);
208 }
209
210 /**
211 * See merge_pix_fmts().
212 */
213 5987 static int merge_channel_layouts_internal(AVFilterChannelLayouts *a,
214 AVFilterChannelLayouts *b, int check)
215 {
216 5987 AVChannelLayout *channel_layouts = NULL;
217 5987 unsigned a_all = a->all_layouts + a->all_counts;
218 5987 unsigned b_all = b->all_layouts + b->all_counts;
219 5987 int ret_max, ret_nb = 0, i, j, round;
220
221 av_assert2(a->refcount && b->refcount);
222
223
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5987 times.
5987 if (a == b) return 1;
224
225 /* Put the most generic set in a, to avoid doing everything twice */
226
2/2
✓ Branch 0 taken 2967 times.
✓ Branch 1 taken 3020 times.
5987 if (a_all < b_all) {
227 2967 FFSWAP(AVFilterChannelLayouts *, a, b);
228 2967 FFSWAP(unsigned, a_all, b_all);
229 }
230
2/2
✓ Branch 0 taken 5810 times.
✓ Branch 1 taken 177 times.
5987 if (a_all) {
231
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5805 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5810 if (a_all == 1 && !b_all) {
232 /* keep only known layouts in b; works also for b_all = 1 */
233
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 for (i = j = 0; i < b->nb_channel_layouts; i++)
234
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5 times.
5 if (KNOWN(&b->channel_layouts[i]) && i != j++) {
235 if (check)
236 return 1;
237 av_channel_layout_copy(&b->channel_layouts[j], &b->channel_layouts[i]);
238 }
239 /* Not optimal: the unknown layouts of b may become known after
240 another merge. */
241
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!j)
242 return 0;
243 5 b->nb_channel_layouts = j;
244 }
245
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 5810 times.
✓ Branch 3 taken 10195 times.
✓ Branch 4 taken 5810 times.
16005 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, return AVERROR(ENOMEM););
246 5810 return 1;
247 }
248
249 177 ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
250
3/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 114 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 63 times.
177 if (!check && !(channel_layouts = av_calloc(ret_max, sizeof(*channel_layouts))))
251 return AVERROR(ENOMEM);
252
253 /* a[known] intersect b[known] */
254
2/2
✓ Branch 0 taken 177 times.
✓ Branch 1 taken 71 times.
248 for (i = 0; i < a->nb_channel_layouts; i++) {
255
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 176 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
177 if (!KNOWN(&a->channel_layouts[i]))
256 1 continue;
257
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 7 times.
279 for (j = 0; j < b->nb_channel_layouts; j++) {
258
2/2
✓ Branch 1 taken 169 times.
✓ Branch 2 taken 103 times.
272 if (!av_channel_layout_compare(&a->channel_layouts[i], &b->channel_layouts[j])) {
259
2/2
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 63 times.
169 if (check)
260 106 return 1;
261 63 av_channel_layout_copy(&channel_layouts[ret_nb++], &a->channel_layouts[i]);
262 63 av_channel_layout_uninit(&a->channel_layouts[i]);
263 63 av_channel_layout_uninit(&b->channel_layouts[j]);
264 63 break;
265 }
266 }
267 }
268 /* 1st round: a[known] intersect b[generic]
269 2nd round: a[generic] intersect b[known] */
270
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 70 times.
212 for (round = 0; round < 2; round++) {
271
2/2
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 141 times.
369 for (i = 0; i < a->nb_channel_layouts; i++) {
272 228 AVChannelLayout *fmt = &a->channel_layouts[i], bfmt = { 0 };
273
5/6
✓ Branch 1 taken 102 times.
✓ Branch 2 taken 126 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 101 times.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
228 if (!av_channel_layout_check(fmt) || !KNOWN(fmt))
274 127 continue;
275 101 bfmt = FF_COUNT2LAYOUT(fmt->nb_channels);
276
2/2
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 100 times.
201 for (j = 0; j < b->nb_channel_layouts; j++)
277
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 100 times.
101 if (!av_channel_layout_compare(&b->channel_layouts[j], &bfmt)) {
278
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (check)
279 1 return 1;
280 av_channel_layout_copy(&channel_layouts[ret_nb++], fmt);
281 }
282 }
283 /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
284 141 FFSWAP(AVFilterChannelLayouts *, a, b);
285 }
286 /* a[generic] intersect b[generic] */
287
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 70 times.
140 for (i = 0; i < a->nb_channel_layouts; i++) {
288
3/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 63 times.
✗ Branch 3 not taken.
70 if (KNOWN(&a->channel_layouts[i]))
289 70 continue;
290 for (j = 0; j < b->nb_channel_layouts; j++)
291 if (!av_channel_layout_compare(&a->channel_layouts[i], &b->channel_layouts[j])) {
292 if (check)
293 return 1;
294 av_channel_layout_copy(&channel_layouts[ret_nb++], &a->channel_layouts[i]);
295 }
296 }
297
298
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 63 times.
70 if (!ret_nb) {
299 7 av_free(channel_layouts);
300 7 return 0;
301 }
302
303
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 51 times.
63 if (a->refcount > b->refcount)
304 12 FFSWAP(AVFilterChannelLayouts *, a, b);
305
306
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 63 times.
✓ Branch 4 taken 129 times.
✓ Branch 5 taken 63 times.
192 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts,
307 { av_free(channel_layouts); return AVERROR(ENOMEM); });
308 63 av_freep(&b->channel_layouts);
309 63 b->channel_layouts = channel_layouts;
310 63 b->nb_channel_layouts = ret_nb;
311 63 return 1;
312 }
313
314 4992 static int can_merge_channel_layouts(const void *a, const void *b)
315 {
316 4992 return merge_channel_layouts_internal((AVFilterChannelLayouts *)a,
317 (AVFilterChannelLayouts *)b, 1);
318 }
319
320 995 static int merge_channel_layouts(void *a, void *b)
321 {
322 995 return merge_channel_layouts_internal(a, b, 0);
323 }
324
325 80816 static int merge_generic_internal(AVFilterFormats *a,
326 AVFilterFormats *b, int check)
327 {
328 av_assert2(check || (a->refcount && b->refcount));
329
330
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80816 times.
80816 if (a == b)
331 return 1;
332
333
13/16
✓ Branch 0 taken 80816 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 257172 times.
✓ Branch 3 taken 1048909 times.
✓ Branch 4 taken 39220 times.
✓ Branch 5 taken 217952 times.
✓ Branch 6 taken 1306081 times.
✓ Branch 7 taken 4229 times.
✓ Branch 8 taken 261401 times.
✓ Branch 9 taken 41596 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 41596 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 41596 times.
✓ Branch 15 taken 73624 times.
✓ Branch 16 taken 41596 times.
1425530 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0);
334
335 41596 return 1;
336 }
337
338 39220 static int can_merge_generic(const void *a, const void *b)
339 {
340 39220 return merge_generic_internal((AVFilterFormats *)a,
341 (AVFilterFormats *)b, 1);
342 }
343
344 41596 static int merge_generic(void *a, void *b)
345 {
346 41596 return merge_generic_internal(a, b, 0);
347 }
348
349 static const AVFilterFormatsMerger mergers_video[] = {
350 {
351 .offset = offsetof(AVFilterFormatsConfig, formats),
352 .merge = merge_pix_fmts,
353 .can_merge = can_merge_pix_fmts,
354 },
355 {
356 .offset = offsetof(AVFilterFormatsConfig, color_spaces),
357 .merge = merge_generic,
358 .can_merge = can_merge_generic,
359 },
360 {
361 .offset = offsetof(AVFilterFormatsConfig, color_ranges),
362 .merge = merge_generic,
363 .can_merge = can_merge_generic,
364 },
365 };
366
367 static const AVFilterFormatsMerger mergers_audio[] = {
368 {
369 .offset = offsetof(AVFilterFormatsConfig, channel_layouts),
370 .merge = merge_channel_layouts,
371 .can_merge = can_merge_channel_layouts,
372 },
373 {
374 .offset = offsetof(AVFilterFormatsConfig, samplerates),
375 .merge = merge_samplerates,
376 .can_merge = can_merge_samplerates,
377 },
378 {
379 .offset = offsetof(AVFilterFormatsConfig, formats),
380 .merge = merge_sample_fmts,
381 .can_merge = can_merge_sample_fmts,
382 },
383 };
384
385 static const AVFilterNegotiation negotiate_video = {
386 .nb_mergers = FF_ARRAY_ELEMS(mergers_video),
387 .mergers = mergers_video,
388 .conversion_filter = "scale",
389 .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts),
390 };
391
392 static const AVFilterNegotiation negotiate_audio = {
393 .nb_mergers = FF_ARRAY_ELEMS(mergers_audio),
394 .mergers = mergers_audio,
395 .conversion_filter = "aresample",
396 .conversion_opts_offset = offsetof(AVFilterGraph, aresample_swr_opts),
397 };
398
399 26308 const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link)
400 {
401
2/3
✓ Branch 0 taken 20846 times.
✓ Branch 1 taken 5462 times.
✗ Branch 2 not taken.
26308 switch (link->type) {
402 20846 case AVMEDIA_TYPE_VIDEO: return &negotiate_video;
403 5462 case AVMEDIA_TYPE_AUDIO: return &negotiate_audio;
404 default: return NULL;
405 }
406 }
407
408 7130 int ff_fmt_is_in(int fmt, const int *fmts)
409 {
410 const int *p;
411
412
2/2
✓ Branch 0 taken 9083 times.
✓ Branch 1 taken 87 times.
9170 for (p = fmts; *p != -1; p++) {
413
2/2
✓ Branch 0 taken 7043 times.
✓ Branch 1 taken 2040 times.
9083 if (fmt == *p)
414 7043 return 1;
415 }
416 87 return 0;
417 }
418
419 #define MAKE_FORMAT_LIST(type, field, count_field) \
420 type *formats; \
421 int count = 0; \
422 if (fmts) \
423 for (count = 0; fmts[count] != -1; count++) \
424 ; \
425 formats = av_mallocz(sizeof(*formats)); \
426 if (!formats) \
427 return NULL; \
428 formats->count_field = count; \
429 if (count) { \
430 formats->field = av_malloc_array(count, sizeof(*formats->field)); \
431 if (!formats->field) { \
432 av_freep(&formats); \
433 return NULL; \
434 } \
435 }
436
437 9271 AVFilterFormats *ff_make_format_list(const int *fmts)
438 {
439
6/10
✓ Branch 0 taken 9271 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 77488 times.
✓ Branch 3 taken 9271 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9271 times.
✓ Branch 7 taken 9271 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 9271 times.
86759 MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
440
2/2
✓ Branch 0 taken 77488 times.
✓ Branch 1 taken 9271 times.
86759 while (count--)
441 77488 formats->formats[count] = fmts[count];
442
443 9271 return formats;
444 }
445
446 31 AVFilterChannelLayouts *ff_make_channel_layout_list(const AVChannelLayout *fmts)
447 {
448 AVFilterChannelLayouts *ch_layouts;
449 31 int count = 0;
450
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 if (fmts)
451
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 31 times.
62 for (count = 0; fmts[count].nb_channels; count++)
452 ;
453 31 ch_layouts = av_mallocz(sizeof(*ch_layouts));
454
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (!ch_layouts)
455 return NULL;
456 31 ch_layouts->nb_channel_layouts = count;
457
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 if (count) {
458 62 ch_layouts->channel_layouts =
459 31 av_calloc(count, sizeof(*ch_layouts->channel_layouts));
460
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (!ch_layouts->channel_layouts) {
461 av_freep(&ch_layouts);
462 return NULL;
463 }
464
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 31 times.
62 for (int i = 0; i < count; i++) {
465 31 int ret = av_channel_layout_copy(&ch_layouts->channel_layouts[i], &fmts[i]);
466
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (ret < 0)
467 goto fail;
468 }
469 }
470
471 31 return ch_layouts;
472
473 fail:
474 for (int i = 0; i < count; i++)
475 av_channel_layout_uninit(&ch_layouts->channel_layouts[i]);
476 av_free(ch_layouts->channel_layouts);
477 av_freep(&ch_layouts);
478
479 return NULL;
480 }
481
482 #define ADD_FORMAT(f, fmt, unref_fn, type, list, nb) \
483 do { \
484 type *fmts; \
485 \
486 if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) { \
487 return AVERROR(ENOMEM); \
488 } \
489 \
490 fmts = av_realloc_array((*f)->list, (*f)->nb + 1, \
491 sizeof(*(*f)->list)); \
492 if (!fmts) { \
493 unref_fn(f); \
494 return AVERROR(ENOMEM); \
495 } \
496 \
497 (*f)->list = fmts; \
498 ASSIGN_FMT(f, fmt, list, nb); \
499 } while (0)
500
501 #define ASSIGN_FMT(f, fmt, list, nb) \
502 do { \
503 (*f)->list[(*f)->nb++] = fmt; \
504 } while (0)
505
506 2441828 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
507 {
508
4/6
✓ Branch 0 taken 118872 times.
✓ Branch 1 taken 2322956 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 118872 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2441828 times.
2441828 ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
509 2441828 return 0;
510 }
511
512 #undef ASSIGN_FMT
513 #define ASSIGN_FMT(f, fmt, list, nb) \
514 do { \
515 int ret; \
516 memset((*f)->list + (*f)->nb, 0, sizeof(*(*f)->list)); \
517 ret = av_channel_layout_copy(&(*f)->list[(*f)->nb], fmt); \
518 if (ret < 0) \
519 return ret; \
520 (*f)->nb++; \
521 } while (0)
522
523 2576 int ff_add_channel_layout(AVFilterChannelLayouts **l,
524 const AVChannelLayout *channel_layout)
525 {
526 av_assert1(!(*l && (*l)->all_layouts));
527
5/8
✓ Branch 0 taken 1428 times.
✓ Branch 1 taken 1148 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1428 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2576 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2576 times.
2576 ADD_FORMAT(l, channel_layout, ff_channel_layouts_unref, AVChannelLayout, channel_layouts, nb_channel_layouts);
528 2576 return 0;
529 }
530
531 58 AVFilterFormats *ff_make_formats_list_singleton(int fmt)
532 {
533 58 int fmts[2] = { fmt, -1 };
534 58 return ff_make_format_list(fmts);
535 }
536
537 35046 AVFilterFormats *ff_all_formats(enum AVMediaType type)
538 {
539 35046 AVFilterFormats *ret = NULL;
540
541
2/2
✓ Branch 0 taken 25697 times.
✓ Branch 1 taken 9349 times.
35046 if (type == AVMEDIA_TYPE_VIDEO) {
542 25697 return ff_formats_pixdesc_filter(0, 0);
543
1/2
✓ Branch 0 taken 9349 times.
✗ Branch 1 not taken.
9349 } else if (type == AVMEDIA_TYPE_AUDIO) {
544 9349 enum AVSampleFormat fmt = 0;
545
2/2
✓ Branch 1 taken 112188 times.
✓ Branch 2 taken 9349 times.
121537 while (av_get_sample_fmt_name(fmt)) {
546
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 112188 times.
112188 if (ff_add_format(&ret, fmt) < 0)
547 return NULL;
548 112188 fmt++;
549 }
550 }
551
552 9349 return ret;
553 }
554
555 26284 AVFilterFormats *ff_formats_pixdesc_filter(unsigned want, unsigned rej)
556 {
557 unsigned nb_formats, fmt, flags;
558 26284 AVFilterFormats *formats = NULL;
559
560 while (1) {
561 52568 nb_formats = 0;
562 12038072 for (fmt = 0;; fmt++) {
563 12038072 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
564
2/2
✓ Branch 0 taken 52568 times.
✓ Branch 1 taken 11985504 times.
12038072 if (!desc)
565 52568 break;
566 11985504 flags = desc->flags;
567
2/2
✓ Branch 0 taken 11249552 times.
✓ Branch 1 taken 735952 times.
11985504 if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
568
2/2
✓ Branch 0 taken 4993960 times.
✓ Branch 1 taken 6255592 times.
11249552 !(desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
569
3/4
✓ Branch 0 taken 4573416 times.
✓ Branch 1 taken 420544 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4573416 times.
4993960 (desc->log2_chroma_w || desc->log2_chroma_h))
570 420544 flags |= FF_PIX_FMT_FLAG_SW_FLAT_SUB;
571
2/2
✓ Branch 0 taken 16736 times.
✓ Branch 1 taken 11968768 times.
11985504 if ((flags & (want | rej)) != want)
572 16736 continue;
573
2/2
✓ Branch 0 taken 5984384 times.
✓ Branch 1 taken 5984384 times.
11968768 if (formats)
574 5984384 formats->formats[nb_formats] = fmt;
575 11968768 nb_formats++;
576 }
577
2/2
✓ Branch 0 taken 26284 times.
✓ Branch 1 taken 26284 times.
52568 if (formats) {
578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26284 times.
26284 av_assert0(formats->nb_formats == nb_formats);
579 26284 return formats;
580 }
581 26284 formats = av_mallocz(sizeof(*formats));
582
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26284 times.
26284 if (!formats)
583 return NULL;
584 26284 formats->nb_formats = nb_formats;
585
1/2
✓ Branch 0 taken 26284 times.
✗ Branch 1 not taken.
26284 if (nb_formats) {
586 26284 formats->formats = av_malloc_array(nb_formats, sizeof(*formats->formats));
587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26284 times.
26284 if (!formats->formats) {
588 av_freep(&formats);
589 return NULL;
590 }
591 }
592 }
593 }
594
595 40 AVFilterFormats *ff_planar_sample_fmts(void)
596 {
597 40 AVFilterFormats *ret = NULL;
598 int fmt;
599
600
2/2
✓ Branch 1 taken 480 times.
✓ Branch 2 taken 40 times.
520 for (fmt = 0; av_get_bytes_per_sample(fmt)>0; fmt++)
601
2/2
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 240 times.
480 if (av_sample_fmt_is_planar(fmt))
602
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 240 times.
240 if (ff_add_format(&ret, fmt) < 0)
603 return NULL;
604
605 40 return ret;
606 }
607
608 35983 AVFilterFormats *ff_all_samplerates(void)
609 {
610 35983 AVFilterFormats *ret = av_mallocz(sizeof(*ret));
611 35983 return ret;
612 }
613
614 5 AVFilterChannelLayouts *ff_all_channel_layouts(void)
615 {
616 5 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
617
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!ret)
618 return NULL;
619 5 ret->all_layouts = 1;
620 5 return ret;
621 }
622
623 37862 AVFilterChannelLayouts *ff_all_channel_counts(void)
624 {
625 37862 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
626
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37862 times.
37862 if (!ret)
627 return NULL;
628 37862 ret->all_layouts = ret->all_counts = 1;
629 37862 return ret;
630 }
631
632 32748 AVFilterFormats *ff_all_color_spaces(void)
633 {
634 32748 AVFilterFormats *ret = NULL;
635
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32748 times.
32748 if (ff_add_format(&ret, AVCOL_SPC_UNSPECIFIED) < 0)
636 return NULL;
637
2/2
✓ Branch 0 taken 589464 times.
✓ Branch 1 taken 32748 times.
622212 for (int csp = 0; csp < AVCOL_SPC_NB; csp++) {
638
4/4
✓ Branch 0 taken 556716 times.
✓ Branch 1 taken 32748 times.
✓ Branch 2 taken 32748 times.
✓ Branch 3 taken 523968 times.
589464 if (csp == AVCOL_SPC_RESERVED ||
639 csp == AVCOL_SPC_UNSPECIFIED)
640 65496 continue;
641
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 523968 times.
523968 if (ff_add_format(&ret, csp) < 0)
642 return NULL;
643 }
644
645 32748 return ret;
646 }
647
648 40636 AVFilterFormats *ff_all_color_ranges(void)
649 {
650 40636 AVFilterFormats *ret = NULL;
651
2/2
✓ Branch 0 taken 121908 times.
✓ Branch 1 taken 40636 times.
162544 for (int range = 0; range < AVCOL_RANGE_NB; range++) {
652
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 121908 times.
121908 if (ff_add_format(&ret, range) < 0)
653 return NULL;
654 }
655
656 40636 return ret;
657 }
658
659 #define FORMATS_REF(f, ref, unref_fn) \
660 void *tmp; \
661 \
662 if (!f) \
663 return AVERROR(ENOMEM); \
664 \
665 tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1); \
666 if (!tmp) { \
667 unref_fn(&f); \
668 return AVERROR(ENOMEM); \
669 } \
670 f->refs = tmp; \
671 f->refs[f->refcount++] = ref; \
672 *ref = f; \
673 return 0
674
675 10916 int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
676 {
677
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10916 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10916 times.
10916 FORMATS_REF(f, ref, ff_channel_layouts_unref);
678 }
679
680 155947 int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
681 {
682
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 155947 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 155947 times.
155947 FORMATS_REF(f, ref, ff_formats_unref);
683 }
684
685 #define FIND_REF_INDEX(ref, idx) \
686 do { \
687 int i; \
688 for (i = 0; i < (*ref)->refcount; i ++) \
689 if((*ref)->refs[i] == ref) { \
690 idx = i; \
691 break; \
692 } \
693 } while (0)
694
695 #define FORMATS_UNREF(ref, list) \
696 do { \
697 int idx = -1; \
698 \
699 if (!*ref) \
700 return; \
701 \
702 FIND_REF_INDEX(ref, idx); \
703 \
704 if (idx >= 0) { \
705 memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
706 sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
707 --(*ref)->refcount; \
708 } \
709 if (!(*ref)->refcount) { \
710 FREE_LIST(ref, list); \
711 av_free((*ref)->list); \
712 av_free((*ref)->refs); \
713 av_free(*ref); \
714 } \
715 *ref = NULL; \
716 } while (0)
717
718 #define FREE_LIST(ref, list) do { } while(0)
719 583340 void ff_formats_unref(AVFilterFormats **ref)
720 {
721
10/10
✓ Branch 0 taken 345698 times.
✓ Branch 1 taken 237642 times.
✓ Branch 2 taken 155947 times.
✓ Branch 3 taken 48619 times.
✓ Branch 4 taken 204566 times.
✓ Branch 5 taken 81695 times.
✓ Branch 6 taken 155947 times.
✓ Branch 7 taken 81695 times.
✓ Branch 8 taken 117098 times.
✓ Branch 9 taken 120544 times.
631959 FORMATS_UNREF(ref, formats);
722 }
723
724 #undef FREE_LIST
725 #define FREE_LIST(ref, list) \
726 do { \
727 for (int i = 0; i < (*ref)->nb_channel_layouts; i++) \
728 av_channel_layout_uninit(&(*ref)->list[i]); \
729 } while(0)
730
731 150938 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
732 {
733
12/12
✓ Branch 0 taken 108804 times.
✓ Branch 1 taken 42134 times.
✓ Branch 2 taken 10916 times.
✓ Branch 3 taken 8017 times.
✓ Branch 4 taken 18933 times.
✓ Branch 5 taken 31218 times.
✓ Branch 6 taken 10916 times.
✓ Branch 7 taken 31218 times.
✓ Branch 8 taken 33453 times.
✓ Branch 9 taken 8681 times.
✓ Branch 11 taken 2235 times.
✓ Branch 12 taken 33453 times.
161190 FORMATS_UNREF(ref, channel_layouts);
734 }
735
736 #define FORMATS_CHANGEREF(oldref, newref) \
737 do { \
738 int idx = -1; \
739 \
740 FIND_REF_INDEX(oldref, idx); \
741 \
742 if (idx >= 0) { \
743 (*oldref)->refs[idx] = newref; \
744 *newref = *oldref; \
745 *oldref = NULL; \
746 } \
747 } while (0)
748
749 466 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
750 AVFilterChannelLayouts **newref)
751 {
752
4/6
✓ Branch 0 taken 466 times.
✓ Branch 1 taken 1413 times.
✓ Branch 2 taken 1879 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 466 times.
✗ Branch 5 not taken.
1879 FORMATS_CHANGEREF(oldref, newref);
753 466 }
754
755 2714 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
756 {
757
4/6
✓ Branch 0 taken 2714 times.
✓ Branch 1 taken 1037 times.
✓ Branch 2 taken 3751 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2714 times.
✗ Branch 5 not taken.
3751 FORMATS_CHANGEREF(oldref, newref);
758 2714 }
759
760 #define SET_COMMON_FORMATS(ctx, fmts, media_type, ref_fn, unref_fn) \
761 int i; \
762 \
763 if (!fmts) \
764 return AVERROR(ENOMEM); \
765 \
766 for (i = 0; i < ctx->nb_inputs; i++) { \
767 AVFilterLink *const link = ctx->inputs[i]; \
768 if (link && !link->outcfg.fmts && \
769 (media_type == AVMEDIA_TYPE_UNKNOWN || link->type == media_type)) { \
770 int ret = ref_fn(fmts, &ctx->inputs[i]->outcfg.fmts); \
771 if (ret < 0) { \
772 return ret; \
773 } \
774 } \
775 } \
776 for (i = 0; i < ctx->nb_outputs; i++) { \
777 AVFilterLink *const link = ctx->outputs[i]; \
778 if (link && !link->incfg.fmts && \
779 (media_type == AVMEDIA_TYPE_UNKNOWN || link->type == media_type)) { \
780 int ret = ref_fn(fmts, &ctx->outputs[i]->incfg.fmts); \
781 if (ret < 0) { \
782 return ret; \
783 } \
784 } \
785 } \
786 \
787 if (!fmts->refcount) \
788 unref_fn(&fmts); \
789 \
790 return 0;
791
792 36546 int ff_set_common_channel_layouts(AVFilterContext *ctx,
793 AVFilterChannelLayouts *channel_layouts)
794 {
795
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 36546 times.
✓ Branch 2 taken 28772 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24516 times.
✓ Branch 5 taken 4256 times.
✓ Branch 6 taken 4062 times.
✓ Branch 7 taken 20454 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4062 times.
✓ Branch 11 taken 28772 times.
✓ Branch 12 taken 36546 times.
✓ Branch 13 taken 28766 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 24510 times.
✓ Branch 16 taken 4256 times.
✓ Branch 17 taken 4064 times.
✓ Branch 18 taken 20446 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 4064 times.
✓ Branch 22 taken 28766 times.
✓ Branch 23 taken 36546 times.
✓ Branch 24 taken 31218 times.
✓ Branch 25 taken 5328 times.
94084 SET_COMMON_FORMATS(ctx, channel_layouts, AVMEDIA_TYPE_AUDIO,
796 ff_channel_layouts_ref, ff_channel_layouts_unref);
797 }
798
799 28 int ff_set_common_channel_layouts_from_list(AVFilterContext *ctx,
800 const AVChannelLayout *fmts)
801 {
802 28 return ff_set_common_channel_layouts(ctx, ff_make_channel_layout_list(fmts));
803 }
804
805 32416 int ff_set_common_all_channel_counts(AVFilterContext *ctx)
806 {
807 32416 return ff_set_common_channel_layouts(ctx, ff_all_channel_counts());
808 }
809
810 35339 int ff_set_common_samplerates(AVFilterContext *ctx,
811 AVFilterFormats *samplerates)
812 {
813
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 35339 times.
✓ Branch 2 taken 27567 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24583 times.
✓ Branch 5 taken 2984 times.
✓ Branch 6 taken 4129 times.
✓ Branch 7 taken 20454 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4129 times.
✓ Branch 11 taken 27567 times.
✓ Branch 12 taken 35339 times.
✓ Branch 13 taken 28832 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 24576 times.
✓ Branch 16 taken 4256 times.
✓ Branch 17 taken 4130 times.
✓ Branch 18 taken 20446 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 4130 times.
✓ Branch 22 taken 28832 times.
✓ Branch 23 taken 35339 times.
✓ Branch 24 taken 29946 times.
✓ Branch 25 taken 5393 times.
91738 SET_COMMON_FORMATS(ctx, samplerates, AVMEDIA_TYPE_AUDIO,
814 ff_formats_ref, ff_formats_unref);
815 }
816
817 46 int ff_set_common_samplerates_from_list(AVFilterContext *ctx,
818 const int *samplerates)
819 {
820 46 return ff_set_common_samplerates(ctx, ff_make_format_list(samplerates));
821 }
822
823 32483 int ff_set_common_all_samplerates(AVFilterContext *ctx)
824 {
825 32483 return ff_set_common_samplerates(ctx, ff_all_samplerates());
826 }
827
828 37192 int ff_set_common_color_spaces(AVFilterContext *ctx,
829 AVFilterFormats *color_spaces)
830 {
831
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 37192 times.
✓ Branch 2 taken 26232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22330 times.
✓ Branch 5 taken 3902 times.
✓ Branch 6 taken 16913 times.
✓ Branch 7 taken 5417 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16913 times.
✓ Branch 11 taken 26232 times.
✓ Branch 12 taken 37192 times.
✓ Branch 13 taken 30684 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 22338 times.
✓ Branch 16 taken 8346 times.
✓ Branch 17 taken 16913 times.
✓ Branch 18 taken 5425 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 16913 times.
✓ Branch 22 taken 30684 times.
✓ Branch 23 taken 37192 times.
✓ Branch 24 taken 15031 times.
✓ Branch 25 taken 22161 times.
94108 SET_COMMON_FORMATS(ctx, color_spaces, AVMEDIA_TYPE_VIDEO,
832 ff_formats_ref, ff_formats_unref);
833 }
834
835 int ff_set_common_color_spaces_from_list(AVFilterContext *ctx,
836 const int *color_ranges)
837 {
838 return ff_set_common_color_spaces(ctx, ff_make_format_list(color_ranges));
839 }
840
841 32748 int ff_set_common_all_color_spaces(AVFilterContext *ctx)
842 {
843 32748 return ff_set_common_color_spaces(ctx, ff_all_color_spaces());
844 }
845
846 37192 int ff_set_common_color_ranges(AVFilterContext *ctx,
847 AVFilterFormats *color_ranges)
848 {
849
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 37192 times.
✓ Branch 2 taken 26232 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22330 times.
✓ Branch 5 taken 3902 times.
✓ Branch 6 taken 16913 times.
✓ Branch 7 taken 5417 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16913 times.
✓ Branch 11 taken 26232 times.
✓ Branch 12 taken 37192 times.
✓ Branch 13 taken 30684 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 22338 times.
✓ Branch 16 taken 8346 times.
✓ Branch 17 taken 16913 times.
✓ Branch 18 taken 5425 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 16913 times.
✓ Branch 22 taken 30684 times.
✓ Branch 23 taken 37192 times.
✓ Branch 24 taken 15031 times.
✓ Branch 25 taken 22161 times.
94108 SET_COMMON_FORMATS(ctx, color_ranges, AVMEDIA_TYPE_VIDEO,
850 ff_formats_ref, ff_formats_unref);
851 }
852
853 int ff_set_common_color_ranges_from_list(AVFilterContext *ctx,
854 const int *color_ranges)
855 {
856 return ff_set_common_color_ranges(ctx, ff_make_format_list(color_ranges));
857 }
858
859 32748 int ff_set_common_all_color_ranges(AVFilterContext *ctx)
860 {
861 32748 return ff_set_common_color_ranges(ctx, ff_all_color_ranges());
862 }
863
864 /**
865 * A helper for query_formats() which sets all links to the same list of
866 * formats. If there are no links hooked to this filter, the list of formats is
867 * freed.
868 */
869 48855 int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
870 {
871
15/20
✗ Branch 0 not taken.
✓ Branch 1 taken 48855 times.
✓ Branch 2 taken 35810 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20947 times.
✓ Branch 5 taken 14863 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20947 times.
✓ Branch 9 taken 35810 times.
✓ Branch 10 taken 48855 times.
✓ Branch 11 taken 42324 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 20973 times.
✓ Branch 14 taken 21351 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 20973 times.
✓ Branch 18 taken 42324 times.
✓ Branch 19 taken 48855 times.
✓ Branch 20 taken 21371 times.
✓ Branch 21 taken 27484 times.
126989 SET_COMMON_FORMATS(ctx, formats, AVMEDIA_TYPE_UNKNOWN,
872 ff_formats_ref, ff_formats_unref);
873 }
874
875 123 int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
876 {
877 123 return ff_set_common_formats(ctx, ff_make_format_list(fmts));
878 }
879
880 32781 int ff_default_query_formats(AVFilterContext *ctx)
881 {
882 32781 const AVFilter *const f = ctx->filter;
883 AVFilterFormats *formats;
884 enum AVMediaType type;
885 int ret;
886
887
5/5
✓ Branch 0 taken 336 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 33 times.
✓ Branch 3 taken 13 times.
✓ Branch 4 taken 32379 times.
32781 switch (f->formats_state) {
888 336 case FF_FILTER_FORMATS_PIXFMT_LIST:
889 336 type = AVMEDIA_TYPE_VIDEO;
890 336 formats = ff_make_format_list(f->formats.pixels_list);
891 336 break;
892 20 case FF_FILTER_FORMATS_SAMPLEFMTS_LIST:
893 20 type = AVMEDIA_TYPE_AUDIO;
894 20 formats = ff_make_format_list(f->formats.samples_list);
895 20 break;
896 33 case FF_FILTER_FORMATS_SINGLE_PIXFMT:
897 33 type = AVMEDIA_TYPE_VIDEO;
898 33 formats = ff_make_formats_list_singleton(f->formats.pix_fmt);
899 33 break;
900 13 case FF_FILTER_FORMATS_SINGLE_SAMPLEFMT:
901 13 type = AVMEDIA_TYPE_AUDIO;
902 13 formats = ff_make_formats_list_singleton(f->formats.sample_fmt);
903 13 break;
904 32379 default:
905 av_assert2(!"Unreachable");
906 /* Intended fallthrough */
907 case FF_FILTER_FORMATS_PASSTHROUGH:
908 case FF_FILTER_FORMATS_QUERY_FUNC:
909 32379 type = AVMEDIA_TYPE_UNKNOWN;
910
2/2
✓ Branch 0 taken 25822 times.
✓ Branch 1 taken 6557 times.
38936 formats = ff_all_formats(ctx->nb_inputs ? ctx->inputs [0]->type :
911
1/2
✓ Branch 0 taken 6557 times.
✗ Branch 1 not taken.
6557 ctx->nb_outputs ? ctx->outputs[0]->type :
912 AVMEDIA_TYPE_VIDEO);
913 32379 break;
914 }
915
916 32781 ret = ff_set_common_formats(ctx, formats);
917
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32781 times.
32781 if (ret < 0)
918 return ret;
919
2/2
✓ Branch 0 taken 32748 times.
✓ Branch 1 taken 33 times.
32781 if (type != AVMEDIA_TYPE_AUDIO) {
920 32748 ret = ff_set_common_all_color_spaces(ctx);
921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32748 times.
32748 if (ret < 0)
922 return ret;
923 32748 ret = ff_set_common_all_color_ranges(ctx);
924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32748 times.
32748 if (ret < 0)
925 return ret;
926 }
927
2/2
✓ Branch 0 taken 32412 times.
✓ Branch 1 taken 369 times.
32781 if (type != AVMEDIA_TYPE_VIDEO) {
928 32412 ret = ff_set_common_all_channel_counts(ctx);
929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32412 times.
32412 if (ret < 0)
930 return ret;
931 32412 ret = ff_set_common_all_samplerates(ctx);
932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32412 times.
32412 if (ret < 0)
933 return ret;
934 }
935
936 32781 return 0;
937 }
938
939 /* internal functions for parsing audio format arguments */
940
941 10528 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
942 {
943 char *tail;
944 10528 int pix_fmt = av_get_pix_fmt(arg);
945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10528 times.
10528 if (pix_fmt == AV_PIX_FMT_NONE) {
946 pix_fmt = strtol(arg, &tail, 0);
947 if (*tail || !av_pix_fmt_desc_get(pix_fmt)) {
948 av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
949 return AVERROR(EINVAL);
950 }
951 }
952 10528 *ret = pix_fmt;
953 10528 return 0;
954 }
955
956 15 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
957 {
958 char *tail;
959 15 double srate = av_strtod(arg, &tail);
960
4/8
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 15 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 15 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 15 times.
15 if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
961 av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
962 return AVERROR(EINVAL);
963 }
964 15 *ret = srate;
965 15 return 0;
966 }
967
968 65 int ff_parse_channel_layout(AVChannelLayout *ret, int *nret, const char *arg,
969 void *log_ctx)
970 {
971 65 AVChannelLayout chlayout = { 0 };
972 int res;
973
974 65 res = av_channel_layout_from_string(&chlayout, arg);
975
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 60 times.
65 if (res < 0) {
976 5 av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
977 5 return AVERROR(EINVAL);
978 }
979
980
3/4
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 47 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
60 if (chlayout.order == AV_CHANNEL_ORDER_UNSPEC && !nret) {
981 av_log(log_ctx, AV_LOG_ERROR, "Unknown channel layout '%s' is not supported.\n", arg);
982 return AVERROR(EINVAL);
983 }
984 60 *ret = chlayout;
985
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 if (nret)
986 60 *nret = chlayout.nb_channels;
987
988 60 return 0;
989 }
990
991 113246 static int check_list(void *log, const char *name, const AVFilterFormats *fmts)
992 {
993 unsigned i, j;
994
995
2/2
✓ Branch 0 taken 50447 times.
✓ Branch 1 taken 62799 times.
113246 if (!fmts)
996 50447 return 0;
997
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62799 times.
62799 if (!fmts->nb_formats) {
998 av_log(log, AV_LOG_ERROR, "Empty %s list\n", name);
999 return AVERROR(EINVAL);
1000 }
1001
2/2
✓ Branch 0 taken 2121736 times.
✓ Branch 1 taken 62799 times.
2184535 for (i = 0; i < fmts->nb_formats; i++) {
1002
2/2
✓ Branch 0 taken 187707523 times.
✓ Branch 1 taken 2121736 times.
189829259 for (j = i + 1; j < fmts->nb_formats; j++) {
1003
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 187707523 times.
187707523 if (fmts->formats[i] == fmts->formats[j]) {
1004 av_log(log, AV_LOG_ERROR, "Duplicated %s\n", name);
1005 return AVERROR(EINVAL);
1006 }
1007 }
1008 }
1009 62799 return 0;
1010 }
1011
1012 34215 int ff_formats_check_pixel_formats(void *log, const AVFilterFormats *fmts)
1013 {
1014 34215 return check_list(log, "pixel format", fmts);
1015 }
1016
1017 8512 int ff_formats_check_sample_formats(void *log, const AVFilterFormats *fmts)
1018 {
1019 8512 return check_list(log, "sample format", fmts);
1020 }
1021
1022 8512 int ff_formats_check_sample_rates(void *log, const AVFilterFormats *fmts)
1023 {
1024
4/4
✓ Branch 0 taken 7240 times.
✓ Branch 1 taken 1272 times.
✓ Branch 2 taken 5151 times.
✓ Branch 3 taken 2089 times.
8512 if (!fmts || !fmts->nb_formats)
1025 6423 return 0;
1026 2089 return check_list(log, "sample rate", fmts);
1027 }
1028
1029 34215 int ff_formats_check_color_spaces(void *log, const AVFilterFormats *fmts)
1030 {
1031
4/4
✓ Branch 0 taken 79146 times.
✓ Branch 1 taken 21967 times.
✓ Branch 2 taken 66898 times.
✓ Branch 3 taken 12248 times.
101113 for (int i = 0; fmts && i < fmts->nb_formats; i++) {
1032
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66898 times.
66898 if (fmts->formats[i] == AVCOL_SPC_RESERVED) {
1033 av_log(log, AV_LOG_ERROR, "Invalid color range\n");
1034 return AVERROR(EINVAL);
1035 }
1036 }
1037 34215 return check_list(log, "color space", fmts);
1038 }
1039
1040 34215 int ff_formats_check_color_ranges(void *log, const AVFilterFormats *fmts)
1041 {
1042 34215 return check_list(log, "color range", fmts);
1043 }
1044
1045 3180 static int layouts_compatible(const AVChannelLayout *a, const AVChannelLayout *b)
1046 {
1047 3180 return !av_channel_layout_compare(a, b) ||
1048
3/12
✓ Branch 0 taken 3180 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 3180 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 3180 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
6360 (KNOWN(a) && !KNOWN(b) && a->nb_channels == b->nb_channels) ||
1049
2/10
✗ Branch 0 not taken.
✓ Branch 1 taken 3180 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3180 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
3180 (KNOWN(b) && !KNOWN(a) && b->nb_channels == a->nb_channels);
1050 }
1051
1052 8512 int ff_formats_check_channel_layouts(void *log, const AVFilterChannelLayouts *fmts)
1053 {
1054 unsigned i, j;
1055
1056
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8512 times.
8512 if (!fmts)
1057 return 0;
1058
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8512 times.
8512 if (fmts->all_layouts < fmts->all_counts) {
1059 av_log(log, AV_LOG_ERROR, "Inconsistent generic list\n");
1060 return AVERROR(EINVAL);
1061 }
1062
3/4
✓ Branch 0 taken 1571 times.
✓ Branch 1 taken 6941 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1571 times.
8512 if (!fmts->all_layouts && !fmts->nb_channel_layouts) {
1063 av_log(log, AV_LOG_ERROR, "Empty channel layout list\n");
1064 return AVERROR(EINVAL);
1065 }
1066
2/2
✓ Branch 0 taken 2189 times.
✓ Branch 1 taken 8512 times.
10701 for (i = 0; i < fmts->nb_channel_layouts; i++) {
1067
2/2
✓ Branch 0 taken 3180 times.
✓ Branch 1 taken 2189 times.
5369 for (j = i + 1; j < fmts->nb_channel_layouts; j++) {
1068
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3180 times.
3180 if (layouts_compatible(&fmts->channel_layouts[i], &fmts->channel_layouts[j])) {
1069 av_log(log, AV_LOG_ERROR, "Duplicated or redundant channel layout\n");
1070 return AVERROR(EINVAL);
1071 }
1072 }
1073 }
1074 8512 return 0;
1075 }
1076