]> git.sesse.net Git - vlc/blobdiff - modules/demux/ts.c
* mp4: use ES_OUT_SET_NEXT_DISPLAY_TIME when doing a seek (avoid late
[vlc] / modules / demux / ts.c
index 89328ea3d5bad5ec1afd6a26ce3a4dafc3fcf16c..30df8f84a6b0ec08272bca5dac3dc4e4e0a079fc 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>
@@ -500,6 +500,8 @@ static int Open( vlc_object_t *p_this )
         pid->b_seen     = VLC_FALSE;
         pid->b_valid    = VLC_FALSE;
     }
+    /* PID 8191 is padding */
+    p_sys->pid[8191].b_seen = VLC_TRUE;
     p_sys->i_packet_size = i_packet_size;
     p_sys->b_udp_out = VLC_FALSE;
     p_sys->i_ts_read = 50;
@@ -688,13 +690,13 @@ static int Open( vlc_object_t *p_this )
                      ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
 #endif
             p_sys->csa = csa_New();
-            
+
             if( p_sys->csa )
             {
                 vlc_value_t pkt_val;
-                
+
                 csa_SetCW( p_sys->csa, ck, ck );
-            
+
                 var_Create( p_demux, "ts-csa-pkt", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
                 var_Get( p_demux, "ts-csa-pkt", &pkt_val );
                 if( pkt_val.i_int < 4 || pkt_val.i_int > 188 )
@@ -817,14 +819,14 @@ static void Close( vlc_object_t *p_this )
  * DemuxFile:
  *****************************************************************************/
 static int DemuxFile( demux_t *p_demux )
-{    
+{
     demux_sys_t *p_sys = p_demux->p_sys;
     uint8_t     *p_buffer = p_sys->buffer; /* Put first on sync byte */
     int i_diff= 0;
     int i_data= 0;
     int i_pos = 0;
     int i_bufsize = p_sys->i_packet_size * p_sys->i_ts_read;
-    
+
     i_data = stream_Read( p_demux->s, p_sys->buffer, i_bufsize );
     if( (i_data <= 0) && (i_data < p_sys->i_packet_size) )
     {
@@ -839,7 +841,7 @@ static int DemuxFile( demux_t *p_demux )
         vlc_bool_t b_payload; /* indicates a packet with payload */
         vlc_bool_t b_adaptation; /* adaptation field */
         int i_cc  = 0;        /* continuity counter */
-    
+
         if( p_sys->buffer[i_pos] != 0x47 )
         {
             msg_Warn( p_demux, "lost sync" );
@@ -852,7 +854,7 @@ static int DemuxFile( demux_t *p_demux )
             if( !p_demux->b_die )
                 msg_Warn( p_demux, "sync found" );
         }
-        
+
         /* continuous when (one of this):
          * diff == 1
          * diff == 0 and payload == 0
@@ -862,10 +864,10 @@ static int DemuxFile( demux_t *p_demux )
         i_cc  = p_buffer[i_pos+3]&0x0f;
         b_payload = p_buffer[i_pos+3]&0x10;
         b_adaptation = p_buffer[i_pos+3]&0x20;
-        
+
         /* Get the PID */
         p_pid = &p_sys->pid[ ((p_buffer[i_pos+1]&0x1f)<<8)|p_buffer[i_pos+2] ];
-        
+
         /* Detect discontinuity indicator in adaptation field */
         if( b_adaptation )
         {
@@ -874,7 +876,7 @@ static int DemuxFile( demux_t *p_demux )
             if( p_buffer[i_pos+5]&0x40 )
                 msg_Warn( p_demux, "random access indicator (pid=%d) ", p_pid->i_pid );
         }
+
         i_diff = ( i_cc - p_pid->i_cc )&0x0f;
         if( b_payload && i_diff == 1 )
         {
@@ -893,17 +895,17 @@ static int DemuxFile( demux_t *p_demux )
                 /* FIXME what to do when discontinuity_indicator is set ? */
                 msg_Warn( p_demux, "transport error detected 0x%x instead of 0x%x",
                           i_cc, ( p_pid->i_cc + 1 )&0x0f );
-    
+
                 p_pid->i_cc = i_cc;
                 /* Mark transport error in the TS packet. */
                 p_buffer[i_pos+1] |= 0x80;
             }
         }
-        
+
         /* Test if user wants to decrypt it first */
         if( p_sys->csa )
             csa_Decrypt( p_demux->p_sys->csa, &p_buffer[i_pos], p_demux->p_sys->i_csa_pkt_size );
-        
+
         i_pos += p_sys->i_packet_size;
     }
 
@@ -1063,6 +1065,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
     demux_sys_t *p_sys = p_demux->p_sys;
     double f, *pf;
     int64_t i64;
+    int64_t *pi64;
     int i_int;
 
     if( p_sys->b_file_out )
@@ -1114,6 +1117,12 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             }
             *pi64 = 0;
             return VLC_EGENERIC;
+#else
+        case DEMUX_GET_TIME:
+        case DEMUX_GET_LENGTH:
+            pi64 = (int64_t*)va_arg( args, int64_t * );
+            *pi64 = 0;
+            return VLC_SUCCESS;
 #endif
         case DEMUX_SET_GROUP:
         {
@@ -1613,9 +1622,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;
@@ -1655,11 +1664,18 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
         i_skip = 5 + p[4];
         if( p[4] > 0 )
         {
-            if( p[5]&0x80 )
+            /* discontinuity indicator found in stream */
+            b_discontinuity = (p[5]&0x80) ? VLC_TRUE : VLC_FALSE;
+            if( b_discontinuity && pid->es->p_pes )
             {
-                msg_Warn( p_demux, "discontinuity_indicator (pid=%d) "
-                          "ignored", pid->i_pid );
+                msg_Warn( p_demux, "discontinuity indicator (pid=%d) ",
+                            pid->i_pid );
+                /* pid->es->p_pes->i_flags |= BLOCK_FLAG_DISCONTINUITY; */
             }
+#if 0
+            if( p[5]&0x40 )
+                msg_Dbg( p_demux, "random access indicator (pid=%d) ", pid->i_pid );
+#endif
         }
     }
 
@@ -1670,7 +1686,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 +1699,12 @@ 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
@@ -1949,12 +1962,14 @@ 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;
     }
 
     i_iod_length = IODDescriptorLength( &i_data, &p_data );
-#ifdef DEBUG    
+#ifdef DEBUG
     fprintf( stderr, "\n* length:%d", i_iod_length );
 #endif
     if( i_iod_length > i_data )
@@ -1974,10 +1989,10 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
     if( b_url )
     {
         p_iod->psz_url = IODGetURL( &i_data, &p_data );
-#ifdef DEBUG        
+#ifdef DEBUG
         fprintf( stderr, "\n* url string:%s", p_iod->psz_url );
         fprintf( stderr, "\n*****************************\n" );
-#endif        
+#endif
         return p_iod;
     }
     else
@@ -2073,7 +2088,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
                     i_decoderConfigDescr_length = IODDescriptorLength( &i_data, &p_data );
 #ifdef DEBUG
                     fprintf( stderr, "\n*   - DecoderConfigDesc length:%d", i_decoderConfigDescr_length );
-#endif                    
+#endif
 #define dec_descr   es_descr.dec_descr
                     dec_descr.i_objectTypeIndication = IODGetByte( &i_data, &p_data );
                     i_flags = IODGetByte( &i_data, &p_data );
@@ -2082,14 +2097,14 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
                     dec_descr.i_bufferSizeDB = IODGet3Bytes( &i_data, &p_data );
                     dec_descr.i_maxBitrate = IODGetDWord( &i_data, &p_data );
                     dec_descr.i_avgBitrate = IODGetDWord( &i_data, &p_data );
-#ifdef DEBUG                    
+#ifdef DEBUG
                     fprintf( stderr, "\n*     * objectTypeIndication:0x%x", dec_descr.i_objectTypeIndication  );
                     fprintf( stderr, "\n*     * streamType:0x%x", dec_descr.i_streamType );
                     fprintf( stderr, "\n*     * upStream:%d", dec_descr.b_upStream );
                     fprintf( stderr, "\n*     * bufferSizeDB:%d", dec_descr.i_bufferSizeDB );
                     fprintf( stderr, "\n*     * maxBitrate:%d", dec_descr.i_maxBitrate );
                     fprintf( stderr, "\n*     * avgBitrate:%d", dec_descr.i_avgBitrate );
-#endif                    
+#endif
                     if( i_decoderConfigDescr_length > 13 && IODGetByte( &i_data, &p_data ) == 0x05 )
                     {
                         int i;
@@ -2119,7 +2134,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
 
                     if( IODGetByte( &i_data, &p_data ) != 0x06 )
                     {
-#ifdef DEBUG                    
+#ifdef DEBUG
                         fprintf( stderr, "\n* ERR missing SLConfigDescr" );
 #endif
                         es_descr.b_ok = 0;
@@ -2168,9 +2183,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
                             }
                             break;
                         default:
-#ifdef DEBUG                        
+#ifdef DEBUG
                             fprintf( stderr, "\n* ERR unsupported SLConfigDescr predefined" );
-#endif                            
+#endif
                             es_descr.b_ok = 0;
                             break;
                     }
@@ -2179,9 +2194,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
 #undef  sl_descr
 #undef  es_descr
             default:
-#ifdef DEBUG            
+#ifdef DEBUG
                 fprintf( stderr, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag, i_length );
-#endif                
+#endif
                 break;
         }
 
