player: add ability to speed up based on delay

Added the following command-line options:
 --rt-catchup: enables the new feature
 --rt-catchup-multiplier: (double) sets a constant speed multiplier
 --rt-catchup-max-delay: (double) sets the maximum delay before speedup

If --rt-catchup is enabled, when the player falls a number of seconds
exceeding the value given by --rt-catchup-max-delay, playback speed is
multiplied by the sum of 1 and the square of the product of the value
given by --rt-catchup-multiplier and the current delay in excess of the
delay given by --rt-catchup-max-delay in seconds.

The speed multiplier is applied in addition to the playback speed
multiplier set by the user.

This feature is introduced to help prevent falling behind real-time
sources such as live streams.
This commit is contained in:
Dexter Gaon-Shatford 2022-01-19 15:59:45 -05:00
parent f235bfbf36
commit 756a351984
4 changed files with 45 additions and 0 deletions

View File

@ -216,6 +216,21 @@ Playback Control
speed higher than normal automatically inserts the ``scaletempo2`` audio
filter.
``--rt-catchup``
Enable the player to speed up by a factor equal to the sum of 1, and the
square of the product of how many seconds behind the the delay given by
``--rt-catchup-max-delay`` the player has fallen and the value given by
``--rt-catchup-multiplier`` unless the delay does not exceed the delay
given by ``--rt-catchup-max-delay``.
``--rt-catchup-max-delay=<0.0..>``
The maximum delay in seconds behind the media source the player may reach
before it starts speeding up, if ``--rt-catchup`` is enabled.
``--rt-catchup-multiplier=<0.0..>``
A coefficient applied during the speed multiplier calculation according to
``--rt-catchup`` and ``--rt-catchup-max-delay``
``--pause``
Start the player in paused state.

View File

@ -568,6 +568,13 @@ static const m_option_t mp_opts[] = {
// set a-v distance
{"audio-delay", OPT_FLOAT(audio_delay)},
// set live/realtime catch-up parameters
{"rt-catchup", OPT_FLAG(realtime_catchup)},
{"rt-catchup-multiplier", OPT_DOUBLE(realtime_catchup_speed_multiplier),
M_RANGE(0, DBL_MAX)},
{"rt-catchup-max-delay", OPT_DOUBLE(realtime_catchup_max_delay),
M_RANGE(0, DBL_MAX)},
// ------------------------- codec/vfilter options --------------------
{"af-defaults", OPT_SETTINGSLIST(af_defs, &af_obj_list),

View File

@ -224,6 +224,9 @@ typedef struct MPOpts {
int hr_seek_framedrop;
float audio_delay;
float default_max_pts_correction;
int realtime_catchup;
double realtime_catchup_speed_multiplier;
double realtime_catchup_max_delay;
int autosync;
int frame_dropping;
int video_latency_hacks;

View File

@ -174,9 +174,29 @@ void audio_update_volume(struct MPContext *mpctx)
ao_set_gain(ao_c->ao, gain);
}
// Calculate a speed multiplier proportional to the delay between the current
// playback time and the media source. This multiplier is used to keep up with a
// real-time source such as a live stream.
static double calc_realtime_catchup_speed(struct MPContext *mpctx)
{
double max_delay = mpctx->opts->realtime_catchup_max_delay;
double delay = get_time_length(mpctx) - get_playback_time(mpctx);
if (delay > max_delay) {
double multiplier = mpctx->opts->realtime_catchup_speed_multiplier;
return 1.0 + powf((delay - max_delay) * multiplier, 2.0);
} else {
return 1.0;
}
}
// Call this if opts->playback_speed or mpctx->speed_factor_* change.
void update_playback_speed(struct MPContext *mpctx)
{
if (mpctx->opts->realtime_catchup) {
mpctx->opts->playback_speed = calc_realtime_catchup_speed(mpctx);
}
mpctx->audio_speed = mpctx->opts->playback_speed * mpctx->speed_factor_a;
mpctx->video_speed = mpctx->opts->playback_speed * mpctx->speed_factor_v;