On Wed, Mar 13, 2013 at 08:52:04PM +0100, Anton Khirnov wrote:
> ---
>  Changelog       |    2 ++
>  avconv.c        |    1 +
>  avconv.h        |    2 ++
>  avconv_opt.c    |   88 
> ++++++++++++++++++++++++++++++++++++++++++++++++++-----
>  doc/avconv.texi |   12 ++++++++
>  5 files changed, 98 insertions(+), 7 deletions(-)
> 
> diff --git a/Changelog b/Changelog
> index 15c0873..1c493c2 100644
> --- a/Changelog
> +++ b/Changelog
> @@ -7,6 +7,8 @@ version 10:
>  - reference-counting for AVFrame and AVPacket data
>  - avconv now fails when input options are used for output file
>    or vice versa
> +- new avconv options -filter_script and -filter_complex_script, which allow a
> +  filtergraph description to be read from a file
>  
>  
>  version 9:
> diff --git a/avconv.c b/avconv.c
> index 1a18ad3..a5a4c7f 100644
> --- a/avconv.c
> +++ b/avconv.c
> @@ -160,6 +160,7 @@ static void exit_program(void)
>              av_freep(&filtergraphs[i]->outputs[j]);
>          }
>          av_freep(&filtergraphs[i]->outputs);
> +        av_freep(&filtergraphs[i]->graph_desc);
>          av_freep(&filtergraphs[i]);
>      }
>      av_freep(&filtergraphs);
> diff --git a/avconv.h b/avconv.h
> index eb9df9b..73e20e8 100644
> --- a/avconv.h
> +++ b/avconv.h
> @@ -158,6 +158,8 @@ typedef struct OptionsContext {
>      int        nb_copy_initial_nonkeyframes;
>      SpecifierOpt *filters;
>      int        nb_filters;
> +    SpecifierOpt *filter_scripts;
> +    int        nb_filter_scripts;
>      SpecifierOpt *pass;
>      int        nb_pass;
>      SpecifierOpt *passlogfiles;
> diff --git a/avconv_opt.c b/avconv_opt.c
> index 30fbadf..09e7d03 100644
> --- a/avconv_opt.c
> +++ b/avconv_opt.c
> @@ -926,6 +926,59 @@ static void parse_matrix_coeffs(uint16_t *dest, const 
> char *str)
>      }
>  }
>  
> +/* read file contents into a string */
> +static uint8_t *read_file(const char *filename)
> +{
> +    AVIOContext *pb      = NULL;
> +    AVIOContext *dyn_buf = NULL;
> +    int ret = avio_open(&pb, filename, AVIO_FLAG_READ);
> +    uint8_t buf[1024], *str;
> +
> +    if (ret < 0) {
> +        av_log(NULL, AV_LOG_ERROR, "Error opening file %s.\n", filename);
> +        return NULL;
> +    }
> +
> +    ret = avio_open_dyn_buf(&dyn_buf);
> +    if (ret < 0) {
> +        avio_closep(&pb);
> +        return NULL;
> +    }
> +    while ((ret = avio_read(pb, buf, sizeof(buf))) > 0)
> +        avio_write(dyn_buf, buf, ret);
> +    avio_w8(dyn_buf, 0);
> +    avio_closep(&pb);
> +
> +    ret = avio_close_dyn_buf(dyn_buf, &str);
> +    if (ret < 0)
> +        return NULL;
> +    return str;
> +}
> +
> +static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
> +                             OutputStream *ost)
> +{
> +    AVStream *st = ost->st;
> +    char *filter = NULL, *filter_script = NULL;
> +
> +    MATCH_PER_STREAM_OPT(filter_scripts, str, filter_script, oc, st);
> +    MATCH_PER_STREAM_OPT(filters, str, filter, oc, st);
> +
> +    if (filter_script && filter) {
> +        av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
> +               "output stream #%d:%d.\n", nb_output_files, st->index);
> +        exit(1);
> +    }
> +
> +    if (filter_script)
> +        return read_file(filter_script);
> +    else if (filter)
> +        return av_strdup(filter);
> +
> +    return av_strdup(st->codec->codec_type == AVMEDIA_TYPE_VIDEO ?
> +                     "null" : "anull");
> +}
> +
>  static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc)
>  {
>      AVStream *st;
> @@ -941,7 +994,6 @@ static OutputStream *new_video_stream(OptionsContext *o, 
> AVFormatContext *oc)
>          char *frame_rate = NULL, *frame_size = NULL;
>          char *frame_aspect_ratio = NULL, *frame_pix_fmt = NULL;
>          char *intra_matrix = NULL, *inter_matrix = NULL;
> -        const char *filters = "null";
>          int do_pass = 0;
>          int i;
>  
> @@ -1036,8 +1088,10 @@ static OutputStream *new_video_stream(OptionsContext 
> *o, AVFormatContext *oc)
>          ost->top_field_first = -1;
>          MATCH_PER_STREAM_OPT(top_field_first, i, ost->top_field_first, oc, 
> st);
>  
> -        MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
> -        ost->avfilter = av_strdup(filters);
> +
> +        ost->avfilter = get_ost_filters(o, oc, ost);
> +        if (!ost->avfilter)
> +            exit(1);
>      } else {
>          MATCH_PER_STREAM_OPT(copy_initial_nonkeyframes, i, 
> ost->copy_initial_nonkeyframes, oc ,st);
>      }
> @@ -1059,7 +1113,6 @@ static OutputStream *new_audio_stream(OptionsContext 
> *o, AVFormatContext *oc)
>  
>      if (!ost->stream_copy) {
>          char *sample_fmt = NULL;
> -        const char *filters = "anull";
>  
>          MATCH_PER_STREAM_OPT(audio_channels, i, audio_enc->channels, oc, st);
>  
> @@ -1072,8 +1125,9 @@ static OutputStream *new_audio_stream(OptionsContext 
> *o, AVFormatContext *oc)
>  
>          MATCH_PER_STREAM_OPT(audio_sample_rate, i, audio_enc->sample_rate, 
> oc, st);
>  
> -        MATCH_PER_STREAM_OPT(filters, str, filters, oc, st);
> -        ost->avfilter = av_strdup(filters);
> +        ost->avfilter = get_ost_filters(o, oc, ost);
> +        if (!ost->avfilter)
> +            exit(1);
>      }
>  
>      return ost;
> @@ -1878,7 +1932,23 @@ static int opt_filter_complex(void *optctx, const char 
> *opt, const char *arg)
>      if (!(filtergraphs[nb_filtergraphs - 1] = 
> av_mallocz(sizeof(*filtergraphs[0]))))
>          return AVERROR(ENOMEM);
>      filtergraphs[nb_filtergraphs - 1]->index       = nb_filtergraphs - 1;

