GCC Code Coverage Report
Directory: ../../../ffmpeg/ Exec Total Coverage
File: src/libavfilter/formats.c Lines: 220 267 82.4 %
Date: 2020-08-14 10:39:37 Branches: 268 412 65.0 %

Line Branch Exec Source
1
/*
2
 * Filter layer - format negotiation
3
 * Copyright (c) 2007 Bobby Bingham
4
 *
5
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#include "libavutil/avassert.h"
23
#include "libavutil/channel_layout.h"
24
#include "libavutil/common.h"
25
#include "libavutil/eval.h"
26
#include "libavutil/pixdesc.h"
27
#include "libavutil/parseutils.h"
28
#include "avfilter.h"
29
#include "internal.h"
30
#include "formats.h"
31
32
#define KNOWN(l) (!FF_LAYOUT2COUNT(l)) /* for readability */
33
34
/**
35
 * Add all refs from a to ret and destroy a.
36
 * ret->refs must have enough spare room left for this.
37
 */
38
#define MERGE_REF_NO_ALLOC(ret, a, fmts)                                   \
39
do {                                                                       \
40
    int i;                                                                 \
41
    for (i = 0; i < a->refcount; i ++) {                                   \
42
        ret->refs[ret->refcount] = a->refs[i];                             \
43
        *ret->refs[ret->refcount++] = ret;                                 \
44
    }                                                                      \
45
                                                                           \
46
    av_freep(&a->refs);                                                    \
47
    av_freep(&a->fmts);                                                    \
48
    av_freep(&a);                                                          \
49
} while (0)
50
51
#define MERGE_REF(ret, a, fmts, type, fail_statement)                      \
52
do {                                                                       \
53
    type ***tmp;                                                           \
54
                                                                           \
55
    if (!(tmp = av_realloc_array(ret->refs, ret->refcount + a->refcount,   \
56
                                 sizeof(*tmp))))                           \
57
        { fail_statement }                                                 \
58
    ret->refs = tmp;                                                       \
59
    MERGE_REF_NO_ALLOC(ret, a, fmts);                                      \
60
} while (0)
61
62
/**
63
 * Add all formats common for a and b to ret, copy the refs and destroy
64
 * a and b.
65
 */
66
#define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail)                          \
67
do {                                                                            \
68
    int i, j, k = 0, count = FFMIN(a->nb, b->nb);                               \
69
    type ***tmp;                                                                \
70
                                                                                \
71
    if (!(ret = av_mallocz(sizeof(*ret))))                                      \
72
        goto fail;                                                              \
73
                                                                                \
74
    if (count) {                                                                \
75
        if (!(ret->fmts = av_malloc_array(count, sizeof(*ret->fmts))))          \
76
            goto fail;                                                          \
77
        for (i = 0; i < a->nb; i++)                                             \
78
            for (j = 0; j < b->nb; j++)                                         \
79
                if (a->fmts[i] == b->fmts[j]) {                                 \
80
                    if(k >= FFMIN(a->nb, b->nb)){                               \
81
                        av_log(NULL, AV_LOG_ERROR, "Duplicate formats in %s detected\n", __FUNCTION__); \
82
                        av_free(ret->fmts);                                     \
83
                        av_free(ret);                                           \
84
                        return NULL;                                            \
85
                    }                                                           \
86
                    ret->fmts[k++] = a->fmts[i];                                \
87
                }                                                               \
88
    }                                                                           \
89
    ret->nb = k;                                                                \
90
    /* check that there was at least one common format */                       \
91
    if (!ret->nb)                                                               \
92
        goto fail;                                                              \
93
                                                                                \
94
    tmp = av_realloc_array(NULL, a->refcount + b->refcount, sizeof(*tmp));      \
95
    if (!tmp)                                                                   \
96
        goto fail;                                                              \
97
    ret->refs = tmp;                                                            \
98
                                                                                \
99
    MERGE_REF_NO_ALLOC(ret, a, fmts);                                           \
100
    MERGE_REF_NO_ALLOC(ret, b, fmts);                                           \
101
} while (0)
102
103
44579
AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b,
104
                                  enum AVMediaType type)
