Commit 4bc25883 authored by Christophe Massiot's avatar Christophe Massiot

multicat: new option to fix continuity counters

parent 6d625a12
$Id$
Changes between 2.0 and 2.1:
----------------------------
* FreeBSD and Mac OS X support
* Support for changing source address with raw sockets
* Fix overflow in date calculation on 32 bit platforms
* New fd= interface option
* Reorder packets based on sequence numbers instead of timestamps
* Add ability to cap the number of retx requests in reordertp
* Allow retransmission to work without a dedicated connection
* Add option to fix continuity counters
Changes between 1.0 and 2.0:
----------------------------
* Support for directory input/output, where the stream is stored into
......
......@@ -61,6 +61,7 @@
#define POLL_TIMEOUT 1000 /* 1 s */
#define MAX_LATENESS INT64_C(27000000) /* 1 s */
#define FILE_FLUSH INT64_C(2700000) /* 100 ms */
#define MAX_PIDS 8192
/*****************************************************************************
* Local declarations
......@@ -76,31 +77,33 @@ static bool b_input_udp = false, b_output_udp = false;
static size_t i_asked_payload_size = DEFAULT_PAYLOAD_SIZE;
static size_t i_rtp_header_size = RTP_HEADER_SIZE;
static uint64_t i_rotate_size = DEFAULT_ROTATE_SIZE;
struct udprawpkt pktheader;
bool b_raw_packets = false;
static struct udprawpkt pktheader;
static bool b_raw_packets = false;
static uint8_t *pi_pid_cc_table = NULL;
static volatile sig_atomic_t b_die = 0, b_error = 0;
static uint16_t i_rtp_seqnum;
static uint64_t i_stc = 0; /* system time clock, used for date calculations */
static uint64_t i_first_stc = 0;
static uint64_t i_pcr = 0, i_pcr_stc = 0; /* for RTP/TS output */
uint64_t (*pf_Date)(void) = wall_Date;
void (*pf_Sleep)( uint64_t ) = wall_Sleep;
ssize_t (*pf_Read)( void *p_buf, size_t i_len );
bool (*pf_Delay)(void) = NULL;
void (*pf_ExitRead)(void);
ssize_t (*pf_Write)( const void *p_buf, size_t i_len );
void (*pf_ExitWrite)(void);
static uint64_t (*pf_Date)(void) = wall_Date;
static void (*pf_Sleep)( uint64_t ) = wall_Sleep;
static ssize_t (*pf_Read)( void *p_buf, size_t i_len );
static bool (*pf_Delay)(void) = NULL;
static void (*pf_ExitRead)(void);
static ssize_t (*pf_Write)( const void *p_buf, size_t i_len );
static void (*pf_ExitWrite)(void);
static void usage(void)
{
msg_Raw( NULL, "Usage: multicat [-i <RT priority>] [-l <syslogtag>] [-t <ttl>] [-X] [-T <file name>] [-f] [-p <PCR PID>] [-s <chunks>] [-n <chunks>] [-k <start time>] [-d <duration>] [-a] [-r <file duration>] [-S <SSRC IP>] [-u] [-U] [-m <payload size>] [-R <RTP header size>] [-w] <input item> <output item>" );
msg_Raw( NULL, "Usage: multicat [-i <RT priority>] [-l <syslogtag>] [-t <ttl>] [-X] [-T <file name>] [-f] [-p <PCR PID>] [-C] [-s <chunks>] [-n <chunks>] [-k <start time>] [-d <duration>] [-a] [-r <file duration>] [-S <SSRC IP>] [-u] [-U] [-m <payload size>] [-R <RTP header size>] [-w] <input item> <output item>" );
msg_Raw( NULL, " item format: <file path | device path | FIFO path | directory path | network host>" );
msg_Raw( NULL, " host format: [<connect addr>[:<connect port>]][@[<bind addr][:<bind port>]]" );
msg_Raw( NULL, " -X: also pass-through all packets to stdout" );
msg_Raw( NULL, " -T: write an XML file with the current characteristics of transmission" );
msg_Raw( NULL, " -f: output packets as fast as possible" );
msg_Raw( NULL, " -p: overwrite or create RTP timestamps using PCR PID (MPEG-2/TS)" );
msg_Raw( NULL, " -C: rewrite continuity counters to be continuous" );
msg_Raw( NULL, " -s: skip the first N chunks of payload [deprecated]" );
msg_Raw( NULL, " -n: exit after playing N chunks of payload [deprecated]" );
msg_Raw( NULL, " -k: start at the given position (in 27 MHz units, negative = from the end)" );
......@@ -743,9 +746,8 @@ static void GetPCR( const uint8_t *p_buffer, size_t i_read_size )
if ( !ts_validate( p_buffer ) )
{
msg_Warn( NULL, "invalid TS packet (sync=0x%x)", p_buffer[0] );
return;
}
if ( (i_pid == i_pcr_pid || i_pcr_pid == 8192)
else if ( (i_pid == i_pcr_pid || i_pcr_pid == 8192)
&& ts_has_adaptation(p_buffer) && ts_get_adaptation(p_buffer)
&& tsaf_has_pcr(p_buffer) )
{
......@@ -757,6 +759,37 @@ static void GetPCR( const uint8_t *p_buffer, size_t i_read_size )
}
}
/*****************************************************************************
* FIxCC: fix continuity counters
*****************************************************************************/
static void FixCC( uint8_t *p_buffer, size_t i_read_size )
{
while ( i_read_size >= TS_SIZE )
{
uint16_t i_pid = ts_get_pid( p_buffer );
if ( !ts_validate( p_buffer ) )
{
msg_Warn( NULL, "invalid TS packet (sync=0x%x)", p_buffer[0] );
}
else
{
if ( pi_pid_cc_table[i_pid] == 0x10 )
{
msg_Dbg( NULL, "new pid entry %d", i_pid );
pi_pid_cc_table[i_pid] = 0;
}
else if ( ts_has_payload( p_buffer ) )
{
pi_pid_cc_table[i_pid] = (pi_pid_cc_table[i_pid] + 1) % 0x10;
}
ts_set_cc( p_buffer, pi_pid_cc_table[i_pid] );
}
p_buffer += TS_SIZE;
i_read_size -= TS_SIZE;
}
}
/*****************************************************************************
* Entry point
*****************************************************************************/
......@@ -777,7 +810,7 @@ int main( int i_argc, char **pp_argv )
sigset_t set;
/* Parse options */
while ( (c = getopt( i_argc, pp_argv, "i:l:t:XT:fp:s:n:k:d:ar:S:uUm:R:wh" )) != -1 )
while ( (c = getopt( i_argc, pp_argv, "i:l:t:XT:fp:Cs:n:k:d:ar:S:uUm:R:wh" )) != -1 )
{
switch ( c )
{
......@@ -812,6 +845,11 @@ int main( int i_argc, char **pp_argv )
i_pcr_pid = strtol( optarg, NULL, 0 );
break;
case 'C':
pi_pid_cc_table = malloc(MAX_PIDS * sizeof(uint8_t));
memset(pi_pid_cc_table, 0x10, MAX_PIDS * sizeof(uint8_t));
break;
case 's':
i_skip_chunks = strtol( optarg, NULL, 0 );
break;
......@@ -1018,6 +1056,10 @@ int main( int i_argc, char **pp_argv )
i_payload_size += TS_SIZE;
}
/* Fix continuity counters */
if ( pi_pid_cc_table != NULL )
FixCC( p_payload, i_payload_size );
/* Prepare header and size of output */
if ( b_output_udp )
{
......@@ -1093,6 +1135,8 @@ dropped_packet:
break;
}
free(pi_pid_cc_table);
pf_ExitRead();
pf_ExitWrite();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment