]> git.sesse.net Git - ffmpeg/blob - libavfilter/formats.c
avfilter/formats: Fix heap-buffer overflow 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)                                \
52 do {                                                                       \
53     type ***tmp;                                                           \
54                                                                            \
55     if (!(tmp = av_realloc_array(ret->refs, ret->refcount + a->refcount,   \
56                                  sizeof(*tmp))))                           \
57         goto fail;                                                         \
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, fail);
161         ret = a;
162     } else {
163         MERGE_REF(b, a, formats, AVFilterFormats, fail);
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     AVFilterChannelLayouts *ret = NULL;
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, fail);
205         return b;
206     }
207
208     ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
209     if (!(ret = av_mallocz(sizeof(*ret))) ||
210         !(ret->channel_layouts = av_malloc_array(ret_max,
211                                                  sizeof(*ret->channel_layouts))))
212         goto fail;
213
214     /* a[known] intersect b[known] */
215     for (i = 0; i < a->nb_channel_layouts; i++) {
216         if (!KNOWN(a->channel_layouts[i]))
217             continue;
218         for (j = 0; j < b->nb_channel_layouts; j++) {
219             if (a->channel_layouts[i] == b->channel_layouts[j]) {
220                 ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
221                 a->channel_layouts[i] = b->channel_layouts[j] = 0;
222                 break;
223             }
224         }
225     }
226     /* 1st round: a[known] intersect b[generic]
227        2nd round: a[generic] intersect b[known] */
228     for (round = 0; round < 2; round++) {
229         for (i = 0; i < a->nb_channel_layouts; i++) {
230             uint64_t fmt = a->channel_layouts[i], bfmt;
231             if (!fmt || !KNOWN(fmt))
232                 continue;
233             bfmt = FF_COUNT2LAYOUT(av_get_channel_layout_nb_channels(fmt));
234             for (j = 0; j < b->nb_channel_layouts; j++)
235                 if (b->channel_layouts[j] == bfmt)
236                     ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
237         }
238         /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
239         FFSWAP(AVFilterChannelLayouts *, a, b);
240     }
241     /* a[generic] intersect b[generic] */
242     for (i = 0; i < a->nb_channel_layouts; i++) {
243         if (KNOWN(a->channel_layouts[i]))
244             continue;
245         for (j = 0; j < b->nb_channel_layouts; j++)
246             if (a->channel_layouts[i] == b->channel_layouts[j])
247                 ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
248     }
249
250     ret->nb_channel_layouts = ret_nb;
251     if (!ret->nb_channel_layouts)
252         goto fail;
253
254     ret->refs = av_realloc_array(NULL, a->refcount + b->refcount,
255                                  sizeof(*ret->refs));
256     if (!ret->refs)
257         goto fail;
258     MERGE_REF_NO_ALLOC(ret, a, channel_layouts);
259     MERGE_REF_NO_ALLOC(ret, b, channel_layouts);
260     return ret;
261
262 fail:
263     if (ret) {
264         av_assert1(!ret->refs);
265         av_freep(&ret->channel_layouts);
266         av_freep(&ret);
267     }
268     return NULL;
269 }
270
271 int ff_fmt_is_in(int fmt, const int *fmts)
272 {
273     const int *p;
274
275     for (p = fmts; *p != -1; p++) {
276         if (fmt == *p)
277             return 1;
278     }
279     return 0;
280 }
281
282 #define MAKE_FORMAT_LIST(type, field, count_field)                      \
283     type *formats;                                                      \
284     int count = 0;                                                      \
285     if (fmts)                                                           \
286         for (count = 0; fmts[count] != -1; count++)                     \
287             ;                                                           \
288     formats = av_mallocz(sizeof(*formats));                             \
289     if (!formats)                                                       \
290         return NULL;                                                    \
291     formats->count_field = count;                                       \
292     if (count) {                                                        \
293         formats->field = av_malloc_array(count, sizeof(*formats->field));      \
294         if (!formats->field) {                                          \
295             av_freep(&formats);                                         \
296             return NULL;                                                \
297         }                                                               \
298     }
299
300 AVFilterFormats *ff_make_format_list(const int *fmts)
301 {
302     MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
303     while (count--)
304         formats->formats[count] = fmts[count];
305
306     return formats;
307 }
308
309 AVFilterChannelLayouts *ff_make_format64_list(const int64_t *fmts)
310 {
311     MAKE_FORMAT_LIST(AVFilterChannelLayouts,
312                      channel_layouts, nb_channel_layouts);
313     if (count)
314         memcpy(formats->channel_layouts, fmts,
315                sizeof(*formats->channel_layouts) * count);
316
317     return formats;
318 }
319
320 #if LIBAVFILTER_VERSION_MAJOR < 8
321 AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts)
322 {
323     return ff_make_format64_list(fmts);
324 }
325 #endif
326
327 #define ADD_FORMAT(f, fmt, unref_fn, type, list, nb)        \
328 do {                                                        \
329     type *fmts;                                             \
330     void *oldf = *f;                                        \
331                                                             \
332     if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) {         \
333         return AVERROR(ENOMEM);                             \
334     }                                                       \
335                                                             \
336     fmts = av_realloc_array((*f)->list, (*f)->nb + 1,       \
337                             sizeof(*(*f)->list));           \
338     if (!fmts) {                                            \
339         unref_fn(f);                                        \
340         if (!oldf)                                          \
341             av_freep(f);                                    \
342         return AVERROR(ENOMEM);                             \
343     }                                                       \
344                                                             \
345     (*f)->list = fmts;                                      \
346     (*f)->list[(*f)->nb++] = fmt;                           \
347 } while (0)
348
349 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
350 {
351     ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
352     return 0;
353 }
354
355 int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
356 {
357     av_assert1(!(*l && (*l)->all_layouts));
358     ADD_FORMAT(l, channel_layout, ff_channel_layouts_unref, uint64_t, channel_layouts, nb_channel_layouts);
359     return 0;
360 }
361
362 AVFilterFormats *ff_all_formats(enum AVMediaType type)
363 {
364     AVFilterFormats *ret = NULL;
365
366     if (type == AVMEDIA_TYPE_VIDEO) {
367         const AVPixFmtDescriptor *desc = NULL;
368         while ((desc = av_pix_fmt_desc_next(desc))) {
369             if (ff_add_format(&ret, av_pix_fmt_desc_get_id(desc)) < 0)
370                 return NULL;
371         }
372     } else if (type == AVMEDIA_TYPE_AUDIO) {
373         enum AVSampleFormat fmt = 0;
374         while (av_get_sample_fmt_name(fmt)) {
375             if (ff_add_format(&ret, fmt) < 0)
376                 return NULL;
377             fmt++;
378         }
379     }
380
381     return ret;
382 }
383
384 int ff_formats_pixdesc_filter(AVFilterFormats **rfmts, unsigned want, unsigned rej)
385 {
386     unsigned nb_formats, fmt, flags;
387     AVFilterFormats *formats = NULL;
388
389     while (1) {
390         nb_formats = 0;
391         for (fmt = 0;; fmt++) {
392             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
393             if (!desc)
394                 break;
395             flags = desc->flags;
396             if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
397                 !(desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
398                 (desc->log2_chroma_w || desc->log2_chroma_h))
399                 flags |= FF_PIX_FMT_FLAG_SW_FLAT_SUB;
400             if ((flags & (want | rej)) != want)
401                 continue;
402             if (formats)
403                 formats->formats[nb_formats] = fmt;
404             nb_formats++;
405         }
406         if (formats) {
407             av_assert0(formats->nb_formats == nb_formats);
408             *rfmts = formats;
409             return 0;
410         }
411         formats = av_mallocz(sizeof(*formats));
412         if (!formats)
413             return AVERROR(ENOMEM);
414         formats->nb_formats = nb_formats;
415         if (nb_formats) {
416             formats->formats = av_malloc_array(nb_formats, sizeof(*formats->formats));
417             if (!formats->formats) {
418                 av_freep(&formats);
419                 return AVERROR(ENOMEM);
420             }
421         }
422     }
423 }
424
425 AVFilterFormats *ff_planar_sample_fmts(void)
426 {
427     AVFilterFormats *ret = NULL;
428     int fmt;
429
430     for (fmt = 0; av_get_bytes_per_sample(fmt)>0; fmt++)
431         if (av_sample_fmt_is_planar(fmt))
432             if (ff_add_format(&ret, fmt) < 0)
433                 return NULL;
434
435     return ret;
436 }
437
438 AVFilterFormats *ff_all_samplerates(void)
439 {
440     AVFilterFormats *ret = av_mallocz(sizeof(*ret));
441     return ret;
442 }
443
444 AVFilterChannelLayouts *ff_all_channel_layouts(void)
445 {
446     AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
447     if (!ret)
448         return NULL;
449     ret->all_layouts = 1;
450     return ret;
451 }
452
453 AVFilterChannelLayouts *ff_all_channel_counts(void)
454 {
455     AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
456     if (!ret)
457         return NULL;
458     ret->all_layouts = ret->all_counts = 1;
459     return ret;
460 }
461
462 #define FORMATS_REF(f, ref, unref_fn)                                           \
463     void *tmp;                                                                  \
464                                                                                 \
465     if (!f || !ref)                                                             \
466         return AVERROR(ENOMEM);                                                 \
467                                                                                 \
468     tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1);         \
469     if (!tmp) {                                                                 \
470         unref_fn(&f);                                                           \
471         return AVERROR(ENOMEM);                                                 \
472     }                                                                           \
473     f->refs = tmp;                                                              \
474     f->refs[f->refcount++] = ref;                                               \
475     *ref = f;                                                                   \
476     return 0
477
478 int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
479 {
480     FORMATS_REF(f, ref, ff_channel_layouts_unref);
481 }
482
483 int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
484 {
485     FORMATS_REF(f, ref, ff_formats_unref);
486 }
487
488 #define FIND_REF_INDEX(ref, idx)            \
489 do {                                        \
490     int i;                                  \
491     for (i = 0; i < (*ref)->refcount; i ++) \
492         if((*ref)->refs[i] == ref) {        \
493             idx = i;                        \
494             break;                          \
495         }                                   \
496 } while (0)
497
498 #define FORMATS_UNREF(ref, list)                                   \
499 do {                                                               \
500     int idx = -1;                                                  \
501                                                                    \
502     if (!ref || !*ref || !(*ref)->refs)                            \
503         return;                                                    \
504                                                                    \
505     FIND_REF_INDEX(ref, idx);                                      \
506                                                                    \
507     if (idx >= 0)                                                  \
508         memmove((*ref)->refs + idx, (*ref)->refs + idx + 1,        \
509             sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
510                                                                    \
511     if(!--(*ref)->refcount) {                                      \
512         av_free((*ref)->list);                                     \
513         av_free((*ref)->refs);                                     \
514         av_free(*ref);                                             \
515     }                                                              \
516     *ref = NULL;                                                   \
517 } while (0)
518
519 void ff_formats_unref(AVFilterFormats **ref)
520 {
521     FORMATS_UNREF(ref, formats);
522 }
523
524 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
525 {
526     FORMATS_UNREF(ref, channel_layouts);
527 }
528
529 #define FORMATS_CHANGEREF(oldref, newref)       \
530 do {                                            \
531     int idx = -1;                               \
532                                                 \
533     FIND_REF_INDEX(oldref, idx);                \
534                                                 \
535     if (idx >= 0) {                             \
536         (*oldref)->refs[idx] = newref;          \
537         *newref = *oldref;                      \
538         *oldref = NULL;                         \
539     }                                           \
540 } while (0)
541
542 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
543                                   AVFilterChannelLayouts **newref)
544 {
545     FORMATS_CHANGEREF(oldref, newref);
546 }
547
548 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
549 {
550     FORMATS_CHANGEREF(oldref, newref);
551 }
552
553 #define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref_fn, unref_fn, list) \
554     int count = 0, i;                                               \
555                                                                     \
556     if (!fmts)                                                      \
557         return AVERROR(ENOMEM);                                     \
558                                                                     \
559     for (i = 0; i < ctx->nb_inputs; i++) {                          \
560         if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) {          \
561             int ret = ref_fn(fmts, &ctx->inputs[i]->out_fmts);      \
562             if (ret < 0) {                                          \
563                 unref_fn(&fmts);                                    \
564                 if (fmts)                                           \
565                     av_freep(&fmts->list);                          \
566                 av_freep(&fmts);                                    \
567                 return ret;                                         \
568             }                                                       \
569             count++;                                                \
570         }                                                           \
571     }                                                               \
572     for (i = 0; i < ctx->nb_outputs; i++) {                         \
573         if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) {         \
574             int ret = ref_fn(fmts, &ctx->outputs[i]->in_fmts);      \
575             if (ret < 0) {                                          \
576                 unref_fn(&fmts);                                    \
577                 if (fmts)                                           \
578                     av_freep(&fmts->list);                          \
579                 av_freep(&fmts);                                    \
580                 return ret;                                         \
581             }                                                       \
582             count++;                                                \
583         }                                                           \
584     }                                                               \
585                                                                     \
586     if (!count) {                                                   \
587         av_freep(&fmts->list);                                      \
588         av_freep(&fmts->refs);                                      \
589         av_freep(&fmts);                                            \
590     }                                                               \
591                                                                     \
592     return 0;
593
594 int ff_set_common_channel_layouts(AVFilterContext *ctx,
595                                   AVFilterChannelLayouts *layouts)
596 {
597     SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
598                        ff_channel_layouts_ref, ff_channel_layouts_unref, channel_layouts);
599 }
600
601 int ff_set_common_samplerates(AVFilterContext *ctx,
602                               AVFilterFormats *samplerates)
603 {
604     SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
605                        ff_formats_ref, ff_formats_unref, formats);
606 }
607
608 /**
609  * A helper for query_formats() which sets all links to the same list of
610  * formats. If there are no links hooked to this filter, the list of formats is
611  * freed.
612  */
613 int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
614 {
615     SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
616                        ff_formats_ref, ff_formats_unref, formats);
617 }
618
619 static int default_query_formats_common(AVFilterContext *ctx,
620                                         AVFilterChannelLayouts *(layouts)(void))
621 {
622     int ret;
623     enum AVMediaType type = ctx->inputs  && ctx->inputs [0] ? ctx->inputs [0]->type :
624                             ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
625                             AVMEDIA_TYPE_VIDEO;
626
627     ret = ff_set_common_formats(ctx, ff_all_formats(type));
628     if (ret < 0)
629         return ret;
630     if (type == AVMEDIA_TYPE_AUDIO) {
631         ret = ff_set_common_channel_layouts(ctx, layouts());
632         if (ret < 0)
633             return ret;
634         ret = ff_set_common_samplerates(ctx, ff_all_samplerates());
635         if (ret < 0)
636             return ret;
637     }
638
639     return 0;
640 }
641
642 int ff_default_query_formats(AVFilterContext *ctx)
643 {
644     return default_query_formats_common(ctx, ff_all_channel_counts);
645 }
646
647 int ff_query_formats_all_layouts(AVFilterContext *ctx)
648 {
649     return default_query_formats_common(ctx, ff_all_channel_layouts);
650 }
651
652 /* internal functions for parsing audio format arguments */
653
654 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
655 {
656     char *tail;
657     int pix_fmt = av_get_pix_fmt(arg);
658     if (pix_fmt == AV_PIX_FMT_NONE) {
659         pix_fmt = strtol(arg, &tail, 0);
660         if (*tail || !av_pix_fmt_desc_get(pix_fmt)) {
661             av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
662             return AVERROR(EINVAL);
663         }
664     }
665     *ret = pix_fmt;
666     return 0;
667 }
668
669 int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
670 {
671     char *tail;
672     int sfmt = av_get_sample_fmt(arg);
673     if (sfmt == AV_SAMPLE_FMT_NONE) {
674         sfmt = strtol(arg, &tail, 0);
675         if (*tail || av_get_bytes_per_sample(sfmt)<=0) {
676             av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
677             return AVERROR(EINVAL);
678         }
679     }
680     *ret = sfmt;
681     return 0;
682 }
683
684 int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
685 {
686     AVRational r;
687     if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0  ||r.den<=0) {
688         av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
689         return AVERROR(EINVAL);
690     }
691     *ret = r;
692     return 0;
693 }
694
695 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
696 {
697     char *tail;
698     double srate = av_strtod(arg, &tail);
699     if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
700         av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
701         return AVERROR(EINVAL);
702     }
703     *ret = srate;
704     return 0;
705 }
706
707 int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
708                             void *log_ctx)
709 {
710     int64_t chlayout;
711     int nb_channels;
712
713     if (av_get_extended_channel_layout(arg, &chlayout, &nb_channels) < 0) {
714         av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
715         return AVERROR(EINVAL);
716     }
717     if (!chlayout && !nret) {
718         av_log(log_ctx, AV_LOG_ERROR, "Unknown channel layout '%s' is not supported.\n", arg);
719         return AVERROR(EINVAL);
720     }
721     *ret = chlayout;
722     if (nret)
723         *nret = nb_channels;
724
725     return 0;
726 }