105
{
106
44579
    AVFilterFormats *ret = NULL;
107
    int i, j;
108
44579
    int alpha1=0, alpha2=0;
109
44579
    int chroma1=0, chroma2=0;
110
111
44579
    if (a == b)
112
        return a;
113
114
    /* Do not lose chroma or alpha in merging.
115
       It happens if both lists have formats with chroma (resp. alpha), but
116
       the only formats in common do not have it (e.g. YUV+gray vs.
117
       RGB+gray): in that case, the merging would select the gray format,
118
       possibly causing a lossy conversion elsewhere in the graph.
119
       To avoid that, pretend that there are no common formats to force the
120
       insertion of a conversion filter. */
121
44579
    if (type == AVMEDIA_TYPE_VIDEO)
122
809145
        for (i = 0; i < a->nb_formats; i++)
123
17079190
            for (j = 0; j < b->nb_formats; j++) {
124
16305114
                const AVPixFmtDescriptor *adesc = av_pix_fmt_desc_get(a->formats[i]);
125
16305114
                const AVPixFmtDescriptor *bdesc = av_pix_fmt_desc_get(b->formats[j]);
126
16305114
                alpha2 |= adesc->flags & bdesc->flags & AV_PIX_FMT_FLAG_ALPHA;
127

16305114
                chroma2|= adesc->nb_components > 1 && bdesc->nb_components > 1;
128
16305114
                if (a->formats[i] == b->formats[j]) {
129
90641
                    alpha1 |= adesc->flags & AV_PIX_FMT_FLAG_ALPHA;
130
90641
                    chroma1|= adesc->nb_components > 1;
131
                }
132
            }
133
134
    // If chroma or alpha can be lost through merging then do not merge
135

44579
    if (alpha2 > alpha1 || chroma2 > chroma1)
136
2283
        return NULL;
137
138





17362432
    MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
139
140
41450
    return ret;
141
846
fail:
142
846
    if (ret) {
143
        av_assert1(!ret->refs);
144
846
        av_freep(&ret->formats);
145
846
        av_freep(&ret);
146
    }
147
846
    return NULL;
148
}
149
150
9510
AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
151
                                      AVFilterFormats *b)
152
{
153
9510
    AVFilterFormats *ret = NULL;
154
155
9510
    if (a == b) return a;
156
157

9510
    if (a->nb_formats && b->nb_formats) {
158





973
        MERGE_FORMATS(ret, a, b, formats, nb_formats, AVFilterFormats, fail);
159
9386
    } else if (a->nb_formats) {
160

12540
        MERGE_REF(a, b, formats, AVFilterFormats, return NULL;);
161
6548
        ret = a;
162
    } else {
163

5779
        MERGE_REF(b, a, formats, AVFilterFormats, return NULL;);
164
2838
        ret = b;
165
    }
166
167
9493
    return ret;
168
17
fail:
169
17
    if (ret) {
170
        av_assert1(!ret->refs);
171
17
        av_freep(&ret->formats);
172
17
        av_freep(&ret);
173
    }
174
17
    return NULL;
175
}
176
177
5042
AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
178
                                                 AVFilterChannelLayouts *b)
179
{
180
    uint64_t *channel_layouts;
181
5042
    unsigned a_all = a->all_layouts + a->all_counts;
182
5042
    unsigned b_all = b->all_layouts + b->all_counts;
183
5042
    int ret_max, ret_nb = 0, i, j, round;
184
185
5042
    if (a == b) return a;
186
187
    /* Put the most generic set in a, to avoid doing everything twice */
188
5042
    if (a_all < b_all) {
189
2357
        FFSWAP(AVFilterChannelLayouts *, a, b);
190
2357
        FFSWAP(unsigned, a_all, b_all);
191
    }
192
5042
    if (a_all) {
193

5001
        if (a_all == 1 && !b_all) {
194
            /* keep only known layouts in b; works also for b_all = 1 */
195
8
            for (i = j = 0; i < b->nb_channel_layouts; i++)
196

4
                if (KNOWN(b->channel_layouts[i]))
197
4
                    b->channel_layouts[j++] = b->channel_layouts[i];
198
            /* Not optimal: the unknown layouts of b may become known after
199
               another merge. */
200
4
            if (!j)
201
                return NULL;
202
4
            b->nb_channel_layouts = j;
203
        }
204

13579
        MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, return NULL;);
205
5001
        return b;
206
    }
