• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavfilter/avfiltergraph.c

Go to the documentation of this file.
00001 /*
00002  * filter graphs
00003  * copyright (c) 2008 Vitor Sessak
00004  * copyright (c) 2007 Bobby Bingham
00005  *
00006  * This file is part of FFmpeg.
00007  *
00008  * FFmpeg is free software; you can redistribute it and/or
00009  * modify it under the terms of the GNU Lesser General Public
00010  * License as published by the Free Software Foundation; either
00011  * version 2.1 of the License, or (at your option) any later version.
00012  *
00013  * FFmpeg is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * Lesser General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU Lesser General Public
00019  * License along with FFmpeg; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
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     AVFilterContext **filters = av_realloc(graph->filters,
00040                                            sizeof(AVFilterContext*) * (graph->filter_count+1));
00041     if (!filters)
00042         return AVERROR(ENOMEM);
00043 
00044     graph->filters = filters;
00045     graph->filters[graph->filter_count++] = 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 int avfilter_graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
00081 {
00082     AVFilterContext *filt;
00083     int i, ret;
00084 
00085     for (i=0; i < graph->filter_count; i++) {
00086         filt = graph->filters[i];
00087 
00088         if (!filt->output_count) {
00089             if ((ret = avfilter_config_links(filt)))
00090                 return ret;
00091         }
00092     }
00093 
00094     return 0;
00095 }
00096 
00097 AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, char *name)
00098 {
00099     int i;
00100 
00101     for(i = 0; i < graph->filter_count; i ++)
00102         if(graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
00103             return graph->filters[i];
00104 
00105     return NULL;
00106 }
00107 
00108 static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
00109 {
00110     int i, j;
00111     int scaler_count = 0;
00112     char inst_name[30];
00113 
00114     /* ask all the sub-filters for their supported colorspaces */
00115     for(i = 0; i < graph->filter_count; i ++) {
00116         if(graph->filters[i]->filter->query_formats)
00117             graph->filters[i]->filter->query_formats(graph->filters[i]);
00118         else
00119             avfilter_default_query_formats(graph->filters[i]);
00120     }
00121 
00122     /* go through and merge as many format lists as possible */
00123     for(i = 0; i < graph->filter_count; i ++) {
00124         AVFilterContext *filter = graph->filters[i];
00125 
00126         for(j = 0; j < filter->input_count; j ++) {
00127             AVFilterLink *link = filter->inputs[j];
00128             if(link && link->in_formats != link->out_formats) {
00129                 if(!avfilter_merge_formats(link->in_formats,
00130                                            link->out_formats)) {
00131                     AVFilterContext *scale;
00132                     char scale_args[256];
00133                     /* couldn't merge format lists. auto-insert scale filter */
00134                     snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
00135                              scaler_count++);
00136                     scale =
00137                         avfilter_open(avfilter_get_by_name("scale"),inst_name);
00138 
00139                     snprintf(scale_args, sizeof(scale_args), "0:0:%s", graph->scale_sws_opts);
00140                     if(!scale || scale->filter->init(scale, scale_args, NULL) ||
00141                                  avfilter_insert_filter(link, scale, 0, 0)) {
00142                         avfilter_destroy(scale);
00143                         return -1;
00144                     }
00145 
00146                     if (avfilter_graph_add_filter(graph, scale) < 0)
00147                         return -1;
00148 
00149                     scale->filter->query_formats(scale);
00150                     if (((link = scale-> inputs[0]) &&
00151                          !avfilter_merge_formats(link->in_formats, link->out_formats)) ||
00152                         ((link = scale->outputs[0]) &&
00153                          !avfilter_merge_formats(link->in_formats, link->out_formats))) {
00154                         av_log(log_ctx, AV_LOG_ERROR,
00155                                "Impossible to convert between the formats supported by the filter "
00156                                "'%s' and the filter '%s'\n", link->src->name, link->dst->name);
00157                         return -1;
00158                     }
00159                 }
00160             }
00161         }
00162     }
00163 
00164     return 0;
00165 }
00166 
00167 static void pick_format(AVFilterLink *link)
00168 {
00169     if(!link || !link->in_formats)
00170         return;
00171 
00172     link->in_formats->format_count = 1;
00173     link->format = link->in_formats->formats[0];
00174 
00175     avfilter_formats_unref(&link->in_formats);
00176     avfilter_formats_unref(&link->out_formats);
00177 }
00178 
00179 static void pick_formats(AVFilterGraph *graph)
00180 {
00181     int i, j;
00182 
00183     for(i = 0; i < graph->filter_count; i ++) {
00184         AVFilterContext *filter = graph->filters[i];
00185 
00186         for(j = 0; j < filter->input_count; j ++)
00187             pick_format(filter->inputs[j]);
00188         for(j = 0; j < filter->output_count; j ++)
00189             pick_format(filter->outputs[j]);
00190     }
00191 }
00192 
00193 int avfilter_graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
00194 {
00195     /* find supported formats from sub-filters, and merge along links */
00196     if(query_formats(graph, log_ctx))
00197         return -1;
00198 
00199     /* Once everything is merged, it's possible that we'll still have
00200      * multiple valid colorspace choices. We pick the first one. */
00201     pick_formats(graph);
00202 
00203     return 0;
00204 }
00205 

Generated on Fri Sep 16 2011 17:17:47 for FFmpeg by  doxygen 1.7.1