@@ -2191,7 +2206,7 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
     }
 #ifdef DEBUG
     fprintf( stderr, "\n*****************************\n" );
-#endif    
+#endif
     return p_iod;
 }
 
@@ -2243,7 +2258,8 @@ static vlc_bool_t DVBProgramIsSelected( demux_t *p_demux, uint16_t i_pgrm )
     demux_sys_t          *p_sys = p_demux->p_sys;
 
     if ( !p_sys->b_dvb_control ) return VLC_FALSE;
-    if ( p_sys->i_dvb_program == -1 && p_sys->p_programs_list == NULL )
+    if ( (p_sys->i_dvb_program == -1 && p_sys->p_programs_list == NULL)
+           || p_sys->i_dvb_program == 0 )
         return VLC_TRUE;
     if ( p_sys->i_dvb_program == i_pgrm ) return VLC_TRUE;
 
@@ -2287,7 +2303,7 @@ static void SDTCallBack( demux_t *p_demux, dvbpsi_sdt_t *p_sdt )
         dvbpsi_descriptor_t *p_dr;
 
         msg_Dbg( p_demux, "  * service id=%d eit schedule=%d present=%d "
-                 "runing=%d free_ca=%d",
+                 "running=%d free_ca=%d",
                  p_srv->i_service_id, p_srv->b_eit_schedule,
                  p_srv->b_eit_present, p_srv->i_running_status,
                  p_srv->b_free_ca );
