[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