History

lavfi: refactor query_formats and auto-insert audio conversion filters

Behaviour has been changed to fail negotiation if fields have been left empty. Patch was originally based on a patch by Hemanth.

Mina Nagy Zaki committed 15 years ago

Commit 3ee0bed1 parent 37cc4431 file · +73 −28Browse files

Showing the changes to libavfilter/avfiltergraph.c (1 of 1 file). Show all

Unified · Split

libavfilter/avfiltergraph.c+73−28
@@ -23,6 +23,7 @@ · 22 unmodified lines
2323 #include <ctype.h>
2424 #include <string.h>
2525
26+#include "libavutil/audioconvert.h"
2627 #include "avfilter.h"
2728 #include "avfiltergraph.h"
2829 #include "internal.h"
@@ -135,11 +136,57 @@ AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name) · 106 unmodified lines
135136 return NULL;
136137 }
137138
139+static int insert_conv_filter(AVFilterGraph *graph, AVFilterLink *link,
140+ const char *filt_name, const char *filt_args)
141+{
142+ static int auto_count = 0, ret;
143+ char inst_name[32];
144+ AVFilterContext *filt_ctx;
145+
146+ snprintf(inst_name, sizeof(inst_name), "auto-inserted %s %d",
147+ filt_name, auto_count++);
148+
149+ if ((ret = avfilter_graph_create_filter(&filt_ctx,
150+ avfilter_get_by_name(filt_name),
151+ inst_name, filt_args, NULL, graph)) < 0)
152+ return ret;
153+ if ((ret = avfilter_insert_filter(link, filt_ctx, 0, 0)) < 0)
154+ return ret;
155+
156+ filt_ctx->filter->query_formats(filt_ctx);
157+
158+ if ( ((link = filt_ctx-> inputs[0]) &&
159+ !avfilter_merge_formats(link->in_formats, link->out_formats)) ||
160+ ((link = filt_ctx->outputs[0]) &&
161+ !avfilter_merge_formats(link->in_formats, link->out_formats))
162+ ) {
163+ av_log(NULL, AV_LOG_ERROR,
164+ "Impossible to convert between the formats supported by the filter "
165+ "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
166+ return AVERROR(EINVAL);
167+ }
168+
169+ if (link->type == AVMEDIA_TYPE_AUDIO &&
170+ (((link = filt_ctx-> inputs[0]) &&
171+ (!avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts) ||
172+ !avfilter_merge_formats(link->in_packing, link->out_packing))) ||
173+ ((link = filt_ctx->outputs[0]) &&
174+ (!avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts) ||
175+ !avfilter_merge_formats(link->in_packing, link->out_packing))))
176+ ) {
177+ av_log(NULL, AV_LOG_ERROR,
178+ "Impossible to convert between the channel layouts/packing formats supported by the filter "
179+ "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
180+ return AVERROR(EINVAL);
181+ }
182+
183+ return 0;
184+}
185+
138186 static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
139187 {
140188 int i, j, ret;
141− int scaler_count = 0;
142− char inst_name[30];
189+ char filt_args[128];
143190
144191 /* ask all the sub-filters for their supported media formats */
145192 for (i = 0; i < graph->filter_count; i++) {
@@ -155,32 +202,30 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) · 9 unmodified lines
155202
156203 for (j = 0; j < filter->input_count; j++) {
157204 AVFilterLink *link = filter->inputs[j];
158− if (link && link->in_formats != link->out_formats) {
159− if (!avfilter_merge_formats(link->in_formats,
160− link->out_formats)) {
161− AVFilterContext *scale;
162− char scale_args[256];
163− /* couldn't merge format lists. auto-insert scale filter */
164− snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
165− scaler_count++);
166− snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
167− if ((ret = avfilter_graph_create_filter(&scale, avfilter_get_by_name("scale"),
168− inst_name, scale_args, NULL, graph)) < 0)
169− return ret;
170− if ((ret = avfilter_insert_filter(link, scale, 0, 0)) < 0)
171− return ret;
172−
173− scale->filter->query_formats(scale);
174− if (((link = scale-> inputs[0]) &&
175− !avfilter_merge_formats(link->in_formats, link->out_formats)) ||
176− ((link = scale->outputs[0]) &&
177− !avfilter_merge_formats(link->in_formats, link->out_formats))) {
178− av_log(log_ctx, AV_LOG_ERROR,
179− "Impossible to convert between the formats supported by the filter "
180− "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
181− return AVERROR(EINVAL);
182− }
183− }
205+ if (!link) continue;
206+
207+ if (!link->in_formats || !link->out_formats)
208+ return AVERROR(EINVAL);
209+
210+ if (link->type == AVMEDIA_TYPE_VIDEO &&
211+ !avfilter_merge_formats(link->in_formats, link->out_formats)) {
212+
213+ /* couldn't merge format lists, auto-insert scale filter */
214+ snprintf(filt_args, sizeof(filt_args), "0:0:%s",
215+ graph->scale_sws_opts);
216+ if (ret = insert_conv_filter(graph, link, "scale", filt_args))
217+ return ret;
218+ }
219+ else if (link->type == AVMEDIA_TYPE_AUDIO) {
220+ if (!link->in_chlayouts || !link->out_chlayouts ||
221+ !link->in_packing || !link->out_packing)
222+ return AVERROR(EINVAL);
223+
224+ if (!avfilter_merge_formats(link->in_formats, link->out_formats) ||
225+ !avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts) ||
226+ !avfilter_merge_formats(link->in_packing, link->out_packing))
227+ if (ret = insert_conv_filter(graph, link, "aconvert", NULL))
228+ return ret;
184229 }
185230 }
186231 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t