summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMina Nagy Zaki <mnzaki@gmail.com>2011-07-13 18:04:03 +0300
committerStefano Sabatini <stefasab@gmail.com>2011-09-16 20:44:27 +0200
commit3ee0bedcc00650b0827833e3fa90e76d10cf6e01 (patch)
treed12c986f53847bb6e87a921008b11c86d5fe55a2
parent37cc443c83589b172a0cbc807e05059e3ce4582b (diff)
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. Signed-off-by: Stefano Sabatini <stefasab@gmail.com>
-rw-r--r--libavfilter/avfiltergraph.c101
1 files changed, 73 insertions, 28 deletions
diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c
index 2997bbe344..c97e495c96 100644
--- a/libavfilter/avfiltergraph.c
+++ b/libavfilter/avfiltergraph.c
@@ -23,6 +23,7 @@
#include <ctype.h>
#include <string.h>
+#include "libavutil/audioconvert.h"
#include "avfilter.h"
#include "avfiltergraph.h"
#include "internal.h"
@@ -135,11 +136,57 @@ AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
return NULL;
}
+static int insert_conv_filter(AVFilterGraph *graph, AVFilterLink *link,
+ const char *filt_name, const char *filt_args)
+{
+ static int auto_count = 0, ret;
+ char inst_name[32];
+ AVFilterContext *filt_ctx;
+
+ snprintf(inst_name, sizeof(inst_name), "auto-inserted %s %d",
+ filt_name, auto_count++);
+
+ if ((ret = avfilter_graph_create_filter(&filt_ctx,
+ avfilter_get_by_name(filt_name),
+ inst_name, filt_args, NULL, graph)) < 0)
+ return ret;
+ if ((ret = avfilter_insert_filter(link, filt_ctx, 0, 0)) < 0)
+ return ret;
+
+ filt_ctx->filter->query_formats(filt_ctx);
+
+ if ( ((link = filt_ctx-> inputs[0]) &&
+ !avfilter_merge_formats(link->in_formats, link->out_formats)) ||
+ ((link = filt_ctx->outputs[0]) &&
+ !avfilter_merge_formats(link->in_formats, link->out_formats))
+ ) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Impossible to convert between the formats supported by the filter "
+ "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
+ return AVERROR(EINVAL);
+ }
+
+ if (link->type == AVMEDIA_TYPE_AUDIO &&
+ (((link = filt_ctx-> inputs[0]) &&
+ (!avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts) ||
+ !avfilter_merge_formats(link->in_packing, link->out_packing))) ||
+ ((link = filt_ctx->outputs[0]) &&
+ (!avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts) ||
+ !avfilter_merge_formats(link->in_packing, link->out_packing))))
+ ) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Impossible to convert between the channel layouts/packing formats supported by the filter "
+ "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
+ return AVERROR(EINVAL);
+ }
+
+ return 0;
+}
+
static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
{
int i, j, ret;
- int scaler_count = 0;
- char inst_name[30];
+ char filt_args[128];
/* ask all the sub-filters for their supported media formats */
for (i = 0; i < graph->filter_count; i++) {
@@ -155,32 +202,30 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
for (j = 0; j < filter->input_count; j++) {
AVFilterLink *link = filter->inputs[j];
- if (link && link->in_formats != link->out_formats) {
- if (!avfilter_merge_formats(link->in_formats,
- link->out_formats)) {
- AVFilterContext *scale;
- char scale_args[256];
- /* couldn't merge format lists. auto-insert scale filter */
- snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
- scaler_count++);
- snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
- if ((ret = avfilter_graph_create_filter(&scale, avfilter_get_by_name("scale"),
- inst_name, scale_args, NULL, graph)) < 0)
- return ret;
- if ((ret = avfilter_insert_filter(link, scale, 0, 0)) < 0)
- return ret;
-
- scale->filter->query_formats(scale);
- if (((link = scale-> inputs[0]) &&
- !avfilter_merge_formats(link->in_formats, link->out_formats)) ||
- ((link = scale->outputs[0]) &&
- !avfilter_merge_formats(link->in_formats, link->out_formats))) {
- av_log(log_ctx, AV_LOG_ERROR,
- "Impossible to convert between the formats supported by the filter "
- "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
- return AVERROR(EINVAL);
- }
- }
+ if (!link) continue;
+
+ if (!link->in_formats || !link->out_formats)
+ return AVERROR(EINVAL);
+
+ if (link->type == AVMEDIA_TYPE_VIDEO &&
+ !avfilter_merge_formats(link->in_formats, link->out_formats)) {
+
+ /* couldn't merge format lists, auto-insert scale filter */
+ snprintf(filt_args, sizeof(filt_args), "0:0:%s",
+ graph->scale_sws_opts);
+ if (ret = insert_conv_filter(graph, link, "scale", filt_args))
+ return ret;
+ }
+ else if (link->type == AVMEDIA_TYPE_AUDIO) {
+ if (!link->in_chlayouts || !link->out_chlayouts ||
+ !link->in_packing || !link->out_packing)
+ return AVERROR(EINVAL);
+
+ if (!avfilter_merge_formats(link->in_formats, link->out_formats) ||
+ !avfilter_merge_formats(link->in_chlayouts, link->out_chlayouts) ||
+ !avfilter_merge_formats(link->in_packing, link->out_packing))
+ if (ret = insert_conv_filter(graph, link, "aconvert", NULL))
+ return ret;
}
}
}