[vlc-devel] commit: Fixed and improved ts-extra-pmt option (close #1592). ( Laurent Aimar )

git version control git at videolan.org
Fri Jul 4 22:46:31 CEST 2008


vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Fri Jul  4 20:22:06 2008 +0000| [d0dd8179b650055dcdf4b095c5690427a767fa2e]

Fixed and improved ts-extra-pmt option (close #1592).
If you specify and extra pmt, the parsing of the PAT will be disabled
(unlike previous behaviour).
You can now just specify the pid and number of your program and it will
automatically be used.
You can specify es by type (video, audio, spu) and fourcc instead of
stream type.
You can specify the pcr pid.

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

 modules/demux/ts.c |  127 ++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 89 insertions(+), 38 deletions(-)

diff --git a/modules/demux/ts.c b/modules/demux/ts.c
index 8aebbfb..3ca1295 100644
--- a/modules/demux/ts.c
+++ b/modules/demux/ts.c
@@ -98,6 +98,15 @@ static int ChangeKeyCallback    ( vlc_object_t *, char const *, vlc_value_t, vlc
 static int  Open  ( vlc_object_t * );
 static void Close ( vlc_object_t * );
 
+/* TODO
+ * - Rename "extra pmt" to "user pmt"
+ * - Update extra pmt description
+ *      pmt_pid[:pmt_number]=pid_description[,pid_description]
+ *      where pid_description could take 3 forms:
+ *          1. pid:pcr (to force the pcr pid)
+ *          2. pid:stream_type
+ *          3. pid:type:fourcc where type=(video|audio|spu)
+ */
 #define PMT_TEXT N_("Extra PMT")
 #define PMT_LONGTEXT N_( \
   "Allows a user to specify an extra pmt (pmt_pid=pid:stream_type[,...])." )
@@ -333,6 +342,7 @@ struct demux_sys_t
     ts_pid_t    pid[8192];
 
     /* All PMT */
+    bool        b_user_pmt;
     int         i_pmt;
     ts_pid_t    **pmt;
 
@@ -389,6 +399,7 @@ 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 * );
 
+#define TS_USER_PMT_NUMBER (0)
 static int UserPmt( demux_t *p_demux, const char * );
 
 #define TS_PACKET_SIZE_188 188
@@ -713,7 +724,8 @@ static int Open( vlc_object_t *p_this )
     /* We handle description of an extra PMT */
     var_Create( p_demux, "ts-extra-pmt", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
     var_Get( p_demux, "ts-extra-pmt", &val );
-    if( val.psz_string && strchr( val.psz_string, '=' ) != NULL )
+    p_sys->b_user_pmt = false;
+    if( val.psz_string && *val.psz_string )
         UserPmt( p_demux, val.psz_string );
     free( val.psz_string );
 
@@ -1390,18 +1402,26 @@ static int UserPmt( demux_t *p_demux, const char *psz_fmt )
     char *psz_dup = strdup( psz_fmt );
     char *psz = psz_dup;
     int  i_pid;
+    int  i_number;
 
     if( !psz_dup )
         return VLC_ENOMEM;
 
+    /* Parse PID */
     i_pid = strtol( psz, &psz, 0 );
     if( i_pid < 2 || i_pid >= 8192 )
         goto error;
 
+    /* Parse optional program number */
+    i_number = 0;
+    if( *psz == ':' )
+        i_number = strtol( &psz[1], &psz, 0 );
+
+    /* */
     ts_pid_t *pmt = &p_sys->pid[i_pid];
     ts_prg_psi_t *prg;
 
-    msg_Dbg( p_demux, "extra pmt specified (pid=%d)", i_pid );
+    msg_Dbg( p_demux, "user pmt specified (pid=%d,number=%d)", i_pid, i_number );
     PIDInit( pmt, true, NULL );
 
     /* Dummy PMT */
@@ -1412,53 +1432,84 @@ static int UserPmt( demux_t *p_demux, const char *psz_fmt )
     memset( prg, 0, sizeof( ts_prg_psi_t ) );
     prg->i_pid_pcr  = -1;
     prg->i_pid_pmt  = -1;
-    prg->i_number   = 0;    /* special */
-    prg->handle     = dvbpsi_AttachPMT( 1, (dvbpsi_pmt_callback)PMTCallBack, p_demux );
+    prg->i_version  = -1;
+    prg->i_number   = i_number != 0 ? i_number : TS_USER_PMT_NUMBER;
+    prg->handle     = dvbpsi_AttachPMT( i_number != TS_USER_PMT_NUMBER ? i_number : 1, (dvbpsi_pmt_callback)PMTCallBack, p_demux );
     TAB_APPEND( pmt->psi->i_prg, pmt->psi->prg, prg );
 
-    psz = strchr( psz, '=' ) + 1;   /* can't failed */
+    psz = strchr( psz, '=' );
+    if( psz )
+        psz++;
     while( psz && *psz )
     {
         char *psz_next = strchr( psz, ',' );
-        int i_pid, i_stream_type;
+        int i_pid;
 
         if( psz_next )
-        {
             *psz_next++ = '\0';
-        }
 
         i_pid = strtol( psz, &psz, 0 );
-        if( *psz == ':' )
+        if( *psz != ':' || i_pid < 2 || i_pid >= 8192 )
+            goto next;
+
+        char *psz_opt = &psz[1];
+        if( !strcmp( psz_opt, "pcr" ) )
         {
-            i_stream_type = strtol( psz + 1, &psz, 0 );
-            if( i_pid >= 2 && i_pid < 8192 &&
-                !p_sys->pid[i_pid].b_valid )
+            prg->i_pid_pcr = i_pid;
+        }
+        else if( !p_sys->pid[i_pid].b_valid )
+        {
+            ts_pid_t *pid = &p_sys->pid[i_pid];
+
+            char *psz_arg = strchr( psz_opt, '=' );
+            if( psz_arg )
+                *psz_arg++ = '\0';
+
+            PIDInit( pid, false, pmt->psi);
+            if( prg->i_pid_pcr <= 0 )
+                prg->i_pid_pcr = i_pid;
+
+            if( psz_arg && strlen( psz_arg ) == 4 )
             {
-                ts_pid_t *pid = &p_sys->pid[i_pid];
+                const vlc_fourcc_t i_codec = VLC_FOURCC( psz_arg[0], psz_arg[1],
+                                                         psz_arg[2], psz_arg[3] );
+                int i_cat = UNKNOWN_ES;
+                es_format_t *fmt = &pid->es->fmt;
+
+                if( !strcmp( psz_opt, "video" ) )
+                    i_cat = VIDEO_ES;
+                else if( !strcmp( psz_opt, "audio" ) )
+                    i_cat = AUDIO_ES;
+                else if( !strcmp( psz_opt, "spu" ) )
+                    i_cat = SPU_ES;
+
+                es_format_Init( fmt, i_cat, i_codec );
+                fmt->b_packetized = false;
+            }
+            else
+            {
+                const int i_stream_type = strtol( psz_opt, NULL, 0 );
+                PIDFillFormat( pid, i_stream_type );
+            }
+            pid->es->fmt.i_group = i_number;
+            if( p_sys->b_es_id_pid )
+                pid->es->fmt.i_id = i_pid;
 
-                PIDInit( pid, false, pmt->psi);
-                if( pmt->psi->prg[0]->i_pid_pcr <= 0 )
-                {
-                    pmt->psi->prg[0]->i_pid_pcr = i_pid;
-                }
-                PIDFillFormat( pid, i_stream_type);
-                if( pid->es->fmt.i_cat != UNKNOWN_ES )
-                {
-                    if( p_sys->b_es_id_pid )
-                    {
-                        pid->es->fmt.i_id = i_pid;
-                    }
-                    msg_Dbg( p_demux, "  * es pid=%d type=%d "
-                             "fcc=%4.4s", i_pid, i_stream_type,
-                             (char*)&pid->es->fmt.i_codec );
-                    pid->es->id = es_out_Add( p_demux->out,
-                                              &pid->es->fmt );
-                }
+            if( pid->es->fmt.i_cat != UNKNOWN_ES )
+            {
+                msg_Dbg( p_demux, "  * es pid=%d fcc=%4.4s", i_pid,
+                         (char*)&pid->es->fmt.i_codec );
+                pid->es->id = es_out_Add( p_demux->out,
+                                          &pid->es->fmt );
             }
         }
+
+    next:
         psz = psz_next;
     }
 
+    p_sys->b_user_pmt = true;
+    TAB_APPEND( p_sys->i_pmt, p_sys->pmt, pmt );
     free( psz_dup );
     return VLC_SUCCESS;
 
@@ -2977,8 +3028,8 @@ static void PMTCallBack( demux_t *p_demux, dvbpsi_pmt_t *p_pmt )
         int i_prg;
         for( i_prg = 0; i_prg < p_sys->pmt[i]->psi->i_prg; i_prg++ )
         {
-            if( p_sys->pmt[i]->psi->prg[i_prg]->i_number ==
-                p_pmt->i_program_number )
+            const int i_pmt_number = p_sys->pmt[i]->psi->prg[i_prg]->i_number;
+            if( i_pmt_number != TS_USER_PMT_NUMBER && i_pmt_number == p_pmt->i_program_number )
             {
                 pmt = p_sys->pmt[i];
                 prg = p_sys->pmt[i]->psi->prg[i_prg];
@@ -3851,9 +3902,10 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat )
 
     msg_Dbg( p_demux, "PATCallBack called" );
 
-    if( pat->psi->i_pat_version != -1 &&
-        ( !p_pat->b_current_next ||
-          p_pat->i_version == pat->psi->i_pat_version ) )
+    if( ( pat->psi->i_pat_version != -1 &&
+            ( !p_pat->b_current_next ||
+              p_pat->i_version == pat->psi->i_pat_version ) ) ||
+        p_sys->b_user_pmt )
     {
         dvbpsi_DeletePAT( p_pat );
         return;
@@ -3946,8 +3998,7 @@ static void PATCallBack( demux_t *p_demux, dvbpsi_pat_t *p_pat )
             for( i_prg = 0; i_prg < pmt_rm[i]->psi->i_prg; i_prg++ )
             {
                 const int i_number = pmt_rm[i]->psi->prg[i_prg]->i_number;
-                if( i_number != 0 )
-                    es_out_Control( p_demux->out, ES_OUT_DEL_GROUP, i_number );
+                es_out_Control( p_demux->out, ES_OUT_DEL_GROUP, i_number );
             }
 
             PIDClean( p_demux->out, &p_sys->pid[pmt_rm[i]->i_pid] );




More information about the vlc-devel mailing list