[vlc-commits] [Git][videolan/vlc][master] 5 commits: player: timer: handle seek state
Steve Lhomme (@robUx4)
gitlab at videolan.org
Fri Jan 19 10:11:30 UTC 2024
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
1ecb283c by Thomas Guillem at 2024-01-19T09:47:41+00:00
player: timer: handle seek state
Keep the last requested seek position/time, that will be used for
successive jumps. It will be more precise than using the demux
GET_TIME/GET_POSITION.
Send 'on_seek' callback with a valid point when starting a new seek.
This callback will be called with a NULL point once all seek requests
are processed.
UI have now the choice to update their time/position to the seeked
value. This will fix the UI not updated when the seek is long to
process.
Refs #27383
Refs #28482
- - - - -
293d8919 by Thomas Guillem at 2024-01-19T09:47:41+00:00
player: expose seeking from GetPos/GetTime
- - - - -
05c9c727 by Thomas Guillem at 2024-01-19T09:47:41+00:00
player: always seek the input_thread with absolute values
Don't use INPUT_CONTROL_JUMP_POSITION and INPUT_CONTROL_JUMP_TIME, that
use input times from the demuxer. Instead, add up the time from the
player timer, that use ts from the output clocks.
This fixes a possible gap with relatives seeks, depending on the input
source or output delay (aout).
For examples, seeking -3s was seeking -2s and seeking +3s was seeking
+4s before this commit. Now seeking back and forth with stay at the same
position.
Fixes #28482
Fixes #27383
- - - - -
396c8141 by Thomas Guillem at 2024-01-19T09:47:41+00:00
input: remove JUMP controls
The input_thread can now only seek with absolute values.
- - - - -
c20e4543 by Thomas Guillem at 2024-01-19T09:47:41+00:00
qt: implement timer.on_seek
Set the time and position to the requested seek point. Pause timers
while seeking.
- - - - -
13 changed files:
- include/vlc_demux.h
- include/vlc_player.h
- modules/demux/mpeg/ps.c
- modules/gui/qt/player/player_controller.cpp
- modules/gui/qt/player/player_controller_p.hpp
- modules/stream_out/chromecast/chromecast_demux.cpp
- src/input/input.c
- src/input/input_internal.h
- src/player/input.c
- src/player/osd.c
- src/player/player.c
- src/player/player.h
- src/player/timer.c
Changes:
=====================================
include/vlc_demux.h
=====================================
@@ -544,18 +544,8 @@ static inline bool demux_IsForced( demux_t *p_demux, const char *psz_name )
return true;
}
-static inline int demux_SetPosition( demux_t *p_demux, double pos, bool precise,
- bool absolute)
+static inline int demux_SetPosition( demux_t *p_demux, double pos, bool precise )
{
- if( !absolute )
- {
- double current_pos;
- int ret = vlc_demux_GetPosition( p_demux, ¤t_pos );
- if( ret != VLC_SUCCESS )
- return ret;
- pos += current_pos;
- }
-
if( pos < 0.f )
pos = 0.f;
else if( pos > 1.f )
@@ -563,18 +553,8 @@ static inline int demux_SetPosition( demux_t *p_demux, double pos, bool precise,
return demux_Control( p_demux, DEMUX_SET_POSITION, pos, precise );
}
-static inline int demux_SetTime( demux_t *p_demux, vlc_tick_t time, bool precise,
- bool absolute )
+static inline int demux_SetTime( demux_t *p_demux, vlc_tick_t time, bool precise )
{
- if( !absolute )
- {
- vlc_tick_t current_time;
- int ret = vlc_demux_GetTime( p_demux, ¤t_time );
- if( ret != VLC_SUCCESS )
- return ret;
- time += current_time;
- }
-
if( time < 0 )
time = 0;
return demux_Control( p_demux, DEMUX_SET_TIME, time, precise );
=====================================
include/vlc_player.h
=====================================
@@ -3399,6 +3399,15 @@ struct vlc_player_timer_cbs
* @param data opaque pointer set by vlc_player_AddTimer()
*/
void (*on_discontinuity)(vlc_tick_t system_date, void *data);
+
+ /**
+ * Called when the player is seeking or finished seeking
+ *
+ * @param value point of the seek request or NULL when seeking is finished
+ * value.system_date = VLC_TICK_MAX in that case
+ * @param data opaque pointer set by vlc_player_AddTimer()
+ */
+ void (*on_seek)(const struct vlc_player_timer_point *value, void *data);
};
/**
=====================================
modules/demux/mpeg/ps.c
=====================================
@@ -804,7 +804,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
{
vlc_tick_t i_time = va_arg( args, vlc_tick_t );
i_time -= p_sys->tk[p_sys->i_time_track_index].i_first_pts;
- return demux_SetPosition( p_demux, (double) i_time / p_sys->i_length, false, true );
+ return demux_SetPosition( p_demux, (double) i_time / p_sys->i_length, false );
}
break;
}
=====================================
modules/gui/qt/player/player_controller.cpp
=====================================
@@ -904,6 +904,9 @@ static void on_player_timer_update(const struct vlc_player_timer_point *point,
void *data)
{
PlayerControllerPrivate* that = static_cast<PlayerControllerPrivate*>(data);
+ if (that->seeking)
+ return;
+
that->callAsync([that,point_copy = *point](){
PlayerController* q = that->q_func();
@@ -974,6 +977,32 @@ static void on_player_timer_discontinuity(vlc_tick_t system_date, void *data)
});
}
+static void on_player_timer_seek(const struct vlc_player_timer_point *point,
+ void *data)
+{
+ PlayerControllerPrivate* that = static_cast<PlayerControllerPrivate*>(data);
+ if (point != NULL)
+ {
+ that->seeking = true;
+ that->callAsync([that,point_copy = *point](){
+ PlayerController* q = that->q_func();
+
+ that->m_player_time = point_copy;
+ if (that->m_player_time.position > 0)
+ that->m_position = that->m_player_time.position;
+ if (that->m_player_time.ts != VLC_TICK_INVALID)
+ that->m_time = that->m_player_time.ts - VLC_TICK_0;
+
+ q->updatePosition();
+ q->updateTime(VLC_TICK_INVALID, false);
+
+ that->m_position_timer.stop();
+ that->m_time_timer.stop();
+ });
+ }
+ else
+ that->seeking = false;
+}
static void on_player_timer_smpte_update(const struct vlc_player_timer_smpte_timecode *tc,
void *data)
{
@@ -1049,6 +1078,7 @@ static const vlc_player_timer_cbs player_timer_cbs = []{
struct vlc_player_timer_cbs cbs {};
cbs.on_update = on_player_timer_update;
cbs.on_discontinuity = on_player_timer_discontinuity;
+ cbs.on_seek = on_player_timer_seek;
return cbs;
}();
@@ -1734,7 +1764,8 @@ void PlayerController::updateTime(vlc_tick_t system_now, bool forceUpdate)
d->m_remainingTime = VLC_TICK_INVALID;
emit remainingTimeChanged(d->m_remainingTime);
- if (d->m_player_time.system_date != VLC_TICK_MAX
+ if (system_now != VLC_TICK_INVALID
+ && d->m_player_time.system_date != VLC_TICK_MAX
&& (forceUpdate || !d->m_time_timer.isActive()))
{
// Tell the timer to wait until the next second is reached.
=====================================
modules/gui/qt/player/player_controller_p.hpp
=====================================
@@ -107,6 +107,7 @@ public:
vlc_player_timer_id* m_player_timer = nullptr;
vlc_player_timer_id* m_player_timer_smpte = nullptr;
struct vlc_player_timer_point m_player_time;
+ bool seeking = false;
QTimer m_position_timer;
QTimer m_time_timer;
=====================================
modules/stream_out/chromecast/chromecast_demux.cpp
=====================================
@@ -221,7 +221,7 @@ struct demux_cc
ret = demux_Control( p_demux->s, DEMUX_SET_TIME, time, false );
if( ret != VLC_SUCCESS && pos >= 0 )
- demux_SetPosition( p_demux->s, pos, false, true );
+ demux_SetPosition( p_demux->s, pos, false );
}
}
@@ -346,7 +346,7 @@ struct demux_cc
{
double pos = va_arg( args, double );
/* Force imprecise seek */
- int ret = demux_SetPosition( p_demux->s, pos, false, true );
+ int ret = demux_SetPosition( p_demux->s, pos, false );
if( ret != VLC_SUCCESS )
return ret;
=====================================
src/input/input.c
=====================================
@@ -1493,16 +1493,6 @@ static size_t ControlGetReducedIndexLocked( input_thread_t *p_input,
{
return sys->i_control - 1;
}
- else if ( i_ct == INPUT_CONTROL_JUMP_TIME )
- {
- c->param.time.i_val += prev_control->param.time.i_val;
- return sys->i_control - 1;
- }
- else if ( i_ct == INPUT_CONTROL_JUMP_POSITION )
- {
- c->param.pos.f_val += prev_control->param.pos.f_val;
- return sys->i_control - 1;
- }
else if ( i_ct == INPUT_CONTROL_UPDATE_VIEWPOINT )
{
c->param.viewpoint.yaw += prev_control->param.viewpoint.yaw;
@@ -1601,9 +1591,7 @@ static bool ControlIsSeekRequest( int i_type )
switch( i_type )
{
case INPUT_CONTROL_SET_POSITION:
- case INPUT_CONTROL_JUMP_POSITION:
case INPUT_CONTROL_SET_TIME:
- case INPUT_CONTROL_JUMP_TIME:
case INPUT_CONTROL_SET_TITLE:
case INPUT_CONTROL_SET_TITLE_NEXT:
case INPUT_CONTROL_SET_TITLE_PREV:
@@ -1917,9 +1905,7 @@ static bool Control( input_thread_t *p_input,
switch( i_type )
{
case INPUT_CONTROL_SET_POSITION:
- case INPUT_CONTROL_JUMP_POSITION:
{
- const bool absolute = i_type == INPUT_CONTROL_SET_POSITION;
if( priv->b_recording )
{
msg_Err( p_input, "INPUT_CONTROL_SET_POSITION ignored while recording" );
@@ -1929,12 +1915,10 @@ static bool Control( input_thread_t *p_input,
/* Reset the decoders states and clock sync (before calling the demuxer */
es_out_Control( priv->p_es_out, ES_OUT_RESET_PCR );
if( demux_SetPosition( priv->master->p_demux, param.pos.f_val,
- !param.pos.b_fast_seek, absolute ) )
+ !param.pos.b_fast_seek ) )
{
msg_Err( p_input, "INPUT_CONTROL_SET_POSITION "
- "%s%2.1f%% failed",
- absolute ? "@" : param.pos.f_val >= 0 ? "+" : "",
- param.pos.f_val * 100.f );
+ "%2.1f%% failed", param.pos.f_val * 100.f );
}
else
{
@@ -1948,9 +1932,7 @@ static bool Control( input_thread_t *p_input,
}
case INPUT_CONTROL_SET_TIME:
- case INPUT_CONTROL_JUMP_TIME:
{
- const bool absolute = i_type == INPUT_CONTROL_SET_TIME;
int i_ret;
if( priv->b_recording )
@@ -1963,7 +1945,7 @@ static bool Control( input_thread_t *p_input,
es_out_Control( priv->p_es_out, ES_OUT_RESET_PCR );
i_ret = demux_SetTime( priv->master->p_demux, param.time.i_val,
- !param.time.b_fast_seek, absolute );
+ !param.time.b_fast_seek );
if( i_ret )
{
vlc_tick_t i_length = InputSourceGetLength( priv->master, priv->p_item );
@@ -1972,16 +1954,13 @@ static bool Control( input_thread_t *p_input,
{
double f_pos = (double)param.time.i_val / (double)i_length;
i_ret = demux_SetPosition( priv->master->p_demux, f_pos,
- !param.time.b_fast_seek,
- absolute );
+ !param.time.b_fast_seek );
}
}
if( i_ret )
{
- msg_Warn( p_input, "INPUT_CONTROL_SET_TIME %s%"PRId64
- " failed or not possible",
- absolute ? "@" : param.time.i_val >= 0 ? "+" : "",
- param.time.i_val );
+ msg_Warn( p_input, "INPUT_CONTROL_SET_TIME @%"PRId64
+ " failed or not possible", param.time.i_val );
}
else
{
=====================================
src/input/input_internal.h
=====================================
@@ -557,10 +557,8 @@ enum input_control_e
INPUT_CONTROL_SET_RATE,
INPUT_CONTROL_SET_POSITION,
- INPUT_CONTROL_JUMP_POSITION,
INPUT_CONTROL_SET_TIME,
- INPUT_CONTROL_JUMP_TIME,
INPUT_CONTROL_SET_PROGRAM,
=====================================
src/player/input.c
=====================================
@@ -59,25 +59,27 @@ vlc_player_input_HandleAtoBLoop(struct vlc_player_input *input, vlc_tick_t time,
}
vlc_tick_t
-vlc_player_input_GetTime(struct vlc_player_input *input, vlc_tick_t system_now)
+vlc_player_input_GetTime(struct vlc_player_input *input, bool seeking,
+ vlc_tick_t system_now)
{
vlc_player_t *player = input->player;
vlc_tick_t ts;
if (input == player->input
- && vlc_player_GetTimerPoint(player, system_now, &ts, NULL) == 0)
+ && vlc_player_GetTimerPoint(player, seeking, system_now, &ts, NULL) == 0)
return ts;
return input->time;
}
double
-vlc_player_input_GetPos(struct vlc_player_input *input, vlc_tick_t system_now)
+vlc_player_input_GetPos(struct vlc_player_input *input, bool seeking,
+ vlc_tick_t system_now)
{
vlc_player_t *player = input->player;
double pos;
if (input == player->input
- && vlc_player_GetTimerPoint(player, system_now, NULL, &pos) == 0)
+ && vlc_player_GetTimerPoint(player, seeking, system_now, NULL, &pos) == 0)
return pos;
return input->position;
}
@@ -89,8 +91,8 @@ vlc_player_input_UpdateTime(struct vlc_player_input *input)
{
vlc_tick_t now = vlc_tick_now();
vlc_player_input_HandleAtoBLoop(input,
- vlc_player_input_GetTime(input, now),
- vlc_player_input_GetPos(input, now));
+ vlc_player_input_GetTime(input, false, now),
+ vlc_player_input_GetPos(input, false, now));
}
}
@@ -123,18 +125,24 @@ vlc_player_input_SeekByPos(struct vlc_player_input *input, double position,
vlc_player_t *player = input->player;
vlc_player_assert_seek_params(speed, whence);
- const int type =
- whence == VLC_PLAYER_WHENCE_ABSOLUTE ? INPUT_CONTROL_SET_POSITION
- : INPUT_CONTROL_JUMP_POSITION;
- int ret = input_ControlPush(input->thread, type,
+ if (whence != VLC_PLAYER_WHENCE_ABSOLUTE)
+ position += vlc_player_input_GetPos(input, true, vlc_tick_now());
+
+ if (position < 0)
+ position = 0;
+ else if (position > 1)
+ position = 1;
+
+ vlc_player_UpdateTimerSeekState(player, VLC_TICK_INVALID, position);
+
+ int ret = input_ControlPush(input->thread, INPUT_CONTROL_SET_POSITION,
&(input_control_param_t) {
.pos.f_val = position,
.pos.b_fast_seek = speed == VLC_PLAYER_SEEK_FAST,
});
if (ret == VLC_SUCCESS)
- vlc_player_osd_Position(player, input, VLC_TICK_INVALID, position,
- whence);
+ vlc_player_osd_Position(player, input, VLC_TICK_INVALID, position);
}
void
@@ -145,17 +153,22 @@ vlc_player_input_SeekByTime(struct vlc_player_input *input, vlc_tick_t time,
vlc_player_t *player = input->player;
vlc_player_assert_seek_params(speed, whence);
- const int type =
- whence == VLC_PLAYER_WHENCE_ABSOLUTE ? INPUT_CONTROL_SET_TIME
- : INPUT_CONTROL_JUMP_TIME;
- int ret = input_ControlPush(input->thread, type,
+ if (whence != VLC_PLAYER_WHENCE_ABSOLUTE)
+ time += vlc_player_input_GetTime(input, true, vlc_tick_now());
+
+ if (time < VLC_TICK_0)
+ time = VLC_TICK_0;
+
+ vlc_player_UpdateTimerSeekState(player, time, -1);
+
+ int ret = input_ControlPush(input->thread, INPUT_CONTROL_SET_TIME,
&(input_control_param_t) {
.time.i_val = time,
.time.b_fast_seek = speed == VLC_PLAYER_SEEK_FAST,
});
if (ret == VLC_SUCCESS)
- vlc_player_osd_Position(player, input, time, -1, whence);
+ vlc_player_osd_Position(player, input, time, -1);
}
void
=====================================
src/player/osd.c
=====================================
@@ -119,10 +119,8 @@ vlc_player_osd_Icon(vlc_player_t *player, short type)
void
vlc_player_osd_Position(vlc_player_t *player,
struct vlc_player_input *input, vlc_tick_t time,
- double position, enum vlc_player_whence whence)
+ double position)
{
- vlc_tick_t now = vlc_tick_now();
-
if (input->length != VLC_TICK_INVALID)
{
if (time == VLC_TICK_INVALID)
@@ -136,13 +134,6 @@ vlc_player_osd_Position(vlc_player_t *player,
if (time != VLC_TICK_INVALID)
{
- if (whence == VLC_PLAYER_WHENCE_RELATIVE)
- {
- time += vlc_player_input_GetTime(input, now);
- if (time < 0)
- time = 0;
- }
-
char time_text[MSTRTIME_MAX_SIZE];
vlc_tick_to_str(time_text, time);
if (input->length != VLC_TICK_INVALID)
@@ -156,15 +147,7 @@ vlc_player_osd_Position(vlc_player_t *player,
}
if (vlc_player_vout_IsFullscreen(player))
- {
- if (whence == VLC_PLAYER_WHENCE_RELATIVE)
- {
- position += vlc_player_input_GetPos(input, now);
- if (position < 0.f)
- position = 0.f;
- }
vouts_osd_Slider(vouts, count, position * 100, OSD_HOR_SLIDER);
- }
vlc_player_osd_ReleaseAll(player, vouts, count);
}
=====================================
src/player/player.c
=====================================
@@ -1378,7 +1378,7 @@ vlc_player_GetTime(vlc_player_t *player)
if (!input)
return VLC_TICK_INVALID;
- return vlc_player_input_GetTime(input, vlc_tick_now());
+ return vlc_player_input_GetTime(input, false, vlc_tick_now());
}
double
@@ -1386,7 +1386,7 @@ vlc_player_GetPosition(vlc_player_t *player)
{
struct vlc_player_input *input = vlc_player_get_input_locked(player);
- return input ? vlc_player_input_GetPos(input, vlc_tick_now()) : -1.f;
+ return input ? vlc_player_input_GetPos(input, false, vlc_tick_now()) : -1.f;
}
void
@@ -1398,9 +1398,8 @@ vlc_player_DisplayPosition(vlc_player_t *player)
vlc_tick_t now = vlc_tick_now();
vlc_player_osd_Position(player, input,
- vlc_player_input_GetTime(input, now),
- vlc_player_input_GetPos(input, now),
- VLC_PLAYER_WHENCE_ABSOLUTE);
+ vlc_player_input_GetTime(input, false, now),
+ vlc_player_input_GetPos(input, false, now));
}
void
=====================================
src/player/player.h
=====================================
@@ -215,13 +215,16 @@ struct vlc_player_timer
vlc_mutex_t lock;
enum vlc_player_timer_state state;
- bool seeking;
vlc_tick_t input_length;
vlc_tick_t input_normal_time;
vlc_tick_t last_ts;
double input_position;
+ vlc_tick_t seek_ts;
+ double seek_position;
+ bool seeking;
+
struct vlc_player_timer_source sources[VLC_PLAYER_TIMER_TYPE_COUNT];
#define best_source sources[VLC_PLAYER_TIMER_TYPE_BEST]
#define smpte_source sources[VLC_PLAYER_TIMER_TYPE_SMPTE]
@@ -437,10 +440,12 @@ vlc_player_input_GetSelectedTrackStringIds(struct vlc_player_input *input,
enum es_format_category_e cat) VLC_MALLOC;
vlc_tick_t
-vlc_player_input_GetTime(struct vlc_player_input *input, vlc_tick_t system_now);
+vlc_player_input_GetTime(struct vlc_player_input *input, bool seeking,
+ vlc_tick_t system_now);
double
-vlc_player_input_GetPos(struct vlc_player_input *input, vlc_tick_t system_now);
+vlc_player_input_GetPos(struct vlc_player_input *input, bool seeking,
+ vlc_tick_t system_now);
int
vlc_player_input_Start(struct vlc_player_input *input);
@@ -482,6 +487,10 @@ vlc_player_UpdateTimerState(vlc_player_t *player, vlc_es_id_t *es_source,
enum vlc_player_timer_state state,
vlc_tick_t system_date);
+void
+vlc_player_UpdateTimerSeekState(vlc_player_t *player, vlc_tick_t time,
+ double position);
+
void
vlc_player_UpdateTimer(vlc_player_t *player, vlc_es_id_t *es_source,
bool es_source_is_master,
@@ -493,7 +502,8 @@ void
vlc_player_RemoveTimerSource(vlc_player_t *player, vlc_es_id_t *es_source);
int
-vlc_player_GetTimerPoint(vlc_player_t *player, vlc_tick_t system_now,
+vlc_player_GetTimerPoint(vlc_player_t *player, bool seeking,
+ vlc_tick_t system_now,
vlc_tick_t *out_ts, double *out_pos);
/*
@@ -529,7 +539,7 @@ vlc_player_osd_Icon(vlc_player_t *player, short type);
void
vlc_player_osd_Position(vlc_player_t *player,
struct vlc_player_input *input, vlc_tick_t time,
- double position, enum vlc_player_whence whence);
+ double position);
void
vlc_player_osd_Volume(vlc_player_t *player, bool mute_action);
=====================================
src/player/timer.c
=====================================
@@ -37,10 +37,28 @@ vlc_player_ResetTimer(vlc_player_t *player)
player->timer.last_ts = VLC_TICK_INVALID;
player->timer.input_position = 0;
player->timer.smpte_source.smpte.last_framenum = ULONG_MAX;
+ player->timer.seek_ts = VLC_TICK_INVALID;
+ player->timer.seek_position = -1;
+ player->timer.seeking = false;
vlc_mutex_unlock(&player->timer.lock);
}
+static void
+vlc_player_SendTimerSeek(vlc_player_t *player,
+ struct vlc_player_timer_source *source,
+ const struct vlc_player_timer_point *point)
+{
+ (void) player;
+ vlc_player_timer_id *timer;
+
+ vlc_list_foreach(timer, &source->listeners, node)
+ {
+ if (timer->cbs->on_seek != NULL)
+ timer->cbs->on_seek(point, timer->data);
+ }
+}
+
static void
vlc_player_SendTimerSourceUpdates(vlc_player_t *player,
struct vlc_player_timer_source *source,
@@ -194,8 +212,22 @@ vlc_player_UpdateTimerState(vlc_player_t *player, vlc_es_id_t *es_source,
if (source->es != es_source)
continue;
/* signal discontinuity only on best source */
- if (source->point.system_date != VLC_TICK_INVALID)
- notify = bestsource->es == es_source;
+ if (bestsource->es == es_source)
+ {
+ /* And only once */
+ if (source->point.system_date != VLC_TICK_INVALID)
+ notify = true;
+
+ /* There can be several discontinuities on the same source
+ * for one seek request, hence the need of the
+ * 'timer.seeking' variable to notify only once the end of
+ * the seek request. */
+ if (player->timer.seeking)
+ {
+ player->timer.seeking = false;
+ vlc_player_SendTimerSeek(player, bestsource, NULL);
+ }
+ }
source->point.system_date = VLC_TICK_INVALID;
}
break;
@@ -228,6 +260,47 @@ vlc_player_UpdateTimerState(vlc_player_t *player, vlc_es_id_t *es_source,
vlc_mutex_unlock(&player->timer.lock);
}
+void
+vlc_player_UpdateTimerSeekState(vlc_player_t *player, vlc_tick_t time,
+ double position)
+{
+ vlc_mutex_lock(&player->timer.lock);
+ struct vlc_player_timer_source *source = &player->timer.best_source;
+
+ if (time == VLC_TICK_INVALID)
+ {
+ assert(position >= 0);
+ if (source->point.length != VLC_TICK_INVALID)
+ player->timer.seek_ts = position * source->point.length;
+ else
+ player->timer.seek_ts = VLC_TICK_INVALID;
+ }
+ else
+ player->timer.seek_ts = time;
+
+ if (position < 0)
+ {
+ assert(time != VLC_TICK_INVALID);
+ if (source->point.length != VLC_TICK_INVALID)
+ player->timer.seek_position = time / (double) source->point.length;
+ }
+ else
+ player->timer.seek_position = position;
+
+ const struct vlc_player_timer_point point =
+ {
+ .position = player->timer.seek_position,
+ .rate = source->point.rate,
+ .ts = player->timer.seek_ts,
+ .length = source->point.length,
+ .system_date = VLC_TICK_MAX,
+ };
+
+ player->timer.seeking = true;
+ vlc_player_SendTimerSeek(player, source, &point);
+ vlc_mutex_unlock(&player->timer.lock);
+}
+
static void
vlc_player_UpdateTimerSource(vlc_player_t *player,
struct vlc_player_timer_source *source,
@@ -340,6 +413,17 @@ vlc_player_UpdateTimer(vlc_player_t *player, vlc_es_id_t *es_source,
vlc_player_UpdateTimerSource(player, source, point->rate, point->ts,
system_date);
+ /* It is possible to receive valid points while seeking. These
+ * points could be updated when the input thread didn't yet process
+ * the seek request. */
+ if (!player->timer.seeking)
+ {
+ /* Reset seek time/position now that we receive a valid point
+ * and seek was processed */
+ player->timer.seek_ts = VLC_TICK_INVALID;
+ player->timer.seek_position = -1;
+ }
+
if (!vlc_list_is_empty(&source->listeners))
vlc_player_SendTimerSourceUpdates(player, source, force_update,
&source->point);
@@ -384,6 +468,14 @@ void
vlc_player_RemoveTimerSource(vlc_player_t *player, vlc_es_id_t *es_source)
{
vlc_mutex_lock(&player->timer.lock);
+
+ /* Unlikely case where the source ES is deleted while seeking */
+ if (player->timer.best_source.es == es_source && player->timer.seeking)
+ {
+ player->timer.seeking = false;
+ vlc_player_SendTimerSeek(player, &player->timer.best_source, NULL);
+ }
+
for (size_t i = 0; i < VLC_PLAYER_TIMER_TYPE_COUNT; ++i)
{
struct vlc_player_timer_source *source = &player->timer.sources[i];
@@ -398,23 +490,41 @@ vlc_player_RemoveTimerSource(vlc_player_t *player, vlc_es_id_t *es_source)
}
int
-vlc_player_GetTimerPoint(vlc_player_t *player, vlc_tick_t system_now,
+vlc_player_GetTimerPoint(vlc_player_t *player, bool seeking,
+ vlc_tick_t system_now,
vlc_tick_t *out_ts, double *out_pos)
{
- int ret;
+ int ret = VLC_EGENERIC;
vlc_mutex_lock(&player->timer.lock);
- if (player->timer.best_source.point.system_date == VLC_TICK_INVALID)
+ if (seeking
+ && (player->timer.seek_ts != VLC_TICK_INVALID || player->timer.seek_position >= 0.0f))
{
- vlc_mutex_unlock(&player->timer.lock);
- return VLC_EGENERIC;
+ if (out_ts != NULL)
+ {
+ if (player->timer.seek_ts == VLC_TICK_INVALID)
+ goto end;
+ *out_ts = player->timer.seek_ts;
+ }
+ if (out_pos != NULL)
+ {
+ if (player->timer.seek_position < 0)
+ goto end;
+ *out_pos = player->timer.seek_position;
+ }
+ ret = VLC_SUCCESS;
+ goto end;
}
+ if (player->timer.best_source.point.system_date == VLC_TICK_INVALID)
+ goto end;
+
if (system_now != VLC_TICK_INVALID)
ret = vlc_player_timer_point_Interpolate(&player->timer.best_source.point,
system_now, out_ts, out_pos);
else
ret = VLC_SUCCESS;
+end:
vlc_mutex_unlock(&player->timer.lock);
return ret;
}
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4ea2f636707f67ccb6be74fb51da86b0cb120519...c20e45433545cc4974cffdbf9feda42aaefaa76a
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/4ea2f636707f67ccb6be74fb51da86b0cb120519...c20e45433545cc4974cffdbf9feda42aaefaa76a
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list