@@ -76,6 +76,12 @@ In a complete filterchain all the unlabelled filter input and output | |||||
pads must be connected. A filtergraph is considered valid if all the | pads must be connected. A filtergraph is considered valid if all the | ||||
filter input and output pads of all the filterchains are connected. | filter input and output pads of all the filterchains are connected. | ||||
Libavfilter will automatically insert scale filters where format | |||||
conversion is required. It is possible to specify swscale flags | |||||
for those automatically inserted scalers by prepending | |||||
@code{sws_flags=@var{flags};} | |||||
to the filtergraph description. | |||||
Follows a BNF description for the filtergraph syntax: | Follows a BNF description for the filtergraph syntax: | ||||
@example | @example | ||||
@var{NAME} ::= sequence of alphanumeric characters and '_' | @var{NAME} ::= sequence of alphanumeric characters and '_' | ||||
@@ -84,7 +90,7 @@ Follows a BNF description for the filtergraph syntax: | |||||
@var{FILTER_ARGUMENTS} ::= sequence of chars (eventually quoted) | @var{FILTER_ARGUMENTS} ::= sequence of chars (eventually quoted) | ||||
@var{FILTER} ::= [@var{LINKNAMES}] @var{NAME} ["=" @var{ARGUMENTS}] [@var{LINKNAMES}] | @var{FILTER} ::= [@var{LINKNAMES}] @var{NAME} ["=" @var{ARGUMENTS}] [@var{LINKNAMES}] | ||||
@var{FILTERCHAIN} ::= @var{FILTER} [,@var{FILTERCHAIN}] | @var{FILTERCHAIN} ::= @var{FILTER} [,@var{FILTERCHAIN}] | ||||
@var{FILTERGRAPH} ::= @var{FILTERCHAIN} [;@var{FILTERGRAPH}] | |||||
@var{FILTERGRAPH} ::= [sws_flags=@var{flags};] @var{FILTERCHAIN} [;@var{FILTERGRAPH}] | |||||
@end example | @end example | ||||
@c man end FILTERGRAPH DESCRIPTION | @c man end FILTERGRAPH DESCRIPTION | ||||
@@ -349,6 +349,30 @@ static int parse_outputs(const char **buf, AVFilterInOut **curr_inputs, | |||||
#else | #else | ||||
#define log_ctx NULL | #define log_ctx NULL | ||||
#endif | #endif | ||||
static int parse_sws_flags(const char **buf, AVFilterGraph *graph) | |||||
{ | |||||
char *p = strchr(*buf, ';'); | |||||
if (strncmp(*buf, "sws_flags=", 10)) | |||||
return 0; | |||||
if (!p) { | |||||
av_log(log_ctx, AV_LOG_ERROR, "sws_flags not terminated with ';'.\n"); | |||||
return AVERROR(EINVAL); | |||||
} | |||||
*buf += 4; // keep the 'flags=' part | |||||
av_freep(&graph->scale_sws_opts); | |||||
if (!(graph->scale_sws_opts = av_mallocz(p - *buf + 1))) | |||||
return AVERROR(ENOMEM); | |||||
av_strlcpy(graph->scale_sws_opts, *buf, p - *buf + 1); | |||||
*buf = p + 1; | |||||
return 0; | |||||
} | |||||
int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, | int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, | ||||
AVFilterInOut **inputs, | AVFilterInOut **inputs, | ||||
AVFilterInOut **outputs) | AVFilterInOut **outputs) | ||||
@@ -358,6 +382,11 @@ int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, | |||||
AVFilterInOut *curr_inputs = NULL, *open_inputs = NULL, *open_outputs = NULL; | AVFilterInOut *curr_inputs = NULL, *open_inputs = NULL, *open_outputs = NULL; | ||||
filters += strspn(filters, WHITESPACES); | |||||
if ((ret = parse_sws_flags(&filters, graph)) < 0) | |||||
goto fail; | |||||
do { | do { | ||||
AVFilterContext *filter; | AVFilterContext *filter; | ||||
filters += strspn(filters, WHITESPACES); | filters += strspn(filters, WHITESPACES); | ||||