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 #define KNOWN(l) (!FF_LAYOUT2COUNT(l)) /* for readability */
32
33 /**
34 * Add all refs from a to ret and destroy a.
35 */
36 #define MERGE_REF(ret, a, fmts, type, fail_statement) \
37 do { \
38 type ***tmp; \
39 int i; \
40 \
41 if (!(tmp = av_realloc_array(ret->refs, ret->refcount + a->refcount, \
42 sizeof(*tmp)))) \
43 { fail_statement } \
44 ret->refs = tmp; \
45 \
46 for (i = 0; i < a->refcount; i ++) { \
47 ret->refs[ret->refcount] = a->refs[i]; \
48 *ret->refs[ret->refcount++] = ret; \
49 } \
50 \
51 av_freep(&a->refs); \
52 av_freep(&a->fmts); \
53 av_freep(&a); \
54 } while (0)
55
56 /**
57 * Add all formats common to a and b to a, add b's refs to a and destroy b.
58 * If check is set, nothing is modified and it is only checked whether
59 * the formats are compatible.
60 * If empty_allowed is set and one of a,b->nb is zero, the lists are
61 * merged; otherwise, it is treated as error.
62 */
63 #define MERGE_FORMATS(a, b, fmts, nb, type, check, empty_allowed) \
64 do { \
65 int i, j, k = 0, skip = 0; \
66 \
67 if (empty_allowed) { \
68 if (!a->nb || !b->nb) { \
69 if (check) \
70 return 1; \
71 if (!a->nb) \
72 FFSWAP(type *, a, b); \
73 skip = 1; \
74 } \
75 } \
76 if (!skip) { \
77 for (i = 0; i < a->nb; i++) \
78 for (j = 0; j < b->nb; j++) \
79 if (a->fmts[i] == b->fmts[j]) { \
80 if (check) \
81 return 1; \
82 a->fmts[k++] = a->fmts[i]; \
83 break; \
84 } \
85 /* Check that there was at least one common format. \
86 * Notice that both a and b are unchanged if not. */ \
87 if (!k) \
88 return 0; \
89 av_assert2(!check); \
90 a->nb = k; \
91 } \
92 \
93 MERGE_REF(a, b, fmts, type, return AVERROR(ENOMEM);); \
94 } while (0)
95
merge_formats_internal(AVFilterFormats * a,AVFilterFormats * b,enum AVMediaType type,int check)96 static int merge_formats_internal(AVFilterFormats *a, AVFilterFormats *b,
97 enum AVMediaType type, int check)
98 {
99 int i, j;
100 int alpha1=0, alpha2=0;
101 int chroma1=0, chroma2=0;
102
103 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 if (type == AVMEDIA_TYPE_VIDEO)
114 for (i = 0; i < a->nb_formats; i++)
115 for (j = 0; j < b->nb_formats; j++) {
116 const AVPixFmtDescriptor *adesc = av_pix_fmt_desc_get(a->formats[i]);
117 const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
118 alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA;
119 chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
120 if (a->formats[i] == b->formats[j]) {
121 alpha1 |= adesc->flags & AV_PIX_FMT_FLAG_ALPHA;
122 chroma1|= adesc->nb_components > 1;
123 }
124 }
125
126 // If chroma or alpha can be lost through merging then do not merge
127 if (alpha2 > alpha1 || chroma2 > chroma1)
128 return 0;
129
130 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0);
131
132 return 1;
133 }
134
ff_can_merge_formats(const AVFilterFormats * a,const AVFilterFormats * b,enum AVMediaType type)135 int ff_can_merge_formats(const AVFilterFormats *a, const AVFilterFormats *b,
136 enum AVMediaType type)
137 {
138 return merge_formats_internal((AVFilterFormats *)a,
139 (AVFilterFormats *)b, type, 1);
140 }
141
ff_merge_formats(AVFilterFormats * a,AVFilterFormats * b,enum AVMediaType type)142 int ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b,
143 enum AVMediaType type)
144 {
145 av_assert2(a->refcount && b->refcount);
146 return merge_formats_internal(a, b, type, 0);
147 }
148
merge_samplerates_internal(AVFilterFormats * a,AVFilterFormats * b,int check)149 static int merge_samplerates_internal(AVFilterFormats *a,
150 AVFilterFormats *b, int check)
151 {
152 if (a == b) return 1;
153
154 MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 1);
155 return 1;
156 }
157
ff_can_merge_samplerates(const AVFilterFormats * a,const AVFilterFormats * b)158 int ff_can_merge_samplerates(const AVFilterFormats *a, const AVFilterFormats *b)
159 {
160 return merge_samplerates_internal((AVFilterFormats *)a, (AVFilterFormats *)b, 1);
161 }
162
ff_merge_samplerates(AVFilterFormats * a,AVFilterFormats * b)163 int ff_merge_samplerates(AVFilterFormats *a, AVFilterFormats *b)
164 {
165 av_assert2(a->refcount && b->refcount);
166 return merge_samplerates_internal(a, b, 0);
167 }
168
ff_merge_channel_layouts(AVFilterChannelLayouts * a,AVFilterChannelLayouts * b)169 int ff_merge_channel_layouts(AVFilterChannelLayouts *a,
170 AVFilterChannelLayouts *b)
171 {
172 uint64_t *channel_layouts;
173 unsigned a_all = a->all_layouts + a->all_counts;
174 unsigned b_all = b->all_layouts + b->all_counts;
175 int ret_max, ret_nb = 0, i, j, round;
176
177 av_assert2(a->refcount && b->refcount);
178
179 if (a == b) return 1;
180
181 /* Put the most generic set in a, to avoid doing everything twice */
182 if (a_all < b_all) {
183 FFSWAP(AVFilterChannelLayouts *, a, b);
184 FFSWAP(unsigned, a_all, b_all);
185 }
186 if (a_all) {
187 if (a_all == 1 && !b_all) {
188 /* keep only known layouts in b; works also for b_all = 1 */
189 for (i = j = 0; i < b->nb_channel_layouts; i++)
190 if (KNOWN(b->channel_layouts[i]))
191 b->channel_layouts[j++] = b->channel_layouts[i];
192 /* Not optimal: the unknown layouts of b may become known after
193 another merge. */
194 if (!j)
195 return 0;
196 b->nb_channel_layouts = j;
197 }
198 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, return AVERROR(ENOMEM););
199 return 1;
200 }
201
202 ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
203 if (!(channel_layouts = av_malloc_array(ret_max, sizeof(*channel_layouts))))
204 return AVERROR(ENOMEM);
205
206 /* a[known] intersect b[known] */
207 for (i = 0; i < a->nb_channel_layouts; i++) {
208 if (!KNOWN(a->channel_layouts[i]))
209 continue;
210 for (j = 0; j < b->nb_channel_layouts; j++) {
211 if (a->channel_layouts[i] == b->channel_layouts[j]) {
212 channel_layouts[ret_nb++] = a->channel_layouts[i];
213 a->channel_layouts[i] = b->channel_layouts[j] = 0;
214 break;
215 }
216 }
217 }
218 /* 1st round: a[known] intersect b[generic]
219 2nd round: a[generic] intersect b[known] */
220 for (round = 0; round < 2; round++) {
221 for (i = 0; i < a->nb_channel_layouts; i++) {
222 uint64_t fmt = a->channel_layouts[i], bfmt;
223 if (!fmt || !KNOWN(fmt))
224 continue;
225 bfmt = FF_COUNT2LAYOUT(av_get_channel_layout_nb_channels(fmt));
226 for (j = 0; j < b->nb_channel_layouts; j++)
227 if (b->channel_layouts[j] == bfmt)
228 channel_layouts[ret_nb++] = a->channel_layouts[i];
229 }
230 /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
231 FFSWAP(AVFilterChannelLayouts *, a, b);
232 }
233 /* a[generic] intersect b[generic] */
234 for (i = 0; i < a->nb_channel_layouts; i++) {
235 if (KNOWN(a->channel_layouts[i]))
236 continue;
237 for (j = 0; j < b->nb_channel_layouts; j++)
238 if (a->channel_layouts[i] == b->channel_layouts[j])
239 channel_layouts[ret_nb++] = a->channel_layouts[i];
240 }
241
242 if (!ret_nb) {
243 av_free(channel_layouts);
244 return 0;
245 }
246
247 if (a->refcount > b->refcount)
248 FFSWAP(AVFilterChannelLayouts *, a, b);
249
250 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts,
251 { av_free(channel_layouts); return AVERROR(ENOMEM); });
252 av_freep(&b->channel_layouts);
253 b->channel_layouts = channel_layouts;
254 b->nb_channel_layouts = ret_nb;
255 return 1;
256 }
257
ff_fmt_is_in(int fmt,const int * fmts)258 int ff_fmt_is_in(int fmt, const int *fmts)
259 {
260 const int *p;
261
262 for (p = fmts; *p != -1; p++) {
263 if (fmt == *p)
264 return 1;
265 }
266 return 0;
267 }
268
269 #define MAKE_FORMAT_LIST(type, field, count_field) \
270 type *formats; \
271 int count = 0; \
272 if (fmts) \
273 for (count = 0; fmts[count] != -1; count++) \
274 ; \
275 formats = av_mallocz(sizeof(*formats)); \
276 if (!formats) \
277 return NULL; \
278 formats->count_field = count; \
279 if (count) { \
280 formats->field = av_malloc_array(count, sizeof(*formats->field)); \
281 if (!formats->field) { \
282 av_freep(&formats); \
283 return NULL; \
284 } \
285 }
286
ff_make_format_list(const int * fmts)287 AVFilterFormats *ff_make_format_list(const int *fmts)
288 {
289 MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
290 while (count--)
291 formats->formats[count] = fmts[count];
292
293 return formats;
294 }
295
ff_make_format64_list(const int64_t * fmts)296 AVFilterChannelLayouts *ff_make_format64_list(const int64_t *fmts)
297 {
298 MAKE_FORMAT_LIST(AVFilterChannelLayouts,
299 channel_layouts, nb_channel_layouts);
300 if (count)
301 memcpy(formats->channel_layouts, fmts,
302 sizeof(*formats->channel_layouts) * count);
303
304 return formats;
305 }
306
307 #if LIBAVFILTER_VERSION_MAJOR < 8
avfilter_make_format64_list(const int64_t * fmts)308 AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts)
309 {
310 return ff_make_format64_list(fmts);
311 }
312 #endif
313
314 #define ADD_FORMAT(f, fmt, unref_fn, type, list, nb) \
315 do { \
316 type *fmts; \
317 \
318 if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) { \
319 return AVERROR(ENOMEM); \
320 } \
321 \
322 fmts = av_realloc_array((*f)->list, (*f)->nb + 1, \
323 sizeof(*(*f)->list)); \
324 if (!fmts) { \
325 unref_fn(f); \
326 return AVERROR(ENOMEM); \
327 } \
328 \
329 (*f)->list = fmts; \
330 (*f)->list[(*f)->nb++] = fmt; \
331 } while (0)
332
ff_add_format(AVFilterFormats ** avff,int64_t fmt)333 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
334 {
335 ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
336 return 0;
337 }
338
ff_add_channel_layout(AVFilterChannelLayouts ** l,uint64_t channel_layout)339 int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
340 {
341 av_assert1(!(*l && (*l)->all_layouts));
342 ADD_FORMAT(l, channel_layout, ff_channel_layouts_unref, uint64_t, channel_layouts, nb_channel_layouts);
343 return 0;
344 }
345
ff_all_formats(enum AVMediaType type)346 AVFilterFormats *ff_all_formats(enum AVMediaType type)
347 {
348 AVFilterFormats *ret = NULL;
349
350 if (type == AVMEDIA_TYPE_VIDEO) {
351 const AVPixFmtDescriptor *desc = NULL;
352 while ((desc = av_pix_fmt_desc_next(desc))) {
353 if (ff_add_format(&ret, av_pix_fmt_desc_get_id(desc)) < 0)
354 return NULL;
355 }
356 } else if (type == AVMEDIA_TYPE_AUDIO) {
357 enum AVSampleFormat fmt = 0;
358 while (av_get_sample_fmt_name(fmt)) {
359 if (ff_add_format(&ret, fmt) < 0)
360 return NULL;
361 fmt++;
362 }
363 }
364
365 return ret;
366 }
367
ff_formats_pixdesc_filter(AVFilterFormats ** rfmts,unsigned want,unsigned rej)368 int ff_formats_pixdesc_filter(AVFilterFormats **rfmts, unsigned want, unsigned rej)
369 {
370 unsigned nb_formats, fmt, flags;
371 AVFilterFormats *formats = NULL;
372
373 while (1) {
374 nb_formats = 0;
375 for (fmt = 0;; fmt++) {
376 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
377 if (!desc)
378 break;
379 flags = desc->flags;
380 if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
381 !(desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
382 (desc->log2_chroma_w || desc->log2_chroma_h))
383 flags |= FF_PIX_FMT_FLAG_SW_FLAT_SUB;
384 if ((flags & (want | rej)) != want)
385 continue;
386 if (formats)
387 formats->formats[nb_formats] = fmt;
388 nb_formats++;
389 }
390 if (formats) {
391 av_assert0(formats->nb_formats == nb_formats);
392 *rfmts = formats;
393 return 0;
394 }
395 formats = av_mallocz(sizeof(*formats));
396 if (!formats)
397 return AVERROR(ENOMEM);
398 formats->nb_formats = nb_formats;
399 if (nb_formats) {
400 formats->formats = av_malloc_array(nb_formats, sizeof(*formats->formats));
401 if (!formats->formats) {
402 av_freep(&formats);
403 return AVERROR(ENOMEM);
404 }
405 }
406 }
407 }
408
ff_planar_sample_fmts(void)409 AVFilterFormats *ff_planar_sample_fmts(void)
410 {
411 AVFilterFormats *ret = NULL;
412 int fmt;
413
414 for (fmt = 0; av_get_bytes_per_sample(fmt)>0; fmt++)
415 if (av_sample_fmt_is_planar(fmt))
416 if (ff_add_format(&ret, fmt) < 0)
417 return NULL;
418
419 return ret;
420 }
421
ff_all_samplerates(void)422 AVFilterFormats *ff_all_samplerates(void)
423 {
424 AVFilterFormats *ret = av_mallocz(sizeof(*ret));
425 return ret;
426 }
427
ff_all_channel_layouts(void)428 AVFilterChannelLayouts *ff_all_channel_layouts(void)
429 {
430 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
431 if (!ret)
432 return NULL;
433 ret->all_layouts = 1;
434 return ret;
435 }
436
ff_all_channel_counts(void)437 AVFilterChannelLayouts *ff_all_channel_counts(void)
438 {
439 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
440 if (!ret)
441 return NULL;
442 ret->all_layouts = ret->all_counts = 1;
443 return ret;
444 }
445
446 #define FORMATS_REF(f, ref, unref_fn) \
447 void *tmp; \
448 \
449 if (!f) \
450 return AVERROR(ENOMEM); \
451 \
452 tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1); \
453 if (!tmp) { \
454 unref_fn(&f); \
455 return AVERROR(ENOMEM); \
456 } \
457 f->refs = tmp; \
458 f->refs[f->refcount++] = ref; \
459 *ref = f; \
460 return 0
461
ff_channel_layouts_ref(AVFilterChannelLayouts * f,AVFilterChannelLayouts ** ref)462 int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
463 {
464 FORMATS_REF(f, ref, ff_channel_layouts_unref);
465 }
466
ff_formats_ref(AVFilterFormats * f,AVFilterFormats ** ref)467 int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
468 {
469 FORMATS_REF(f, ref, ff_formats_unref);
470 }
471
472 #define FIND_REF_INDEX(ref, idx) \
473 do { \
474 int i; \
475 for (i = 0; i < (*ref)->refcount; i ++) \
476 if((*ref)->refs[i] == ref) { \
477 idx = i; \
478 break; \
479 } \
480 } while (0)
481
482 #define FORMATS_UNREF(ref, list) \
483 do { \
484 int idx = -1; \
485 \
486 if (!*ref) \
487 return; \
488 \
489 FIND_REF_INDEX(ref, idx); \
490 \
491 if (idx >= 0) { \
492 memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
493 sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
494 --(*ref)->refcount; \
495 } \
496 if (!(*ref)->refcount) { \
497 av_free((*ref)->list); \
498 av_free((*ref)->refs); \
499 av_free(*ref); \
500 } \
501 *ref = NULL; \
502 } while (0)
503
ff_formats_unref(AVFilterFormats ** ref)504 void ff_formats_unref(AVFilterFormats **ref)
505 {
506 FORMATS_UNREF(ref, formats);
507 }
508
ff_channel_layouts_unref(AVFilterChannelLayouts ** ref)509 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
510 {
511 FORMATS_UNREF(ref, channel_layouts);
512 }
513
514 #define FORMATS_CHANGEREF(oldref, newref) \
515 do { \
516 int idx = -1; \
517 \
518 FIND_REF_INDEX(oldref, idx); \
519 \
520 if (idx >= 0) { \
521 (*oldref)->refs[idx] = newref; \
522 *newref = *oldref; \
523 *oldref = NULL; \
524 } \
525 } while (0)
526
ff_channel_layouts_changeref(AVFilterChannelLayouts ** oldref,AVFilterChannelLayouts ** newref)527 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
528 AVFilterChannelLayouts **newref)
529 {
530 FORMATS_CHANGEREF(oldref, newref);
531 }
532
ff_formats_changeref(AVFilterFormats ** oldref,AVFilterFormats ** newref)533 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
534 {
535 FORMATS_CHANGEREF(oldref, newref);
536 }
537
538 #define SET_COMMON_FORMATS(ctx, fmts, ref_fn, unref_fn) \
539 int count = 0, i; \
540 \
541 if (!fmts) \
542 return AVERROR(ENOMEM); \
543 \
544 for (i = 0; i < ctx->nb_inputs; i++) { \
545 if (ctx->inputs[i] && !ctx->inputs[i]->outcfg.fmts) { \
546 int ret = ref_fn(fmts, &ctx->inputs[i]->outcfg.fmts); \
547 if (ret < 0) { \
548 return ret; \
549 } \
550 count++; \
551 } \
552 } \
553 for (i = 0; i < ctx->nb_outputs; i++) { \
554 if (ctx->outputs[i] && !ctx->outputs[i]->incfg.fmts) { \
555 int ret = ref_fn(fmts, &ctx->outputs[i]->incfg.fmts); \
556 if (ret < 0) { \
557 return ret; \
558 } \
559 count++; \
560 } \
561 } \
562 \
563 if (!count) { \
564 unref_fn(&fmts); \
565 } \
566 \
567 return 0;
568
ff_set_common_channel_layouts(AVFilterContext * ctx,AVFilterChannelLayouts * channel_layouts)569 int ff_set_common_channel_layouts(AVFilterContext *ctx,
570 AVFilterChannelLayouts *channel_layouts)
571 {
572 SET_COMMON_FORMATS(ctx, channel_layouts,
573 ff_channel_layouts_ref, ff_channel_layouts_unref);
574 }
575
ff_set_common_samplerates(AVFilterContext * ctx,AVFilterFormats * samplerates)576 int ff_set_common_samplerates(AVFilterContext *ctx,
577 AVFilterFormats *samplerates)
578 {
579 SET_COMMON_FORMATS(ctx, samplerates,
580 ff_formats_ref, ff_formats_unref);
581 }
582
583 /**
584 * A helper for query_formats() which sets all links to the same list of
585 * formats. If there are no links hooked to this filter, the list of formats is
586 * freed.
587 */
ff_set_common_formats(AVFilterContext * ctx,AVFilterFormats * formats)588 int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
589 {
590 SET_COMMON_FORMATS(ctx, formats,
591 ff_formats_ref, ff_formats_unref);
592 }
593
ff_default_query_formats(AVFilterContext * ctx)594 int ff_default_query_formats(AVFilterContext *ctx)
595 {
596 int ret;
597 enum AVMediaType type = ctx->nb_inputs ? ctx->inputs [0]->type :
598 ctx->nb_outputs ? ctx->outputs[0]->type :
599 AVMEDIA_TYPE_VIDEO;
600
601 ret = ff_set_common_formats(ctx, ff_all_formats(type));
602 if (ret < 0)
603 return ret;
604 if (type == AVMEDIA_TYPE_AUDIO) {
605 ret = ff_set_common_channel_layouts(ctx, ff_all_channel_counts());
606 if (ret < 0)
607 return ret;
608 ret = ff_set_common_samplerates(ctx, ff_all_samplerates());
609 if (ret < 0)
610 return ret;
611 }
612
613 return 0;
614 }
615
616 /* internal functions for parsing audio format arguments */
617
ff_parse_pixel_format(enum AVPixelFormat * ret,const char * arg,void * log_ctx)618 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
619 {
620 char *tail;
621 int pix_fmt = av_get_pix_fmt(arg);
622 if (pix_fmt == AV_PIX_FMT_NONE) {
623 pix_fmt = strtol(arg, &tail, 0);
624 if (*tail || !av_pix_fmt_desc_get(pix_fmt)) {
625 av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
626 return AVERROR(EINVAL);
627 }
628 }
629 *ret = pix_fmt;
630 return 0;
631 }
632
ff_parse_sample_rate(int * ret,const char * arg,void * log_ctx)633 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
634 {
635 char *tail;
636 double srate = av_strtod(arg, &tail);
637 if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
638 av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
639 return AVERROR(EINVAL);
640 }
641 *ret = srate;
642 return 0;
643 }
644
ff_parse_channel_layout(int64_t * ret,int * nret,const char * arg,void * log_ctx)645 int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
646 void *log_ctx)
647 {
648 int64_t chlayout;
649 int nb_channels;
650
651 if (av_get_extended_channel_layout(arg, &chlayout, &nb_channels) < 0) {
652 av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
653 return AVERROR(EINVAL);
654 }
655 if (!chlayout && !nret) {
656 av_log(log_ctx, AV_LOG_ERROR, "Unknown channel layout '%s' is not supported.\n", arg);
657 return AVERROR(EINVAL);
658 }
659 *ret = chlayout;
660 if (nret)
661 *nret = nb_channels;
662
663 return 0;
664 }
665
check_list(void * log,const char * name,const AVFilterFormats * fmts)666 static int check_list(void *log, const char *name, const AVFilterFormats *fmts)
667 {
668 unsigned i, j;
669
670 if (!fmts)
671 return 0;
672 if (!fmts->nb_formats) {
673 av_log(log, AV_LOG_ERROR, "Empty %s list\n", name);
674 return AVERROR(EINVAL);
675 }
676 for (i = 0; i < fmts->nb_formats; i++) {
677 for (j = i + 1; j < fmts->nb_formats; j++) {
678 if (fmts->formats[i] == fmts->formats[j]) {
679 av_log(log, AV_LOG_ERROR, "Duplicated %s\n", name);
680 return AVERROR(EINVAL);
681 }
682 }
683 }
684 return 0;
685 }
686
ff_formats_check_pixel_formats(void * log,const AVFilterFormats * fmts)687 int ff_formats_check_pixel_formats(void *log, const AVFilterFormats *fmts)
688 {
689 return check_list(log, "pixel format", fmts);
690 }
691
ff_formats_check_sample_formats(void * log,const AVFilterFormats * fmts)692 int ff_formats_check_sample_formats(void *log, const AVFilterFormats *fmts)
693 {
694 return check_list(log, "sample format", fmts);
695 }
696
ff_formats_check_sample_rates(void * log,const AVFilterFormats * fmts)697 int ff_formats_check_sample_rates(void *log, const AVFilterFormats *fmts)
698 {
699 if (!fmts || !fmts->nb_formats)
700 return 0;
701 return check_list(log, "sample rate", fmts);
702 }
703
layouts_compatible(uint64_t a,uint64_t b)704 static int layouts_compatible(uint64_t a, uint64_t b)
705 {
706 return a == b ||
707 (KNOWN(a) && !KNOWN(b) && av_get_channel_layout_nb_channels(a) == FF_LAYOUT2COUNT(b)) ||
708 (KNOWN(b) && !KNOWN(a) && av_get_channel_layout_nb_channels(b) == FF_LAYOUT2COUNT(a));
709 }
710
ff_formats_check_channel_layouts(void * log,const AVFilterChannelLayouts * fmts)711 int ff_formats_check_channel_layouts(void *log, const AVFilterChannelLayouts *fmts)
712 {
713 unsigned i, j;
714
715 if (!fmts)
716 return 0;
717 if (fmts->all_layouts < fmts->all_counts) {
718 av_log(log, AV_LOG_ERROR, "Inconsistent generic list\n");
719 return AVERROR(EINVAL);
720 }
721 if (!fmts->all_layouts && !fmts->nb_channel_layouts) {
722 av_log(log, AV_LOG_ERROR, "Empty channel layout list\n");
723 return AVERROR(EINVAL);
724 }
725 for (i = 0; i < fmts->nb_channel_layouts; i++) {
726 for (j = i + 1; j < fmts->nb_channel_layouts; j++) {
727 if (layouts_compatible(fmts->channel_layouts[i], fmts->channel_layouts[j])) {
728 av_log(log, AV_LOG_ERROR, "Duplicated or redundant channel layout\n");
729 return AVERROR(EINVAL);
730 }
731 }
732 }
733 return 0;
734 }
735