]> git.sesse.net Git - vlc/blobdiff - modules/demux/ts.c
demux: ts: reject unknown probed streams
[vlc] / modules / demux / ts.c
index 577c0ccb35e2cfc85237a1508517e518532b140b..a467b56561c5c2cc39ce074eb6aae1c73694c977 100644 (file)
@@ -319,7 +319,7 @@ typedef struct
     int i_service;
 } vdr_info_t;
 
-#define MIN_ES_PID 32
+#define MIN_ES_PID 4    /* Should be 32.. broken muxers */
 #define MAX_ES_PID 8190
 
 struct demux_sys_t
@@ -443,6 +443,7 @@ static void GetLastPCR( demux_t *p_demux );
 static void CheckPCR( demux_t *p_demux );
 static void PCRHandle( demux_t *p_demux, ts_pid_t *, block_t * );
 static void PCRFixHandle( demux_t *, block_t * );
+static mtime_t AdjustPTSWrapAround( demux_t *, mtime_t );
 
 static void              IODFree( iod_descriptor_t * );
 
@@ -853,7 +854,7 @@ static void MissingPATPMTFixup( demux_t *p_demux )
     for( int i = MIN_ES_PID; i < MAX_ES_PID; i++ )
     {
         if( !p_sys->pid[i].b_seen ||
-            !p_sys->pid[i].probed.i_type )
+            p_sys->pid[i].probed.i_type == -1 )
             continue;
 
         if( i_pcr_pid == 0x1FFF && ( p_sys->pid[i].probed.i_type == 0x03 ||
@@ -906,7 +907,7 @@ static void MissingPATPMTFixup( demux_t *p_demux )
         for( int i = MIN_ES_PID; i < MAX_ES_PID; i++ )
         {
             if( !p_sys->pid[i].b_seen ||
-                !p_sys->pid[i].probed.i_type )
+                p_sys->pid[i].probed.i_type == -1 )
                 continue;
 
             esstreams[j].pes.i_stream_type = p_sys->pid[i].probed.i_type;
@@ -1181,7 +1182,7 @@ static int Open( vlc_object_t *p_this )
         }
     }
 
