]> git.sesse.net Git - vlc/blobdiff - modules/demux/ts.c
* include/vlc_es.h: added b_packetized field to es_format_t to tell a decoder if...
[vlc] / modules / demux / ts.c
index aff4e010548815c9f8cb8aa6817c501a4d7b554d..0f3a13e79d39dffd8eba53818d51076060411721 100644 (file)
@@ -2,7 +2,7 @@
  * ts.c: Transport Stream input module for VLC.
  *****************************************************************************
  * Copyright (C) 2004 VideoLAN
- * $Id: ts.c,v 1.11 2004/02/14 01:53:17 gbazin Exp $
+ * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
@@ -60,8 +60,8 @@
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
-static int  Open    ( vlc_object_t * );
-static void Close  ( vlc_object_t * );
+static int  Open  ( vlc_object_t * );
+static void Close ( vlc_object_t * );
 
 vlc_module_begin();
     set_description( _("ISO 13818-1 MPEG Transport Stream input - new" ) );
@@ -235,6 +235,8 @@ static inline int PIDGet( block_t *p )
 
 static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk );
 
+static void PCRHandle( demux_t *p_demux, ts_pid_t *, block_t * );
+
 static iod_descriptor_t *IODNew( int , uint8_t * );
 static void              IODFree( iod_descriptor_t * );
 
@@ -528,10 +530,10 @@ static void Close( vlc_object_t *p_this )
         csa_Delete( p_sys->csa );
     }
 
+    if( p_sys->i_pmt ) free( p_sys->pmt );
     free( p_sys );
 }
 
-
 /*****************************************************************************
  * Demux:
  *****************************************************************************/
@@ -625,6 +627,8 @@ static int Demux( demux_t *p_demux )
             {
                 msg_Dbg( p_demux, "pid[0x%x] unknown", p_pid->i_pid );
             }
+            /* We have to handle PCR if present */
+            PCRHandle( p_demux, p_pid, p_pkt );
             block_Release( p_pkt );
         }
         p_pid->b_seen = VLC_TRUE;
@@ -934,6 +938,37 @@ static void ParsePES ( demux_t *p_demux, ts_pid_t *pid )
     }
 }
 
+static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
+{
+    demux_sys_t   *p_sys = p_demux->p_sys;
+    const uint8_t *p = p_bk->p_buffer;
+
+    if( ( p[3]&0x20 ) && /* adaptation */
+        ( p[5]&0x10 ) &&
+        ( p[4] >= 7 ) )
+    {
+        int i;
+        mtime_t i_pcr;  /* 33 bits */
+
+        i_pcr = ( (mtime_t)p[6] << 25 ) |
+                ( (mtime_t)p[7] << 17 ) |
+                ( (mtime_t)p[8] << 9 ) |
+                ( (mtime_t)p[9] << 1 ) |
+                ( (mtime_t)p[10] >> 7 );
+
+        /* Search program and set the PCR */
+        for( i = 0; i < p_sys->i_pmt; i++ )
+        {
+            if( pid->i_pid == p_sys->pmt[i]->psi->i_pid_pcr )
+            {
+                es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR,
+                                (int)p_sys->pmt[i]->psi->i_number,
+                                (int64_t)(i_pcr * 100 / 9) );
+            }
+        }
+    }
+}
+
 static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
 {
     const uint8_t    *p = p_bk->p_buffer;
@@ -1009,20 +1044,7 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
         }
     }
 
-    if( b_adaptation &&
-        (p[5] & 0x10) && p[4]>=7 && pid->p_owner && pid->p_owner->i_pid_pcr == pid->i_pid )
-    {
-        mtime_t i_pcr;  /* 33 bits */
-
-        i_pcr = ( (mtime_t)p[6] << 25 ) |
-                ( (mtime_t)p[7] << 17 ) |
-                ( (mtime_t)p[8] << 9 ) |
-                ( (mtime_t)p[9] << 1 ) |
-                ( (mtime_t)p[10] >> 7 );
-
-        es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR, (int)pid->p_owner->i_number, (int64_t)(i_pcr * 100 / 9) );
-    }
-
+    PCRHandle( p_demux, pid, p_bk );
 
     if( i_skip >= 188 || pid->es->id == NULL || p_demux->p_sys->b_udp_out )
     {
@@ -1126,6 +1148,9 @@ static int PIDFillFormat( ts_pid_t *pid, int i_stream_type )
             break;
     }
 
