Unified · Split
| @@ -943,8 +943,9 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec) · 942 unmodified lines | ||
| 943 | 943 | return ret; |
| 944 | 944 | } |
| 945 | 945 | |
| 946 | −AVDictionary *filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id, | |
| 947 | − AVFormatContext *s, AVStream *st, const AVCodec *codec) | |
| 946 | +int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id, | |
| 947 | + AVFormatContext *s, AVStream *st, const AVCodec *codec, | |
| 948 | + AVDictionary **dst) | |
| 948 | 949 | { |
| 949 | 950 | AVDictionary *ret = NULL; |
| 950 | 951 | const AVDictionaryEntry *t = NULL; |
| @@ -977,12 +978,16 @@ AVDictionary *filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_i · 26 unmodified lines | ||
| 977 | 978 | char *p = strchr(t->key, ':'); |
| 978 | 979 | |
| 979 | 980 | /* check stream specification in opt name */ |
| 980 | − if (p) | |
| 981 | − switch (check_stream_specifier(s, st, p + 1)) { | |
| 982 | − case 1: *p = 0; break; | |
| 983 | − case 0: continue; | |
| 984 | − default: exit_program(1); | |
| 985 | − } | |
| 981 | + if (p) { | |
| 982 | + int err = check_stream_specifier(s, st, p + 1); | |
| 983 | + if (err < 0) { | |
| 984 | + av_dict_free(&ret); | |
| 985 | + return err; | |
| 986 | + } else if (!err) | |
| 987 | + continue; | |
| 988 | + | |
| 989 | + *p = 0; | |
| 990 | + } | |
| 986 | 991 | |
| 987 | 992 | if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) || |
| 988 | 993 | !codec || |
| @@ -998,14 +1003,16 @@ AVDictionary *filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_i · 9 unmodified lines | ||
| 998 | 1003 | if (p) |
| 999 | 1004 | *p = ':'; |
| 1000 | 1005 | } |
| 1001 | − return ret; | |
| 1006 | + | |
| 1007 | + *dst = ret; | |
| 1008 | + return 0; | |
| 1002 | 1009 | } |
| 1003 | 1010 | |
| 1004 | 1011 | int setup_find_stream_info_opts(AVFormatContext *s, |
| 1005 | 1012 | AVDictionary *codec_opts, |
| 1006 | 1013 | AVDictionary ***dst) |
| 1007 | 1014 | { |
| 1008 | − int i; | |
| 1015 | + int ret; | |
| 1009 | 1016 | AVDictionary **opts; |
| 1010 | 1017 | |
| 1011 | 1018 | *dst = NULL; |
| @@ -1017,11 +1024,19 @@ int setup_find_stream_info_opts(AVFormatContext *s, · 5 unmodified lines | ||
| 1017 | 1024 | if (!opts) |
| 1018 | 1025 | return AVERROR(ENOMEM); |
| 1019 | 1026 | |
| 1020 | − for (i = 0; i < s->nb_streams; i++) | |
| 1021 | − opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id, | |
| 1022 | − s, s->streams[i], NULL); | |
| 1027 | + for (int i = 0; i < s->nb_streams; i++) { | |
| 1028 | + ret = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id, | |
| 1029 | + s, s->streams[i], NULL, &opts[i]); | |
| 1030 | + if (ret < 0) | |
| 1031 | + goto fail; | |
| 1032 | + } | |
| 1023 | 1033 | *dst = opts; |
| 1024 | 1034 | return 0; |
| 1035 | +fail: | |
| 1036 | + for (int i = 0; i < s->nb_streams; i++) | |
| 1037 | + av_dict_free(&opts[i]); | |
| 1038 | + av_freep(&opts); | |
| 1039 | + return ret; | |
| 1025 | 1040 | } |
| 1026 | 1041 | |
| 1027 | 1042 | int grow_array(void **array, int elem_size, int *size, int new_size) |
| @@ -333,10 +333,12 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec); · 332 unmodified lines | ||
| 333 | 333 | * @param st A stream from s for which the options should be filtered. |
| 334 | 334 | * @param codec The particular codec for which the options should be filtered. |
| 335 | 335 | * If null, the default one is looked up according to the codec id. |
| 336 | − * @return a pointer to the created dictionary | |
| 336 | + * @param dst a pointer to the created dictionary | |
| 337 | + * @return a non-negative number on success, a negative error code on failure | |
| 337 | 338 | */ |
| 338 | −AVDictionary *filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id, | |
| 339 | − AVFormatContext *s, AVStream *st, const AVCodec *codec); | |
| 339 | +int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id, | |
| 340 | + AVFormatContext *s, AVStream *st, const AVCodec *codec, | |
| 341 | + AVDictionary **dst); | |
| 340 | 342 | |
| 341 | 343 | /** |
| 342 | 344 | * Setup AVCodecContext options for avformat_find_stream_info(). |
| @@ -1176,7 +1176,10 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st) · 1175 unmodified lines | ||
| 1176 | 1176 | if (ret < 0) |
| 1177 | 1177 | return ret; |
| 1178 | 1178 | |
| 1179 | − ist->decoder_opts = filter_codec_opts(o->g->codec_opts, ist->st->codecpar->codec_id, ic, st, ist->dec); | |
| 1179 | + ret = filter_codec_opts(o->g->codec_opts, ist->st->codecpar->codec_id, | |
| 1180 | + ic, st, ist->dec, &ist->decoder_opts); | |
| 1181 | + if (ret < 0) | |
| 1182 | + return ret; | |
| 1180 | 1183 | |
| 1181 | 1184 | ist->reinit_filters = -1; |
| 1182 | 1185 | MATCH_PER_STREAM_OPT(reinit_filters, i, ist->reinit_filters, ic, st); |
| @@ -1206,8 +1206,10 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, · 1205 unmodified lines | ||
| 1206 | 1206 | const char *enc_stats_pre = NULL, *enc_stats_post = NULL, *mux_stats = NULL; |
| 1207 | 1207 | const char *enc_time_base = NULL; |
| 1208 | 1208 | |
| 1209 | − ost->encoder_opts = filter_codec_opts(o->g->codec_opts, enc->codec_id, | |
| 1210 | − oc, st, enc->codec); | |
| 1209 | + ret = filter_codec_opts(o->g->codec_opts, enc->codec_id, | |
| 1210 | + oc, st, enc->codec, &ost->encoder_opts); | |
| 1211 | + if (ret < 0) | |
| 1212 | + return ret; | |
| 1211 | 1213 | |
| 1212 | 1214 | MATCH_PER_STREAM_OPT(presets, str, preset, oc, st); |
| 1213 | 1215 | ost->autoscale = 1; |
| @@ -1305,7 +1307,10 @@ static int ost_add(Muxer *mux, const OptionsContext *o, enum AVMediaType type, · 91 unmodified lines | ||
| 1305 | 1307 | ost->enc_timebase = q; |
| 1306 | 1308 | } |
| 1307 | 1309 | } else { |
| 1308 | − ost->encoder_opts = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, NULL); | |
| 1310 | + ret = filter_codec_opts(o->g->codec_opts, AV_CODEC_ID_NONE, oc, st, | |
| 1311 | + NULL, &ost->encoder_opts); | |
| 1312 | + if (ret < 0) | |
| 1313 | + return ret; | |
| 1309 | 1314 | } |
| 1310 | 1315 | |
| 1311 | 1316 | |
| @@ -2584,7 +2584,11 @@ static int stream_component_open(VideoState *is, int stream_index) · 2583 unmodified lines | ||
| 2584 | 2584 | if (fast) |
| 2585 | 2585 | avctx->flags2 |= AV_CODEC_FLAG2_FAST; |
| 2586 | 2586 | |
| 2587 | − opts = filter_codec_opts(codec_opts, avctx->codec_id, ic, ic->streams[stream_index], codec); | |
| 2587 | + ret = filter_codec_opts(codec_opts, avctx->codec_id, ic, | |
| 2588 | + ic->streams[stream_index], codec, &opts); | |
| 2589 | + if (ret < 0) | |
| 2590 | + goto fail; | |
| 2591 | + | |
| 2588 | 2592 | if (!av_dict_get(opts, "threads", NULL, 0)) |
| 2589 | 2593 | av_dict_set(&opts, "threads", "auto", 0); |
| 2590 | 2594 | if (stream_lowres) |
| @@ -3421,8 +3421,12 @@ static int open_input_file(InputFile *ifile, const char *filename, · 3420 unmodified lines | ||
| 3421 | 3421 | continue; |
| 3422 | 3422 | } |
| 3423 | 3423 | { |
| 3424 | − AVDictionary *opts = filter_codec_opts(codec_opts, stream->codecpar->codec_id, | |
| 3425 | − fmt_ctx, stream, codec); | |
| 3424 | + AVDictionary *opts; | |
| 3425 | + | |
| 3426 | + err = filter_codec_opts(codec_opts, stream->codecpar->codec_id, | |
| 3427 | + fmt_ctx, stream, codec, &opts); | |
| 3428 | + if (err < 0) | |
| 3429 | + exit(1); | |
| 3426 | 3430 | |
| 3427 | 3431 | ist->dec_ctx = avcodec_alloc_context3(codec); |
| 3428 | 3432 | if (!ist->dec_ctx) |