]> git.sesse.net Git - vlc/commitdiff
Flagging BLOCK_FLAG_DISCONTINUITY for every PID in the input when the slider is moved...
authorJean-Paul Saman <jpsaman@videolan.org>
Wed, 10 Aug 2005 20:07:20 +0000 (20:07 +0000)
committerJean-Paul Saman <jpsaman@videolan.org>
Wed, 10 Aug 2005 20:07:20 +0000 (20:07 +0000)
modules/demux/ts.c
modules/mux/mpeg/ts.c
modules/packetizer/mpegvideo.c
src/input/es_out.c

index b4b1e3b70977009f88977f42cd005499ad9700f2..12197283d0f9e7232ff55bd60f829dda44a3424c 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * ts.c: Transport Stream input module for VLC.
  *****************************************************************************
- * Copyright (C) 2004-2005 the VideoLAN team
+ * Copyright (C) 2004-2005 VideoLAN (Centrale Réseaux) and its contributors
  * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
@@ -1613,9 +1613,9 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
     const vlc_bool_t b_adaptation = p[3]&0x20;
     const vlc_bool_t b_payload    = p[3]&0x10;
     const int        i_cc         = p[3]&0x0f;   /* continuity counter */
+    vlc_bool_t       b_discontinuity = VLC_FALSE;/* discontinuity */    
 
     /* transport_scrambling_control is ignored */
-
     int         i_skip = 0;
     vlc_bool_t  i_ret  = VLC_FALSE;
     int         i_diff;
@@ -1660,6 +1660,10 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
                 msg_Warn( p_demux, "discontinuity_indicator (pid=%d) "
                           "ignored", pid->i_pid );
             }
+            /* discontinuity indicator found in stream */
+            b_discontinuity = p[5]&0x80 ? VLC_TRUE : VLC_FALSE;
+            if( p[5]&0x40 )
+                msg_Dbg( p_demux, "random access indicator (pid=%d) ", pid->i_pid );
         }
     }
 
@@ -1670,7 +1674,6 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
         * diff == 0 and duplicate packet (playload != 0) <- should we
         *   test the content ?
      */
-
     i_diff = ( i_cc - pid->i_cc )&0x0f;
     if( b_payload && i_diff == 1 )
     {
@@ -1684,14 +1687,13 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
                       pid->i_pid, i_cc );
             pid->i_cc = i_cc;
         }
