[FFmpeg-devel] [PATCH] allows for independent codec setting per output video stream

Alexander Solonsky alexander.solonsky at castlabs.com
Mon Apr 26 14:01:44 EEST 2021


Sometimes it is useful that output video streams have different gop structure and other settings. Currently one setting used for all and I added a posibility to have it separately
---
 fftools/cmdutils.c   | 22 ++++++++++++++++++++--
 fftools/cmdutils.h   |  2 ++
 fftools/ffmpeg_opt.c |  2 +-
 3 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c
index fe424b6a4c..4a3520b84b 100644
--- a/fftools/cmdutils.c
+++ b/fftools/cmdutils.c
@@ -67,7 +67,8 @@ static int init_report(const char *env);
 
 AVDictionary *sws_dict;
 AVDictionary *swr_opts;
-AVDictionary *format_opts, *codec_opts, *resample_opts;
+AVDictionary *format_opts, *codec_opts, *resample_opts, *codec_opts_aux[MAX_CODEC_OPTS];
+int codec_opts_aux_counter = 0;
 
 static FILE *report_file;
 static int report_file_level = AV_LOG_DEBUG;
@@ -86,11 +87,16 @@ void init_opts(void)
 
 void uninit_opts(void)
 {
+    int i;
+
     av_dict_free(&swr_opts);
     av_dict_free(&sws_dict);
     av_dict_free(&format_opts);
     av_dict_free(&codec_opts);
     av_dict_free(&resample_opts);
+    for(i = 0; i < codec_opts_aux_counter; i ++)
+        av_dict_free(&codec_opts_aux[i]);
+
 }
 
 void log_callback_help(void *ptr, int level, const char *fmt, va_list vl)
@@ -567,6 +573,10 @@ int opt_default(void *optctx, const char *opt, const char *arg)
         ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
          (o = opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ)))) {
         av_dict_set(&codec_opts, opt, arg, FLAGS);
+        av_dict_set(&codec_opts_aux[codec_opts_aux_counter], opt, arg, FLAGS);
+        if(codec_opts_aux_counter + 1 < MAX_CODEC_OPTS)
+            codec_opts_aux_counter ++;
+        // if more streams require separate codec opts - the rest will have to use the latest setting
         consumed = 1;
     }
     if ((o = opt_find(&fc, opt, NULL, 0,
@@ -660,6 +670,7 @@ static void finish_group(OptionParseContext *octx, int group_idx,
 {
     OptionGroupList *l = &octx->groups[group_idx];
     OptionGroup *g;
+    int i;
 
     GROW_ARRAY(l->groups, l->nb_groups);
     g = &l->groups[l->nb_groups - 1];
@@ -673,6 +684,11 @@ static void finish_group(OptionParseContext *octx, int group_idx,
     g->format_opts = format_opts;
     g->resample_opts = resample_opts;
 
+    for(i = 0; i < codec_opts_aux_counter; i ++)
+        g->codec_opts_aux[i] = codec_opts_aux[i];
+
+    for(i = 0; i < codec_opts_aux_counter; i ++)
+        codec_opts_aux[i] = NULL;
     codec_opts  = NULL;
     format_opts = NULL;
     resample_opts = NULL;
@@ -722,7 +738,7 @@ static void init_parse_context(OptionParseContext *octx,
 
 void uninit_parse_context(OptionParseContext *octx)
 {
-    int i, j;
+    int i, j, k;
 
     for (i = 0; i < octx->nb_groups; i++) {
         OptionGroupList *l = &octx->groups[i];
@@ -735,6 +751,8 @@ void uninit_parse_context(OptionParseContext *octx)
 
             av_dict_free(&l->groups[j].sws_dict);
             av_dict_free(&l->groups[j].swr_opts);
+            for (k = 0; k < codec_opts_aux_counter; k ++)
+                av_dict_free(&l->groups[j].codec_opts_aux[k]);
         }
         av_freep(&l->groups);
     }
diff --git a/fftools/cmdutils.h b/fftools/cmdutils.h
index 5da9f4c88f..238b80857f 100644
--- a/fftools/cmdutils.h
+++ b/fftools/cmdutils.h
@@ -308,6 +308,7 @@ typedef struct OptionGroupDef {
     int flags;
 } OptionGroupDef;
 
+#define MAX_CODEC_OPTS 16
 typedef struct OptionGroup {
     const OptionGroupDef *group_def;
     const char *arg;
@@ -316,6 +317,7 @@ typedef struct OptionGroup {
     int  nb_opts;
 
     AVDictionary *codec_opts;
+    AVDictionary *codec_opts_aux[MAX_CODEC_OPTS];
     AVDictionary *format_opts;
     AVDictionary *resample_opts;
     AVDictionary *sws_dict;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index 807e783422..a02e05f081 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -1474,7 +1474,7 @@ static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, e
         AVIOContext *s = NULL;
         char *buf = NULL, *arg = NULL, *preset = NULL;
 
-        ost->encoder_opts  = filter_codec_opts(o->g->codec_opts, ost->enc->id, oc, st, ost->enc);
+        ost->encoder_opts  = filter_codec_opts(o->g->codec_opts_aux[ost->index], ost->enc->id, oc, st, ost->enc);
 
         MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);
         ost->autoscale = 1;
-- 
2.28.0.windows.1



More information about the ffmpeg-devel mailing list