Message ID | 20210807101507.83161-3-fulinjie@zju.edu.cn |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/3] Revert "fftools/ffmpeg_filter: fix the flags parsing for scaler" | expand |
Context | Check | Description |
---|---|---|
andriy/x86_make | success | Make finished |
andriy/x86_make_fate | success | Make fate finished |
andriy/PPC64_make | success | Make finished |
andriy/PPC64_make_fate | success | Make fate finished |
Linjie Fu: > From: Linjie Fu <linjie.justin.fu@gmail.com> > > To pass the swscale options for the inserted scalers. > > ffmpeg -i input.mp4 -filter_complex \ > "scale_sws_opts=alphablend=checkerboard;format=nv12" \ > -t 0.5 output.mp4 > > Update docs. > > Signed-off-by: Linjie Fu <linjie.justin.fu@gmail.com> > --- > doc/filters.texi | 7 ++++--- > libavfilter/graphparser.c | 27 +++++++++++++++++++++++++++ > 2 files changed, 31 insertions(+), 3 deletions(-) > > diff --git a/doc/filters.texi b/doc/filters.texi > index 790d165433..dbbb3a6940 100644 > --- a/doc/filters.texi > +++ b/doc/filters.texi > @@ -204,9 +204,9 @@ pads must be connected. A filtergraph is considered valid if all the > filter input and output pads of all the filterchains are connected. > > Libavfilter will automatically insert @ref{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};} > +conversion is required. It is possible to specify swscale flags or > +scale_sws_opts for those automatically inserted scalers by prepending > +@code{sws_flags=@var{flags};} or @code{scale_sws_opts=@var{scale_sws_opts};} > to the filtergraph description. > > Here is a BNF description of the filtergraph syntax: > @@ -219,6 +219,7 @@ Here is a BNF description of the filtergraph syntax: > @var{FILTER} ::= [@var{LINKLABELS}] @var{FILTER_NAME} ["=" @var{FILTER_ARGUMENTS}] [@var{LINKLABELS}] > @var{FILTERCHAIN} ::= @var{FILTER} [,@var{FILTERCHAIN}] > @var{FILTERGRAPH} ::= [sws_flags=@var{flags};] @var{FILTERCHAIN} [;@var{FILTERGRAPH}] > +@var{FILTERGRAPH} ::= [scale_sws_opts=@var{opts};] @var{FILTERCHAIN} [;@var{FILTERGRAPH}] > @end example > > @anchor{filtergraph escaping} > diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c > index 1385c3ae71..8c63d6454e 100644 > --- a/libavfilter/graphparser.c > +++ b/libavfilter/graphparser.c > @@ -415,6 +415,30 @@ static int parse_sws_flags(const char **buf, AVFilterGraph *graph) > return 0; > } > > +static int parse_scale_sws_opts(const char **buf, AVFilterGraph *graph) > +{ > + char *p = strchr(*buf, ';'); > + > + if (strncmp(*buf, "scale_sws_opts=", 15)) { av_strstart() > + return 0; > + } > + > + if (!p) { > + av_log(graph, AV_LOG_ERROR, "scale_sws_opts not terminated with ';'.\n"); > + return AVERROR(EINVAL); > + } > + > + *buf += 15; > + > + 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); av_strndup() > + > + *buf = p + 1; > + return 0; > +} > + > int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, > AVFilterInOut **inputs, > AVFilterInOut **outputs) > @@ -429,6 +453,9 @@ int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, > if ((ret = parse_sws_flags(&filters, graph)) < 0) > goto fail; > > + if ((ret = parse_scale_sws_opts(&filters, graph)) < 0) > + goto fail; > + > do { > AVFilterContext *filter; > filters += strspn(filters, WHITESPACES); >
Andreas: On Sat, Aug 7, 2021 at 9:52 PM Andreas Rheinhardt < andreas.rheinhardt@outlook.com> wrote: > Linjie Fu: > > From: Linjie Fu <linjie.justin.fu@gmail.com> > > > > To pass the swscale options for the inserted scalers. > > > > ffmpeg -i input.mp4 -filter_complex \ > > "scale_sws_opts=alphablend=checkerboard;format=nv12" \ > > -t 0.5 output.mp4 > > > > Update docs. > > > > Signed-off-by: Linjie Fu <linjie.justin.fu@gmail.com> > > --- > > doc/filters.texi | 7 ++++--- > > libavfilter/graphparser.c | 27 +++++++++++++++++++++++++++ > > 2 files changed, 31 insertions(+), 3 deletions(-) > > > > diff --git a/doc/filters.texi b/doc/filters.texi > > index 790d165433..dbbb3a6940 100644 > > --- a/doc/filters.texi > > +++ b/doc/filters.texi > > @@ -204,9 +204,9 @@ pads must be connected. A filtergraph is considered > valid if all the > > filter input and output pads of all the filterchains are connected. > > > > Libavfilter will automatically insert @ref{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};} > > +conversion is required. It is possible to specify swscale flags or > > +scale_sws_opts for those automatically inserted scalers by prepending > > +@code{sws_flags=@var{flags};} or > @code{scale_sws_opts=@var{scale_sws_opts};} > > to the filtergraph description. > > > > Here is a BNF description of the filtergraph syntax: > > @@ -219,6 +219,7 @@ Here is a BNF description of the filtergraph syntax: > > @var{FILTER} ::= [@var{LINKLABELS}] @var{FILTER_NAME} ["=" > @var{FILTER_ARGUMENTS}] [@var{LINKLABELS}] > > @var{FILTERCHAIN} ::= @var{FILTER} [,@var{FILTERCHAIN}] > > @var{FILTERGRAPH} ::= [sws_flags=@var{flags};] @var{FILTERCHAIN} > [;@var{FILTERGRAPH}] > > +@var{FILTERGRAPH} ::= [scale_sws_opts=@var{opts};] > @var{FILTERCHAIN} [;@var{FILTERGRAPH}] > > @end example > > > > @anchor{filtergraph escaping} > > diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c > > index 1385c3ae71..8c63d6454e 100644 > > --- a/libavfilter/graphparser.c > > +++ b/libavfilter/graphparser.c > > @@ -415,6 +415,30 @@ static int parse_sws_flags(const char **buf, > AVFilterGraph *graph) > > return 0; > > } > > > > +static int parse_scale_sws_opts(const char **buf, AVFilterGraph *graph) > > +{ > > + char *p = strchr(*buf, ';'); > > + > > + if (strncmp(*buf, "scale_sws_opts=", 15)) { > > av_strstart() > > > + return 0; > > + } > > + > > + if (!p) { > > + av_log(graph, AV_LOG_ERROR, "scale_sws_opts not terminated with > ';'.\n"); > > + return AVERROR(EINVAL); > > + } > > + > > + *buf += 15; > > + > > + 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); > > av_strndup() > Yes, thanks for pointing this out. This patch uses the similar code from current implementation[1], hence I guess it could be simplified too. - linjie [1] https://github.com/FFmpeg/FFmpeg/blob/master/libavfilter/graphparser.c#L395
diff --git a/doc/filters.texi b/doc/filters.texi index 790d165433..dbbb3a6940 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -204,9 +204,9 @@ pads must be connected. A filtergraph is considered valid if all the filter input and output pads of all the filterchains are connected. Libavfilter will automatically insert @ref{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};} +conversion is required. It is possible to specify swscale flags or +scale_sws_opts for those automatically inserted scalers by prepending +@code{sws_flags=@var{flags};} or @code{scale_sws_opts=@var{scale_sws_opts};} to the filtergraph description. Here is a BNF description of the filtergraph syntax: @@ -219,6 +219,7 @@ Here is a BNF description of the filtergraph syntax: @var{FILTER} ::= [@var{LINKLABELS}] @var{FILTER_NAME} ["=" @var{FILTER_ARGUMENTS}] [@var{LINKLABELS}] @var{FILTERCHAIN} ::= @var{FILTER} [,@var{FILTERCHAIN}] @var{FILTERGRAPH} ::= [sws_flags=@var{flags};] @var{FILTERCHAIN} [;@var{FILTERGRAPH}] +@var{FILTERGRAPH} ::= [scale_sws_opts=@var{opts};] @var{FILTERCHAIN} [;@var{FILTERGRAPH}] @end example @anchor{filtergraph escaping} diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c index 1385c3ae71..8c63d6454e 100644 --- a/libavfilter/graphparser.c +++ b/libavfilter/graphparser.c @@ -415,6 +415,30 @@ static int parse_sws_flags(const char **buf, AVFilterGraph *graph) return 0; } +static int parse_scale_sws_opts(const char **buf, AVFilterGraph *graph) +{ + char *p = strchr(*buf, ';'); + + if (strncmp(*buf, "scale_sws_opts=", 15)) { + return 0; + } + + if (!p) { + av_log(graph, AV_LOG_ERROR, "scale_sws_opts not terminated with ';'.\n"); + return AVERROR(EINVAL); + } + + *buf += 15; + + 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, AVFilterInOut **inputs, AVFilterInOut **outputs) @@ -429,6 +453,9 @@ int avfilter_graph_parse2(AVFilterGraph *graph, const char *filters, if ((ret = parse_sws_flags(&filters, graph)) < 0) goto fail; + if ((ret = parse_scale_sws_opts(&filters, graph)) < 0) + goto fail; + do { AVFilterContext *filter; filters += strspn(filters, WHITESPACES);