| @@ -326,6 +326,8 @@ typedef struct OptionsContext { · 325 unmodified lines |
| 326 | int nb_inter_matrices; | 326 | int nb_inter_matrices; |
| 327 | SpecifierOpt *top_field_first; | 327 | SpecifierOpt *top_field_first; |
| 328 | int nb_top_field_first; | 328 | int nb_top_field_first; |
| | 329 | SpecifierOpt *presets; |
| | 330 | int nb_presets; |
| 329 | #if CONFIG_AVFILTER | 331 | #if CONFIG_AVFILTER |
| 330 | SpecifierOpt *filters; | 332 | SpecifierOpt *filters; |
| 331 | int nb_filters; | 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 | static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type) | 3016 | static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type) |
| 2970 | { | 3017 | { |
| 2971 | OutputStream *ost; | 3018 | OutputStream *ost; |
| 2972 | AVStream *st = av_new_stream(oc, oc->nb_streams < o->nb_streamid_map ? o->streamid_map[oc->nb_streams] : 0); | 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 | int64_t max_frames = INT64_MAX; | 3021 | int64_t max_frames = INT64_MAX; |
| 2975 | char *bsf = NULL, *next, *codec_tag = NULL; | 3022 | char *bsf = NULL, *next, *codec_tag = NULL; |
| 2976 | AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; | 3023 | AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL; |
| 2977 | double qscale = -1; | 3024 | double qscale = -1; |
| | 3025 | char *buf = NULL, *arg = NULL, *preset = NULL; |
| | 3026 | AVIOContext *s = NULL; |
| 2978 | | 3027 | |
| 2979 | if (!st) { | 3028 | if (!st) { |
| 2980 | av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n"); | 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 | avcodec_get_context_defaults3(st->codec, ost->enc); | 3045 | avcodec_get_context_defaults3(st->codec, ost->enc); |
| 2997 | st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy | 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 | MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st); | 3073 | MATCH_PER_STREAM_OPT(max_frames, i64, max_frames, oc, st); |
| 3000 | ost->max_frames = max_frames; | 3074 | ost->max_frames = max_frames; |
| 3001 | | 3075 | |
| @@ -3906,6 +3980,7 @@ static const OptionDef options[] = { · 904 unmodified lines |
| 3906 | { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, | 3980 | { "y", OPT_BOOL, {(void*)&file_overwrite}, "overwrite output files" }, |
| 3907 | { "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, | 3981 | { "c", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, |
| 3908 | { "codec", HAS_ARG | OPT_STRING | OPT_SPEC, {.off = OFFSET(codec_names)}, "codec name", "codec" }, | 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 | { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" }, | 3984 | { "map", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map}, "set input stream mapping", "file.stream[:syncfile.syncstream]" }, |
| 3910 | { "map_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", | 3985 | { "map_metadata", HAS_ARG | OPT_EXPERT | OPT_FUNC2, {(void*)opt_map_metadata}, "set metadata information of outfile from infile", |
| 3911 | "outfile[,metadata]:infile[,metadata]" }, | 3986 | "outfile[,metadata]:infile[,metadata]" }, |