[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