2 * Filter layer - format negotiation
3 * Copyright (c) 2007 Bobby Bingham
5 * This file is part of Libav.
7 * Libav 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 * Libav 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 Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "libavutil/pixdesc.h"
28 * Add all refs from a to ret and destroy a.
30 #define MERGE_REF(ret, a, fmts, type, fail) \
35 if (!(tmp = av_realloc(ret->refs, \
36 sizeof(*tmp) * (ret->refcount + a->refcount)))) \
40 for (i = 0; i < a->refcount; i ++) { \
41 ret->refs[ret->refcount] = a->refs[i]; \
42 *ret->refs[ret->refcount++] = ret; \
51 * Add all formats common for a and b to ret, copy the refs and destroy
54 #define MERGE_FORMATS(ret, a, b, fmts, nb, type, fail) \
56 int i, j, k = 0, count = FFMIN(a->nb, b->nb); \
58 if (!(ret = av_mallocz(sizeof(*ret)))) \
62 if (!(ret->fmts = av_malloc(sizeof(*ret->fmts) * count))) \
64 for (i = 0; i < a->nb; i++) \
65 for (j = 0; j < b->nb; j++) \
66 if (a->fmts[i] == b->fmts[j]) \
67 ret->fmts[k++] = a->fmts[i]; \
71 /* check that there was at least one common format */ \
75 MERGE_REF(ret, a, fmts, type, fail); \
76 MERGE_REF(ret, b, fmts, type, fail); \
79 AVFilterFormats *ff_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
81 AVFilterFormats *ret = NULL;
86 MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
92 av_freep(&ret->formats);
98 AVFilterFormats *ff_merge_samplerates(AVFilterFormats *a,
101 AVFilterFormats *ret = NULL;
103 if (a == b) return a;
105 if (a->format_count && b->format_count) {
106 MERGE_FORMATS(ret, a, b, formats, format_count, AVFilterFormats, fail);
107 } else if (a->format_count) {
108 MERGE_REF(a, b, formats, AVFilterFormats, fail);
111 MERGE_REF(b, a, formats, AVFilterFormats, fail);
118 av_freep(&ret->refs);
119 av_freep(&ret->formats);
125 AVFilterChannelLayouts *ff_merge_channel_layouts(AVFilterChannelLayouts *a,
126 AVFilterChannelLayouts *b)
128 AVFilterChannelLayouts *ret = NULL;
130 if (a == b) return a;
132 if (a->nb_channel_layouts && b->nb_channel_layouts) {
133 MERGE_FORMATS(ret, a, b, channel_layouts, nb_channel_layouts,
134 AVFilterChannelLayouts, fail);
135 } else if (a->nb_channel_layouts) {
136 MERGE_REF(a, b, channel_layouts, AVFilterChannelLayouts, fail);
139 MERGE_REF(b, a, channel_layouts, AVFilterChannelLayouts, fail);
146 av_freep(&ret->refs);
147 av_freep(&ret->channel_layouts);
153 int ff_fmt_is_in(int fmt, const int *fmts)
157 for (p = fmts; *p != PIX_FMT_NONE; p++) {
164 AVFilterFormats *ff_make_format_list(const int *fmts)
166 AVFilterFormats *formats;
169 for (count = 0; fmts[count] != -1; count++)
172 formats = av_mallocz(sizeof(*formats));
174 formats->formats = av_malloc(sizeof(*formats->formats) * count);
175 formats->format_count = count;
176 memcpy(formats->formats, fmts, sizeof(*formats->formats) * count);
181 #define ADD_FORMAT(f, fmt, type, list, nb) \
185 if (!(*f) && !(*f = av_mallocz(sizeof(**f)))) \
186 return AVERROR(ENOMEM); \
188 fmts = av_realloc((*f)->list, \
189 sizeof(*(*f)->list) * ((*f)->nb + 1));\
191 return AVERROR(ENOMEM); \
194 (*f)->list[(*f)->nb++] = fmt; \
198 int ff_add_format(AVFilterFormats **avff, int fmt)
200 ADD_FORMAT(avff, fmt, int, formats, format_count);
203 int ff_add_channel_layout(AVFilterChannelLayouts **l, uint64_t channel_layout)
205 ADD_FORMAT(l, channel_layout, uint64_t, channel_layouts, nb_channel_layouts);
208 AVFilterFormats *ff_all_formats(enum AVMediaType type)
210 AVFilterFormats *ret = NULL;
212 int num_formats = type == AVMEDIA_TYPE_VIDEO ? PIX_FMT_NB :
213 type == AVMEDIA_TYPE_AUDIO ? AV_SAMPLE_FMT_NB : 0;
215 for (fmt = 0; fmt < num_formats; fmt++)
216 if ((type != AVMEDIA_TYPE_VIDEO) ||
217 (type == AVMEDIA_TYPE_VIDEO && !(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_HWACCEL)))
218 ff_add_format(&ret, fmt);
223 AVFilterFormats *ff_planar_sample_fmts(void)
225 AVFilterFormats *ret = NULL;
228 for (fmt = 0; fmt < AV_SAMPLE_FMT_NB; fmt++)
229 if (av_sample_fmt_is_planar(fmt))
230 ff_add_format(&ret, fmt);
235 AVFilterFormats *ff_all_samplerates(void)
237 AVFilterFormats *ret = av_mallocz(sizeof(*ret));
241 AVFilterChannelLayouts *ff_all_channel_layouts(void)
243 AVFilterChannelLayouts *ret = av_mallocz(sizeof(*ret));
247 #define FORMATS_REF(f, ref) \
250 f->refs = av_realloc(f->refs, sizeof(*f->refs) * ++f->refcount); \
251 f->refs[f->refcount-1] = ref; \
254 void ff_channel_layouts_ref(AVFilterChannelLayouts *f, AVFilterChannelLayouts **ref)
259 void ff_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
264 #define FIND_REF_INDEX(ref, idx) \
267 for (i = 0; i < (*ref)->refcount; i ++) \
268 if((*ref)->refs[i] == ref) { \
274 #define FORMATS_UNREF(ref, list) \
281 FIND_REF_INDEX(ref, idx); \
284 memmove((*ref)->refs + idx, (*ref)->refs + idx + 1, \
285 sizeof(*(*ref)->refs) * ((*ref)->refcount - idx - 1)); \
287 if(!--(*ref)->refcount) { \
288 av_free((*ref)->list); \
289 av_free((*ref)->refs); \
295 void ff_formats_unref(AVFilterFormats **ref)
297 FORMATS_UNREF(ref, formats);
300 void ff_channel_layouts_unref(AVFilterChannelLayouts **ref)
302 FORMATS_UNREF(ref, channel_layouts);
305 #define FORMATS_CHANGEREF(oldref, newref) \
309 FIND_REF_INDEX(oldref, idx); \
312 (*oldref)->refs[idx] = newref; \
318 void ff_channel_layouts_changeref(AVFilterChannelLayouts **oldref,
319 AVFilterChannelLayouts **newref)
321 FORMATS_CHANGEREF(oldref, newref);
324 void ff_formats_changeref(AVFilterFormats **oldref, AVFilterFormats **newref)
326 FORMATS_CHANGEREF(oldref, newref);
329 #define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
333 for (i = 0; i < ctx->input_count; i++) { \
334 if (ctx->inputs[i]) { \
335 ref(fmts, &ctx->inputs[i]->out_fmts); \
339 for (i = 0; i < ctx->output_count; i++) { \
340 if (ctx->outputs[i]) { \
341 ref(fmts, &ctx->outputs[i]->in_fmts); \
347 av_freep(&fmts->list); \
348 av_freep(&fmts->refs); \
353 void ff_set_common_channel_layouts(AVFilterContext *ctx,
354 AVFilterChannelLayouts *layouts)
356 SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
357 ff_channel_layouts_ref, channel_layouts);
360 void ff_set_common_samplerates(AVFilterContext *ctx,
361 AVFilterFormats *samplerates)
363 SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
364 ff_formats_ref, formats);
368 * A helper for query_formats() which sets all links to the same list of
369 * formats. If there are no links hooked to this filter, the list of formats is
372 void ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
374 SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
375 ff_formats_ref, formats);
378 int ff_default_query_formats(AVFilterContext *ctx)
380 enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
381 ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
384 ff_set_common_formats(ctx, ff_all_formats(type));
385 if (type == AVMEDIA_TYPE_AUDIO) {
386 ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
387 ff_set_common_samplerates(ctx, ff_all_samplerates());
393 #if FF_API_FILTERS_PUBLIC
394 int avfilter_default_query_formats(AVFilterContext *ctx)
396 return ff_default_query_formats(ctx);
398 void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
400 ff_set_common_formats(ctx, formats);
402 AVFilterFormats *avfilter_make_format_list(const int *fmts)
404 return ff_make_format_list(fmts);
406 int avfilter_add_format(AVFilterFormats **avff, int fmt)
408 return ff_add_format(avff, fmt);
410 AVFilterFormats *avfilter_all_formats(enum AVMediaType type)
412 return ff_all_formats(type);
414 AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b)
416 return ff_merge_formats(a, b);
418 void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref)
420 ff_formats_ref(f, ref);
422 void avfilter_formats_unref(AVFilterFormats **ref)
424 ff_formats_unref(ref);
426 void avfilter_formats_changeref(AVFilterFormats **oldref,
427 AVFilterFormats **newref)
429 ff_formats_changeref(oldref, newref);