[FFmpeg-devel] [PATCH] ffmpeg: add -fpsmin to clamp output framerate
Gyan Doshi
ffmpeg at gyani.pro
Thu Jun 3 17:03:39 EEST 2021
On 2021-06-03 14:08, Matthias Neugebauer wrote:
> Add -fpsmin analogously to -fpsmax for setting a lower bound to the
> auto-set frame rate.
Still not picked up.
Should be sent same as your patch from December.
https://patchwork.ffmpeg.org/project/ffmpeg/list/?series=&submitter=1113&state=*&q=&archive=both&delegate=
>
> Signed-off-by: Matthias Neugebauer <mtneug at mailbox.org>
> ---
> doc/ffmpeg.texi | 7 +++++++
> fftools/ffmpeg.c | 7 ++++++-
> fftools/ffmpeg.h | 3 +++
> fftools/ffmpeg_opt.c | 26 +++++++++++++++++++++++---
> 4 files changed, 39 insertions(+), 4 deletions(-)
>
> diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
> index 9feabe6517..5576508347 100644
> --- a/doc/ffmpeg.texi
> +++ b/doc/ffmpeg.texi
> @@ -862,6 +862,13 @@ Clamps output frame rate when output framerate is auto-set and is higher than th
> Useful in batch processing or when input framerate is wrongly detected as very high.
> It cannot be set together with @code{-r}. It is ignored during streamcopy.
>
> + at item -fpsmin[:@var{stream_specifier}] @var{fps} (@emph{output,per-stream})
> +Set minimum frame rate (Hz value, fraction or abbreviation).
> +
> +Clamps output frame rate when output framerate is auto-set and is lower than this value.
> +Useful in batch processing or when input framerate is wrongly detected as very low.
> +It cannot be set together with @code{-r}. It is ignored 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 b3658d8f65..fd9747a8ac 100644
> --- a/fftools/ffmpeg.c
> +++ b/fftools/ffmpeg.c
> @@ -3390,7 +3390,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 && !ost->max_frame_rate.num) {
> + if (ist && !ost->frame_rate.num && !ost->max_frame_rate.num && !ost->min_frame_rate.num) {
> ost->frame_rate = (AVRational){25, 1};
> av_log(NULL, AV_LOG_WARNING,
> "No information "
> @@ -3400,6 +3400,11 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame)
> ost->file_index, ost->index);
> }
>
> + if (ost->min_frame_rate.num &&
> + (av_q2d(ost->frame_rate) < av_q2d(ost->min_frame_rate) ||
> + !ost->frame_rate.den))
> + ost->frame_rate = ost->min_frame_rate;
> +
> if (ost->max_frame_rate.num &&
> (av_q2d(ost->frame_rate) > av_q2d(ost->max_frame_rate) ||
> !ost->frame_rate.den))
> diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
> index 606f2afe0c..515d0c7a46 100644
> --- a/fftools/ffmpeg.h
> +++ b/fftools/ffmpeg.h
> @@ -110,6 +110,8 @@ typedef struct OptionsContext {
> int nb_frame_rates;
> SpecifierOpt *max_frame_rates;
> int nb_max_frame_rates;
> + SpecifierOpt *min_frame_rates;
> + int nb_min_frame_rates;
> SpecifierOpt *frame_sizes;
> int nb_frame_sizes;
> SpecifierOpt *frame_pix_fmts;
> @@ -486,6 +488,7 @@ typedef struct OutputStream {
> /* video only */
> AVRational frame_rate;
> AVRational max_frame_rate;
> + AVRational min_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 849d24b16d..b0d7550ce6 100644
> --- a/fftools/ffmpeg_opt.c
> +++ b/fftools/ffmpeg_opt.c
> @@ -56,6 +56,7 @@ 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[] = {"fpsmax", NULL};
> +static const char *const opt_name_min_frame_rates[] = {"fpsmin", 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};
> @@ -1694,7 +1695,7 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in
> AVStream *st;
> OutputStream *ost;
> AVCodecContext *video_enc;
> - char *frame_rate = NULL, *max_frame_rate = NULL, *frame_aspect_ratio = NULL;
> + char *frame_rate = NULL, *max_frame_rate = NULL, *min_frame_rate = NULL, *frame_aspect_ratio = NULL;
>
> ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index);
> st = ost->st;
> @@ -1712,14 +1713,30 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, in
> exit_program(1);
> }
>
> + MATCH_PER_STREAM_OPT(min_frame_rates, str, min_frame_rate, oc, st);
> + if (min_frame_rate && av_parse_video_rate(&ost->min_frame_rate, min_frame_rate) < 0) {
> + av_log(NULL, AV_LOG_FATAL, "Invalid minimum framerate value: %s\n", min_frame_rate);
> + exit_program(1);
> + }
> +
> if (frame_rate && max_frame_rate) {
> av_log(NULL, AV_LOG_ERROR, "Only one of -fpsmax and -r can be set for a stream.\n");
> exit_program(1);
> }
>
> - if ((frame_rate || max_frame_rate) &&
> + if (frame_rate && min_frame_rate) {
> + av_log(NULL, AV_LOG_ERROR, "Only one of -fpsmin and -r can be set for a stream.\n");
> + exit_program(1);
> + }
> +
> + if (min_frame_rate && max_frame_rate && av_q2d(ost->min_frame_rate) > av_q2d(ost->max_frame_rate)) {
> + av_log(NULL, AV_LOG_ERROR, "-fpsmin cannot be larger then -fpsmax.\n");
> + exit_program(1);
> + }
> +
> + if ((frame_rate || max_frame_rate || min_frame_rate) &&
> video_sync_method == VSYNC_PASSTHROUGH)
> - av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r/-fpsmax can produce invalid output files\n");
> + av_log(NULL, AV_LOG_ERROR, "Using -vsync 0 and -r/-fpsmax/-fpsmin can produce invalid output files\n");
>
> MATCH_PER_STREAM_OPT(frame_aspect_ratios, str, frame_aspect_ratio, oc, st);
> if (frame_aspect_ratio) {
> @@ -3609,6 +3626,9 @@ const OptionDef options[] = {
> { "fpsmax", 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" },
> + { "fpsmin", OPT_VIDEO | HAS_ARG | OPT_STRING | OPT_SPEC |
> + OPT_OUTPUT, { .off = OFFSET(min_frame_rates) },
> + "set min 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" },
More information about the ffmpeg-devel
mailing list