<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Georgi <br>
<br>
Thanks for the feedback. Other than the minor formatting points, I
have added some details to do with the mapping itself at the end.<br>
<br>
On 05/12/2011 09:39, Georgi Chorbadzhiyski wrote:
<blockquote cite="mid:4EDC914D.5010500@unixsol.org" type="cite">On
12/2/11 5:36 PM, Peter Martin wrote:
<br>
> Georgi, thanks for the feedback. I have taken on board your
comments below and
<br>
> created the patch as a git patch as requested. I've had to
gzip it to get it
<br>
> past my emailer. Any other changes let me know.
<br>
<br>
Thanks for the attachment. More comments bellow.
<br>
<br>
- You seem to be using tabs with width 8. Replace each tab with 8
spaces.
<br>
- There are a lot of places that introduce white space at the end
of lines,
<br>
please remove it.
<br>
<br>
<blockquote type="cite">From
aaf49a6e4e42dc2bbc730da2d4a91881adaab0df Mon Sep 17 00:00:00
2001
<br>
From: Peter Martin <a class="moz-txt-link-rfc2396E" href="mailto:peter.martin@tripleplay-services.com"><peter.martin@tripleplay-services.com></a>
<br>
Date: Fri, 2 Dec 2011 15:25:49 +0000
<br>
Subject: [PATCH] Add an options to map the ES pids to fixed
values. This is useful when using legacy IP STBs which do not
parse the PMT to obtain the PIDs.
<br>
<br>
---
<br>
NEWS | 3 ++
<br>
demux.c | 70
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
<br>
dvblast.1 | 5 +++-
<br>
dvblast.c | 34 +++++++++++++++++++++++++++-
<br>
dvblast.h | 22 +++++++++++++++++++
<br>
output.c | 37 ++++++++++++++++++++++++++++++++
<br>
6 files changed, 164 insertions(+), 7 deletions(-)
<br>
<br>
diff --git a/NEWS b/NEWS
<br>
index d085f9b..43048a7 100644
<br>
--- a/NEWS
<br>
+++ b/NEWS
<br>
@@ -1,3 +1,6 @@
<br>
+Changes since 2.0:
<br>
+------------------
<br>
+ * Add an option to allow the ES pids to be mapped to fixed
values
<br>
</blockquote>
<br>
We have not released 2.0 yet :) Put he news item on the bottom of
<br>
1.2 -> 2.0 changes.
<br>
<br>
<blockquote type="cite"> Changes between 1.2 and 2.0:
<br>
----------------------------
<br>
diff --git a/demux.c b/demux.c
<br>
index ee0e827..81daaa7 100644
<br>
--- a/demux.c
<br>
+++ b/demux.c
<br>
@@ -135,6 +135,48 @@ static void NewSDT( output_t *p_output );
<br>
static void HandlePSIPacket( uint8_t *p_ts, mtime_t i_dts );
<br>
static const char *get_pid_desc(uint16_t i_pid, uint16_t
*i_sid);
<br>
<br>
+/*
<br>
+ * Remap an ES pid to a fixed value.
<br>
+ * Multiple streams of the same type use sequential pids
<br>
+ * Returns the new pid and updates the map tables
<br>
+*/
<br>
+uint16_t map_es_pid(output_t * p_output, uint16_t
i_stream_type, uint16_t i_pid)
<br>
+{
<br>
+ uint16_t i_newpid = i_pid;
<br>
+
<br>
+ if(! i_do_remap )
<br>
+ return i_pid;
<br>
+
<br>
+ switch (i_stream_type)
<br>
+ {
<br>
+ case 0x3: /* audio MPEG-1 */
<br>
+ case 0x4: /* audio */
<br>
+ case 0xf: /* audio AAC ADTS */
<br>
</blockquote>
<br>
These (and bellow) would be better looking as:
<br>
case 0x03:
<br>
case 0x04:
<br>
<br>
<blockquote type="cite">+ case 0x11: /* audio AAC LATM */
<br>
+ case 0x81: /* ATSC AC-3 */
<br>
+ case 0x87: /* ATSC Enhanced AC-3 */
<br>
+ i_newpid = pi_newpids[I_APID];
<br>
+ break;
<br>
+ case 0x1: /* video MPEG-1 */ <br>
+ case 0x2: /* video */
<br>
+ case 0x10: /* video MPEG-4 */
<br>
+ case 0x1b: /* video H264 */
<br>
+ i_newpid = pi_newpids[I_VPID];
<br>
+ break;
<br>
+ case 0x06: /* Subtitles */
<br>
+ i_newpid = pi_newpids[I_SPUPID];
<br>
+ break;
<br>
+ }
<br>
+ /* Got the new base for the mapped pid. Find the next free
one
<br>
+ we do this to ensure that multiple audios get unique
pids */
<br>
+ while(p_output->pi_freepids[i_newpid] != UNUSED_PID)
<br>
+ i_newpid++;
<br>
+
<br>
+ p_output->pi_freepids[i_newpid] = i_pid; /* Mark as in
use */
<br>
+ p_output->pi_newpids[i_pid] = i_newpid; /* Save the
new pid */
<br>
+ return i_newpid;
<br>
+}
<br>
+
<br>
/*****************************************************************************
<br>
* demux_Open
<br>
*****************************************************************************/<br>
@@ -986,6 +1028,10 @@ static void SendPAT( mtime_t i_dts )
<br>
static void SendPMT( sid_t *p_sid, mtime_t i_dts )
<br>
{
<br>
int i;
<br>
+ int i_pmt_pid = p_sid->i_pmt_pid;
<br>
+
<br>
+ if ( i_do_remap )
<br>
+ i_pmt_pid = pi_newpids[I_PMTPID];
<br>
<br>
for ( i = 0; i < i_nb_outputs; i++ )
<br>
{
<br>
@@ -995,7 +1041,7 @@ static void SendPMT( sid_t *p_sid, mtime_t
i_dts )
<br>
&& p_output->config.i_sid ==
p_sid->i_sid
<br>
&& p_output->p_pmt_section != NULL )
<br>
OutputPSISection( p_output,
p_output->p_pmt_section,
<br>
- p_sid->i_pmt_pid,
&p_output->i_pmt_cc, i_dts,
<br>
+ i_pmt_pid,
&p_output->i_pmt_cc, i_dts,
<br>
NULL, NULL );
<br>
}
<br>
}
<br>
@@ -1144,7 +1190,13 @@ static void NewPAT( output_t *p_output )
<br>
p = pat_get_program( p_output->p_pat_section, k++ );
<br>
patn_init( p );
<br>
patn_set_program( p, p_output->config.i_sid );
<br>
- patn_set_pid( p, patn_get_pid( p_program ) );
<br>
+ if( i_do_remap)
<br>
+ {
<br>
+ msg_Dbg ( NULL, "Mapping PMT PID %d to %d\n",
patn_get_pid( p_program ),
pi_newpids[I_PMTPID]);
<br>
+ patn_set_pid( p, pi_newpids[I_PMTPID]);
<br>
+ }
<br>
+ else
<br>
+ patn_set_pid( p, patn_get_pid( p_program ) );
<br>
<br>
p = pat_get_program( p_output->p_pat_section, k );
<br>
pat_set_length( p_output->p_pat_section,
<br>
@@ -1193,6 +1245,7 @@ static void NewPMT( output_t *p_output )
<br>
uint8_t *p;
<br>
int i;
<br>
uint16_t j, k;
<br>
+ uint16_t i_pcrpid;
<br>
<br>
free( p_output->p_pmt_section );
<br>
p_output->p_pmt_section = NULL;
<br>
@@ -1215,8 +1268,9 @@ static void NewPMT( output_t *p_output )
<br>
pmt_set_program( p, p_output->config.i_sid );
<br>
psi_set_version( p, p_output->i_pmt_version );
<br>
psi_set_current( p );
<br>
- pmt_set_pcrpid( p, pmt_get_pcrpid( p_current_pmt ) );
<br>
pmt_set_desclength( p, 0 );
<br>
+ init_Mapping(p_output);
<br>
+
<br>
<br>
CopyDescriptors( pmt_get_descs( p ), pmt_get_descs(
p_current_pmt ) );
<br>
<br>
@@ -1236,13 +1290,21 @@ static void NewPMT( output_t *p_output )
<br>
k++;
<br>
pmtn_init( p_es );
<br>
pmtn_set_streamtype( p_es, pmtn_get_streamtype(
p_current_es ) );
<br>
- pmtn_set_pid( p_es, i_pid );
<br>
+ pmtn_set_pid( p_es, map_es_pid(p_output,
pmtn_get_streamtype( p_current_es ), i_pid) );
<br>
pmtn_set_desclength( p_es, 0 );
<br>
<br>
CopyDescriptors( pmtn_get_descs( p_es ),
<br>
pmtn_get_descs( p_current_es ) );
<br>
}
<br>
<br>
+ /* Do the pcr pid after everything else as it may have been
remapped */
<br>
+ i_pcrpid = pmt_get_pcrpid( p_current_pmt );
<br>
+ if(p_output->pi_newpids[i_pcrpid] != UNUSED_PID) {
<br>
+ msg_Dbg ( NULL, "Mapping pcrpid from 0x%x to 0x%x\n",
<br>
+ i_pcrpid, p_output->pi_newpids[i_pcrpid]);
<br>
+ i_pcrpid = p_output->pi_newpids[i_pcrpid];
<br>
+ }
<br>
+ pmt_set_pcrpid( p, i_pcrpid );
<br>
</blockquote>
<br>
Add i_do_remap check in addition to UNUSED_PID?
<br>
<br>
<blockquote type="cite"> p_es = pmt_get_es( p, k );
<br>
if ( p_es == NULL )
<br>
/* This shouldn't happen if the incoming PMT is valid
*/
<br>
diff --git a/dvblast.1 b/dvblast.1
<br>
index 189d171..a205cfe 100644
<br>
--- a/dvblast.1
<br>
+++ b/dvblast.1
<br>
@@ -22,7 +22,7 @@ DVBlast is designed to be the core of a custom
IRD or CID, based on a PC with
<br>
Linux-supported DVB cards.
<br>
<br>
DVBlast does not do any kind of processing on the elementary
streams, such as
<br>
-transcoding, PID remapping or remultiplexing. it does not
stream from plain
<br>
+transcoding or remultiplexing. it does not stream from plain
<br>
files, only DVB devices. If you were looking for these
features, switch to VLC.
<br>
.SH OPTIONS
<br>
.PP
<br>
@@ -191,6 +191,9 @@ pass through all ESs from the PMT, of any
type
<br>
\fB\-Z\fR, \fB\-\-mrtg-file\fR <mrtg_file>
<br>
Every 10 seconds log statistics in <mrtg_file>. The file
has 4 numbers in it
<br>
and the format is: <passed_bytes> <error_packets>
<packets_with_seq_errors> <scrambled_packets>
<br>
+.TP
<br>
+\fB\-k\fR, \fB\-\-pidmap\fR
<pmtpid,audiopid,videopid,spupid>
<br>
+Map the Elemntary Stream pids to the values given for all
Elementary Streams. Where there are multiple audio pids, then
these will be mapped to audiopid, auiopid+1, audiopid +2 and so
on.
<br>
</blockquote>
<br>
Word wrap at col 72. One day others should be done too.
<br>
<br>
<blockquote type="cite"> .SH SEE ALSO
<br>
Read the README file for more information about the
configuration of dvblast.
<br>
.SH AUTHORS
<br>
diff --git a/dvblast.c b/dvblast.c
<br>
index a0e6a5d..7749eb9 100644
<br>
--- a/dvblast.c
<br>
+++ b/dvblast.c
<br>
@@ -111,9 +111,15 @@ static mtime_t i_latency_global =
DEFAULT_OUTPUT_LATENCY;
<br>
static mtime_t i_retention_global = DEFAULT_MAX_RETENTION;
<br>
static int i_ttl_global = 64;
<br>
<br>
-/* TPS Input log filename */
<br>
+/* Input log filename */
<br>
char * psz_mrtg_file = NULL;
<br>
<br>
+/* pidmapping */
<br>
+bool i_do_remap = false;
<br>
</blockquote>
<br>
bool b_do_remap. You have changed the type but not the name.
<br>
<br>
<blockquote type="cite">+uint16_t pi_newpids[N_MAP_PIDS]; /* pmt,
audio, video, spu */
<br>
+void init_Mapping( output_t *) ;
<br>
+
<br>
+
<br>
</blockquote>
<br>
One new line is enough.
<br>
<br>
<blockquote type="cite"> void (*pf_Open)( void ) = NULL;
<br>
block_t * (*pf_Read)( mtime_t i_poll_timeout ) = NULL;
<br>
void (*pf_Reset)( void ) = NULL;
<br>
@@ -597,10 +603,11 @@ int main( int i_argc, char **pp_argv )
<br>
{ "help", no_argument, NULL, 'h' },
<br>
{ "version", no_argument, NULL, 'V' },
<br>
{ "mrtg-file", required_argument, NULL, 'Z' },
<br>
+ { "pidmap", required_argument, NULL, 'k' },
<br>
{ 0, 0, 0, 0 }
<br>
};
<br>
<br>
- 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 )
<br>
+ 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 )
<br>
{
<br>
switch ( c )
<br>
{
<br>
@@ -853,6 +860,29 @@ int main( int i_argc, char **pp_argv )
<br>
psz_mrtg_file = optarg;
<br>
break;
<br>
<br>
+ case 'k':
<br>
+ {
<br>
</blockquote>
<br>
Move the brace next to the case and pull the code 4 spaces left.
<br>
<br>
<blockquote type="cite">+ /* We expect a comma separated
list of numbers.
<br>
+ Put them into the pi_newpids array as they
appear */
<br>
+ char * str1;
<br>
+ char * saveptr = NULL;
<br>
+ char * tok = NULL;
<br>
+ int i, i_newpid;
<br>
+ for(i = 0, str1 = optarg; i < N_MAP_PIDS;
i++, str1 = NULL)
<br>
</blockquote>
<br>
Umm, too much magic. optarg can't be null (getopt will take care
of this).
<br>
<br>
<blockquote type="cite">+ {
<br>
+ tok = strtok_r(str1, ",", &saveptr);
<br>
+ if(tok == NULL)
<br>
+ break;
<br>
+ i_newpid = strtoul(tok, NULL, 0);
<br>
+ if(0 == i_newpid) {
<br>
+ msg_Err( NULL, "Invalid pidmap string" );
<br>
+ usage();
<br>
+ }
<br>
+ pi_newpids[i] = i_newpid;
<br>
+ }
<br>
+ i_do_remap = true;
<br>
+ }
<br>
+ break;
<br>
case 'h':
<br>
default:
<br>
usage();
<br>
diff --git a/dvblast.h b/dvblast.h
<br>
index 40ce4c4..38c4292 100644
<br>
--- a/dvblast.h
<br>
+++ b/dvblast.h
<br>
@@ -43,6 +43,18 @@
<br>
#define DEFAULT_FRONTEND_TIMEOUT 30000000 /* 30 s */
<br>
#define EXIT_STATUS_FRONTEND_TIMEOUT 100
<br>
<br>
+/* Defines for pid mapping */
<br>
+#define N_MAP_PIDS 4
<br>
+/* Offsets in the command line args for the pid mapping */
<br>
+typedef enum
<br>
+{
<br>
+ I_PMTPID = 0, I_APID, I_VPID, I_SPUPID
<br>
+} PidMapOffset;
<br>
</blockquote>
<br>
Each value on a line, and maybe pidmap_offset_t?
<br>
<br>
<blockquote type="cite">+/* Impossible PID value */
<br>
+#define UNUSED_PID (MAX_PIDS + 1)
<br>
+
<br>
+
<br>
/*****************************************************************************
<br>
* Output configuration flags (for output_t -> i_config) -
bit values
<br>
* Bit 0 : Set for watch mode
<br>
@@ -73,6 +85,7 @@ typedef struct block_t
<br>
uint8_t p_ts[TS_SIZE];
<br>
int i_refcount;
<br>
mtime_t i_dts;
<br>
+ uint16_t tmp_pid;
<br>
struct block_t *p_next;
<br>
} block_t;
<br>
<br>
@@ -131,6 +144,10 @@ typedef struct output_t
<br>
block_t *p_eit_ts_buffer;
<br>
uint8_t i_eit_ts_buffer_offset, i_eit_cc;
<br>
uint16_t i_tsid;
<br>
+ // Arrays used for mapping pids.
<br>
+ // newpids is indexed using the original pid
<br>
+ uint16_t pi_newpids[MAX_PIDS];
<br>
+ uint16_t pi_freepids[MAX_PIDS]; // used where multiple
streams of the same type are used
<br>
} output_t;
<br>
<br>
typedef struct ts_pid_info {
<br>
@@ -191,6 +208,11 @@ extern const char *psz_native_charset;
<br>
extern const char *psz_dvb_charset;
<br>
extern enum print_type_t i_print_type;
<br>
<br>
+/* pid mapping */
<br>
+extern bool i_do_remap;
<br>
+extern uint16_t pi_newpids[N_MAP_PIDS];
<br>
+void init_Mapping(output_t *);
<br>
+
<br>
extern void (*pf_Open)( void );
<br>
extern block_t * (*pf_Read)( mtime_t i_poll_timeout );
<br>
extern void (*pf_Reset)( void );
<br>
diff --git a/output.c b/output.c
<br>
index 0cc5bf7..ba84a29 100644
<br>
--- a/output.c
<br>
+++ b/output.c
<br>
@@ -103,6 +103,16 @@ output_t *output_Create( const
output_config_t *p_config )
<br>
return p_output;
<br>
}
<br>
<br>
+/* Init the mapped pids to unused */
<br>
+void init_Mapping( output_t * p_output)
<br>
+{
<br>
+ unsigned int i;
<br>
+ for(i = 0; i< MAX_PIDS; i++) {
<br>
+ p_output->pi_newpids[i] = UNUSED_PID;
<br>
+ p_output->pi_freepids[i] = UNUSED_PID;
<br>
+ }
<br>
+}
<br>
+
<br>
/*****************************************************************************
<br>
* output_Init : set up the output initial config
<br>
*****************************************************************************/<br>
@@ -135,6 +145,9 @@ int output_Init( output_t *p_output, const
output_config_t *p_config )
<br>
if ( b_random_tsid )
<br>
p_output->i_tsid = rand() & 0xffff;
<br>
<br>
+ /* Init the mapped pids to unused */
<br>
+ init_Mapping(p_output);
<br>
+
<br>
/* Init socket-related fields */
<br>
p_output->config.i_family = p_config->i_family;
<br>
memcpy( &p_output->config.connect_addr,
&p_config->connect_addr,
<br>
@@ -273,6 +286,24 @@ static void output_Flush( output_t
*p_output )
<br>
<br>
for ( i_block = 0; i_block < p_packet->i_depth;
i_block++ )
<br>
{
<br>
+ /* Do pid mapping here if needed.
<br>
+ * save the original pid in the block.
<br>
+ * set the pid to the new pid
<br>
+ * later we re-instate the old pid for the next output
<br>
+ */
<br>
+ if(i_do_remap) {
<br>
+ block_t * p_block =
p_packet->pp_blocks[i_block];
<br>
+ uint16_t i_pid = (p_block->p_ts[1] & 0x1f)
<< 8 | p_block->p_ts[2];
<br>
+ p_block->tmp_pid = UNUSED_PID;
<br>
+ if(UNUSED_PID != p_output->pi_newpids[i_pid])
<br>
</blockquote>
<br>
Variable order in the if.
<br>
<br>
<blockquote type="cite">+ {
<br>
+ uint16_t i_newpid =
p_output->pi_newpids[i_pid];
<br>
+ /* Need to map this pid to the new pid */
<br>
+ ts_set_pid( p_block, i_newpid );
<br>
+ p_block->tmp_pid = i_pid;
<br>
+ }
<br>
+ }
<br>
+
<br>
p_iov[i_iov].iov_base =
p_packet->pp_blocks[i_block]->p_ts;
<br>
p_iov[i_iov].iov_len = TS_SIZE;
<br>
i_iov++;
<br>
@@ -298,6 +329,12 @@ static void output_Flush( output_t
*p_output )
<br>
p_packet->pp_blocks[i_block]->i_refcount--;
<br>
if ( !p_packet->pp_blocks[i_block]->i_refcount )
<br>
block_Delete( p_packet->pp_blocks[i_block] );
<br>
+ else if(i_do_remap) {
<br>
+ /* still referenced so re-instate the orignial pid
if remapped */
<br>
+ block_t * p_block =
p_packet->pp_blocks[i_block];
<br>
+ if(p_block->tmp_pid != UNUSED_PID)
<br>
+ ts_set_pid( p_block, p_block->tmp_pid );
<br>
+ }
<br>
</blockquote>
<br>
Why do you change the pid and then return it back? Since pidmap is
<br>
initialized globally once the pid is changed it should be ok for
other
<br>
outputs?
<br>
</blockquote>
The reason I did this was because a pid might be used in two
prorammes - say A and B . If there are multiple audio pids (a1 and
a2) then then it is possible for programme A to have a1=>200 and
a2=>201 and programme B to have a2=>200, so the same input pid
has two possible output values.<br>
<br>
Pete<br>
<br>
<blockquote cite="mid:4EDC914D.5010500@unixsol.org" type="cite">
<br>
Thanks.
<br>
<br>
</blockquote>
<br>
<br>
<div class="moz-signature">-- <br>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<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>