[FFmpeg-cvslog] avconv: refactor selecting an encoder

Anton Khirnov git at videolan.org
Sat Aug 6 20:58:13 EEST 2016


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Mon May 23 07:38:58 2016 +0200| [90944ee3ab79081845ea1bd97eea475031ce0842] | committer: Anton Khirnov

avconv: refactor selecting an encoder

Fail immediately if automatic encoder selection failed. Always set the
stream_copy/encoding_needed flags in one place.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=90944ee3ab79081845ea1bd97eea475031ce0842
---

 avconv.c     | 11 -----------
 avconv_opt.c | 51 +++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 37 insertions(+), 25 deletions(-)

diff --git a/avconv.c b/avconv.c
index 4f8d688..6470837 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 9e90711..eab79f2 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;



More information about the ffmpeg-cvslog mailing list