<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    On 02/12/2011 13:12, Georgi Chorbadzhiyski wrote:
    <blockquote cite="mid:4ED8CEC6.9020107@unixsol.org" type="cite">
      <pre wrap="">Around 12/02/2011 02:25 PM, Peter Martin scribbled:
</pre>
      <blockquote type="cite">
        <pre wrap="">Here is a patch I am using to allow me to remap ES pids to fixed values. This is 
needed by some legacy IP STBs which don't understand how to use PMTs. The 
command line flag -k is followed by four pids, which map the PMT, Audio, Video 
and Spu pids respectively. It has been designed to impose a minimal overhead and 
supports transponders which share pids between different programmes and 
programmes with multiple audio or spu pids.

This diff has been prepared against the latest git version.
</pre>
      </blockquote>
      <pre wrap="">
Please send it as attachment create by git format-patch because currently it is
unusable.</pre>
    </blockquote>
    Georgi, thanks for the feedback. I have taken on board your comments
    below and created the patch as a git patch as requested. I've had to
    gzip it to get it past my emailer. Any other changes let me know.<br>
    <br>
    Pete<br>
    <blockquote cite="mid:4ED8CEC6.9020107@unixsol.org" type="cite">
      <pre wrap="">

Partial review bellow.

- Missing man page text describing the parameter and possibly example uses
  so we test the patch.
- Missing NEWS entry.

</pre>
      <blockquote type="cite">
        <pre wrap="">diff -Naur dvblast.orig/demux.c dvblast/demux.c
--- dvblast.orig/demux.c 2011-12-02 11:08:22.000000000 +0000
+++ dvblast/demux.c 2011-12-02 11:26:50.000000000 +0000
@@ -135,6 +135,50 @@
static void HandlePSIPacket( uint8_t *p_ts, mtime_t i_dts );
static const char *get_pid_desc(uint16_t i_pid, uint16_t *i_sid);

+/*
+ * Remap an ES pid to a fixed value.
+ * Multiple streams of the same type use sequential pids
+ * Returns the new pid and updates the map tables
+*/
+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(!i_do_remap) {
+ return i_pid;
+ }
</pre>
      </blockquote>
      <pre wrap="">
Braces are unneeded. Shouldn't do_remap be boolean?

</pre>
      <blockquote type="cite">
        <pre wrap="">+ switch (i_stream_type) {
+ case 0x3: /* audio MPEG-1 */
+ case 0x4: /* audio */
+ case 0xf: /* audio AAC ADTS */
+ case 0x11: /* audio AAC LATM */
+ case 0x81: /* ATSC AC-3 */
+ case 0x87: /* ATSC Enhanced AC-3 */
+ i_newpid = pi_newpids[I_APID];
+ break;
+ case 0x1: /* video MPEG-1 */
+ case 0x2: /* video */
+ case 0x10: /* video MPEG-4 */
+ case 0x1b: /* video H264 */
+ i_newpid = pi_newpids[I_VPID];
+ break;
+ case 0x06: /* Subtitles */
+ i_newpid = pi_newpids[I_SPUPID];
+ break;
+ default:
+ break;
+ }
</pre>
      </blockquote>
      <pre wrap="">
The default is unneeded.

</pre>
      <blockquote type="cite">
        <pre wrap="">+ /* 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(UNUSED_PID != p_output->pi_freepids[i_newpid]) {
+ i_newpid++;
+ }
</pre>
      </blockquote>
      <pre wrap="">
Please use while(p_output->pi_freepids[i_newpid] != UNUSED_PID)
I know it is the same but parsing it backwards hurts my head :)

</pre>
      <blockquote type="cite">
        <pre wrap="">+ p_output->pi_freepids[i_newpid] = i_pid; /* Mark as in use */
