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