| @@ -326,6 +326,8 @@ typedef struct OptionsContext { · 325 unmodified lines |
| 326 | 326 | int nb_inter_matrices; |
| 327 | 327 | SpecifierOpt *top_field_first; |
| 328 | 328 | int nb_top_field_first; |
| 329 | + SpecifierOpt *presets; |
| 330 | + int nb_presets; |
| 329 | 331 | #if CONFIG_AVFILTER |
| 330 | 332 | SpecifierOpt *filters; |
| 331 | 333 | int nb_filters; |
| @@ -2966,15 +2968,62 @@ static void parse_forced_key_frames(char *kf, OutputStream *ost, · 2634 unmodified lines |
| 2966 | 2968 | } |
| 2967 | 2969 | } |
| 2968 | 2970 | |
| 2971 | +static uint8_t *get_line(AVIOContext *s) |
| 2972 | +{ |
| 2973 | + AVIOContext *line; |
| 2974 | + uint8_t *buf; |
| 2975 | + char c; |
| 2976 | + |
| 2977 | + if (avio_open_dyn_buf(&line) < 0) { |
| 2978 | + av_log(NULL, AV_LOG_FATAL, "Could not alloc buffer for reading preset.\n"); |
| 2979 | + exit_program(1); |
| 2980 | + } |
| 2981 | + |
| 2982 | + while ((c = avio_r8(s)) && c != '\n') |
| 2983 | + avio_w8(line, c); |
| 2984 | + avio_w8(line, 0); |
| 2985 | + avio_close_dyn_buf(line, &buf); |
| 2986 | + |
| 2987 | + return buf; |
| 2988 | +} |
| 2989 | + |
| 2990 | +static int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s) |
| 2991 | +{ |
| 2992 | + int i, ret = 1; |
| 2993 | + char filename[1000]; |
| 2994 | + const char *base[3] = { getenv("AVCONV_DATADIR"), |
| 2995 | + getenv("HOME"), |
| 2996 | + AVCONV_DATADIR, |
| 2997 | + }; |
| 2998 | + |
| 2999 | + for (i = 0; i < FF_ARRAY_ELEMS(base) && ret; i++) { |
| 3000 | + if (!base[i]) |
| 3001 | + continue; |
| 3002 | + if (codec_name) { |
| 3003 | + snprintf(filename, sizeof(filename), "%s%s/%s-%s.avpreset", base[i], |
| 3004 | + i != 1 ? "" : "/.avconv", codec_name, preset_name); |
| 3005 | + ret = avio_open(s, filename, AVIO_FLAG_READ); |
| 3006 | + } |
| 3007 | + if (ret) { |
| 3008 | + snprintf(filename, sizeof(filename), "%s%s/%s.avpreset", base[i], |
| 3009 | + i != 1 ? "" : "/.avconv", preset_name); |
| 3010 | + ret = avio_open(s, filename, AVIO_FLAG_READ); |
| 3011 | + } |
| 3012 | + } |
| 3013 | + return ret; |
| 3014 | +} |
| 3015 | + |
| 2969 | 3016 | static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type) |
| 2970 | 3017 | { |
| 2971 | 3018 | OutputStream *ost; |
| 2972 | 3019 | AVStream *st = av_new_stream(oc, oc->nb_streams < o->nb_streamid_map ? o->streamid_map[oc->nb_streams] : 0); |
| 2973 | | − int idx = oc->nb_streams - 1; |
| 3020 | + int idx = oc->nb_streams - 1, ret = 0; |
| 2974 | 3021 | int64_t max_frames = INT64_MAX; |
| 2975 | 3022 | char *bsf = NULL, *next, *codec_tag = NULL; |
| 2976 | 3023 | AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; |
| 2977 | 3024 | double qscale = -1; |
| 3025 | + char *buf = NULL, *arg = NULL, *preset = NULL; |
| 3026 | + AVIOContext *s = NULL; |
| 2978 | 3027 | |
| 2979 | 3028 | if (!st) { |
| 2980 | 3029 | av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n"); |
| @@ -2996,6 +3045,31 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e · 15 unmodified lines |
| 2996 | 3045 | avcodec_get_context_defaults3(st->codec, ost->enc); |
| 2997 | 3046 | st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy |
| 2998 | 3047 | |
| 3048 | + MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); |
| 3049 | + if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) { |
| 3050 | + do { |
| 3051 | + buf = get_line(s); |
| 3052 | + if (!buf[0] || buf[0] == '#') { |
| 3053 | + av_free(buf); |
| 3054 | + continue; |
| 3055 | + } |
| 3056 | + if (!(arg = strchr(buf, '='))) { |
| 3057 | + av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n"); |
| 3058 | + exit_program(1); |
| 3059 | + } |
| 3060 | + *arg++ = 0; |
| 3061 | + av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE); |
| 3062 | + av_free(buf); |
| 3063 | + } while (!s->eof_reached); |
| 3064 | + avio_close(s); |
| 3065 | + } |
| 3066 | + if (ret) { |
| 3067 | + av_log(NULL, AV_LOG_FATAL, |
| 3068 | + "Preset %s specified for stream %d:%d, but could not be opened.\n", |
| 3069 | + preset, ost->file_index, ost->index); |
| 3070 | + exit_program(1); |
| 3071 | + } |
| 3072 | + |
| 2999 | 3073 | MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st); |
| 3000 | 3074 | ost->max_frames = max_frames; |
| 3001 | 3075 | |
| @@ -3906,6 +3980,7 @@ static const OptionDef options[] = { · 904 unmodified lines |
| 3906 | 3980 | { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, |
| 3907 | 3981 | { "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, |
| 3908 | 3982 | { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, |
| 3983 | + { "pre", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(presets)}, "preset name", "preset" }, |
| 3909 | 3984 | { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" }, |
| 3910 | 3985 | { "map_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", |
| 3911 | 3986 | "outfile[,metadata]:infile[,metadata]" }, |