+ p_output->pi_newpids[i_pid] = i_newpid; /* Save the new pid */
+ return i_newpid;
+}
+
/*****************************************************************************
* demux_Open
*****************************************************************************/
@@ -986,6 +1030,11 @@
static void SendPMT( sid_t *p_sid, mtime_t i_dts )
{
int i;
+ int i_pmtpid = p_sid->i_pmt_pid;
+ if ( i_do_remap )
+ {
+ i_pmtpid = pi_newpids[I_PMTPID];
+ }
</pre>
      </blockquote>
      <pre wrap="">
Braces... i_pmt_pid please, not i_pmtpid.

</pre>
      <blockquote type="cite">
        <pre wrap="">for ( i = 0; i < i_nb_outputs; i++ )
{
@@ -995,7 +1044,7 @@
&& p_output->config.i_sid == p_sid->i_sid
&& p_output->p_pmt_section != NULL )
OutputPSISection( p_output, p_output->p_pmt_section,
- p_sid->i_pmt_pid, &p_output->i_pmt_cc, i_dts,
+ i_pmtpid, &p_output->i_pmt_cc, i_dts,
NULL, NULL );
}
}
@@ -1144,7 +1193,15 @@
p = pat_get_program( p_output->p_pat_section, k++ );
patn_init( p );
patn_set_program( p, p_output->config.i_sid );
- patn_set_pid( p, patn_get_pid( p_program ) );
+ if( i_do_remap)
+ {
+ 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
+ {
+ patn_set_pid( p, patn_get_pid( p_program ) );
+ }

p = pat_get_program( p_output->p_pat_section, k );
pat_set_length( p_output->p_pat_section,
@@ -1193,6 +1250,7 @@
uint8_t *p;
int i;
uint16_t j, k;
+ uint16_t i_pcrpid;

free( p_output->p_pmt_section );
p_output->p_pmt_section = NULL;
@@ -1215,8 +1273,9 @@
pmt_set_program( p, p_output->config.i_sid );
psi_set_version( p, p_output->i_pmt_version );
psi_set_current( p );
- pmt_set_pcrpid( p, pmt_get_pcrpid( p_current_pmt ) );
pmt_set_desclength( p, 0 );
+ init_Mapping(p_output);
+
</pre>
      </blockquote>
      <pre wrap="">
Where does pmt_set_pcrpid() go?

</pre>
      <blockquote type="cite">
        <pre wrap="">CopyDescriptors( pmt_get_descs( p ), pmt_get_descs( p_current_pmt ) );

@@ -1236,13 +1295,20 @@
k++;
pmtn_init( p_es );
pmtn_set_streamtype( p_es, pmtn_get_streamtype( p_current_es ) );
- pmtn_set_pid( p_es, i_pid );
+ pmtn_set_pid( p_es, map_es_pid(p_output, pmtn_get_streamtype( p_current_es ), 
i_pid) );
pmtn_set_desclength( p_es, 0 );

CopyDescriptors( pmtn_get_descs( p_es ),
pmtn_get_descs( p_current_es ) );
}

+ /* Do the pcr pid after everything else as it may have been remapped */
+ i_pcrpid = pmt_get_pcrpid( p_current_pmt );
+ if(UNUSED_PID != p_output->pi_newpids[i_pcrpid]) {
</pre>
      </blockquote>
      <pre wrap="">
Variable order.

</pre>
      <blockquote type="cite">
        <pre wrap="">+ printf("Mapping pcrpid from 0x%x to 0x%x\n", i_pcrpid, 
p_output->pi_newpids[i_pcrpid]);
</pre>
      </blockquote>
      <pre wrap="">
No printfs please. msg_Dbg ot something.

</pre>
      <blockquote type="cite">
        <pre wrap="">+ i_pcrpid = p_output->pi_newpids[i_pcrpid];
+ }
+ pmt_set_pcrpid( p, i_pcrpid );
p_es = pmt_get_es( p, k );
if ( p_es == NULL )
/* This shouldn't happen if the incoming PMT is valid */
diff -Naur dvblast.orig/dvblast.c dvblast/dvblast.c
--- dvblast.orig/dvblast.c 2011-12-02 11:08:22.000000000 +0000
+++ dvblast/dvblast.c 2011-12-02 11:34:48.000000000 +0000
@@ -114,6 +114,12 @@
/* TPS Input log filename */
char * psz_mrtg_file = NULL;

+/* TPS pidmapping */
</pre>
      </blockquote>
      <pre wrap="">
What is TPS?

</pre>
      <blockquote type="cite">
        <pre wrap="">+int i_do_remap = 0;
</pre>
      </blockquote>
      <pre wrap="">
Boolean;

</pre>
      <blockquote type="cite">
        <pre wrap="">+uint16_t pi_newpids[N_MAP_PIDS]; /* pmt, audio, video, spu */
+void init_Mapping( output_t *) ;
+
+
void (*pf_Open)( void ) = NULL;
block_t * (*pf_Read)( mtime_t i_poll_timeout ) = NULL;
void (*pf_Reset)( void ) = NULL;
@@ -597,10 +603,11 @@
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ "mrtg-file", required_argument, NULL, 'Z' },
+ { "pidmap", required_argument, NULL, 'k' },
{ 0, 0, 0, 0 }
};

