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