Plan to push this in a day.

On 01-02-2021 06:52 pm, Gyan Doshi wrote:
Useful when encoding in batch or with aberrant inputs.
---
  doc/ffmpeg.texi      |  7 +++++++
  fftools/ffmpeg.c     |  7 ++++++-
  fftools/ffmpeg.h     |  3 +++
  fftools/ffmpeg_opt.c | 24 +++++++++++++++++++++---
  4 files changed, 37 insertions(+), 4 deletions(-)

Forgot to nullify rmax with r set.

diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 8eb012b7c0..7726f25082 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -759,6 +759,13 @@ If in doubt use @option{-framerate} instead of the input 
option @option{-r}.
  As an output option, duplicate or drop input frames to achieve constant output
  frame rate @var{fps}.
+@item -rmax[:@var{stream_specifier}] @var{fps} (@emph{output,per-stream})
+Set maximum frame rate (Hz value, fraction or abbreviation).
+
+Clamps output frame rate when output framerate is auto-set and is higher than 
this value.
+Useful in batch processing or when input framerate is wrongly detected as very 
high.
+Ignored when either @code{-r} is set or during streamcopy.
+
  @item -s[:@var{stream_specifier}] @var{size} (@emph{input/output,per-stream})
  Set frame size.
diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c
index d7c833be63..add5a3e505 100644
--- a/fftools/ffmpeg.c
+++ b/fftools/ffmpeg.c
@@ -3376,7 +3376,7 @@ static int init_output_stream_encode(OutputStream *ost, 
AVFrame *frame)
              ost->frame_rate = ist->framerate;
          if (ist && !ost->frame_rate.num)
              ost->frame_rate = ist->st->r_frame_rate;
-        if (ist && !ost->frame_rate.num) {
+        if (ist && !ost->frame_rate.num && !ost->max_frame_rate.num) {
              ost->frame_rate = (AVRational){25, 1};
              av_log(NULL, AV_LOG_WARNING,
                     "No information "
@@ -3386,6 +3386,11 @@ static int init_output_stream_encode(OutputStream *ost, 
AVFrame *frame)
                     ost->file_index, ost->index);
          }
+ if (ost->max_frame_rate.num &&
+            (av_q2d(ost->frame_rate) > av_q2d(ost->max_frame_rate) ||
+            !ost->frame_rate.den))
+            ost->frame_rate = ost->max_frame_rate;
+
          if (ost->enc->supported_framerates && !ost->force_fps) {
              int idx = av_find_nearest_q_idx(ost->frame_rate, 
ost->enc->supported_framerates);
              ost->frame_rate = ost->enc->supported_framerates[idx];
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index 8046e75026..3662130da4 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -108,6 +108,8 @@ typedef struct OptionsContext {
      int        nb_audio_sample_rate;
      SpecifierOpt *frame_rates;
      int        nb_frame_rates;
+    SpecifierOpt *max_frame_rates;
+    int        nb_max_frame_rates;
      SpecifierOpt *frame_sizes;
      int        nb_frame_sizes;
      SpecifierOpt *frame_pix_fmts;
@@ -479,6 +481,7 @@ typedef struct OutputStream {
/* video only */
      AVRational frame_rate;
+    AVRational max_frame_rate;
      int is_cfr;
      int force_fps;
      int top_field_first;
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index bf2eb26246..2080499e65 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -55,6 +55,7 @@ static const char *const opt_name_codec_names[]               = {"c", 
"codec", "
  static const char *const opt_name_audio_channels[]            = {"ac", NULL};
  static const char *const opt_name_audio_sample_rate[]         = {"ar", NULL};
  static const char *const opt_name_frame_rates[]               = {"r", NULL};
+static const char *const opt_name_max_frame_rates[]           = {"rmax", NULL};
  static const char *const opt_name_frame_sizes[]               = {"s", NULL};
  static const char *const opt_name_frame_pix_fmts[]            = {"pix_fmt", 
NULL};
  static const char *const opt_name_ts_scale[]                  = {"itsscale", 
NULL};
@@ -1688,7 +1689,7 @@ static OutputStream *new_video_stream(OptionsContext *o, 
AVFormatContext *oc, in
      AVStream *st;
      OutputStream *ost;
      AVCodecContext *video_enc;
-    char *frame_rate = NULL, *frame_aspect_ratio = NULL;
+    char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = 
NULL;
ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index);
      st  = ost->st;
@@ -1699,8 +1700,22 @@ static OutputStream *new_video_stream(OptionsContext *o, 
AVFormatContext *oc, in
          av_log(NULL, AV_LOG_FATAL, "Invalid framerate value: %s\n", 
frame_rate);
          exit_program(1);
      }
-    if (frame_rate && video_sync_method == VSYNC_PASSTHROUGH)
-        av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r can produce invalid 
output files\n");
+
+    MATCH_PER_STREAM_OPT(max_frame_rates, str, max_frame_rate, oc, st);
+    if (max_frame_rate && av_parse_video_rate(&ost->max_frame_rate, 
max_frame_rate) < 0) {
+        av_log(NULL, AV_LOG_FATAL, "Invalid maximum framerate value: %s\n", 
max_frame_rate);
+        exit_program(1);
+    }
+
+    if (frame_rate && max_frame_rate) {
+        av_log(NULL, AV_LOG_WARNING, "-rmax for stream %d:%d will have no effect 
as"
+               " -r is also set.\n", ost->file_index, ost->index);
+        ost->max_frame_rate = (AVRational){0, 1};
+    }
+
+    if ((frame_rate || max_frame_rate) &&
+        video_sync_method == VSYNC_PASSTHROUGH)
+        av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r/-rmax can produce invalid 
output files\n");
MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
      if (frame_aspect_ratio) {
@@ -3596,6 +3611,9 @@ const OptionDef options[] = {
      { "r",            OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
                        OPT_INPUT | OPT_OUTPUT,                                 
   { .off = OFFSET(frame_rates) },
          "set frame rate (Hz value, fraction or abbreviation)", "rate" },
+    { "rmax",         OPT_VIDEO | HAS_ARG  | OPT_STRING | OPT_SPEC |
+                      OPT_OUTPUT,                                              
  { .off = OFFSET(max_frame_rates) },
+        "set max frame rate (Hz value, fraction or abbreviation)", "rate" },
      { "s",            OPT_VIDEO | HAS_ARG | OPT_SUBTITLE | OPT_STRING | 
OPT_SPEC |
                        OPT_INPUT | OPT_OUTPUT,                                 
   { .off = OFFSET(frame_sizes) },
          "set frame size (WxH or abbreviation)", "size" },

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to