diff mbox series

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

Message ID 20210426110144.109-1-alexander.solonsky@castlabs.com
State New
Headers show
Series [FFmpeg-devel] allows for independent codec setting per output video stream
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate fail Make fate failed
andriy/PPC64_make success Make finished
andriy/PPC64_make_fate warning Make fate failed

Commit Message

Alexander Solonsky April 26, 2021, 11:01 a.m. UTC
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(-)

Comments

Nicolas George April 26, 2021, 12:54 p.m. UTC | #1
Alexander Solonsky (12021-04-26):
> 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

It is already possible by suffixing options names with a colon and the
number of the stream.

Regards,
Alexander Solonsky April 26, 2021, 4:07 p.m. UTC | #2
Hi Nicolas,

I guess it is supposed to work in this way but it doesn't. And if you look
in the code you will see, than only one codec_opt is served for all c:v:0,
c:v:1 etc.

Best regards,
Alexander
///////////

On Mon, Apr 26, 2021 at 7:54 PM Nicolas George <george@nsup.org> wrote:

> Alexander Solonsky (12021-04-26):
> > 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
>
> It is already possible by suffixing options names with a colon and the
> number of the stream.
>
> Regards,
>
> --
>   Nicolas George
>
Nicolas George April 26, 2021, 4:16 p.m. UTC | #3
Alexander Solonsky (12021-04-26):
> I guess it is supposed to work in this way but it doesn't. And if you look
> in the code you will see, than only one codec_opt is served for all c:v:0,
> c:v:1 etc.

I checked it works before replying.

Do not top-post on this mailing-list. If you don't know what it means
look it up.

Regards,
Alexander Solonsky April 26, 2021, 4:40 p.m. UTC | #4
> I checked it works before replying. 
Thanks,
maybe let's get on the same page what we both think is working and what not.
I used this simple script:
ffmpeg -i $1 -map 0:v:0 -c:v:0 libx264 -x264-params 
"keyint=24:bframes=1" -map 0:v:0 -c:v:1 libx264 -x264-params 
"keyint=72:bframes=3" $2 -y
to create 2 streams out of 1 with different gop structure. And ffmpeg as 
it is currently produces both streams with keyint=72 and bframes=3. With 
my patch each stream preserves the x264 params set individually. Which 
script you used, that you could get for the similar scenario two 
different gop sized streams?

Thanks,
Alexander
///////////
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Nicolas George April 26, 2021, 4:43 p.m. UTC | #5
Alexander Solonsky (12021-04-26):
> maybe let's get on the same page what we both think is working and what not.
> I used this simple script:
> ffmpeg -i $1 -map 0:v:0 -c:v:0 libx264 -x264-params "keyint=24:bframes=1"
> -map 0:v:0 -c:v:1 libx264 -x264-params "keyint=72:bframes=3" $2 -y
> to create 2 streams out of 1 with different gop structure. And ffmpeg as it
> is currently produces both streams with keyint=72 and bframes=3. With my
> patch each stream preserves the x264 params set individually. Which script
> you used, that you could get for the similar scenario two different gop
> sized streams?

You specified -x264-params for all streams, it applies to all streams.
You need to use a stream specifier.

For further questions, please ask on the users mailing-lists.

Regards,
diff mbox series

Patch

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;