LCOV - code coverage report
Current view: top level - src/libavfilter - formats.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 201 243 82.7 %
Date: 2017-01-24 04:42:20 Functions: 28 31 90.3 %

          Line data    Source code
       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 avfilter_merge_formats() detected\n"); \
      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       37860 : AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b,
      93             :                                   enum AVMediaType type)
      94             : {
      95       37860 :     AVFilterFormats *ret = NULL;
      96             :     int i, j;
      97       37860 :     int alpha1=0, alpha2=0;
      98       37860 :     int chroma1=0, chroma2=0;
      99             : 
     100       37860 :     if (a == b)
     101           0 :         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       37860 :     if (type == AVMEDIA_TYPE_VIDEO)
     111      613368 :         for (i = 0; i < a->nb_formats; i++)
     112    13873402 :             for (j = 0; j < b->nb_formats; j++) {
     113    13289459 :                 const AVPixFmtDescriptor *adesc = av_pix_fmt_desc_get(a->formats[i]);
     114    13289459 :                 const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
     115    13289459 :                 alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA;
     116    13289459 :                 chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
     117    13289459 :                 if (a->formats[i] == b->formats[j]) {
     118       77501 :                     alpha1 |= adesc->flags & AV_PIX_FMT_FLAG_ALPHA;
     119       77501 :                     chroma1|= adesc->nb_components > 1;
     120             :                 }
     121             :             }
     122             : 
     123             :     // If chroma or alpha can be lost through merging then do not merge
     124       37860 :     if (alpha2 > alpha1 || chroma2 > chroma1)
     125        1871 :         return NULL;
     126             : 
     127       35989 :     MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
     128             : 
     129       35252 :     return ret;
     130             : fail:
     131         737 :     if (ret) {
     132         737 :         av_freep(&ret->refs);
     133         737 :         av_freep(&ret->formats);
     134             :     }
     135         737 :     av_freep(&ret);
     136         737 :     return NULL;
     137             : }
     138             : 
     139        8435 : AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
     140             :                                       AVFilterFormats *b)
     141             : {
     142        8435 :     AVFilterFormats *ret = NULL;
     143             : 
     144        8435 :     if (a == b) return a;
     145             : 
     146        8435 :     if (a->nb_formats && b->nb_formats) {
     147         118 :         MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
     148        8317 :     } else if (a->nb_formats) {
     149        5750 :         MERGE_REF(a, b, formats, AVFilterFormats, fail);
     150        5750 :         ret = a;
     151             :     } else {
     152        2567 :         MERGE_REF(b, a, formats, AVFilterFormats, fail);
     153        2567 :         ret = b;
     154             :     }
     155             : 
     156        8418 :     return ret;
     157             : fail:
     158          17 :     if (ret) {
     159          17 :         av_freep(&ret->refs);
     160          17 :         av_freep(&ret->formats);
     161             :     }
     162          17 :     av_freep(&ret);
     163          17 :     return NULL;
     164             : }
     165             : 
     166        4490 : AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
     167             :                                                  AVFilterChannelLayouts *b)
     168             : {
     169        4490 :     AVFilterChannelLayouts *ret = NULL;
     170        4490 :     unsigned a_all = a->all_layouts + a->all_counts;
     171        4490 :     unsigned b_all = b->all_layouts + b->all_counts;
     172        4490 :     int ret_max, ret_nb = 0, i, j, round;
     173             : 
     174        4490 :     if (a == b) return a;
     175             : 
     176             :     /* Put the most generic set in a, to avoid doing everything twice */
     177        4490 :     if (a_all < b_all) {
     178        2131 :         FFSWAP(AVFilterChannelLayouts *, a, b);
     179        2131 :         FFSWAP(unsigned, a_all, b_all);
     180             :     }
     181        4490 :     if (a_all) {
     182        4454 :         if (a_all == 1 && !b_all) {
     183             :             /* keep only known layouts in b; works also for b_all = 1 */
     184           8 :             for (i = j = 0; i < b->nb_channel_layouts; i++)
     185           4 :                 if (KNOWN(b->channel_layouts[i]))
     186           4 :                     b->channel_layouts[j++] = b->channel_layouts[i];
     187             :             /* Not optimal: the unknown layouts of b may become known after
     188             :                another merge. */
     189           4 :             if (!j)
     190           0 :                 return NULL;
     191           4 :             b->nb_channel_layouts = j;
     192             :         }
     193        4454 :         MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail);
     194        4454 :         return b;
     195             :     }
     196             : 
     197          36 :     ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
     198          72 :     if (!(ret = av_mallocz(sizeof(*ret))) ||
     199          36 :         !(ret->channel_layouts = av_malloc_array(ret_max,
     200             :                                                  sizeof(*ret->channel_layouts))))
     201             :         goto fail;
     202             : 
     203             :     /* a[known] intersect b[known] */
     204          72 :     for (i = 0; i < a->nb_channel_layouts; i++) {
     205          36 :         if (!KNOWN(a->channel_layouts[i]))
     206           0 :             continue;
     207          99 :         for (j = 0; j < b->nb_channel_layouts; j++) {
     208          63 :             if (a->channel_layouts[i] == b->channel_layouts[j]) {
     209          35 :                 ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
     210          35 :                 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         108 :     for (round = 0; round < 2; round++) {
     217         171 :         for (i = 0; i < a->nb_channel_layouts; i++) {
     218          99 :             uint64_t fmt = a->channel_layouts[i], bfmt;
     219          99 :             if (!fmt || !KNOWN(fmt))
     220          70 :                 continue;
     221          29 :             bfmt = FF_COUNT2LAYOUT(av_get_channel_layout_nb_channels(fmt));
     222          58 :             for (j = 0; j < b->nb_channel_layouts; j++)
     223          29 :                 if (b->channel_layouts[j] == bfmt)
     224           0 :                     ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
     225             :         }
     226             :         /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
     227          72 :         FFSWAP(AVFilterChannelLayouts *, a, b);
     228             :     }
     229             :     /* a[generic] intersect b[generic] */
     230          72 :     for (i = 0; i < a->nb_channel_layouts; i++) {
     231          36 :         if (KNOWN(a->channel_layouts[i]))
     232          36 :             continue;
     233           0 :         for (j = 0; j < b->nb_channel_layouts; j++)
     234           0 :             if (a->channel_layouts[i] == b->channel_layouts[j])
     235           0 :                 ret->channel_layouts[ret_nb++] = a->channel_layouts[i];
     236             :     }
     237             : 
     238          36 :     ret->nb_channel_layouts = ret_nb;
     239          36 :     if (!ret->nb_channel_layouts)
     240           1 :         goto fail;
     241          35 :     MERGE_REF(ret, a, channel_layouts, AVFilterChannelLayouts, fail);
     242          35 :     MERGE_REF(ret, b, channel_layouts, AVFilterChannelLayouts, fail);
     243          35 :     return ret;
     244             : 
     245             : fail:
     246           1 :     if (ret) {
     247           1 :         av_freep(&ret->refs);
     248           1 :         av_freep(&ret->channel_layouts);
     249             :     }
     250           1 :     av_freep(&ret);
     251           1 :     return NULL;
     252             : }
     253             : 
     254         104 : int ff_fmt_is_in(int fmt, const int *fmts)
     255             : {
     256             :     const int *p;
     257             : 
     258        1446 :     for (p = fmts; *p != -1; p++) {
     259        1411 :         if (fmt == *p)
     260          69 :             return 1;
     261             :     }
     262          35 :     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        5614 : AVFilterFormats *ff_make_format_list(const int *fmts)
     284             : {
     285        5614 :     MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
     286       24853 :     while (count--)
     287       13625 :         formats->formats[count] = fmts[count];
     288             : 
     289        5614 :     return formats;
     290             : }
     291             : 
     292           0 : AVFilterChannelLayouts *ff_make_formatu64_list(const uint64_t *fmts)
     293             : {
     294           0 :     MAKE_FORMAT_LIST(AVFilterChannelLayouts,
     295             :                      channel_layouts, nb_channel_layouts);
     296           0 :     if (count)
     297           0 :         memcpy(formats->channel_layouts, fmts,
     298             :                sizeof(*formats->channel_layouts) * count);
     299             : 
     300           0 :     return formats;
     301             : }
     302             : 
     303          11 : AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts)
     304             : {
     305          11 :     MAKE_FORMAT_LIST(AVFilterChannelLayouts,
     306             :                      channel_layouts, nb_channel_layouts);
     307          11 :     if (count)
     308          11 :         memcpy(formats->channel_layouts, fmts,
     309             :                sizeof(*formats->channel_layouts) * count);
     310             : 
     311          11 :     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             :         unref_fn(f);                                        \
     321             :         return AVERROR(ENOMEM);                             \
     322             :     }                                                       \
     323             :                                                             \
     324             :     fmts = av_realloc_array((*f)->list, (*f)->nb + 1,       \
     325             :                             sizeof(*(*f)->list));           \
     326             :     if (!fmts) {                                            \
     327             :         unref_fn(f);                                        \
     328             :         if (!oldf)                                          \
     329             :             av_freep(f);                                    \
     330             :         return AVERROR(ENOMEM);                             \
     331             :     }                                                       \
     332             :                                                             \
     333             :     (*f)->list = fmts;                                      \
     334             :     (*f)->list[(*f)->nb++] = fmt;                           \
     335             : } while (0)
     336             : 
     337     5525684 : int ff_add_format(AVFilterFormats **avff, int64_t fmt)
     338             : {
     339     5525684 :     ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
     340     5525684 :     return 0;
     341             : }
     342             : 
     343        2299 : int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
     344             : {
     345             :     av_assert1(!(*l && (*l)->all_layouts));
     346        2299 :     ADD_FORMAT(l, channel_layout, ff_channel_layouts_unref, uint64_t, channel_layouts, nb_channel_layouts);
     347        2299 :     return 0;
     348             : }
     349             : 
     350       31474 : AVFilterFormats *ff_all_formats(enum AVMediaType type)
     351             : {
     352       31474 :     AVFilterFormats *ret = NULL;
     353             : 
     354       31474 :     if (type == AVMEDIA_TYPE_VIDEO) {
     355       23844 :         const AVPixFmtDescriptor *desc = NULL;
     356     4411140 :         while ((desc = av_pix_fmt_desc_next(desc))) {
     357     4363452 :             if (ff_add_format(&ret, av_pix_fmt_desc_get_id(desc)) < 0)
     358           0 :                 return NULL;
     359             :         }
     360        7630 :     } else if (type == AVMEDIA_TYPE_AUDIO) {
     361        7630 :         enum AVSampleFormat fmt = 0;
     362      106820 :         while (av_get_sample_fmt_name(fmt)) {
     363       91560 :             if (ff_add_format(&ret, fmt) < 0)
     364           0 :                 return NULL;
     365       91560 :             fmt++;
     366             :         }
     367             :     }
     368             : 
     369       31474 :     return ret;
     370             : }
     371             : 
     372             : const int64_t avfilter_all_channel_layouts[] = {
     373             : #include "all_channel_layouts.inc"
     374             :     -1
     375             : };
     376             : 
     377             : // AVFilterFormats *avfilter_make_all_channel_layouts(void)
     378             : // {
     379             : //     return avfilter_make_format64_list(avfilter_all_channel_layouts);
     380             : // }
     381             : 
     382           4 : AVFilterFormats *ff_planar_sample_fmts(void)
     383             : {
     384           4 :     AVFilterFormats *ret = NULL;
     385             :     int fmt;
     386             : 
     387          52 :     for (fmt = 0; av_get_bytes_per_sample(fmt)>0; fmt++)
     388          48 :         if (av_sample_fmt_is_planar(fmt))
     389          24 :             if (ff_add_format(&ret, fmt) < 0)
     390           0 :                 return NULL;
     391             : 
     392           4 :     return ret;
     393             : }
     394             : 
     395        8359 : AVFilterFormats *ff_all_samplerates(void)
     396             : {
     397        8359 :     AVFilterFormats *ret = av_mallocz(sizeof(*ret));
     398        8359 :     return ret;
     399             : }
     400             : 
     401        4439 : AVFilterChannelLayouts *ff_all_channel_layouts(void)
     402             : {
     403        4439 :     AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
     404        4439 :     if (!ret)
     405           0 :         return NULL;
     406        4439 :     ret->all_layouts = 1;
     407        4439 :     return ret;
     408             : }
     409             : 
     410        5452 : AVFilterChannelLayouts *ff_all_channel_counts(void)
     411             : {
     412        5452 :     AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
     413        5452 :     if (!ret)
     414           0 :         return NULL;
     415        5452 :     ret->all_layouts = ret->all_counts = 1;
     416        5452 :     return ret;
     417             : }
     418             : 
     419             : #define FORMATS_REF(f, ref, unref_fn)                                           \
     420             :     void *tmp;                                                                  \
     421             :                                                                                 \
     422             :     if (!f || !ref)                                                             \
     423             :         return AVERROR(ENOMEM);                                                 \
     424             :                                                                                 \
     425             :     tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1);         \
     426             :     if (!tmp) {                                                                 \
     427             :         unref_fn(&f);                                                           \
     428             :         return AVERROR(ENOMEM);                                                 \
     429             :     }                                                                           \
     430             :     f->refs = tmp;                                                              \
     431             :     f->refs[f->refcount++] = ref;                                               \
     432             :     *ref = f;                                                                   \
     433             :     return 0
     434             : 
     435        8978 : int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
     436             : {
     437        8978 :     FORMATS_REF(f, ref, ff_channel_layouts_unref);
     438             : }
     439             : 
     440       49572 : int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
     441             : {
     442       49572 :     FORMATS_REF(f, ref, ff_formats_unref);
     443             : }
     444             : 
     445             : #define FIND_REF_INDEX(ref, idx)            \
     446             : do {                                        \
     447             :     int i;                                  \
     448             :     for (i = 0; i < (*ref)->refcount; i ++) \
     449             :         if((*ref)->refs[i] == ref) {        \
     450             :             idx = i;                        \
     451             :             break;                          \
     452             :         }                                   \
     453             : } while (0)
     454             : 
     455             : #define FORMATS_UNREF(ref, list)                                   \
     456             : do {                                                               \
     457             :     int idx = -1;                                                  \
     458             :                                                                    \
     459             :     if (!*ref || !(*ref)->refs)                                    \
     460             :         return;                                                    \
     461             :                                                                    \
     462             :     FIND_REF_INDEX(ref, idx);                                      \
     463             :                                                                    \
     464             :     if (idx >= 0)                                                  \
     465             :         memmove((*ref)->refs + idx, (*ref)->refs + idx + 1,        \
     466             :             sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
     467             :                                                                    \
     468             :     if(!--(*ref)->refcount) {                                      \
     469             :         av_free((*ref)->list);                                     \
     470             :         av_free((*ref)->refs);                                     \
     471             :         av_free(*ref);                                             \
     472             :     }                                                              \
     473             :     *ref = NULL;                                                   \
     474             : } while (0)
     475             : 
     476      162596 : void ff_formats_unref(AVFilterFormats **ref)
     477             : {
     478      162596 :     FORMATS_UNREF(ref, formats);
     479             : }
     480             : 
     481       81298 : void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
     482             : {
     483       81298 :     FORMATS_UNREF(ref, channel_layouts);
     484             : }
     485             : 
     486             : #define FORMATS_CHANGEREF(oldref, newref)       \
     487             : do {                                            \
     488             :     int idx = -1;                               \
     489             :                                                 \
     490             :     FIND_REF_INDEX(oldref, idx);                \
     491             :                                                 \
     492             :     if (idx >= 0) {                             \
     493             :         (*oldref)->refs[idx] = newref;          \
     494             :         *newref = *oldref;                      \
     495             :         *oldref = NULL;                         \
     496             :     }                                           \
     497             : } while (0)
     498             : 
     499         543 : void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
     500             :                                   AVFilterChannelLayouts **newref)
     501             : {
     502         543 :     FORMATS_CHANGEREF(oldref, newref);
     503         543 : }
     504             : 
     505        3163 : void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
     506             : {
     507        3163 :     FORMATS_CHANGEREF(oldref, newref);
     508        3163 : }
     509             : 
     510             : #define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref_fn, unref_fn, list) \
     511             :     int count = 0, i;                                               \
     512             :                                                                     \
     513             :     if (!fmts)                                                      \
     514             :         return AVERROR(ENOMEM);                                     \
     515             :                                                                     \
     516             :     for (i = 0; i < ctx->nb_inputs; i++) {                          \
     517             :         if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) {          \
     518             :             int ret = ref_fn(fmts, &ctx->inputs[i]->out_fmts);      \
     519             :             if (ret < 0) {                                          \
     520             :                 unref_fn(&fmts);                                    \
     521             :                 av_freep(&fmts->list);                              \
     522             :                 av_freep(&fmts);                                    \
     523             :                 return ret;                                         \
     524             :             }                                                       \
     525             :             count++;                                                \
     526             :         }                                                           \
     527             :     }                                                               \
     528             :     for (i = 0; i < ctx->nb_outputs; i++) {                         \
     529             :         if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) {         \
     530             :             int ret = ref_fn(fmts, &ctx->outputs[i]->in_fmts);      \
     531             :             if (ret < 0) {                                          \
     532             :                 unref_fn(&fmts);                                    \
     533             :                 av_freep(&fmts->list);                              \
     534             :                 av_freep(&fmts);                                    \
     535             :                 return ret;                                         \
     536             :             }                                                       \
     537             :             count++;                                                \
     538             :         }                                                           \
     539             :     }                                                               \
     540             :                                                                     \
     541             :     if (!count) {                                                   \
     542             :         av_freep(&fmts->list);                                      \
     543             :         av_freep(&fmts->refs);                                      \
     544             :         av_freep(&fmts);                                            \
     545             :     }                                                               \
     546             :                                                                     \
     547             :     return 0;
     548             : 
     549        8859 : int ff_set_common_channel_layouts(AVFilterContext *ctx,
     550             :                                   AVFilterChannelLayouts *layouts)
     551             : {
     552        8859 :     SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
     553             :                        ff_channel_layouts_ref, ff_channel_layouts_unref, channel_layouts);
     554             : }
     555             : 
     556        7852 : int ff_set_common_samplerates(AVFilterContext *ctx,
     557             :                               AVFilterFormats *samplerates)
     558             : {
     559        7852 :     SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
     560             :                        ff_formats_ref, ff_formats_unref, formats);
     561             : }
     562             : 
     563             : /**
     564             :  * A helper for query_formats() which sets all links to the same list of
     565             :  * formats. If there are no links hooked to this filter, the list of formats is
     566             :  * freed.
     567             :  */
     568       41406 : int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
     569             : {
     570       41406 :     SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
     571             :                        ff_formats_ref, ff_formats_unref, formats);
     572             : }
     573             : 
     574        8173 : static int default_query_formats_common(AVFilterContext *ctx,
     575             :                                         AVFilterChannelLayouts *(layouts)(void))
     576             : {
     577             :     int ret;
     578        8173 :     enum AVMediaType type = ctx->inputs  && ctx->inputs [0] ? ctx->inputs [0]->type :
     579           0 :                             ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
     580             :                             AVMEDIA_TYPE_VIDEO;
     581             : 
     582        8173 :     ret = ff_set_common_formats(ctx, ff_all_formats(type));
     583        8173 :     if (ret < 0)
     584           0 :         return ret;
     585        8173 :     if (type == AVMEDIA_TYPE_AUDIO) {
     586        1072 :         ret = ff_set_common_channel_layouts(ctx, layouts());
     587        1072 :         if (ret < 0)
     588           0 :             return ret;
     589        1072 :         ret = ff_set_common_samplerates(ctx, ff_all_samplerates());
     590        1072 :         if (ret < 0)
     591           0 :             return ret;
     592             :     }
     593             : 
     594        8173 :     return 0;
     595             : }
     596             : 
     597        8172 : int ff_default_query_formats(AVFilterContext *ctx)
     598             : {
     599        8172 :     return default_query_formats_common(ctx, ff_all_channel_counts);
     600             : }
     601             : 
     602           1 : int ff_query_formats_all_layouts(AVFilterContext *ctx)
     603             : {
     604           1 :     return default_query_formats_common(ctx, ff_all_channel_layouts);
     605             : }
     606             : 
     607             : /* internal functions for parsing audio format arguments */
     608             : 
     609        5404 : int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
     610             : {
     611             :     char *tail;
     612        5404 :     int pix_fmt = av_get_pix_fmt(arg);
     613        5404 :     if (pix_fmt == AV_PIX_FMT_NONE) {
     614           0 :         pix_fmt = strtol(arg, &tail, 0);
     615           0 :         if (*tail || !av_pix_fmt_desc_get(pix_fmt)) {
     616           0 :             av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
     617           0 :             return AVERROR(EINVAL);
     618             :         }
     619             :     }
     620        5404 :     *ret = pix_fmt;
     621        5404 :     return 0;
     622             : }
     623             : 
     624           0 : int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
     625             : {
     626             :     char *tail;
     627           0 :     int sfmt = av_get_sample_fmt(arg);
     628           0 :     if (sfmt == AV_SAMPLE_FMT_NONE) {
     629           0 :         sfmt = strtol(arg, &tail, 0);
     630           0 :         if (*tail || av_get_bytes_per_sample(sfmt)<=0) {
     631           0 :             av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
     632           0 :             return AVERROR(EINVAL);
     633             :         }
     634             :     }
     635           0 :     *ret = sfmt;
     636           0 :     return 0;
     637             : }
     638             : 
     639           0 : int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
     640             : {
     641             :     AVRational r;
     642           0 :     if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0  ||r.den<=0) {
     643           0 :         av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
     644           0 :         return AVERROR(EINVAL);
     645             :     }
     646           0 :     *ret = r;
     647           0 :     return 0;
     648             : }
     649             : 
     650           4 : int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
     651             : {
     652             :     char *tail;
     653           4 :     double srate = av_strtod(arg, &tail);
     654           4 :     if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
     655           0 :         av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
     656           0 :         return AVERROR(EINVAL);
     657             :     }
     658           4 :     *ret = srate;
     659           4 :     return 0;
     660             : }
     661             : 
     662          21 : int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
     663             :                             void *log_ctx)
     664             : {
     665             :     char *tail;
     666             :     int64_t chlayout;
     667             : 
     668          21 :     chlayout = av_get_channel_layout(arg);
     669          21 :     if (chlayout == 0) {
     670           5 :         chlayout = strtol(arg, &tail, 10);
     671           5 :         if (!(*tail == '\0' || *tail == 'c' && *(tail + 1) == '\0') || chlayout <= 0 || chlayout > 63) {
     672           4 :             av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
     673           4 :             return AVERROR(EINVAL);
     674             :         }
     675           1 :         if (nret) {
     676           1 :             *nret = chlayout;
     677           1 :             *ret = 0;
     678           1 :             return 0;
     679             :         }
     680             :     }
     681          16 :     *ret = chlayout;
     682          16 :     if (nret)
     683          16 :         *nret = av_get_channel_layout_nb_channels(chlayout);
     684          16 :     return 0;
     685             : }

Generated by: LCOV version 1.12