From 90944ee3ab79081845ea1bd97eea475031ce0842 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Mon, 23 May 2016 07:38:58 +0200 Subject: [PATCH] avconv: refactor selecting an encoder Fail immediately if automatic encoder selection failed. Always set the stream_copy/encoding_needed flags in one place. --- avconv.c | 11 ----------- avconv_opt.c | 51 +++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/avconv.c b/avconv.c index 4f8d688895..6470837d59 100644 --- a/avconv.c +++ b/avconv.c @@ -1949,17 +1949,6 @@ static int transcode_init(void) AVCodecContext *enc_ctx = ost->enc_ctx; AVCodecContext *dec_ctx = NULL; - if (!ost->enc) { - /* should only happen when a default codec is not present. */ - snprintf(error, sizeof(error), "Automatic encoder selection " - "failed for output stream #%d:%d. Default encoder for " - "format %s is probably disabled. Please choose an " - "encoder manually.\n", ost->file_index, ost->index, - oc->oformat->name); - ret = AVERROR(EINVAL); - goto dump_format; - } - set_encoder_id(output_files[ost->file_index], ost); if (ist) { diff --git a/avconv_opt.c b/avconv_opt.c index 9e907113a2..eab79f20d5 100644 --- a/avconv_opt.c +++ b/avconv_opt.c @@ -919,21 +919,39 @@ static int get_preset_file_2(const char *preset_name, const char *codec_name, AV return ret; } -static void choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost) +static int choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost) { + enum AVMediaType type = ost->st->codecpar->codec_type; char *codec_name = NULL; - MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st); - if (!codec_name) { - ost->st->codecpar->codec_id = av_guess_codec(s->oformat, NULL, s->filename, - NULL, ost->st->codecpar->codec_type); - ost->enc = avcodec_find_encoder(ost->st->codecpar->codec_id); - } else if (!strcmp(codec_name, "copy")) - ost->stream_copy = 1; - else { - ost->enc = find_codec_or_die(codec_name, ost->st->codecpar->codec_type, 1); - ost->st->codecpar->codec_id = ost->enc->id; + if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_SUBTITLE) { + MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, ost->st); + if (!codec_name) { + ost->st->codecpar->codec_id = av_guess_codec(s->oformat, NULL, s->filename, + NULL, ost->st->codecpar->codec_type); + ost->enc = avcodec_find_encoder(ost->st->codecpar->codec_id); + if (!ost->enc) { + av_log(NULL, AV_LOG_FATAL, "Automatic encoder selection failed for " + "output stream #%d:%d. Default encoder for format %s is " + "probably disabled. Please choose an encoder manually.\n", + ost->file_index, ost->index, s->oformat->name); + return AVERROR_ENCODER_NOT_FOUND; + } + } else if (!strcmp(codec_name, "copy")) + ost->stream_copy = 1; + else { + ost->enc = find_codec_or_die(codec_name, ost->st->codecpar->codec_type, 1); + ost->st->codecpar->codec_id = ost->enc->id; + } + + ost->encoding_needed = !ost->stream_copy; + } else { + /* no encoding supported for other media types */ + ost->stream_copy = 1; + ost->encoding_needed = 0; } + + return 0; } static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type) @@ -962,7 +980,13 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e ost->index = idx; ost->st = st; st->codecpar->codec_type = type; - choose_encoder(o, oc, ost); + + ret = choose_encoder(o, oc, ost); + if (ret < 0) { + av_log(NULL, AV_LOG_FATAL, "Error selecting an encoder for stream " + "%d:%d\n", ost->file_index, ost->index); + exit_program(1); + } ost->enc_ctx = avcodec_alloc_context3(ost->enc); if (!ost->enc_ctx) { @@ -1723,11 +1747,10 @@ loop_end: } av_dict_free(&unused_opts); - /* set the encoding/decoding_needed flags and create simple filtergraphs */ + /* set the decoding_needed flags and create simple filtergraphs */ for (i = of->ost_index; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; - ost->encoding_needed = !ost->stream_copy; if (ost->encoding_needed && ost->source_index >= 0) { InputStream *ist = input_streams[ost->source_index]; ist->decoding_needed = 1;