207
208
41
    ret_max = a->nb_channel_layouts + b->nb_channel_layouts;
209
41
    if (!(channel_layouts = av_malloc_array(ret_max, sizeof(*channel_layouts))))
210
        return NULL;
211
212
    /* a[known] intersect b[known] */
213
82
    for (i = 0; i < a->nb_channel_layouts; i++) {
214

41
        if (!KNOWN(a->channel_layouts[i]))
215
            continue;
216
57
        for (j = 0; j < b->nb_channel_layouts; j++) {
217
56
            if (a->channel_layouts[i] == b->channel_layouts[j]) {
218
40
                channel_layouts[ret_nb++] = a->channel_layouts[i];
219
40
                a->channel_layouts[i] = b->channel_layouts[j] = 0;
220
40
                break;
221
            }
222
        }
223
    }
224
    /* 1st round: a[known] intersect b[generic]
225
       2nd round: a[generic] intersect b[known] */
226
123
    for (round = 0; round < 2; round++) {
227
193
        for (i = 0; i < a->nb_channel_layouts; i++) {
228
111
            uint64_t fmt = a->channel_layouts[i], bfmt;
229

111
            if (!fmt || !KNOWN(fmt))
230
80
                continue;
231
31
            bfmt = FF_COUNT2LAYOUT(av_get_channel_layout_nb_channels(fmt));
232
62
            for (j = 0; j < b->nb_channel_layouts; j++)
233
31
                if (b->channel_layouts[j] == bfmt)
234
                    channel_layouts[ret_nb++] = a->channel_layouts[i];
235
        }
236
        /* 1st round: swap to prepare 2nd round; 2nd round: put it back */
237
82
        FFSWAP(AVFilterChannelLayouts *, a, b);
238
    }
239
    /* a[generic] intersect b[generic] */
240
82
    for (i = 0; i < a->nb_channel_layouts; i++) {
241

41
        if (KNOWN(a->channel_layouts[i]))
242
41
            continue;
243
        for (j = 0; j < b->nb_channel_layouts; j++)
244
            if (a->channel_layouts[i] == b->channel_layouts[j])
245
                channel_layouts[ret_nb++] = a->channel_layouts[i];
246
    }
247
248
41
    if (!ret_nb)
249
1
        goto fail;
250
251
40
    if (a->refcount > b->refcount)
252
11
        FFSWAP(AVFilterChannelLayouts *, a, b);
253
254

99
    MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, goto fail;);
255
40
    av_freep(&b->channel_layouts);
256
40
    b->channel_layouts    = channel_layouts;
257
40
    b->nb_channel_layouts = ret_nb;
258
40
    return b;
259
260
1
fail:
261
1
    av_free(channel_layouts);
262
1
    return NULL;
263
}
264
265
153
int ff_fmt_is_in(int fmt, const int *fmts)
266
{
267
    const int *p;
268
269
2055
    for (p = fmts; *p != -1; p++) {
270
1989
        if (fmt == *p)
271
87
            return 1;
272
    }
273
66
    return 0;
274
}
275
276
#define MAKE_FORMAT_LIST(type, field, count_field)                      \
277
    type *formats;                                                      \
278
    int count = 0;                                                      \
279
    if (fmts)                                                           \
280
        for (count = 0; fmts[count] != -1; count++)                     \
281
            ;                                                           \