-    while( p_sys->i_pmt_es <= 0 && vlc_object_alive( p_demux )
+    while( p_sys->i_pmt_es <= 0
            && (!p_sys->pid[0].b_seen && !p_sys->patfix.b_pat_deadline) )
     {
         if( Demux( p_demux ) != 1 )
@@ -1192,11 +1193,6 @@ static int Open( vlc_object_t *p_this )
     if( p_sys->i_pmt_es == 0 && !p_sys->pid[0].b_seen )
         MissingPATPMTFixup( p_demux );
 
-    while( p_sys->i_pmt_es <= 0 && vlc_object_alive( p_demux ) )
-    {
-        if( Demux( p_demux ) != 1 )
-            break;
-    }
     return VLC_SUCCESS;
 }
 
@@ -2098,9 +2094,13 @@ static void ParsePES( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
             if( header[7]&0x80 )    /* has pts */
             {
                 i_pts = ExtractPESTimestamp( &header[9] );
+                i_pts = AdjustPTSWrapAround( p_demux, i_pts );
 
                 if( header[7]&0x40 )    /* has dts */
+                {
                     i_dts = ExtractPESTimestamp( &header[14] );
+                    i_dts = AdjustPTSWrapAround( p_demux, i_dts );
+                }
             }
         }
         else
@@ -2392,7 +2392,7 @@ static block_t* ReadTSPacket( demux_t *p_demux )
     {
         msg_Warn( p_demux, "lost synchro" );
         block_Release( p_pkt );
-        while( vlc_object_alive (p_demux) )
+        for( ;; )
         {
             const uint8_t *p_peek;
             int i_peek, i_skip = 0;
@@ -2452,6 +2452,32 @@ static mtime_t AdjustPCRWrapAround( demux_t *p_demux, mtime_t i_pcr )
     return i_pcr + i_adjust;
 }
 
+static mtime_t AdjustPTSWrapAround( demux_t *p_demux, mtime_t i_pts )
+{
+    demux_sys_t *p_sys = p_demux->p_sys;
+    mtime_t i_pcr = p_sys->i_current_pcr;
+
+    mtime_t i_adjustremain = i_pcr % 0x1FFFFFFFF;
+    mtime_t i_adjustbase = i_pcr - i_adjustremain;
+
+    mtime_t i_pts_adjust = i_adjustbase;
+
+    /* PTS has rolled first */
+    if( i_adjustremain >= 0xFFFFFFFF && i_pts < 0xFFFFFFFF )
+    {
+        i_pts_adjust += 0x1FFFFFFFF;
+    }
+    /* PCR has rolled first (PTS is late!) */
+    else if( i_adjustremain < 0xFFFFFFFF && i_pts >= 0xFFFFFFFF )
+    {
+        if( i_adjustbase >= 0x1FFFFFFFF ) /* we need to remove current roll */
+            i_pts_adjust -= 0x1FFFFFFFF;
+    }
+
+    i_pts += i_pts_adjust;
+    return i_pts;
+}
+
 static mtime_t GetPCR( block_t *p_pkt )
 {
     const uint8_t *p = p_pkt->p_buffer;
@@ -2489,7 +2515,7 @@ static int SeekToPCR( demux_t *p_demux, int64_t i_pos )
     if( stream_Seek( p_sys->stream, i_pos ) )
         return VLC_EGENERIC;
 
-    while( vlc_object_alive( p_demux ) )
+    for( ;; )
     {
         block_t *p_pkt;
 
@@ -2599,7 +2625,7 @@ static void GetFirstPCR( demux_t *p_demux )
     if( stream_Seek( p_sys->stream, 0 ) )
         return;
 
-    while( vlc_object_alive (p_demux) )
+    for( ;; )
     {
         block_t     *p_pkt;
 
@@ -2640,7 +2666,7 @@ static void GetLastPCR( demux_t *p_demux )
     if( i_pos < 0 && i_pos >= i_stream_size )
         return;
 
-    while( vlc_object_alive( p_demux ) )
+    for( ;; )
     {
         if( SeekToPCR( p_demux, i_pos ) )
             break;
@@ -2648,20 +2674,7 @@ static void GetLastPCR( demux_t *p_demux )
         if( ( i_pos = stream_Tell( p_sys->stream ) ) >= i_last_pos )
             break;
     }
-    if( p_sys->i_last_pcr >= 0 )
-    {
-        int64_t i_size = stream_Size( p_sys->stream );
-        mtime_t i_duration_msec = ( p_sys->i_last_pcr - p_sys->i_first_pcr ) * 100 / 9 / 1000;
-        int64_t i_rate = ( i_size < 0 || i_duration_msec <= 0 ) ? 0 : i_size * 1000 * 8 / i_duration_msec;
-        const int64_t TS_SUPPOSED_MAXRATE = 55 * 1000 * 1000; //FIXME I think it's enough.
-        const int64_t TS_SUPPOSED_MINRATE = 0.5 * 1000 * 1000; //FIXME
-        if( i_rate < TS_SUPPOSED_MINRATE || i_rate > TS_SUPPOSED_MAXRATE )
-        {
-            msg_Dbg( p_demux, "calculated bitrate (%"PRId64"bit/s) is too low or too high. min bitrate (%"PRId64"bit/s) max bitrate (%"PRId64"bit/s)",
-                     i_rate, TS_SUPPOSED_MINRATE, TS_SUPPOSED_MAXRATE );
-            p_sys->i_last_pcr = -1;
-        }
-    }
+
     stream_Seek( p_sys->stream, i_initial_pos );
     assert( i_initial_pos == stream_Tell( p_sys->stream ) );
     p_sys->i_current_pcr = i_initial_pcr;
@@ -2680,7 +2693,7 @@ static void CheckPCR( demux_t *p_demux )
     p_sys->p_pcrs[0] = p_sys->i_first_pcr;
     p_sys->p_pos[0] = i_initial_pos;
 
-    for( i = 1; i < p_sys->i_pcrs_num && vlc_object_alive( p_demux ); ++i )
+    for( i = 1; i < p_sys->i_pcrs_num; ++i )
     {
         /* Round i_pos to a multiple of p_sys->i_packet_size */
         int64_t i_pos = i_size / p_sys->i_pcrs_num * i;
@@ -2717,13 +2730,15 @@ static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
     if( i_pcr < 0 )
         return;
 
+    i_pcr = AdjustPCRWrapAround( p_demux, i_pcr );
+
     if( p_sys->i_pid_ref_pcr == pid->i_pid )
-        p_sys->i_current_pcr = AdjustPCRWrapAround( p_demux, i_pcr );
+        p_sys->i_current_pcr = i_pcr;
 
     /* Search program and set the PCR */
-    int i_group = -1;
-    for( int i = 0; i < p_sys->i_pmt && i_group < 0 ; i++ )
+    for( int i = 0; i < p_sys->i_pmt; i++ )
     {
+        int i_group = -1;
         for( int i_prg = 0; i_prg < p_sys->pmt[i]->psi->i_prg; i_prg++ )
         {
             ts_prg_psi_t *p_prg = p_sys->pmt[i]->psi->prg[i_prg];
@@ -3401,9 +3416,9 @@ static void SDTCallBack( demux_t *p_demux, dvbpsi_sdt_t *p_sdt )
 
     msg_Dbg( p_demux, "SDTCallBack called" );
 
-    if( sdt->psi->i_sdt_version != -1 &&
-        ( !p_sdt->b_current_next ||
-          p_sdt->i_version == sdt->psi->i_sdt_version ) )
+    if( p_sys->b_delay_es_creation ||
+       !p_sdt->b_current_next ||
+        p_sdt->i_version == sdt->psi->i_sdt_version )
     {
         dvbpsi_DeleteSDT( p_sdt );
         return;
@@ -4674,6 +4689,10 @@ static bool PMTSetupEsHDMV( demux_t *p_demux, ts_pid_t *pid,
         p_fmt->i_cat = AUDIO_ES;
         p_fmt->i_codec = VLC_CODEC_BD_LPCM;
         break;
+    case 0x81:
+        p_fmt->i_cat = AUDIO_ES;
+        p_fmt->i_codec = VLC_CODEC_A52;
+        break;
     case 0x82:
     case 0x85: /* DTS-HD High resolution audio */
     case 0x86: /* DTS-HD Master audio */
@@ -4699,6 +4718,10 @@ static bool PMTSetupEsHDMV( demux_t *p_demux, ts_pid_t *pid,
     case 0x91: /* Interactive graphics */
     case 0x92: /* Subtitle */
         return false;
+    case 0xEA:
+        p_fmt->i_cat = VIDEO_ES;
+        p_fmt->i_codec = VLC_CODEC_VC1;
+        break;
     default:
         msg_Info( p_demux, "HDMV registration not implemented for pid 0x%x type 0x%x",
                   p_es->i_pid, p_es->i_type );