Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc
  • chouquette/vlc
  • bakiewicz.marek122/vlc
  • devnexen/vlc
  • rohanrajpal/vlc
  • blurrrb/vlc
  • gsoc/gsoc2019/darkapex/vlc
  • b1ue/vlc
  • fkuehne/vlc
  • magsoft/vlc
  • chub/vlc
  • cramiro9/vlc
  • robUx4/vlc
  • rom1v/vlc
  • akshayaky/vlc
  • tmk907/vlc
  • akymaster/vlc
  • govind.sharma/vlc
  • psilokos/vlc
  • xjbeta/vlc
  • jahan/vlc
  • 1480c1/vlc
  • amanchande/vlc
  • aaqib/vlc
  • rist/vlc
  • apol/vlc
  • mindfreeze/vlc
  • alexandre-janniaux/vlc
  • sandsmark/vlc
  • jagannatharjun/vlc
  • gsoc/gsoc2020/matiaslgonzalez/vlc
  • gsoc/gsoc2020/jagannatharjun/vlc
  • mstorsjo/vlc
  • gsoc/gsoc2020/vedenta/vlc
  • gsoc/gsoc2020/arnav-ishaan/vlc
  • gsoc/gsoc2020/andreduong/vlc
  • fuzun/vlc
  • gsoc/gsoc2020/vatsin/vlc
  • gsoc/gsoc2020/sagid/vlc
  • yaron/vlc
  • Phoenix/vlc
  • Garf/vlc
  • ePiratWorkarounds/vlc
  • tguillem/vlc
  • jnqnfe/vlc
  • mdc/vlc
  • Vedaa/vlc
  • rasa/vlc
  • quink/vlc
  • yealo/vlc
  • aleksey_ak/vlc
  • ePirat/vlc
  • ilya.yanok/vlc
  • asenat/vlc
  • m/vlc
  • bunjee/vlc
  • BLumia/vlc
  • sagudev/vlc
  • hamedmonji30/vlc
  • nullgemm/vlc
  • DivyamAhuja/vlc
  • thesamesam/vlc
  • dag7/vlc
  • snehil101/vlc
  • haasn/vlc
  • jbk/vlc
  • ValZapod/vlc
  • mfkl/vlc
  • WangChuan/vlc
  • core1024/vlc
  • GhostVaibhav/vlc
  • dfuhrmann/vlc
  • davide.prade/vlc
  • tmatth/vlc
  • Courmisch/vlc
  • zouya/vlc
  • hpi/vlc
  • EwoutH/vlc
  • aleung27/vlc
  • hengwu0/vlc
  • saladin/vlc
  • ashuio/vlc
  • richselwood/vlc
  • verma16Ayush/vlc
  • chemicalflash/vlc
  • PoignardAzur/vlc
  • huangjieNT/vlc
  • Blake-Haydon/vlc
  • AnuthaDev/vlc
  • gsoc/gsoc2021/mpd/vlc
  • nicolas_lequec/vlc
  • sambassaly/vlc
  • thresh/vlc
  • bonniegong/vlc
  • myaashish/vlc
  • stavros.vagionitis/vlc
  • ileoo/vlc
  • louis-santucci/vlc
  • cchristiansen/vlc
  • sabyasachi07/vlc
  • AbduAmeen/vlc
  • ashishb0410/vlc
  • urbanhusky/vlc
  • davidepietrasanta/vlc
  • riksleutelstad/vlc
  • jeremyVignelles/vlc
  • komh/vlc
  • iamjithinjohn/vlc
  • JohannesKauffmann/vlc2
  • kunglao/vlc
  • natzberg/vlc
  • jill/vlc
  • cwendling/vlc
  • adufou/vlc
  • ErwanAirone/vlc
  • HasinduDilshan10/vlc
  • vagrantc/vlc
  • rafiv/macos-bigsur-icon
  • Aymeriic/vlc
  • saranshg20/vlc
  • metzlove24/vlc
  • linkfanel/vlc
  • Ds886/vlc
  • metehan-arslan/vlc
  • Skantes/vlc
  • kgsandundananjaya96/vlc
  • mitchcapper/vlc
  • advaitgupta/vlc
  • StefanBruens/vlc
  • ratajs/vlc
  • T.M.F.B.3761/vlc
  • m222059/vlc
  • casemerrick/vlc
  • joshuaword2alt/vlc
  • sjwaddy/vlc
  • dima/vlc
  • Ybalrid/vlc
  • umxprime/vlc
  • eschmidt/vlc
  • vannieuwenhuysenmichelle/vlc
  • badcf00d/vlc
  • wesinator/vlc
  • louis/vlc
  • xqq/vlc
  • EmperorYP7/vlc
  • NicoLiam/vlc
  • loveleen/vlc
  • rofferom/vlc
  • rbultje/vlc
  • TheUnamed/vlc
  • pratiksharma341/vlc
  • Saurab17/vlc
  • purist.coder/vlc
  • Shuicheng/vlc
  • mdrrubel292/vlc
  • silverbleu00/vlc
  • metif12/vlc
  • asher-m/vlc
  • jeffk/vlc
  • Brandonbr1/vlc
  • beautyyuyanli/vlc
  • rego21/vlc
  • muyangren907/vlc
  • collectionbylawrencejason/vlc
  • evelez/vlc
  • GSMgeeth/vlc
  • Oneric/vlc
  • TJ5/vlc
  • XuanTung95/vlc
  • darrenjenny21/vlc
  • Trenly/vlc
  • RockyTDR/vlc
  • mjakubowski/vlc
  • caprica/vlc
  • ForteFrankie/vlc
  • seannamiller19/vlc
  • junlon2006/vlc
  • kiwiren6666/vlc
  • iuseiphonexs/vlc
  • fenngtun/vlc
  • Rajdutt999/vlc
  • typx/vlc
  • leon.vitanos/vlc
  • robertogarci0938/vlc
  • gsoc/gsoc2022/luc65r/vlc-mpd
  • skeller/vlc
  • MCJack123/vlc
  • luc65r/vlc-mpd
  • popov895/vlc
  • claucambra/vlc
  • brad/vlc
  • matthewmurua88/vlc
  • Tomas8874/vlc
  • philenotfound/vlc
  • makita-do3/vlc
  • LZXCorp/vlc
  • mar0x/vlc
  • senojetkennedy0102/vlc
  • shaneb243/vlc
  • ahmadbader/vlc
  • rajduttcse26/vlc-audio-filters
  • Juniorzito8415/vlc
  • achernyakov/vlc
  • lucasjetgroup/vlc
  • pupdoggy666/vlc
  • gmde9363/vlc
  • alexnwayne/vlc
  • bahareebrahimi781/vlc
  • hamad633666/vlc
  • umghof3112/vlc
  • joe0199771874/vlc
  • Octocats66666666/vlc
  • jjm_223/vlc
  • btech10110.19/vlc
  • sunnykfc028/vlc-audio-filters
  • loic/vlc
  • nguyenminhducmx1/vlc
  • JanekKrueger/vlc
  • bstubbington2/vlc
  • rcombs/vlc
  • Ordissimo/vlc
  • king7532/vlc
  • noobsauce101/vlc
  • schong0525/vlc
  • myQwil/vlc
  • apisbg91/vlc
  • geeboy0101017/vlc
  • kim.faughey/vlc
  • nurupo/vlc
  • yyusea/vlc
  • 0711235879.khco/vlc
  • ialo/vlc
  • iloveyeye2/vlc
  • gdtdftdqtd/vlc
  • leandroconsiglio/vlc
  • AndyHTML2012/vlc
  • ncz/vlc
  • lucenticus/vlc
  • knr1931/vlc
  • kjoonlee/vlc
  • chandrakant100/vlc-qt
  • johge42/vlc
  • polter/vlc
  • hexchain/vlc
  • Tushwrld/vlc
  • mztea928/vlc
  • jbelloncastro/vlc
  • alvinhochun/vlc
  • ghostpiratecrow/vlc
  • ujjwaltwitx/vlc
  • alexsonarin06/vlc
  • adrianbon76/vlc
  • altsod/vlc
  • damien.lucas44/vlc
  • dmytrivtaisa/vlc
  • utk202/vlc
  • aaxhrj/vlc
  • thomas.hermes/vlc
  • structurenewworldorder/vlc
  • slomo/vlc
  • wantlamy/vlc
  • musc.o3cminc/vlc
  • thebarshablog/vlc
  • kerrick/vlc
  • kratos142518/vlc
  • leogps/vlc
  • vacantron/vlc
  • luna_koly/vlc
  • Ratio2/vlc
  • anuoshemohammad/vlc
  • apsun/vlc
  • aaa1115910/vlc
  • alimotmoyo/vlc
  • Ambossmann/vlc
  • Sam-LearnsToCode/vlc
  • Chilledheart/vlc
  • Labnann/vlc
  • ktcoooot1/vlc
  • mohit-marathe/vlc
  • johnddx/vlc
  • manstabuk/vlc
  • Omar-ahmed314/vlc
  • vineethkm/vlc
  • 9Enemi86/vlc
  • radoslav.m.panteleev/vlc
  • ashishami2002/vlc
  • Corbax/vlc
  • firnasahmed/vlc
  • pelayarmalam4/vlc
  • c0ff330k/vlc
  • shikhindahikar/vlc
  • l342723951/vlc
  • christianschwandner/vlc
  • douniwan5788/vlc
  • 7damian7/vlc
  • ferdnyc/vlc
  • f.ales1/vlc
  • pandagby/vlc
  • BaaBaa/vlc
  • jewe37/vlc
  • w00drow/vlc
  • russelltg/vlc
  • ironicallygod/vlc
  • soumyaDghosh/vlc
  • linzihao1999/vlc
  • deyayush6/vlc
  • mibi88/vlc
  • newabdallah10/vlc
  • jhorbincolombia/vlc
  • rimvihaqueshupto/vlc
  • andrewkhon98/vlc
  • fab78/vlc
  • lapaz17/vlc
  • amanna13/vlc
  • mdakram28/vlc
  • 07jw1980/vlc
  • sohamgupta/vlc
  • Eson-Jia1/vlc
  • Sumou/vlc
  • vikram-kangotra/vlc
  • chalice191/vlc
  • olivercalder/vlc
  • aaasg4001/vlc
  • zipdox/vlc
  • kwizart/vlc
  • Dragon-S/vlc
  • jdemeule/vlc
  • gabriel_lt/vlc
  • locutusofborg/vlc
  • sammirata/vlc-librist
  • another/vlc
  • Benjamin_Loison/vlc
  • ahmedmoselhi/vlc
  • petergaal/vlc
  • huynhsontung/vlc
  • dariusmihut/vlc
  • tvermaashutosh/vlc
  • buti/vlc
  • Niram7777/vlc
  • rohan-here/vlc
  • balaji-sivasakthi/vlc
  • rlindner81/vlc
  • Kakadus/vlc
  • djain/vlc
  • ABBurmeister/vlc
  • craighuggins/vlc
  • orbea/vlc
  • maxos/vlc
  • aakarshmj/vlc
  • kblaschke/vlc
  • ankitm/vlc
  • advait-0/vlc
  • mohak2003/vlc
  • yselkowitz/vlc
  • AZM999/vlc-azm
  • andrey.turkin/vlc
  • Disha-Baghel/vlc
  • nowrep/vlc
  • Apeng/vlc
  • Choucroute_melba/vlc
  • autra/vlc
  • eclipseo/vlc
  • fhuber/vlc
  • olafhering/vlc
  • sdasda7777/vlc
  • 1div0/vlc
  • skosnits/vlc-extended-playlist-support
  • dnicolson/vlc
  • Timshel/vlc
  • octopols/vlc
  • MangalK/vlc
  • nima64/vlc
  • misawai/vlc
  • Alexander-Wilms/vlc
  • Maxime2/vlc-fork-for-visualizer
  • ww/vlc
  • jeske/vlc
  • sgross-emlix/vlc
  • morenonatural/vlc
  • freakingLovesVLC/vlc
  • borisgolovnev/vlc
  • mpromonet/vlc
  • diogo.simao-marques/vlc
  • masstock/vlc
  • pratikpatel8982/vlc
  • hugok79/vlc
  • longervision/vlc
  • abhiudaysurya/vlc
  • rishabhgarg/vlc
  • tumic/vlc
  • cart/vlc
  • shubham442/vlc
  • Aditya692005/vlc
  • sammirata/vlc4
  • syrykh/vlc
  • Vvorcun/macos-new-icon
  • AyaanshC/vlc
  • nasso/vlc
  • Quark/vlc
  • sebastinas/vlc
  • rhstone/vlc
  • talregev/vlc
  • Managor/vlc
  • abdsaber000/vlc
  • falbrechtskirchinger/vlc
