On Fri, Oct 07, 2011 at 03:18:27PM +0200, Alexandra Khirnova wrote:
> ---
>  avconv.c        |   67 
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  doc/avconv.texi |   18 ++++++++++++++
>  2 files changed, 85 insertions(+), 0 deletions(-)
> 
> diff --git a/avconv.c b/avconv.c
> index 74120c8..eaac503 100644
> --- a/avconv.c
> +++ b/avconv.c
> @@ -325,6 +325,8 @@ typedef struct OptionsContext {
>      int        nb_inter_matrices;
>      SpecifierOpt *top_field_first;
>      int        nb_top_field_first;
> +    SpecifierOpt *presets;
> +    int        nb_presets;
>  #if CONFIG_AVFILTER
>      SpecifierOpt *filters;
>      int        nb_filters;
> @@ -2932,6 +2934,49 @@ static void parse_forced_key_frames(char *kf, 
> OutputStream *ost,
>      }
>  }
>  
> +static uint8_t *get_line(AVIOContext *s)
> +{
> +    AVIOContext *line;
> +    uint8_t *buf = NULL;
> +    char c;
> +
> +    if (avio_open_dyn_buf(&line) < 0) {
> +        av_log(NULL, AV_LOG_FATAL, "Could not read line.\n");
> +        exit_program(1);

the failure message should be more verbose if avconv exits afterwards,
something like
"failure while reading line in preset file %s\n", s->filename

> +    }
> +
> +    while ((c = avio_r8(s)) && (c != '\n'))
> +        avio_w8(line, c);
> +    avio_w8(line, 0);
> +    avio_close_dyn_buf(line, &buf);
> +
> +    return buf;
> +}
> +
> +static int get_preset_file_2(const char *preset_name, const char 
> *codec_name, AVIOContext **s)
> +{
> +    int i, ret = 1;
> +    char filename[1000];
> +    const char *base[3] = { getenv("AVCONV_DATADIR"),
> +        getenv("HOME"),
> +        AVCONV_DATADIR,
> +    };
> +
> +    for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) {
> +        if (!base[i])
> +            continue;
> +        snprintf(filename, sizeof(filename), "%s%s/%s.ffpreset", base[i], i 
> != 1 ? "" : "/.avconv", preset_name);
> +        ret = avio_open(s, filename, AVIO_FLAG_READ);
> +        if (ret && codec_name) {

would it make more sense to try to open the codec specific preset file
first? 

> +            snprintf(filename, sizeof(filename),
> +                    "%s%s/%s-%s.ffpreset", base[i],  i != 1 ? "" : 
> "/.avconv", codec_name, preset_name);
> +            ret = avio_open(s, filename, AVIO_FLAG_READ);
> +        }
> +    }
> +
> +    return ret;
> +}
> +
>  static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext 
> *oc, enum AVMediaType type)
>  {
>      OutputStream *ost;
> @@ -2941,6 +2986,8 @@ static OutputStream *new_output_stream(OptionsContext 
> *o, AVFormatContext *oc, e
>      char *bsf = NULL, *next, *codec_tag = NULL;
>      AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;
>      double qscale = -1;
> +    char *preset = NULL, *buf = NULL, *arg = NULL;
> +    AVIOContext *s = NULL;
>  
>      if (!st) {
>          av_log(NULL, AV_LOG_ERROR, "Could not alloc stream.\n");
> @@ -2962,6 +3009,25 @@ static OutputStream *new_output_stream(OptionsContext 
> *o, AVFormatContext *oc, e
>      avcodec_get_context_defaults3(st->codec, ost->enc);
>      st->codec->codec_type = type; // XXX hack, 
> avcodec_get_context_defaults2() sets type to unknown for stream copy
>  
> +    MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
> +    if (preset && (get_preset_file_2(preset, ost->enc->name, &s) == 0)) {
> +        do  {
> +            buf = get_line(s);
> +            if (!buf[0] || buf[0] == '#') {
> +                av_free(buf);
> +                continue;
> +            }
> +            if (!(arg = strchr(buf, '='))) {
> +                av_log(NULL, AV_LOG_FATAL, "Not a preset file.\n");
> +                exit_program(1);
> +            }
> +            *arg++ = 0;
> +            av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);
> +            av_free(buf);
> +        } while (!s->eof_reached);
> +        avio_close(s);
> +    }
> +
>      MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st);
>      ost->max_frames = max_frames;
>  
> @@ -3914,6 +3980,7 @@ static const OptionDef options[] = {
>      { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" },
>      { "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, 
> "codec name", "codec" },
>      { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = 
> OFFSET(codec_names)}, "codec name", "codec" },
> +    { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(presets)}, 
> "preset name", "preset" },
>      { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input 
> stream mapping", "file.stream[:syncfile.syncstream]" },
>      { "map_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, 
> {(void*)opt_map_metadata}, "set metadata information of outfile from infile",
>        "outfile[,metadata]:infile[,metadata]" },
> diff --git a/doc/avconv.texi b/doc/avconv.texi
> index 156b9c2..d59fd7e 100644
> --- a/doc/avconv.texi
> +++ b/doc/avconv.texi
> @@ -188,6 +188,9 @@ codec-dependent.
>  the stream. Use @code{-filters} to show all the available filters
>  (including also sources and sinks).
>  
> +@item -pre[:@var{stream_specifier}] @var{preset_name} 
> (@emph{output,per-stream})
> +Specify the preset for matching stream(s).
> +
>  @end table
>  
>  @section Video Options
> @@ -766,6 +769,21 @@ quality).
>  @chapter Examples
>  @c man begin EXAMPLES
>  
> +@section Preset file
> +
> +A preset file contains a sequence of @var{option}=@var{value} pairs, one for
> +each line, specifying a sequence of options which would be awkward to 
> specify on
> +the command line. Lines starting with the hash ('#') character are ignored 
> and
> +are used to provide comments. Empty lines are also ignored. Check the
> +@file{ffpresets} directory in the Libav source tree for examples.

do the libx264 preset files in ffpresets still work? At least some use
deprected options. We should probably delete them since we can now use
-profile and -preset for libx264 directly.

> +Preset files are specified with the @code{pre} option, this option takes a
> +preset name as input.  Avconv searches for a file named @var{arg}.ffpreset in
> +the directories @file{$AVCONV_DATADIR} (if set), and @file{$HOME/.avconv}, 
> and in
> +the datadir defined at configuration time (usually 
> @file{$PREFIX/share/avconv})
> +in that order.  For example, if the argument is @code{libx264-max}, it will
> +search for the file @file{libx264-max.ffpreset}.
> +
>  @section Video and Audio grabbing
>  
>  If you specify the input format and device then avconv can grab video

looks good otherwise

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

Reply via email to