[vlc-commits] CDG: fix seek

Zhao Zhili git at videolan.org
Tue Nov 17 22:10:55 CET 2015


vlc | branch: master | Zhao Zhili <wantlamy at gmail.com> | Tue Nov 17 10:11:50 2015 +0800| [5e9406e75ae2207cf3422cf28d86eb2fbaa85349] | committer: Jean-Baptiste Kempf

CDG: fix seek

The video output is messed up if we only do a stream_Seek(). If we want
to seeking forward, we should decode and discard pictures to keep the
decoder at the right state. For seeking backward, seeking to the
beginning and decode from there. Since the bitrate is very low and the
decoding process is really simple, there is no obvious delay. I have
tested this strategy on a dual core ARM board.

Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=5e9406e75ae2207cf3422cf28d86eb2fbaa85349
---

 modules/codec/cdg.c |    2 +-
 modules/demux/cdg.c |   26 ++++++++++++++++++++++----
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/modules/codec/cdg.c b/modules/codec/cdg.c
index 98c07c8..763ba1a 100644
--- a/modules/codec/cdg.c
+++ b/modules/codec/cdg.c
@@ -158,7 +158,7 @@ static picture_t *Decode( decoder_t *p_dec, block_t **pp_block )
     }
 
     /* Only display 25 frame per second (there is 75 packets per second) */
-    if( (p_sys->i_packet%3) == 1 )
+    if( (p_sys->i_packet%3) == 1 && p_block->i_pts == p_block->i_dts )
     {
         /* Get a new picture */
         p_pic = decoder_NewPicture( p_dec );
diff --git a/modules/demux/cdg.c b/modules/demux/cdg.c
index 212a4f3..14df882 100644
--- a/modules/demux/cdg.c
+++ b/modules/demux/cdg.c
@@ -119,6 +119,10 @@ static int Demux( demux_t *p_demux )
 {
     demux_sys_t *p_sys = p_demux->p_sys;
     block_t     *p_block;
+    mtime_t     i_date;
+    mtime_t     i_delta;
+
+    i_delta = INT64_C(1000000) / CDG_FRAME_RATE;
 
     p_block = stream_Block( p_demux->s, CDG_FRAME_SIZE );
     if( p_block == NULL )
@@ -127,15 +131,22 @@ static int Demux( demux_t *p_demux )
         return 0;
     }
 
-    p_block->i_dts =
-    p_block->i_pts = VLC_TS_0 + date_Get( &p_sys->pts );
+    i_date = stream_Tell( p_demux->s ) / CDG_FRAME_SIZE * i_delta;
+    if( i_date >= date_Get( &p_sys->pts ) + i_delta )
+    {
+        p_block->i_dts = p_block->i_pts = i_date;
+        date_Set( &p_sys->pts, i_date );
+    }
+    else
+    {
+        p_block->i_dts = i_date;
+        p_block->i_pts = date_Get( &p_sys->pts );
+    }
 
     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts );
 
     es_out_Send( p_demux->out, p_sys->p_es, p_block );
 
-    date_Increment( &p_sys->pts, 1 );
-
     return 1;
 }
 
@@ -155,13 +166,20 @@ static void Close ( vlc_object_t * p_this )
  *****************************************************************************/
 static int Control( demux_t *p_demux, int i_query, va_list args )
 {
+    uint64_t i_old_offset = stream_Tell( p_demux->s );
     int i_ret = demux_vaControlHelper( p_demux->s, 0, -1,
                                        8*CDG_FRAME_SIZE*CDG_FRAME_RATE, CDG_FRAME_SIZE,
                                        i_query, args );
     if( !i_ret && ( i_query == DEMUX_SET_POSITION || i_query == DEMUX_SET_TIME ) )
+    {
         date_Set( &p_demux->p_sys->pts,
                   stream_Tell( p_demux->s ) / CDG_FRAME_SIZE *
                     INT64_C(1000000) / CDG_FRAME_RATE );
+        if ( i_old_offset > stream_Tell( p_demux->s ) )
+            i_ret = stream_Seek( p_demux->s, 0 );
+        else
+            i_ret = stream_Seek( p_demux->s, i_old_offset );
+    }
 
     return i_ret;
 }



More information about the vlc-commits mailing list