Commit 089089ca authored by Laurent Aimar's avatar Laurent Aimar

Display first frame after a seek as soon as possible.

It works while paused too.
parent 7bd51629
......@@ -201,8 +201,6 @@ void input_clock_Update( input_clock_t *cl,
vlc_mutex_lock( &cl->lock );
assert( !cl->b_paused );
if( ( !cl->b_has_reference ) ||
( i_ck_stream == 0 && cl->last.i_stream != 0 ) )
{
......@@ -394,6 +392,9 @@ void input_clock_ChangeSystemOrigin( input_clock_t *cl, mtime_t i_system )
cl->ref.i_system += i_offset;
cl->last.i_system += i_offset;
if( cl->b_paused )
cl->i_pause_date = i_system;
vlc_mutex_unlock( &cl->lock );
}
......
......@@ -124,6 +124,7 @@ struct decoder_owner_sys_t
bool b_buffering;
struct
{
bool b_first;
bool b_full;
int i_count;
......@@ -483,6 +484,7 @@ void input_DecoderStartBuffering( decoder_t *p_dec )
DecoderFlush( p_dec );
p_owner->buffer.b_first = true;
p_owner->buffer.b_full = false;
p_owner->buffer.i_count = 0;
......@@ -681,6 +683,7 @@ static decoder_t * CreateDecoder( input_thread_t *p_input,
p_owner->pause.i_date = 0;
p_owner->b_buffering = false;
p_owner->buffer.b_first = true;
p_owner->buffer.b_full = false;
p_owner->buffer.i_count = 0;
p_owner->buffer.p_picture = NULL;
......@@ -834,8 +837,12 @@ static void DecoderWaitUnblock( decoder_t *p_dec, bool *pb_reject )
while( !p_owner->b_flushing )
{
if( p_owner->b_paused && p_owner->b_buffering && !p_owner->buffer.b_full )
break;
if( !p_owner->b_paused && ( !p_owner->b_buffering || !p_owner->buffer.b_full ) )
break;
vlc_cond_wait( &p_owner->wait, &p_owner->lock );
}
......@@ -1044,7 +1051,13 @@ static void DecoderPlayAudio( decoder_t *p_dec, aout_buffer_t *p_audio,
if( !b_has_more )
break;
vlc_mutex_lock( &p_owner->lock );
if( !p_owner->buffer.p_audio )
{
vlc_mutex_unlock( &p_owner->lock );
break;
}
}
}
......@@ -1205,7 +1218,7 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
/* */
vlc_mutex_lock( &p_owner->lock );
if( p_owner->b_buffering || p_owner->buffer.p_picture )
if( ( p_owner->b_buffering && !p_owner->buffer.b_first ) || p_owner->buffer.p_picture )
{
p_picture->p_next = NULL;
......@@ -1228,11 +1241,12 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
bool b_reject;
DecoderWaitUnblock( p_dec, &b_reject );
if( p_owner->b_buffering )
if( p_owner->b_buffering && !p_owner->buffer.b_first )
{
vlc_mutex_unlock( &p_owner->lock );
return;
}
bool b_buffering_first = p_owner->b_buffering;
/* */
if( p_owner->buffer.p_picture )
......@@ -1250,8 +1264,23 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
int i_rate = INPUT_RATE_DEFAULT;
mtime_t i_delay;
DecoderFixTs( p_dec, &p_picture->date, NULL, NULL,
&i_rate, &i_delay, false );
if( b_buffering_first )
{
assert( p_owner->buffer.b_first );
assert( !p_owner->buffer.i_count );
msg_Dbg( p_dec, "Received first picture" );
p_owner->buffer.b_first = false;
p_picture->date = mdate();
p_picture->b_force = true;
i_delay = 0;
if( p_owner->p_clock )
i_rate = input_clock_GetRate( p_owner->p_clock );
}
else
{
DecoderFixTs( p_dec, &p_picture->date, NULL, NULL,
&i_rate, &i_delay, false );
}
vlc_mutex_unlock( &p_owner->lock );
......@@ -1295,9 +1324,15 @@ static void DecoderPlayVideo( decoder_t *p_dec, picture_t *p_picture,
*pi_played_sum += i_tmp_display;
*pi_lost_sum += i_tmp_lost;
if( !b_has_more )
if( !b_has_more || b_buffering_first )
break;
vlc_mutex_lock( &p_owner->lock );
if( !p_owner->buffer.p_picture )
{
vlc_mutex_unlock( &p_owner->lock );
break;
}
}
}
......@@ -1432,6 +1467,11 @@ static void DecoderPlaySpu( decoder_t *p_dec, subpicture_t *p_subpic,
if( !b_has_more )
break;
vlc_mutex_lock( &p_owner->lock );
if( !p_owner->buffer.p_subpic )
{
vlc_mutex_unlock( &p_owner->lock );
break;
}
}
}
......
......@@ -513,7 +513,7 @@ void input_EsOutChangePosition( es_out_t *out )
p_sys->b_buffering = true;
}
bool input_EsOutDecodersEmpty( es_out_t *out )
bool input_EsOutDecodersIsEmpty( es_out_t *out )
{
es_out_sys_t *p_sys = out->p_sys;
int i;
......@@ -537,6 +537,11 @@ bool input_EsOutDecodersEmpty( es_out_t *out )
return true;
}
bool input_EsOutIsBuffering( es_out_t *out )
{
return out->p_sys->b_buffering;
}
/*****************************************************************************
*
*****************************************************************************/
......@@ -556,9 +561,21 @@ static void EsOutDecodersStopBuffering( es_out_t *out, bool b_forced )
if( i_ret )
return;
if( i_stream_duration <= p_sys->p_input->i_pts_delay && !b_forced )
mtime_t i_preroll_duration = 0;
mtime_t i_preroll_end = 0;
for( int i = 0; i < p_sys->i_es; i++ )
{
es_out_id_t *p_es = p_sys->es[i];
if( p_es->p_dec && p_es->i_preroll_end > 0 )
i_preroll_end = __MAX( i_preroll_end, p_es->i_preroll_end );
}
if( i_preroll_end > 0 )
i_preroll_duration = __MAX( i_preroll_end - i_stream_start, 0 );
if( i_stream_duration <= p_sys->p_input->i_pts_delay + i_preroll_duration && !b_forced )
{
msg_Dbg( p_sys->p_input, "Buffering %d%%", (int)(100 * i_stream_duration / p_sys->p_input->i_pts_delay) );
msg_Dbg( p_sys->p_input, "Buffering %d%%", (int)(100 * i_stream_duration / ( p_sys->p_input->i_pts_delay + i_preroll_duration )) );
return;
}
......
......@@ -729,11 +729,15 @@ static void MainLoop( input_thread_t *p_input )
mtime_t i_current;
mtime_t i_deadline;
mtime_t i_wakeup;
bool b_paused;
/* Demux data */
b_force_update = false;
i_wakeup = 0;
if( p_input->i_state != PAUSE_S )
b_paused = p_input->i_state == PAUSE_S &&
!input_EsOutIsBuffering( p_input->p->p_es_out );
if( !b_paused )
{
MainLoopDemux( p_input, &b_force_update, &i_start_mdate );
i_wakeup = input_EsOutGetWakeup( p_input->p->p_es_out );
......@@ -742,7 +746,7 @@ static void MainLoop( input_thread_t *p_input )
/* */
do {
i_deadline = i_wakeup;
if( p_input->i_state == PAUSE_S )
if( b_paused )
i_deadline = __MIN( i_intf_update, i_statistic_update );
/* Handle control */
......@@ -785,7 +789,7 @@ static void MainLoop( input_thread_t *p_input )
/* We have finish to demux data but not to play them */
while( vlc_object_alive( p_input ) )
{
if( input_EsOutDecodersEmpty( p_input->p->p_es_out ) )
if( input_EsOutDecodersIsEmpty( p_input->p->p_es_out ) )
break;
msg_Dbg( p_input, "waiting decoder fifos to empty" );
......
......@@ -337,7 +337,8 @@ int input_EsOutSetRecord( es_out_t *, bool b_record );
void input_EsOutChangeRate( es_out_t *, int );
void input_EsOutChangePause( es_out_t *, bool b_paused, mtime_t i_date );
void input_EsOutChangePosition( es_out_t * );
bool input_EsOutDecodersEmpty( es_out_t * );
bool input_EsOutDecodersIsEmpty( es_out_t * );
bool input_EsOutIsBuffering( es_out_t * );
/* Subtitles */
char **subtitles_Detect( input_thread_t *, char* path, const char *fname );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment