[vlc-devel] commit: Display first frame after a seek as soon as possible. ( Laurent Aimar )
git version control
git at videolan.org
Fri Oct 10 21:28:57 CEST 2008
vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Fri Oct 10 00:36:49 2008 +0200| [089089cac5b8e2b219e811aa695610da863536a2] | committer: Laurent Aimar
Display first frame after a seek as soon as possible.
It works while paused too.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=089089cac5b8e2b219e811aa695610da863536a2
---
src/input/clock.c | 5 ++-
src/input/decoder.c | 50 +++++++++++++++++++++++++++++++++++++++----
src/input/es_out.c | 23 +++++++++++++++++--
src/input/input.c | 10 ++++++--
src/input/input_internal.h | 3 +-
5 files changed, 77 insertions(+), 14 deletions(-)
diff --git a/src/input/clock.c b/src/input/clock.c
index e06917a..7019457 100644
--- a/src/input/clock.c
+++ b/src/input/clock.c
@@ -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 );
}
diff --git a/src/input/decoder.c b/src/input/decoder.c
index 80ed3b3..1306181 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -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;
+ }
}
}
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 5fa4efa..e7f1784 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -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;
}
diff --git a/src/input/input.c b/src/input/input.c
index 81bda27..0f75f62 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -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" );
diff --git a/src/input/input_internal.h b/src/input/input_internal.h
index 4ba8701..720a01a 100644
--- a/src/input/input_internal.h
+++ b/src/input/input_internal.h
@@ -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 );
More information about the vlc-devel
mailing list