FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/formats.c
Date: 2024-03-28 14:59:00
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/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 51307 static int merge_formats_internal(AVFilterFormats *a, AVFilterFormats *b,
95 enum AVMediaType type, int check)
96 {
97 int i, j;
98 51307 int alpha1=0, alpha2=0;
99 51307 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 51307 times.
51307 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 40908 times.
✓ Branch 1 taken 10399 times.
51307 if (type == AVMEDIA_TYPE_VIDEO)
114
2/2
✓ Branch 0 taken 1418938 times.
✓ Branch 1 taken 40908 times.
1459846 for (i = 0; i < a->nb_formats; i++) {
115 1418938 const AVPixFmtDescriptor *const adesc = av_pix_fmt_desc_get(a->formats[i]);
116
2/2
✓ Branch 0 taken 25405989 times.
✓ Branch 1 taken 1418938 times.
26824927 for (j = 0; j < b->nb_formats; j++) {
117 25405989 const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
118 25405989 alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA;
119
4/4
✓ Branch 0 taken 22890985 times.
✓ Branch 1 taken 2515004 times.
✓ Branch 2 taken 20105628 times.
✓ Branch 3 taken 2785357 times.
25405989 chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
120
2/2
✓ Branch 0 taken 122483 times.
✓ Branch 1 taken 25283506 times.
25405989 if (a->formats[i] == b->formats[j]) {
121 122483 alpha1 |= adesc->flags & AV_PIX_FMT_FLAG_ALPHA;
122 122483 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 51286 times.
✓ Branch 1 taken 21 times.
✓ Branch 2 taken 528 times.
✓ Branch 3 taken 50758 times.
51307 if (alpha2 > alpha1 || chroma2 > chroma1)
129 549 return 0;
130
131
14/16
✓ Branch 0 taken 50758 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 93723 times.
✓ Branch 3 taken 6624636 times.
✓ Branch 4 taken 24072 times.
✓ Branch 5 taken 69651 times.
✓ Branch 6 taken 6718359 times.
✓ Branch 7 taken 962569 times.
✓ Branch 8 taken 1056292 times.
✓ Branch 9 taken 26686 times.
✓ Branch 10 taken 498 times.
✓ Branch 11 taken 26188 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 26188 times.
✓ Branch 15 taken 52772 times.
✓ Branch 16 taken 26188 times.
7760386 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0);
132
133 26188 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 20157 static int can_merge_pix_fmts(const void *a, const void *b)
144 {
145 20157 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 20751 static int merge_pix_fmts(void *a, void *b)
162 {
163 20751 return merge_formats_internal(a, b, AVMEDIA_TYPE_VIDEO, 0);
164 }
165
166 /**
167 * See can_merge_pix_fmts().
168 */
169 4962 static int can_merge_sample_fmts(const void *a, const void *b)
170 {
171 4962 return merge_formats_internal((AVFilterFormats *)a,
172 (AVFilterFormats *)b, AVMEDIA_TYPE_AUDIO, 1);
173 }
174
175 /**
176 * See merge_pix_fmts().
177 */
178 5437 static int merge_sample_fmts(void *a, void *b)
179 {
180 5437 return merge_formats_internal(a, b, AVMEDIA_TYPE_AUDIO, 0);
181 }
182
183 10403 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 10403 times.
10403 if (a == b) return 1;
188
189
23/24
✓ Branch 0 taken 6869 times.
✓ Branch 1 taken 3534 times.
✓ Branch 2 taken 6743 times.
✓ Branch 3 taken 126 times.
✓ Branch 4 taken 4888 times.
✓ Branch 5 taken 5389 times.
✓ Branch 6 taken 1999 times.
✓ Branch 7 taken 3390 times.
✓ Branch 8 taken 126 times.
✓ Branch 9 taken 5389 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 5437 times.
✓ Branch 23 taken 9780 times.
✓ Branch 24 taken 5437 times.
20285 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 1);
190 5437 return 1;
191 }
192
193 /**
194 * See can_merge_pix_fmts().
195 */
196 4966 static int can_merge_samplerates(const void *a, const void *b)
197 {
198 4966 return merge_samplerates_internal((AVFilterFormats *)a, (AVFilterFormats *)b, 1);
199 }
200
201 /**
202 * See merge_pix_fmts().
203 */
204 5437 static int merge_samplerates(void *a, void *b)
205 {
206 5437 return merge_samplerates_internal(a, b, 0);
207 }
208
209 /**
210 * See merge_pix_fmts().
211 */
212 5964 static int merge_channel_layouts_internal(AVFilterChannelLayouts *a,
213 AVFilterChannelLayouts *b, int check)
214 {
215 5964 AVChannelLayout *channel_layouts = NULL;
216 5964 unsigned a_all = a->all_layouts + a->all_counts;
217 5964 unsigned b_all = b->all_layouts + b->all_counts;
218 5964 int ret_max, ret_nb = 0, i, j, round;
219
220 av_assert2(a->refcount && b->refcount);
221
222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5964 times.
5964 if (a == b) return 1;
223
224 /* Put the most generic set in a, to avoid doing everything twice */
225
2/2
✓ Branch 0 taken 2953 times.
✓ Branch 1 taken 3011 times.
5964 if (a_all < b_all) {
226 2953 FFSWAP(AVFilterChannelLayouts *, a, b);
227 2953 FFSWAP(unsigned, a_all, b_all);
228 }
229
2/2
✓ Branch 0 taken 5787 times.
✓ Branch 1 taken 177 times.
5964 if (a_all) {
230
3/4
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5782 times.
✓ Branch 2 taken 5 times.
✗ Branch 3 not taken.
5787 if (a_all == 1 && !b_all) {
231 /* keep only known layouts in b; works also for b_all = 1 */
232
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 5 times.
10 for (i = j = 0; i < b->nb_channel_layouts; i++)
233
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++) {
234 if (check)
235 return 1;
236 av_channel_layout_copy(&b->channel_layouts[j], &b->channel_layouts[i]);
237 }
238 /* Not optimal: the unknown layouts of b may become known after
239 another merge. */
240
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!j)
241 return 0;
242 5 b->nb_channel_layouts = j;
243 }
244
3/4
✗ Branch 1 not taken.
✓ Branch 2 taken 5787 times.
✓ Branch 3 taken 10150 times.
✓ Branch 4 taken 5787 times.
15937 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, return AVERROR(ENOMEM););
245 5787 return 1;
246 }
247
248 177 ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
249
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))))
250 return AVERROR(ENOMEM);
251
252 /* a[known] intersect b[known] */
253
2/2
✓ Branch 0 taken 177 times.
✓ Branch 1 taken 71 times.
248 for (i = 0; i < a->nb_channel_layouts; i++) {
254
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]))
255 1 continue;
256
2/2
✓ Branch 0 taken 272 times.
✓ Branch 1 taken 7 times.
279 for (j = 0; j < b->nb_channel_layouts; j++) {
257
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])) {
258
2/2
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 63 times.
169 if (check)
259 106 return 1;
260 63 av_channel_layout_copy(&channel_layouts[ret_nb++], &a->channel_layouts[i]);
261 63 av_channel_layout_uninit(&a->channel_layouts[i]);
262 63 av_channel_layout_uninit(&b->channel_layouts[j]);
263 63 break;
264 }
265 }
266 }
267 /* 1st round: a[known] intersect b[generic]
268 2nd round: a[generic] intersect b[known] */
269
2/2
✓ Branch 0 taken 142 times.
✓ Branch 1 taken 70 times.
212 for (round = 0; round < 2; round++) {
270
2/2
✓ Branch 0 taken 228 times.
✓ Branch 1 taken 141 times.
369 for (i = 0; i < a->nb_channel_layouts; i++) {
271 228 AVChannelLayout *fmt = &a->channel_layouts[i], bfmt = { 0 };
272
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))
273 127 continue;
274 101 bfmt = FF_COUNT2LAYOUT(fmt->nb_channels);
275
2/2
✓ Branch 0 taken 101 times.
✓ Branch 1 taken 100 times.
201 for (j = 0; j < b->nb_channel_layouts; j++)
276
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 100 times.
101 if (!av_channel_layout_compare(&b->channel_layouts[j], &bfmt)) {
277
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (check)
278 1 return 1;
279 av_channel_layout_copy(&channel_layouts[ret_nb++], fmt);
280 }
281 }
282 /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
283 141 FFSWAP(AVFilterChannelLayouts *, a, b);
284 }
285 /* a[generic] intersect b[generic] */
286
2/2
✓ Branch 0 taken 70 times.
✓ Branch 1 taken 70 times.
140 for (i = 0; i < a->nb_channel_layouts; i++) {
287
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]))
288 70 continue;
289 for (j = 0; j < b->nb_channel_layouts; j++)
290 if (!av_channel_layout_compare(&a->channel_layouts[i], &b->channel_layouts[j])) {
291 if (check)
292 return 1;
293 av_channel_layout_copy(&channel_layouts[ret_nb++], &a->channel_layouts[i]);
294 }
295 }
296
297
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 63 times.
70 if (!ret_nb) {
298 7 av_free(channel_layouts);
299 7 return 0;
300 }
301
302
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 51 times.
63 if (a->refcount > b->refcount)
303 12 FFSWAP(AVFilterChannelLayouts *, a, b);
304
305
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,
306 { av_free(channel_layouts); return AVERROR(ENOMEM); });
307 63 av_freep(&b->channel_layouts);
308 63 b->channel_layouts = channel_layouts;
309 63 b->nb_channel_layouts = ret_nb;
310 63 return 1;
311 }
312
313 4973 static int can_merge_channel_layouts(const void *a, const void *b)
314 {
315 4973 return merge_channel_layouts_internal((AVFilterChannelLayouts *)a,
316 (AVFilterChannelLayouts *)b, 1);
317 }
318
319 991 static int merge_channel_layouts(void *a, void *b)
320 {
321 991 return merge_channel_layouts_internal(a, b, 0);
322 }
323
324 80620 static int merge_generic_internal(AVFilterFormats *a,
325 AVFilterFormats *b, int check)
326 {
327 av_assert2(check || (a->refcount && b->refcount));
328
329
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 80620 times.
80620 if (a == b)
330 return 1;
331
332
13/16
✓ Branch 0 taken 80620 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 242079 times.
✓ Branch 3 taken 810652 times.
✓ Branch 4 taken 39122 times.
✓ Branch 5 taken 202957 times.
✓ Branch 6 taken 1052731 times.
✓ Branch 7 taken 2360 times.
✓ Branch 8 taken 244439 times.
✓ Branch 9 taken 41498 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 41498 times.
✗ Branch 13 not taken.
✓ Branch 14 taken 41498 times.
✓ Branch 15 taken 73594 times.
✓ Branch 16 taken 41498 times.
1170183 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0);
333
334 41498 return 1;
335 }
336
337 39122 static int can_merge_generic(const void *a, const void *b)
338 {
339 39122 return merge_generic_internal((AVFilterFormats *)a,
340 (AVFilterFormats *)b, 1);
341 }
342
343 41498 static int merge_generic(void *a, void *b)
344 {
345 41498 return merge_generic_internal(a, b, 0);
346 }
347
348 static const AVFilterFormatsMerger mergers_video[] = {
349 {
350 .offset = offsetof(AVFilterFormatsConfig, formats),
351 .merge = merge_pix_fmts,
352 .can_merge = can_merge_pix_fmts,
353 },
354 {
355 .offset = offsetof(AVFilterFormatsConfig, color_spaces),
356 .merge = merge_generic,
357 .can_merge = can_merge_generic,
358 },
359 {
360 .offset = offsetof(AVFilterFormatsConfig, color_ranges),
361 .merge = merge_generic,
362 .can_merge = can_merge_generic,
363 },
364 };
365
366 static const AVFilterFormatsMerger mergers_audio[] = {
367 {
368 .offset = offsetof(AVFilterFormatsConfig, channel_layouts),
369 .merge = merge_channel_layouts,
370 .can_merge = can_merge_channel_layouts,
371 },
372 {
373 .offset = offsetof(AVFilterFormatsConfig, samplerates),
374 .merge = merge_samplerates,
375 .can_merge = can_merge_samplerates,
376 },
377 {
378 .offset = offsetof(AVFilterFormatsConfig, formats),
379 .merge = merge_sample_fmts,
380 .can_merge = can_merge_sample_fmts,
381 },
382 };
383
384 static const AVFilterNegotiation negotiate_video = {
385 .nb_mergers = FF_ARRAY_ELEMS(mergers_video),
386 .mergers = mergers_video,
387 .conversion_filter = "scale",
388 .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts),
389 };
390
391 static const AVFilterNegotiation negotiate_audio = {
392 .nb_mergers = FF_ARRAY_ELEMS(mergers_audio),
393 .mergers = mergers_audio,
394 .conversion_filter = "aresample",
395 .conversion_opts_offset = offsetof(AVFilterGraph, aresample_swr_opts),
396 };
397
398 26238 const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link)
399 {
400
2/3
✓ Branch 0 taken 20797 times.
✓ Branch 1 taken 5441 times.
✗ Branch 2 not taken.
26238 switch (link->type) {
401 20797 case AVMEDIA_TYPE_VIDEO: return &negotiate_video;
402 5441 case AVMEDIA_TYPE_AUDIO: return &negotiate_audio;
403 default: return NULL;
404 }
405 }
406
407 6958 int ff_fmt_is_in(int fmt, const int *fmts)
408 {
409 const int *p;
410
411
2/2
✓ Branch 0 taken 8911 times.
✓ Branch 1 taken 87 times.
8998 for (p = fmts; *p != -1; p++) {
412
2/2
✓ Branch 0 taken 6871 times.
✓ Branch 1 taken 2040 times.
8911 if (fmt == *p)
413 6871 return 1;
414 }
415 87 return 0;
416 }
417
418 #define MAKE_FORMAT_LIST(type, field, count_field) \
419 type *formats; \
420 int count = 0; \
421 if (fmts) \
422 for (count = 0; fmts[count] != -1; count++) \
423 ; \
424 formats = av_mallocz(sizeof(*formats)); \
425 if (!formats) \
426 return NULL; \
427 formats->count_field = count; \
428 if (count) { \
429 formats->field = av_malloc_array(count, sizeof(*formats->field)); \
430 if (!formats->field) { \
431 av_freep(&formats); \
432 return NULL; \
433 } \
434 }
435
436 9092 AVFilterFormats *ff_make_format_list(const int *fmts)
437 {
438
6/10
✓ Branch 0 taken 9092 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 76066 times.
✓ Branch 3 taken 9092 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 9092 times.
✓ Branch 7 taken 9092 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 9092 times.
85158 MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
439
2/2
✓ Branch 0 taken 76066 times.
✓ Branch 1 taken 9092 times.
85158 while (count--)
440 76066 formats->formats[count] = fmts[count];
441
442 9092 return formats;
443 }
444
445 31 AVFilterChannelLayouts *ff_make_channel_layout_list(const AVChannelLayout *fmts)
446 {
447 AVFilterChannelLayouts *ch_layouts;
448 31 int count = 0;
449
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 if (fmts)
450
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 31 times.
62 for (count = 0; fmts[count].nb_channels; count++)
451 ;
452 31 ch_layouts = av_mallocz(sizeof(*ch_layouts));
453
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (!ch_layouts)
454 return NULL;
455 31 ch_layouts->nb_channel_layouts = count;
456
1/2
✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
31 if (count) {
457 62 ch_layouts->channel_layouts =
458 31 av_calloc(count, sizeof(*ch_layouts->channel_layouts));
459
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (!ch_layouts->channel_layouts) {
460 av_freep(&ch_layouts);
461 return NULL;
462 }
463
2/2
✓ Branch 0 taken 31 times.
✓ Branch 1 taken 31 times.
62 for (int i = 0; i < count; i++) {
464 31 int ret = av_channel_layout_copy(&ch_layouts->channel_layouts[i], &fmts[i]);
465
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if (ret < 0)
466 goto fail;
467 }
468 }
469
470 31 return ch_layouts;
471
472 fail:
473 for (int i = 0; i < count; i++)
474 av_channel_layout_uninit(&ch_layouts->channel_layouts[i]);
475 av_free(ch_layouts->channel_layouts);
476 av_freep(&ch_layouts);
477
478 return NULL;
479 }
480
481 #define ADD_FORMAT(f, fmt, unref_fn, type, list, nb) \
482 do { \
483 type *fmts; \
484 \
485 if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) { \
486 return AVERROR(ENOMEM); \
487 } \
488 \
489 fmts = av_realloc_array((*f)->list, (*f)->nb + 1, \
490 sizeof(*(*f)->list)); \
491 if (!fmts) { \
492 unref_fn(f); \
493 return AVERROR(ENOMEM); \
494 } \
495 \
496 (*f)->list = fmts; \
497 ASSIGN_FMT(f, fmt, list, nb); \
498 } while (0)
499
500 #define ASSIGN_FMT(f, fmt, list, nb) \
501 do { \
502 (*f)->list[(*f)->nb++] = fmt; \
503 } while (0)
504
505 2307738 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
506 {
507
4/6
✓ Branch 0 taken 118254 times.
✓ Branch 1 taken 2189484 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 118254 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2307738 times.
2307738 ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
508 2307738 return 0;
509 }
510
511 #undef ASSIGN_FMT
512 #define ASSIGN_FMT(f, fmt, list, nb) \
513 do { \
514 int ret; \
515 memset((*f)->list + (*f)->nb, 0, sizeof(*(*f)->list)); \
516 ret = av_channel_layout_copy(&(*f)->list[(*f)->nb], fmt); \
517 if (ret < 0) \
518 return ret; \
519 (*f)->nb++; \
520 } while (0)
521
522 2569 int ff_add_channel_layout(AVFilterChannelLayouts **l,
523 const AVChannelLayout *channel_layout)
524 {
525 av_assert1(!(*l && (*l)->all_layouts));
526
5/8
✓ Branch 0 taken 1422 times.
✓ Branch 1 taken 1147 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1422 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 2569 times.
✗ Branch 10 not taken.
✓ Branch 11 taken 2569 times.
2569 ADD_FORMAT(l, channel_layout, ff_channel_layouts_unref, AVChannelLayout, channel_layouts, nb_channel_layouts);
527 2569 return 0;
528 }
529
530 57 AVFilterFormats *ff_make_formats_list_singleton(int fmt)
531 {
532 57 int fmts[2] = { fmt, -1 };
533 57 return ff_make_format_list(fmts);
534 }
535
536 34958 AVFilterFormats *ff_all_formats(enum AVMediaType type)
537 {
538 34958 AVFilterFormats *ret = NULL;
539
540
2/2
✓ Branch 0 taken 25641 times.
✓ Branch 1 taken 9317 times.
34958 if (type == AVMEDIA_TYPE_VIDEO) {
541 25641 return ff_formats_pixdesc_filter(0, 0);
542
1/2
✓ Branch 0 taken 9317 times.
✗ Branch 1 not taken.
9317 } else if (type == AVMEDIA_TYPE_AUDIO) {
543 9317 enum AVSampleFormat fmt = 0;
544
2/2
✓ Branch 1 taken 111804 times.
✓ Branch 2 taken 9317 times.
121121 while (av_get_sample_fmt_name(fmt)) {
545
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 111804 times.
111804 if (ff_add_format(&ret, fmt) < 0)
546 return NULL;
547 111804 fmt++;
548 }
549 }
550
551 9317 return ret;
552 }
553
554 26224 AVFilterFormats *ff_formats_pixdesc_filter(unsigned want, unsigned rej)
555 {
556 unsigned nb_formats, fmt, flags;
557 26224 AVFilterFormats *formats = NULL;
558
559 while (1) {
560 52448 nb_formats = 0;
561 12010592 for (fmt = 0;; fmt++) {
562 12010592 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
563
2/2
✓ Branch 0 taken 52448 times.
✓ Branch 1 taken 11958144 times.
12010592 if (!desc)
564 52448 break;
565 11958144 flags = desc->flags;
566
2/2
✓ Branch 0 taken 11223872 times.
✓ Branch 1 taken 734272 times.
11958144 if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
567
2/2
✓ Branch 0 taken 4982560 times.
✓ Branch 1 taken 6241312 times.
11223872 !(desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
568
3/4
✓ Branch 0 taken 4562976 times.
✓ Branch 1 taken 419584 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4562976 times.
4982560 (desc->log2_chroma_w || desc->log2_chroma_h))
569 419584 flags |= FF_PIX_FMT_FLAG_SW_FLAT_SUB;
570
2/2
✓ Branch 0 taken 16632 times.
✓ Branch 1 taken 11941512 times.
11958144 if ((flags & (want | rej)) != want)
571 16632 continue;
572
2/2
✓ Branch 0 taken 5970756 times.
✓ Branch 1 taken 5970756 times.
11941512 if (formats)
573 5970756 formats->formats[nb_formats] = fmt;
574 11941512 nb_formats++;
575 }
576
2/2
✓ Branch 0 taken 26224 times.
✓ Branch 1 taken 26224 times.
52448 if (formats) {
577
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26224 times.
26224 av_assert0(formats->nb_formats == nb_formats);
578 26224 return formats;
579 }
580 26224 formats = av_mallocz(sizeof(*formats));
581
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26224 times.
26224 if (!formats)
582 return NULL;
583 26224 formats->nb_formats = nb_formats;
584
1/2
✓ Branch 0 taken 26224 times.
✗ Branch 1 not taken.
26224 if (nb_formats) {
585 26224 formats->formats = av_malloc_array(nb_formats, sizeof(*formats->formats));
586
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 26224 times.
26224 if (!formats->formats) {
587 av_freep(&formats);
588 return NULL;
589 }
590 }
591 }
592 }
593
594 40 AVFilterFormats *ff_planar_sample_fmts(void)
595 {
596 40 AVFilterFormats *ret = NULL;
597 int fmt;
598
599
2/2
✓ Branch 1 taken 480 times.
✓ Branch 2 taken 40 times.
520 for (fmt = 0; av_get_bytes_per_sample(fmt)>0; fmt++)
600
2/2
✓ Branch 1 taken 240 times.
✓ Branch 2 taken 240 times.
480 if (av_sample_fmt_is_planar(fmt))
601
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 240 times.
240 if (ff_add_format(&ret, fmt) < 0)
602 return NULL;
603
604 40 return ret;
605 }
606
607 35888 AVFilterFormats *ff_all_samplerates(void)
608 {
609 35888 AVFilterFormats *ret = av_mallocz(sizeof(*ret));
610 35888 return ret;
611 }
612
613 5 AVFilterChannelLayouts *ff_all_channel_layouts(void)
614 {
615 5 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
616
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (!ret)
617 return NULL;
618 5 ret->all_layouts = 1;
619 5 return ret;
620 }
621
622 37761 AVFilterChannelLayouts *ff_all_channel_counts(void)
623 {
624 37761 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37761 times.
37761 if (!ret)
626 return NULL;
627 37761 ret->all_layouts = ret->all_counts = 1;
628 37761 return ret;
629 }
630
631 32662 AVFilterFormats *ff_all_color_spaces(void)
632 {
633 32662 AVFilterFormats *ret = NULL;
634
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 32662 times.
32662 if (ff_add_format(&ret, AVCOL_SPC_UNSPECIFIED) < 0)
635 return NULL;
636
2/2
✓ Branch 0 taken 489930 times.
✓ Branch 1 taken 32662 times.
522592 for (int csp = 0; csp < AVCOL_SPC_NB; csp++) {
637
4/4
✓ Branch 0 taken 457268 times.
✓ Branch 1 taken 32662 times.
✓ Branch 2 taken 32662 times.
✓ Branch 3 taken 424606 times.
489930 if (csp == AVCOL_SPC_RESERVED ||
638 csp == AVCOL_SPC_UNSPECIFIED)
639 65324 continue;
640
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 424606 times.
424606 if (ff_add_format(&ret, csp) < 0)
641 return NULL;
642 }
643
644 32662 return ret;
645 }
646
647 40376 AVFilterFormats *ff_all_color_ranges(void)
648 {
649 40376 AVFilterFormats *ret = NULL;
650
2/2
✓ Branch 0 taken 121128 times.
✓ Branch 1 taken 40376 times.
161504 for (int range = 0; range < AVCOL_RANGE_NB; range++) {
651
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 121128 times.
121128 if (ff_add_format(&ret, range) < 0)
652 return NULL;
653 }
654
655 40376 return ret;
656 }
657
658 #define FORMATS_REF(f, ref, unref_fn) \
659 void *tmp; \
660 \
661 if (!f) \
662 return AVERROR(ENOMEM); \
663 \
664 tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1); \
665 if (!tmp) { \
666 unref_fn(&f); \
667 return AVERROR(ENOMEM); \
668 } \
669 f->refs = tmp; \
670 f->refs[f->refcount++] = ref; \
671 *ref = f; \
672 return 0
673
674 10874 int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
675 {
676
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 10874 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 10874 times.
10874 FORMATS_REF(f, ref, ff_channel_layouts_unref);
677 }
678
679 155547 int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
680 {
681
2/4
✗ Branch 0 not taken.
✓ Branch 1 taken 155547 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 155547 times.
155547 FORMATS_REF(f, ref, ff_formats_unref);
682 }
683
684 #define FIND_REF_INDEX(ref, idx) \
685 do { \
686 int i; \
687 for (i = 0; i < (*ref)->refcount; i ++) \
688 if((*ref)->refs[i] == ref) { \
689 idx = i; \
690 break; \
691 } \
692 } while (0)
693
694 #define FORMATS_UNREF(ref, list) \
695 do { \
696 int idx = -1; \
697 \
698 if (!*ref) \
699 return; \
700 \
701 FIND_REF_INDEX(ref, idx); \
702 \
703 if (idx >= 0) { \
704 memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
705 sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
706 --(*ref)->refcount; \
707 } \
708 if (!(*ref)->refcount) { \
709 FREE_LIST(ref, list); \
710 av_free((*ref)->list); \
711 av_free((*ref)->refs); \
712 av_free(*ref); \
713 } \
714 *ref = NULL; \
715 } while (0)
716
717 #define FREE_LIST(ref, list) do { } while(0)
718 581601 void ff_formats_unref(AVFilterFormats **ref)
719 {
720
10/10
✓ Branch 0 taken 344804 times.
✓ Branch 1 taken 236797 times.
✓ Branch 2 taken 155547 times.
✓ Branch 3 taken 48416 times.
✓ Branch 4 taken 203963 times.
✓ Branch 5 taken 81250 times.
✓ Branch 6 taken 155547 times.
✓ Branch 7 taken 81250 times.
✓ Branch 8 taken 116335 times.
✓ Branch 9 taken 120462 times.
630017 FORMATS_UNREF(ref, formats);
721 }
722
723 #undef FREE_LIST
724 #define FREE_LIST(ref, list) \
725 do { \
726 for (int i = 0; i < (*ref)->nb_channel_layouts; i++) \
727 av_channel_layout_uninit(&(*ref)->list[i]); \
728 } while(0)
729
730 150551 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
731 {
732
12/12
✓ Branch 0 taken 108536 times.
✓ Branch 1 taken 42015 times.
✓ Branch 2 taken 10874 times.
✓ Branch 3 taken 7992 times.
✓ Branch 4 taken 18866 times.
✓ Branch 5 taken 31141 times.
✓ Branch 6 taken 10874 times.
✓ Branch 7 taken 31141 times.
✓ Branch 8 taken 33369 times.
✓ Branch 9 taken 8646 times.
✓ Branch 11 taken 2228 times.
✓ Branch 12 taken 33369 times.
160771 FORMATS_UNREF(ref, channel_layouts);
733 }
734
735 #define FORMATS_CHANGEREF(oldref, newref) \
736 do { \
737 int idx = -1; \
738 \
739 FIND_REF_INDEX(oldref, idx); \
740 \
741 if (idx >= 0) { \
742 (*oldref)->refs[idx] = newref; \
743 *newref = *oldref; \
744 *oldref = NULL; \
745 } \
746 } while (0)
747
748 464 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
749 AVFilterChannelLayouts **newref)
750 {
751
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);
752 464 }
753
754 2710 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
755 {
756
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);
757 2710 }
758
759 #define SET_COMMON_FORMATS(ctx, fmts, media_type, ref_fn, unref_fn) \
760 int i; \
761 \
762 if (!fmts) \
763 return AVERROR(ENOMEM); \
764 \
765 for (i = 0; i < ctx->nb_inputs; i++) { \
766 AVFilterLink *const link = ctx->inputs[i]; \
767 if (link && !link->outcfg.fmts && \
768 (media_type == AVMEDIA_TYPE_UNKNOWN || link->type == media_type)) { \
769 int ret = ref_fn(fmts, &ctx->inputs[i]->outcfg.fmts); \
770 if (ret < 0) { \
771 return ret; \
772 } \
773 } \
774 } \
775 for (i = 0; i < ctx->nb_outputs; i++) { \
776 AVFilterLink *const link = ctx->outputs[i]; \
777 if (link && !link->incfg.fmts && \
778 (media_type == AVMEDIA_TYPE_UNKNOWN || link->type == media_type)) { \
779 int ret = ref_fn(fmts, &ctx->outputs[i]->incfg.fmts); \
780 if (ret < 0) { \
781 return ret; \
782 } \
783 } \
784 } \
785 \
786 if (!fmts->refcount) \
787 unref_fn(&fmts); \
788 \
789 return 0;
790
791 36445 int ff_set_common_channel_layouts(AVFilterContext *ctx,
792 AVFilterChannelLayouts *channel_layouts)
793 {
794
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 36445 times.
✓ Branch 2 taken 28693 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24452 times.
✓ Branch 5 taken 4241 times.
✓ Branch 6 taken 4044 times.
✓ Branch 7 taken 20408 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4044 times.
✓ Branch 11 taken 28693 times.
✓ Branch 12 taken 36445 times.
✓ Branch 13 taken 28688 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 24447 times.
✓ Branch 16 taken 4241 times.
✓ Branch 17 taken 4046 times.
✓ Branch 18 taken 20401 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 4046 times.
✓ Branch 22 taken 28688 times.
✓ Branch 23 taken 36445 times.
✓ Branch 24 taken 31141 times.
✓ Branch 25 taken 5304 times.
93826 SET_COMMON_FORMATS(ctx, channel_layouts, AVMEDIA_TYPE_AUDIO,
795 ff_channel_layouts_ref, ff_channel_layouts_unref);
796 }
797
798 28 int ff_set_common_channel_layouts_from_list(AVFilterContext *ctx,
799 const AVChannelLayout *fmts)
800 {
801 28 return ff_set_common_channel_layouts(ctx, ff_make_channel_layout_list(fmts));
802 }
803
804 32333 int ff_set_common_all_channel_counts(AVFilterContext *ctx)
805 {
806 32333 return ff_set_common_channel_layouts(ctx, ff_all_channel_counts());
807 }
808
809 35244 int ff_set_common_samplerates(AVFilterContext *ctx,
810 AVFilterFormats *samplerates)
811 {
812
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 35244 times.
✓ Branch 2 taken 27494 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 24519 times.
✓ Branch 5 taken 2975 times.
✓ Branch 6 taken 4111 times.
✓ Branch 7 taken 20408 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 4111 times.
✓ Branch 11 taken 27494 times.
✓ Branch 12 taken 35244 times.
✓ Branch 13 taken 28754 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 24513 times.
✓ Branch 16 taken 4241 times.
✓ Branch 17 taken 4112 times.
✓ Branch 18 taken 20401 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 4112 times.
✓ Branch 22 taken 28754 times.
✓ Branch 23 taken 35244 times.
✓ Branch 24 taken 29875 times.
✓ Branch 25 taken 5369 times.
91492 SET_COMMON_FORMATS(ctx, samplerates, AVMEDIA_TYPE_AUDIO,
813 ff_formats_ref, ff_formats_unref);
814 }
815
816 46 int ff_set_common_samplerates_from_list(AVFilterContext *ctx,
817 const int *samplerates)
818 {
819 46 return ff_set_common_samplerates(ctx, ff_make_format_list(samplerates));
820 }
821
822 32400 int ff_set_common_all_samplerates(AVFilterContext *ctx)
823 {
824 32400 return ff_set_common_samplerates(ctx, ff_all_samplerates());
825 }
826
827 37098 int ff_set_common_color_spaces(AVFilterContext *ctx,
828 AVFilterFormats *color_spaces)
829 {
830
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 37098 times.
✓ Branch 2 taken 26163 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22348 times.
✓ Branch 5 taken 3815 times.
✓ Branch 6 taken 16951 times.
✓ Branch 7 taken 5397 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16951 times.
✓ Branch 11 taken 26163 times.
✓ Branch 12 taken 37098 times.
✓ Branch 13 taken 30607 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 22356 times.
✓ Branch 16 taken 8251 times.
✓ Branch 17 taken 16951 times.
✓ Branch 18 taken 5405 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 16951 times.
✓ Branch 22 taken 30607 times.
✓ Branch 23 taken 37098 times.
✓ Branch 24 taken 14910 times.
✓ Branch 25 taken 22188 times.
93868 SET_COMMON_FORMATS(ctx, color_spaces, AVMEDIA_TYPE_VIDEO,
831 ff_formats_ref, ff_formats_unref);
832 }
833
834 int ff_set_common_color_spaces_from_list(AVFilterContext *ctx,
835 const int *color_ranges)
836 {
837 return ff_set_common_color_spaces(ctx, ff_make_format_list(color_ranges));
838 }
839
840 32662 int ff_set_common_all_color_spaces(AVFilterContext *ctx)
841 {
842 32662 return ff_set_common_color_spaces(ctx, ff_all_color_spaces());
843 }
844
845 37098 int ff_set_common_color_ranges(AVFilterContext *ctx,
846 AVFilterFormats *color_ranges)
847 {
848
19/24
✗ Branch 0 not taken.
✓ Branch 1 taken 37098 times.
✓ Branch 2 taken 26163 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 22348 times.
✓ Branch 5 taken 3815 times.
✓ Branch 6 taken 16951 times.
✓ Branch 7 taken 5397 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 16951 times.
✓ Branch 11 taken 26163 times.
✓ Branch 12 taken 37098 times.
✓ Branch 13 taken 30607 times.
✗ Branch 14 not taken.
✓ Branch 15 taken 22356 times.
✓ Branch 16 taken 8251 times.
✓ Branch 17 taken 16951 times.
✓ Branch 18 taken 5405 times.
✗ Branch 20 not taken.
✓ Branch 21 taken 16951 times.
✓ Branch 22 taken 30607 times.
✓ Branch 23 taken 37098 times.
✓ Branch 24 taken 14910 times.
✓ Branch 25 taken 22188 times.
93868 SET_COMMON_FORMATS(ctx, color_ranges, AVMEDIA_TYPE_VIDEO,
849 ff_formats_ref, ff_formats_unref);
850 }
851
852 int ff_set_common_color_ranges_from_list(AVFilterContext *ctx,
853 const int *color_ranges)
854 {
855 return ff_set_common_color_ranges(ctx, ff_make_format_list(color_ranges));
856 }
857
858 32662 int ff_set_common_all_color_ranges(AVFilterContext *ctx)
859 {
860 32662 return ff_set_common_color_ranges(ctx, ff_all_color_ranges());
861 }
862
863 /**
864 * A helper for query_formats() which sets all links to the same list of
865 * formats. If there are no links hooked to this filter, the list of formats is
866 * freed.
867 */
868 48726 int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
869 {
870
15/20
✗ Branch 0 not taken.
✓ Branch 1 taken 48726 times.
✓ Branch 2 taken 35714 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 20967 times.
✓ Branch 5 taken 14747 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 20967 times.
✓ Branch 9 taken 35714 times.
✓ Branch 10 taken 48726 times.
✓ Branch 11 taken 42212 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 20993 times.
✓ Branch 14 taken 21219 times.
✗ Branch 16 not taken.
✓ Branch 17 taken 20993 times.
✓ Branch 18 taken 42212 times.
✓ Branch 19 taken 48726 times.
✓ Branch 20 taken 21239 times.
✓ Branch 21 taken 27487 times.
126652 SET_COMMON_FORMATS(ctx, formats, AVMEDIA_TYPE_UNKNOWN,
871 ff_formats_ref, ff_formats_unref);
872 }
873
874 123 int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
875 {
876 123 return ff_set_common_formats(ctx, ff_make_format_list(fmts));
877 }
878
879 32694 int ff_default_query_formats(AVFilterContext *ctx)
880 {
881 32694 const AVFilter *const f = ctx->filter;
882 AVFilterFormats *formats;
883 enum AVMediaType type;
884 int ret;
885
886
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 32297 times.
32694 switch (f->formats_state) {
887 333 case FF_FILTER_FORMATS_PIXFMT_LIST:
888 333 type = AVMEDIA_TYPE_VIDEO;
889 333 formats = ff_make_format_list(f->formats.pixels_list);
890 333 break;
891 19 case FF_FILTER_FORMATS_SAMPLEFMTS_LIST:
892 19 type = AVMEDIA_TYPE_AUDIO;
893 19 formats = ff_make_format_list(f->formats.samples_list);
894 19 break;
895 32 case FF_FILTER_FORMATS_SINGLE_PIXFMT:
896 32 type = AVMEDIA_TYPE_VIDEO;
897 32 formats = ff_make_formats_list_singleton(f->formats.pix_fmt);
898 32 break;
899 13 case FF_FILTER_FORMATS_SINGLE_SAMPLEFMT:
900 13 type = AVMEDIA_TYPE_AUDIO;
901 13 formats = ff_make_formats_list_singleton(f->formats.sample_fmt);
902 13 break;
903 32297 default:
904 av_assert2(!"Unreachable");
905 /* Intended fallthrough */
906 case FF_FILTER_FORMATS_PASSTHROUGH:
907 case FF_FILTER_FORMATS_QUERY_FUNC:
908 32297 type = AVMEDIA_TYPE_UNKNOWN;
909
2/2
✓ Branch 0 taken 25756 times.
✓ Branch 1 taken 6541 times.
38838 formats = ff_all_formats(ctx->nb_inputs ? ctx->inputs [0]->type :
910
1/2
✓ Branch 0 taken 6541 times.
✗ Branch 1 not taken.
6541 ctx->nb_outputs ? ctx->outputs[0]->type :
911 AVMEDIA_TYPE_VIDEO);
912 32297 break;
913 }
914
915 32694 ret = ff_set_common_formats(ctx, formats);
916
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32694 times.
32694 if (ret < 0)
917 return ret;
918
2/2
✓ Branch 0 taken 32662 times.
✓ Branch 1 taken 32 times.
32694 if (type != AVMEDIA_TYPE_AUDIO) {
919 32662 ret = ff_set_common_all_color_spaces(ctx);
920
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32662 times.
32662 if (ret < 0)
921 return ret;
922 32662 ret = ff_set_common_all_color_ranges(ctx);
923
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32662 times.
32662 if (ret < 0)
924 return ret;
925 }
926
2/2
✓ Branch 0 taken 32329 times.
✓ Branch 1 taken 365 times.
32694 if (type != AVMEDIA_TYPE_VIDEO) {
927 32329 ret = ff_set_common_all_channel_counts(ctx);
928
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32329 times.
32329 if (ret < 0)
929 return ret;
930 32329 ret = ff_set_common_all_samplerates(ctx);
931
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 32329 times.
32329 if (ret < 0)
932 return ret;
933 }
934
935 32694 return 0;
936 }
937
938 /* internal functions for parsing audio format arguments */
939
940 10506 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
941 {
942 char *tail;
943 10506 int pix_fmt = av_get_pix_fmt(arg);
944
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10506 times.
10506 if (pix_fmt == AV_PIX_FMT_NONE) {
945 pix_fmt = strtol(arg, &tail, 0);
946 if (*tail || !av_pix_fmt_desc_get(pix_fmt)) {
947 av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
948 return AVERROR(EINVAL);
949 }
950 }
951 10506 *ret = pix_fmt;
952 10506 return 0;
953 }
954
955 15 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
956 {
957 char *tail;
958 15 double srate = av_strtod(arg, &tail);
959
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) {
960 av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
961 return AVERROR(EINVAL);
962 }
963 15 *ret = srate;
964 15 return 0;
965 }
966
967 65 int ff_parse_channel_layout(AVChannelLayout *ret, int *nret, const char *arg,
968 void *log_ctx)
969 {
970 65 AVChannelLayout chlayout = { 0 };
971 int res;
972
973 65 res = av_channel_layout_from_string(&chlayout, arg);
974
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 60 times.
65 if (res < 0) {
975 5 av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
976 5 return AVERROR(EINVAL);
977 }
978
979
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) {
980 av_log(log_ctx, AV_LOG_ERROR, "Unknown channel layout '%s' is not supported.\n", arg);
981 return AVERROR(EINVAL);
982 }
983 60 *ret = chlayout;
984
1/2
✓ Branch 0 taken 60 times.
✗ Branch 1 not taken.
60 if (nret)
985 60 *nret = chlayout.nb_channels;
986
987 60 return 0;
988 }
989
990 112508 static int check_list(void *log, const char *name, const AVFilterFormats *fmts)
991 {
992 unsigned i, j;
993
994
2/2
✓ Branch 0 taken 50327 times.
✓ Branch 1 taken 62181 times.
112508 if (!fmts)
995 50327 return 0;
996
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 62181 times.
62181 if (!fmts->nb_formats) {
997 av_log(log, AV_LOG_ERROR, "Empty %s list\n", name);
998 return AVERROR(EINVAL);
999 }
1000
2/2
✓ Branch 0 taken 2084527 times.
✓ Branch 1 taken 62181 times.
2146708 for (i = 0; i < fmts->nb_formats; i++) {
1001
2/2
✓ Branch 0 taken 184323916 times.
✓ Branch 1 taken 2084527 times.
186408443 for (j = i + 1; j < fmts->nb_formats; j++) {
1002
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 184323916 times.
184323916 if (fmts->formats[i] == fmts->formats[j]) {
1003 av_log(log, AV_LOG_ERROR, "Duplicated %s\n", name);
1004 return AVERROR(EINVAL);
1005 }
1006 }
1007 }
1008 62181 return 0;
1009 }
1010
1011 33981 int ff_formats_check_pixel_formats(void *log, const AVFilterFormats *fmts)
1012 {
1013 33981 return check_list(log, "pixel format", fmts);
1014 }
1015
1016 8482 int ff_formats_check_sample_formats(void *log, const AVFilterFormats *fmts)
1017 {
1018 8482 return check_list(log, "sample format", fmts);
1019 }
1020
1021 8482 int ff_formats_check_sample_rates(void *log, const AVFilterFormats *fmts)
1022 {
1023
4/4
✓ Branch 0 taken 7216 times.
✓ Branch 1 taken 1266 times.
✓ Branch 2 taken 5133 times.
✓ Branch 3 taken 2083 times.
8482 if (!fmts || !fmts->nb_formats)
1024 6399 return 0;
1025 2083 return check_list(log, "sample rate", fmts);
1026 }
1027
1028 33981 int ff_formats_check_color_spaces(void *log, const AVFilterFormats *fmts)
1029 {
1030
4/4
✓ Branch 0 taken 77552 times.
✓ Branch 1 taken 21915 times.
✓ Branch 2 taken 65486 times.
✓ Branch 3 taken 12066 times.
99467 for (int i = 0; fmts && i < fmts->nb_formats; i++) {
1031
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 65486 times.
65486 if (fmts->formats[i] == AVCOL_SPC_RESERVED) {
1032 av_log(log, AV_LOG_ERROR, "Invalid color range\n");
1033 return AVERROR(EINVAL);
1034 }
1035 }
1036 33981 return check_list(log, "color space", fmts);
1037 }
1038
1039 33981 int ff_formats_check_color_ranges(void *log, const AVFilterFormats *fmts)
1040 {
1041 33981 return check_list(log, "color range", fmts);
1042 }
1043
1044 3180 static int layouts_compatible(const AVChannelLayout *a, const AVChannelLayout *b)
1045 {
1046 3180 return !av_channel_layout_compare(a, b) ||
1047
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) ||
1048
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);
1049 }
1050
1051 8482 int ff_formats_check_channel_layouts(void *log, const AVFilterChannelLayouts *fmts)
1052 {
1053 unsigned i, j;
1054
1055
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8482 times.
8482 if (!fmts)
1056 return 0;
1057
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8482 times.
8482 if (fmts->all_layouts < fmts->all_counts) {
1058 av_log(log, AV_LOG_ERROR, "Inconsistent generic list\n");
1059 return AVERROR(EINVAL);
1060 }
1061
3/4
✓ Branch 0 taken 1565 times.
✓ Branch 1 taken 6917 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1565 times.
8482 if (!fmts->all_layouts && !fmts->nb_channel_layouts) {
1062 av_log(log, AV_LOG_ERROR, "Empty channel layout list\n");
1063 return AVERROR(EINVAL);
1064 }
1065
2/2
✓ Branch 0 taken 2183 times.
✓ Branch 1 taken 8482 times.
10665 for (i = 0; i < fmts->nb_channel_layouts; i++) {
1066
2/2
✓ Branch 0 taken 3180 times.
✓ Branch 1 taken 2183 times.
5363 for (j = i + 1; j < fmts->nb_channel_layouts; j++) {
1067
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 3180 times.
3180 if (layouts_compatible(&fmts->channel_layouts[i], &fmts->channel_layouts[j])) {
1068 av_log(log, AV_LOG_ERROR, "Duplicated or redundant channel layout\n");
1069 return AVERROR(EINVAL);
1070 }
1071 }
1072 }
1073 8482 return 0;
1074 }
1075