282
    formats = av_mallocz(sizeof(*formats));                             \
283
    if (!formats)                                                       \
284
        return NULL;                                                    \
285
    formats->count_field = count;                                       \
286
    if (count) {                                                        \
287
        formats->field = av_malloc_array(count, sizeof(*formats->field));      \
288
        if (!formats->field) {                                          \
289
            av_freep(&formats);                                         \
290
            return NULL;                                                \
291
        }                                                               \
292
    }
293
294
7089
AVFilterFormats *ff_make_format_list(const int *fmts)
295
{
296


26589
    MAKE_FORMAT_LIST(AVFilterFormats, formats, nb_formats);
297
26589
    while (count--)
298
19500
        formats->formats[count] = fmts[count];
299
300
7089
    return formats;
301
}
302
303
23
AVFilterChannelLayouts *ff_make_format64_list(const int64_t *fmts)
304
{
305


46
    MAKE_FORMAT_LIST(AVFilterChannelLayouts,
306
                     channel_layouts, nb_channel_layouts);
307
23
    if (count)
308
23
        memcpy(formats->channel_layouts, fmts,
309
               sizeof(*formats->channel_layouts) * count);
310
311
23
    return formats;
312
}
313
314
#if LIBAVFILTER_VERSION_MAJOR < 8
315
AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts)
316
{
317
    return ff_make_format64_list(fmts);
318
}
319
#endif
320
321
#define ADD_FORMAT(f, fmt, unref_fn, type, list, nb)        \
322
do {                                                        \
323
    type *fmts;                                             \
324
    void *oldf = *f;                                        \
325
                                                            \
326
    if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) {         \
327
        return AVERROR(ENOMEM);                             \
328
    }                                                       \
329
                                                            \
330
    fmts = av_realloc_array((*f)->list, (*f)->nb + 1,       \
331
                            sizeof(*(*f)->list));           \
332
    if (!fmts) {                                            \
333
        unref_fn(f);                                        \
334
        if (!oldf)                                          \
335
            av_freep(f);                                    \
336
        return AVERROR(ENOMEM);                             \
337
    }                                                       \
338
                                                            \
339
    (*f)->list = fmts;                                      \
340
    (*f)->list[(*f)->nb++] = fmt;                           \
341
} while (0)
342
343
7001287
int ff_add_format(AVFilterFormats **avff, int64_t fmt)
344
{
345


7001287
    ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats);
346
7001287
    return 0;
