Commit b17f6aad authored by Sam Hocevar's avatar Sam Hocevar

Bon finalement puisque tout le monde dort, je l'ai fait :)

  . rajout de i_pes_real_size dans la structure p_pes_packet, qui vaut 0
   par d�faut, et est initialis� � la taille du payload PES annonc�e dans
   le header si celle-ci est pr�sente.
  . � chaque nouveau paquet TS, si i_pes_real_size == i_pes_size on envoie
   directement le PES au d�codeur sans attendre le d�but du PES suivant.
  . cr�ation de input_ParsePES pour y mettre le code dupliqu� de
   input_DemuxPES.

 Ca fait 1 test de plus par paquet TS, donc n�gligeable. Par contre si
des gens ayant boss� sur l'input ont le temps de v�rifier que je n'ai pas
fait de connerie, �a peut �tre int�ressant :)
parent ee9f4f3e
......@@ -59,8 +59,8 @@ typedef struct pes_packet_s
/* PES properties */
boolean_t b_data_loss; /* The previous (at least) PES packet
* has been lost. The decoders will have to find a way to recover. */
boolean_t b_data_alignment; /* used to find the beginning of a
* video or audio unit */
boolean_t b_data_alignment; /* used to find the beginning of
* a video or audio unit */
boolean_t b_has_pts; /* is the following field set ? */
mtime_t i_pts; /* the PTS for this packet (if set above) */
boolean_t b_random_access;
......@@ -69,10 +69,14 @@ typedef struct pes_packet_s
*/
u8 i_stream_id; /* payload type and id */
int i_pes_size; /* size of the current PES packet */
int i_pes_real_size; /* real size of the current
* PES packet, ie. the one
* announced in the header */
int i_ts_packets;/* number of TS packets in this PES */
/* Demultiplexer environment */
boolean_t b_discard_payload; /* is the packet messed up ? */
boolean_t b_already_parsed; /* was it already parsed ? */
byte_t * p_pes_header; /* pointer to the PES header */
byte_t * p_pes_header_save; /* temporary buffer */
......
......@@ -166,6 +166,7 @@ static __inline__ pes_packet_t* input_NetlistGetPES( input_thread_t *p_input )
p_pes_packet->b_random_access = 0;
p_pes_packet->b_discard_payload = 0;
p_pes_packet->i_pes_size = 0;
p_pes_packet->i_pes_real_size = 0;
p_pes_packet->i_ts_packets = 0;
p_pes_packet->p_first_ts = NULL;
p_pes_packet->p_last_ts = NULL;
......
......@@ -91,6 +91,8 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
ts_packet_t *ts_packet,
es_descriptor_t *p_es_descriptor,
boolean_t b_unit_start, boolean_t b_packet_lost );
static __inline__ void input_ParsePES( input_thread_t *p_input,
es_descriptor_t *p_es_descriptor );
static __inline__ void input_DemuxPSI( input_thread_t *p_input,
ts_packet_t *ts_packet,
es_descriptor_t *p_es_descriptor,
......@@ -797,7 +799,7 @@ static __inline__ void input_DemuxTS( input_thread_t *p_input,
if( !b_payload && i_dummy == 0 )
{
/* This is a packet without payload, this is allowed by the draft
As there is nothing interessant in this packet (except PCR that
As there is nothing interesting in this packet (except PCR that
have already been handled), we can trash the packet. */
intf_DbgMsg("Packet without payload received by TS demux\n");
b_trash = 1;
......@@ -865,7 +867,7 @@ static __inline__ void input_DemuxTS( input_thread_t *p_input,
/*****************************************************************************
* input_DemuxPES:
*****************************************************************************
* Gather a PES packet and analyzes its header.
* Gather a PES packet.
*****************************************************************************/
static __inline__ void input_DemuxPES( input_thread_t *p_input,
ts_packet_t *p_ts_packet,
......@@ -873,8 +875,6 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
boolean_t b_unit_start,
boolean_t b_packet_lost )
{
decoder_fifo_t * p_fifo;
u8 i_pes_header_size;
int i_dummy;
pes_packet_t* p_last_pes;
ts_packet_t * p_ts;
......@@ -904,33 +904,27 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
so parse its header and give it to the decoders */
if( b_unit_start && p_pes != NULL )
{
//intf_DbgMsg("End of PES packet %p\n", p_pes);
/* Parse the header. The header has a variable length, but in order
to improve the algorithm, we will read the 14 bytes we may be
interested in */
/* If this part of the header did not fit in the current TS packet,
copy the part of the header we are interested in to the
p_pes_header_save buffer. The buffer is dynamicly allocated if
needed so it's time expensive but this situation almost never
occurs. */
p_ts = p_pes->p_first_ts;
i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
i_dummy = 0;
if(i_ts_payload_size >= PES_HEADER_SIZE)
{
/* This part of the header entirely fits in the payload of
the first TS packet */
p_pes->p_pes_header = &(p_ts->buffer[p_ts->i_payload_start]);
}
else
if(i_ts_payload_size < PES_HEADER_SIZE)
{
/* This part of the header does not fit in the current TS packet:
copy the part of the header we are interested in to the
p_pes_header_save buffer. The buffer is dynamicly allocated if
needed so it's time expensive but this situation almost never occur. */
intf_DbgMsg("Code never tested encountered, WARNING ! (benny)\n");
if( !p_pes->p_pes_header_save )
{
p_pes->p_pes_header_save = malloc(PES_HEADER_SIZE);
}
i_dummy = 0;
do
{
memcpy(p_pes->p_pes_header_save + i_dummy,
......@@ -964,18 +958,152 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
/* The header must be read in the buffer not in any TS packet */
p_pes->p_pes_header = p_pes->p_pes_header_save;
/* Get the PES size if defined */
if( (i_dummy = U16_AT(p_pes->p_pes_header + 4)) )
{
p_pes->i_pes_real_size = i_dummy + 6;
}
}
/* Now we have the part of the PES header we were interested in:
parse it */
p_pes_header and i_pes_real_size ; we can parse it */
input_ParsePES( p_input, p_es_descriptor );
}
/* If we are at the beginning of a new PES packet, we must fetch a new
PES buffer to begin with the reassembly of this PES packet. This is
also here that we can synchronise with the stream if we we lost
packets or if the decoder has just started */
if( b_unit_start )
{
p_last_pes = p_pes;
/* Get a new one PES from the PES netlist. */
if( (p_pes = input_NetlistGetPES( p_input )) == (NULL) )
{
/* PES netlist is empty ! */
p_input->b_error = 1;
}
else
{
//intf_DbgMsg("New PES packet %p (first TS: %p)\n", p_pes, p_ts_packet);
/* Init the PES fields so that the first TS packet could be
* correctly added to the PES packet (see below) */
p_pes->p_first_ts = p_ts_packet;
p_pes->p_last_ts = NULL;
/* If the last pes packet was null, this means that the
* synchronization was lost and so warn the decoder that he
* will have to find a way to recover */
if( !p_last_pes )
p_pes->b_data_loss = 1;
/* Tell the Demux we haven't yet parsed this PES */
p_pes->b_already_parsed = 0;
/* Read the b_random_access flag status and then reinit it */
p_pes->b_random_access = p_es_descriptor->b_random;
p_es_descriptor->b_random = 0;
}
/* If the PES header fits in the first TS packet, we can
* already set p_pes->p_pes_header, and in all cases we
* set p_pes->i_pes_real_size */
if( p_ts_packet->i_payload_end - p_ts_packet->i_payload_start
>= PES_HEADER_SIZE )
{
p_pes->p_pes_header = &(p_ts_packet->buffer[p_ts_packet->i_payload_start]);
if( (i_dummy = U16_AT(p_pes->p_pes_header + 4)) )
{
p_pes->i_pes_real_size = i_dummy + 6;
}
}
}
/* If we are synchronized with the stream, and so if we are ready to
receive correctly the data, add the TS packet to the current PES
packet */
if( p_pes != NULL )
{
//intf_DbgMsg("Adding TS %p to PES %p\n", p_ts_packet, p_pes);
/* Size of the payload carried in the TS packet */
i_ts_payload_size = p_ts_packet->i_payload_end -
p_ts_packet->i_payload_start;
/* Update the relations between the TS packets */
p_ts_packet->p_prev_ts = p_pes->p_last_ts;
p_ts_packet->p_next_ts = NULL;
if( p_pes->i_ts_packets != 0 )
{
/* Regarder si il serait pas plus efficace de ne creer que
* les liens precedent->suivant pour le moment, et les
* liens suivant->precedent quand le paquet est termine */
/* Otherwise it is the first TS packet. */
p_pes->p_last_ts->p_next_ts = p_ts_packet;
}
/* Now add the TS to the PES packet */
p_pes->p_last_ts = p_ts_packet;
p_pes->i_ts_packets++;
p_pes->i_pes_size += i_ts_payload_size;
/* Stats */
#ifdef STATS
i_dummy = p_ts_packet->i_payload_end - p_ts_packet->i_payload_start;
p_es_descriptor->c_payload_bytes += i_dummy;
#endif
/* We can check if the packet is finished */
if( p_pes->i_pes_size == p_pes->i_pes_real_size )
{
/* The packet is finished, parse it */
input_ParsePES( p_input, p_es_descriptor );
/* Tell the Demux we have parsed this PES, no need to redo it */
p_pes = NULL;
}
}
else
{
/* Since we don't use the TS packet to build a PES packet, we don't
need it anymore, so give it back to the netlist */
//intf_DbgMsg("Trashing TS %p: no PES being build\n", p_ts_packet);
input_NetlistFreeTS( p_input, p_ts_packet );
}
#undef p_pes
}
/*****************************************************************************
* input_ParsePES
*****************************************************************************
* Parse a finished PES packet and analyze its header.
*****************************************************************************/
static __inline__ void input_ParsePES( input_thread_t *p_input,
es_descriptor_t *p_es_descriptor )
{
decoder_fifo_t * p_fifo;
u8 i_pes_header_size;
ts_packet_t * p_ts;
int i_ts_payload_size;
#define p_pes (p_es_descriptor->p_pes_packet)
//intf_DbgMsg("End of PES packet %p\n", p_pes);
/* First read the 6 header bytes common to all PES packets:
use them to test the PES validity */
if( (p_pes->p_pes_header[0] || p_pes->p_pes_header[1] ||
(p_pes->p_pes_header[2] != 1)) ||
/* packet_start_code_prefix != 0x000001 */
((i_dummy = U16_AT(p_pes->p_pes_header + 4)) &&
(i_dummy + 6 != p_pes->i_pes_size)) )
((p_pes->i_pes_real_size) &&
(p_pes->i_pes_real_size != p_pes->i_pes_size)) )
/* PES_packet_length is set and != total received payload */
{
/* Trash the packet and set p_pes to NULL to be sure the next PES
......@@ -1095,16 +1223,14 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
break;
case AC3_AUDIO_ES:
#if 0
/* we skip 4 bytes at the beginning of the AC3 payload */
p_ts->i_payload_start += 4;
#endif
//p_ts->i_payload_start += 4;
p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo);
break;
case DVD_SPU_ES:
/* we skip 4 bytes at the beginning of the subpicture payload */
p_ts->i_payload_start += 4;
//p_ts->i_payload_start += 4;
p_fifo = &(((spudec_thread_t *)(p_es_descriptor->p_dec))->fifo);
break;
......@@ -1152,92 +1278,11 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
input_NetlistFreePES( p_input, p_pes );
}
}
}
/* If we are at the beginning of a new PES packet, we must fetch a new
PES buffer to begin with the reassembly of this PES packet. This is
also here that we can synchronise with the stream if we we lost
packets or if the decoder has just started */
if( b_unit_start )
{
p_last_pes = p_pes;
/* Get a new one PES from the PES netlist. */
if( (p_pes = input_NetlistGetPES( p_input )) == (NULL) )
{
/* PES netlist is empty ! */
p_input->b_error = 1;
}
else
{
//intf_DbgMsg("New PES packet %p (first TS: %p)\n", p_pes, p_ts_packet);
/* Init the PES fields so that the first TS packet could be correctly
added to the PES packet (see below) */
p_pes->p_first_ts = p_ts_packet;
p_pes->p_last_ts = NULL;
/* If the last pes packet was null, this means that the synchronisation
was lost and so warn the decoder that he will have to find a way to
recover */
if( !p_last_pes )
p_pes->b_data_loss = 1;
/* Read the b_random_access flag status and then reinit it */
p_pes->b_random_access = p_es_descriptor->b_random;
p_es_descriptor->b_random = 0;
}
}
/* If we are synchronised with the stream, and so if we are ready to
receive correctly the data, add the TS packet to the current PES
packet */
if( p_pes != NULL )
{
//intf_DbgMsg("Adding TS %p to PES %p\n", p_ts_packet, p_pes);
/* Size of the payload carried in the TS packet */
i_ts_payload_size = p_ts_packet->i_payload_end -
p_ts_packet->i_payload_start;
/* Update the relations between the TS packets */
p_ts_packet->p_prev_ts = p_pes->p_last_ts;
p_ts_packet->p_next_ts = NULL;
if( p_pes->i_ts_packets != 0 )
{
/* Regarder si il serait pas plus efficace de ne creer que les liens
precedent->suivant pour le moment, et les liens suivant->precedent
quand le paquet est termine */
/* Otherwise it is the first TS packet. */
p_pes->p_last_ts->p_next_ts = p_ts_packet;
}
/* Now add the TS to the PES packet */
p_pes->p_last_ts = p_ts_packet;
p_pes->i_ts_packets++;
p_pes->i_pes_size += i_ts_payload_size;
/* Stats */
#ifdef STATS
i_dummy = p_ts_packet->i_payload_end - p_ts_packet->i_payload_start;
p_es_descriptor->c_payload_bytes += i_dummy;
#endif
}
else
{
/* Since we don't use the TS packet to build a PES packet, we don't
need it anymore, so give it back to the netlist */
//intf_DbgMsg("Trashing TS %p: no PES being build\n", p_ts_packet);
input_NetlistFreeTS( p_input, p_ts_packet );
}
#undef p_pes
}
/*****************************************************************************
* input_DemuxPSI:
*****************************************************************************
......
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