Commit 03e270d0 authored by Jean-Paul Saman's avatar Jean-Paul Saman

(Forward port from branch 0.8.1-jpsaman-thedj) TS demux can now dump a TS...

(Forward port from branch 0.8.1-jpsaman-thedj) TS demux can now dump a TS stream directly to a file or special devices, this mode can be used with DSP's. Enhanced CSA encryption/decryption with a non standard mode to encrypt/decrypt a part of a TS packet. Further I replaced a bunch of // comments with /* .. */ comments style.
parent a0c550b8
/***************************************************************************** /*****************************************************************************
* ts.c: Transport Stream input module for VLC. * ts.c: Transport Stream input module for VLC.
***************************************************************************** *****************************************************************************
* Copyright (C) 2004 the VideoLAN team * Copyright (C) 2004-2005 the VideoLAN team
* $Id$ * $Id$
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Jean-Paul Saman <jpsaman #_at_# m2x.nl>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -101,6 +102,24 @@ static void Close ( vlc_object_t * ); ...@@ -101,6 +102,24 @@ static void Close ( vlc_object_t * );
#define CAPMT_SYSID_TEXT N_("CAPMT System ID") #define CAPMT_SYSID_TEXT N_("CAPMT System ID")
#define CAPMT_SYSID_LONGTEXT N_("only forward descriptors from this SysID to the CAM") #define CAPMT_SYSID_LONGTEXT N_("only forward descriptors from this SysID to the CAM")
#define CPKT_TEXT N_("Packet size in bytes to decrypt")
#define CPKT_LONGTEXT N_("Specify the size of the TS packet to decrypt. " \
"The decryption routines subtract the TS-header from the value before " \
"decrypting. " )
#define TSDUMP_TEXT N_("Filename of dump")
#define TSDUMP_LONGTEXT N_("Specify a filename where to dump the TS in")
#define APPEND_TEXT N_("Append")
#define APPEND_LONGTEXT N_( \
"If the file exists and this option is selected, the existing file " \
"will not be overwritten." )
#define DUMPSIZE_TEXT N_("Dump buffer size")
#define DUMPSIZE_LONGTEXT N_( \
"Tweak the buffer size for reading and writing an integer number of packets." \
"Specify the size of the buffer here and not the number of packets." )
vlc_module_begin(); vlc_module_begin();
set_description( _("MPEG Transport Stream demuxer") ); set_description( _("MPEG Transport Stream demuxer") );
set_shortname ( "MPEG-TS" ); set_shortname ( "MPEG-TS" );
...@@ -113,8 +132,14 @@ vlc_module_begin(); ...@@ -113,8 +132,14 @@ vlc_module_begin();
add_integer( "ts-out-mtu", 1500, NULL, MTUOUT_TEXT, add_integer( "ts-out-mtu", 1500, NULL, MTUOUT_TEXT,
MTUOUT_LONGTEXT, VLC_TRUE ); MTUOUT_LONGTEXT, VLC_TRUE );
add_string( "ts-csa-ck", NULL, NULL, CSA_TEXT, CSA_LONGTEXT, VLC_TRUE ); add_string( "ts-csa-ck", NULL, NULL, CSA_TEXT, CSA_LONGTEXT, VLC_TRUE );
add_integer( "ts-csa-pkt", 188, NULL, CPKT_TEXT, CPKT_LONGTEXT, VLC_TRUE );
add_bool( "ts-silent", 0, NULL, SILENT_TEXT, SILENT_LONGTEXT, VLC_TRUE ); add_bool( "ts-silent", 0, NULL, SILENT_TEXT, SILENT_LONGTEXT, VLC_TRUE );
add_file( "ts-dump-file", NULL, NULL, TSDUMP_TEXT, TSDUMP_LONGTEXT, VLC_FALSE );
add_bool( "ts-dump-append", 0, NULL, APPEND_TEXT, APPEND_LONGTEXT, VLC_FALSE );
add_integer( "ts-dump-size", 16384, NULL, DUMPSIZE_TEXT,
DUMPSIZE_LONGTEXT, VLC_TRUE );
set_capability( "demux2", 10 ); set_capability( "demux2", 10 );
set_callbacks( Open, Close ); set_callbacks( Open, Close );
add_shortcut( "ts" ); add_shortcut( "ts" );
...@@ -284,6 +309,7 @@ struct demux_sys_t ...@@ -284,6 +309,7 @@ struct demux_sys_t
/* */ /* */
vlc_bool_t b_es_id_pid; vlc_bool_t b_es_id_pid;
csa_t *csa; csa_t *csa;
int i_csa_pkt_size;
vlc_bool_t b_silent; vlc_bool_t b_silent;
vlc_bool_t b_udp_out; vlc_bool_t b_udp_out;
...@@ -294,14 +320,20 @@ struct demux_sys_t ...@@ -294,14 +320,20 @@ struct demux_sys_t
int i_dvb_program; int i_dvb_program;
vlc_list_t *p_programs_list; vlc_list_t *p_programs_list;
/* TS dump */
char *psz_file; /* file to dump data in */
FILE *p_file; /* filehandle */
uint64_t i_write; /* bytes written */
vlc_bool_t b_file_out; /* dump mode enabled */
/* */ /* */
vlc_bool_t b_meta; vlc_bool_t b_meta;
}; };
static int Demux ( demux_t *p_demux ); static int Demux ( demux_t *p_demux );
static int DemuxFile( demux_t *p_demux );
static int Control( demux_t *p_demux, int i_query, va_list args ); static int Control( demux_t *p_demux, int i_query, va_list args );
static void PIDInit ( ts_pid_t *pid, vlc_bool_t b_psi, ts_psi_t *p_owner ); static void PIDInit ( ts_pid_t *pid, vlc_bool_t b_psi, ts_psi_t *p_owner );
static void PIDClean( es_out_t *out, ts_pid_t *pid ); static void PIDClean( es_out_t *out, ts_pid_t *pid );
static int PIDFillFormat( ts_pid_t *pid, int i_stream_type ); static int PIDFillFormat( ts_pid_t *pid, int i_stream_type );
...@@ -313,7 +345,6 @@ static void PSINewTableCallBack( demux_t *, dvbpsi_handle, ...@@ -313,7 +345,6 @@ static void PSINewTableCallBack( demux_t *, dvbpsi_handle,
uint8_t i_table_id, uint16_t i_extension ); uint8_t i_table_id, uint16_t i_extension );
#endif #endif
static inline int PIDGet( block_t *p ) static inline int PIDGet( block_t *p )
{ {
return ( (p->p_buffer[1]&0x1f)<<8 )|p->p_buffer[2]; return ( (p->p_buffer[1]&0x1f)<<8 )|p->p_buffer[2];
...@@ -344,6 +375,8 @@ static int Open( vlc_object_t *p_this ) ...@@ -344,6 +375,8 @@ static int Open( vlc_object_t *p_this )
int i_packet_size; int i_packet_size;
ts_pid_t *pat; ts_pid_t *pat;
char *psz_mode;
vlc_bool_t b_append;
vlc_value_t val; vlc_value_t val;
...@@ -396,7 +429,60 @@ static int Open( vlc_object_t *p_this ) ...@@ -396,7 +429,60 @@ static int Open( vlc_object_t *p_this )
return VLC_EGENERIC; return VLC_EGENERIC;
} }
p_sys->i_packet_size = i_packet_size;
/* Fill dump mode fields */
p_sys->i_write = 0;
p_sys->p_file = NULL;
p_sys->b_file_out = VLC_FALSE;
p_sys->psz_file = var_CreateGetString( p_demux, "ts-dump-file" );
if( *p_sys->psz_file != '\0' )
{
p_sys->b_file_out = VLC_TRUE;
var_Create( p_demux, "ts-dump-append", VLC_VAR_BOOL|VLC_VAR_DOINHERIT );
var_Get( p_demux, "ts-dump-append", &val );
b_append = val.b_bool;
if ( b_append )
psz_mode = "ab";
else
psz_mode = "wb";
if( !strcmp( p_sys->psz_file, "-" ) )
{
msg_Info( p_demux, "dumping raw stream to standard output" );
p_sys->p_file = stdout;
}
else if( ( p_sys->p_file = fopen( p_sys->psz_file, psz_mode ) ) == NULL )
{
msg_Err( p_demux, "cannot create `%s' for writing", p_sys->psz_file );
p_sys->b_file_out = VLC_FALSE;
}
if( p_sys->b_file_out )
{
vlc_value_t bufsize;
/* Determine how many packets to read. */
var_Create( p_demux, "ts-dump-size",
VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Get( p_demux, "ts-dump-size", &bufsize );
p_sys->i_ts_read = (int) (bufsize.i_int / p_sys->i_packet_size);
if( p_sys->i_ts_read <= 0 )
{
p_sys->i_ts_read = 1500 / p_sys->i_packet_size;
}
p_sys->buffer = malloc( p_sys->i_packet_size * p_sys->i_ts_read );
msg_Info( p_demux, "%s raw stream to file `%s' reading packets %d",
b_append ? "appending" : "dumping", p_sys->psz_file,
p_sys->i_ts_read );
}
}
/* Fill p_demux field */ /* Fill p_demux field */
if( p_sys->b_file_out )
p_demux->pf_demux = DemuxFile;
else
p_demux->pf_demux = Demux; p_demux->pf_demux = Demux;
p_demux->pf_control = Control; p_demux->pf_control = Control;
p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) ); p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
...@@ -459,7 +545,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -459,7 +545,7 @@ static int Open( vlc_object_t *p_this )
var_Create( p_demux, "ts-out", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Create( p_demux, "ts-out", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Get( p_demux, "ts-out", &val ); var_Get( p_demux, "ts-out", &val );
if( val.psz_string && *val.psz_string ) if( val.psz_string && *val.psz_string && !p_sys->b_file_out )
{ {
vlc_value_t mtu; vlc_value_t mtu;
char *psz = strchr( val.psz_string, ':' ); char *psz = strchr( val.psz_string, ':' );
...@@ -499,7 +585,6 @@ static int Open( vlc_object_t *p_this ) ...@@ -499,7 +585,6 @@ static int Open( vlc_object_t *p_this )
free( val.psz_string ); free( val.psz_string );
} }
/* We handle description of an extra PMT */ /* We handle description of an extra PMT */
var_Create( p_demux, "ts-extra-pmt", VLC_VAR_STRING | VLC_VAR_DOINHERIT ); var_Create( p_demux, "ts-extra-pmt", VLC_VAR_STRING | VLC_VAR_DOINHERIT );
var_Get( p_demux, "ts-extra-pmt", &val ); var_Get( p_demux, "ts-extra-pmt", &val );
...@@ -597,13 +682,28 @@ static int Open( vlc_object_t *p_this ) ...@@ -597,13 +682,28 @@ static int Open( vlc_object_t *p_this )
{ {
ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff; ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
} }
#ifndef TS_NO_CSA_CK_MSG
msg_Dbg( p_demux, "using CSA scrambling with " msg_Dbg( p_demux, "using CSA scrambling with "
"ck=%x:%x:%x:%x:%x:%x:%x:%x", "ck=%x:%x:%x:%x:%x:%x:%x:%x",
ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] ); ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
#endif
p_sys->csa = csa_New(); p_sys->csa = csa_New();
if( p_sys->csa )
{
csa_SetCW( p_sys->csa, ck, ck ); csa_SetCW( p_sys->csa, ck, ck );
var_Create( p_demux, "ts-csa-pkt", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT );
var_Get( p_demux, "ts-csa-pkt", &val );
if( val.i_int < 4 || val.i_int > 188 )
{
msg_Err( p_demux, "wrong packet size %d specified.", val.i_int );
msg_Warn( p_demux, "using default packet size of 188 bytes" );
p_sys->i_csa_pkt_size = 188;
}
else p_sys->i_csa_pkt_size = val.i_int;
msg_Dbg( p_demux, "decrypting %d bytes of packet", p_sys->i_csa_pkt_size );
}
} }
} }
if( val.psz_string ) if( val.psz_string )
...@@ -691,9 +791,135 @@ static void Close( vlc_object_t *p_this ) ...@@ -691,9 +791,135 @@ static void Close( vlc_object_t *p_this )
var_Change( p_demux, "programs", VLC_VAR_FREELIST, &val, NULL ); var_Change( p_demux, "programs", VLC_VAR_FREELIST, &val, NULL );
} }
/* If in dump mode, then close the file */
if( p_sys->b_file_out )
{
msg_Info( p_demux ,"closing %s ("I64Fd" Kbytes dumped)", p_sys->psz_file,
p_sys->i_write / 1024 );
if( p_sys->p_file != stdout )
{
fclose( p_sys->p_file );
p_sys->p_file = NULL;
}
free( p_sys->psz_file );
p_sys->psz_file = NULL;
free( p_sys->buffer );
}
free( p_sys ); free( p_sys );
} }
/*****************************************************************************
* DemuxFile:
*****************************************************************************/
static int DemuxFile( demux_t *p_demux )
{
demux_sys_t *p_sys = p_demux->p_sys;
uint8_t *p_buffer = p_sys->buffer; /* Put first on sync byte */
int i_diff= 0;
int i_data= 0;
int i_pos = 0;
int i_bufsize = p_sys->i_packet_size * p_sys->i_ts_read;
i_data = stream_Read( p_demux->s, p_sys->buffer, i_bufsize );
if( (i_data <= 0) && (i_data < p_sys->i_packet_size) )
{
msg_Dbg( p_demux, "Error reading malformed packets" );
return i_data;
}
/* Test continuity counter */
while( i_pos < i_data )
{
ts_pid_t *p_pid; /* point to a PID structure */
vlc_bool_t b_payload; /* indicates a packet with payload */
vlc_bool_t b_adaptation; /* adaptation field */
int i_cc = 0; /* continuity counter */
if( p_sys->buffer[i_pos] != 0x47 )
{
msg_Warn( p_demux, "lost sync" );
while( !p_demux->b_die && (i_pos < i_data) )
{
i_pos++;
if( p_sys->buffer[i_pos] == 0x47 )
break;
}
if( !p_demux->b_die )
msg_Warn( p_demux, "sync found" );
}
/* continuous when (one of this):
* diff == 1
* diff == 0 and payload == 0
* diff == 0 and duplicate packet (playload != 0) <- should we
* test the content ?
*/
i_cc = p_buffer[i_pos+3]&0x0f;
b_payload = p_buffer[i_pos+3]&0x10;
b_adaptation = p_buffer[i_pos+3]&0x20;
/* Get the PID */
p_pid = &p_sys->pid[ ((p_buffer[i_pos+1]&0x1f)<<8)|p_buffer[i_pos+2] ];
/* Detect discontinuity indicator in adaptation field */
if( b_adaptation )
{
if( p_buffer[i_pos+5]&0x80 )
msg_Warn( p_demux, "discontinuity indicator (pid=%d) ", p_pid->i_pid );
if( p_buffer[i_pos+5]&0x40 )
msg_Warn( p_demux, "random access indicator (pid=%d) ", p_pid->i_pid );
}
i_diff = ( i_cc - p_pid->i_cc )&0x0f;
if( b_payload && i_diff == 1 )
{
p_pid->i_cc++;
}
else
{
if( p_pid->i_cc == 0xff )
{
msg_Warn( p_demux, "first packet for pid=%d cc=0x%x",
p_pid->i_pid, i_cc );
p_pid->i_cc = i_cc;
}
else if( i_diff != 0 )
{
/* FIXME what to do when discontinuity_indicator is set ? */
msg_Warn( p_demux, "transport error detected 0x%x instead of 0x%x",
i_cc, ( p_pid->i_cc + 1 )&0x0f );
p_pid->i_cc = i_cc;
/* Mark transport error in the TS packet. */
p_buffer[i_pos+1] |= 0x80;
}
}
/* Test if user wants to decrypt it first */
if( p_sys->csa )
csa_Decrypt( p_demux->p_sys->csa, &p_buffer[i_pos], p_demux->p_sys->i_csa_pkt_size );
i_pos += p_sys->i_packet_size;
}
/* Then write */
i_data = fwrite( p_sys->buffer, 1, i_data, p_sys->p_file );
if( i_data < 0 )
{
msg_Err( p_demux, "failed to write data" );
return -1;
}
#if 0
msg_Dbg( p_demux, "dumped %d bytes", i_data );
#endif
p_sys->i_write += i_data;
return 1;
}
/***************************************************************************** /*****************************************************************************
* Demux: * Demux:
*****************************************************************************/ *****************************************************************************/
...@@ -837,6 +1063,9 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) ...@@ -837,6 +1063,9 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
int64_t i64; int64_t i64;
int i_int; int i_int;
if( p_sys->b_file_out )
return demux2_vaControlHelper( p_demux->s, 0, -1, 0, 1, i_query, args );
switch( i_query ) switch( i_query )
{ {
case DEMUX_GET_POSITION: case DEMUX_GET_POSITION:
...@@ -1409,7 +1638,7 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk ) ...@@ -1409,7 +1638,7 @@ static vlc_bool_t GatherPES( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk )
if( p_demux->p_sys->csa ) if( p_demux->p_sys->csa )
{ {
csa_Decrypt( p_demux->p_sys->csa, p_bk->p_buffer ); csa_Decrypt( p_demux->p_sys->csa, p_bk->p_buffer, p_demux->p_sys->i_csa_pkt_size );
} }
if( !b_adaptation ) if( !b_adaptation )
...@@ -1682,7 +1911,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1682,7 +1911,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
p_iod = malloc( sizeof( iod_descriptor_t ) ); p_iod = malloc( sizeof( iod_descriptor_t ) );
memset( p_iod, 0, sizeof( iod_descriptor_t ) ); memset( p_iod, 0, sizeof( iod_descriptor_t ) );
#ifdef DEBUG
fprintf( stderr, "\n************ IOD ************" ); fprintf( stderr, "\n************ IOD ************" );
#endif
for( i = 0; i < 255; i++ ) for( i = 0; i < 255; i++ )
{ {
p_iod->es_descr[i].b_ok = 0; p_iod->es_descr[i].b_ok = 0;
...@@ -1709,10 +1940,11 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1709,10 +1940,11 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
p_iod->i_iod_label = byte2; p_iod->i_iod_label = byte2;
i_iod_tag = byte3; i_iod_tag = byte3;
} }
#ifdef DEBUG
fprintf( stderr, "\n* iod_label:%d", p_iod->i_iod_label ); fprintf( stderr, "\n* iod_label:%d", p_iod->i_iod_label );
fprintf( stderr, "\n* ===========" ); fprintf( stderr, "\n* ===========" );
fprintf( stderr, "\n* tag:0x%x", i_iod_tag ); fprintf( stderr, "\n* tag:0x%x", i_iod_tag );
#endif
if( i_iod_tag != 0x02 ) if( i_iod_tag != 0x02 )
{ {
fprintf( stderr, "\n ERR: tag %02x != 0x02", i_iod_tag ); fprintf( stderr, "\n ERR: tag %02x != 0x02", i_iod_tag );
...@@ -1720,7 +1952,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1720,7 +1952,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
} }
i_iod_length = IODDescriptorLength( &i_data, &p_data ); i_iod_length = IODDescriptorLength( &i_data, &p_data );
#ifdef DEBUG
fprintf( stderr, "\n* length:%d", i_iod_length ); fprintf( stderr, "\n* length:%d", i_iod_length );
#endif
if( i_iod_length > i_data ) if( i_iod_length > i_data )
{ {
i_iod_length = i_data; i_iod_length = i_data;
...@@ -1730,16 +1964,18 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1730,16 +1964,18 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
i_flags = IODGetByte( &i_data, &p_data ); i_flags = IODGetByte( &i_data, &p_data );
p_iod->i_od_id |= i_flags >> 6; p_iod->i_od_id |= i_flags >> 6;
b_url = ( i_flags >> 5 )&0x01; b_url = ( i_flags >> 5 )&0x01;
#ifdef DEBUG
fprintf( stderr, "\n* od_id:%d", p_iod->i_od_id ); fprintf( stderr, "\n* od_id:%d", p_iod->i_od_id );
fprintf( stderr, "\n* url flag:%d", b_url ); fprintf( stderr, "\n* url flag:%d", b_url );
fprintf( stderr, "\n* includeInlineProfileLevel flag:%d", ( i_flags >> 4 )&0x01 ); fprintf( stderr, "\n* includeInlineProfileLevel flag:%d", ( i_flags >> 4 )&0x01 );
#endif
if( b_url ) if( b_url )
{ {
p_iod->psz_url = IODGetURL( &i_data, &p_data ); p_iod->psz_url = IODGetURL( &i_data, &p_data );
#ifdef DEBUG
fprintf( stderr, "\n* url string:%s", p_iod->psz_url ); fprintf( stderr, "\n* url string:%s", p_iod->psz_url );
fprintf( stderr, "\n*****************************\n" ); fprintf( stderr, "\n*****************************\n" );
#endif
return p_iod; return p_iod;
} }
else else
...@@ -1752,13 +1988,13 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1752,13 +1988,13 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
p_iod->i_audioProfileLevelIndication = IODGetByte( &i_data, &p_data ); p_iod->i_audioProfileLevelIndication = IODGetByte( &i_data, &p_data );
p_iod->i_visualProfileLevelIndication = IODGetByte( &i_data, &p_data ); p_iod->i_visualProfileLevelIndication = IODGetByte( &i_data, &p_data );
p_iod->i_graphicsProfileLevelIndication = IODGetByte( &i_data, &p_data ); p_iod->i_graphicsProfileLevelIndication = IODGetByte( &i_data, &p_data );
#ifdef DEBUG
fprintf( stderr, "\n* ODProfileLevelIndication:%d", p_iod->i_ODProfileLevelIndication ); fprintf( stderr, "\n* ODProfileLevelIndication:%d", p_iod->i_ODProfileLevelIndication );
fprintf( stderr, "\n* sceneProfileLevelIndication:%d", p_iod->i_sceneProfileLevelIndication ); fprintf( stderr, "\n* sceneProfileLevelIndication:%d", p_iod->i_sceneProfileLevelIndication );
fprintf( stderr, "\n* audioProfileLevelIndication:%d", p_iod->i_audioProfileLevelIndication ); fprintf( stderr, "\n* audioProfileLevelIndication:%d", p_iod->i_audioProfileLevelIndication );
fprintf( stderr, "\n* visualProfileLevelIndication:%d", p_iod->i_visualProfileLevelIndication ); fprintf( stderr, "\n* visualProfileLevelIndication:%d", p_iod->i_visualProfileLevelIndication );
fprintf( stderr, "\n* graphicsProfileLevelIndication:%d", p_iod->i_graphicsProfileLevelIndication ); fprintf( stderr, "\n* graphicsProfileLevelIndication:%d", p_iod->i_graphicsProfileLevelIndication );
#endif
while( i_data > 0 && i_es_index < 255) while( i_data > 0 && i_es_index < 255)
{ {
...@@ -1780,7 +2016,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1780,7 +2016,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
{ {
#define es_descr p_iod->es_descr[i_es_index] #define es_descr p_iod->es_descr[i_es_index]
int i_decoderConfigDescr_length; int i_decoderConfigDescr_length;
#ifdef DEBUG
fprintf( stderr, "\n* - ES_Descriptor length:%d", i_length ); fprintf( stderr, "\n* - ES_Descriptor length:%d", i_length );
#endif
es_descr.b_ok = 1; es_descr.b_ok = 1;
es_descr.i_es_id = IODGetWord( &i_data, &p_data ); es_descr.i_es_id = IODGetWord( &i_data, &p_data );
...@@ -1789,20 +2027,25 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1789,20 +2027,25 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
b_url = ( i_flags >> 6 )&0x01; b_url = ( i_flags >> 6 )&0x01;
es_descr.b_OCRStreamFlag = ( i_flags >> 5 )&0x01; es_descr.b_OCRStreamFlag = ( i_flags >> 5 )&0x01;
es_descr.i_streamPriority = i_flags & 0x1f; es_descr.i_streamPriority = i_flags & 0x1f;
#ifdef DEBUG
fprintf( stderr, "\n* * streamDependenceFlag:%d", es_descr.b_streamDependenceFlag ); fprintf( stderr, "\n* * streamDependenceFlag:%d", es_descr.b_streamDependenceFlag );
fprintf( stderr, "\n* * OCRStreamFlag:%d", es_descr.b_OCRStreamFlag ); fprintf( stderr, "\n* * OCRStreamFlag:%d", es_descr.b_OCRStreamFlag );
fprintf( stderr, "\n* * streamPriority:%d", es_descr.i_streamPriority ); fprintf( stderr, "\n* * streamPriority:%d", es_descr.i_streamPriority );
#endif
if( es_descr.b_streamDependenceFlag ) if( es_descr.b_streamDependenceFlag )
{ {
es_descr.i_dependOn_es_id = IODGetWord( &i_data, &p_data ); es_descr.i_dependOn_es_id = IODGetWord( &i_data, &p_data );
#ifdef DEBUG
fprintf( stderr, "\n* * dependOn_es_id:%d", es_descr.i_dependOn_es_id ); fprintf( stderr, "\n* * dependOn_es_id:%d", es_descr.i_dependOn_es_id );
#endif
} }
if( b_url ) if( b_url )
{ {
es_descr.psz_url = IODGetURL( &i_data, &p_data ); es_descr.psz_url = IODGetURL( &i_data, &p_data );
#ifdef DEBUG
fprintf( stderr, "\n* url string:%s", es_descr.psz_url ); fprintf( stderr, "\n* url string:%s", es_descr.psz_url );
#endif
} }
else else
{ {
...@@ -1812,18 +2055,23 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1812,18 +2055,23 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
if( es_descr.b_OCRStreamFlag ) if( es_descr.b_OCRStreamFlag )
{ {
es_descr.i_OCR_es_id = IODGetWord( &i_data, &p_data ); es_descr.i_OCR_es_id = IODGetWord( &i_data, &p_data );
#ifdef DEBUG
fprintf( stderr, "\n* * OCR_es_id:%d", es_descr.i_OCR_es_id ); fprintf( stderr, "\n* * OCR_es_id:%d", es_descr.i_OCR_es_id );
#endif
} }
if( IODGetByte( &i_data, &p_data ) != 0x04 ) if( IODGetByte( &i_data, &p_data ) != 0x04 )
{ {
#ifdef DEBUG
fprintf( stderr, "\n* ERR missing DecoderConfigDescr" ); fprintf( stderr, "\n* ERR missing DecoderConfigDescr" );
#endif
es_descr.b_ok = 0; es_descr.b_ok = 0;
break; break;
} }
i_decoderConfigDescr_length = IODDescriptorLength( &i_data, &p_data ); i_decoderConfigDescr_length = IODDescriptorLength( &i_data, &p_data );
#ifdef DEBUG
fprintf( stderr, "\n* - DecoderConfigDesc length:%d", i_decoderConfigDescr_length ); fprintf( stderr, "\n* - DecoderConfigDesc length:%d", i_decoderConfigDescr_length );
#endif
#define dec_descr es_descr.dec_descr #define dec_descr es_descr.dec_descr
dec_descr.i_objectTypeIndication = IODGetByte( &i_data, &p_data ); dec_descr.i_objectTypeIndication = IODGetByte( &i_data, &p_data );
i_flags = IODGetByte( &i_data, &p_data ); i_flags = IODGetByte( &i_data, &p_data );
...@@ -1832,12 +2080,14 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1832,12 +2080,14 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
dec_descr.i_bufferSizeDB = IODGet3Bytes( &i_data, &p_data ); dec_descr.i_bufferSizeDB = IODGet3Bytes( &i_data, &p_data );
dec_descr.i_maxBitrate = IODGetDWord( &i_data, &p_data ); dec_descr.i_maxBitrate = IODGetDWord( &i_data, &p_data );
dec_descr.i_avgBitrate = IODGetDWord( &i_data, &p_data ); dec_descr.i_avgBitrate = IODGetDWord( &i_data, &p_data );
#ifdef DEBUG
fprintf( stderr, "\n* * objectTypeIndication:0x%x", dec_descr.i_objectTypeIndication ); fprintf( stderr, "\n* * objectTypeIndication:0x%x", dec_descr.i_objectTypeIndication );
fprintf( stderr, "\n* * streamType:0x%x", dec_descr.i_streamType ); fprintf( stderr, "\n* * streamType:0x%x", dec_descr.i_streamType );
fprintf( stderr, "\n* * upStream:%d", dec_descr.b_upStream ); fprintf( stderr, "\n* * upStream:%d", dec_descr.b_upStream );
fprintf( stderr, "\n* * bufferSizeDB:%d", dec_descr.i_bufferSizeDB ); fprintf( stderr, "\n* * bufferSizeDB:%d", dec_descr.i_bufferSizeDB );
fprintf( stderr, "\n* * maxBitrate:%d", dec_descr.i_maxBitrate ); fprintf( stderr, "\n* * maxBitrate:%d", dec_descr.i_maxBitrate );
fprintf( stderr, "\n* * avgBitrate:%d", dec_descr.i_avgBitrate ); fprintf( stderr, "\n* * avgBitrate:%d", dec_descr.i_avgBitrate );
#endif
if( i_decoderConfigDescr_length > 13 && IODGetByte( &i_data, &p_data ) == 0x05 ) if( i_decoderConfigDescr_length > 13 && IODGetByte( &i_data, &p_data ) == 0x05 )
{ {
int i; int i;
...@@ -1867,15 +2117,20 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1867,15 +2117,20 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
if( IODGetByte( &i_data, &p_data ) != 0x06 ) if( IODGetByte( &i_data, &p_data ) != 0x06 )
{ {
#ifdef DEBUG
fprintf( stderr, "\n* ERR missing SLConfigDescr" ); fprintf( stderr, "\n* ERR missing SLConfigDescr" );
#endif
es_descr.b_ok = 0; es_descr.b_ok = 0;
break; break;
} }
i_SLConfigDescr_length = IODDescriptorLength( &i_data, &p_data ); i_SLConfigDescr_length = IODDescriptorLength( &i_data, &p_data );
#ifdef DEBUG
fprintf( stderr, "\n* - SLConfigDescr length:%d", i_SLConfigDescr_length ); fprintf( stderr, "\n* - SLConfigDescr length:%d", i_SLConfigDescr_length );
#endif
i_predefined = IODGetByte( &i_data, &p_data ); i_predefined = IODGetByte( &i_data, &p_data );
#ifdef DEBUG
fprintf( stderr, "\n* * i_predefined:0x%x", i_predefined ); fprintf( stderr, "\n* * i_predefined:0x%x", i_predefined );
#endif
switch( i_predefined ) switch( i_predefined )
{ {
case 0x01: case 0x01:
...@@ -1911,7 +2166,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1911,7 +2166,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
} }
break; break;
default: default:
#ifdef DEBUG
fprintf( stderr, "\n* ERR unsupported SLConfigDescr predefined" ); fprintf( stderr, "\n* ERR unsupported SLConfigDescr predefined" );
#endif
es_descr.b_ok = 0; es_descr.b_ok = 0;
break; break;
} }
...@@ -1920,7 +2177,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1920,7 +2177,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
#undef sl_descr #undef sl_descr
#undef es_descr #undef es_descr
default: default:
#ifdef DEBUG
fprintf( stderr, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag, i_length ); fprintf( stderr, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag, i_length );
#endif
break; break;
} }
...@@ -1928,9 +2187,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data ) ...@@ -1928,9 +2187,9 @@ static iod_descriptor_t *IODNew( int i_data, uint8_t *p_data )
i_data = i_data_sav - i_length; i_data = i_data_sav - i_length;
i_es_index++; i_es_index++;
} }
#ifdef DEBUG
fprintf( stderr, "\n*****************************\n" ); fprintf( stderr, "\n*****************************\n" );
#endif
return p_iod; return p_iod;
} }
......
/***************************************************************************** /*****************************************************************************
* libcsa.c: CSA scrambler/descrambler * libcsa.c: CSA scrambler/descrambler
***************************************************************************** *****************************************************************************
* Copyright (C) 2004 Laurent Aimar * Copyright (C) 2004-2005 Laurent Aimar
* $Id$ * $Id$
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Jean-Paul Saman <jpsaman #_at_# m2x.nl>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -89,7 +90,7 @@ void csa_SetCW( csa_t *c, uint8_t o_ck[8], uint8_t e_ck[8] ) ...@@ -89,7 +90,7 @@ void csa_SetCW( csa_t *c, uint8_t o_ck[8], uint8_t e_ck[8] )
/***************************************************************************** /*****************************************************************************
* csa_Decrypt: * csa_Decrypt:
*****************************************************************************/ *****************************************************************************/
void csa_Decrypt( csa_t *c, uint8_t *pkt ) void csa_Decrypt( csa_t *c, uint8_t *pkt, int i_pkt_size )
{ {
uint8_t *ck; uint8_t *ck;
uint8_t *kk; uint8_t *kk;
...@@ -133,8 +134,11 @@ void csa_Decrypt( csa_t *c, uint8_t *pkt ) ...@@ -133,8 +134,11 @@ void csa_Decrypt( csa_t *c, uint8_t *pkt )
csa_StreamCypher( c, 1, ck, &pkt[i_hdr], ib ); csa_StreamCypher( c, 1, ck, &pkt[i_hdr], ib );
/* */ /* */
n = (188 - i_hdr) / 8; n = (i_pkt_size - i_hdr) / 8;
i_residue = (188 - i_hdr) % 8; if( n < 0 )
return;
i_residue = (i_pkt_size - i_hdr) % 8;
for( i = 1; i < n + 1; i++ ) for( i = 1; i < n + 1; i++ )
{ {
csa_BlockDecypher( kk, ib, block ); csa_BlockDecypher( kk, ib, block );
...@@ -167,7 +171,7 @@ void csa_Decrypt( csa_t *c, uint8_t *pkt ) ...@@ -167,7 +171,7 @@ void csa_Decrypt( csa_t *c, uint8_t *pkt )
csa_StreamCypher( c, 0, ck, NULL, stream ); csa_StreamCypher( c, 0, ck, NULL, stream );
for( j = 0; j < i_residue; j++ ) for( j = 0; j < i_residue; j++ )
{ {
pkt[188 - i_residue + j] ^= stream[j]; pkt[i_pkt_size - i_residue + j] ^= stream[j];
} }
} }
} }
...@@ -175,13 +179,13 @@ void csa_Decrypt( csa_t *c, uint8_t *pkt ) ...@@ -175,13 +179,13 @@ void csa_Decrypt( csa_t *c, uint8_t *pkt )
/***************************************************************************** /*****************************************************************************
* csa_Encrypt: * csa_Encrypt:
*****************************************************************************/ *****************************************************************************/
void csa_Encrypt( csa_t *c, uint8_t *pkt, int b_odd ) void csa_Encrypt( csa_t *c, uint8_t *pkt, int i_pkt_size, int b_odd )
{ {
uint8_t *ck; uint8_t *ck;
uint8_t *kk; uint8_t *kk;
int i, j; int i, j;
int i_hdr; int i_hdr = 4; /* hdr len */
uint8_t ib[184/8+2][8], stream[8], block[8]; uint8_t ib[184/8+2][8], stream[8], block[8];
int n, i_residue; int n, i_residue;
...@@ -210,10 +214,10 @@ void csa_Encrypt( csa_t *c, uint8_t *pkt, int b_odd ) ...@@ -210,10 +214,10 @@ void csa_Encrypt( csa_t *c, uint8_t *pkt, int b_odd )
/* skip adaption field */ /* skip adaption field */
i_hdr += pkt[4] + 1; i_hdr += pkt[4] + 1;
} }
n = (188 - i_hdr) / 8; n = (i_pkt_size - i_hdr) / 8;
i_residue = (188 - i_hdr) % 8; i_residue = (i_pkt_size - i_hdr) % 8;
if( n == 0 ) if( n <= 0 )
{ {
pkt[3] &= 0x3f; pkt[3] &= 0x3f;
return; return;
...@@ -253,7 +257,7 @@ void csa_Encrypt( csa_t *c, uint8_t *pkt, int b_odd ) ...@@ -253,7 +257,7 @@ void csa_Encrypt( csa_t *c, uint8_t *pkt, int b_odd )
csa_StreamCypher( c, 0, ck, NULL, stream ); csa_StreamCypher( c, 0, ck, NULL, stream );
for( j = 0; j < i_residue; j++ ) for( j = 0; j < i_residue; j++ )
{ {
pkt[188 - i_residue + j] ^= stream[j]; pkt[i_pkt_size - i_residue + j] ^= stream[j];
} }
} }
} }
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/ *****************************************************************************/
#ifndef _CSA_H
#define _CSA_H 1
typedef struct csa_t csa_t; typedef struct csa_t csa_t;
#define csa_New E_(__csa_New) #define csa_New E_(__csa_New)
#define csa_Delete E_(__csa_Delete) #define csa_Delete E_(__csa_Delete)
...@@ -33,6 +36,7 @@ void csa_Delete( csa_t * ); ...@@ -33,6 +36,7 @@ void csa_Delete( csa_t * );
void csa_SetCW( csa_t *, uint8_t o_ck[8], uint8_t e_ck[8] ); void csa_SetCW( csa_t *, uint8_t o_ck[8], uint8_t e_ck[8] );
void csa_Decrypt( csa_t *, uint8_t *pkt ); void csa_Decrypt( csa_t *, uint8_t *pkt, int i_pkt_size );
void csa_Encrypt( csa_t *, uint8_t *pkt, int b_odd ); void csa_Encrypt( csa_t *, uint8_t *pkt, int i_pkt_size, int b_odd );
#endif /* _CSA_H */
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Eric Petit <titer@videolan.org> * Eric Petit <titer@videolan.org>
* Jean-Paul Saman <jpsaman #_at_# m2x.nl>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -130,6 +131,11 @@ static void Close ( vlc_object_t * ); ...@@ -130,6 +131,11 @@ static void Close ( vlc_object_t * );
#define CK_LONGTEXT N_("Defines the CSA encryption key. This must be a " \ #define CK_LONGTEXT N_("Defines the CSA encryption key. This must be a " \
"16 char string (8 hexadecimal bytes).") "16 char string (8 hexadecimal bytes).")
#define CPKT_TEXT N_("Packet size in bytes to encrypt")
#define CPKT_LONGTEXT N_("Specify the size of the TS packet to encrypt. " \
"The encryption routines subtract the TS-header from the value before " \
"encrypting. " )
#define SOUT_CFG_PREFIX "sout-ts-" #define SOUT_CFG_PREFIX "sout-ts-"
vlc_module_begin(); vlc_module_begin();
...@@ -176,6 +182,7 @@ vlc_module_begin(); ...@@ -176,6 +182,7 @@ vlc_module_begin();
add_string( SOUT_CFG_PREFIX "csa-ck", NULL, NULL, CK_TEXT, CK_LONGTEXT, add_string( SOUT_CFG_PREFIX "csa-ck", NULL, NULL, CK_TEXT, CK_LONGTEXT,
VLC_TRUE ); VLC_TRUE );
add_integer( SOUT_CFG_PREFIX "csa-pkt", 188, NULL, CPKT_TEXT, CPKT_LONGTEXT, VLC_TRUE );
set_callbacks( Open, Close ); set_callbacks( Open, Close );
vlc_module_end(); vlc_module_end();
...@@ -186,7 +193,7 @@ vlc_module_end(); ...@@ -186,7 +193,7 @@ vlc_module_end();
static const char *ppsz_sout_options[] = { static const char *ppsz_sout_options[] = {
"pid-video", "pid-audio", "pid-spu", "pid-pmt", "tsid", "program-pmt", "pid-video", "pid-audio", "pid-spu", "pid-pmt", "tsid", "program-pmt",
"es-id-pid", "shaping", "pcr", "bmin", "bmax", "use-key-frames", "es-id-pid", "shaping", "pcr", "bmin", "bmax", "use-key-frames",
"dts-delay", "csa-ck", "crypt-audio", "crypt-video", "dts-delay", "csa-ck", "csa-pkt", "crypt-audio", "crypt-video",
NULL NULL
}; };
...@@ -203,6 +210,7 @@ static inline void BufferChainInit ( sout_buffer_chain_t *c ) ...@@ -203,6 +210,7 @@ static inline void BufferChainInit ( sout_buffer_chain_t *c )
c->p_first = NULL; c->p_first = NULL;
c->pp_last = &c->p_first; c->pp_last = &c->p_first;
} }
static inline void BufferChainAppend( sout_buffer_chain_t *c, block_t *b ) static inline void BufferChainAppend( sout_buffer_chain_t *c, block_t *b )
{ {
*c->pp_last = b; *c->pp_last = b;
...@@ -215,6 +223,7 @@ static inline void BufferChainAppend( sout_buffer_chain_t *c, block_t *b ) ...@@ -215,6 +223,7 @@ static inline void BufferChainAppend( sout_buffer_chain_t *c, block_t *b )
} }
c->pp_last = &b->p_next; c->pp_last = &b->p_next;
} }
static inline block_t *BufferChainGet( sout_buffer_chain_t *c ) static inline block_t *BufferChainGet( sout_buffer_chain_t *c )
{ {
block_t *b = c->p_first; block_t *b = c->p_first;
...@@ -233,12 +242,14 @@ static inline block_t *BufferChainGet( sout_buffer_chain_t *c ) ...@@ -233,12 +242,14 @@ static inline block_t *BufferChainGet( sout_buffer_chain_t *c )
} }
return b; return b;
} }
static inline block_t *BufferChainPeek( sout_buffer_chain_t *c ) static inline block_t *BufferChainPeek( sout_buffer_chain_t *c )
{ {
block_t *b = c->p_first; block_t *b = c->p_first;
return b; return b;
} }
static inline void BufferChainClean( sout_instance_t *p_sout, static inline void BufferChainClean( sout_instance_t *p_sout,
sout_buffer_chain_t *c ) sout_buffer_chain_t *c )
{ {
...@@ -293,14 +304,14 @@ struct sout_mux_sys_t ...@@ -293,14 +304,14 @@ struct sout_mux_sys_t
int i_pid_video; int i_pid_video;
int i_pid_audio; int i_pid_audio;
int i_pid_spu; int i_pid_spu;
int i_pid_free; // first usable pid int i_pid_free; /* first usable pid */
int i_tsid; int i_tsid;
int i_pat_version_number; int i_pat_version_number;
ts_stream_t pat; ts_stream_t pat;
int i_pmt_version_number; int i_pmt_version_number;
ts_stream_t pmt; // Up to now only one program ts_stream_t pmt; /* Up to now only one program */
int i_pmt_program_number; int i_pmt_program_number;
int i_mpeg4_streams; int i_mpeg4_streams;
...@@ -321,11 +332,11 @@ struct sout_mux_sys_t ...@@ -321,11 +332,11 @@ struct sout_mux_sys_t
mtime_t i_pcr; /* last PCR emited */ mtime_t i_pcr; /* last PCR emited */
csa_t *csa; csa_t *csa;
int i_csa_pkt_size;
vlc_bool_t b_crypt_audio; vlc_bool_t b_crypt_audio;
vlc_bool_t b_crypt_video; vlc_bool_t b_crypt_video;
}; };
/* Reserve a pid and return it */ /* Reserve a pid and return it */
static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat ) static int AllocatePID( sout_mux_sys_t *p_sys, int i_cat )
{ {
...@@ -542,12 +553,25 @@ static int Open( vlc_object_t *p_this ) ...@@ -542,12 +553,25 @@ static int Open( vlc_object_t *p_this )
{ {
ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff; ck[i] = ( i_ck >> ( 56 - 8*i) )&0xff;
} }
#ifndef TS_NO_CSA_CK_MSG
msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x", msg_Dbg( p_mux, "using CSA scrambling with ck=%x:%x:%x:%x:%x:%x:%x:%x",
ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] ); ck[0], ck[1], ck[2], ck[3], ck[4], ck[5], ck[6], ck[7] );
#endif
p_sys->csa = csa_New(); p_sys->csa = csa_New();
if( p_sys->csa )
{
csa_SetCW( p_sys->csa, ck, ck ); csa_SetCW( p_sys->csa, ck, ck );
var_Get( p_mux, SOUT_CFG_PREFIX "csa-pkt", &val );
if( val.i_int < 12 || val.i_int > 188 )
{
msg_Err( p_mux, "wrong packet size %d specified.", val.i_int );
msg_Warn( p_mux, "using default packet size of 188 bytes" );
p_sys->i_csa_pkt_size = 188;
}
else p_sys->i_csa_pkt_size = val.i_int;
msg_Dbg( p_mux, "encrypting %d bytes of packet", p_sys->i_csa_pkt_size );
}
} }
} }
if( val.psz_string ) free( val.psz_string ); if( val.psz_string ) free( val.psz_string );
...@@ -663,8 +687,8 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) ...@@ -663,8 +687,8 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
case VLC_FOURCC( 'D', 'I', 'V', '2' ): case VLC_FOURCC( 'D', 'I', 'V', '2' ):
case VLC_FOURCC( 'D', 'I', 'V', '1' ): case VLC_FOURCC( 'D', 'I', 'V', '1' ):
case VLC_FOURCC( 'M', 'J', 'P', 'G' ): case VLC_FOURCC( 'M', 'J', 'P', 'G' ):
p_stream->i_stream_type = 0xa0; // private p_stream->i_stream_type = 0xa0; /* private */
p_stream->i_stream_id = 0xa0; // beurk p_stream->i_stream_id = 0xa0; /* beurk */
p_stream->i_bih_codec = p_input->p_fmt->i_codec; p_stream->i_bih_codec = p_input->p_fmt->i_codec;
p_stream->i_bih_width = p_input->p_fmt->video.i_width; p_stream->i_bih_width = p_input->p_fmt->video.i_width;
p_stream->i_bih_height = p_input->p_fmt->video.i_height; p_stream->i_bih_height = p_input->p_fmt->video.i_height;
...@@ -773,7 +797,6 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) ...@@ -773,7 +797,6 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
} }
} }
/* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */ /* Copy extra data (VOL for MPEG-4 and extra BitMapInfoHeader for VFW */
p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra; p_stream->i_decoder_specific_info = p_input->p_fmt->i_extra;
if( p_stream->i_decoder_specific_info > 0 ) if( p_stream->i_decoder_specific_info > 0 )
...@@ -1496,7 +1519,7 @@ static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts, ...@@ -1496,7 +1519,7 @@ static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
} }
if( p_ts->i_flags & BLOCK_FLAG_SCRAMBLED ) if( p_ts->i_flags & BLOCK_FLAG_SCRAMBLED )
{ {
csa_Encrypt( p_sys->csa, p_ts->p_buffer, 0 ); csa_Encrypt( p_sys->csa, p_ts->p_buffer, p_sys->i_csa_pkt_size, 0 );
} }
/* latency */ /* latency */
...@@ -1811,7 +1834,6 @@ static block_t *WritePSISection( sout_instance_t *p_sout, ...@@ -1811,7 +1834,6 @@ static block_t *WritePSISection( sout_instance_t *p_sout,
{ {
block_t *p_psi, *p_first = NULL; block_t *p_psi, *p_first = NULL;
while( p_section ) while( p_section )
{ {
int i_size; int i_size;
...@@ -1825,7 +1847,7 @@ static block_t *WritePSISection( sout_instance_t *p_sout, ...@@ -1825,7 +1847,7 @@ static block_t *WritePSISection( sout_instance_t *p_sout,
p_psi->i_length = 0; p_psi->i_length = 0;
p_psi->i_buffer = i_size + 1; p_psi->i_buffer = i_size + 1;
p_psi->p_buffer[0] = 0; // pointer p_psi->p_buffer[0] = 0; /* pointer */
memcpy( p_psi->p_buffer + 1, memcpy( p_psi->p_buffer + 1,
p_section->p_data, p_section->p_data,
i_size ); i_size );
...@@ -1847,14 +1869,14 @@ static void GetPAT( sout_mux_t *p_mux, ...@@ -1847,14 +1869,14 @@ static void GetPAT( sout_mux_t *p_mux,
dvbpsi_psi_section_t *p_section; dvbpsi_psi_section_t *p_section;
dvbpsi_InitPAT( &pat, p_sys->i_tsid, p_sys->i_pat_version_number, dvbpsi_InitPAT( &pat, p_sys->i_tsid, p_sys->i_pat_version_number,
1 ); // b_current_next 1 ); /* b_current_next */
/* add all program (only one) */ /* add all program (only one) */
dvbpsi_PATAddProgram( &pat, dvbpsi_PATAddProgram( &pat,
p_sys->i_pmt_program_number, // i_number p_sys->i_pmt_program_number, /* i_number */
p_sys->pmt.i_pid ); // i_pid p_sys->pmt.i_pid ); /* i_pid */
p_section = dvbpsi_GenPATSections( &pat, p_section = dvbpsi_GenPATSections( &pat,
0 ); // max program per section 0 ); /* max program per section */
p_pat = WritePSISection( p_mux->p_sout, p_section ); p_pat = WritePSISection( p_mux->p_sout, p_section );
...@@ -1888,9 +1910,9 @@ static void GetPMT( sout_mux_t *p_mux, ...@@ -1888,9 +1910,9 @@ static void GetPMT( sout_mux_t *p_mux,
int i_stream; int i_stream;
dvbpsi_InitPMT( &pmt, dvbpsi_InitPMT( &pmt,
p_sys->i_pmt_program_number, // program number p_sys->i_pmt_program_number, /* program number */
p_sys->i_pmt_version_number, p_sys->i_pmt_version_number,
1, // b_current_next 1, /* b_current_next */
p_sys->i_pcr_pid ); p_sys->i_pcr_pid );
if( p_sys->i_mpeg4_streams > 0 ) if( p_sys->i_mpeg4_streams > 0 )
...@@ -1905,25 +1927,25 @@ static void GetPMT( sout_mux_t *p_mux, ...@@ -1905,25 +1927,25 @@ static void GetPMT( sout_mux_t *p_mux,
memset( iod, 0, 4096 ); memset( iod, 0, 4096 );
bits_initwrite( &bits, 4096, iod ); bits_initwrite( &bits, 4096, iod );
// IOD_label_scope /* IOD_label_scope */
bits_write( &bits, 8, 0x11 ); bits_write( &bits, 8, 0x11 );
// IOD_label /* IOD_label */
bits_write( &bits, 8, 0x01 ); bits_write( &bits, 8, 0x01 );
// InitialObjectDescriptor /* InitialObjectDescriptor */
bits_align( &bits ); bits_align( &bits );
bits_write( &bits, 8, 0x02 ); // tag bits_write( &bits, 8, 0x02 ); /* tag */
bits_fix_IOD = bits; // save states to fix length later bits_fix_IOD = bits; /* save states to fix length later */
bits_write( &bits, 24, bits_write( &bits, 24,
GetDescriptorLength24b( 0 ) ); // variable length (fixed later) GetDescriptorLength24b( 0 ) ); /* variable length (fixed later) */
bits_write( &bits, 10, 0x01 ); // ObjectDescriptorID bits_write( &bits, 10, 0x01 ); /* ObjectDescriptorID */
bits_write( &bits, 1, 0x00 ); // URL Flag bits_write( &bits, 1, 0x00 ); /* URL Flag */
bits_write( &bits, 1, 0x00 ); // includeInlineProfileLevelFlag bits_write( &bits, 1, 0x00 ); /* includeInlineProfileLevelFlag */
bits_write( &bits, 4, 0x0f ); // reserved bits_write( &bits, 4, 0x0f ); /* reserved */
bits_write( &bits, 8, 0xff ); // ODProfile (no ODcapability ) bits_write( &bits, 8, 0xff ); /* ODProfile (no ODcapability ) */
bits_write( &bits, 8, 0xff ); // sceneProfile bits_write( &bits, 8, 0xff ); /* sceneProfile */
bits_write( &bits, 8, 0xfe ); // audioProfile (unspecified) bits_write( &bits, 8, 0xfe ); /* audioProfile (unspecified) */
bits_write( &bits, 8, 0xfe ); // visualProfile( // ) bits_write( &bits, 8, 0xfe ); /* visualProfile( // ) */
bits_write( &bits, 8, 0xff ); // graphicProfile (no ) bits_write( &bits, 8, 0xff ); /* graphicProfile (no ) */
for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ ) for( i_stream = 0; i_stream < p_mux->i_nb_inputs; i_stream++ )
{ {
ts_stream_t *p_stream; ts_stream_t *p_stream;
...@@ -1936,41 +1958,41 @@ static void GetPMT( sout_mux_t *p_mux, ...@@ -1936,41 +1958,41 @@ static void GetPMT( sout_mux_t *p_mux,
bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder; bits_buffer_t bits_fix_ESDescr, bits_fix_Decoder;
/* ES descriptor */ /* ES descriptor */
bits_align( &bits ); bits_align( &bits );
bits_write( &bits, 8, 0x03 ); // ES_DescrTag bits_write( &bits, 8, 0x03 ); /* ES_DescrTag */
bits_fix_ESDescr = bits; bits_fix_ESDescr = bits;
bits_write( &bits, 24, bits_write( &bits, 24,
GetDescriptorLength24b( 0 ) ); // variable size GetDescriptorLength24b( 0 ) ); /* variable size */
bits_write( &bits, 16, p_stream->i_es_id ); bits_write( &bits, 16, p_stream->i_es_id );
bits_write( &bits, 1, 0x00 ); // streamDependency bits_write( &bits, 1, 0x00 ); /* streamDependency */
bits_write( &bits, 1, 0x00 ); // URL Flag bits_write( &bits, 1, 0x00 ); /* URL Flag */
bits_write( &bits, 1, 0x00 ); // OCRStreamFlag bits_write( &bits, 1, 0x00 ); /* OCRStreamFlag */
bits_write( &bits, 5, 0x1f ); // streamPriority bits_write( &bits, 5, 0x1f ); /* streamPriority */
// DecoderConfigDesciptor /* DecoderConfigDesciptor */
bits_align( &bits ); bits_align( &bits );
bits_write( &bits, 8, 0x04 ); // DecoderConfigDescrTag bits_write( &bits, 8, 0x04 ); /* DecoderConfigDescrTag */
bits_fix_Decoder = bits; bits_fix_Decoder = bits;
bits_write( &bits, 24, GetDescriptorLength24b( 0 ) ); bits_write( &bits, 24, GetDescriptorLength24b( 0 ) );
if( p_stream->i_stream_type == 0x10 ) if( p_stream->i_stream_type == 0x10 )
{ {
bits_write( &bits, 8, 0x20 ); // Visual 14496-2 bits_write( &bits, 8, 0x20 ); /* Visual 14496-2 */
bits_write( &bits, 6, 0x04 ); // VisualStream bits_write( &bits, 6, 0x04 ); /* VisualStream */
} }
else if( p_stream->i_stream_type == 0x1b ) else if( p_stream->i_stream_type == 0x1b )
{ {
bits_write( &bits, 8, 0x21 ); // Visual 14496-2 bits_write( &bits, 8, 0x21 ); /* Visual 14496-2 */
bits_write( &bits, 6, 0x04 ); // VisualStream bits_write( &bits, 6, 0x04 ); /* VisualStream */
} }
else if( p_stream->i_stream_type == 0x11 || p_stream->i_stream_type == 0x0f ) else if( p_stream->i_stream_type == 0x11 || p_stream->i_stream_type == 0x0f )
{ {
bits_write( &bits, 8, 0x40 ); // Audio 14496-3 bits_write( &bits, 8, 0x40 ); /* Audio 14496-3 */
bits_write( &bits, 6, 0x05 ); // AudioStream bits_write( &bits, 6, 0x05 ); /* AudioStream */
} }
else if( p_stream->i_stream_type == 0x12 && else if( p_stream->i_stream_type == 0x12 &&
p_stream->i_codec == VLC_FOURCC('s','u','b','t') ) p_stream->i_codec == VLC_FOURCC('s','u','b','t') )
{ {
bits_write( &bits, 8, 0x0B ); // Text Stream bits_write( &bits, 8, 0x0B ); /* Text Stream */
bits_write( &bits, 6, 0x04 ); // VisualStream bits_write( &bits, 6, 0x04 ); /* VisualStream */
} }
else else
{ {
...@@ -1980,18 +2002,18 @@ static void GetPMT( sout_mux_t *p_mux, ...@@ -1980,18 +2002,18 @@ static void GetPMT( sout_mux_t *p_mux,
msg_Err( p_mux->p_sout,"Unsupported stream_type => " msg_Err( p_mux->p_sout,"Unsupported stream_type => "
"broken IOD" ); "broken IOD" );
} }
bits_write( &bits, 1, 0x00 ); // UpStream bits_write( &bits, 1, 0x00 ); /* UpStream */
bits_write( &bits, 1, 0x01 ); // reserved bits_write( &bits, 1, 0x01 ); /* reserved */
bits_write( &bits, 24, 1024 * 1024 ); // bufferSizeDB bits_write( &bits, 24, 1024 * 1024 ); /* bufferSizeDB */
bits_write( &bits, 32, 0x7fffffff ); // maxBitrate bits_write( &bits, 32, 0x7fffffff ); /* maxBitrate */
bits_write( &bits, 32, 0 ); // avgBitrate bits_write( &bits, 32, 0 ); /* avgBitrate */
if( p_stream->i_decoder_specific_info > 0 ) if( p_stream->i_decoder_specific_info > 0 )
{ {
int i; int i;
// DecoderSpecificInfo /* DecoderSpecificInfo */
bits_align( &bits ); bits_align( &bits );
bits_write( &bits, 8, 0x05 ); // tag bits_write( &bits, 8, 0x05 ); /* tag */
bits_write( &bits, 24, GetDescriptorLength24b( bits_write( &bits, 24, GetDescriptorLength24b(
p_stream->i_decoder_specific_info ) ); p_stream->i_decoder_specific_info ) );
for( i = 0; i < p_stream->i_decoder_specific_info; i++ ) for( i = 0; i < p_stream->i_decoder_specific_info; i++ )
...@@ -2005,15 +2027,15 @@ static void GetPMT( sout_mux_t *p_mux, ...@@ -2005,15 +2027,15 @@ static void GetPMT( sout_mux_t *p_mux,
GetDescriptorLength24b( bits.i_data - GetDescriptorLength24b( bits.i_data -
bits_fix_Decoder.i_data - 3 ) ); bits_fix_Decoder.i_data - 3 ) );
/* SLConfigDescriptor : predifined (0x01) */ /* SLConfigDescriptor : predefined (0x01) */
bits_align( &bits ); bits_align( &bits );
bits_write( &bits, 8, 0x06 ); // tag bits_write( &bits, 8, 0x06 ); /* tag */
bits_write( &bits, 24, GetDescriptorLength24b( 8 ) ); bits_write( &bits, 24, GetDescriptorLength24b( 8 ) );
bits_write( &bits, 8, 0x01 ); // predefined bits_write( &bits, 8, 0x01 );/* predefined */
bits_write( &bits, 1, 0 ); // durationFlag bits_write( &bits, 1, 0 ); /* durationFlag */
bits_write( &bits, 32, 0 ); // OCRResolution bits_write( &bits, 32, 0 ); /* OCRResolution */
bits_write( &bits, 8, 0 ); // OCRLength bits_write( &bits, 8, 0 ); /* OCRLength */
bits_write( &bits, 8, 0 ); // InstantBitrateLength bits_write( &bits, 8, 0 ); /* InstantBitrateLength */
bits_align( &bits ); bits_align( &bits );
/* fix ESDescr length */ /* fix ESDescr length */
......
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