Commit ff1f51a8 authored by Anton Khirnov's avatar Anton Khirnov

lavfi: add channel layout/sample rate negotiation.

parent 5775a183
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "audio.h" #include "audio.h"
#include "avfilter.h" #include "avfilter.h"
#include "formats.h"
#include "internal.h" #include "internal.h"
typedef struct ResampleContext { typedef struct ResampleContext {
...@@ -56,10 +57,20 @@ static int query_formats(AVFilterContext *ctx) ...@@ -56,10 +57,20 @@ static int query_formats(AVFilterContext *ctx)
AVFilterFormats *in_formats = avfilter_all_formats(AVMEDIA_TYPE_AUDIO); AVFilterFormats *in_formats = avfilter_all_formats(AVMEDIA_TYPE_AUDIO);
AVFilterFormats *out_formats = avfilter_all_formats(AVMEDIA_TYPE_AUDIO); AVFilterFormats *out_formats = avfilter_all_formats(AVMEDIA_TYPE_AUDIO);
AVFilterFormats *in_samplerates = ff_all_samplerates();
AVFilterFormats *out_samplerates = ff_all_samplerates();
AVFilterChannelLayouts *in_layouts = ff_all_channel_layouts();
AVFilterChannelLayouts *out_layouts = ff_all_channel_layouts();
avfilter_formats_ref(in_formats, &inlink->out_formats); avfilter_formats_ref(in_formats, &inlink->out_formats);
avfilter_formats_ref(out_formats, &outlink->in_formats); avfilter_formats_ref(out_formats, &outlink->in_formats);
avfilter_formats_ref(in_samplerates, &inlink->out_samplerates);
avfilter_formats_ref(out_samplerates, &outlink->in_samplerates);
ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts);
ff_channel_layouts_ref(out_layouts, &outlink->in_channel_layouts);
return 0; return 0;
} }
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "libavcodec/avcodec.h" #include "libavcodec/avcodec.h"
#include "avfilter.h" #include "avfilter.h"
#include "formats.h"
#include "internal.h" #include "internal.h"
unsigned avfilter_version(void) { unsigned avfilter_version(void) {
...@@ -176,6 +177,12 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, ...@@ -176,6 +177,12 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt,
if (link->out_formats) if (link->out_formats)
avfilter_formats_changeref(&link->out_formats, avfilter_formats_changeref(&link->out_formats,
&filt->outputs[filt_dstpad_idx]->out_formats); &filt->outputs[filt_dstpad_idx]->out_formats);
if (link->out_samplerates)
avfilter_formats_changeref(&link->out_samplerates,
&filt->outputs[filt_dstpad_idx]->out_samplerates);
if (link->out_channel_layouts)
ff_channel_layouts_changeref(&link->out_channel_layouts,
&filt->outputs[filt_dstpad_idx]->out_channel_layouts);
return 0; return 0;
} }
...@@ -216,12 +223,6 @@ int avfilter_config_links(AVFilterContext *filter) ...@@ -216,12 +223,6 @@ int avfilter_config_links(AVFilterContext *filter)
link->sample_aspect_ratio = link->src->input_count ? link->sample_aspect_ratio = link->src->input_count ?
link->src->inputs[0]->sample_aspect_ratio : (AVRational){1,1}; link->src->inputs[0]->sample_aspect_ratio : (AVRational){1,1};
if (link->sample_rate == 0 && link->src && link->src->input_count)
link->sample_rate = link->src->inputs[0]->sample_rate;
if (link->channel_layout == 0 && link->src && link->src->input_count)
link->channel_layout = link->src->inputs[0]->channel_layout;
if ((config_link = link->dstpad->config_props)) if ((config_link = link->dstpad->config_props))
if ((ret = config_link(link)) < 0) if ((ret = config_link(link)) < 0)
return ret; return ret;
...@@ -614,6 +615,10 @@ void avfilter_free(AVFilterContext *filter) ...@@ -614,6 +615,10 @@ void avfilter_free(AVFilterContext *filter)
link->src->outputs[link->srcpad - link->src->output_pads] = NULL; link->src->outputs[link->srcpad - link->src->output_pads] = NULL;
avfilter_formats_unref(&link->in_formats); avfilter_formats_unref(&link->in_formats);
avfilter_formats_unref(&link->out_formats); avfilter_formats_unref(&link->out_formats);
avfilter_formats_unref(&link->in_samplerates);
avfilter_formats_unref(&link->out_samplerates);
ff_channel_layouts_unref(&link->in_channel_layouts);
ff_channel_layouts_unref(&link->out_channel_layouts);
} }
av_freep(&link); av_freep(&link);
} }
...@@ -623,6 +628,10 @@ void avfilter_free(AVFilterContext *filter) ...@@ -623,6 +628,10 @@ void avfilter_free(AVFilterContext *filter)
link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL; link->dst->inputs[link->dstpad - link->dst->input_pads] = NULL;
avfilter_formats_unref(&link->in_formats); avfilter_formats_unref(&link->in_formats);
avfilter_formats_unref(&link->out_formats); avfilter_formats_unref(&link->out_formats);
avfilter_formats_unref(&link->in_samplerates);
avfilter_formats_unref(&link->out_samplerates);
ff_channel_layouts_unref(&link->in_channel_layouts);
ff_channel_layouts_unref(&link->out_channel_layouts);
} }
av_freep(&link); av_freep(&link);
} }
......
This diff is collapsed.
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "avfilter.h" #include "avfilter.h"
#include "internal.h" #include "internal.h"
#include "formats.h"
/* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */ /* TODO: buffer pool. see comment for avfilter_default_get_video_buffer() */
void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr) void ff_avfilter_default_free_buffer(AVFilterBuffer *ptr)
...@@ -112,9 +113,6 @@ int avfilter_default_config_output_link(AVFilterLink *link) ...@@ -112,9 +113,6 @@ int avfilter_default_config_output_link(AVFilterLink *link)
link->w = link->src->inputs[0]->w; link->w = link->src->inputs[0]->w;
link->h = link->src->inputs[0]->h; link->h = link->src->inputs[0]->h;
link->time_base = link->src->inputs[0]->time_base; link->time_base = link->src->inputs[0]->time_base;
} else if (link->type == AVMEDIA_TYPE_AUDIO) {
link->channel_layout = link->src->inputs[0]->channel_layout;
link->sample_rate = link->src->inputs[0]->sample_rate;
} }
} else { } else {
/* XXX: any non-simple filter which would cause this branch to be taken /* XXX: any non-simple filter which would cause this branch to be taken
...@@ -125,36 +123,53 @@ int avfilter_default_config_output_link(AVFilterLink *link) ...@@ -125,36 +123,53 @@ int avfilter_default_config_output_link(AVFilterLink *link)
return 0; return 0;
} }
#define SET_COMMON_FORMATS(ctx, fmts, in_fmts, out_fmts, ref, list) \
{ \
int count = 0, i; \
\
for (i = 0; i < ctx->input_count; i++) { \
if (ctx->inputs[i]) { \
ref(fmts, &ctx->inputs[i]->out_fmts); \
count++; \
} \
} \
for (i = 0; i < ctx->output_count; i++) { \
if (ctx->outputs[i]) { \
ref(fmts, &ctx->outputs[i]->in_fmts); \
count++; \
} \
} \
\
if (!count) { \
av_freep(&fmts->list); \
av_freep(&fmts->refs); \
av_freep(&fmts); \
} \
}
void ff_set_common_channel_layouts(AVFilterContext *ctx,
AVFilterChannelLayouts *layouts)
{
SET_COMMON_FORMATS(ctx, layouts, in_channel_layouts, out_channel_layouts,
ff_channel_layouts_ref, channel_layouts);
}
void ff_set_common_samplerates(AVFilterContext *ctx,
AVFilterFormats *samplerates)
{
SET_COMMON_FORMATS(ctx, samplerates, in_samplerates, out_samplerates,
avfilter_formats_ref, formats);
}
/** /**
* A helper for query_formats() which sets all links to the same list of * 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 * formats. If there are no links hooked to this filter, the list of formats is
* freed. * 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) void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
{ {
int count = 0, i; SET_COMMON_FORMATS(ctx, formats, in_formats, out_formats,
avfilter_formats_ref, formats);
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++;
}
}
if (!count) {
av_free(formats->formats);
av_free(formats->refs);
av_free(formats);
}
} }
int avfilter_default_query_formats(AVFilterContext *ctx) int avfilter_default_query_formats(AVFilterContext *ctx)
...@@ -164,6 +179,11 @@ int avfilter_default_query_formats(AVFilterContext *ctx) ...@@ -164,6 +179,11 @@ int avfilter_default_query_formats(AVFilterContext *ctx)
AVMEDIA_TYPE_VIDEO; AVMEDIA_TYPE_VIDEO;
avfilter_set_common_formats(ctx, avfilter_all_formats(type)); avfilter_set_common_formats(ctx, avfilter_all_formats(type));
if (type == AVMEDIA_TYPE_AUDIO) {
ff_set_common_channel_layouts(ctx, ff_all_channel_layouts());
ff_set_common_samplerates(ctx, ff_all_samplerates());
}
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment