[dvblast-devel] Add per output PID remapping.

Peter Nenowski git at videolan.org
Mon Jan 21 07:46:52 CET 2013


dvblast | branch: master | Peter Nenowski <developer.wine at gmail.com> | Mon Jan 21 08:43:13 2013 +0200| [e7daf50da9be8293c357d6425e59b192d7340674] | committer: Georgi Chorbadzhiyski

Add per output PID remapping.

This commit adds per output setting for PID remapping.

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

 NEWS      |    3 ++-
 README    |    7 +++++++
 demux.c   |   39 ++++++++++++++++++++++++++++++---------
 dvblast.c |   24 ++++++++++++++++++++++++
 dvblast.h |    8 ++++++++
 output.c  |   12 ++++++++++--
 6 files changed, 81 insertions(+), 12 deletions(-)

diff --git a/NEWS b/NEWS
index d513e13..eb5ea32 100644
--- a/NEWS
+++ b/NEWS
@@ -5,7 +5,8 @@ Changes between 2.2 and 2.3:
   * Added support for uncommitted diseqc switches.
   * Fixed ECM pid selection.
   * Added CA device addressing.
-  * Added support for remapping ES pids to fixed values.
+  * Added support for remapping ES pids to fixed values
+    globally and per output.
   * Added support for multi-delivery system frontends.
   * Added support for multistream that appeared in Linux 3.6
 
diff --git a/README b/README
index cda01aa..ffa8d4f 100644
--- a/README
+++ b/README
@@ -146,6 +146,7 @@ Available options include :
  /mtu=XXXX (sets the maximum UDP packet size)
  /srvname=Some_Channel (set service name in SDT)
  /srvprovider=Some_Provider (set provider name in SDT)
+ /pidmap=pmt_pid,audio_pid,video_pid,spu_pid
 
 When setting text options like /srvname or /srvprovider, remember
 that the underscore character (_) will be replaced by space ( ).
@@ -191,6 +192,12 @@ DVBlast will only stream the PIDs passed. No PAT and PMT will be generated,
 so if they are not included the stream won't be compliant. Also the
 included PAT and PMT may contain ghost programs or ESes.
 
+4. PID remapping
+
+239.255.0.1:1234/udp/epg/tsid=42/ssrc=192.168.0.1/pidmap=pmt_pid,audio_pid,video_pid,spu_pid
+
+All four PIDs are required!
+
 Note that the CAM will not be programmed in that case (unless it has
 been programmed by another line of the config file). The file is read
 from the command-line :
diff --git a/demux.c b/demux.c
index 219c349..667f9ea 100644
--- a/demux.c
+++ b/demux.c
@@ -146,7 +146,7 @@ uint16_t map_es_pid(output_t * p_output, uint16_t i_stream_type, uint16_t i_pid)
 {
     uint16_t i_newpid = i_pid;
 
-    if (! b_do_remap )
+    if (! b_do_remap && !p_output->b_do_remap )
         return i_pid;
 
     switch ( i_stream_type )
@@ -157,25 +157,38 @@ uint16_t map_es_pid(output_t * p_output, uint16_t i_stream_type, uint16_t i_pid)
         case 0x11: /* audio AAC LATM */
         case 0x81: /* ATSC AC-3 */
         case 0x87: /* ATSC Enhanced AC-3 */
-            i_newpid = pi_newpids[I_APID];
+            if ( b_do_remap )
+                i_newpid = pi_newpids[I_APID];
+            else
+                i_newpid = p_output->pi_confpids[I_APID];
             break;
         case 0x01: /* video MPEG-1 */
         case 0x02: /* video */
         case 0x10: /* video MPEG-4 */
         case 0x1b: /* video H264 */
-            i_newpid = pi_newpids[I_VPID];
+            if ( b_do_remap )
+                i_newpid = pi_newpids[I_VPID];
+            else
+                i_newpid = p_output->pi_confpids[I_VPID];
             break;
         case 0x06: /* Subtitles */
-            i_newpid = pi_newpids[I_SPUPID];
+            if ( b_do_remap )
+                i_newpid = pi_newpids[I_SPUPID];
+            else
+                i_newpid = p_output->pi_confpids[I_SPUPID];
             break;
     }
     /* Got the new base for the mapped pid. Find the next free one
        we do this to ensure that multiple audios get unique pids */
-    while (p_output->pi_freepids[i_newpid] != UNUSED_PID)
-        i_newpid++;
-
-    p_output->pi_freepids[i_newpid] = i_pid;  /* Mark as in use */
-    p_output->pi_newpids[i_pid] = i_newpid;   /* Save the new pid */
+    if ( b_do_remap )
+    {
+        while (p_output->pi_freepids[i_newpid] != UNUSED_PID)
+            i_newpid++;
+        p_output->pi_freepids[i_newpid] = i_pid;  /* Mark as in use */
+        p_output->pi_newpids[i_pid] = i_newpid;   /* Save the new pid */
+    } else {
+        p_output->pi_newpids[i_pid] = i_newpid;
+    }
     return i_newpid;
 }
 
@@ -1030,9 +1043,14 @@ static void SendPMT( sid_t *p_sid, mtime_t i_dts )
         if ( (p_output->config.i_config & OUTPUT_VALID)
                && p_output->config.i_sid == p_sid->i_sid
                && p_output->p_pmt_section != NULL )
+        {
+            if ( p_output->b_do_remap )
+                i_pmt_pid = p_output->pi_confpids[I_PMTPID];
+
             OutputPSISection( p_output, p_output->p_pmt_section,
                               i_pmt_pid, &p_output->i_pmt_cc, i_dts,
                               NULL, NULL );
+        }
     }
 }
 