347
}
348
349
2590
int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
350
{
351
    av_assert1(!(*l && (*l)->all_layouts));
352


2590
    ADD_FORMAT(l, channel_layout, ff_channel_layouts_unref, uint64_t, channel_layouts, nb_channel_layouts);
353
2590
    return 0;
354
}
355
356
36817
AVFilterFormats *ff_all_formats(enum AVMediaType type)
357
{
358
36817
    AVFilterFormats *ret = NULL;
359
360
36817
    if (type == AVMEDIA_TYPE_VIDEO) {
361
28224
        const AVPixFmtDescriptor *desc = NULL;
362
5616576
        while ((desc = av_pix_fmt_desc_next(desc))) {
363
5588352
            if (ff_add_format(&ret, av_pix_fmt_desc_get_id(desc)) < 0)
364
                return NULL;
365
        }
366
8593
    } else if (type == AVMEDIA_TYPE_AUDIO) {
367
8593
        enum AVSampleFormat fmt = 0;
368
111709
        while (av_get_sample_fmt_name(fmt)) {
369
103116
            if (ff_add_format(&ret, fmt) < 0)
370
                return NULL;
371
103116
            fmt++;
372
        }
373
    }
374
375
36817
    return ret;
376
}
377
378
165
int ff_formats_pixdesc_filter(AVFilterFormats **rfmts, unsigned want, unsigned rej)
379
{
380
    unsigned nb_formats, fmt, flags;
381
165
    AVFilterFormats *formats = NULL;
382
383
    while (1) {
384
330
        nb_formats = 0;
385
65670
        for (fmt = 0;; fmt++) {
386
65670
            const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt);
387
65670
            if (!desc)
388
330
                break;
389
65340
            flags = desc->flags;
390
65340
            if (!(desc->flags & AV_PIX_FMT_FLAG_HWACCEL) &&
391
60060
                !(desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
392

26070
                (desc->log2_chroma_w || desc->log2_chroma_h))
393
1980
                flags |= FF_PIX_FMT_FLAG_SW_FLAT_SUB;
394
65340
            if ((flags & (want | rej)) != want)
395
3332
                continue;
396
62008
            if (formats)
397
31004
                formats->formats[nb_formats] = fmt;
398
62008
            nb_formats++;
399
        }
400
330
        if (formats) {
401
165
            av_assert0(formats->nb_formats == nb_formats);
402
165
            *rfmts = formats;
403
165
            return 0;
404
        }
405
165
        formats = av_mallocz(sizeof(*formats));
406
165
        if (!formats)
407
            return AVERROR(ENOMEM);
408
165
        formats->nb_formats = nb_formats;
409
165
        if (nb_formats) {
410
165
            formats->formats = av_malloc_array(nb_formats, sizeof(*formats->formats));
411
165
            if (!formats->formats) {
412
                av_freep(&formats);
413
                return AVERROR(ENOMEM);
414
            }
415
        }
416
    }
417
}
418
419
4
AVFilterFormats *ff_planar_sample_fmts(void)
420
{
421
4
    AVFilterFormats *ret = NULL;
422
    int fmt;
423
424
52
    for (fmt = 0; av_get_bytes_per_sample(fmt)>0; fmt++)
425
48
        if (av_sample_fmt_is_planar(fmt))
426
24
            if (ff_add_format(&ret, fmt) < 0)
427
                return NULL;
428
429
4
    return ret;
430
}
431
432
9379
AVFilterFormats *ff_all_samplerates(void)
433
{
434
9379
    AVFilterFormats *ret = av_mallocz(sizeof(*ret));
435
9379
    return ret;
436
}
437
438
4998
AVFilterChannelLayouts *ff_all_channel_layouts(void)
439
{
440
4998
    AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
441
4998
    if (!ret)
442
        return NULL;
443
4998
    ret->all_layouts = 1;
444
4998
    return ret;
445
}
446
447
6146
AVFilterChannelLayouts *ff_all_channel_counts(void)
448
{
449
6146
    AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
450
6146
    if (!ret)
451
        return NULL;
452
6146
    ret->all_layouts = ret->all_counts = 1;
453
6146
    return ret;
454
}
455
456
#define FORMATS_REF(f, ref, unref_fn)                                           \
457
    void *tmp;                                                                  \
458
                                                                                \
459
    if (!f || !ref)                                                             \
460
        return AVERROR(ENOMEM);                                                 \
461
                                                                                \
462
    tmp = av_realloc_array(f->refs, sizeof(*f->refs), f->refcount + 1);         \
463
    if (!tmp) {                                                                 \
464
        unref_fn(&f);                                                           \
465
        return AVERROR(ENOMEM);                                                 \
466
    }                                                                           \
467
    f->refs = tmp;                                                              \
468
    f->refs[f->refcount++] = ref;                                               \
469
    *ref = f;                                                                   \
470
    return 0