- while ( (c = getopt_long(i_argc, pp_argv, 
"q::c:r:t:o:i:a:n:f:F:R:s:S:v:pb:I:m:P:K:G:H:X:O:uwUTL:E:d:D:A:lg:zCWYeM:N:j:J:B:x:Q:hVZ:", 
long_options, NULL)) != -1 )
+ while ( (c = getopt_long(i_argc, pp_argv, 
"q::c:r:t:o:i:a:n:f:F:R:s:S:v:pb:I:m:P:K:G:H:X:O:uwUTL:E:d:D:A:lg:zCWYeM:N:j:J:B:x:Q:hVZ:k:", 
long_options, NULL)) != -1 )
{
switch ( c )
{
@@ -853,6 +860,29 @@
psz_mrtg_file = optarg;
break;

+ case 'k':
+ {
+ /* We expect a comma separated list of numbers.
+ Put them into the pi_newpids array as they appear */
+ char * str1;
+ char * saveptr = NULL;
+ char * tok = NULL;
+ int i, i_newpid;
+ for(i = 0, str1 = optarg; i < N_MAP_PIDS; i++, str1 = NULL)
+ {
+ tok = strtok_r(str1, ",", &saveptr);
+ if(tok == NULL)
+ break;
+ i_newpid = strtoul(tok, NULL, 0);
+ if(0 == i_newpid) {
+ msg_Err( NULL, "Invalid map pid string" );
</pre>
      </blockquote>
      <pre wrap="">
pidmap, map pid, choose one :)

</pre>
      <blockquote type="cite">
        <pre wrap="">+ usage();
+ }
+ pi_newpids[i] = i_newpid;
+ }
+ i_do_remap = 1;
+ }
+ break;
case 'h':
default:
usage();
diff -Naur dvblast.orig/dvblast.h dvblast/dvblast.h
--- dvblast.orig/dvblast.h 2011-12-02 11:08:22.000000000 +0000
+++ dvblast/dvblast.h 2011-12-02 11:32:23.000000000 +0000
@@ -43,6 +43,17 @@
#define DEFAULT_FRONTEND_TIMEOUT 30000000 /* 30 s */
#define EXIT_STATUS_FRONTEND_TIMEOUT 100

+/* Defines for pid mapping */
+#define N_MAP_PIDS 4
+/* Offsets in the command line args for the pid mapping */
+#define I_PMTPID 0
+#define I_APID 1
+#define I_VPID 2
+#define I_SPUPID 3
</pre>
      </blockquote>
      <pre wrap="">
Make it an enum.

</pre>
      <blockquote type="cite">
        <pre wrap="">+/* Impossible PID value */
+#define UNUSED_PID (MAX_PIDS + 1)
+
+
/*****************************************************************************
* Output configuration flags (for output_t -> i_config) - bit values
* Bit 0 : Set for watch mode
@@ -73,6 +84,7 @@
uint8_t p_ts[TS_SIZE];
int i_refcount;
mtime_t i_dts;
+ uint16_t tmp_pid;
struct block_t *p_next;
} block_t;

@@ -131,6 +143,10 @@
block_t *p_eit_ts_buffer;
uint8_t i_eit_ts_buffer_offset, i_eit_cc;
uint16_t i_tsid;
+ // Arrays used for mapping pids.
+ // 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
} output_t;

typedef struct ts_pid_info {
@@ -191,6 +207,11 @@
extern const char *psz_dvb_charset;
extern enum print_type_t i_print_type;

+/* TPS pid mapping */
+extern int i_do_remap;
+extern uint16_t pi_newpids[N_MAP_PIDS];
+void init_Mapping(output_t *);
+
extern void (*pf_Open)( void );
extern block_t * (*pf_Read)( mtime_t i_poll_timeout );
extern void (*pf_Reset)( void );
diff -Naur dvblast.orig/output.c dvblast/output.c
--- dvblast.orig/output.c 2011-12-02 11:08:22.000000000 +0000
+++ dvblast/output.c 2011-12-02 11:34:04.000000000 +0000
@@ -103,6 +103,16 @@
return p_output;
}