-        else if( i_diff != 0 )
+        else if( i_diff != 0 && !b_discontinuity )
         {
             /* FIXME what to do when discontinuity_indicator is set ? */
             msg_Warn( p_demux, "discontinuity received 0x%x instead of 0x%x (pid=%d)",
                       i_cc, ( pid->i_cc + 1 )&0x0f, pid->i_pid );
 
             pid->i_cc = i_cc;
-
             if( pid->es->p_pes && pid->es->fmt.i_cat != VIDEO_ES )
             {
                 /* Small video artifacts are usually better then
@@ -1757,7 +1759,13 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
             }
         }
     }
-
+    
+    if( b_discontinuity && pid->es->p_pes )
+    {
+        msg_Warn( p_demux, "discontinuity indicator (pid=%d) ",
+                     pid->i_pid );
+        pid->es->p_pes->i_flags |= BLOCK_FLAG_DISCONTINUITY;
+    }
     return i_ret;
 }
 
@@ -1949,7 +1957,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
 #endif
     if( i_iod_tag != 0x02 )
     {
+#ifdef DEBUG    
         fprintf( stderr, "\n ERR: tag %02x != 0x02", i_iod_tag );
+#endif        
         return p_iod;
     }
 
index 66bb7a534f927c238a192940ed194af5be17a1ff..cfc0a70a4a026bfbc80455b9b03cade503cdaca7 100644 (file)
@@ -1,7 +1,7 @@
 /*****************************************************************************
  * ts.c: MPEG-II TS Muxer
  *****************************************************************************
- * Copyright (C) 2001, 2002 the VideoLAN team
+ * Copyright (C) 2001-2005 VideoLAN (Centrale Réseaux) and its contributors
  * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
@@ -270,6 +270,7 @@ typedef struct ts_stream_t
     int             i_stream_type;
     int             i_stream_id;
     int             i_continuity_counter;
+    vlc_bool_t      b_discontinuity;
 
     /* to be used for carriege of DIV3 */
     vlc_fourcc_t    i_bih_codec;
@@ -653,6 +654,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
         p_stream->i_pid = AllocatePID( p_sys, p_input->p_fmt->i_cat );
     p_stream->i_codec = p_input->p_fmt->i_codec;
     p_stream->i_continuity_counter    = 0;
+    p_stream->b_discontinuity         = VLC_FALSE;
     p_stream->i_decoder_specific_info = 0;
     p_stream->p_decoder_specific_info = NULL;
 
@@ -1568,6 +1570,7 @@ static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream,
         p_stream->i_continuity_counter;
 
     p_stream->i_continuity_counter = (p_stream->i_continuity_counter+1)%16;
+    p_stream->b_discontinuity = (p_pes->i_flags & BLOCK_FLAG_DISCONTINUITY);
 
     if( b_adaptation_field )
     {
@@ -1581,6 +1584,11 @@ static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream,
 
             p_ts->p_buffer[4] = 7 + i_stuffing;
             p_ts->p_buffer[5] = 0x10;   /* flags */
+            if( p_stream->b_discontinuity )
+            {
+                p_ts->p_buffer[5] |= 0x80; /* flag TS dicontinuity */
+                p_stream->b_discontinuity = VLC_FALSE;
+            }            
             p_ts->p_buffer[6] = ( 0 )&0xff;
             p_ts->p_buffer[7] = ( 0 )&0xff;
             p_ts->p_buffer[8] = ( 0 )&0xff;
@@ -1646,7 +1654,6 @@ static block_t *TSNew( sout_mux_t *p_mux, ts_stream_t *p_stream,
     return p_ts;
 }
 
-
 static void TSSetPCR( block_t *p_ts, mtime_t i_dts )
 {
     mtime_t i_pcr = 9 * i_dts / 100;
@@ -1800,6 +1807,11 @@ static void PEStoTS( sout_instance_t *p_sout,
             if( i_stuffing > 1 )
             {
                 p_ts->p_buffer[5] = 0x00;
+                if( p_stream->b_discontinuity )
+                {
+                    p_ts->p_buffer[5] |= 0x80;
+                    p_stream->b_discontinuity = VLC_FALSE;
+                }
                 for( i = 6; i < 6 + i_stuffing - 2; i++ )
                 {
                     p_ts->p_buffer[i] = 0xff;
index 4380a037164cac355ea4c8a49fee2b7ec09d31ee..551b51316f7f89e3c80b5392aadfe6b8dae4acad 100644 (file)
@@ -1,12 +1,13 @@
 /*****************************************************************************
  * mpegvideo.c: parse and packetize an MPEG1/2 video stream
  *****************************************************************************
- * Copyright (C) 2001, 2002 the VideoLAN team
+ * Copyright (C) 2001-2005 VideoLAN (Centrale Réseaux) and its contributors
  * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Eric Petit <titer@videolan.org>
  *          Gildas Bazin <gbazin@videolan.org>
+ *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
 
 #include "vlc_block_helper.h"
 
+#define SYNC_INTRAFRAME_TEXT N_("Sync on intraframe")
+#define SYNC_INTRAFRAME_LONGTEXT N_("Normally the packetizer would " \
+    "sync on the next full frame. This flags instructs the packetizer " \
+    "to sync on the first intraframe found.")
+
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
@@ -60,6 +66,9 @@ vlc_module_begin();
     set_description( _("MPEG-I/II video packetizer") );
     set_capability( "packetizer", 50 );
     set_callbacks( Open, Close );
+
+    add_bool( "packetizer-mpegvideo-sync-iframe", 1, NULL, SYNC_INTRAFRAME_TEXT,
+              SYNC_INTRAFRAME_LONGTEXT, VLC_TRUE );
 vlc_module_end();
 
 /*****************************************************************************
@@ -112,7 +121,10 @@ struct decoder_sys_t
 
     /* Number of pictures since last sequence header */
     int i_seq_old;
-
+    
+    /* Sync behaviour */
+    vlc_bool_t  b_sync_on_intra_frame;
+    vlc_bool_t  b_discontinuity;
 };
 
 enum {
@@ -174,6 +186,11 @@ static int Open( vlc_object_t *p_this )
     p_sys->i_old_duration = 0;
     p_sys->i_last_ref_pts = 0;
 
+    p_sys->b_discontinuity = VLC_FALSE;
+    p_sys->b_sync_on_intra_frame = var_CreateGetBool( p_dec, "packetizer-mpegvideo-sync-iframe" );
+    if( p_sys->b_sync_on_intra_frame )
+        msg_Dbg( p_dec, "syncing happens on intraframe now." );
+        
     return VLC_SUCCESS;
 }
 
@@ -199,6 +216,8 @@ static void Close( vlc_object_t *p_this )
     {
         block_ChainRelease( p_sys->p_frame );
     }
+    
+    var_Destroy( p_dec, "packetizer-mpegvideo-sync-iframe" );
 
     free( p_sys );
 }
@@ -219,7 +238,9 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
     if( (*pp_block)->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
     {
         p_sys->i_state = STATE_NOSYNC;
-        if( p_sys->p_frame ) block_ChainRelease( p_sys->p_frame );
+        p_sys->b_discontinuity = VLC_TRUE;
+        if( p_sys->p_frame )
+            block_ChainRelease( p_sys->p_frame );        
         p_sys->p_frame = NULL;
         p_sys->pp_last = &p_sys->p_frame;
         p_sys->b_frame_slice = VLC_FALSE;
@@ -294,6 +315,24 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
                 break;
             }
 
+            /* If a discontinuity has been encountered, then wait till
+             * the next Intra frame before continuing with packetizing */
+            if( p_sys->b_discontinuity &&
+                p_sys->b_sync_on_intra_frame )
+            {
+                if( p_pic->i_flags & BLOCK_FLAG_TYPE_I )
+                {
+                    msg_Dbg( p_dec, "synced on Intra frame" );
+                    p_sys->b_discontinuity = VLC_FALSE;
+                    p_pic->i_flags |= BLOCK_FLAG_DISCONTINUITY;
+                }
+                else
+                {
+                    p_sys->i_state = STATE_NOSYNC;
+                    break;
+                }
+            }
+            
             /* We've just started the stream, wait for the first PTS.
              * We discard here so we can still get the sequence header. */
             if( p_sys->i_dts <= 0 && p_sys->i_pts <= 0 &&
index e73072606ac7664b558f1670925ee493382cad4e..23b6e0b00237aad9a05c42f57b76e4264369ba41 100644 (file)
@@ -5,6 +5,7 @@
  * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
+ *          Jean-Paul Saman <jpsaman #_at_# m2x dot nl>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -63,7 +64,10 @@ struct es_out_id_t
     int       i_id;
     es_out_pgrm_t *p_pgrm;
 
-    /* */
+    /* Signal a discontinuity in the timeline for every PID */
+    vlc_bool_t b_discontinuity;
+
+    /* Misc. */
     int64_t i_preroll_end;
 
     /* Channel in the track type */
@@ -276,7 +280,8 @@ void input_EsOutDiscontinuity( es_out_t *out, vlc_bool_t b_audio )
     for( i = 0; i < p_sys->i_es; i++ )
     {
         es_out_id_t *es = p_sys->es[i];
-
+        es->b_discontinuity = VLC_TRUE; /* signal discontinuity */
+        
         /* Send a dummy block to let decoder know that
          * there is a discontinuity */
         if( es->p_dec && ( !b_audio || es->fmt.i_cat == AUDIO_ES ) )
@@ -669,6 +674,7 @@ static es_out_id_t *EsOutAdd( es_out_t *out, es_format_t *fmt )
     es->p_pgrm = p_pgrm;
     es_format_Copy( &es->fmt, fmt );
     es->i_preroll_end = -1;
+    es->b_discontinuity = VLC_FALSE;
 
     switch( fmt->i_cat )
     {
@@ -1031,6 +1037,11 @@ static int EsOutSend( es_out_t *out, es_out_id_t *es, block_t *p_block )
     }
 
     p_block->i_rate = p_input->i_rate;
+    if( es->b_discontinuity )
+    {
+        p_block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
+        es->b_discontinuity = VLC_FALSE;
+    }
 
     /* TODO handle mute */
     if( es->p_dec && ( es->fmt.i_cat != AUDIO_ES ||