471
472
10082
int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
473
{
474

10082
    FORMATS_REF(f, ref, ff_channel_layouts_unref);
475
}
476
477
57938
int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
478
{
479

57938
    FORMATS_REF(f, ref, ff_formats_unref);
480
}
481
482
#define FIND_REF_INDEX(ref, idx)            \
483
do {                                        \
484
    int i;                                  \
485
    for (i = 0; i < (*ref)->refcount; i ++) \
486
        if((*ref)->refs[i] == ref) {        \
487
            idx = i;                        \
488
            break;                          \
489
        }                                   \
490
} while (0)
491
492
#define FORMATS_UNREF(ref, list)                                   \
493
do {                                                               \
494
    int idx = -1;                                                  \
495
                                                                   \
496
    if (!ref || !*ref || !(*ref)->refs)                            \
497
        return;                                                    \
498
                                                                   \
499
    FIND_REF_INDEX(ref, idx);                                      \
500
                                                                   \
501
    if (idx >= 0)                                                  \
502
        memmove((*ref)->refs + idx, (*ref)->refs + idx + 1,        \
503
            sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
504
                                                                   \
505
    if(!--(*ref)->refcount) {                                      \
506
        av_free((*ref)->list);                                     \
507
        av_free((*ref)->refs);                                     \
508
        av_free(*ref);                                             \
509
    }                                                              \
510
    *ref = NULL;                                                   \
511
} while (0)
512
513
191908
void ff_formats_unref(AVFilterFormats **ref)
514
{
515



202405
    FORMATS_UNREF(ref, formats);
516
}
517
518
95954
void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
519
{
520



101851
    FORMATS_UNREF(ref, channel_layouts);
521
}
522
523
#define FORMATS_CHANGEREF(oldref, newref)       \
524
do {                                            \
525
    int idx = -1;                               \
526
                                                \
527
    FIND_REF_INDEX(oldref, idx);                \
528
                                                \
529
    if (idx >= 0) {                             \
530
        (*oldref)->refs[idx] = newref;          \
531
        *newref = *oldref;                      \
532
        *oldref = NULL;                         \
533
    }                                           \
534
} while (0)
535
536
572
void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
537
                                  AVFilterChannelLayouts **newref)
538
{
539

1069
    FORMATS_CHANGEREF(oldref, newref);
540
572
}
541
542
3713
void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
543
{
544

4229
    FORMATS_CHANGEREF(oldref, newref);
545
3713
}
546
547
#define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref_fn, unref_fn, list) \
548
    int count = 0, i;                                               \
549
                                                                    \
550
    if (!fmts)                                                      \
551
        return AVERROR(ENOMEM);                                     \
552
                                                                    \
553
    for (i = 0; i < ctx->nb_inputs; i++) {                          \
554
        if (ctx->inputs[i] && !ctx->inputs[i]->out_fmts) {          \
555
            int ret = ref_fn(fmts, &ctx->inputs[i]->out_fmts);      \
556
            if (ret < 0) {                                          \
557
                unref_fn(&fmts);                                    \
558
                if (fmts)                                           \
559
                    av_freep(&fmts->list);                          \
560
                av_freep(&fmts);                                    \
561
                return ret;                                         \
562
            }                                                       \
563
            count++;                                                \
564
        }                                                           \
565
    }                                                               \
566
    for (i = 0; i < ctx->nb_outputs; i++) {                         \
567
        if (ctx->outputs[i] && !ctx->outputs[i]->in_fmts) {         \
568
            int ret = ref_fn(fmts, &ctx->outputs[i]->in_fmts);      \
569
            if (ret < 0) {                                          \
570
                unref_fn(&fmts);                                    \
571
                if (fmts)                                           \
572
                    av_freep(&fmts->list);                          \
573
                av_freep(&fmts);                                    \
574
                return ret;                                         \
575
            }                                                       \
576
            count++;                                                \
577
        }                                                           \
578
    }                                                               \
579
                                                                    \
580
    if (!count) {                                                   \
581
        av_freep(&fmts->list);                                      \
582
        av_freep(&fmts->refs);                                      \
583
        av_freep(&fmts);                                            \
584
    }                                                               \
585
                                                                    \
586
    return 0;
587
588
9934
int ff_set_common_channel_layouts(AVFilterContext *ctx,
589
                                  AVFilterChannelLayouts *layouts)
590
{
591






25258
    SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
592
                       ff_channel_layouts_ref, ff_channel_layouts_unref, channel_layouts);
593
}
594
595
8821
int ff_set_common_samplerates(AVFilterContext *ctx,
596
                              AVFilterFormats *samplerates)