diego-valign-nit

> -    filtergraphs[nb_filtergraphs - 1]->graph_desc = arg;
> +    filtergraphs[nb_filtergraphs - 1]->graph_desc = av_strdup(arg);
> +    if (!filtergraphs[nb_filtergraphs - 1]->graph_desc)
> +        return AVERROR(ENOMEM);
> +    return 0;
> +}
> +
> +static int opt_filter_complex_script(void *optctx, const char *opt, const 
> char *arg)
> +{
> +    uint8_t *graph_desc = read_file(arg);
> +    if (!graph_desc)
> +        return AVERROR(EINVAL);
> +
> +    GROW_ARRAY(filtergraphs, nb_filtergraphs);
> +    if (!(filtergraphs[nb_filtergraphs - 1] = 
> av_mallocz(sizeof(*filtergraphs[0]))))
> +        return AVERROR(ENOMEM);
> +    filtergraphs[nb_filtergraphs - 1]->index      = nb_filtergraphs - 1;
> +    filtergraphs[nb_filtergraphs - 1]->graph_desc = graph_desc;
>      return 0;
>  }
>  
> @@ -2137,8 +2207,12 @@ const OptionDef options[] = {
>          "use fixed quality scale (VBR)", "q" },
>      { "filter",         HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off 
> = OFFSET(filters) },
>          "set stream filterchain", "filter_list" },
> +    { "filter_script",  HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off 
> = OFFSET(filter_scripts) },
> +        "read stream filtergraph description from a file", "filename" },
>      { "filter_complex", HAS_ARG | OPT_EXPERT,                        { 
> .func_arg = opt_filter_complex },
>          "create a complex filtergraph", "graph_description" },
> +    { "filter_complex_script", HAS_ARG | OPT_EXPERT,                 { 
> .func_arg = opt_filter_complex_script },
> +        "read complex filtergraph description from a file", "filename" },
>      { "stats",          OPT_BOOL,                                    { 
> &print_stats },
>          "print progress report during encoding", },
>      { "attach",         HAS_ARG | OPT_PERFILE | OPT_EXPERT |
> diff --git a/doc/avconv.texi b/doc/avconv.texi
> index 7341d2f..3e1dc4c 100644
> --- a/doc/avconv.texi
> +++ b/doc/avconv.texi
> @@ -330,6 +330,12 @@ the stream. Use @code{-filters} to show all the 
> available filters
>  
>  See also the @option{-filter_complex} option if you want to create filter 
> graphs
>  with multiple inputs and/or outputs.
> +
> +@item -filter_script[:@var{stream_specifier}] @var{filename} 
> (@emph{output,per-stream})
> +This option is similar to @option{-filter}, the only difference is that its
> +argument is the name of the file from which a filtergraph description is to 
> be
> +read.
> +
>  @item -pre[:@var{stream_specifier}] @var{preset_name} 
> (@emph{output,per-stream})
>  Specify the preset for matching stream(s).
>  
> @@ -823,6 +829,12 @@ To generate 5 seconds of pure red video using lavfi 
> @code{color} source:
>  @example
>  avconv -filter_complex 'color=red' -t 5 out.mkv
>  @end example
> +
> +@item -filter_complex_script @var{filename} (@emph{global})
> +This option is similar to @option{-filter_complex}, the only difference is 
> that
> +its argument is the name of the file from which a complex filtergraph
> +description is to be read.
> +
>  @end table
>  @c man end OPTIONS
>  
> -- 

LGTM
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to