Commit 59fd3a2a authored by Benoit Steiner's avatar Benoit Steiner


Nettoyage de input_psi.

Debugage de DemuxPSI. Le nouveau code doit etre capable de gerer des cas
foireux qui ne sont pas senses arriver (et qui n'ont jamais ete rencontre
dans les flux qu'on a, vu que ca n'a jamais plante la avant). Son
principal interet est de ne plus produire de warning a la compilation :)

Benny
parent 9747fbb2
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
******************************************************************************* *******************************************************************************
* Read an MPEG2 stream, demultiplex and parse it before sending it to * Read an MPEG2 stream, demultiplex and parse it before sending it to
* decoders. * decoders.
*******************************************************************************/ ******************************************************************************/
/******************************************************************************* /*******************************************************************************
* Preamble * Preamble
*******************************************************************************/ ******************************************************************************/
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <sys/uio.h> /* iovec */ #include <sys/uio.h> /* iovec */
...@@ -1096,7 +1096,7 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input, ...@@ -1096,7 +1096,7 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
* input_DemuxPSI: * input_DemuxPSI:
******************************************************************************* *******************************************************************************
* Notice that current ES state has been locked by input_SortPacket. (No more true, * Notice that current ES state has been locked by input_SortPacket. (No more true,
* changed by benny - See if it'a ok, and definitely change the code ???????? ) * changed by benny - See if it's ok, and definitely change the code ???????? )
*******************************************************************************/ *******************************************************************************/
static __inline__ void input_DemuxPSI( input_thread_t *p_input, static __inline__ void input_DemuxPSI( input_thread_t *p_input,
ts_packet_t *p_ts_packet, ts_packet_t *p_ts_packet,
...@@ -1105,7 +1105,7 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input, ...@@ -1105,7 +1105,7 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input,
{ {
int i_data_offset; /* Offset of the interesting data in the TS packet */ int i_data_offset; /* Offset of the interesting data in the TS packet */
u16 i_data_length; /* Length of those data */ u16 i_data_length; /* Length of those data */
boolean_t b_first_section; /* Was there another section in the TS packet ? */ //boolean_t b_first_section; /* Was there another section in the TS packet ? */
ASSERT(p_input); ASSERT(p_input);
ASSERT(p_ts_packet); ASSERT(p_ts_packet);
...@@ -1117,80 +1117,87 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input, ...@@ -1117,80 +1117,87 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input,
// intf_DbgMsg( "Packet: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x (unit start: %d)\n", p_ts_packet->buffer[p_ts_packet->i_payload_start], p_ts_packet->buffer[p_ts_packet->i_payload_start+1], p_ts_packet->buffer[p_ts_packet->i_payload_start+2], p_ts_packet->buffer[p_ts_packet->i_payload_start+3], p_ts_packet->buffer[p_ts_packet->i_payload_start+4], p_ts_packet->buffer[p_ts_packet->i_payload_start+5], p_ts_packet->buffer[p_ts_packet->i_payload_start+6], p_ts_packet->buffer[p_ts_packet->i_payload_start+7], p_ts_packet->buffer[p_ts_packet->i_payload_start+8], p_ts_packet->buffer[p_ts_packet->i_payload_start+9], p_ts_packet->buffer[p_ts_packet->i_payload_start+10], p_ts_packet->buffer[p_ts_packet->i_payload_start+11], p_ts_packet->buffer[p_ts_packet->i_payload_start+12], p_ts_packet->buffer[p_ts_packet->i_payload_start+13], p_ts_packet->buffer[p_ts_packet->i_payload_start+14], p_ts_packet->buffer[p_ts_packet->i_payload_start+15], p_ts_packet->buffer[p_ts_packet->i_payload_start+16], p_ts_packet->buffer[p_ts_packet->i_payload_start+17], p_ts_packet->buffer[p_ts_packet->i_payload_start+18], p_ts_packet->buffer[p_ts_packet->i_payload_start+19], p_ts_packet->buffer[p_ts_packet->i_payload_start+20], b_unit_start); // intf_DbgMsg( "Packet: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x (unit start: %d)\n", p_ts_packet->buffer[p_ts_packet->i_payload_start], p_ts_packet->buffer[p_ts_packet->i_payload_start+1], p_ts_packet->buffer[p_ts_packet->i_payload_start+2], p_ts_packet->buffer[p_ts_packet->i_payload_start+3], p_ts_packet->buffer[p_ts_packet->i_payload_start+4], p_ts_packet->buffer[p_ts_packet->i_payload_start+5], p_ts_packet->buffer[p_ts_packet->i_payload_start+6], p_ts_packet->buffer[p_ts_packet->i_payload_start+7], p_ts_packet->buffer[p_ts_packet->i_payload_start+8], p_ts_packet->buffer[p_ts_packet->i_payload_start+9], p_ts_packet->buffer[p_ts_packet->i_payload_start+10], p_ts_packet->buffer[p_ts_packet->i_payload_start+11], p_ts_packet->buffer[p_ts_packet->i_payload_start+12], p_ts_packet->buffer[p_ts_packet->i_payload_start+13], p_ts_packet->buffer[p_ts_packet->i_payload_start+14], p_ts_packet->buffer[p_ts_packet->i_payload_start+15], p_ts_packet->buffer[p_ts_packet->i_payload_start+16], p_ts_packet->buffer[p_ts_packet->i_payload_start+17], p_ts_packet->buffer[p_ts_packet->i_payload_start+18], p_ts_packet->buffer[p_ts_packet->i_payload_start+19], p_ts_packet->buffer[p_ts_packet->i_payload_start+20], b_unit_start);
/* The section we will deal with during the first iteration of the following
loop is the first one contained in the TS packet */
b_first_section = 1;
/* Reassemble the pieces of sections contained in the TS packet and decode /* Try to find the beginning of the payload in the packet to initialise
the sections that could have been completed */ the do-while loop that follows -> Compute the i_data_offset variable:
do by default, the value is set so that we won't enter in the while loop.
It will be set to a correct value if the data are not corrupted */
i_data_offset = TS_PACKET_SIZE;
/* Has the reassembly of a section already began in a previous packet ? */
if( p_psi->b_running_section )
{ {
/* Has the reassembly of a section already began in a previous packet ? */ /* Was data lost since the last TS packet ? */
if( p_psi->b_running_section ) if( b_packet_lost )
{ {
/* Was data lost since the last TS packet ? */ /* Discard the packet and wait for the begining of a new one to resynch */
if( b_packet_lost ) p_psi->b_running_section = 0;
{ p_psi->i_current_position = 0;
/* Discard the section and wait for the begining of a new one to resynch */ intf_DbgMsg( "PSI section(s) discarded due to packet loss\n" );
p_psi->b_running_section = 0; }
intf_DbgMsg( "Section discarded due to packet loss\n" ); else
} {
else /* The data that complete a previously began section are always at
{ the beginning of the TS payload... */
/* The data that complete a previously began section are always at i_data_offset = p_ts_packet->i_payload_start;
the beginning of the TS payload... */ /* ...Unless there is a pointer field, that we have to bypass */
i_data_offset = p_ts_packet->i_payload_start; if( b_unit_start )
/* ...Unless there is a pointer field, that we have to bypass */ i_data_offset++;
if( b_unit_start ) // intf_DbgMsg( "New part of the section received at offset %d\n", i_data_offset );
i_data_offset ++; }
// intf_DbgMsg( "New part of the section received at offset %d\n", i_data_offset ); }
} /* We are looking for the beginning of a new section */
else
{
if( b_unit_start )
{
/* Get the offset at which the data for that section can be found
The offset is stored in the pointer_field since we are interested in
the first section of the TS packet. Note that the +1 is to bypass
the pointer field */
i_data_offset = p_ts_packet->i_payload_start +
p_ts_packet->buffer[p_ts_packet->i_payload_start] + 1;
// intf_DbgMsg( "New section beginning at offset %d in TS packet\n", i_data_offset );
} }
/* We are looking for the beginning of a new section */
else else
{ {
if( !b_unit_start ) /* This may either mean that the TS is bad or that the packet contains
the end of a section that had been discarded in a previous loop:
trash the TS packet since we cannot do anything with those data: */
p_psi->b_running_section = 0;
p_psi->i_current_position = 0;
intf_DbgMsg( "PSI packet discarded due to lack of synchronisation\n" );
}
}
/* The section we will deal with during the first iteration of the following
loop is the first one contained in the TS packet */
// b_first_section = 1;
/* Reassemble the pieces of sections contained in the TS packet and decode
the sections that could have been completed.
Stop when we reach the end of the packet or stuffing bytes */
while( i_data_offset < TS_PACKET_SIZE && p_ts_packet->buffer[i_data_offset] != 0xFF )
{
/* If the current section is a new one, reinit the data fields of the p_psi
struct to start its decoding */
if( !p_psi->b_running_section )
{
/* Read the length of the new section */
p_psi->i_length = (U16_AT(&p_ts_packet->buffer[i_data_offset+1]) & 0xFFF) + 3;
// intf_DbgMsg( "Section length %d\n", p_psi->i_length );
if( p_psi->i_length > PSI_SECTION_SIZE )
{ {
/* Cannot do anything with those data: trash both PSI section and TS packet */ /* The TS packet is corrupted, stop here to avoid possible a seg fault */
p_psi->b_running_section = 0; intf_DbgMsg( "PSI Section size is too big, aborting its reception\n" );
break; break;
} }
else
{
/* Get the offset at which the data for that section can be found */
if( b_first_section )
{
/* The offset is stored in the pointer_field since we are interested in
the first section of the TS packet. Note that the +1 is to bypass
the pointer field */
i_data_offset = p_ts_packet->i_payload_start +
p_ts_packet->buffer[p_ts_packet->i_payload_start] + 1;
}
else
{
/* Since no gap is allowed between 2 sections in a TS packet, the
offset is given by the end of the previous section. In fact, there
is nothing to do, i_offset was set to the right value in the
previous iteration */
}
// intf_DbgMsg( "New section beginning at offset %d in TS packet\n", i_data_offset );
/* Read the length of that section */
p_psi->i_length = (U16_AT(&p_ts_packet->buffer[i_data_offset+1]) & 0xFFF) + 3;
// intf_DbgMsg( "Section length %d\n", p_psi->i_length );
if( p_psi->i_length > PSI_SECTION_SIZE )
{
/* The TS packet is corrupted, stop here to avoid possible a seg fault */
intf_DbgMsg( "Section size is too big, aborting its reception\n" );
break;
}
/* Init the reassembly of that section */ /* Init the reassembly of that section */
p_psi->b_running_section = 1; p_psi->b_running_section = 1;
p_psi->i_current_position = 0; p_psi->i_current_position = 0;
}
} }
/* Compute the length of data related to the section in this TS packet */ /* Compute the length of data related to the section in this TS packet */
if( p_psi->i_length - p_psi->i_current_position > TS_PACKET_SIZE - i_data_offset) if( p_psi->i_length - p_psi->i_current_position > TS_PACKET_SIZE - i_data_offset)
i_data_length = TS_PACKET_SIZE - i_data_offset; i_data_length = TS_PACKET_SIZE - i_data_offset;
...@@ -1200,8 +1207,9 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input, ...@@ -1200,8 +1207,9 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input,
/* Copy those data in the section buffer */ /* Copy those data in the section buffer */
memcpy( &p_psi->buffer[p_psi->i_current_position], &p_ts_packet->buffer[i_data_offset], memcpy( &p_psi->buffer[p_psi->i_current_position], &p_ts_packet->buffer[i_data_offset],
i_data_length ); i_data_length );
/* Interesting data are now after the ones we copied */ /* Interesting data are now after the ones we copied, since no gap is
allowed between 2 sections in a TS packets */
i_data_offset += i_data_length; i_data_offset += i_data_length;
/* Decode the packet if it is now complete */ /* Decode the packet if it is now complete */
...@@ -1216,7 +1224,7 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input, ...@@ -1216,7 +1224,7 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input,
p_psi->b_running_section = 0; p_psi->b_running_section = 0;
/* The new section won't be the first anymore */ /* The new section won't be the first anymore */
b_first_section = 0; //b_first_section = 0;
} }
else else
{ {
...@@ -1228,8 +1236,6 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input, ...@@ -1228,8 +1236,6 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input,
// intf_DbgMsg( "Must loop ? Next data offset: %d, stuffing: %d\n", // intf_DbgMsg( "Must loop ? Next data offset: %d, stuffing: %d\n",
// i_data_offset, p_ts_packet->buffer[i_data_offset] ); // i_data_offset, p_ts_packet->buffer[i_data_offset] );
} }
/* Stop if we reached the end of the packet or stuffing bytes */
while( i_data_offset < TS_PACKET_SIZE && p_ts_packet->buffer[i_data_offset] != 0xFF );
/* Relase the TS packet, we don't need it anymore */ /* Relase the TS packet, we don't need it anymore */
input_NetlistFreeTS( p_input, p_ts_packet ); input_NetlistFreeTS( p_input, p_ts_packet );
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
******************************************************************************* *******************************************************************************
* Manages structures containing PSI information, and affiliated decoders. * Manages structures containing PSI information, and affiliated decoders.
* TO DO: Fonctions d'init des structures * TO DO: Fonctions d'init des structures
*******************************************************************************/ ******************************************************************************/
/******************************************************************************* /*******************************************************************************
* Preamble * Preamble
*******************************************************************************/ ******************************************************************************/
#include <errno.h> #include <errno.h>
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
...@@ -77,19 +77,20 @@ static int input_DelPsiPID( input_thread_t *p_input, int i_pid ); ...@@ -77,19 +77,20 @@ static int input_DelPsiPID( input_thread_t *p_input, int i_pid );
static void DecodePgrmAssocSection( byte_t* p_pas, input_thread_t *p_input ); static void DecodePgrmAssocSection( byte_t* p_pas, input_thread_t *p_input );
static void DecodePgrmMapSection( byte_t* p_pms, input_thread_t *p_input ); static void DecodePgrmMapSection( byte_t* p_pms, input_thread_t *p_input );
static void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input ); static void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input );
static void DecodePgrmDescriptor( byte_t* p_descriptor, pgrm_descriptor_t* p_pgrm ); static void DecodePgrmDescriptor( byte_t* p_descr, pgrm_descriptor_t* p_pgrm );
static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es ); static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es );
static stream_descriptor_t* AddStreamDescr(input_thread_t* p_input, static stream_descriptor_t* AddStreamDescr( input_thread_t* p_input,
u16 i_stream_id); u16 i_stream_id );
static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id); static void DestroyStreamDescr( input_thread_t* p_input, u16 i_stream_id );
static pgrm_descriptor_t* AddPgrmDescr(stream_descriptor_t* p_stream, static pgrm_descriptor_t* AddPgrmDescr( stream_descriptor_t* p_stream,
u16 i_pgrm_id); u16 i_pgrm_id );
static void DestroyPgrmDescr(input_thread_t* p_input, stream_descriptor_t* p_stream, u16 i_pgrm_id); static void DestroyPgrmDescr( input_thread_t* p_input,
static es_descriptor_t* AddESDescr(input_thread_t* p_input, stream_descriptor_t* p_stream, u16 i_pgrm_id );
pgrm_descriptor_t* p_pgrm, u16 i_es_pid); static es_descriptor_t* AddESDescr( input_thread_t* p_input,
static void DestroyESDescr(input_thread_t* p_input, pgrm_descriptor_t* p_pgrm, pgrm_descriptor_t* p_pgrm, u16 i_es_pid );
u16 i_es_pid); static void DestroyESDescr( input_thread_t* p_input, pgrm_descriptor_t* p_pgrm,
u16 i_es_pid);
static void BuildCrc32Table(); static void BuildCrc32Table();
static int CheckCRC32( u8* p_pms, int i_size); static int CheckCRC32( u8* p_pms, int i_size);
...@@ -179,12 +180,16 @@ void input_PsiRead( input_thread_t *p_input /* ??? */ ) ...@@ -179,12 +180,16 @@ void input_PsiRead( input_thread_t *p_input /* ??? */ )
for( i_index2 = 0; i_index2 < p_pgrm->i_es_number; i_index2++ ) for( i_index2 = 0; i_index2 < p_pgrm->i_es_number; i_index2++ )
{ {
intf_DbgMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n", p_pgrm->ap_es[i_index2]->i_id, intf_DbgMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n",
p_pgrm->ap_es[i_index2]->i_type, p_pgrm->ap_es[i_index2]->b_pcr, p_pgrm->ap_es[i_index2]->i_id,
p_pgrm->ap_es[i_index2]->b_psi); p_pgrm->ap_es[i_index2]->i_type,
p_pgrm->ap_es[i_index2]->b_pcr,
intf_IntfMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n", p_pgrm->ap_es[i_index2]->i_id, p_pgrm->ap_es[i_index2]->b_psi);
p_pgrm->ap_es[i_index2]->i_type, p_pgrm->ap_es[i_index2]->b_pcr,
intf_IntfMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n",
p_pgrm->ap_es[i_index2]->i_id,
p_pgrm->ap_es[i_index2]->i_type,
p_pgrm->ap_es[i_index2]->b_pcr,
p_pgrm->ap_es[i_index2]->b_psi); p_pgrm->ap_es[i_index2]->b_psi);
} }
} }
...@@ -262,7 +267,7 @@ void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section ) ...@@ -262,7 +267,7 @@ void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section )
******************************************************************************/ ******************************************************************************/
static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input ) static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
{ {
u8 i_stream_id; /* Id of the stream described in that section */ u8 i_stream_id; /* Id of the stream described in that section */
u8 i_version; /* Version of the table carried in the section */ u8 i_version; /* Version of the table carried in the section */
u16 i_pgrm_id; /* Id of the current described pgrm */ u16 i_pgrm_id; /* Id of the current described pgrm */
...@@ -282,34 +287,34 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input ) ...@@ -282,34 +287,34 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
#define p_descr (p_input->p_stream) #define p_descr (p_input->p_stream)
/* Read stream id and version number immediately, to be sure they will be /* Read stream id and version number immediately, to be sure they will be
initialised in all cases we will need it */ initialised in all cases we will need it */
i_stream_id = U16_AT(&p_pas[3]); i_stream_id = U16_AT(&p_pas[3]);
i_version = (p_pas[5] >> 1) & 0x1F; i_version = (p_pas[5] >> 1) & 0x1F;
//intf_DbgMsg("TS Id: %d, version: %d\n", U16_AT(&p_pas[3]),(p_pas[5] >> 1) & 0x1F); //intf_DbgMsg("TS Id: %d, version: %d\n", U16_AT(&p_pas[3]),(p_pas[5] >> 1) & 0x1F);
/* Test if the stream has not changed by looking at the stream_id */ /* Test if the stream has not changed by looking at the stream_id */
if( p_descr->i_stream_id != i_stream_id ) if( p_descr->i_stream_id != i_stream_id )
{ {
/* This can either mean that the PSI decoder has just started or that /* This can either mean that the PSI decoder has just started or that
the stream has changed */ the stream has changed */
if( p_descr->i_PAT_version== PSI_UNINITIALISED ) if( p_descr->i_PAT_version== PSI_UNINITIALISED )
intf_DbgMsg("Building Program Association table\n"); intf_DbgMsg("Building Program Association table\n");
else else
intf_ErrMsg( "Stream Id has suddently changed ! Rebuilding PAT\n" ); intf_ErrMsg( "Stream Id has suddently changed ! Rebuilding PAT\n" );
/* Whatever it is, ask the PSI decoder to rebuild the table */ /* Whatever it is, ask the PSI decoder to rebuild the table */
b_is_invalid = 1; b_is_invalid = 1;
} }
else else
{ {
/* Stream has not changed, test if the PMT is up to date */ /* Stream has not changed, test if the PMT is up to date */
if( p_descr->i_PAT_version != i_version ) if( p_descr->i_PAT_version != i_version )
{ {
intf_DbgMsg("PAT has been updated, rebuilding it\n"); intf_DbgMsg("PAT has been updated, rebuilding it\n");
/* Ask the PSI decoder to rebuild the table */ /* Ask the PSI decoder to rebuild the table */
b_is_invalid = 1; b_is_invalid = 1;
} }
} }
/* Clear the table if needed */ /* Clear the table if needed */
...@@ -334,14 +339,16 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input ) ...@@ -334,14 +339,16 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
&& p_input->pp_selected_es[i_es_index]->i_id != 17 && p_input->pp_selected_es[i_es_index]->i_id != 17
#endif #endif
) )
input_DelPsiPID( p_input, p_input->pp_selected_es[i_es_index]->i_id ); input_DelPsiPID( p_input,
p_input->pp_selected_es[i_es_index]->i_id );
} }
else else
input_DelPgrmElem( p_input, p_input->pp_selected_es[i_es_index]->i_id ); input_DelPgrmElem( p_input,
p_input->pp_selected_es[i_es_index]->i_id );
} }
/* Recreate a new stream description. Since it is virgin, the decoder /* Recreate a new stream description. Since it is virgin, the decoder
will on is own rebuild it entirely */ will rebuild it entirely on is own */
DestroyStreamDescr(p_input, p_descr->i_stream_id); DestroyStreamDescr(p_input, p_descr->i_stream_id);
AddStreamDescr(p_input, i_stream_id); AddStreamDescr(p_input, i_stream_id);
...@@ -352,8 +359,9 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input ) ...@@ -352,8 +359,9 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
/* Build the table if not already complete or if it was cleared */ /* Build the table if not already complete or if it was cleared */
if( p_descr->b_is_PAT_complete ) if( p_descr->b_is_PAT_complete )
{ {
/* Nothing to do */ /* Nothing to do */
//intf_DbgMsg("Table already complete\n"); if( b_is_invalid )
intf_DbgMsg("Bug: table invalid but PAT said to be complete\n");
} }
else else
{ {
...@@ -380,10 +388,11 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input ) ...@@ -380,10 +388,11 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
{ {
i_pgrm_id = U16_AT(&p_pas[8+4*i_pgrm_index]); i_pgrm_id = U16_AT(&p_pas[8+4*i_pgrm_index]);
i_pgrm_map_pid = U16_AT(&p_pas[8+4*i_pgrm_index+2]) & 0x1FFF; i_pgrm_map_pid = U16_AT(&p_pas[8+4*i_pgrm_index+2]) & 0x1FFF;
intf_DbgMsg("Pgrm %d described on pid %d\n", i_pgrm_id, i_pgrm_map_pid); intf_DbgMsg("Pgrm %d described on pid %d\n", i_pgrm_id,
i_pgrm_map_pid);
/* Check we are not already receiving that pid because it carries info /* Check we are not already receiving that pid because it carries
for another program */ info for another program */
for( i_es_index = 0; i_es_index < INPUT_MAX_ES; i_es_index++ ) for( i_es_index = 0; i_es_index < INPUT_MAX_ES; i_es_index++ )
{ {
if( p_input->p_es[i_es_index].i_id == i_pgrm_map_pid) if( p_input->p_es[i_es_index].i_id == i_pgrm_map_pid)
...@@ -402,7 +411,7 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input ) ...@@ -402,7 +411,7 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
(Network information table) */ (Network information table) */
if( i_pgrm_id != 0 ) if( i_pgrm_id != 0 )
{ {
intf_DbgMsg("Adding program %d to the Program Map Table\n", i_pgrm_id); intf_DbgMsg("Adding program %d to the PMT\n", i_pgrm_id);
AddPgrmDescr(p_descr, i_pgrm_id); AddPgrmDescr(p_descr, i_pgrm_id);
} }
} }
...@@ -434,8 +443,8 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input ) ...@@ -434,8 +443,8 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
******************************************************************************/ ******************************************************************************/
static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input ) static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
{ {
u16 i_pgrm_number; /* Id of the program described in that section */ u16 i_pgrm_number; /* Id of the program described in that section */
u8 i_version; /* Version of the description for that program */ u8 i_version; /* Version of the description for that program */
u16 i_offset; u16 i_offset;
u16 i_section_length; u16 i_section_length;
...@@ -468,7 +477,7 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input ) ...@@ -468,7 +477,7 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
/* If none entry exists, this simply means that the PAT is not complete, /* If none entry exists, this simply means that the PAT is not complete,
so skip this section since it is the responsability of the PAT decoder so skip this section since it is the responsability of the PAT decoder
to add pgrm_descriptor slots to the table of known pgrms */ to add pgrm_descriptor slots to the table of known pgrms */
intf_DbgMsg( "Pgrm %d is unknown: skipping its description\n", i_pgrm_number ); intf_DbgMsg( "Unknown pgrm %d: skipping its description\n", i_pgrm_number );
return; return;
} }
...@@ -535,11 +544,11 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input ) ...@@ -535,11 +544,11 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
/* Compute the length of the section minus the final CRC */ /* Compute the length of the section minus the final CRC */
i_section_length = (U16_AT(&p_pms[1]) & 0xFFF) + 3 - 4; i_section_length = (U16_AT(&p_pms[1]) & 0xFFF) + 3 - 4;
intf_DbgMsg("Section length (CRC not included): %d\n", i_section_length); intf_DbgMsg("Section length (without CRC): %d\n", i_section_length);
/* Read additional info stored in the descriptors if any */ /* Read additional info stored in the descriptors if any */
intf_DbgMsg("description length for program %d: %d\n", p_pgrm->i_number, intf_DbgMsg("Description length for program %d: %d\n",
(U16_AT(&p_pms[10]) & 0x0FFF)); p_pgrm->i_number, (U16_AT(&p_pms[10]) & 0x0FFF));
i_descr_end = (U16_AT(&p_pms[10]) & 0x0FFF) + 12; i_descr_end = (U16_AT(&p_pms[10]) & 0x0FFF) + 12;
intf_DbgMsg("description ends at offset: %d\n", i_descr_end); intf_DbgMsg("description ends at offset: %d\n", i_descr_end);
...@@ -565,11 +574,12 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input ) ...@@ -565,11 +574,12 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
p_es = AddESDescr(p_input, p_pgrm, i_es_pid); p_es = AddESDescr(p_input, p_pgrm, i_es_pid);
if (!p_es) if (!p_es)
{ {
intf_ErrMsg("Warning: definition of program %d will be uncomplete\n", intf_ErrMsg("Warning: definition for pgrm %d won't be complete\n",
p_pgrm->i_number); p_pgrm->i_number);
/* The best way to handle this is to stop decoding the info for that /* The best way to handle this is to stop decoding the info for
section but do as if everything is ok. Thus we will eventually have that section but do as if everything is ok. Thus we will
an uncomplete ES table marked as being complete and some error msgs */ eventually have an uncomplete ES table marked as being
complete and some error msgs */
break; break;
} }
else else
...@@ -620,7 +630,8 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input ) ...@@ -620,7 +630,8 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
if( p_program_data->cfg.b_video ) if( p_program_data->cfg.b_video )
{ {
/* Spawn a video thread */ /* Spawn a video thread */
input_AddPgrmElem( p_input, p_input->p_es[i_es_loop].i_id ); input_AddPgrmElem( p_input,
p_input->p_es[i_es_loop].i_id );
} }
break; break;
case MPEG1_AUDIO_ES: case MPEG1_AUDIO_ES:
...@@ -628,7 +639,8 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input ) ...@@ -628,7 +639,8 @@ static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
if( p_program_data->cfg.b_audio ) if( p_program_data->cfg.b_audio )
{ {
/* Spawn an audio thread */ /* Spawn an audio thread */
input_AddPgrmElem( p_input, p_input->p_es[i_es_loop].i_id ); input_AddPgrmElem( p_input,
p_input->p_es[i_es_loop].i_id );
} }
break; break;
default: default:
...@@ -703,7 +715,8 @@ void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input ) ...@@ -703,7 +715,8 @@ void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input )
/* Find the program to which the description applies */ /* Find the program to which the description applies */
for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ ) for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
{ {
if( p_stream->ap_programs[i_index]->i_number == U16_AT(&p_sdt[i_offset]) ) if( p_stream->ap_programs[i_index]->i_number ==
U16_AT(&p_sdt[i_offset]) )
{ {
/* Here we are */ /* Here we are */
intf_DbgMsg("FOUND: %d\n", p_stream->ap_programs[i_index]->i_number); intf_DbgMsg("FOUND: %d\n", p_stream->ap_programs[i_index]->i_number);
...@@ -732,7 +745,8 @@ void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input ) ...@@ -732,7 +745,8 @@ void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input )
****************************************************************************** ******************************************************************************
* Decode any descriptor applying to the definition of a program * Decode any descriptor applying to the definition of a program
******************************************************************************/ ******************************************************************************/
static void DecodePgrmDescriptor( byte_t* p_descriptor, pgrm_descriptor_t* p_pgrm ) static void DecodePgrmDescriptor( byte_t* p_descriptor,
pgrm_descriptor_t* p_pgrm )
{ {
u8 i_type; /* Type of the descriptor */ u8 i_type; /* Type of the descriptor */
u8 i_length; /* Length of the descriptor */ u8 i_length; /* Length of the descriptor */
...@@ -763,9 +777,10 @@ static void DecodePgrmDescriptor( byte_t* p_descriptor, pgrm_descriptor_t* p_pgr ...@@ -763,9 +777,10 @@ static void DecodePgrmDescriptor( byte_t* p_descriptor, pgrm_descriptor_t* p_pgr
first byte of the name */ first byte of the name */
if( p_descriptor[i_offset] >= 0x20 ) if( p_descriptor[i_offset] >= 0x20 )
{ {
/* The charset is the one of our computer: just manually dup the string */ /* The charset is the one of our computer: just dup the string */
p_pgrm->psz_srv_name = malloc(i_length - i_offset +1); p_pgrm->psz_srv_name = malloc(i_length - i_offset +1);
memcpy(p_pgrm->psz_srv_name, &p_descriptor[i_offset], i_length - i_offset); memcpy(p_pgrm->psz_srv_name, &p_descriptor[i_offset],
i_length - i_offset);
p_pgrm->psz_srv_name[i_length - i_offset + 1] = '\0'; p_pgrm->psz_srv_name[i_length - i_offset + 1] = '\0';
} }
else else
...@@ -791,7 +806,7 @@ static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es ) ...@@ -791,7 +806,7 @@ static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es )
{ {
u8 i_type; /* Type of the descriptor */ u8 i_type; /* Type of the descriptor */
u8 i_length; /* Length of the descriptor */ u8 i_length; /* Length of the descriptor */
// int i_offset; /* Current position in the descriptor */ // int i_offset; /* Current position in the descriptor */
ASSERT(p_descriptor); ASSERT(p_descriptor);
ASSERT(p_es); ASSERT(p_es);
...@@ -870,7 +885,7 @@ static int input_AddPsiPID( input_thread_t *p_input, int i_pid ) ...@@ -870,7 +885,7 @@ static int input_AddPsiPID( input_thread_t *p_input, int i_pid )
{ {
if( !p_input->pp_selected_es[i_index] ) if( !p_input->pp_selected_es[i_index] )
{ {
intf_DbgMsg( "Free Selected ES slot found at offset %d: Will use it for PID %d\n", intf_DbgMsg( "Free Selected ES slot found at offset %d for PID %d\n",
i_index, i_pid ); i_index, i_pid );
p_input->pp_selected_es[i_index] = p_psi_es; p_input->pp_selected_es[i_index] = p_psi_es;
break; break;
...@@ -1052,7 +1067,8 @@ static void Unset_known( byte_t* a_known_section, u8 i_section ) ...@@ -1052,7 +1067,8 @@ static void Unset_known( byte_t* a_known_section, u8 i_section )
****************************************************************************** ******************************************************************************
* *
******************************************************************************/ ******************************************************************************/
static stream_descriptor_t* AddStreamDescr(input_thread_t* p_input, u16 i_stream_id) static stream_descriptor_t* AddStreamDescr(input_thread_t* p_input,
u16 i_stream_id)
{ {
ASSERT(p_input); ASSERT(p_input);
...@@ -1101,7 +1117,8 @@ static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id) ...@@ -1101,7 +1117,8 @@ static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id)
/* Free the structures that describes the programs of that stream */ /* Free the structures that describes the programs of that stream */
for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ ) for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ )
{ {
DestroyPgrmDescr( p_input, p_input->p_stream, p_input->p_stream->ap_programs[i_index]->i_number ); DestroyPgrmDescr( p_input, p_input->p_stream,
p_input->p_stream->ap_programs[i_index]->i_number );
} }
/* Free the table of pgrm descriptors */ /* Free the table of pgrm descriptors */
...@@ -1119,31 +1136,34 @@ static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id) ...@@ -1119,31 +1136,34 @@ static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id)
****************************************************************************** ******************************************************************************
* This program descriptor will be referenced in the given stream descriptor * This program descriptor will be referenced in the given stream descriptor
******************************************************************************/ ******************************************************************************/
static pgrm_descriptor_t* AddPgrmDescr(stream_descriptor_t* p_stream, u16 i_pgrm_id) static pgrm_descriptor_t* AddPgrmDescr( stream_descriptor_t* p_stream,
u16 i_pgrm_id)
{ {
int i_pgrm_index = p_stream->i_pgrm_number; /* Where to add the pgrm */
ASSERT(p_stream); ASSERT(p_stream);
intf_DbgMsg("Adding description for pgrm %d\n", i_pgrm_id); intf_DbgMsg("Adding description for pgrm %d\n", i_pgrm_id);
/* Add an entry to the list of program associated with the stream */ /* Add an entry to the list of program associated with the stream */
p_stream->i_pgrm_number++; p_stream->i_pgrm_number++;
p_stream->ap_programs = realloc( p_stream->ap_programs, p_stream->ap_programs = realloc( p_stream->ap_programs,
p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t*) ); p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t*) );
/* Allocate the structure to store this description */ /* Allocate the structure to store this description */
p_stream->ap_programs[p_stream->i_pgrm_number-1] = malloc(sizeof(pgrm_descriptor_t)); p_stream->ap_programs[i_pgrm_index] = malloc(sizeof(pgrm_descriptor_t));
/* Init this entry */ /* Init this entry */
p_stream->ap_programs[p_stream->i_pgrm_number-1]->i_number = i_pgrm_id; p_stream->ap_programs[i_pgrm_index]->i_number = i_pgrm_id;
p_stream->ap_programs[p_stream->i_pgrm_number-1]->i_version = PSI_UNINITIALISED; p_stream->ap_programs[i_pgrm_index]->i_version = PSI_UNINITIALISED;
p_stream->ap_programs[p_stream->i_pgrm_number-1]->b_is_ok = 0; p_stream->ap_programs[i_pgrm_index]->b_is_ok = 0;
p_stream->ap_programs[p_stream->i_pgrm_number-1]->i_es_number = 0; p_stream->ap_programs[i_pgrm_index]->i_es_number = 0;
p_stream->ap_programs[p_stream->i_pgrm_number-1]->ap_es = NULL; p_stream->ap_programs[i_pgrm_index]->ap_es = NULL;
/* descriptors ???? */ /* descriptors ???? */
return p_stream->ap_programs[p_stream->i_pgrm_number-1]; return p_stream->ap_programs[i_pgrm_index];
} }
/****************************************************************************** /******************************************************************************
...@@ -1151,13 +1171,16 @@ static pgrm_descriptor_t* AddPgrmDescr(stream_descriptor_t* p_stream, u16 i_pgrm ...@@ -1151,13 +1171,16 @@ static pgrm_descriptor_t* AddPgrmDescr(stream_descriptor_t* p_stream, u16 i_pgrm
****************************************************************************** ******************************************************************************
* All ES descriptions referenced in the descriptor will be deleted. * All ES descriptions referenced in the descriptor will be deleted.
******************************************************************************/ ******************************************************************************/
static void DestroyPgrmDescr( input_thread_t * p_input, stream_descriptor_t * p_stream, u16 i_pgrm_id ) static void DestroyPgrmDescr( input_thread_t * p_input,
stream_descriptor_t * p_stream, u16 i_pgrm_id )
{ {
int i_index, i_pgrm_index; int i_index, i_pgrm_index = -1;
pgrm_descriptor_t * p_pgrm; pgrm_descriptor_t* p_pgrm = NULL;
ASSERT( p_stream ); ASSERT( p_stream );
intf_DbgMsg("Deleting description for pgrm %d\n", i_pgrm_id);
/* Find where this program is described */ /* Find where this program is described */
for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ ) for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
{ {
...@@ -1169,6 +1192,10 @@ static void DestroyPgrmDescr( input_thread_t * p_input, stream_descriptor_t * p_ ...@@ -1169,6 +1192,10 @@ static void DestroyPgrmDescr( input_thread_t * p_input, stream_descriptor_t * p_
} }
} }
/* Make sure that the pgrm exists */
ASSERT(i_pgrm_index >= 0);
ASSERT(p_pgrm);
/* Free the structures that describe the es that belongs to that program */ /* Free the structures that describe the es that belongs to that program */
for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ ) for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
{ {
...@@ -1183,8 +1210,10 @@ static void DestroyPgrmDescr( input_thread_t * p_input, stream_descriptor_t * p_ ...@@ -1183,8 +1210,10 @@ static void DestroyPgrmDescr( input_thread_t * p_input, stream_descriptor_t * p_
/* Remove this program from the stream's list of programs */ /* Remove this program from the stream's list of programs */
p_stream->i_pgrm_number--; p_stream->i_pgrm_number--;
p_stream->ap_programs[ i_pgrm_index ] = p_stream->ap_programs[ p_stream->i_pgrm_number ]; p_stream->ap_programs[i_pgrm_index] =
p_stream->ap_programs = realloc( p_stream->ap_programs, p_stream->i_pgrm_number * sizeof(pgrm_descriptor_t *) ); p_stream->ap_programs[p_stream->i_pgrm_number];
p_stream->ap_programs = realloc( p_stream->ap_programs,
p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t *) );
} }
/****************************************************************************** /******************************************************************************
...@@ -1218,7 +1247,7 @@ static es_descriptor_t* AddESDescr(input_thread_t* p_input, ...@@ -1218,7 +1247,7 @@ static es_descriptor_t* AddESDescr(input_thread_t* p_input,
/* Reserve the slot for that ES */ /* Reserve the slot for that ES */
p_es = &p_input->p_es[i_index]; p_es = &p_input->p_es[i_index];
p_es->i_id = i_es_pid; p_es->i_id = i_es_pid;
intf_DbgMsg("Slot %d in p_es table reserved for ES %d\n", i_index, i_es_pid); intf_DbgMsg("Slot %d in p_es table assigned to ES %d\n", i_index, i_es_pid);
/* Init its values */ /* Init its values */
p_es->i_type = 0; /* ??? */ p_es->i_type = 0; /* ??? */
...@@ -1233,12 +1262,15 @@ static es_descriptor_t* AddESDescr(input_thread_t* p_input, ...@@ -1233,12 +1262,15 @@ static es_descriptor_t* AddESDescr(input_thread_t* p_input,
if( p_pgrm ) if( p_pgrm )
{ {
p_pgrm->i_es_number++; p_pgrm->i_es_number++;
p_pgrm->ap_es = realloc( p_pgrm->ap_es, p_pgrm->i_es_number*sizeof(es_descriptor_t *) ); p_pgrm->ap_es = realloc( p_pgrm->ap_es,
p_pgrm->i_es_number*sizeof(es_descriptor_t *) );
p_pgrm->ap_es[p_pgrm->i_es_number-1] = p_es; p_pgrm->ap_es[p_pgrm->i_es_number-1] = p_es;
intf_DbgMsg("Added ES %d to definition of pgrm %d\n", i_es_pid, p_pgrm->i_number); intf_DbgMsg( "Added ES %d to definition of pgrm %d\n",
i_es_pid, p_pgrm->i_number );
} }
else else
intf_DbgMsg("Added ES %d not added to the definition of any pgrm\n", i_es_pid); intf_DbgMsg( "Added ES %d not added to the definition of any pgrm\n",
i_es_pid );
} }
return p_es; return p_es;
...@@ -1249,12 +1281,11 @@ static es_descriptor_t* AddESDescr(input_thread_t* p_input, ...@@ -1249,12 +1281,11 @@ static es_descriptor_t* AddESDescr(input_thread_t* p_input,
****************************************************************************** ******************************************************************************
* *
******************************************************************************/ ******************************************************************************/
static void DestroyESDescr(input_thread_t* p_input, pgrm_descriptor_t* p_pgrm, u16 i_pid) static void DestroyESDescr(input_thread_t* p_input,
pgrm_descriptor_t* p_pgrm, u16 i_pid)
{ {
int i_index; int i_index;
ASSERT(p_pgrm);
/* Look for the description of the ES */ /* Look for the description of the ES */
for(i_index = 0; i_index < INPUT_MAX_ES; i_index++) for(i_index = 0; i_index < INPUT_MAX_ES; i_index++)
{ {
...@@ -1268,7 +1299,7 @@ static void DestroyESDescr(input_thread_t* p_input, pgrm_descriptor_t* p_pgrm, u ...@@ -1268,7 +1299,7 @@ static void DestroyESDescr(input_thread_t* p_input, pgrm_descriptor_t* p_pgrm, u
} }
/* Remove this ES from the description of the program if it is associated to /* Remove this ES from the description of the program if it is associated to
one */ one */
if( p_pgrm ) if( p_pgrm )
{ {
for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ ) for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ )
......
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