@@ -2873,23 +2889,32 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
                 else if( p_dr->i_tag == 0x73 )
                 {
                     /* DTS audio descriptor (ETSI TS 101 154 Annex F) */
-                    msg_Dbg( p_demux, "   * DTS audio descriptor not decoded" );
+                    msg_Dbg( p_demux, "    * DTS audio descriptor not decoded" );
                     pid->es->fmt.i_cat = AUDIO_ES;
                     pid->es->fmt.i_codec = VLC_FOURCC( 'd', 't', 's', ' ' );
                 }
                 else if( p_dr->i_tag == 0x45 )
                 {
-                    msg_Dbg( p_demux, "   * VBI Data descriptor" );
+                    msg_Dbg( p_demux, "    * VBI Data descriptor" );
                     /* FIXME : store the information somewhere */
                 }
                 else if( p_dr->i_tag == 0x46 )
                 {
-                    msg_Dbg( p_demux, "  * VBI Teletext descriptor" );
+                    msg_Dbg( p_demux, "    * VBI Teletext descriptor" );
                     /* FIXME : store the information somewhere */
                 }
+#ifdef _DVBPSI_DR_52_H_
+                else if( p_dr->i_tag == 0x52 )
+                {
+                    dvbpsi_stream_identifier_dr_t *si;
+                    si = dvbpsi_DecodeStreamIdentifierDr( p_dr );
+                    
+                    msg_Dbg( p_demux, "    * Stream Component Identifier: %d", si->i_component_tag );
+                }
+#endif
                 else if( p_dr->i_tag == 0x56 )
                 {
-                    msg_Dbg( p_demux, "   * EBU Teletext descriptor" );
+                    msg_Dbg( p_demux, "    * EBU Teletext descriptor" );
                     pid->es->fmt.i_cat = SPU_ES;
                     pid->es->fmt.i_codec = VLC_FOURCC( 't', 'e', 'l', 'x' );
                     pid->es->fmt.psz_description = strdup( "Teletext" );