@@ -1199,6 +1217,9 @@ static void NewPAT( output_t *p_output )
     {
         msg_Dbg( NULL, "Mapping PMT PID %d to %d\n", patn_get_pid( p_program ), pi_newpids[I_PMTPID] );
         patn_set_pid( p, pi_newpids[I_PMTPID]);
+    } else if ( p_output->b_do_remap ) {
+        msg_Dbg( NULL, "Mapping PMT PID %d to %d\n", patn_get_pid( p_program ), p_output->pi_confpids[I_PMTPID] );
+        patn_set_pid( p, p_output->pi_confpids[I_PMTPID]);
     } else {
         patn_set_pid( p, patn_get_pid( p_program ) );
     }
diff --git a/dvblast.c b/dvblast.c
index 3c2bee4..f68cbd6 100644
--- a/dvblast.c
+++ b/dvblast.c
@@ -144,6 +144,11 @@ void config_Init( output_config_t *p_config )
     p_config->i_if_index_v6 = -1;
 
     p_config->pi_pids = NULL;
+    p_config->b_do_remap = false;
+    unsigned int i;
+    for ( i = 0; i < N_MAP_PIDS; i++ ) {
+        p_config->pi_confpids[i]  = UNUSED_PID;
+    }
 }
 
 void config_Free( output_config_t *p_config )
@@ -260,6 +265,25 @@ bool config_ParseHost( output_config_t *p_config, char *psz_string )
             in_addr_t i_addr = inet_addr( ARG_OPTION("ssrc=") );
             memcpy( p_config->pi_ssrc, &i_addr, 4 * sizeof(uint8_t) );
         }
+        else if ( IS_OPTION("pidmap=") )
+        {
+            char *str1;
+            char *saveptr = NULL;
+            char *tok = NULL;
+            int i, i_newpid;
+            for (i = 0, str1 = config_stropt( (ARG_OPTION("pidmap="))); i < N_MAP_PIDS; i++, str1 = NULL)
+            {
+                tok = strtok_r(str1, ",", &saveptr);
+                if ( !tok )
+                    break;
+                i_newpid = strtoul(tok, NULL, 0);
+                if ( !i_newpid ) {
+                     msg_Warn( NULL, "Invalid output pidmap setting" );
+                }
+                p_config->pi_confpids[i] = i_newpid;
+            }
+            p_config->b_do_remap = true;
+        }
         else
             msg_Warn( NULL, "unrecognized option %s", psz_string );
 
diff --git a/dvblast.h b/dvblast.h
index 7026ab8..20c4dde 100644
--- a/dvblast.h
+++ b/dvblast.h
@@ -96,6 +96,10 @@ typedef struct output_config_t
     uint16_t i_sid; /* 0 if raw mode */
     uint16_t *pi_pids;
     int i_nb_pids;
+
+    /* for pidmap from config file */
+    bool b_do_remap;
+    uint16_t pi_confpids[N_MAP_PIDS];
 } output_config_t;
 
 typedef struct output_t
@@ -127,6 +131,10 @@ typedef struct output_t
     // newpids is indexed using the original pid
     uint16_t pi_newpids[MAX_PIDS];
     uint16_t pi_freepids[MAX_PIDS];   // used where multiple streams of the same type are used
+
+    /* For pidmap from config file */
+    bool b_do_remap;
+    uint16_t pi_confpids[N_MAP_PIDS];
 } output_t;
 
 typedef struct ts_pid_info {
diff --git a/output.c b/output.c
index a80434e..f50bc6b 100644
--- a/output.c
+++ b/output.c
@@ -146,6 +146,7 @@ int output_Init( output_t *p_output, const output_config_t *p_config )
         p_output->i_tsid = rand() & 0xffff;
 
     /* Init the mapped pids to unused */
+    p_output->b_do_remap = p_config->b_do_remap;
     init_pid_mapping( p_output );
 
     /* Init socket-related fields */
@@ -291,7 +292,7 @@ static void output_Flush( output_t *p_output )
          * set the pid to the new pid
          * later we re-instate the old pid for the next output
          */
-        if ( b_do_remap ) {
+        if ( b_do_remap || p_output->b_do_remap ) {
             block_t *p_block = p_packet->pp_blocks[i_block];
             uint16_t i_pid = ts_get_pid( p_block->p_ts );
             p_block->tmp_pid = UNUSED_PID;
@@ -329,7 +330,7 @@ static void output_Flush( output_t *p_output )
         p_packet->pp_blocks[i_block]->i_refcount--;
         if ( !p_packet->pp_blocks[i_block]->i_refcount )
             block_Delete( p_packet->pp_blocks[i_block] );
-        else if ( b_do_remap ) {
+        else if ( b_do_remap || p_output->b_do_remap ) {
             /* still referenced so re-instate the orignial pid if remapped */
             block_t * p_block = p_packet->pp_blocks[i_block];
             if (p_block->tmp_pid != UNUSED_PID)
@@ -513,6 +514,13 @@ void output_Change( output_t *p_output, const output_config_t *p_config )
             p_packet->pp_blocks = &p_packet->p_blocks;
         }
     }
+    if ( p_config->b_do_remap )
+    {
+        p_output->pi_confpids[I_PMTPID] = p_config->pi_confpids[I_PMTPID];
+        p_output->pi_confpids[I_APID]   = p_config->pi_confpids[I_APID];
+        p_output->pi_confpids[I_VPID]   = p_config->pi_confpids[I_VPID];
+        p_output->pi_confpids[I_SPUPID] = p_config->pi_confpids[I_SPUPID];
+    }
 }
 
 /*****************************************************************************



More information about the dvblast-devel mailing list