597
{
598






23057
    SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
599
                       ff_formats_ref, ff_formats_unref, formats);
600
}
601
602
/**
603
 * A helper for query_formats() which sets all links to the same list of
604
 * formats. If there are no links hooked to this filter, the list of formats is
605
 * freed.
606
 */
607
48952
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
608
{
609






124607
    SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
610
                       ff_formats_ref, ff_formats_unref, formats);
611
}
612
613
9217
static int default_query_formats_common(AVFilterContext *ctx,
614
                                        AVFilterChannelLayouts *(layouts)(void))
615
{
616
    int ret;
617

9217
    enum AVMediaType type = ctx->inputs  && ctx->inputs [0] ? ctx->inputs [0]->type :
618
                            ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
619
                            AVMEDIA_TYPE_VIDEO;
620
621
9217
    ret = ff_set_common_formats(ctx, ff_all_formats(type));
622
9217
    if (ret < 0)
623
        return ret;
624
9217
    if (type == AVMEDIA_TYPE_AUDIO) {
625
1181
        ret = ff_set_common_channel_layouts(ctx, layouts());
626
1181
        if (ret < 0)
627
            return ret;
628
1181
        ret = ff_set_common_samplerates(ctx, ff_all_samplerates());
629
1181
        if (ret < 0)
630
            return ret;
631
    }
632
633
9217
    return 0;
634
}
635
636
9217
int ff_default_query_formats(AVFilterContext *ctx)
637
{
638
9217
    return default_query_formats_common(ctx, ff_all_channel_counts);
639
}
640
641
int ff_query_formats_all_layouts(AVFilterContext *ctx)
642
{
643
    return default_query_formats_common(ctx, ff_all_channel_layouts);
644
}
645
646
/* internal functions for parsing audio format arguments */
647
648
6712
int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx)
649
{
650
    char *tail;
651
6712
    int pix_fmt = av_get_pix_fmt(arg);
652
6712
    if (pix_fmt == AV_PIX_FMT_NONE) {
653
        pix_fmt = strtol(arg, &tail, 0);
654
        if (*tail || !av_pix_fmt_desc_get(pix_fmt)) {
655
            av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
656
            return AVERROR(EINVAL);
657
        }
658
    }
659
6712
    *ret = pix_fmt;
660
6712
    return 0;
661
}
662
663
int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
664
{
665
    char *tail;
666
    int sfmt = av_get_sample_fmt(arg);
667
    if (sfmt == AV_SAMPLE_FMT_NONE) {
668
        sfmt = strtol(arg, &tail, 0);
669
        if (*tail || av_get_bytes_per_sample(sfmt)<=0) {
670
            av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
671
            return AVERROR(EINVAL);
672
        }
673
    }
674
    *ret = sfmt;
675
    return 0;
676
}
677
678
int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
679
{
680
    AVRational r;
681
    if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0  ||r.den<=0) {
682
        av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
683
        return AVERROR(EINVAL);
684
    }
685
    *ret = r;
686
    return 0;
687
}
688
689
14
int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
690
{
691
    char *tail;
692
14
    double srate = av_strtod(arg, &tail);
693


14
    if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
694
        av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
695
        return AVERROR(EINVAL);
696
    }
697
14
    *ret = srate;
698
14
    return 0;
699
}
700
701
36
int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg,
702
                            void *log_ctx)
703
{
704
    int64_t chlayout;
705
    int nb_channels;
706
707
36
    if (av_get_extended_channel_layout(arg, &chlayout, &nb_channels) < 0) {
708
6
        av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
709
6
        return AVERROR(EINVAL);
710
    }
711

30
    if (!chlayout && !nret) {
712
        av_log(log_ctx, AV_LOG_ERROR, "Unknown channel layout '%s' is not supported.\n", arg);
713
        return AVERROR(EINVAL);
714
    }
715
30
    *ret = chlayout;
716
30
    if (nret)
717
30
        *nret = nb_channels;
718
719
30
    return 0;
720
}