blob: d4de86223750373006311fa058147c6ddee85ad7
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 | 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 | |
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 | |
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 | |
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 | |
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 | |
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 | |
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 | 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 | int ff_add_format(AVFilterFormats **avff, int64_t fmt) |
338 | { |
339 | ADD_FORMAT(avff, fmt, ff_formats_unref, int, formats, nb_formats); |
340 | return 0; |
341 | } |
342 | |
343 | int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout) |
344 | { |
345 | av_assert1(!(*l && (*l)->all_layouts)); |
346 | ADD_FORMAT(l, channel_layout, ff_channel_layouts_unref, uint64_t, channel_layouts, nb_channel_layouts); |
347 | return 0; |
348 | } |
349 | |
350 | AVFilterFormats *ff_all_formats(enum AVMediaType type) |
351 | { |
352 | AVFilterFormats *ret = NULL; |
353 | |
354 | if (type == AVMEDIA_TYPE_VIDEO) { |
355 | const AVPixFmtDescriptor *desc = NULL; |
356 | while ((desc = av_pix_fmt_desc_next(desc))) { |
357 | if (ff_add_format(&ret, av_pix_fmt_desc_get_id(desc)) < 0) |
358 | return NULL; |
359 | } |
360 | } else if (type == AVMEDIA_TYPE_AUDIO) { |
361 | enum AVSampleFormat fmt = 0; |
362 | while (av_get_sample_fmt_name(fmt)) { |
363 | if (ff_add_format(&ret, fmt) < 0) |
364 | return NULL; |
365 | fmt++; |
366 | } |
367 | } |
368 | |
369 | 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 | AVFilterFormats *ff_planar_sample_fmts(void) |
383 | { |
384 | AVFilterFormats *ret = NULL; |
385 | int fmt; |
386 | |
387 | for (fmt = 0; av_get_bytes_per_sample(fmt)>0; fmt++) |
388 | if (av_sample_fmt_is_planar(fmt)) |
389 | if (ff_add_format(&ret, fmt) < 0) |
390 | return NULL; |
391 | |
392 | return ret; |
393 | } |
394 | |
395 | AVFilterFormats *ff_all_samplerates(void) |
396 | { |
397 | AVFilterFormats *ret = av_mallocz(sizeof(*ret)); |
398 | return ret; |
399 | } |
400 | |
401 | AVFilterChannelLayouts *ff_all_channel_layouts(void) |
402 | { |
403 | AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret)); |
404 | if (!ret) |
405 | return NULL; |
406 | ret->all_layouts = 1; |
407 | return ret; |
408 | } |
409 | |
410 | AVFilterChannelLayouts *ff_all_channel_counts(void) |
411 | { |
412 | AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret)); |
413 | if (!ret) |
414 | return NULL; |
415 | ret->all_layouts = ret->all_counts = 1; |
416 | 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 | int ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref) |
436 | { |
437 | FORMATS_REF(f, ref, ff_channel_layouts_unref); |
438 | } |
439 | |
440 | int ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref) |
441 | { |
442 | 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 | void ff_formats_unref(AVFilterFormats **ref) |
477 | { |
478 | FORMATS_UNREF(ref, formats); |
479 | } |
480 | |
481 | void ff_channel_layouts_unref(AVFilterChannelLayouts **ref) |
482 | { |
483 | 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 | void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref, |
500 | AVFilterChannelLayouts **newref) |
501 | { |
502 | FORMATS_CHANGEREF(oldref, newref); |
503 | } |
504 | |
505 | void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref) |
506 | { |
507 | FORMATS_CHANGEREF(oldref, newref); |
508 | } |
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 | int ff_set_common_channel_layouts(AVFilterContext *ctx, |
550 | AVFilterChannelLayouts *layouts) |
551 | { |
552 | 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 | int ff_set_common_samplerates(AVFilterContext *ctx, |
557 | AVFilterFormats *samplerates) |
558 | { |
559 | 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 | int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats) |
569 | { |
570 | SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats, |
571 | ff_formats_ref, ff_formats_unref, formats); |
572 | } |
573 | |
574 | static int default_query_formats_common(AVFilterContext *ctx, |
575 | AVFilterChannelLayouts *(layouts)(void)) |
576 | { |
577 | int ret; |
578 | enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type : |
579 | ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type : |
580 | AVMEDIA_TYPE_VIDEO; |
581 | |
582 | ret = ff_set_common_formats(ctx, ff_all_formats(type)); |
583 | if (ret < 0) |
584 | return ret; |
585 | if (type == AVMEDIA_TYPE_AUDIO) { |
586 | ret = ff_set_common_channel_layouts(ctx, layouts()); |
587 | if (ret < 0) |
588 | return ret; |
589 | ret = ff_set_common_samplerates(ctx, ff_all_samplerates()); |
590 | if (ret < 0) |
591 | return ret; |
592 | } |
593 | |
594 | return 0; |
595 | } |
596 | |
597 | int ff_default_query_formats(AVFilterContext *ctx) |
598 | { |
599 | return default_query_formats_common(ctx, ff_all_channel_counts); |
600 | } |
601 | |
602 | int ff_query_formats_all_layouts(AVFilterContext *ctx) |
603 | { |
604 | return default_query_formats_common(ctx, ff_all_channel_layouts); |
605 | } |
606 | |
607 | /* internal functions for parsing audio format arguments */ |
608 | |
609 | int ff_parse_pixel_format(enum AVPixelFormat *ret, const char *arg, void *log_ctx) |
610 | { |
611 | char *tail; |
612 | int pix_fmt = av_get_pix_fmt(arg); |
613 | if (pix_fmt == AV_PIX_FMT_NONE) { |
614 | pix_fmt = strtol(arg, &tail, 0); |
615 | if (*tail || !av_pix_fmt_desc_get(pix_fmt)) { |
616 | av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg); |
617 | return AVERROR(EINVAL); |
618 | } |
619 | } |
620 | *ret = pix_fmt; |
621 | return 0; |
622 | } |
623 | |
624 | int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx) |
625 | { |
626 | char *tail; |
627 | int sfmt = av_get_sample_fmt(arg); |
628 | if (sfmt == AV_SAMPLE_FMT_NONE) { |
629 | sfmt = strtol(arg, &tail, 0); |
630 | if (*tail || av_get_bytes_per_sample(sfmt)<=0) { |
631 | av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg); |
632 | return AVERROR(EINVAL); |
633 | } |
634 | } |
635 | *ret = sfmt; |
636 | return 0; |
637 | } |
638 | |
639 | int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx) |
640 | { |
641 | AVRational r; |
642 | if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0 ||r.den<=0) { |
643 | av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg); |
644 | return AVERROR(EINVAL); |
645 | } |
646 | *ret = r; |
647 | return 0; |
648 | } |
649 | |
650 | int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx) |
651 | { |
652 | char *tail; |
653 | double srate = av_strtod(arg, &tail); |
654 | if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) { |
655 | av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg); |
656 | return AVERROR(EINVAL); |
657 | } |
658 | *ret = srate; |
659 | return 0; |
660 | } |
661 | |
662 | 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 | int nb_channels; |
668 | |
669 | if (av_get_extended_channel_layout(arg, &chlayout, &nb_channels) < 0) { |
670 | /* [TEMPORARY 2016-12 -> 2017-12]*/ |
671 | nb_channels = strtol(arg, &tail, 10); |
672 | if (!errno && *tail == 'c' && *(tail + 1) == '\0' && nb_channels > 0 && nb_channels < 64) { |
673 | chlayout = 0; |
674 | av_log(log_ctx, AV_LOG_WARNING, "Deprecated channel count specification '%s'. This will stop working in releases made in 2018 and after.\n", arg); |
675 | } else { |
676 | av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg); |
677 | return AVERROR(EINVAL); |
678 | } |
679 | } |
680 | if (!chlayout && !nret) { |
681 | av_log(log_ctx, AV_LOG_ERROR, "Unknown channel layout '%s' is not supported.\n", arg); |
682 | return AVERROR(EINVAL); |
683 | } |
684 | *ret = chlayout; |
685 | if (nret) |
686 | *nret = nb_channels; |
687 | |
688 | return 0; |
689 | } |
690 |