diff mbox series

[FFmpeg-devel,1/4] fftools/ffmpeg: add ability to set a input burst time before readrate is enforced

Message ID 20230502134316.10496-1-anton@khirnov.net
State Accepted
Commit 2ae16b05d62f50ba3719af3c279db1109240a74b
Headers show
Series [FFmpeg-devel,1/4] fftools/ffmpeg: add ability to set a input burst time before readrate is enforced | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished

Commit Message

Anton Khirnov May 2, 2023, 1:43 p.m. UTC
From: Davy Durham <ddurham@davyandbeth.com>

Signed-off-by: Anton Khirnov <anton@khirnov.net>
---
Picking up this patch because it interacts with my ongoing work on
ffmpeg CLI. Applied my review comments, including renaming the option to
-readrate_initial_burst.

CCing the original author, please let me know if you'd prefer to handle
this patch yourself.
---
 Changelog              |  1 +
 doc/ffmpeg.texi        |  3 +++
 fftools/ffmpeg.h       |  1 +
 fftools/ffmpeg_demux.c | 18 +++++++++++++++++-
 fftools/ffmpeg_opt.c   |  3 +++
 5 files changed, 25 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/Changelog b/Changelog
index 4901ef6ad7..2061aaf462 100644
--- a/Changelog
+++ b/Changelog
@@ -7,6 +7,7 @@  version <next>:
 - Extend VAAPI support for libva-win32 on Windows
 - afireqsrc audio source filter
 - arls filter
+- ffmpeg CLI new option: -readrate_initial_burst
 
 version 6.0:
 - Radiance HDR image support
diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi
index 0fea0bacb1..a12700e2f3 100644
--- a/doc/ffmpeg.texi
+++ b/doc/ffmpeg.texi
@@ -1708,6 +1708,9 @@  it may cause packet loss.
 It is useful for when flow speed of output packets is important, such as live streaming.
 @item -re (@emph{input})
 Read input at native frame rate. This is equivalent to setting @code{-readrate 1}.
+@item -readrate_initial_burst @var{seconds}
+Set an initial read burst time, in seconds, after which @option{-re/-readrate}
+will be enforced.
 @item -vsync @var{parameter} (@emph{global})
 @itemx -fps_mode[:@var{stream_specifier}] @var{parameter} (@emph{output,per-stream})
 Set video sync method / framerate mode. vsync is applied to all output video streams
diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h
index b6389d7f99..a03a6b0302 100644
--- a/fftools/ffmpeg.h
+++ b/fftools/ffmpeg.h
@@ -126,6 +126,7 @@  typedef struct OptionsContext {
     int loop;
     int rate_emu;
     float readrate;
+    double readrate_initial_burst;
     int accurate_seek;
     int thread_queue_size;
     int input_sync_ref;
diff --git a/fftools/ffmpeg_demux.c b/fftools/ffmpeg_demux.c
index 26426c7ac1..37d7649da9 100644
--- a/fftools/ffmpeg_demux.c
+++ b/fftools/ffmpeg_demux.c
@@ -81,6 +81,8 @@  typedef struct Demuxer {
     /* number of streams that the user was warned of */
     int nb_streams_warn;
 
+    double readrate_initial_burst;
+
     AVThreadMessageQueue *in_thread_queue;
     int                   thread_queue_size;
     pthread_t             thread;
@@ -455,6 +457,7 @@  int ifile_get_packet(InputFile *f, AVPacket **pkt)
                               (f->start_time != AV_NOPTS_VALUE ? f->start_time : 0)
                              );
         float scale = f->rate_emu ? 1.0 : f->readrate;
+        int64_t burst_until = AV_TIME_BASE * d->readrate_initial_burst;
         for (i = 0; i < f->nb_streams; i++) {
             InputStream *ist = f->streams[i];
             int64_t stream_ts_offset, pts, now;
@@ -462,7 +465,7 @@  int ifile_get_packet(InputFile *f, AVPacket **pkt)
             stream_ts_offset = FFMAX(ist->first_dts != AV_NOPTS_VALUE ? ist->first_dts : 0, file_start);
             pts = av_rescale(ist->dts, 1000000, AV_TIME_BASE);
             now = (av_gettime_relative() - ist->start) * scale + stream_ts_offset;
-            if (pts > now)
+            if (pts - burst_until > now)
                 return AVERROR(EAGAIN);
         }
     }
@@ -1236,6 +1239,19 @@  int ifile_open(const OptionsContext *o, const char *filename)
         f->rate_emu = 0;
     }
 
+    if (f->readrate || f->rate_emu) {
+        d->readrate_initial_burst = o->readrate_initial_burst ? o->readrate_initial_burst : 0.0;
+        if (d->readrate_initial_burst < 0.0) {
+            av_log(d, AV_LOG_ERROR,
+                   "Option -readrate_initial_burst is %0.3f; it must be non-negative.\n",
+                   d->readrate_initial_burst);
+            exit_program(1);
+        }
+    } else if (o->readrate_initial_burst) {
+        av_log(d, AV_LOG_WARNING, "Option -readrate_initial_burst ignored "
+               "since neither -readrate nor -re were given\n");
+    }
+
     d->thread_queue_size = o->thread_queue_size;
 
     /* update the current parameters so that they match the one of the input stream */
diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c
index cf385c388e..7f22b22604 100644
--- a/fftools/ffmpeg_opt.c
+++ b/fftools/ffmpeg_opt.c
@@ -1454,6 +1454,9 @@  const OptionDef options[] = {
     { "readrate",       HAS_ARG | OPT_FLOAT | OPT_OFFSET |
                         OPT_EXPERT | OPT_INPUT,                      { .off = OFFSET(readrate) },
         "read input at specified rate", "speed" },
+    { "readrate_initial_burst", HAS_ARG | OPT_DOUBLE | OPT_OFFSET |
+                                OPT_EXPERT | OPT_INPUT,              { .off = OFFSET(readrate_initial_burst) },
+        "The initial amount of input to burst read before imposing any readrate", "seconds" },
     { "target",         HAS_ARG | OPT_PERFILE | OPT_OUTPUT,          { .func_arg = opt_target },
         "specify target file type (\"vcd\", \"svcd\", \"dvd\", \"dv\" or \"dv50\" "
         "with optional prefixes \"pal-\", \"ntsc-\" or \"film-\")", "type" },