2 * Filter layer - format negotiation
3 * Copyright (c) 2007 Bobby Bingham
5 * This file is part of FFmpeg.
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.
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.
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
22 #include "libavutil/eval.h"
23 #include "libavutil/pixdesc.h"
24 #include "libavutil/parseutils.h"
25 #include "libavutil/audioconvert.h"
31 * Add all refs from a to ret and destroy a.
33 #define MERGE_REF(ret, a, fmts, type, fail) \
38 if (!(tmp = av_realloc(ret->refs, \
39 sizeof(*tmp) * (ret->refcount + a->refcount)))) \
43 for (i = 0; i < a->refcount; i ++) { \
44 ret->refs[ret->refcount] = a->refs[i]; \
45 *ret->refs[ret->refcount++] = ret; \
54 * Add all formats common for a and b to ret, copy the refs and destroy
57 #define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail) \
59 int i, j, k = 0, count = FFMIN(a->nb, b->nb); \
61 if (!(ret = av_mallocz(sizeof(*ret)))) \
65 if (!(ret->fmts = av_malloc(sizeof(*ret->fmts) * count))) \
67 for (i = 0; i < a->nb; i++) \
68 for (j = 0; j < b->nb; j++) \
69 if (a->fmts[i] == b->fmts[j]) { \
70 if(k >= FFMIN(a->nb, b->nb)){ \
71 av_log(0, AV_LOG_ERROR, "Duplicate formats in avfilter_merge_formats() detected\n"); \
76 ret->fmts[k++] = a->fmts[i]; \
80 /* check that there was at least one common format */ \
84 MERGE_REF(ret, a, fmts, type, fail); \
85 MERGE_REF(ret, b, fmts, type, fail); \
88 AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
90 AVFilterFormats *ret = NULL;
95 MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
100 av_freep(&ret->refs);
101 av_freep(&ret->formats);
107 AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
110 AVFilterFormats *ret = NULL;
112 if (a == b) return a;
114 if (a->format_count && b->format_count) {
115 MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
116 } else if (a->format_count) {
117 MERGE_REF(a, b, formats, AVFilterFormats, fail);
120 MERGE_REF(b, a, formats, AVFilterFormats, fail);
127 av_freep(&ret->refs);
128 av_freep(&ret->formats);
134 AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
135 AVFilterChannelLayouts *b)
137 AVFilterChannelLayouts *ret = NULL;
139 if (a == b) return a;
141 if (a->nb_channel_layouts && b->nb_channel_layouts) {
142 MERGE_FORMATS(ret, a, b, channel_layouts, nb_channel_layouts,
143 AVFilterChannelLayouts, fail);
144 } else if (a->nb_channel_layouts) {
145 MERGE_REF(a, b, channel_layouts, AVFilterChannelLayouts, fail);
148 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail);
155 av_freep(&ret->refs);
156 av_freep(&ret->channel_layouts);
162 int ff_fmt_is_in(int fmt, const int *fmts)
166 for (p = fmts; *p != -1; p++) {
173 #define COPY_INT_LIST(list_copy, list, type) { \
176 for (count = 0; list[count] != -1; count++) \
178 list_copy = av_calloc(count+1, sizeof(type)); \
180 memcpy(list_copy, list, sizeof(type) * count); \
181 list_copy[count] = -1; \
185 int *ff_copy_int_list(const int * const list)
188 COPY_INT_LIST(ret, list, int);
192 int64_t *ff_copy_int64_list(const int64_t * const list)
195 COPY_INT_LIST(ret, list, int64_t);
199 #define MAKE_FORMAT_LIST(type, field, count_field) \
203 for (count = 0; fmts[count] != -1; count++) \
205 formats = av_mallocz(sizeof(*formats)); \
206 if (!formats) return NULL; \
207 formats->count_field = count; \
209 formats->field = av_malloc(sizeof(*formats->field)*count); \
210 if (!formats->field) { \
216 AVFilterFormats *avfilter_make_format_list(const int *fmts)
218 MAKE_FORMAT_LIST(AVFilterFormats, formats, format_count);
220 formats->formats[count] = fmts[count];
225 AVFilterChannelLayouts *avfilter_make_format64_list(const int64_t *fmts)
227 MAKE_FORMAT_LIST(AVFilterChannelLayouts,
228 channel_layouts, nb_channel_layouts);
230 memcpy(formats->channel_layouts, fmts,
231 sizeof(*formats->channel_layouts) * count);
236 #define ADD_FORMAT(f, fmt, type, list, nb) \
240 if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) \
241 return AVERROR(ENOMEM); \
243 fmts = av_realloc((*f)->list, \
244 sizeof(*(*f)->list) * ((*f)->nb + 1));\
246 return AVERROR(ENOMEM); \
249 (*f)->list[(*f)->nb++] = fmt; \
253 int avfilter_add_format(AVFilterFormats **avff, int64_t fmt)
255 ADD_FORMAT(avff, fmt, int, formats, format_count);
258 int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
260 ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts);
263 #if FF_API_OLD_ALL_FORMATS_API
264 AVFilterFormats *avfilter_all_formats(enum AVMediaType type)
266 return avfilter_make_all_formats(type);
270 AVFilterFormats *avfilter_make_all_formats(enum AVMediaType type)
272 AVFilterFormats *ret = NULL;
274 int num_formats = type == AVMEDIA_TYPE_VIDEO ? PIX_FMT_NB :
275 type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
277 for (fmt = 0; fmt < num_formats; fmt++)
278 if ((type != AVMEDIA_TYPE_VIDEO) ||
279 (type == AVMEDIA_TYPE_VIDEO && !(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_HWACCEL)))
280 avfilter_add_format(&ret, fmt);
285 const int64_t avfilter_all_channel_layouts[] = {
286 #include "all_channel_layouts.inc"
290 // AVFilterFormats *avfilter_make_all_channel_layouts(void)
292 // return avfilter_make_format64_list(avfilter_all_channel_layouts);
296 AVFilterFormats *avfilter_make_all_packing_formats(void)
298 static const int packing[] = {
304 return avfilter_make_format_list(packing);
308 AVFilterFormats *ff_all_samplerates(void)
310 AVFilterFormats *ret = av_mallocz(sizeof(*ret));
314 AVFilterChannelLayouts *ff_all_channel_layouts(void)
316 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
320 #define FORMATS_REF(f, ref) \
323 f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount); \
324 f->refs[f->refcount-1] = ref; \
327 void ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
332 void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
337 #define FIND_REF_INDEX(ref, idx) \
340 for (i = 0; i < (*ref)->refcount; i ++) \
341 if((*ref)->refs[i] == ref) { \
347 #define FORMATS_UNREF(ref, list) \
354 FIND_REF_INDEX(ref, idx); \
357 memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
358 sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
360 if(!--(*ref)->refcount) { \
361 av_free((*ref)->list); \
362 av_free((*ref)->refs); \
368 void avfilter_formats_unref(AVFilterFormats **ref)
370 FORMATS_UNREF(ref, formats);
373 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
375 FORMATS_UNREF(ref, channel_layouts);
378 #define FORMATS_CHANGEREF(oldref, newref) \
382 FIND_REF_INDEX(oldref, idx); \
385 (*oldref)->refs[idx] = newref; \
391 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
392 AVFilterChannelLayouts **newref)
394 FORMATS_CHANGEREF(oldref, newref);
397 void avfilter_formats_changeref(AVFilterFormats **oldref,
398 AVFilterFormats **newref)
400 FORMATS_CHANGEREF(oldref, newref);
403 #define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
407 for (i = 0; i < ctx->input_count; i++) { \
408 if (ctx->inputs[i]) { \
409 ref(fmts, &ctx->inputs[i]->out_fmts); \
413 for (i = 0; i < ctx->output_count; i++) { \
414 if (ctx->outputs[i]) { \
415 ref(fmts, &ctx->outputs[i]->in_fmts); \
421 av_freep(&fmts->list); \
422 av_freep(&fmts->refs); \
427 void ff_set_common_channel_layouts(AVFilterContext *ctx,
428 AVFilterChannelLayouts *layouts)
430 SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
431 ff_channel_layouts_ref, channel_layouts);
434 void ff_set_common_samplerates(AVFilterContext *ctx,
435 AVFilterFormats *samplerates)
437 SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
438 avfilter_formats_ref, formats);
442 * A helper for query_formats() which sets all links to the same list of
443 * formats. If there are no links hooked to this filter, the list of formats is
446 void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
448 SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
449 avfilter_formats_ref, formats);
452 int ff_default_query_formats(AVFilterContext *ctx)
454 enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
455 ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
458 avfilter_set_common_formats(ctx, avfilter_all_formats(type));
459 if (type == AVMEDIA_TYPE_AUDIO) {
460 ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
461 ff_set_common_samplerates(ctx, ff_all_samplerates());
467 /* internal functions for parsing audio format arguments */
469 int ff_parse_pixel_format(enum PixelFormat *ret, const char *arg, void *log_ctx)
472 int pix_fmt = av_get_pix_fmt(arg);
473 if (pix_fmt == PIX_FMT_NONE) {
474 pix_fmt = strtol(arg, &tail, 0);
475 if (*tail || (unsigned)pix_fmt >= PIX_FMT_NB) {
476 av_log(log_ctx, AV_LOG_ERROR, "Invalid pixel format '%s'\n", arg);
477 return AVERROR(EINVAL);
484 int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx)
487 int sfmt = av_get_sample_fmt(arg);
488 if (sfmt == AV_SAMPLE_FMT_NONE) {
489 sfmt = strtol(arg, &tail, 0);
490 if (*tail || (unsigned)sfmt >= AV_SAMPLE_FMT_NB) {
491 av_log(log_ctx, AV_LOG_ERROR, "Invalid sample format '%s'\n", arg);
492 return AVERROR(EINVAL);
499 int ff_parse_time_base(AVRational *ret, const char *arg, void *log_ctx)
502 if(av_parse_ratio(&r, arg, INT_MAX, 0, log_ctx) < 0 ||r.num<=0 ||r.den<=0) {
503 av_log(log_ctx, AV_LOG_ERROR, "Invalid time base '%s'\n", arg);
504 return AVERROR(EINVAL);
510 int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx)
513 double srate = av_strtod(arg, &tail);
514 if (*tail || srate < 1 || (int)srate != srate || srate > INT_MAX) {
515 av_log(log_ctx, AV_LOG_ERROR, "Invalid sample rate '%s'\n", arg);
516 return AVERROR(EINVAL);
522 int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx)
525 int64_t chlayout = av_get_channel_layout(arg);
527 chlayout = strtol(arg, &tail, 10);
528 if (*tail || chlayout == 0) {
529 av_log(log_ctx, AV_LOG_ERROR, "Invalid channel layout '%s'\n", arg);
530 return AVERROR(EINVAL);
537 #if FF_API_FILTERS_PUBLIC
538 int avfilter_default_query_formats(AVFilterContext *ctx)
540 return ff_default_query_formats(ctx);
552 for (cl = avfilter_all_channel_layouts; *cl != -1; cl++) {
553 av_get_channel_layout_string(buf, sizeof(buf), -1, *cl);