[FFmpeg-devel] [PATCH v2] ffmpeg: add -fpsmin to clamp output framerate

Gyan Doshi ffmpeg at gyani.pro
Sat May 29 09:41:58 EEST 2021



On 2021-05-15 18:41, Gyan Doshi wrote:
> I'll review this in a few days.

Can you send this again? Patchwork hasn't appeared to pick it up earlier?

>
> On 2021-05-11 21:42, Matthias Neugebauer wrote:
>> Add -fpsmin analogously to -fpsmax for setting a lower bound to the
>> auto-set frame rate.
>>
>> Signed-off-by: Matthias Neugebauer <mtneug at mailbox.org>
>> ---
>> doc/ffmpeg.texi      |  7 +++++++
>> fftools/ffmpeg.c     |  8 +++++++-
>> fftools/ffmpeg.h     |  3 +++
>> fftools/ffmpeg_opt.c | 26 +++++++++++++++++++++++---
>> 4 files changed, 40 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 3ad11452da..696ba7d730 100644
>> --- a/fftools/ffmpeg.c
>> +++ b/fftools/ffmpeg.c
>> @@ -3390,7 +3390,8 @@ 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 +3401,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" },
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".



More information about the ffmpeg-devel mailing list