FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/formats.c
Date: 2022-11-26 13:19:19
Exec Total Coverage
Lines: 290 342 84.8%
Branches: 301 422 71.3%

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/pixdesc.h"
27 #include "avfilter.h"
28 #include "internal.h"
29 #include "formats.h"
30
31 /**
32 * Add all refs from a to ret and destroy a.
33 */
34 #define MERGE_REF(ret, a, fmts, type, fail_statement) \
35 do { \
36 type ***tmp; \
37 int i; \
38 \
39 if (!(tmp = av_realloc_array(ret->refs, ret->refcount + a->refcount, \
40 sizeof(*tmp)))) \
41 { fail_statement } \
42 ret->refs = tmp; \
43 \
44 for (i = 0; i < a->refcount; i ++) { \
45 ret->refs[ret->refcount] = a->refs[i]; \
46 *ret->refs[ret->refcount++] = ret; \
47 } \
48 \
49 av_freep(&a->refs); \
50 av_freep(&a->fmts); \
51 av_freep(&a); \
52 } while (0)
53
54 /**
55 * Add all formats common to a and b to a, add b's refs to a and destroy b.
56 * If check is set, nothing is modified and it is only checked whether
57 * the formats are compatible.
58 * If empty_allowed is set and one of a,b->nb is zero, the lists are
59 * merged; otherwise, 0 (for nonmergeability) is returned.
60 */
61 #define MERGE_FORMATS(a, b, fmts, nb, type, check, empty_allowed) \
62 do { \
63 int i, j, k = 0, skip = 0; \
64 \
65 if (empty_allowed) { \
66 if (!a->nb || !b->nb) { \
67 if (check) \
68 return 1; \
69 if (!a->nb) \
70 FFSWAP(type *, a, b); \
71 skip = 1; \
72 } \
73 } \
74 if (!skip) { \
75 for (i = 0; i < a->nb; i++) \
76 for (j = 0; j < b->nb; j++) \
77 if (a->fmts[i] == b->fmts[j]) { \
78 if (check) \
79 return 1; \
80 a->fmts[k++] = a->fmts[i]; \
81 break; \
82 } \
83 /* Check that there was at least one common format. \
84 * Notice that both a and b are unchanged if not. */ \
85 if (!k) \
86 return 0; \
87 av_assert2(!check); \
88 a->nb = k; \
89 } \
90 \
91 MERGE_REF(a, b, fmts, type, return AVERROR(ENOMEM);); \
92 } while (0)
93
94 30350 static int merge_formats_internal(AVFilterFormats *a, AVFilterFormats *b,
95 enum AVMediaType type, int check)
96 {
97 int i, j;
98 30350 int alpha1=0, alpha2=0;
99 30350 int chroma1=0, chroma2=0;
100
101 av_assert2(check || (a->refcount && b->refcount));
102
103
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30350 times.
30350 if (a == b)
104 return 1;
105
106 /* Do not lose chroma or alpha in merging.
107 It happens if both lists have formats with chroma (resp. alpha), but
108 the only formats in common do not have it (e.g. YUV+gray vs.
109 RGB+gray): in that case, the merging would select the gray format,
110 possibly causing a lossy conversion elsewhere in the graph.
111 To avoid that, pretend that there are no common formats to force the
112 insertion of a conversion filter. */
113
2/2
✓ Branch 0 taken 20548 times.
✓ Branch 1 taken 9802 times.
30350 if (type == AVMEDIA_TYPE_VIDEO)
114
2/2
✓ Branch 0 taken 710548 times.
✓ Branch 1 taken 20548 times.
731096 for (i = 0; i < a->nb_formats; i++) {
115 710548 const AVPixFmtDescriptor *const adesc = av_pix_fmt_desc_get(a->formats[i]);
116
2/2
✓ Branch 0 taken 11448555 times.
✓ Branch 1 taken 710548 times.
12159103 for (j = 0; j < b->nb_formats; j++) {
117 11448555 const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
118 11448555 alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA;
119
4/4
✓ Branch 0 taken 10301957 times.
✓ Branch 1 taken 1146598 times.
✓ Branch 2 taken 9024472 times.
✓ Branch 3 taken 1277485 times.
11448555 chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
120
2/2
✓ Branch 0 taken 57080 times.
✓ Branch 1 taken 11391475 times.
11448555 if (a->formats[i] == b->formats[j]) {
121 57080 alpha1 |= adesc->flags & AV_PIX_FMT_FLAG_ALPHA;
122 57080 chroma1|= adesc->nb_components > 1;
123 }
124 }
125 }
126
127 // If chroma or alpha can be lost through merging then do not merge
128
4/4
✓ Branch 0 taken 30329 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 501 times.
✓ Branch 3 taken 29828 times.
30350 if (alpha2 > alpha1 || chroma2 > chroma1)
129 522 return 0;
130
131
14/16
✓ Branch 0 taken 29828 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 67607 times.
✓ Branch 3 taken 5151574 times.
✓ Branch 4 taken 4300 times.
✓ Branch 5 taken 63307 times.
✓ Branch 6 taken 5219181 times.
✓ Branch 7 taken 669988 times.
✓ Branch 8 taken 737595 times.
✓ Branch 9 taken 25528 times.
✓ Branch 10 taken 417 times.
✓ Branch 11 taken 25111 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 25111 times.
✓ Branch 15 taken 44328 times.
✓ Branch 16 taken 25111 times.
5959025 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0);
132
133 25111 return 1;
134 }
135
136
137 /**
138 * Check the formats lists for compatibility for merging without actually
139 * merging.
140 *
141 * @return 1 if they are compatible, 0 if not.
142 */
143 static int can_merge_pix_fmts(const void *a, const void *b)
144 {
145 return merge_formats_internal((AVFilterFormats *)a,
146 (AVFilterFormats *)b, AVMEDIA_TYPE_VIDEO, 1);
147 }
148
149 /**
150 * Merge the formats lists if they are compatible and update all the
151 * references of a and b to point to the combined list and free the old
152 * lists as needed. The combined list usually contains the intersection of
153 * the lists of a and b.
154 *
155 * Both a and b must have owners (i.e. refcount > 0) for these functions.
156 *
157 * @return 1 if merging succeeded, 0 if a and b are incompatible
158 * and negative AVERROR code on failure.
159 * a and b are unmodified if 0 is returned.
160 */
161 20548 static int merge_pix_fmts(void *a, void *b)
162 {
163 20548 return merge_formats_internal(a, b, AVMEDIA_TYPE_VIDEO, 0);
164 }
165
166 /**
167 * See can_merge_pix_fmts().
168 */
169 4689 static int can_merge_sample_fmts(const void *a, const void *b)
170 {
171 4689 return merge_formats_internal((AVFilterFormats *)a,
172 (AVFilterFormats *)b, AVMEDIA_TYPE_AUDIO, 1);
173 }
174
175 /**
176 * See merge_pix_fmts().
177 */
178 5113 static int merge_sample_fmts(void *a, void *b)
179 {
180 5113 return merge_formats_internal(a, b, AVMEDIA_TYPE_AUDIO, 0);
181 }
182
183 9819 static int merge_samplerates_internal(AVFilterFormats *a,
184 AVFilterFormats *b, int check)
185 {
186 av_assert2(check || (a->refcount && b->refcount));
187
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9819 times.
9819 if (a == b) return 1;
188
189
23/24
✓ Branch 0 taken 6624 times.
✓ Branch 1 taken 3195 times.
✓ Branch 2 taken 6487 times.
✓ Branch 3 taken 137 times.
✓ Branch 4 taken 4616 times.
✓ Branch 5 taken 5066 times.
✓ Branch 6 taken 1801 times.
✓ Branch 7 taken 3265 times.
✓ Branch 8 taken 137 times.
✓ Branch 9 taken 5066 times.
✓ Branch 10 taken 120 times.
✓ Branch 11 taken 63 times.
✓ Branch 12 taken 73 times.
✓ Branch 13 taken 47 times.
✓ Branch 14 taken 183 times.
✓ Branch 15 taken 17 times.
✓ Branch 16 taken 137 times.
✓ Branch 17 taken 64 times.
✓ Branch 18 taken 17 times.
✓ Branch 19 taken 47 times.
✗ Branch 21 not taken.
✓ Branch 22 taken 5113 times.
✓ Branch 23 taken 9123 times.
✓ Branch 24 taken 5113 times.
19069 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 1);
190 5113 return 1;
191 }
192
193 /**
194 * See can_merge_pix_fmts().
195 */
196 4706 static int can_merge_samplerates(const void *a, const void *b)
197 {
198 4706 return merge_samplerates_internal((AVFilterFormats *)a, (AVFilterFormats *)b, 1);
199 }
200
201 /**
202 * See merge_pix_fmts().
203 */
204 5113 static int merge_samplerates(void *a, void *b)
205 {
206 5113 return merge_samplerates_internal(a, b, 0);
207 }
208
209 /**
210 * See merge_pix_fmts().
211 */
212 5114 static int merge_channel_layouts(void *va, void *vb)
213 {
214 5114 AVFilterChannelLayouts *a = va;
215 5114 AVFilterChannelLayouts *b = vb;
216 AVChannelLayout *channel_layouts;
217 5114 unsigned a_all = a->all_layouts + a->all_counts;
218 5114 unsigned b_all = b->all_layouts + b->all_counts;
219 5114 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 5114 times.
5114 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 2330 times.
✓ Branch 1 taken 2784 times.
5114 if (a_all < b_all) {
227 2330 FFSWAP(AVFilterChannelLayouts *, a, b);
228 2330 FFSWAP(unsigned, a_all, b_all);
229 }
230
2/2
✓ Branch 0 taken 5050 times.
✓ Branch 1 taken 64 times.
5114 if (a_all) {
231
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5047 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
5050 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 3 times.
✓ Branch 1 taken 3 times.
6 for (i = j = 0; i < b->nb_channel_layouts; i++)
234
2/6
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 3 times.
3 if (KNOWN(&b->channel_layouts[i]) && i != j++)
235 av_channel_layout_copy(&b->channel_layouts[j], &b->channel_layouts[i]);
236 /* Not optimal: the unknown layouts of b may become known after
237 another merge. */
238
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (!j)
239 return 0;
240 3 b->nb_channel_layouts = j;
241 }
242
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 5050 times.
✓ Branch 3 taken 8570 times.
✓ Branch 4 taken 5050 times.
13620 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, return AVERROR(ENOMEM););
243 5050 return 1;
244 }
245
246 64 ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
247
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 64 times.
64 if (!(channel_layouts = av_calloc(ret_max, sizeof(*channel_layouts))))
248 return AVERROR(ENOMEM);
249
250 /* a[known] intersect b[known] */
251
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 64 times.
128 for (i = 0; i < a->nb_channel_layouts; i++) {
252
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 64 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
64 if (!KNOWN(&a->channel_layouts[i]))
253 continue;
254
2/2
✓ Branch 0 taken 104 times.
✓ Branch 1 taken 1 times.
105 for (j = 0; j < b->nb_channel_layouts; j++) {
255
2/2
✓ Branch 1 taken 63 times.
✓ Branch 2 taken 41 times.
104 if (!av_channel_layout_compare(&a->channel_layouts[i], &b->channel_layouts[j])) {
256 63 av_channel_layout_copy(&channel_layouts[ret_nb++], &a->channel_layouts[i]);
257 63 av_channel_layout_uninit(&a->channel_layouts[i]);
258 63 av_channel_layout_uninit(&b->channel_layouts[j]);
259 63 break;
260 }
261 }
262 }
263 /* 1st round: a[known] intersect b[generic]
264 2nd round: a[generic] intersect b[known] */
265
2/2
✓ Branch 0 taken 128 times.
✓ Branch 1 taken 64 times.
192 for (round = 0; round < 2; round++) {
266
2/2
✓ Branch 0 taken 214 times.
✓ Branch 1 taken 128 times.
342 for (i = 0; i < a->nb_channel_layouts; i++) {
267 214 AVChannelLayout *fmt = &a->channel_layouts[i], bfmt = { 0 };
268
3/6
✓ Branch 1 taken 88 times.
✓ Branch 2 taken 126 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 88 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
214 if (!av_channel_layout_check(fmt) || !KNOWN(fmt))
269 126 continue;
270 88 bfmt = FF_COUNT2LAYOUT(fmt->nb_channels);
271
2/2
✓ Branch 0 taken 88 times.
✓ Branch 1 taken 88 times.
176 for (j = 0; j < b->nb_channel_layouts; j++)
272
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 88 times.
88 if (!av_channel_layout_compare(&b->channel_layouts[j], &bfmt))
273 av_channel_layout_copy(&channel_layouts[ret_nb++], fmt);
274 }
275 /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
276 128 FFSWAP(AVFilterChannelLayouts *, a, b);
277 }
278 /* a[generic] intersect b[generic] */
279
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 64 times.
128 for (i = 0; i < a->nb_channel_layouts; i++) {
280
3/4
✓ Branch 0 taken 63 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 63 times.
✗ Branch 3 not taken.
64 if (KNOWN(&a->channel_layouts[i]))
281 64 continue;
282 for (j = 0; j < b->nb_channel_layouts; j++)
283 if (!av_channel_layout_compare(&a->channel_layouts[i], &b->channel_layouts[j]))
284 av_channel_layout_copy(&channel_layouts[ret_nb++], &a->channel_layouts[i]);
285 }
286
287
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 63 times.
64 if (!ret_nb) {
288 1 av_free(channel_layouts);
289 1 return 0;
290 }
291
292
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 51 times.
63 if (a->refcount > b->refcount)
293 12 FFSWAP(AVFilterChannelLayouts *, a, b);
294
295
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,
296 { av_free(channel_layouts); return AVERROR(ENOMEM); });
297 63 av_freep(&b->channel_layouts);
298 63 b->channel_layouts = channel_layouts;
299 63 b->nb_channel_layouts = ret_nb;
300 63 return 1;
301 }
302
303 static const AVFilterFormatsMerger mergers_video[] = {
304 {
305 .offset = offsetof(AVFilterFormatsConfig, formats),
306 .merge = merge_pix_fmts,
307 .can_merge = can_merge_pix_fmts,
308 },
309 };
310
311 static const AVFilterFormatsMerger mergers_audio[] = {
312 {
313 .offset = offsetof(AVFilterFormatsConfig, channel_layouts),
314 .merge = merge_channel_layouts,
315 .can_merge = NULL,
316 },
317 {
318 .offset = offsetof(AVFilterFormatsConfig, samplerates),
319 .merge = merge_samplerates,
320 .can_merge = can_merge_samplerates,
321 },
322 {
323 .offset = offsetof(AVFilterFormatsConfig, formats),
324 .merge = merge_sample_fmts,
325 .can_merge = can_merge_sample_fmts,
326 },
327 };
328
329 static const AVFilterNegotiation negotiate_video = {
330 .nb_mergers = FF_ARRAY_ELEMS(mergers_video),
331 .mergers = mergers_video,
332 .conversion_filter = "scale",
333 .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts),
334 };
335
336 static const AVFilterNegotiation negotiate_audio = {
337 .nb_mergers = FF_ARRAY_ELEMS(mergers_audio),
338 .mergers = mergers_audio,
339 .conversion_filter = "aresample",
340 .conversion_opts_offset = offsetof(AVFilterGraph, aresample_swr_opts),
341 };
342
343 25161 const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link)
344 {
345
2/3
✓ Branch 0 taken 20044 times.
✓ Branch 1 taken 5117 times.
✗ Branch 2 not taken.
25161 switch (link->type) {
346 20044 case AVMEDIA_TYPE_VIDEO: return &negotiate_video;
347 5117 case AVMEDIA_TYPE_AUDIO: return &negotiate_audio;
348 default: return NULL;
349 }
350 }
351
352 152 int ff_fmt_is_in(int fmt, const int *fmts)
353 {
354 const int *p;
355
356
2/2
✓ Branch 0 taken 1986 times.
✓ Branch 1 taken 66 times.
2052 for (p = fmts; *p != -1; p++) {
357
2/2
✓ Branch 0 taken 86 times.
✓ Branch 1 taken 1900 times.
1986 if (fmt == *p)
358 86 return 1;
359 }
360 66 return 0;
361 }
362
363 #define MAKE_FORMAT_LIST(type, field, count_field) \
364 type *formats; \
365 int count = 0; \
366 if (fmts) \
367 for (count = 0; fmts[count] != -1; count++) \
368 ; \
369 formats = av_mallocz(sizeof(*formats)); \
370 if (!formats) \
371 return NULL; \
372 formats->count_field = count; \
373 if (count) { \
374 formats->field = av_malloc_array(count, sizeof(*formats->field)); \
375 if (!formats->field) { \
376 av_freep(&formats); \
377 return NULL; \
378 } \
379 }
380
381 7643 AVFilterFormats *ff_make_format_list(const int *fmts)
382 {
383
6/10
✓ Branch 0 taken 7643 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 21593 times.
✓ Branch 3 taken 7643 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 7643 times.
✓ Branch 7 taken 7643 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 7643 times.
29236 MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
384
2/2
✓ Branch 0 taken 21593 times.
✓ Branch 1 taken 7643 times.
29236 while (count--)
385 21593 formats->formats[count] = fmts[count];
386
387 7643 return formats;
388 }
389
390 30 AVFilterChannelLayouts *ff_make_channel_layout_list(const AVChannelLayout *fmts)
391 {
392 AVFilterChannelLayouts *ch_layouts;
393 30 int count = 0;
394
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (fmts)
395
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 30 times.
60 for (count = 0; fmts[count].nb_channels; count++)
396 ;
397 30 ch_layouts = av_mallocz(sizeof(*ch_layouts));
398
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (!ch_layouts)
399 return NULL;
400 30 ch_layouts->nb_channel_layouts = count;
401
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (count) {
402 60 ch_layouts->channel_layouts =
403 30 av_calloc(count, sizeof(*ch_layouts->channel_layouts));
404
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (!ch_layouts->channel_layouts) {
405 av_freep(&ch_layouts);
406 return NULL;
407 }
408
2/2
✓ Branch 0 taken 30 times.
✓ Branch 1 taken 30 times.
60 for (int i = 0; i < count; i++) {
409 30 int ret = av_channel_layout_copy(&ch_layouts->channel_layouts[i], &fmts[i]);
410
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30 times.
30 if (ret < 0)
411 goto fail;
412 }
413 }
414
415 30 return ch_layouts;
416
417 fail:
418 for (int i = 0; i < count; i++)
419 av_channel_layout_uninit(&ch_layouts->channel_layouts[i]);
420 av_free(ch_layouts->channel_layouts);
421 av_freep(&ch_layouts);
422
423 return NULL;
424 }
425
426 #define ADD_FORMAT(f, fmt, unref_fn, type, list, nb) \
427 do { \
428 type *fmts; \
429 \
430 if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) { \
431 return AVERROR(ENOMEM); \
432 } \
433 \
434 fmts = av_realloc_array((*f)->list, (*f)->nb + 1, \
435 sizeof(*(*f)->list)); \
436 if (!fmts) { \
437 unref_fn(f); \
438 return AVERROR(ENOMEM); \
439 } \
440 \
441 (*f)->list = fmts; \
442 ASSIGN_FMT(f, fmt, list, nb); \
443 } while (0)
444
445 #define ASSIGN_FMT(f, fmt, list, nb) \
446 do { \
447 (*f)->list[(*f)->nb++] = fmt; \
448 } while (0)
449
450 1593588 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
451 {
452
4/6
✓ Branch 0 taken 25877 times.
✓ Branch 1 taken 1567711 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 25877 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1593588 times.
1593588 ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
453 1593588 return 0;
454 }
455
456 #undef ASSIGN_FMT
457 #define ASSIGN_FMT(f, fmt, list, nb) \
458 do { \
459 int ret; \
460 memset((*f)->list + (*f)->nb, 0, sizeof(*(*f)->list)); \
461 ret = av_channel_layout_copy(&(*f)->list[(*f)->nb], fmt); \
462 if (ret < 0) \
463 return ret; \
464 (*f)->nb++; \
465 } while (0)
466
467 2821 int ff_add_channel_layout(AVFilterChannelLayouts **l,
468 const AVChannelLayout *channel_layout)
469 {
470 av_assert1(!(*l && (*l)->all_layouts));
471
5/8
✓ Branch 0 taken 1335 times.
✓ Branch 1 taken 1486 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1335 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2821 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2821 times.
2821 ADD_FORMAT(l, channel_layout, ff_channel_layouts_unref, AVChannelLayout, channel_layouts, nb_channel_layouts);
472 2821 return 0;
473 }
474
475 43 AVFilterFormats *ff_make_formats_list_singleton(int fmt)
476 {
477 43 int fmts[2] = { fmt, -1 };
478 43 return ff_make_format_list(fmts);
479 }
480
481 38549 AVFilterFormats *ff_all_formats(enum AVMediaType type)
482 {
483 38549 AVFilterFormats *ret = NULL;
484
485
2/2
✓ Branch 0 taken 29758 times.
✓ Branch 1 taken 8791 times.
38549 if (type == AVMEDIA_TYPE_VIDEO) {
486 29758 return ff_formats_pixdesc_filter(0, 0);
487
1/2
✓ Branch 0 taken 8791 times.
✗ Branch 1 not taken.
8791 } else if (type == AVMEDIA_TYPE_AUDIO) {
488 8791 enum AVSampleFormat fmt = 0;
489
2/2
✓ Branch 1 taken 105492 times.
✓ Branch 2 taken 8791 times.
114283 while (av_get_sample_fmt_name(fmt)) {
490
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 105492 times.
105492 if (ff_add_format(&ret, fmt) < 0)
491 return NULL;
492 105492 fmt++;
493 }
494 }
495
496 8791 return ret;
497 }
498
499 30318 AVFilterFormats *ff_formats_pixdesc_filter(unsigned want, unsigned rej)
500 {
501 unsigned nb_formats, fmt, flags;
502 30318 AVFilterFormats *formats = NULL;
503
504 while (1) {
505 60636 nb_formats = 0;
506 13521828 for (fmt = 0;; fmt++) {
507 13521828 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
508
2/2
✓ Branch 0 taken 60636 times.
✓ Branch 1 taken 13461192 times.
13521828 if (!desc)
509 60636 break;
510 13461192 flags = desc->flags;
511
2/2
✓ Branch 0 taken 12612288 times.
✓ Branch 1 taken 848904 times.
13461192 if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
512
2/2
✓ Branch 0 taken 5760420 times.
✓ Branch 1 taken 6851868 times.
12612288 !(desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
513
3/4
✓ Branch 0 taken 5275332 times.
✓ Branch 1 taken 485088 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5275332 times.
5760420 (desc->log2_chroma_w || desc->log2_chroma_h))
514 485088 flags |= FF_PIX_FMT_FLAG_SW_FLAT_SUB;
515
2/2
✓ Branch 0 taken 15956 times.
✓ Branch 1 taken 13445236 times.
13461192 if ((flags & (want | rej)) != want)
516 15956 continue;
517
2/2
✓ Branch 0 taken 6722618 times.
✓ Branch 1 taken 6722618 times.
13445236 if (formats)
518 6722618 formats->formats[nb_formats] = fmt;
519 13445236 nb_formats++;
520 }
521
2/2
✓ Branch 0 taken 30318 times.
✓ Branch 1 taken 30318 times.
60636 if (formats) {
522
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30318 times.
30318 av_assert0(formats->nb_formats == nb_formats);
523 30318 return formats;
524 }
525 30318 formats = av_mallocz(sizeof(*formats));
526
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30318 times.
30318 if (!formats)
527 return NULL;
528 30318 formats->nb_formats = nb_formats;
529
1/2
✓ Branch 0 taken 30318 times.
✗ Branch 1 not taken.
30318 if (nb_formats) {
530 30318 formats->formats = av_malloc_array(nb_formats, sizeof(*formats->formats));
531
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 30318 times.
30318 if (!formats->formats) {
532 av_freep(&formats);
533 return NULL;
534 }
535 }
536 }
537 }
538
539 6 AVFilterFormats *ff_planar_sample_fmts(void)
540 {
541 6 AVFilterFormats *ret = NULL;
542 int fmt;
543
544
2/2
✓ Branch 1 taken 72 times.
✓ Branch 2 taken 6 times.
78 for (fmt = 0; av_get_bytes_per_sample(fmt)>0; fmt++)
545
2/2
✓ Branch 1 taken 36 times.
✓ Branch 2 taken 36 times.
72 if (av_sample_fmt_is_planar(fmt))
546
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 36 times.
36 if (ff_add_format(&ret, fmt) < 0)
547 return NULL;
548
549 6 return ret;
550 }
551
552 9629 AVFilterFormats *ff_all_samplerates(void)
553 {
554 9629 AVFilterFormats *ret = av_mallocz(sizeof(*ret));
555 9629 return ret;
556 }
557
558 5221 AVFilterChannelLayouts *ff_all_channel_layouts(void)
559 {
560 5221 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
561
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5221 times.
5221 if (!ret)
562 return NULL;
563 5221 ret->all_layouts = 1;
564 5221 return ret;
565 }
566
567 6221 AVFilterChannelLayouts *ff_all_channel_counts(void)
568 {
569 6221 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6221 times.
6221 if (!ret)
571 return NULL;
572 6221 ret->all_layouts = ret->all_counts = 1;
573 6221 return ret;
574 }
575
576 #define FORMATS_REF(f, ref, unref_fn) \
577 void *tmp; \
578 \
579 if (!f) \
580 return AVERROR(ENOMEM); \
581 \
582 tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1); \
583 if (!tmp) { \
584 unref_fn(&f); \
585 return AVERROR(ENOMEM); \
586 } \
587 f->refs = tmp; \
588 f->refs[f->refcount++] = ref; \
589 *ref = f; \
590 return 0
591
592 10226 int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
593 {
594
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10226 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10226 times.
10226 FORMATS_REF(f, ref, ff_channel_layouts_unref);
595 }
596
597 60584 int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
598 {
599
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 60584 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 60584 times.
60584 FORMATS_REF(f, ref, ff_formats_unref);
600 }
601
602 #define FIND_REF_INDEX(ref, idx) \
603 do { \
604 int i; \
605 for (i = 0; i < (*ref)->refcount; i ++) \
606 if((*ref)->refs[i] == ref) { \
607 idx = i; \
608 break; \
609 } \
610 } while (0)
611
612 #define FORMATS_UNREF(ref, list) \
613 do { \
614 int idx = -1; \
615 \
616 if (!*ref) \
617 return; \
618 \
619 FIND_REF_INDEX(ref, idx); \
620 \
621 if (idx >= 0) { \
622 memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
623 sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
624 --(*ref)->refcount; \
625 } \
626 if (!(*ref)->refcount) { \
627 FREE_LIST(ref, list); \
628 av_free((*ref)->list); \
629 av_free((*ref)->refs); \
630 av_free(*ref); \
631 } \
632 *ref = NULL; \
633 } while (0)
634
635 #define FREE_LIST(ref, list) do { } while(0)
636 234525 void ff_formats_unref(AVFilterFormats **ref)
637 {
638
10/10
✓ Branch 0 taken 144476 times.
✓ Branch 1 taken 90049 times.
✓ Branch 2 taken 60584 times.
✓ Branch 3 taken 9324 times.
✓ Branch 4 taken 69908 times.
✓ Branch 5 taken 29465 times.
✓ Branch 6 taken 60584 times.
✓ Branch 7 taken 29465 times.
✓ Branch 8 taken 43243 times.
✓ Branch 9 taken 46806 times.
243849 FORMATS_UNREF(ref, formats);
639 }
640
641 #undef FREE_LIST
642 #define FREE_LIST(ref, list) \
643 do { \
644 for (int i = 0; i < (*ref)->nb_channel_layouts; i++) \
645 av_channel_layout_uninit(&(*ref)->list[i]); \
646 } while(0)
647
648 107745 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
649 {
650
12/12
✓ Branch 0 taken 92304 times.
✓ Branch 1 taken 15441 times.
✓ Branch 2 taken 10226 times.
✓ Branch 3 taken 6662 times.
✓ Branch 4 taken 16888 times.
✓ Branch 5 taken 5215 times.
✓ Branch 6 taken 10226 times.
✓ Branch 7 taken 5215 times.
✓ Branch 8 taken 7694 times.
✓ Branch 9 taken 7747 times.
✓ Branch 11 taken 2479 times.
✓ Branch 12 taken 7694 times.
116886 FORMATS_UNREF(ref, channel_layouts);
651 }
652
653 #define FORMATS_CHANGEREF(oldref, newref) \
654 do { \
655 int idx = -1; \
656 \
657 FIND_REF_INDEX(oldref, idx); \
658 \
659 if (idx >= 0) { \
660 (*oldref)->refs[idx] = newref; \
661 *newref = *oldref; \
662 *oldref = NULL; \
663 } \
664 } while (0)
665
666 407 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
667 AVFilterChannelLayouts **newref)
668 {
669
4/6
✓ Branch 0 taken 407 times.
✓ Branch 1 taken 337 times.
✓ Branch 2 taken 744 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 407 times.
✗ Branch 5 not taken.
744 FORMATS_CHANGEREF(oldref, newref);
670 407 }
671
672 1364 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
673 {
674
4/6
✓ Branch 0 taken 1364 times.
✓ Branch 1 taken 377 times.
✓ Branch 2 taken 1741 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1364 times.
✗ Branch 5 not taken.
1741 FORMATS_CHANGEREF(oldref, newref);
675 1364 }
676
677 #define SET_COMMON_FORMATS(ctx, fmts, media_type, ref_fn, unref_fn) \
678 int i; \
679 \
680 if (!fmts) \
681 return AVERROR(ENOMEM); \
682 \
683 for (i = 0; i < ctx->nb_inputs; i++) { \
684 AVFilterLink *const link = ctx->inputs[i]; \
685 if (link && !link->outcfg.fmts && \
686 (media_type == AVMEDIA_TYPE_UNKNOWN || link->type == media_type)) { \
687 int ret = ref_fn(fmts, &ctx->inputs[i]->outcfg.fmts); \
688 if (ret < 0) { \
689 return ret; \
690 } \
691 } \
692 } \
693 for (i = 0; i < ctx->nb_outputs; i++) { \
694 AVFilterLink *const link = ctx->outputs[i]; \
695 if (link && !link->incfg.fmts && \
696 (media_type == AVMEDIA_TYPE_UNKNOWN || link->type == media_type)) { \
697 int ret = ref_fn(fmts, &ctx->outputs[i]->incfg.fmts); \
698 if (ret < 0) { \
699 return ret; \
700 } \
701 } \
702 } \
703 \
704 if (!fmts->refcount) \
705 unref_fn(&fmts); \
706 \
707 return 0;
708
709 10247 int ff_set_common_channel_layouts(AVFilterContext *ctx,
710 AVFilterChannelLayouts *channel_layouts)
711 {
712
17/24
✗ Branch 0 not taken.
✓ Branch 1 taken 10247 times.
✓ Branch 2 taken 7828 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3827 times.
✓ Branch 5 taken 4001 times.
✓ Branch 6 taken 3827 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 3827 times.
✓ Branch 11 taken 7828 times.
✓ Branch 12 taken 10247 times.
✓ Branch 13 taken 7842 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 3829 times.
✓ Branch 16 taken 4013 times.
✓ Branch 17 taken 3829 times.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 3829 times.
✓ Branch 22 taken 7842 times.
✓ Branch 23 taken 10247 times.
✓ Branch 24 taken 5215 times.
✓ Branch 25 taken 5032 times.
25917 SET_COMMON_FORMATS(ctx, channel_layouts, AVMEDIA_TYPE_AUDIO,
713 ff_channel_layouts_ref, ff_channel_layouts_unref);
714 }
715
716 27 int ff_set_common_channel_layouts_from_list(AVFilterContext *ctx,
717 const AVChannelLayout *fmts)
718 {
719 27 return ff_set_common_channel_layouts(ctx, ff_make_channel_layout_list(fmts));
720 }
721
722 1099 int ff_set_common_all_channel_counts(AVFilterContext *ctx)
723 {
724 1099 return ff_set_common_channel_layouts(ctx, ff_all_channel_counts());
725 }
726
727 9076 int ff_set_common_samplerates(AVFilterContext *ctx,
728 AVFilterFormats *samplerates)
729 {
730
17/24
✗ Branch 0 not taken.
✓ Branch 1 taken 9076 times.
✓ Branch 2 taken 6659 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 3861 times.
✓ Branch 5 taken 2798 times.
✓ Branch 6 taken 3861 times.
✗ Branch 7 not taken.
✗ Branch 9 not taken.
✓ Branch 10 taken 3861 times.
✓ Branch 11 taken 6659 times.
✓ Branch 12 taken 9076 times.
✓ Branch 13 taken 7875 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 3861 times.
✓ Branch 16 taken 4014 times.
✓ Branch 17 taken 3861 times.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 3861 times.
✓ Branch 22 taken 7875 times.
✓ Branch 23 taken 9076 times.
✓ Branch 24 taken 4012 times.
✓ Branch 25 taken 5064 times.
23610 SET_COMMON_FORMATS(ctx, samplerates, AVMEDIA_TYPE_AUDIO,
731 ff_formats_ref, ff_formats_unref);
732 }
733
734 45 int ff_set_common_samplerates_from_list(AVFilterContext *ctx,
735 const int *samplerates)
736 {
737 45 return ff_set_common_samplerates(ctx, ff_make_format_list(samplerates));
738 }
739
740 6349 int ff_set_common_all_samplerates(AVFilterContext *ctx)
741 {
742 6349 return ff_set_common_samplerates(ctx, ff_all_samplerates());
743 }
744
745 /**
746 * A helper for query_formats() which sets all links to the same list of
747 * formats. If there are no links hooked to this filter, the list of formats is
748 * freed.
749 */
750 51836 int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
751 {
752
15/20
✗ Branch 0 not taken.
✓ Branch 1 taken 51836 times.
✓ Branch 2 taken 39329 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20114 times.
✓ Branch 5 taken 19215 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20114 times.
✓ Branch 9 taken 39329 times.
✓ Branch 10 taken 51836 times.
✓ Branch 11 taken 40516 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 20139 times.
✓ Branch 14 taken 20377 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 20139 times.
✓ Branch 18 taken 40516 times.
✓ Branch 19 taken 51836 times.
✓ Branch 20 taken 25453 times.
✓ Branch 21 taken 26383 times.
131681 SET_COMMON_FORMATS(ctx, formats, AVMEDIA_TYPE_UNKNOWN,
753 ff_formats_ref, ff_formats_unref);
754 }
755
756 6424 int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
757 {
758 6424 return ff_set_common_formats(ctx, ff_make_format_list(fmts));
759 }
760
761 9789 int ff_default_query_formats(AVFilterContext *ctx)
762 {
763 9789 const AVFilter *const f = ctx->filter;
764 AVFilterFormats *formats;
765 enum AVMediaType type;
766 int ret;
767
768
5/5
✓ Branch 0 taken 326 times.
✓ Branch 1 taken 19 times.
✓ Branch 2 taken 30 times.
✓ Branch 3 taken 13 times.
✓ Branch 4 taken 9401 times.
9789 switch (f->formats_state) {
769 326 case FF_FILTER_FORMATS_PIXFMT_LIST:
770 326 type = AVMEDIA_TYPE_VIDEO;
771 326 formats = ff_make_format_list(f->formats.pixels_list);
772 326 break;
773 19 case FF_FILTER_FORMATS_SAMPLEFMTS_LIST:
774 19 type = AVMEDIA_TYPE_AUDIO;
775 19 formats = ff_make_format_list(f->formats.samples_list);
776 19 break;
777 30 case FF_FILTER_FORMATS_SINGLE_PIXFMT:
778 30 type = AVMEDIA_TYPE_VIDEO;
779 30 formats = ff_make_formats_list_singleton(f->formats.pix_fmt);
780 30 break;
781 13 case FF_FILTER_FORMATS_SINGLE_SAMPLEFMT:
782 13 type = AVMEDIA_TYPE_AUDIO;
783 13 formats = ff_make_formats_list_singleton(f->formats.sample_fmt);
784 13 break;
785 9401 default:
786 av_assert2(!"Unreachable");
787 /* Intended fallthrough */
788 case FF_FILTER_FORMATS_PASSTHROUGH:
789 case FF_FILTER_FORMATS_QUERY_FUNC:
790
1/2
✓ Branch 0 taken 9401 times.
✗ Branch 1 not taken.
9401 type = ctx->nb_inputs ? ctx->inputs [0]->type :
791 ctx->nb_outputs ? ctx->outputs[0]->type : AVMEDIA_TYPE_VIDEO;
792 9401 formats = ff_all_formats(type);
793 9401 break;
794 }
795
796 9789 ret = ff_set_common_formats(ctx, formats);
797
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9789 times.
9789 if (ret < 0)
798 return ret;
799
2/2
✓ Branch 0 taken 1097 times.
✓ Branch 1 taken 8692 times.
9789 if (type == AVMEDIA_TYPE_AUDIO) {
800 1097 ret = ff_set_common_all_channel_counts(ctx);
801
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1097 times.
1097 if (ret < 0)
802 return ret;
803 1097 ret = ff_set_common_all_samplerates(ctx);
804
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1097 times.
1097 if (ret < 0)
805 return ret;
806 }
807
808 9789 return 0;
809 }
810
811 /* internal functions for parsing audio format arguments */
812
813 7768 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
814 {
815 char *tail;
816 7768 int pix_fmt = av_get_pix_fmt(arg);
817
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7768 times.
7768 if (pix_fmt == AV_PIX_FMT_NONE) {
818 pix_fmt = strtol(arg, &tail, 0);
819 if (*tail || !av_pix_fmt_desc_get(pix_fmt)) {
820 av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
821 return AVERROR(EINVAL);
822 }
823 }
824 7768 *ret = pix_fmt;
825 7768 return 0;
826 }
827
828 15 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
829 {
830 char *tail;
831 15 double srate = av_strtod(arg, &tail);
832
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) {
833 av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
834 return AVERROR(EINVAL);
835 }
836 15 *ret = srate;
837 15 return 0;
838 }
839
840 52 int ff_parse_channel_layout(AVChannelLayout *ret, int *nret, const char *arg,
841 void *log_ctx)
842 {
843 52 AVChannelLayout chlayout = { 0 };
844 int res;
845
846 52 res = av_channel_layout_from_string(&chlayout, arg);
847
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 44 times.
52 if (res < 0) {
848 #if FF_API_OLD_CHANNEL_LAYOUT
849 int64_t mask;
850 int nb_channels;
851 FF_DISABLE_DEPRECATION_WARNINGS
852
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 3 times.
8 if (av_get_extended_channel_layout(arg, &mask, &nb_channels) < 0) {
853 #endif
854 5 av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
855 5 return AVERROR(EINVAL);
856 #if FF_API_OLD_CHANNEL_LAYOUT
857 }
858 FF_ENABLE_DEPRECATION_WARNINGS
859 3 av_log(log_ctx, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
860 arg);
861
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (mask)
862 3 av_channel_layout_from_mask(&chlayout, mask);
863 else
864 chlayout = (AVChannelLayout) { .order = AV_CHANNEL_ORDER_UNSPEC, .nb_channels = nb_channels };
865 #endif
866 }
867
868
3/4
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 39 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 8 times.
47 if (chlayout.order == AV_CHANNEL_ORDER_UNSPEC && !nret) {
869 av_log(log_ctx, AV_LOG_ERROR, "Unknown channel layout '%s' is not supported.\n", arg);
870 return AVERROR(EINVAL);
871 }
872 47 *ret = chlayout;
873
1/2
✓ Branch 0 taken 47 times.
✗ Branch 1 not taken.
47 if (nret)
874 47 *nret = chlayout.nb_channels;
875
876 47 return 0;
877 }
878
879 42813 static int check_list(void *log, const char *name, const AVFilterFormats *fmts)
880 {
881 unsigned i, j;
882
883
2/2
✓ Branch 0 taken 1184 times.
✓ Branch 1 taken 41629 times.
42813 if (!fmts)
884 1184 return 0;
885
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 41629 times.
41629 if (!fmts->nb_formats) {
886 av_log(log, AV_LOG_ERROR, "Empty %s list\n", name);
887 return AVERROR(EINVAL);
888 }
889
2/2
✓ Branch 0 taken 2978623 times.
✓ Branch 1 taken 41629 times.
3020252 for (i = 0; i < fmts->nb_formats; i++) {
890
2/2
✓ Branch 0 taken 290305331 times.
✓ Branch 1 taken 2978623 times.
293283954 for (j = i + 1; j < fmts->nb_formats; j++) {
891
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 290305331 times.
290305331 if (fmts->formats[i] == fmts->formats[j]) {
892 av_log(log, AV_LOG_ERROR, "Duplicated %s\n", name);
893 return AVERROR(EINVAL);
894 }
895 }
896 }
897 41629 return 0;
898 }
899
900 32752 int ff_formats_check_pixel_formats(void *log, const AVFilterFormats *fmts)
901 {
902 32752 return check_list(log, "pixel format", fmts);
903 }
904
905 8024 int ff_formats_check_sample_formats(void *log, const AVFilterFormats *fmts)
906 {
907 8024 return check_list(log, "sample format", fmts);
908 }
909
910 8024 int ff_formats_check_sample_rates(void *log, const AVFilterFormats *fmts)
911 {
912
4/4
✓ Branch 0 taken 6820 times.
✓ Branch 1 taken 1204 times.
✓ Branch 2 taken 4783 times.
✓ Branch 3 taken 2037 times.
8024 if (!fmts || !fmts->nb_formats)
913 5987 return 0;
914 2037 return check_list(log, "sample rate", fmts);
915 }
916
917 3180 static int layouts_compatible(const AVChannelLayout *a, const AVChannelLayout *b)
918 {
919 3180 return !av_channel_layout_compare(a, b) ||
920
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) ||
921
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);
922 }
923
924 8024 int ff_formats_check_channel_layouts(void *log, const AVFilterChannelLayouts *fmts)
925 {
926 unsigned i, j;
927
928
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8022 times.
8024 if (!fmts)
929 2 return 0;
930
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8022 times.
8022 if (fmts->all_layouts < fmts->all_counts) {
931 av_log(log, AV_LOG_ERROR, "Inconsistent generic list\n");
932 return AVERROR(EINVAL);
933 }
934
3/4
✓ Branch 0 taken 1478 times.
✓ Branch 1 taken 6544 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1478 times.
8022 if (!fmts->all_layouts && !fmts->nb_channel_layouts) {
935 av_log(log, AV_LOG_ERROR, "Empty channel layout list\n");
936 return AVERROR(EINVAL);
937 }
938
2/2
✓ Branch 0 taken 2096 times.
✓ Branch 1 taken 8022 times.
10118 for (i = 0; i < fmts->nb_channel_layouts; i++) {
939
2/2
✓ Branch 0 taken 3180 times.
✓ Branch 1 taken 2096 times.
5276 for (j = i + 1; j < fmts->nb_channel_layouts; j++) {
940
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3180 times.
3180 if (layouts_compatible(&fmts->channel_layouts[i], &fmts->channel_layouts[j])) {
941 av_log(log, AV_LOG_ERROR, "Duplicated or redundant channel layout\n");
942 return AVERROR(EINVAL);
943 }
944 }
945 }
946 8022 return 0;
947 }
948