00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <ctype.h>
00024 #include <string.h>
00025
00026 #include "avfilter.h"
00027 #include "avfiltergraph.h"
00028
00029 void avfilter_graph_destroy(AVFilterGraph *graph)
00030 {
00031 for(; graph->filter_count > 0; graph->filter_count --)
00032 avfilter_destroy(graph->filters[graph->filter_count - 1]);
00033 av_freep(&graph->scale_sws_opts);
00034 av_freep(&graph->filters);
00035 }
00036
00037 int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
00038 {
00039 graph->filters = av_realloc(graph->filters,
00040 sizeof(AVFilterContext*) * ++graph->filter_count);
00041
00042 if (!graph->filters)
00043 return -1;
00044
00045 graph->filters[graph->filter_count - 1] = filter;
00046
00047 return 0;
00048 }
00049
00050 int avfilter_graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
00051 {
00052 AVFilterContext *filt;
00053 int i, j;
00054
00055 for (i=0; i < graph->filter_count; i++) {
00056 filt = graph->filters[i];
00057
00058 for (j = 0; j < filt->input_count; j++) {
00059 if (!filt->inputs[j] || !filt->inputs[j]->src) {
00060 av_log(log_ctx, AV_LOG_ERROR,
00061 "Input pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any source\n",
00062 filt->input_pads[j].name, filt->name, filt->filter->name);
00063 return -1;
00064 }
00065 }
00066
00067 for (j = 0; j < filt->output_count; j++) {
00068 if (!filt->outputs[j] || !filt->outputs[j]->dst) {
00069 av_log(log_ctx, AV_LOG_ERROR,
00070 "Output pad \"%s\" for the filter \"%s\" of type \"%s\" not connected to any destination\n",
00071 filt->output_pads[j].name, filt->name, filt->filter->name);
00072 return -1;
00073 }
00074 }
00075 }
00076
00077 return 0;
00078 }
00079
00080 AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
00081 {
00082 int i;
00083
00084 for(i = 0; i < graph->filter_count; i ++)
00085 if(graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
00086 return graph->filters[i];
00087
00088 return NULL;
00089 }
00090
00091 static int query_formats(AVFilterGraph *graph)
00092 {
00093 int i, j;
00094 int scaler_count = 0;
00095 char inst_name[30];
00096
00097
00098 for(i = 0; i < graph->filter_count; i ++) {
00099 if(graph->filters[i]->filter->query_formats)
00100 graph->filters[i]->filter->query_formats(graph->filters[i]);
00101 else
00102 avfilter_default_query_formats(graph->filters[i]);
00103 }
00104
00105
00106 for(i = 0; i < graph->filter_count; i ++) {
00107 AVFilterContext *filter = graph->filters[i];
00108
00109 for(j = 0; j < filter->input_count; j ++) {
00110 AVFilterLink *link = filter->inputs[j];
00111 if(link && link->in_formats != link->out_formats) {
00112 if(!avfilter_merge_formats(link->in_formats,
00113 link->out_formats)) {
00114 AVFilterContext *scale;
00115 char scale_args[256];
00116
00117 snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
00118 scaler_count);
00119 scale =
00120 avfilter_open(avfilter_get_by_name("scale"),inst_name);
00121
00122 snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
00123 if(!scale || scale->filter->init(scale, scale_args, NULL) ||
00124 avfilter_insert_filter(link, scale, 0, 0)) {
00125 avfilter_destroy(scale);
00126 return -1;
00127 }
00128
00129 if (avfilter_graph_add_filter(graph, scale) < 0)
00130 return -1;
00131
00132 scale->filter->query_formats(scale);
00133 if(!avfilter_merge_formats(scale-> inputs[0]->in_formats,
00134 scale-> inputs[0]->out_formats)||
00135 !avfilter_merge_formats(scale->outputs[0]->in_formats,
00136 scale->outputs[0]->out_formats))
00137 return -1;
00138 }
00139 }
00140 }
00141 }
00142
00143 return 0;
00144 }
00145
00146 static void pick_format(AVFilterLink *link)
00147 {
00148 if(!link || !link->in_formats)
00149 return;
00150
00151 link->in_formats->format_count = 1;
00152 link->format = link->in_formats->formats[0];
00153
00154 avfilter_formats_unref(&link->in_formats);
00155 avfilter_formats_unref(&link->out_formats);
00156 }
00157
00158 static void pick_formats(AVFilterGraph *graph)
00159 {
00160 int i, j;
00161
00162 for(i = 0; i < graph->filter_count; i ++) {
00163 AVFilterContext *filter = graph->filters[i];
00164
00165 for(j = 0; j < filter->input_count; j ++)
00166 pick_format(filter->inputs[j]);
00167 for(j = 0; j < filter->output_count; j ++)
00168 pick_format(filter->outputs[j]);
00169 }
00170 }
00171
00172 int avfilter_graph_config_formats(AVFilterGraph *graph)
00173 {
00174
00175 if(query_formats(graph))
00176 return -1;
00177
00178
00179
00180 pick_formats(graph);
00181
00182 return 0;
00183 }
00184