+    /* PES packets usually contain truncated frames */
+    fmt->b_packetized = VLC_FALSE;
+
     return fmt->i_cat == UNKNOWN_ES ? VLC_EGENERIC : VLC_SUCCESS ;
 }
 
@@ -1545,10 +1570,14 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
         if( p_dr->i_tag == 0x1d )
         {
             /* We have found an IOD descriptor */
-            msg_Warn( p_demux, "found IOD descriptor" );
+            msg_Warn( p_demux, " * descriptor : IOD (0x1d)" );
 
             pmt->psi->iod = IODNew( p_dr->i_length, p_dr->p_data );
         }
+        else
+        {
+            msg_Dbg( p_demux, " * descriptor : unknown (0x%x)", p_dr->i_tag );
+        }
     }
 
     for( p_es = p_pmt->p_first_es; p_es != NULL; p_es = p_es->p_next )
@@ -1673,6 +1702,9 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
 
             for( p_dr = p_es->p_first_descriptor; p_dr != NULL; p_dr = p_dr->p_next )
             {
+                msg_Dbg( p_demux, "  * es pid=0x%x type=0x%x dr->i_tag=0x%x",
+                         p_es->i_pid, p_es->i_type, p_dr->i_tag );
+
                 if( p_dr->i_tag == 0x6a )
                 {
                     pid->es->fmt.i_cat = AUDIO_ES;
@@ -1761,13 +1793,15 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat )
 
     msg_Dbg( p_demux, "PATCallBack called" );
 
-    if( pat->psi->i_version != -1 && ( !p_pat->b_current_next || p_pat->i_version == pat->psi->i_version ) )
+    if( pat->psi->i_version != -1 &&
+        ( !p_pat->b_current_next || p_pat->i_version == pat->psi->i_version ) )
     {
         dvbpsi_DeletePAT( p_pat );
         return;
     }
 
-    msg_Dbg( p_demux, "new PAT ts_id=0x%x version=%d current_next=%d", p_pat->i_ts_id, p_pat->i_version, p_pat->b_current_next );
+    msg_Dbg( p_demux, "new PAT ts_id=0x%x version=%d current_next=%d",
+             p_pat->i_ts_id, p_pat->i_version, p_pat->b_current_next );
 
     /* Clean old */
     for( i = 2; i < 8192; i++ )
@@ -1784,7 +1818,8 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat )
                     TAB_REMOVE( p_sys->i_pmt, p_sys->pmt, pid );
                 }
             }
-            else if( pid->p_owner && pid->p_owner->i_number != 0 && pid->es->id )
+            else if( pid->p_owner && pid->p_owner->i_number != 0 &&
+                     pid->es->id )
             {
                 /* We only remove es that aren't defined by extra pmt */
                 PIDClean( p_demux->out, pid );
@@ -1793,15 +1828,19 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat )
     }
 
     /* now create programs */
-    for( p_program = p_pat->p_first_program; p_program != NULL; p_program = p_program->p_next )
+    for( p_program = p_pat->p_first_program; p_program != NULL;
+         p_program = p_program->p_next )
     {
-        msg_Dbg( p_demux, "  * number=%d pid=0x%x", p_program->i_number, p_program->i_pid );
+        msg_Dbg( p_demux, "  * number=%d pid=0x%x", p_program->i_number,
+                 p_program->i_pid );
         if( p_program->i_number != 0 )
         {
             ts_pid_t *pmt = &p_sys->pid[p_program->i_pid];
 
             PIDInit( pmt, VLC_TRUE, pat->psi );
-            pmt->psi->handle = dvbpsi_AttachPMT( p_program->i_number, (dvbpsi_pmt_callback)PMTCallBack, p_demux );
+            pmt->psi->handle =
+                dvbpsi_AttachPMT( p_program->i_number,
+                                  (dvbpsi_pmt_callback)PMTCallBack, p_demux );
             pmt->psi->i_number = p_program->i_number;
 
             TAB_APPEND( p_sys->i_pmt, p_sys->pmt, pmt );
@@ -1811,4 +1850,3 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat )
 
     dvbpsi_DeletePAT( p_pat );
 }
-