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