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