]> git.sesse.net Git - vlc/commitdiff
Bon finalement puisque tout le monde dort, je l'ai fait :)
authorSam Hocevar <sam@videolan.org>
Mon, 20 Mar 2000 04:29:00 +0000 (04:29 +0000)
committerSam Hocevar <sam@videolan.org>
Mon, 20 Mar 2000 04:29:00 +0000 (04:29 +0000)
  . 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 :)

include/input.h
include/input_netlist.h
src/input/input.c

index e18552a8865b6bdd9a3a20baf56d7a3d7bb0f8ea..970eae75c978a4791d98f7dbb29894e3cf2cf42a 100644 (file)
@@ -57,22 +57,26 @@ typedef struct ts_packet_s
 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_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_has_pts;       /* is the following field set ? */
     mtime_t                 i_pts; /* the PTS for this packet (if set above) */
     boolean_t               b_random_access;
-             /* if TRUE, in the payload of this packet, there is the first byte
-              * of a video sequence header, or the first byte of an audio frame.
-              */
+            /* if TRUE, in the payload of this packet, there is the first byte
+             * of a video sequence header, or the first byte of an audio frame.
+             */
     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 */
 
index c5b6a0c3d0b80207883ac8b929649d5882bc0417..47f8f17e4169308dc774add2e8128019a61c05fa 100644 (file)
@@ -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;
index 41accfb4f39d9089dc06f32d9671207dec51d0d9..7d6ccf487d5af6475bf1c934dcf295c2d8cb1631 100644 (file)
@@ -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,
@@ -722,7 +724,7 @@ static __inline__ void input_DemuxTS( input_thread_t *p_input,
     if( !b_adaption )
     {
         /* We don't have any adaptation_field, so payload start immediately
-         after the 4 byte TS header */
+           after the 4 byte TS header */
         p_ts_packet->i_payload_start = 4;
     }
     else
@@ -736,7 +738,7 @@ static __inline__ void input_DemuxTS( input_thread_t *p_input,
         {
             /* If the packet has both adaptation_field and payload, adaptation_field
                cannot be more than 182 bytes long; if there is only an
-           adaptation_field, it must fill the next 183 bytes. */
+               adaptation_field, it must fill the next 183 bytes. */
             if( b_payload ? (p[4] > 182) : (p[4] != 183) )
             {
                 intf_DbgMsg("input debug: invalid TS adaptation field (%p)\n",
@@ -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,
@@ -963,197 +957,19 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
                    PES_HEADER_SIZE - i_dummy);
 
             /* The header must be read in the buffer not in any TS packet */
-           p_pes->p_pes_header = p_pes->p_pes_header_save;
-        }
-
-        /* Now we have the part of the PES header we were interested in:
-           parse it */
-
-        /* 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)) )
-                   /* PES_packet_length is set and != total received payload */
-        {
-          /* Trash the packet and set p_pes to NULL to be sure the next PES
-             packet will have its b_data_lost flag set */
-          intf_DbgMsg("Corrupted PES packet received: trashed\n");
-          input_NetlistFreePES( p_input, p_pes );
-          p_pes = NULL;
-          /* Stats XXX?? */
-        }
-        else
-        {
-            /* The PES packet is valid. Check its type to test if it may
-               carry additional informations in a header extension */
-            p_pes->i_stream_id =  p_pes->p_pes_header[3];
-
-            switch( p_pes->i_stream_id )
-            {
-            case 0xBE:  /* Padding */
-            case 0xBC:  /* Program stream map */
-            case 0xBF:  /* Private stream 2 */
-            case 0xB0:  /* ECM */
-            case 0xB1:  /* EMM */
-            case 0xFF:  /* Program stream directory */
-            case 0xF2:  /* DSMCC stream */
-            case 0xF8:  /* ITU-T H.222.1 type E stream */
-                /* The payload begins immediatly after the 6 bytes header, so
-                   we have finished with the parsing */
-                i_pes_header_size = 6;
-                break;
-
-            default:
-                /* The PES header contains at least 3 more bytes: parse them */
-                p_pes->b_data_alignment = p_pes->p_pes_header[6] & 0x04;
-                p_pes->b_has_pts = p_pes->p_pes_header[7] & 0x80;
-                i_pes_header_size = p_pes->p_pes_header[8] + 9;
-
-                /* Now parse the optional header extensions (in the limit of
-                   the 14 bytes */
-                if( p_pes->b_has_pts )
-                {
-                    pcr_descriptor_t * p_pcr;
+            p_pes->p_pes_header = p_pes->p_pes_header_save;
 
-                    p_pcr = p_input->p_pcr;
-
-                    p_pes->i_pts =
-                        ( ((mtime_t)(p_pes->p_pes_header[9] & 0x0E) << 29) |
-                          (((mtime_t)U16_AT(p_pes->p_pes_header + 10) << 14) - (1 << 14)) |
-                          ((mtime_t)U16_AT(p_pes->p_pes_header + 12) >> 1) ) * 300;
-                    p_pes->i_pts /= 27;
-
-                    if( p_pcr->i_synchro_state )
-                    {
-                        switch( p_pcr->i_synchro_state )
-                        {
-                            case SYNCHRO_NOT_STARTED:
-                                p_pes->b_has_pts = 0;
-                                break;
-
-                            case SYNCHRO_START:
-                                p_pes->i_pts += p_pcr->delta_pcr;
-                                p_pcr->delta_absolute = mdate() - p_pes->i_pts + INPUT_PTS_DELAY;
-                                p_pes->i_pts += p_pcr->delta_absolute;
-                                p_pcr->i_synchro_state = 0;
-                                break;
-
-                            case SYNCHRO_REINIT: /* We skip a PES */
-                                p_pes->b_has_pts = 0;
-                                p_pcr->i_synchro_state = SYNCHRO_START;
-                                break;
-                        }
-                    }
-                    else
-                    {
-                        p_pes->i_pts += p_pcr->delta_pcr + p_pcr->delta_absolute;
-                    }
-                }
-                break;
-            }
-
-            /* Now we've parsed the header, we just have to indicate in some
-               specific TS packets where the PES payload begins (renumber
-               i_payload_start), so that the decoders can find the beginning
-               of their data right out of the box. */
-            p_ts = p_pes->p_first_ts;
-            i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
-            while( i_pes_header_size > i_ts_payload_size )
+            /* Get the PES size if defined */
+            if( (i_dummy = U16_AT(p_pes->p_pes_header + 4)) )
             {
-                /* These packets are entirely filled by the PES header. */
-                i_pes_header_size -= i_ts_payload_size;
-                p_ts->i_payload_start = p_ts->i_payload_end;
-                /* Go to the next TS packet: here we won't have to test it is
-                   not NULL because we trash the PES packets when packet lost
-                   occurs */
-                p_ts = p_ts->p_next_ts;
-                i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
-            }
-            /* This last packet is partly header, partly payload. */
-            p_ts->i_payload_start += i_pes_header_size;
-
-
-            /* Now we can eventually put the PES packet in the decoder's
-               PES fifo */
-            switch( p_es_descriptor->i_type )
-            {
-                case MPEG1_VIDEO_ES:
-                case MPEG2_VIDEO_ES:
-#ifdef OLD_DECODER
-                    p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo);
-#else
-                    p_fifo = &(((vpar_thread_t*)(p_es_descriptor->p_dec))->fifo);
-#endif
-                    break;
-
-                case MPEG1_AUDIO_ES:
-                case MPEG2_AUDIO_ES:
-                    p_fifo = &(((adec_thread_t*)(p_es_descriptor->p_dec))->fifo);
-                    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_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_fifo = &(((spudec_thread_t *)(p_es_descriptor->p_dec))->fifo);
-                    break;
-
-                default:
-                    /* This should never happen */
-                    intf_DbgMsg("Unknown stream type (%d, %d): PES trashed\n",
-                        p_es_descriptor->i_id, p_es_descriptor->i_type);
-                    p_fifo = NULL;
-                    break;
-            }
-
-            if( p_fifo != NULL )
-            {
-                vlc_mutex_lock( &p_fifo->data_lock );
-                if( DECODER_FIFO_ISFULL( *p_fifo ) )
-                {
-                    /* The FIFO is full !!! This should not happen. */
-#ifdef STATS
-                    p_input->c_packets_trashed += p_pes->i_ts_packets;
-                    p_es_descriptor->c_invalid_packets += p_pes->i_ts_packets;
-#endif
-                    input_NetlistFreePES( p_input, p_pes );
-                    intf_DbgMsg("PES trashed - fifo full ! (%d, %d)\n",
-                               p_es_descriptor->i_id, p_es_descriptor->i_type);
-                }
-        else
-                {
-                    //intf_DbgMsg("Putting %p into fifo %p/%d\n",
-                    //            p_pes, p_fifo, p_fifo->i_end);
-                    p_fifo->buffer[p_fifo->i_end] = p_pes;
-                    DECODER_FIFO_INCEND( *p_fifo );
-
-                    /* Warn the decoder that it's got work to do. */
-                    vlc_cond_signal( &p_fifo->data_wait );
-                }
-                vlc_mutex_unlock( &p_fifo->data_lock );
-            }
-            else
-            {
-                intf_DbgMsg("No fifo to receive PES %p: trash\n", p_pes);
-#ifdef STATS
-                p_input->c_packets_trashed += p_pes->i_ts_packets;
-                p_es_descriptor->c_invalid_packets += p_pes->i_ts_packets;
-#endif
-                input_NetlistFreePES( p_input, p_pes );
+                p_pes->i_pes_real_size = i_dummy + 6;
             }
         }
-    }
 
+        /* Now we have the part of the PES header we were interested in:
+           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
@@ -1173,25 +989,41 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
         {
             //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) */
+            /* 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 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 synchronised with the stream, and so if we are ready to
+    /* 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 )
@@ -1207,9 +1039,9 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
         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 */
+            /* 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;
         }
@@ -1223,6 +1055,16 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
         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
     {
@@ -1237,6 +1079,209 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
 
 
 
+/*****************************************************************************
+ * 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 */
+        ((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
+         packet will have its b_data_lost flag set */
+      intf_DbgMsg("Corrupted PES packet received: trashed\n");
+      input_NetlistFreePES( p_input, p_pes );
+      p_pes = NULL;
+      /* Stats XXX?? */
+    }
+    else
+    {
+        /* The PES packet is valid. Check its type to test if it may
+           carry additional informations in a header extension */
+        p_pes->i_stream_id =  p_pes->p_pes_header[3];
+
+        switch( p_pes->i_stream_id )
+        {
+        case 0xBE:  /* Padding */
+        case 0xBC:  /* Program stream map */
+        case 0xBF:  /* Private stream 2 */
+        case 0xB0:  /* ECM */
+        case 0xB1:  /* EMM */
+        case 0xFF:  /* Program stream directory */
+        case 0xF2:  /* DSMCC stream */
+        case 0xF8:  /* ITU-T H.222.1 type E stream */
+            /* The payload begins immediatly after the 6 bytes header, so
+               we have finished with the parsing */
+            i_pes_header_size = 6;
+            break;
+
+        default:
+            /* The PES header contains at least 3 more bytes: parse them */
+            p_pes->b_data_alignment = p_pes->p_pes_header[6] & 0x04;
+            p_pes->b_has_pts = p_pes->p_pes_header[7] & 0x80;
+            i_pes_header_size = p_pes->p_pes_header[8] + 9;
+
+            /* Now parse the optional header extensions (in the limit of
+               the 14 bytes */
+            if( p_pes->b_has_pts )
+            {
+                pcr_descriptor_t * p_pcr;
+
+                p_pcr = p_input->p_pcr;
+
+                p_pes->i_pts =
+                    ( ((mtime_t)(p_pes->p_pes_header[9] & 0x0E) << 29) |
+                      (((mtime_t)U16_AT(p_pes->p_pes_header + 10) << 14) - (1 << 14)) |
+                      ((mtime_t)U16_AT(p_pes->p_pes_header + 12) >> 1) ) * 300;
+                p_pes->i_pts /= 27;
+
+                if( p_pcr->i_synchro_state )
+                {
+                    switch( p_pcr->i_synchro_state )
+                    {
+                        case SYNCHRO_NOT_STARTED:
+                            p_pes->b_has_pts = 0;
+                            break;
+
+                        case SYNCHRO_START:
+                            p_pes->i_pts += p_pcr->delta_pcr;
+                            p_pcr->delta_absolute = mdate() - p_pes->i_pts + INPUT_PTS_DELAY;
+                            p_pes->i_pts += p_pcr->delta_absolute;
+                            p_pcr->i_synchro_state = 0;
+                            break;
+
+                        case SYNCHRO_REINIT: /* We skip a PES */
+                            p_pes->b_has_pts = 0;
+                            p_pcr->i_synchro_state = SYNCHRO_START;
+                            break;
+                    }
+                }
+                else
+                {
+                    p_pes->i_pts += p_pcr->delta_pcr + p_pcr->delta_absolute;
+                }
+            }
+            break;
+        }
+
+        /* Now we've parsed the header, we just have to indicate in some
+           specific TS packets where the PES payload begins (renumber
+           i_payload_start), so that the decoders can find the beginning
+           of their data right out of the box. */
+        p_ts = p_pes->p_first_ts;
+        i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
+        while( i_pes_header_size > i_ts_payload_size )
+        {
+            /* These packets are entirely filled by the PES header. */
+            i_pes_header_size -= i_ts_payload_size;
+            p_ts->i_payload_start = p_ts->i_payload_end;
+            /* Go to the next TS packet: here we won't have to test it is
+               not NULL because we trash the PES packets when packet lost
+               occurs */
+            p_ts = p_ts->p_next_ts;
+            i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
+        }
+        /* This last packet is partly header, partly payload. */
+        p_ts->i_payload_start += i_pes_header_size;
+
+
+        /* Now we can eventually put the PES packet in the decoder's
+           PES fifo */
+        switch( p_es_descriptor->i_type )
+        {
+            case MPEG1_VIDEO_ES:
+            case MPEG2_VIDEO_ES:
+#ifdef OLD_DECODER
+                p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo);
+#else
+                p_fifo = &(((vpar_thread_t*)(p_es_descriptor->p_dec))->fifo);
+#endif
+                break;
+
+            case MPEG1_AUDIO_ES:
+            case MPEG2_AUDIO_ES:
+                p_fifo = &(((adec_thread_t*)(p_es_descriptor->p_dec))->fifo);
+                break;
+
+            case AC3_AUDIO_ES:
+                /* we skip 4 bytes at the beginning of the AC3 payload */
+                //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_fifo = &(((spudec_thread_t *)(p_es_descriptor->p_dec))->fifo);
+                break;
+
+            default:
+                /* This should never happen */
+                intf_DbgMsg("Unknown stream type (%d, %d): PES trashed\n",
+                    p_es_descriptor->i_id, p_es_descriptor->i_type);
+                p_fifo = NULL;
+                break;
+        }
+
+        if( p_fifo != NULL )
+        {
+            vlc_mutex_lock( &p_fifo->data_lock );
+            if( DECODER_FIFO_ISFULL( *p_fifo ) )
+            {
+                /* The FIFO is full !!! This should not happen. */
+#ifdef STATS
+                p_input->c_packets_trashed += p_pes->i_ts_packets;
+                p_es_descriptor->c_invalid_packets += p_pes->i_ts_packets;
+#endif
+                input_NetlistFreePES( p_input, p_pes );
+                intf_DbgMsg("PES trashed - fifo full ! (%d, %d)\n",
+                           p_es_descriptor->i_id, p_es_descriptor->i_type);
+            }
+        else
+            {
+                //intf_DbgMsg("Putting %p into fifo %p/%d\n",
+                //            p_pes, p_fifo, p_fifo->i_end);
+                p_fifo->buffer[p_fifo->i_end] = p_pes;
+                DECODER_FIFO_INCEND( *p_fifo );
+
+                /* Warn the decoder that it's got work to do. */
+                vlc_cond_signal( &p_fifo->data_wait );
+            }
+            vlc_mutex_unlock( &p_fifo->data_lock );
+        }
+        else
+        {
+            intf_DbgMsg("No fifo to receive PES %p: trash\n", p_pes);
+#ifdef STATS
+            p_input->c_packets_trashed += p_pes->i_ts_packets;
+            p_es_descriptor->c_invalid_packets += p_pes->i_ts_packets;
+#endif
+            input_NetlistFreePES( p_input, p_pes );
+        }
+    }
+#undef p_pes
+}
+
+
 
 /*****************************************************************************
  * input_DemuxPSI: