• 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 /**
32  * Add all refs from a to ret and destroy a.
33  */
34 #define MERGE_REF(ret, a, fmts, type, fail_statement)                      \
35 do {                                                                       \
36     type ***tmp;                                                           \
37     int i;                                                                 \
38                                                                            \
39     if (!(tmp = av_realloc_array(ret->refs, ret->refcount + a->refcount,   \
40                                  sizeof(*tmp))))                           \
41         { fail_statement }                                                 \
42     ret->refs = tmp;                                                       \
43                                                                            \
44     for (i = 0; i < a->refcount; i ++) {                                   \
45         ret->refs[ret->refcount] = a->refs[i];                             \
46         *ret->refs[ret->refcount++] = ret;                                 \
47     }                                                                      \
48                                                                            \
49     av_freep(&a->refs);                                                    \
50     av_freep(&a->fmts);                                                    \
51     av_freep(&a);                                                          \
52 } while (0)
53 
54 /**
55  * Add all formats common to a and b to a, add b's refs to a and destroy b.
56  * If check is set, nothing is modified and it is only checked whether
57  * the formats are compatible.
58  * If empty_allowed is set and one of a,b->nb is zero, the lists are
59  * merged; otherwise, 0 (for nonmergeability) is returned.
60  */
61 #define MERGE_FORMATS(a, b, fmts, nb, type, check, empty_allowed)          \
62 do {                                                                       \
63     int i, j, k = 0, skip = 0;                                             \
64                                                                            \
65     if (empty_allowed) {                                                   \
66         if (!a->nb || !b->nb) {                                            \
67             if (check)                                                     \
68                 return 1;                                                  \
69             if (!a->nb)                                                    \
70                 FFSWAP(type *, a, b);                                      \
71             skip = 1;                                                      \
72         }                                                                  \
73     }                                                                      \
74     if (!skip) {                                                           \
75         for (i = 0; i < a->nb; i++)                                        \
76             for (j = 0; j < b->nb; j++)                                    \
77                 if (a->fmts[i] == b->fmts[j]) {                            \
78                     if (check)                                             \
79                         return 1;                                          \
80                     a->fmts[k++] = a->fmts[i];                             \
81                     break;                                                 \
82                 }                                                          \
83         /* Check that there was at least one common format.                \
84          * Notice that both a and b are unchanged if not. */               \
85         if (!k)                                                            \
86             return 0;                                                      \
87         av_assert2(!check);                                                \
88         a->nb = k;                                                         \
89     }                                                                      \
90                                                                            \
91     MERGE_REF(a, b, fmts, type, return AVERROR(ENOMEM););                  \
92 } while (0)
93 
merge_formats_internal(AVFilterFormats * a,AVFilterFormats * b,enum AVMediaType type,int check)94 static int merge_formats_internal(AVFilterFormats *a, AVFilterFormats *b,
95                                   enum AVMediaType type, int check)
96 {
97     int i, j;
98     int alpha1=0, alpha2=0;
99     int chroma1=0, chroma2=0;
100 
101     av_assert2(check || (a->refcount && b->refcount));
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             const AVPixFmtDescriptor *const adesc = av_pix_fmt_desc_get(a->formats[i]);
116             for (j = 0; j < b->nb_formats; j++) {
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 
127     // If chroma or alpha can be lost through merging then do not merge
128     if (alpha2 > alpha1 || chroma2 > chroma1)
129         return 0;
130 
131     MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 0);
132 
133     return 1;
134 }
135 
136 
137 /**
138  * Check the formats lists for compatibility for merging without actually
139  * merging.
140  *
141  * @return 1 if they are compatible, 0 if not.
142  */
can_merge_pix_fmts(const void * a,const void * b)143 static int can_merge_pix_fmts(const void *a, const void *b)
144 {
145     return merge_formats_internal((AVFilterFormats *)a,
146                                   (AVFilterFormats *)b, AVMEDIA_TYPE_VIDEO, 1);
147 }
148 
149 /**
150  * Merge the formats lists if they are compatible and update all the
151  * references of a and b to point to the combined list and free the old
152  * lists as needed. The combined list usually contains the intersection of
153  * the lists of a and b.
154  *
155  * Both a and b must have owners (i.e. refcount > 0) for these functions.
156  *
157  * @return 1 if merging succeeded, 0 if a and b are incompatible
158  *         and negative AVERROR code on failure.
159  *         a and b are unmodified if 0 is returned.
160  */
merge_pix_fmts(void * a,void * b)161 static int merge_pix_fmts(void *a, void *b)
162 {
163     return merge_formats_internal(a, b, AVMEDIA_TYPE_VIDEO, 0);
164 }
165 
166 /**
167  * See can_merge_pix_fmts().
168  */
can_merge_sample_fmts(const void * a,const void * b)169 static int can_merge_sample_fmts(const void *a, const void *b)
170 {
171     return merge_formats_internal((AVFilterFormats *)a,
172                                   (AVFilterFormats *)b, AVMEDIA_TYPE_AUDIO, 1);
173 }
174 
175 /**
176  * See merge_pix_fmts().
177  */
merge_sample_fmts(void * a,void * b)178 static int merge_sample_fmts(void *a, void *b)
179 {
180     return merge_formats_internal(a, b, AVMEDIA_TYPE_AUDIO, 0);
181 }
182 
merge_samplerates_internal(AVFilterFormats * a,AVFilterFormats * b,int check)183 static int merge_samplerates_internal(AVFilterFormats *a,
184                                       AVFilterFormats *b, int check)
185 {
186     av_assert2(check || (a->refcount && b->refcount));
187     if (a == b) return 1;
188 
189     MERGE_FORMATS(a, b, formats, nb_formats, AVFilterFormats, check, 1);
190     return 1;
191 }
192 
193 /**
194  * See can_merge_pix_fmts().
195  */
can_merge_samplerates(const void * a,const void * b)196 static int can_merge_samplerates(const void *a, const void *b)
197 {
198     return merge_samplerates_internal((AVFilterFormats *)a, (AVFilterFormats *)b, 1);
199 }
200 
201 /**
202  * See merge_pix_fmts().
203  */
merge_samplerates(void * a,void * b)204 static int merge_samplerates(void *a, void *b)
205 {
206     return merge_samplerates_internal(a, b, 0);
207 }
208 
209 /**
210  * See merge_pix_fmts().
211  */
merge_channel_layouts(void * va,void * vb)212 static int merge_channel_layouts(void *va, void *vb)
213 {
214     AVFilterChannelLayouts *a = va;
215     AVFilterChannelLayouts *b = vb;
216     AVChannelLayout *channel_layouts;
217     unsigned a_all = a->all_layouts + a->all_counts;
218     unsigned b_all = b->all_layouts + b->all_counts;
219     int ret_max, ret_nb = 0, i, j, round;
220 
221     av_assert2(a->refcount && b->refcount);
222 
223     if (a == b) return 1;
224 
225     /* Put the most generic set in a, to avoid doing everything twice */
226     if (a_all < b_all) {
227         FFSWAP(AVFilterChannelLayouts *, a, b);
228         FFSWAP(unsigned, a_all, b_all);
229     }
230     if (a_all) {
231         if (a_all == 1 && !b_all) {
232             /* keep only known layouts in b; works also for b_all = 1 */
233             for (i = j = 0; i < b->nb_channel_layouts; i++)
234                 if (KNOWN(&b->channel_layouts[i]) && i != j++)
235                     av_channel_layout_copy(&b->channel_layouts[j], &b->channel_layouts[i]);
236             /* Not optimal: the unknown layouts of b may become known after
237                another merge. */
238             if (!j)
239                 return 0;
240             b->nb_channel_layouts = j;
241         }
242         MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, return AVERROR(ENOMEM););
243         return 1;
244     }
245 
246     ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
247     if (!(channel_layouts = av_calloc(ret_max, sizeof(*channel_layouts))))
248         return AVERROR(ENOMEM);
249 
250     /* a[known] intersect b[known] */
251     for (i = 0; i < a->nb_channel_layouts; i++) {
252         if (!KNOWN(&a->channel_layouts[i]))
253             continue;
254         for (j = 0; j < b->nb_channel_layouts; j++) {
255             if (!av_channel_layout_compare(&a->channel_layouts[i], &b->channel_layouts[j])) {
256                 av_channel_layout_copy(&channel_layouts[ret_nb++], &a->channel_layouts[i]);
257                 av_channel_layout_uninit(&a->channel_layouts[i]);
258                 av_channel_layout_uninit(&b->channel_layouts[j]);
259                 break;
260             }
261         }
262     }
263     /* 1st round: a[known] intersect b[generic]
264        2nd round: a[generic] intersect b[known] */
265     for (round = 0; round < 2; round++) {
266         for (i = 0; i < a->nb_channel_layouts; i++) {
267             AVChannelLayout *fmt = &a->channel_layouts[i], bfmt = { 0 };
268             if (!av_channel_layout_check(fmt) || !KNOWN(fmt))
269                 continue;
270             bfmt = FF_COUNT2LAYOUT(fmt->nb_channels);
271             for (j = 0; j < b->nb_channel_layouts; j++)
272                 if (!av_channel_layout_compare(&b->channel_layouts[j], &bfmt))
273                     av_channel_layout_copy(&channel_layouts[ret_nb++], fmt);
274         }
275         /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
276         FFSWAP(AVFilterChannelLayouts *, a, b);
277     }
278     /* a[generic] intersect b[generic] */
279     for (i = 0; i < a->nb_channel_layouts; i++) {
280         if (KNOWN(&a->channel_layouts[i]))
281             continue;
282         for (j = 0; j < b->nb_channel_layouts; j++)
283             if (!av_channel_layout_compare(&a->channel_layouts[i], &b->channel_layouts[j]))
284                 av_channel_layout_copy(&channel_layouts[ret_nb++], &a->channel_layouts[i]);
285     }
286 
287     if (!ret_nb) {
288         av_free(channel_layouts);
289         return 0;
290     }
291 
292     if (a->refcount > b->refcount)
293         FFSWAP(AVFilterChannelLayouts *, a, b);
294 
295     MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts,
296               { av_free(channel_layouts); return AVERROR(ENOMEM); });
297     av_freep(&b->channel_layouts);
298     b->channel_layouts    = channel_layouts;
299     b->nb_channel_layouts = ret_nb;
300     return 1;
301 }
302 
303 static const AVFilterFormatsMerger mergers_video[] = {
304     {
305         .offset     = offsetof(AVFilterFormatsConfig, formats),
306         .merge      = merge_pix_fmts,
307         .can_merge  = can_merge_pix_fmts,
308     },
309 };
310 
311 static const AVFilterFormatsMerger mergers_audio[] = {
312     {
313         .offset     = offsetof(AVFilterFormatsConfig, channel_layouts),
314         .merge      = merge_channel_layouts,
315         .can_merge  = NULL,
316     },
317     {
318         .offset     = offsetof(AVFilterFormatsConfig, samplerates),
319         .merge      = merge_samplerates,
320         .can_merge  = can_merge_samplerates,
321     },
322     {
323         .offset     = offsetof(AVFilterFormatsConfig, formats),
324         .merge      = merge_sample_fmts,
325         .can_merge  = can_merge_sample_fmts,
326     },
327 };
328 
329 static const AVFilterNegotiation negotiate_video = {
330     .nb_mergers = FF_ARRAY_ELEMS(mergers_video),
331     .mergers = mergers_video,
332     .conversion_filter = "scale",
333     .conversion_opts_offset = offsetof(AVFilterGraph, scale_sws_opts),
334 };
335 
336 static const AVFilterNegotiation negotiate_audio = {
337     .nb_mergers = FF_ARRAY_ELEMS(mergers_audio),
338     .mergers = mergers_audio,
339     .conversion_filter = "aresample",
340     .conversion_opts_offset = offsetof(AVFilterGraph, aresample_swr_opts),
341 };
342 
ff_filter_get_negotiation(AVFilterLink * link)343 const AVFilterNegotiation *ff_filter_get_negotiation(AVFilterLink *link)
344 {
345     switch (link->type) {
346     case AVMEDIA_TYPE_VIDEO: return &negotiate_video;
347     case AVMEDIA_TYPE_AUDIO: return &negotiate_audio;
348     default: return NULL;
349     }
350 }
351 
ff_fmt_is_in(int fmt,const int * fmts)352 int ff_fmt_is_in(int fmt, const int *fmts)
353 {
354     const int *p;
355 
356     for (p = fmts; *p != -1; p++) {
357         if (fmt == *p)
358             return 1;
359     }
360     return 0;
361 }
362 
363 #define MAKE_FORMAT_LIST(type, field, count_field)                      \
364     type *formats;                                                      \
365     int count = 0;                                                      \
366     if (fmts)                                                           \
367         for (count = 0; fmts[count] != -1; count++)                     \
368             ;                                                           \
369     formats = av_mallocz(sizeof(*formats));                             \
370     if (!formats)                                                       \
371         return NULL;                                                    \
372     formats->count_field = count;                                       \
373     if (count) {                                                        \
374         formats->field = av_malloc_array(count, sizeof(*formats->field));      \
375         if (!formats->field) {                                          \
376             av_freep(&formats);                                         \
377             return NULL;                                                \
378         }                                                               \
379     }
380 
ff_make_format_list(const int * fmts)381 AVFilterFormats *ff_make_format_list(const int *fmts)
382 {
383     MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
384     while (count--)
385         formats->formats[count] = fmts[count];
386 
387     return formats;
388 }
389 
ff_make_channel_layout_list(const AVChannelLayout * fmts)390 AVFilterChannelLayouts *ff_make_channel_layout_list(const AVChannelLayout *fmts)
391 {
392     AVFilterChannelLayouts *ch_layouts;
393     int count = 0;
394     if (fmts)
395         for (count = 0; fmts[count].nb_channels; count++)
396             ;
397     ch_layouts = av_mallocz(sizeof(*ch_layouts));
398     if (!ch_layouts)
399         return NULL;
400     ch_layouts->nb_channel_layouts = count;
401     if (count) {
402         ch_layouts->channel_layouts =
403             av_calloc(count, sizeof(*ch_layouts->channel_layouts));
404         if (!ch_layouts->channel_layouts) {
405             av_freep(&ch_layouts);
406             return NULL;
407         }
408         for (int i = 0; i < count; i++) {
409             int ret = av_channel_layout_copy(&ch_layouts->channel_layouts[i], &fmts[i]);
410             if (ret < 0)
411                 goto fail;
412         }
413     }
414 
415     return ch_layouts;
416 
417 fail:
418     for (int i = 0; i < count; i++)
419         av_channel_layout_uninit(&ch_layouts->channel_layouts[i]);
420     av_free(ch_layouts->channel_layouts);
421     av_freep(&ch_layouts);
422 
423     return NULL;
424 }
425 
426 #define ADD_FORMAT(f, fmt, unref_fn, type, list, nb)        \
427 do {                                                        \
428     type *fmts;                                             \
429                                                             \
430     if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) {         \
431         return AVERROR(ENOMEM);                             \
432     }                                                       \
433                                                             \
434     fmts = av_realloc_array((*f)->list, (*f)->nb + 1,       \
435                             sizeof(*(*f)->list));           \
436     if (!fmts) {                                            \
437         unref_fn(f);                                        \
438         return AVERROR(ENOMEM);                             \
439     }                                                       \
440                                                             \
441     (*f)->list = fmts;                                      \
442     ASSIGN_FMT(f, fmt, list, nb);                           \
443 } while (0)
444 
445 #define ASSIGN_FMT(f, fmt, list, nb)                        \
446 do {                                                        \
447     (*f)->list[(*f)->nb++] = fmt;                           \
448 } while (0)
449 
ff_add_format(AVFilterFormats ** avff,int64_t fmt)450 int ff_add_format(AVFilterFormats **avff, int64_t fmt)
451 {
452     ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
453     return 0;
454 }
455 
456 #undef ASSIGN_FMT
457 #define ASSIGN_FMT(f, fmt, list, nb)                              \
458 do {                                                              \
459     int ret;                                                      \
460     memset((*f)->list + (*f)->nb, 0, sizeof(*(*f)->list));        \
461     ret = av_channel_layout_copy(&(*f)->list[(*f)->nb], fmt);     \
462     if (ret < 0)                                                  \
463         return ret;                                               \
464     (*f)->nb++;                                                   \
465 } while (0)
466 
ff_add_channel_layout(AVFilterChannelLayouts ** l,const AVChannelLayout * channel_layout)467 int ff_add_channel_layout(AVFilterChannelLayouts **l,
468                           const AVChannelLayout *channel_layout)
469 {
470     av_assert1(!(*l && (*l)->all_layouts));
471     ADD_FORMAT(l, channel_layout, ff_channel_layouts_unref, AVChannelLayout, channel_layouts, nb_channel_layouts);
472     return 0;
473 }
474 
ff_make_formats_list_singleton(int fmt)475 AVFilterFormats *ff_make_formats_list_singleton(int fmt)
476 {
477     int fmts[2] = { fmt, -1 };
478     return ff_make_format_list(fmts);
479 }
480 
ff_all_formats(enum AVMediaType type)481 AVFilterFormats *ff_all_formats(enum AVMediaType type)
482 {
483     AVFilterFormats *ret = NULL;
484 
485     if (type == AVMEDIA_TYPE_VIDEO) {
486         return ff_formats_pixdesc_filter(0, 0);
487     } else if (type == AVMEDIA_TYPE_AUDIO) {
488         enum AVSampleFormat fmt = 0;
489         while (av_get_sample_fmt_name(fmt)) {
490             if (ff_add_format(&ret, fmt) < 0)
491                 return NULL;
492             fmt++;
493         }
494     }
495 
496     return ret;
497 }
498 
ff_formats_pixdesc_filter(unsigned want,unsigned rej)499 AVFilterFormats *ff_formats_pixdesc_filter(unsigned want, unsigned rej)
500 {
501     unsigned nb_formats, fmt, flags;
502     AVFilterFormats *formats = NULL;
503 
504     while (1) {
505         nb_formats = 0;
506         for (fmt = 0;; fmt++) {
507             const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
508             if (!desc)
509                 break;
510             flags = desc->flags;
511             if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
512                 !(desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
513                 (desc->log2_chroma_w || desc->log2_chroma_h))
514                 flags |= FF_PIX_FMT_FLAG_SW_FLAT_SUB;
515             if ((flags & (want | rej)) != want)
516                 continue;
517             if (formats)
518                 formats->formats[nb_formats] = fmt;
519             nb_formats++;
520         }
521         if (formats) {
522             av_assert0(formats->nb_formats == nb_formats);
523             return formats;
524         }
525         formats = av_mallocz(sizeof(*formats));
526         if (!formats)
527             return NULL;
528         formats->nb_formats = nb_formats;
529         if (nb_formats) {
530             formats->formats = av_malloc_array(nb_formats, sizeof(*formats->formats));
531             if (!formats->formats) {
532                 av_freep(&formats);
533                 return NULL;
534             }
535         }
536     }
537 }
538 
ff_planar_sample_fmts(void)539 AVFilterFormats *ff_planar_sample_fmts(void)
540 {
541     AVFilterFormats *ret = NULL;
542     int fmt;
543 
544     for (fmt = 0; av_get_bytes_per_sample(fmt)>0; fmt++)
545         if (av_sample_fmt_is_planar(fmt))
546             if (ff_add_format(&ret, fmt) < 0)
547                 return NULL;
548 
549     return ret;
550 }
551 
ff_all_samplerates(void)552 AVFilterFormats *ff_all_samplerates(void)
553 {
554     AVFilterFormats *ret = av_mallocz(sizeof(*ret));
555     return ret;
556 }
557 
ff_all_channel_layouts(void)558 AVFilterChannelLayouts *ff_all_channel_layouts(void)
559 {
560     AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
561     if (!ret)
562         return NULL;
563     ret->all_layouts = 1;
564     return ret;
565 }
566 
ff_all_channel_counts(void)567 AVFilterChannelLayouts *ff_all_channel_counts(void)
568 {
569     AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
570     if (!ret)
571         return NULL;
572     ret->all_layouts = ret->all_counts = 1;
573     return ret;
574 }
575 
576 #define FORMATS_REF(f, ref, unref_fn)                                           \
577     void *tmp;                                                                  \
578                                                                                 \
579     if (!f)                                                                     \
580         return AVERROR(ENOMEM);                                                 \
581                                                                                 \
582     tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1);         \
583     if (!tmp) {                                                                 \
584         unref_fn(&f);                                                           \
585         return AVERROR(ENOMEM);                                                 \
586     }                                                                           \
587     f->refs = tmp;                                                              \
588     f->refs[f->refcount++] = ref;                                               \
589     *ref = f;                                                                   \
590     return 0
591 
ff_channel_layouts_ref(AVFilterChannelLayouts * f,AVFilterChannelLayouts ** ref)592 int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
593 {
594     FORMATS_REF(f, ref, ff_channel_layouts_unref);
595 }
596 
ff_formats_ref(AVFilterFormats * f,AVFilterFormats ** ref)597 int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
598 {
599     FORMATS_REF(f, ref, ff_formats_unref);
600 }
601 
602 #define FIND_REF_INDEX(ref, idx)            \
603 do {                                        \
604     int i;                                  \
605     for (i = 0; i < (*ref)->refcount; i ++) \
606         if((*ref)->refs[i] == ref) {        \
607             idx = i;                        \
608             break;                          \
609         }                                   \
610 } while (0)
611 
612 #define FORMATS_UNREF(ref, list)                                   \
613 do {                                                               \
614     int idx = -1;                                                  \
615                                                                    \
616     if (!*ref)                                                     \
617         return;                                                    \
618                                                                    \
619     FIND_REF_INDEX(ref, idx);                                      \
620                                                                    \
621     if (idx >= 0) {                                                \
622         memmove((*ref)->refs + idx, (*ref)->refs + idx + 1,        \
623             sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
624         --(*ref)->refcount;                                        \
625     }                                                              \
626     if (!(*ref)->refcount) {                                       \
627         FREE_LIST(ref, list);                                      \
628         av_free((*ref)->list);                                     \
629         av_free((*ref)->refs);                                     \
630         av_free(*ref);                                             \
631     }                                                              \
632     *ref = NULL;                                                   \
633 } while (0)
634 
635 #define FREE_LIST(ref, list) do { } while(0)
ff_formats_unref(AVFilterFormats ** ref)636 void ff_formats_unref(AVFilterFormats **ref)
637 {
638     FORMATS_UNREF(ref, formats);
639 }
640 
641 #undef FREE_LIST
642 #define FREE_LIST(ref, list)                                       \
643     do {                                                           \
644         for (int i = 0; i < (*ref)->nb_channel_layouts; i++)       \
645             av_channel_layout_uninit(&(*ref)->list[i]);            \
646     } while(0)
647 
ff_channel_layouts_unref(AVFilterChannelLayouts ** ref)648 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
649 {
650     FORMATS_UNREF(ref, channel_layouts);
651 }
652 
653 #define FORMATS_CHANGEREF(oldref, newref)       \
654 do {                                            \
655     int idx = -1;                               \
656                                                 \
657     FIND_REF_INDEX(oldref, idx);                \
658                                                 \
659     if (idx >= 0) {                             \
660         (*oldref)->refs[idx] = newref;          \
661         *newref = *oldref;                      \
662         *oldref = NULL;                         \
663     }                                           \
664 } while (0)
665 
ff_channel_layouts_changeref(AVFilterChannelLayouts ** oldref,AVFilterChannelLayouts ** newref)666 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
667                                   AVFilterChannelLayouts **newref)
668 {
669     FORMATS_CHANGEREF(oldref, newref);
670 }
671 
ff_formats_changeref(AVFilterFormats ** oldref,AVFilterFormats ** newref)672 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
673 {
674     FORMATS_CHANGEREF(oldref, newref);
675 }
676 
677 #define SET_COMMON_FORMATS(ctx, fmts, media_type, ref_fn, unref_fn) \
678     int i;                                                          \
679                                                                     \
680     if (!fmts)                                                      \
681         return AVERROR(ENOMEM);                                     \
682                                                                     \
683     for (i = 0; i < ctx->nb_inputs; i++) {                          \
684         AVFilterLink *const link = ctx->inputs[i];                  \
685         if (link && !link->outcfg.fmts &&                           \
686             (media_type == AVMEDIA_TYPE_UNKNOWN || link->type == media_type)) { \
687             int ret = ref_fn(fmts, &ctx->inputs[i]->outcfg.fmts);   \
688             if (ret < 0) {                                          \
689                 return ret;                                         \
690             }                                                       \
691         }                                                           \
692     }                                                               \
693     for (i = 0; i < ctx->nb_outputs; i++) {                         \
694         AVFilterLink *const link = ctx->outputs[i];                 \
695         if (link && !link->incfg.fmts &&                            \
696             (media_type == AVMEDIA_TYPE_UNKNOWN || link->type == media_type)) { \
697             int ret = ref_fn(fmts, &ctx->outputs[i]->incfg.fmts);   \
698             if (ret < 0) {                                          \
699                 return ret;                                         \
700             }                                                       \
701         }                                                           \
702     }                                                               \
703                                                                     \
704     if (!fmts->refcount)                                            \
705         unref_fn(&fmts);                                            \
706                                                                     \
707     return 0;
708 
ff_set_common_channel_layouts(AVFilterContext * ctx,AVFilterChannelLayouts * channel_layouts)709 int ff_set_common_channel_layouts(AVFilterContext *ctx,
710                                   AVFilterChannelLayouts *channel_layouts)
711 {
712     SET_COMMON_FORMATS(ctx, channel_layouts, AVMEDIA_TYPE_AUDIO,
713                        ff_channel_layouts_ref, ff_channel_layouts_unref);
714 }
715 
ff_set_common_channel_layouts_from_list(AVFilterContext * ctx,const AVChannelLayout * fmts)716 int ff_set_common_channel_layouts_from_list(AVFilterContext *ctx,
717                                             const AVChannelLayout *fmts)
718 {
719     return ff_set_common_channel_layouts(ctx, ff_make_channel_layout_list(fmts));
720 }
721 
ff_set_common_all_channel_counts(AVFilterContext * ctx)722 int ff_set_common_all_channel_counts(AVFilterContext *ctx)
723 {
724     return ff_set_common_channel_layouts(ctx, ff_all_channel_counts());
725 }
726 
ff_set_common_samplerates(AVFilterContext * ctx,AVFilterFormats * samplerates)727 int ff_set_common_samplerates(AVFilterContext *ctx,
728                               AVFilterFormats *samplerates)
729 {
730     SET_COMMON_FORMATS(ctx, samplerates, AVMEDIA_TYPE_AUDIO,
731                        ff_formats_ref, ff_formats_unref);
732 }
733 
ff_set_common_samplerates_from_list(AVFilterContext * ctx,const int * samplerates)734 int ff_set_common_samplerates_from_list(AVFilterContext *ctx,
735                                         const int *samplerates)
736 {
737     return ff_set_common_samplerates(ctx, ff_make_format_list(samplerates));
738 }
739 
ff_set_common_all_samplerates(AVFilterContext * ctx)740 int ff_set_common_all_samplerates(AVFilterContext *ctx)
741 {
742     return ff_set_common_samplerates(ctx, ff_all_samplerates());
743 }
744 
745 /**
746  * A helper for query_formats() which sets all links to the same list of
747  * formats. If there are no links hooked to this filter, the list of formats is
748  * freed.
749  */
ff_set_common_formats(AVFilterContext * ctx,AVFilterFormats * formats)750 int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
751 {
752     SET_COMMON_FORMATS(ctx, formats, AVMEDIA_TYPE_UNKNOWN,
753                        ff_formats_ref, ff_formats_unref);
754 }
755 
ff_set_common_formats_from_list(AVFilterContext * ctx,const int * fmts)756 int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
757 {
758     return ff_set_common_formats(ctx, ff_make_format_list(fmts));
759 }
760 
ff_default_query_formats(AVFilterContext * ctx)761 int ff_default_query_formats(AVFilterContext *ctx)
762 {
763     const AVFilter *const f = ctx->filter;
764     AVFilterFormats *formats;
765     enum AVMediaType type;
766     int ret;
767 
768     switch (f->formats_state) {
769     case FF_FILTER_FORMATS_PIXFMT_LIST:
770         type    = AVMEDIA_TYPE_VIDEO;
771         formats = ff_make_format_list(f->formats.pixels_list);
772         break;
773     case FF_FILTER_FORMATS_SAMPLEFMTS_LIST:
774         type    = AVMEDIA_TYPE_AUDIO;
775         formats = ff_make_format_list(f->formats.samples_list);
776         break;
777     case FF_FILTER_FORMATS_SINGLE_PIXFMT:
778         type    = AVMEDIA_TYPE_VIDEO;
779         formats = ff_make_formats_list_singleton(f->formats.pix_fmt);
780         break;
781     case FF_FILTER_FORMATS_SINGLE_SAMPLEFMT:
782         type    = AVMEDIA_TYPE_AUDIO;
783         formats = ff_make_formats_list_singleton(f->formats.sample_fmt);
784         break;
785     default:
786         av_assert2(!"Unreachable");
787     /* Intended fallthrough */
788     case FF_FILTER_FORMATS_PASSTHROUGH:
789     case FF_FILTER_FORMATS_QUERY_FUNC:
790         type    = ctx->nb_inputs  ? ctx->inputs [0]->type :
791                   ctx->nb_outputs ? ctx->outputs[0]->type : AVMEDIA_TYPE_VIDEO;
792         formats = ff_all_formats(type);
793         break;
794     }
795 
796     ret = ff_set_common_formats(ctx, formats);
797     if (ret < 0)
798         return ret;
799     if (type == AVMEDIA_TYPE_AUDIO) {
800         ret = ff_set_common_all_channel_counts(ctx);
801         if (ret < 0)
802             return ret;
803         ret = ff_set_common_all_samplerates(ctx);
804         if (ret < 0)
805             return ret;
806     }
807 
808     return 0;
809 }
810 
811 /* internal functions for parsing audio format arguments */
812 
ff_parse_pixel_format(enum AVPixelFormat * ret,const char * arg,void * log_ctx)813 int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
814 {
815     char *tail;
816     int pix_fmt = av_get_pix_fmt(arg);
817     if (pix_fmt == AV_PIX_FMT_NONE) {
818         pix_fmt = strtol(arg, &tail, 0);
819         if (*tail || !av_pix_fmt_desc_get(pix_fmt)) {
820             av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
821             return AVERROR(EINVAL);
822         }
823     }
824     *ret = pix_fmt;
825     return 0;
826 }
827 
ff_parse_sample_rate(int * ret,const char * arg,void * log_ctx)828 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
829 {
830     char *tail;
831     double srate = av_strtod(arg, &tail);
832     if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
833         av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
834         return AVERROR(EINVAL);
835     }
836     *ret = srate;
837     return 0;
838 }
839 
ff_parse_channel_layout(AVChannelLayout * ret,int * nret,const char * arg,void * log_ctx)840 int ff_parse_channel_layout(AVChannelLayout *ret, int *nret, const char *arg,
841                             void *log_ctx)
842 {
843     AVChannelLayout chlayout = { 0 };
844     int res;
845 
846     res = av_channel_layout_from_string(&chlayout, arg);
847     if (res < 0) {
848 #if FF_API_OLD_CHANNEL_LAYOUT
849         int64_t mask;
850         int nb_channels;
851 FF_DISABLE_DEPRECATION_WARNINGS
852         if (av_get_extended_channel_layout(arg, &mask, &nb_channels) < 0) {
853 #endif
854             av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
855             return AVERROR(EINVAL);
856 #if FF_API_OLD_CHANNEL_LAYOUT
857         }
858 FF_ENABLE_DEPRECATION_WARNINGS
859         av_log(log_ctx, AV_LOG_WARNING, "Channel layout '%s' uses a deprecated syntax.\n",
860                arg);
861         if (mask)
862             av_channel_layout_from_mask(&chlayout, mask);
863         else
864             chlayout = (AVChannelLayout) { .order = AV_CHANNEL_ORDER_UNSPEC, .nb_channels = nb_channels };
865 #endif
866     }
867 
868     if (chlayout.order == AV_CHANNEL_ORDER_UNSPEC && !nret) {
869         av_log(log_ctx, AV_LOG_ERROR, "Unknown channel layout '%s' is not supported.\n", arg);
870         return AVERROR(EINVAL);
871     }
872     *ret = chlayout;
873     if (nret)
874         *nret = chlayout.nb_channels;
875 
876     return 0;
877 }
878 
check_list(void * log,const char * name,const AVFilterFormats * fmts)879 static int check_list(void *log, const char *name, const AVFilterFormats *fmts)
880 {
881     unsigned i, j;
882 
883     if (!fmts)
884         return 0;
885     if (!fmts->nb_formats) {
886         av_log(log, AV_LOG_ERROR, "Empty %s list\n", name);
887         return AVERROR(EINVAL);
888     }
889     for (i = 0; i < fmts->nb_formats; i++) {
890         for (j = i + 1; j < fmts->nb_formats; j++) {
891             if (fmts->formats[i] == fmts->formats[j]) {
892                 av_log(log, AV_LOG_ERROR, "Duplicated %s\n", name);
893                 return AVERROR(EINVAL);
894             }
895         }
896     }
897     return 0;
898 }
899 
ff_formats_check_pixel_formats(void * log,const AVFilterFormats * fmts)900 int ff_formats_check_pixel_formats(void *log, const AVFilterFormats *fmts)
901 {
902     return check_list(log, "pixel format", fmts);
903 }
904 
ff_formats_check_sample_formats(void * log,const AVFilterFormats * fmts)905 int ff_formats_check_sample_formats(void *log, const AVFilterFormats *fmts)
906 {
907     return check_list(log, "sample format", fmts);
908 }
909 
ff_formats_check_sample_rates(void * log,const AVFilterFormats * fmts)910 int ff_formats_check_sample_rates(void *log, const AVFilterFormats *fmts)
911 {
912     if (!fmts || !fmts->nb_formats)
913         return 0;
914     return check_list(log, "sample rate", fmts);
915 }
916 
layouts_compatible(const AVChannelLayout * a,const AVChannelLayout * b)917 static int layouts_compatible(const AVChannelLayout *a, const AVChannelLayout *b)
918 {
919     return !av_channel_layout_compare(a, b) ||
920            (KNOWN(a) && !KNOWN(b) && a->nb_channels == b->nb_channels) ||
921            (KNOWN(b) && !KNOWN(a) && b->nb_channels == a->nb_channels);
922 }
923 
ff_formats_check_channel_layouts(void * log,const AVFilterChannelLayouts * fmts)924 int ff_formats_check_channel_layouts(void *log, const AVFilterChannelLayouts *fmts)
925 {
926     unsigned i, j;
927 
928     if (!fmts)
929         return 0;
930     if (fmts->all_layouts < fmts->all_counts) {
931         av_log(log, AV_LOG_ERROR, "Inconsistent generic list\n");
932         return AVERROR(EINVAL);
933     }
934     if (!fmts->all_layouts && !fmts->nb_channel_layouts) {
935         av_log(log, AV_LOG_ERROR, "Empty channel layout list\n");
936         return AVERROR(EINVAL);
937     }
938     for (i = 0; i < fmts->nb_channel_layouts; i++) {
939         for (j = i + 1; j < fmts->nb_channel_layouts; j++) {
940             if (layouts_compatible(&fmts->channel_layouts[i], &fmts->channel_layouts[j])) {
941                 av_log(log, AV_LOG_ERROR, "Duplicated or redundant channel layout\n");
942                 return AVERROR(EINVAL);
943             }
944         }
945     }
946     return 0;
947 }
948