FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/formats.c
Date: 2024-04-12 08:31:17
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 51337 static int merge_formats_internal(AVFilterFormats *a, AVFilterFormats *b,
96 enum AVMediaType type, int check)
97 {
98 int i, j;
99 51337 int alpha1=0, alpha2=0;
100 51337 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 51337 times.
51337 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 40932 times.
✓ Branch 1 taken 10405 times.
51337 if (type == AVMEDIA_TYPE_VIDEO)
115
2/2
✓ Branch 0 taken 1448324 times.
✓ Branch 1 taken 40932 times.
1489256 for (i = 0; i < a->nb_formats; i++) {
116 1448324 const AVPixFmtDescriptor *const adesc = av_pix_fmt_desc_get(a->formats[i]);
117
2/2
✓ Branch 0 taken 25219927 times.
✓ Branch 1 taken 1448324 times.
26668251 for (j = 0; j < b->nb_formats; j++) {
118 25219927 const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
119 25219927 alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA;
120
4/4
✓ Branch 0 taken 22720895 times.
✓ Branch 1 taken 2499032 times.
✓ Branch 2 taken 19958802 times.
✓ Branch 3 taken 2762093 times.
25219927 chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
121
2/2
✓ Branch 0 taken 121529 times.
✓ Branch 1 taken 25098398 times.
25219927 if (a->formats[i] == b->formats[j]) {
122 121529 alpha1 |= adesc->flags & AV_PIX_FMT_FLAG_ALPHA;
123 121529 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 51316 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 528 times.
✓ Branch 3 taken 50788 times.
51337 if (alpha2 > alpha1 || chroma2 > chroma1)
130 549 return 0;
131
132
14/16
✓ Branch 0 taken 50788 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 93264 times.
✓ Branch 3 taken 6590807 times.
✓ Branch 4 taken 24087 times.
✓ Branch 5 taken 69177 times.
✓ Branch 6 taken 6684071 times.
✓ Branch 7 taken 988824 times.
✓ Branch 8 taken 1082088 times.
✓ Branch 9 taken 26701 times.
✓ Branch 10 taken 498 times.
✓ Branch 11 taken 26203 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 26203 times.
✓ Branch 15 taken 52735 times.
✓ Branch 16 taken 26203 times.
7752331 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0);
133
134 26203 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 20169 static int can_merge_pix_fmts(const void *a, const void *b)
145 {
146 20169 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 20763 static int merge_pix_fmts(void *a, void *b)
163 {
164 20763 return merge_formats_internal(a, b, AVMEDIA_TYPE_VIDEO, 0);
165 }
166
167 /**
168 * See can_merge_pix_fmts().
169 */
170 4965 static int can_merge_sample_fmts(const void *a, const void *b)
171 {
172 4965 return merge_formats_internal((AVFilterFormats *)a,
173 (AVFilterFormats *)b, AVMEDIA_TYPE_AUDIO, 1);
174 }
175
176 /**
177 * See merge_pix_fmts().
178 */
179 5440 static int merge_sample_fmts(void *a, void *b)
180 {
181 5440 return merge_formats_internal(a, b, AVMEDIA_TYPE_AUDIO, 0);
182 }
183
184 10409 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 10409 times.
10409 if (a == b) return 1;
189
190
23/24
✓ Branch 0 taken 6871 times.
✓ Branch 1 taken 3538 times.
✓ Branch 2 taken 6745 times.
✓ Branch 3 taken 126 times.
✓ Branch 4 taken 4891 times.
✓ Branch 5 taken 5392 times.
✓ Branch 6 taken 2001 times.
✓ Branch 7 taken 3391 times.
✓ Branch 8 taken 126 times.
✓ Branch 9 taken 5392 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 5440 times.
✓ Branch 23 taken 9784 times.
✓ Branch 24 taken 5440 times.
20295 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 1);
191 5440 return 1;
192 }
193
194 /**
195 * See can_merge_pix_fmts().
196 */
197 4969 static int can_merge_samplerates(const void *a, const void *b)
198 {
199 4969 return merge_samplerates_internal((AVFilterFormats *)a, (AVFilterFormats *)b, 1);
200 }
201
202 /**
203 * See merge_pix_fmts().
204 */
205 5440 static int merge_samplerates(void *a, void *b)
206 {
207 5440 return merge_samplerates_internal(a, b, 0);
208 }
209
210 /**
211 * See merge_pix_fmts().
212 */
213 5967 static int merge_channel_layouts_internal(AVFilterChannelLayouts *a,
214 AVFilterChannelLayouts *b, int check)
215 {
216 5967 AVChannelLayout *channel_layouts = NULL;
217 5967 unsigned a_all = a->all_layouts + a->all_counts;
218 5967 unsigned b_all = b->all_layouts + b->all_counts;
219 5967 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 5967 times.
5967 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 2954 times.
✓ Branch 1 taken 3013 times.
5967 if (a_all < b_all) {
227 2954 FFSWAP(AVFilterChannelLayouts *, a, b);
228 2954 FFSWAP(unsigned, a_all, b_all);
229 }
230
2/2
✓ Branch 0 taken 5790 times.
✓ Branch 1 taken 177 times.
5967 if (a_all) {
231
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5785 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5790 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 5790 times.
✓ Branch 3 taken 10154 times.
✓ Branch 4 taken 5790 times.
15944 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, return AVERROR(ENOMEM););
246 5790 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 4976 static int can_merge_channel_layouts(const void *a, const void *b)
315 {
316 4976 return merge_channel_layouts_internal((AVFilterChannelLayouts *)a,
317 (AVFilterChannelLayouts *)b, 1);
318 }
319
320 991 static int merge_channel_layouts(void *a, void *b)
321 {
322 991 return merge_channel_layouts_internal(a, b, 0);
323 }
324
325 80668 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 80668 times.
80668 if (a == b)
331 return 1;
332
333
13/16
✓ Branch 0 taken 80668 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 256689 times.
✓ Branch 3 taken 1046725 times.
✓ Branch 4 taken 39146 times.
✓ Branch 5 taken 217543 times.
✓ Branch 6 taken 1303414 times.
✓ Branch 7 taken 4211 times.
✓ Branch 8 taken 260900 times.
✓ Branch 9 taken 41522 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 41522 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 41522 times.
✓ Branch 15 taken 73492 times.
✓ Branch 16 taken 41522 times.
1422639 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0);
334
335 41522 return 1;
336 }
337
338 39146 static int can_merge_generic(const void *a, const void *b)
339 {
340 39146 return merge_generic_internal((AVFilterFormats *)a,
341 (AVFilterFormats *)b, 1);
342 }
343
344 41522 static int merge_generic(void *a, void *b)
345 {
346 41522 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 26253 const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link)
400 {
401
2/3
✓ Branch 0 taken 20809 times.
✓ Branch 1 taken 5444 times.
✗ Branch 2 not taken.
26253 switch (link->type) {
402 20809 case AVMEDIA_TYPE_VIDEO: return &negotiate_video;
403 5444 case AVMEDIA_TYPE_AUDIO: return &negotiate_audio;
404 default: return NULL;
405 }
406 }
407
408 7118 int ff_fmt_is_in(int fmt, const int *fmts)
409 {
410 const int *p;
411
412
2/2
✓ Branch 0 taken 9071 times.
✓ Branch 1 taken 87 times.
9158 for (p = fmts; *p != -1; p++) {
413
2/2
✓ Branch 0 taken 7031 times.
✓ Branch 1 taken 2040 times.
9071 if (fmt == *p)
414 7031 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 9252 AVFilterFormats *ff_make_format_list(const int *fmts)
438 {
439
6/10
✓ Branch 0 taken 9252 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 77346 times.
✓ Branch 3 taken 9252 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9252 times.
✓ Branch 7 taken 9252 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 9252 times.
86598 MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
440
2/2
✓ Branch 0 taken 77346 times.
✓ Branch 1 taken 9252 times.
86598 while (count--)
441 77346 formats->formats[count] = fmts[count];
442
443 9252 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 2437332 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
507 {
508
4/6
✓ Branch 0 taken 118627 times.
✓ Branch 1 taken 2318705 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 118627 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2437332 times.
2437332 ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
509 2437332 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 2571 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 1423 times.
✓ Branch 1 taken 1148 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1423 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2571 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2571 times.
2571 ADD_FORMAT(l, channel_layout, ff_channel_layouts_unref, AVChannelLayout, channel_layouts, nb_channel_layouts);
528 2571 return 0;
529 }
530
531 57 AVFilterFormats *ff_make_formats_list_singleton(int fmt)
532 {
533 57 int fmts[2] = { fmt, -1 };
534 57 return ff_make_format_list(fmts);
535 }
536
537 34976 AVFilterFormats *ff_all_formats(enum AVMediaType type)
538 {
539 34976 AVFilterFormats *ret = NULL;
540
541
2/2
✓ Branch 0 taken 25653 times.
✓ Branch 1 taken 9323 times.
34976 if (type == AVMEDIA_TYPE_VIDEO) {
542 25653 return ff_formats_pixdesc_filter(0, 0);
543
1/2
✓ Branch 0 taken 9323 times.
✗ Branch 1 not taken.
9323 } else if (type == AVMEDIA_TYPE_AUDIO) {
544 9323 enum AVSampleFormat fmt = 0;
545
2/2
✓ Branch 1 taken 111876 times.
✓ Branch 2 taken 9323 times.
121199 while (av_get_sample_fmt_name(fmt)) {
546
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 111876 times.
111876 if (ff_add_format(&ret, fmt) < 0)
547 return NULL;
548 111876 fmt++;
549 }
550 }
551
552 9323 return ret;
553 }
554
555 26236 AVFilterFormats *ff_formats_pixdesc_filter(unsigned want, unsigned rej)
556 {
557 unsigned nb_formats, fmt, flags;
558 26236 AVFilterFormats *formats = NULL;
559
560 while (1) {
561 52472 nb_formats = 0;
562 12016088 for (fmt = 0;; fmt++) {
563 12016088 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
564
2/2
✓ Branch 0 taken 52472 times.
✓ Branch 1 taken 11963616 times.
12016088 if (!desc)
565 52472 break;
566 11963616 flags = desc->flags;
567
2/2
✓ Branch 0 taken 11229008 times.
✓ Branch 1 taken 734608 times.
11963616 if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
568
2/2
✓ Branch 0 taken 4984840 times.
✓ Branch 1 taken 6244168 times.
11229008 !(desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
569
3/4
✓ Branch 0 taken 4565064 times.
✓ Branch 1 taken 419776 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4565064 times.
4984840 (desc->log2_chroma_w || desc->log2_chroma_h))
570 419776 flags |= FF_PIX_FMT_FLAG_SW_FLAT_SUB;
571
2/2
✓ Branch 0 taken 16632 times.
✓ Branch 1 taken 11946984 times.
11963616 if ((flags & (want | rej)) != want)
572 16632 continue;
573
2/2
✓ Branch 0 taken 5973492 times.
✓ Branch 1 taken 5973492 times.
11946984 if (formats)
574 5973492 formats->formats[nb_formats] = fmt;
575 11946984 nb_formats++;
576 }
577
2/2
✓ Branch 0 taken 26236 times.
✓ Branch 1 taken 26236 times.
52472 if (formats) {
578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26236 times.
26236 av_assert0(formats->nb_formats == nb_formats);
579 26236 return formats;
580 }
581 26236 formats = av_mallocz(sizeof(*formats));
582
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26236 times.
26236 if (!formats)
583 return NULL;
584 26236 formats->nb_formats = nb_formats;
585
1/2
✓ Branch 0 taken 26236 times.
✗ Branch 1 not taken.
26236 if (nb_formats) {
586 26236 formats->formats = av_malloc_array(nb_formats, sizeof(*formats->formats));
587
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26236 times.
26236 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 35907 AVFilterFormats *ff_all_samplerates(void)
609 {
610 35907 AVFilterFormats *ret = av_mallocz(sizeof(*ret));
611 35907 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 37781 AVFilterChannelLayouts *ff_all_channel_counts(void)
624 {
625 37781 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
626
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37781 times.
37781 if (!ret)
627 return NULL;
628 37781 ret->all_layouts = ret->all_counts = 1;
629 37781 return ret;
630 }
631
632 32678 AVFilterFormats *ff_all_color_spaces(void)
633 {
634 32678 AVFilterFormats *ret = NULL;
635
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32678 times.
32678 if (ff_add_format(&ret, AVCOL_SPC_UNSPECIFIED) < 0)
636 return NULL;
637
2/2
✓ Branch 0 taken 588204 times.
✓ Branch 1 taken 32678 times.
620882 for (int csp = 0; csp < AVCOL_SPC_NB; csp++) {
638
4/4
✓ Branch 0 taken 555526 times.
✓ Branch 1 taken 32678 times.
✓ Branch 2 taken 32678 times.
✓ Branch 3 taken 522848 times.
588204 if (csp == AVCOL_SPC_RESERVED ||
639 csp == AVCOL_SPC_UNSPECIFIED)
640 65356 continue;
641
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 522848 times.
522848 if (ff_add_format(&ret, csp) < 0)
642 return NULL;
643 }
644
645 32678 return ret;
646 }
647
648 40552 AVFilterFormats *ff_all_color_ranges(void)
649 {
650 40552 AVFilterFormats *ret = NULL;
651
2/2
✓ Branch 0 taken 121656 times.
✓ Branch 1 taken 40552 times.
162208 for (int range = 0; range < AVCOL_RANGE_NB; range++) {
652
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 121656 times.
121656 if (ff_add_format(&ret, range) < 0)
653 return NULL;
654 }
655
656 40552 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 10880 int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
676 {
677
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10880 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10880 times.
10880 FORMATS_REF(f, ref, ff_channel_layouts_unref);
678 }
679
680 155643 int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
681 {
682
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 155643 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 155643 times.
155643 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 582202 void ff_formats_unref(AVFilterFormats **ref)
720 {
721
10/10
✓ Branch 0 taken 345034 times.
✓ Branch 1 taken 237168 times.
✓ Branch 2 taken 155643 times.
✓ Branch 3 taken 48468 times.
✓ Branch 4 taken 204111 times.
✓ Branch 5 taken 81525 times.
✓ Branch 6 taken 155643 times.
✓ Branch 7 taken 81525 times.
✓ Branch 8 taken 116857 times.
✓ Branch 9 taken 120311 times.
630670 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 150640 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
732 {
733
12/12
✓ Branch 0 taken 108603 times.
✓ Branch 1 taken 42037 times.
✓ Branch 2 taken 10880 times.
✓ Branch 3 taken 7997 times.
✓ Branch 4 taken 18877 times.
✓ Branch 5 taken 31157 times.
✓ Branch 6 taken 10880 times.
✓ Branch 7 taken 31157 times.
✓ Branch 8 taken 33387 times.
✓ Branch 9 taken 8650 times.
✓ Branch 11 taken 2230 times.
✓ Branch 12 taken 33387 times.
160867 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 464 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
750 AVFilterChannelLayouts **newref)
751 {
752
4/6
✓ Branch 0 taken 464 times.
✓ Branch 1 taken 1405 times.
✓ Branch 2 taken 1869 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 464 times.
✗ Branch 5 not taken.
1869 FORMATS_CHANGEREF(oldref, newref);
753 464 }
754
755 2710 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
756 {
757
4/6
✓ Branch 0 taken 2710 times.
✓ Branch 1 taken 1035 times.
✓ Branch 2 taken 3745 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2710 times.
✗ Branch 5 not taken.
3745 FORMATS_CHANGEREF(oldref, newref);
758 2710 }
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 36464 int ff_set_common_channel_layouts(AVFilterContext *ctx,
793 AVFilterChannelLayouts *channel_layouts)
794 {
795
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 36464 times.
✓ Branch 2 taken 28710 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24466 times.
✓ Branch 5 taken 4244 times.
✓ Branch 6 taken 4046 times.
✓ Branch 7 taken 20420 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4046 times.
✓ Branch 11 taken 28710 times.
✓ Branch 12 taken 36464 times.
✓ Branch 13 taken 28705 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 24461 times.
✓ Branch 16 taken 4244 times.
✓ Branch 17 taken 4048 times.
✓ Branch 18 taken 20413 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 4048 times.
✓ Branch 22 taken 28705 times.
✓ Branch 23 taken 36464 times.
✓ Branch 24 taken 31157 times.
✓ Branch 25 taken 5307 times.
93879 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 32349 int ff_set_common_all_channel_counts(AVFilterContext *ctx)
806 {
807 32349 return ff_set_common_channel_layouts(ctx, ff_all_channel_counts());
808 }
809
810 35262 int ff_set_common_samplerates(AVFilterContext *ctx,
811 AVFilterFormats *samplerates)
812 {
813
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 35262 times.
✓ Branch 2 taken 27510 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24533 times.
✓ Branch 5 taken 2977 times.
✓ Branch 6 taken 4113 times.
✓ Branch 7 taken 20420 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4113 times.
✓ Branch 11 taken 27510 times.
✓ Branch 12 taken 35262 times.
✓ Branch 13 taken 28771 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 24527 times.
✓ Branch 16 taken 4244 times.
✓ Branch 17 taken 4114 times.
✓ Branch 18 taken 20413 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 4114 times.
✓ Branch 22 taken 28771 times.
✓ Branch 23 taken 35262 times.
✓ Branch 24 taken 29890 times.
✓ Branch 25 taken 5372 times.
91543 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 32416 int ff_set_common_all_samplerates(AVFilterContext *ctx)
824 {
825 32416 return ff_set_common_samplerates(ctx, ff_all_samplerates());
826 }
827
828 37114 int ff_set_common_color_spaces(AVFilterContext *ctx,
829 AVFilterFormats *color_spaces)
830 {
831
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 37114 times.
✓ Branch 2 taken 26178 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22283 times.
✓ Branch 5 taken 3895 times.
✓ Branch 6 taken 16883 times.
✓ Branch 7 taken 5400 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16883 times.
✓ Branch 11 taken 26178 times.
✓ Branch 12 taken 37114 times.
✓ Branch 13 taken 30622 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 22291 times.
✓ Branch 16 taken 8331 times.
✓ Branch 17 taken 16883 times.
✓ Branch 18 taken 5408 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 16883 times.
✓ Branch 22 taken 30622 times.
✓ Branch 23 taken 37114 times.
✓ Branch 24 taken 14994 times.
✓ Branch 25 taken 22120 times.
93914 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 32678 int ff_set_common_all_color_spaces(AVFilterContext *ctx)
842 {
843 32678 return ff_set_common_color_spaces(ctx, ff_all_color_spaces());
844 }
845
846 37114 int ff_set_common_color_ranges(AVFilterContext *ctx,
847 AVFilterFormats *color_ranges)
848 {
849
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 37114 times.
✓ Branch 2 taken 26178 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22283 times.
✓ Branch 5 taken 3895 times.
✓ Branch 6 taken 16883 times.
✓ Branch 7 taken 5400 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16883 times.
✓ Branch 11 taken 26178 times.
✓ Branch 12 taken 37114 times.
✓ Branch 13 taken 30622 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 22291 times.
✓ Branch 16 taken 8331 times.
✓ Branch 17 taken 16883 times.
✓ Branch 18 taken 5408 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 16883 times.
✓ Branch 22 taken 30622 times.
✓ Branch 23 taken 37114 times.
✓ Branch 24 taken 14994 times.
✓ Branch 25 taken 22120 times.
93914 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 32678 int ff_set_common_all_color_ranges(AVFilterContext *ctx)
860 {
861 32678 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 48753 int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
870 {
871
15/20
✗ Branch 0 not taken.
✓ Branch 1 taken 48753 times.
✓ Branch 2 taken 35739 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20901 times.
✓ Branch 5 taken 14838 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20901 times.
✓ Branch 9 taken 35739 times.
✓ Branch 10 taken 48753 times.
✓ Branch 11 taken 42238 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 20927 times.
✓ Branch 14 taken 21311 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 20927 times.
✓ Branch 18 taken 42238 times.
✓ Branch 19 taken 48753 times.
✓ Branch 20 taken 21331 times.
✓ Branch 21 taken 27422 times.
126730 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 32710 int ff_default_query_formats(AVFilterContext *ctx)
881 {
882 32710 const AVFilter *const f = ctx->filter;
883 AVFilterFormats *formats;
884 enum AVMediaType type;
885 int ret;
886
887
5/5
✓ Branch 0 taken 333 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 32 times.
✓ Branch 3 taken 13 times.
✓ Branch 4 taken 32313 times.
32710 switch (f->formats_state) {
888 333 case FF_FILTER_FORMATS_PIXFMT_LIST:
889 333 type = AVMEDIA_TYPE_VIDEO;
890 333 formats = ff_make_format_list(f->formats.pixels_list);
891 333 break;
892 19 case FF_FILTER_FORMATS_SAMPLEFMTS_LIST:
893 19 type = AVMEDIA_TYPE_AUDIO;
894 19 formats = ff_make_format_list(f->formats.samples_list);
895 19 break;
896 32 case FF_FILTER_FORMATS_SINGLE_PIXFMT:
897 32 type = AVMEDIA_TYPE_VIDEO;
898 32 formats = ff_make_formats_list_singleton(f->formats.pix_fmt);
899 32 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 32313 default:
905 av_assert2(!"Unreachable");
906 /* Intended fallthrough */
907 case FF_FILTER_FORMATS_PASSTHROUGH:
908 case FF_FILTER_FORMATS_QUERY_FUNC:
909 32313 type = AVMEDIA_TYPE_UNKNOWN;
910
2/2
✓ Branch 0 taken 25771 times.
✓ Branch 1 taken 6542 times.
38855 formats = ff_all_formats(ctx->nb_inputs ? ctx->inputs [0]->type :
911
1/2
✓ Branch 0 taken 6542 times.
✗ Branch 1 not taken.
6542 ctx->nb_outputs ? ctx->outputs[0]->type :
912 AVMEDIA_TYPE_VIDEO);
913 32313 break;
914 }
915
916 32710 ret = ff_set_common_formats(ctx, formats);
917
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32710 times.
32710 if (ret < 0)
918 return ret;
919
2/2
✓ Branch 0 taken 32678 times.
✓ Branch 1 taken 32 times.
32710 if (type != AVMEDIA_TYPE_AUDIO) {
920 32678 ret = ff_set_common_all_color_spaces(ctx);
921
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32678 times.
32678 if (ret < 0)
922 return ret;
923 32678 ret = ff_set_common_all_color_ranges(ctx);
924
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32678 times.
32678 if (ret < 0)
925 return ret;
926 }
927
2/2
✓ Branch 0 taken 32345 times.
✓ Branch 1 taken 365 times.
32710 if (type != AVMEDIA_TYPE_VIDEO) {
928 32345 ret = ff_set_common_all_channel_counts(ctx);
929
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32345 times.
32345 if (ret < 0)
930 return ret;
931 32345 ret = ff_set_common_all_samplerates(ctx);
932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32345 times.
32345 if (ret < 0)
933 return ret;
934 }
935
936 32710 return 0;
937 }
938
939 /* internal functions for parsing audio format arguments */
940
941 10518 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
942 {
943 char *tail;
944 10518 int pix_fmt = av_get_pix_fmt(arg);
945
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10518 times.
10518 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 10518 *ret = pix_fmt;
953 10518 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 113049 static int check_list(void *log, const char *name, const AVFilterFormats *fmts)
992 {
993 unsigned i, j;
994
995
2/2
✓ Branch 0 taken 50364 times.
✓ Branch 1 taken 62685 times.
113049 if (!fmts)
996 50364 return 0;
997
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62685 times.
62685 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 2117065 times.
✓ Branch 1 taken 62685 times.
2179750 for (i = 0; i < fmts->nb_formats; i++) {
1002
2/2
✓ Branch 0 taken 187265828 times.
✓ Branch 1 taken 2117065 times.
189382893 for (j = i + 1; j < fmts->nb_formats; j++) {
1003
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 187265828 times.
187265828 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 62685 return 0;
1010 }
1011
1012 34159 int ff_formats_check_pixel_formats(void *log, const AVFilterFormats *fmts)
1013 {
1014 34159 return check_list(log, "pixel format", fmts);
1015 }
1016
1017 8488 int ff_formats_check_sample_formats(void *log, const AVFilterFormats *fmts)
1018 {
1019 8488 return check_list(log, "sample format", fmts);
1020 }
1021
1022 8488 int ff_formats_check_sample_rates(void *log, const AVFilterFormats *fmts)
1023 {
1024
4/4
✓ Branch 0 taken 7221 times.
✓ Branch 1 taken 1267 times.
✓ Branch 2 taken 5137 times.
✓ Branch 3 taken 2084 times.
8488 if (!fmts || !fmts->nb_formats)
1025 6404 return 0;
1026 2084 return check_list(log, "sample rate", fmts);
1027 }
1028
1029 34159 int ff_formats_check_color_spaces(void *log, const AVFilterFormats *fmts)
1030 {
1031
4/4
✓ Branch 0 taken 79004 times.
✓ Branch 1 taken 21933 times.
✓ Branch 2 taken 66778 times.
✓ Branch 3 taken 12226 times.
100937 for (int i = 0; fmts && i < fmts->nb_formats; i++) {
1032
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66778 times.
66778 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 34159 return check_list(log, "color space", fmts);
1038 }
1039
1040 34159 int ff_formats_check_color_ranges(void *log, const AVFilterFormats *fmts)
1041 {
1042 34159 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 8488 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 8488 times.
8488 if (!fmts)
1057 return 0;
1058
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8488 times.
8488 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 1566 times.
✓ Branch 1 taken 6922 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1566 times.
8488 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 2184 times.
✓ Branch 1 taken 8488 times.
10672 for (i = 0; i < fmts->nb_channel_layouts; i++) {
1067
2/2
✓ Branch 0 taken 3180 times.
✓ Branch 1 taken 2184 times.
5364 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 8488 return 0;
1075 }
1076