+/* Init the mapped pids to unused */
+void init_Mapping( output_t * p_output)
+{
+ unsigned int i;
+ for(i = 0; i< MAX_PIDS; i++) {
+ p_output->pi_newpids[i] = UNUSED_PID;
+ p_output->pi_freepids[i] = UNUSED_PID;
</pre>
      </blockquote>
      <pre wrap="">
memset ?

</pre>
      <blockquote type="cite">
        <pre wrap="">+ }
+}
+
/*****************************************************************************
* output_Init : set up the output initial config
*****************************************************************************/
@@ -135,6 +145,9 @@
if ( b_random_tsid )
p_output->i_tsid = rand() & 0xffff;

+ /* Init the mapped pids to unused */
+ init_Mapping(p_output);
+
/* Init socket-related fields */
p_output->config.i_family = p_config->i_family;
memcpy( &p_output->config.connect_addr, &p_config->connect_addr,
@@ -273,6 +286,26 @@

for ( i_block = 0; i_block < p_packet->i_depth; i_block++ )
{
+ /* Do pid mapping here if needed.
+ * save the original pid in the block.
+ * set the pid to the new pid
+ * later we re-instate the old pid for the next output
+ */
+ if(i_do_remap) {
+ block_t * p_block = p_packet->pp_blocks[i_block];
+ uint16_t i_pid = (p_block->p_ts[1] & 0x1f) << 8 | p_block->p_ts[2];
+ p_block->tmp_pid = UNUSED_PID;
+ if(UNUSED_PID != p_output->pi_newpids[i_pid])
+ {
+ uint16_t i_newpid = p_output->pi_newpids[i_pid];
+ /* Need to map this pid to the new pid */
+ p_block->p_ts[1] &= 0xe0;
+ p_block->p_ts[1] |= ((i_newpid >> 8) & 0x1f);
+ p_block->p_ts[2] = i_newpid & 0xff;
+ p_block->tmp_pid = i_pid;
</pre>
      </blockquote>
      <pre wrap="">
Use ts_set_pid()

</pre>
      <blockquote type="cite">
        <pre wrap="">+ }
+ }
+
p_iov[i_iov].iov_base = p_packet->pp_blocks[i_block]->p_ts;
p_iov[i_iov].iov_len = TS_SIZE;
i_iov++;
@@ -298,6 +331,15 @@
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(i_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) {
+ p_block->p_ts[1] &= 0xe0;
+ p_block->p_ts[1] |= ((p_block->tmp_pid >> 8) & 0x1f);
+ p_block->p_ts[2] = p_block->tmp_pid & 0xff;
</pre>
      </blockquote>
      <pre wrap="">
Use ts_set_pid()

</pre>
      <blockquote type="cite">
        <pre wrap="">+ }
+ }
}
p_output->p_packets = p_packet->p_next;
free( p_packet );
</pre>
      </blockquote>
      <pre wrap="">
</pre>
    </blockquote>
    <br>
    <br>
    <div class="moz-signature">-- <br>
      <meta http-equiv="Content-Type" content="text/html;
        charset=ISO-8859-1">
      <title>Tripleplay Signature - Poole</title>
      <font style="candara"> <br>
        <font size="2">Best Regards,</font><br>
        <br>
        <b>Dr. Peter Martin</b><br>
        <font color="#404041" size="2">Chief Technical Officer</font><br>
        <br>
        Tripleplay Services Ltd<br>
        <br>
        Tel: +44 (0) 845 643 2057</font><br>
      Support: +44 (0) 845 094 3357<br>
      Mobile: +44 (0) 7810 876713<br>
      Mail: <a href="mailto:peter.martin@tripleplay-services.com">peter.martin@tripleplay-services.com</a><br>
      WWW: <a href="http://www.tripleplay-services.com">http://www.tripleplay-services.com</a><br>
      <br>
      <b><font color="#404041" size="2">Tripleplay Services Ltd.</font></b><br>
      <font color="#404041" size="2">Unit 3, Concept Park, Yarrow Road,
        POOLE, DORSET, BH12 4QT</font><br>
      <br>
      <i><font color="#404041" size="2">This message is for the
          designated recipient only and may contain privileged,
          proprietary, or otherwise private information. If you have
          received it in error, please notify the sender immediately and
          delete the original. Any review, retransmission, dissemination
          or other use of, or taking of any action in reliance upon,
          this information by persons or entities other than the
          intended recipient is prohibited </font></i><br>
      <br>
      <i><font color="#404041" size="2">Tripleplay Services Limited is a
          private limited liability company in England and Wales, whose
          registered office is Cromwell House, 14 Fulwood Place, London,
          WC1V 6HZ. Registered in England, number 4338092.</font></i>
    </div>
  </body>
</html>