diff --git a/doc/APIchanges b/doc/APIchanges index dc352e72c1..3a3fca9438 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,15 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-06-19 - xxxxxxx - lavfi 2.23.0 - avfilter.h + Add layout negotiation fields and helper functions. + + In particular, add in_chlayouts and out_chlayouts to AVFilterLink, + and the functions: + avfilter_set_common_sample_formats() + avfilter_set_common_channel_layouts() + avfilter_all_channel_layouts() + 2011-06-19 - xxxxxxx - lavfi 2.22.0 - AVFilterFormats Change type of AVFilterFormats.formats from int * to int64_t *, and update formats handling API accordingly. diff --git a/ffplay.c b/ffplay.c index 548fda627a..b88387691d 100644 --- a/ffplay.c +++ b/ffplay.c @@ -1644,7 +1644,7 @@ static int input_query_formats(AVFilterContext *ctx) priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 3b2e3ca2be..44dd515518 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -217,6 +217,9 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, if (link->out_formats) avfilter_formats_changeref(&link->out_formats, &filt->outputs[filt_dstpad_idx]->out_formats); + if (link->out_chlayouts) + avfilter_formats_changeref(&link->out_chlayouts, + &filt->outputs[filt_dstpad_idx]->out_chlayouts); return 0; } diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 1a3a69de57..c276f3037e 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -26,7 +26,7 @@ #include "libavutil/samplefmt.h" #define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 22 +#define LIBAVFILTER_VERSION_MINOR 23 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ @@ -255,6 +255,11 @@ int avfilter_add_format(AVFilterFormats **avff, int64_t fmt); */ AVFilterFormats *avfilter_all_formats(enum AVMediaType type); +/** + * Return a list of all channel layouts supported by FFmpeg. + */ +AVFilterFormats *avfilter_all_channel_layouts(void); + /** * Return a format list which contains the intersection of the formats of * a and b. Also, all the references of a, all the references of b, and @@ -466,11 +471,13 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per int64_t channel_layout, int planar); /** - * A helper for query_formats() which sets all links to the same list of - * formats. If there are no links hooked to this filter, the list of formats is - * freed. + * Helpers for query_formats() which set all links to the same list of + * formats/layouts. If there are no links hooked to this filter, the list + * of formats is freed. */ -void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats); +void avfilter_set_common_pixel_formats(AVFilterContext *ctx, AVFilterFormats *formats); +void avfilter_set_common_sample_formats(AVFilterContext *ctx, AVFilterFormats *formats); +void avfilter_set_common_channel_layouts(AVFilterContext *ctx, AVFilterFormats *formats); /** Default handler for query_formats() */ int avfilter_default_query_formats(AVFilterContext *ctx); @@ -521,9 +528,9 @@ typedef struct AVFilter { void (*uninit)(AVFilterContext *ctx); /** - * Queries formats supported by the filter and its pads, and sets the - * in_formats for links connected to its output pads, and out_formats - * for links connected to its input pads. + * Queries formats/layouts supported by the filter and its pads, and sets + * the in_formats/in_chlayouts for links connected to its output pads, + * and out_formats/out_chlayouts for links connected to its input pads. * * @return zero on success, a negative value corresponding to an * AVERROR code otherwise @@ -593,13 +600,18 @@ struct AVFilterLink { int format; ///< agreed upon media format /** - * Lists of formats supported by the input and output filters respectively. - * These lists are used for negotiating the format to actually be used, - * which will be loaded into the format member, above, when chosen. + * Lists of formats and channel layouts supported by the input and output + * filters respectively. These lists are used for negotiating the format + * to actually be used, which will be loaded into the format and + * channel_layout members, above, when chosen. + * */ AVFilterFormats *in_formats; AVFilterFormats *out_formats; + AVFilterFormats *in_chlayouts; + AVFilterFormats *out_chlayouts; + /** * The buffer reference currently being sent across the link by the source * filter. This is used internally by the filter system to allow diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 60d529ba73..04768617de 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -195,9 +195,16 @@ static void pick_format(AVFilterLink *link) link->in_formats->format_count = 1; link->format = link->in_formats->formats[0]; - avfilter_formats_unref(&link->in_formats); avfilter_formats_unref(&link->out_formats); + + if (link->type == AVMEDIA_TYPE_AUDIO) { + link->in_chlayouts->format_count = 1; + link->channel_layout = link->in_chlayouts->formats[0]; + avfilter_formats_unref(&link->in_chlayouts); + avfilter_formats_unref(&link->out_chlayouts); + } + } static void pick_formats(AVFilterGraph *graph) diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c index c39ed64048..b03816dd24 100644 --- a/libavfilter/defaults.c +++ b/libavfilter/defaults.c @@ -197,45 +197,54 @@ int avfilter_default_config_output_link(AVFilterLink *link) return 0; } -/** - * A helper for query_formats() which sets all links to the same list of - * formats. If there are no links hooked to this filter, the list of formats is - * freed. - * - * FIXME: this will need changed for filters with a mix of pad types - * (video + audio, etc) - */ -void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats) +static void set_common_formats(AVFilterContext *ctx, AVFilterFormats *fmts, + enum AVMediaType type, int offin, int offout) { - int count = 0, i; + int i; + for (i = 0; i < ctx->input_count; i++) + if (ctx->inputs[i] && ctx->inputs[i]->type == type) + avfilter_formats_ref(fmts, + (AVFilterFormats**)((void*)ctx->inputs[i]+offout)); - for (i = 0; i < ctx->input_count; i++) { - if (ctx->inputs[i]) { - avfilter_formats_ref(formats, &ctx->inputs[i]->out_formats); - count++; - } - } - for (i = 0; i < ctx->output_count; i++) { - if (ctx->outputs[i]) { - avfilter_formats_ref(formats, &ctx->outputs[i]->in_formats); - count++; - } - } + for (i = 0; i < ctx->output_count; i++) + if (ctx->outputs[i] && ctx->outputs[i]->type == type) + avfilter_formats_ref(fmts, + (AVFilterFormats**)((void*)ctx->outputs[i]+offin)); - if (!count) { - av_free(formats->formats); - av_free(formats->refs); - av_free(formats); + if (!fmts->refcount) { + av_free(fmts->formats); + av_free(fmts->refs); + av_free(fmts); } } +void avfilter_set_common_pixel_formats(AVFilterContext *ctx, AVFilterFormats *formats) +{ + set_common_formats(ctx, formats, AVMEDIA_TYPE_VIDEO, + offsetof(AVFilterLink, in_formats), + offsetof(AVFilterLink, out_formats)); +} + +void avfilter_set_common_sample_formats(AVFilterContext *ctx, AVFilterFormats *formats) +{ + set_common_formats(ctx, formats, AVMEDIA_TYPE_AUDIO, + offsetof(AVFilterLink, in_formats), + offsetof(AVFilterLink, out_formats)); +} + +void avfilter_set_common_channel_layouts(AVFilterContext *ctx, AVFilterFormats *formats) +{ + set_common_formats(ctx, formats, AVMEDIA_TYPE_AUDIO, + offsetof(AVFilterLink, in_chlayouts), + offsetof(AVFilterLink, out_chlayouts)); +} + int avfilter_default_query_formats(AVFilterContext *ctx) { - enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type : - ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type : - AVMEDIA_TYPE_VIDEO; + avfilter_set_common_pixel_formats(ctx, avfilter_all_formats(AVMEDIA_TYPE_VIDEO)); + avfilter_set_common_sample_formats(ctx, avfilter_all_formats(AVMEDIA_TYPE_AUDIO)); + avfilter_set_common_channel_layouts(ctx, avfilter_all_channel_layouts()); - avfilter_set_common_formats(ctx, avfilter_all_formats(type)); return 0; } diff --git a/libavfilter/formats.c b/libavfilter/formats.c index 4e101c570c..49977c51fd 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -20,6 +20,7 @@ */ #include "libavutil/pixdesc.h" +#include "libavutil/audioconvert.h" #include "avfilter.h" /** @@ -139,6 +140,27 @@ AVFilterFormats *avfilter_all_formats(enum AVMediaType type) return ret; } +AVFilterFormats *avfilter_all_channel_layouts(void) +{ + static int64_t chlayouts[] = { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_QUAD, + AV_CH_LAYOUT_5POINT0, + AV_CH_LAYOUT_5POINT0_BACK, + AV_CH_LAYOUT_5POINT1, + AV_CH_LAYOUT_5POINT1_BACK, + AV_CH_LAYOUT_5POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX, + AV_CH_LAYOUT_7POINT1, + AV_CH_LAYOUT_7POINT1_WIDE, + AV_CH_LAYOUT_7POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX, + -1, + }; + + return avfilter_make_format64_list(chlayouts); +} + void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref) { *ref = f; diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c index 658c30fd22..41b4a92ce5 100644 --- a/libavfilter/vf_blackframe.c +++ b/libavfilter/vf_blackframe.c @@ -44,7 +44,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index 8182a36531..531b8de658 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -104,7 +104,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c index 000c8bb2c2..a997cbede8 100644 --- a/libavfilter/vf_cropdetect.c +++ b/libavfilter/vf_cropdetect.c @@ -46,7 +46,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c index 3785072920..1ad8e94de2 100644 --- a/libavfilter/vf_drawbox.c +++ b/libavfilter/vf_drawbox.c @@ -70,7 +70,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index cf0eb43344..f495f68424 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -334,7 +334,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index 28179a3da4..6c2a23dac3 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -78,7 +78,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_format.c b/libavfilter/vf_format.c index c42e0bb373..9ecb0269ce 100644 --- a/libavfilter/vf_format.c +++ b/libavfilter/vf_format.c @@ -88,7 +88,7 @@ static AVFilterFormats *make_format_list(FormatContext *format, int flag) #if CONFIG_FORMAT_FILTER static int query_formats_format(AVFilterContext *ctx) { - avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 1)); + avfilter_set_common_pixel_formats(ctx, make_format_list(ctx->priv, 1)); return 0; } @@ -118,7 +118,7 @@ AVFilter avfilter_vf_format = { #if CONFIG_NOFORMAT_FILTER static int query_formats_noformat(AVFilterContext *ctx) { - avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 0)); + avfilter_set_common_pixel_formats(ctx, make_format_list(ctx->priv, 0)); return 0; } diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index 0cb5fd30b5..ab1957089e 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -332,7 +332,7 @@ static int query_formats(AVFilterContext *ctx) if (!formats) return AVERROR(ENOMEM); - avfilter_set_common_formats(ctx, formats); + avfilter_set_common_pixel_formats(ctx, formats); return 0; } diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index 32dd3c1072..084dcc5c3c 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -160,7 +160,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c index f1a37e7f5e..9b995a9894 100644 --- a/libavfilter/vf_hflip.c +++ b/libavfilter/vf_hflip.c @@ -62,7 +62,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c index 78a7bf71c7..993ce7623d 100644 --- a/libavfilter/vf_hqdn3d.c +++ b/libavfilter/vf_hqdn3d.c @@ -268,7 +268,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index b789c8e19c..e1b51c52c2 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -61,7 +61,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_BGR24, PIX_FMT_BGRA, PIX_FMT_GRAY8, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c index 792e274c33..c457972474 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -161,7 +161,7 @@ static int query_formats(AVFilterContext *ctx) enum PixelFormat *pix_fmts = lut->is_rgb ? rgb_pix_fmts : lut->is_yuv ? yuv_pix_fmts : all_pix_fmts; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_mp.c b/libavfilter/vf_mp.c index 0642b44f00..36616b9c94 100644 --- a/libavfilter/vf_mp.c +++ b/libavfilter/vf_mp.c @@ -796,7 +796,7 @@ static int query_formats(AVFilterContext *ctx) } //We assume all allowed input formats are also allowed output formats - avfilter_set_common_formats(ctx, avfmts); + avfilter_set_common_pixel_formats(ctx, avfmts); return 0; } diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index 93d613d035..0ca5bd08fc 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -83,7 +83,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index a5247c9753..8b11ae8d53 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -83,7 +83,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index fa75de5d94..3542ca3eac 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -155,7 +155,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_YUVJ444P, PIX_FMT_YUVJ440P, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index d608c65242..296328b71a 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -332,7 +332,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vsink_buffer.c b/libavfilter/vsink_buffer.c index c0824606a9..b5627b4f82 100644 --- a/libavfilter/vsink_buffer.c +++ b/libavfilter/vsink_buffer.c @@ -66,7 +66,7 @@ static int query_formats(AVFilterContext *ctx) { BufferSinkContext *buf = ctx->priv; - avfilter_set_common_formats(ctx, avfilter_make_format_list(buf->pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(buf->pix_fmts)); return 0; } diff --git a/libavfilter/vsrc_buffer.c b/libavfilter/vsrc_buffer.c index 246444b3ac..54867f7766 100644 --- a/libavfilter/vsrc_buffer.c +++ b/libavfilter/vsrc_buffer.c @@ -166,7 +166,7 @@ static int query_formats(AVFilterContext *ctx) BufferSourceContext *c = ctx->priv; enum PixelFormat pix_fmts[] = { c->pix_fmt, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c index 62c7f80945..00bfb66dee 100644 --- a/libavfilter/vsrc_color.c +++ b/libavfilter/vsrc_color.c @@ -99,7 +99,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index 7a3babbec8..eea2660cea 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -203,7 +203,7 @@ static int query_formats(AVFilterContext *ctx) MovieContext *movie = ctx->priv; enum PixelFormat pix_fmts[] = { movie->codec_ctx->pix_fmt, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; }