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,23 +1117,23 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input, ...@@ -1117,23 +1117,23 @@ 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 ? */ /* Has the reassembly of a section already began in a previous packet ? */
if( p_psi->b_running_section ) if( p_psi->b_running_section )
{ {
/* Was data lost since the last TS packet ? */ /* Was data lost since the last TS packet ? */
if( b_packet_lost ) if( b_packet_lost )
{ {
/* Discard the section and wait for the begining of a new one to resynch */ /* Discard the packet and wait for the begining of a new one to resynch */
p_psi->b_running_section = 0; p_psi->b_running_section = 0;
intf_DbgMsg( "Section discarded due to packet loss\n" ); p_psi->i_current_position = 0;
intf_DbgMsg( "PSI section(s) discarded due to packet loss\n" );
} }
else else
{ {
...@@ -1142,46 +1142,54 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input, ...@@ -1142,46 +1142,54 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input,
i_data_offset = p_ts_packet->i_payload_start; i_data_offset = p_ts_packet->i_payload_start;
/* ...Unless there is a pointer field, that we have to bypass */ /* ...Unless there is a pointer field, that we have to bypass */
if( b_unit_start ) if( b_unit_start )
i_data_offset ++; i_data_offset++;
// intf_DbgMsg( "New part of the section received at offset %d\n", 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 */ /* We are looking for the beginning of a new section */
else else
{ {
if( !b_unit_start ) if( b_unit_start )
{
/* Cannot do anything with those data: trash both PSI section and TS packet */
p_psi->b_running_section = 0;
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 /* 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 first section of the TS packet. Note that the +1 is to bypass
the pointer field */ the pointer field */
i_data_offset = p_ts_packet->i_payload_start + i_data_offset = 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] + 1;
// intf_DbgMsg( "New section beginning at offset %d in TS packet\n", i_data_offset );
} }
else else
{ {
/* Since no gap is allowed between 2 sections in a TS packet, the /* This may either mean that the TS is bad or that the packet contains
offset is given by the end of the previous section. In fact, there the end of a section that had been discarded in a previous loop:
is nothing to do, i_offset was set to the right value in the trash the TS packet since we cannot do anything with those data: */
previous iteration */ p_psi->b_running_section = 0;
p_psi->i_current_position = 0;
intf_DbgMsg( "PSI packet discarded due to lack of synchronisation\n" );
}
} }
// intf_DbgMsg( "New section beginning at offset %d in TS packet\n", i_data_offset );
/* Read the length of that section */ /* 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; 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 ); // intf_DbgMsg( "Section length %d\n", p_psi->i_length );
if( p_psi->i_length > PSI_SECTION_SIZE ) if( p_psi->i_length > PSI_SECTION_SIZE )
{ {
/* The TS packet is corrupted, stop here to avoid possible a seg fault */ /* The TS packet is corrupted, stop here to avoid possible a seg fault */
intf_DbgMsg( "Section size is too big, aborting its reception\n" ); intf_DbgMsg( "PSI Section size is too big, aborting its reception\n" );
break; break;
} }
...@@ -1189,7 +1197,6 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input, ...@@ -1189,7 +1197,6 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input,
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)
...@@ -1201,7 +1208,8 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input, ...@@ -1201,7 +1208,8 @@ static __inline__ void input_DemuxPSI( input_thread_t *p_input,
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,18 +77,19 @@ static int input_DelPsiPID( input_thread_t *p_input, int i_pid ); ...@@ -77,18 +77,19 @@ 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 );
static void DestroyESDescr( input_thread_t* p_input, pgrm_descriptor_t* p_pgrm,
u16 i_es_pid); u16 i_es_pid);
static void BuildCrc32Table(); static void BuildCrc32Table();
...@@ -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]->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);
intf_IntfMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n", p_pgrm->ap_es[i_index2]->i_id, intf_IntfMsg( " ->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]->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);
} }
} }
...@@ -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);
...@@ -353,7 +360,8 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input ) ...@@ -353,7 +360,8 @@ static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
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);
} }
} }
...@@ -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
...@@ -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,8 +1136,11 @@ static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id) ...@@ -1119,8 +1136,11 @@ 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);
...@@ -1131,19 +1151,19 @@ static pgrm_descriptor_t* AddPgrmDescr(stream_descriptor_t* p_stream, u16 i_pgrm ...@@ -1131,19 +1151,19 @@ static pgrm_descriptor_t* AddPgrmDescr(stream_descriptor_t* p_stream, u16 i_pgrm
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++)
{ {
......
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