405 results
Show changes
Commits on Source (5)
  • Thomas Guillem's avatar
    player: timer: handle seek state · 1ecb283c
    Thomas Guillem authored and Steve Lhomme's avatar Steve Lhomme committed
    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
    1ecb283c
  • Thomas Guillem's avatar
    player: expose seeking from GetPos/GetTime · 293d8919
    Thomas Guillem authored and Steve Lhomme's avatar Steve Lhomme committed
    293d8919
  • Thomas Guillem's avatar
    player: always seek the input_thread with absolute values · 05c9c727
    Thomas Guillem authored and Steve Lhomme's avatar Steve Lhomme committed
    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
    05c9c727
  • Thomas Guillem's avatar
    input: remove JUMP controls · 396c8141
    Thomas Guillem authored and Steve Lhomme's avatar Steve Lhomme committed
    The input_thread can now only seek with absolute values.
    396c8141
  • Thomas Guillem's avatar
    qt: implement timer.on_seek · c20e4543
    Thomas Guillem authored and Steve Lhomme's avatar Steve Lhomme committed
    Set the time and position to the requested seek point. Pause timers
    while seeking.
    c20e4543
......@@ -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, &current_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, &current_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 );
......
......@@ -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);
};
/**
......
......@@ -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;
}
......
......@@ -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.
......
......@@ -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;
......
......@@ -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;
......
......@@ -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
{
......
......@@ -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,
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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);
......
......@@ -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;
}
......