]> git.sesse.net Git - vlc/blobdiff - src/input/input.c
. le d�codeur de sous-titres s'appelle maintenant spu_decoder
[vlc] / src / input / input.c
index dd7b798c9bfa5967cbaa48b78287f7e189d42232..eca9a82b8ef57e060ad5f2b785e0647d6d9bd56e 100644 (file)
 #include <sys/uio.h>                                               
 #include <string.h>
 
-#include <X11/Xlib.h>
-#include <X11/extensions/XShm.h>
-#include <sys/soundcard.h>
-
 #include <stdlib.h>                            
 #include <stdio.h>
 #include <sys/ioctl.h>                                            
 /******************************************************************************
  * Local prototypes
  ******************************************************************************/
-static void input_Thread( input_thread_t *p_input );
-static void ErrorThread( input_thread_t *p_input );
-static void EndThread( input_thread_t *p_input );
-static __inline__ int input_ReadPacket( input_thread_t *p_input );
-static __inline__ void input_SortPacket( input_thread_t *p_input,
-                                         ts_packet_t *ts_packet );
-static __inline__ void input_DemuxTS( input_thread_t *p_input,
-                                      ts_packet_t *ts_packet,
-                                      es_descriptor_t *es_descriptor );
-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_DemuxPSI( input_thread_t *p_input,
+static void RunThread   ( input_thread_t *p_input );
+static void ErrorThread ( input_thread_t *p_input );
+static void EndThread   ( input_thread_t *p_input );
+
+static __inline__ int   input_ReadPacket( input_thread_t *p_input );
+static __inline__ void  input_SortPacket( input_thread_t *p_input,
+                                          ts_packet_t *ts_packet );
+static __inline__ void  input_DemuxTS( 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 );
+                                       es_descriptor_t *es_descriptor );
+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_DemuxPSI( 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 );
 
 /*******************************************************************************
- * input_CreateThread: initialize and spawn an input thread
+ * input_CreateThread: creates a new input thread
  *******************************************************************************
- * This function initializes and spawns an input thread. It returns NULL on
- * failure. If you want a better understanding of the input thread, don't start
- * by reading this function :-).
+ * This function creates a new input, and returns a pointer
+ * to its description. On error, it returns NULL.
+ * If pi_status is NULL, then the function will block until the thread is ready.
+ * If not, it will be updated using one of the THREAD_* constants.
  *******************************************************************************/
-input_thread_t *input_CreateThread( input_cfg_t *p_cfg )
+input_thread_t *input_CreateThread ( int i_method, char *psz_source, int i_port, int i_vlan,
+                                     p_vout_thread_t p_vout, p_aout_thread_t p_aout, int *pi_status )
 {
-    input_thread_t *    p_input;
-    int i_index;
+    input_thread_t *    p_input;                          /* thread descriptor */
+    int                 i_status;                             /* thread status */    
+    int                 i_index;            /* index for tables initialization */    
     
-    intf_DbgMsg("input debug 1-1: creating thread (cfg : %p)\n", p_cfg );
-
-    /* Allocate input_thread_t structure. */
-    if( !( p_input = (input_thread_t *)malloc(sizeof(input_thread_t)) ) )
+    /* Allocate descriptor */
+    intf_DbgMsg("\n");
+    p_input = (input_thread_t *)malloc( sizeof(input_thread_t) );
+    if( p_input == NULL )
     {
-        intf_ErrMsg("input error: can't allocate input thread structure (%s)\n",
-                    strerror(errno));
+        intf_ErrMsg("error: %s\n", strerror(ENOMEM));
         return( NULL );
     }
-    /* Init it */
-    bzero( p_input, sizeof(input_thread_t));
-    for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ )
+
+    /* Initialize thread properties */
+    p_input->b_die              = 0;
+    p_input->b_error            = 0;
+    p_input->pi_status          = (pi_status != NULL) ? pi_status : &i_status;
+    *p_input->pi_status         = THREAD_CREATE;
+
+    /* Initialize input method description */
+    p_input->i_method           = i_method;
+    p_input->psz_source         = psz_source;
+    p_input->i_port             = i_port;
+    p_input->i_vlan             = i_vlan;
+    switch( i_method )
     {
-        p_input->p_es[i_index].i_id = EMPTY_PID;
+    case INPUT_METHOD_TS_FILE:                                 /* file methods */
+        p_input->p_Open =   input_FileOpen;
+        p_input->p_Read =   input_FileRead;
+        p_input->p_Close =  input_FileClose;
+        break;
+    case INPUT_METHOD_TS_VLAN_BCAST:                    /* vlan network method */        
+        if( !p_main->b_vlans )
+        {
+            intf_ErrMsg("error: vlans are not activated\n");
+            free( p_input );
+            return( NULL );            
+        }        
+        /* ... pass through */
+    case INPUT_METHOD_TS_UCAST:                             /* network methods */
+    case INPUT_METHOD_TS_MCAST:
+    case INPUT_METHOD_TS_BCAST:
+        p_input->p_Open =   input_NetworkOpen;
+        p_input->p_Read =   input_NetworkRead;
+        p_input->p_Close =  input_NetworkClose;
+        break;
+    default:
+        intf_ErrMsg("error: unknow input method\n");
+        free( p_input );
+        return( NULL );  
+        break;            
     }
 
-    /* Find out which method we are gonna use and retrieve pointers. */
-    if( !((p_cfg->i_properties) & INPUT_CFG_METHOD) )
+    /* Initialize stream description */
+    for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ )
     {
-        /* i_method is not set. */
-        intf_DbgMsg("input debug: using default method (%d)\n",
-                    INPUT_DEFAULT_METHOD);
-        p_cfg->i_method = INPUT_DEFAULT_METHOD;
-        p_cfg->i_properties |= INPUT_CFG_METHOD;
+        p_input->p_es[i_index].i_id = EMPTY_PID;
     }
-    p_input->i_method = p_cfg->i_method;
-    switch( p_cfg->i_method )
-    {
-        /* File methods */
-        case INPUT_METHOD_TS_FILE:
-            p_input->p_open = &input_FileCreateMethod;
-            p_input->p_read = &input_FileRead;
-            p_input->p_clean = &input_FileDestroyMethod;
-            break;
-
-        /* Network methods */
-        case INPUT_METHOD_TS_UCAST:
-        case INPUT_METHOD_TS_MCAST:
-        case INPUT_METHOD_TS_BCAST:
-        case INPUT_METHOD_TS_VLAN_BCAST:
-            p_input->p_open = &input_NetworkCreateMethod;
-            p_input->p_read = &input_NetworkRead;
-            p_input->p_clean = &input_NetworkDestroyMethod;
-            break;
+    
+    /* Initialize default settings for spawned decoders */
+    p_input->p_aout                     = p_aout;
+    p_input->p_vout                     = p_vout; 
 
-        case INPUT_METHOD_NONE:
-        default:
-#ifdef DEBUG
-            /* Internal error, which should never happen */
-            intf_DbgMsg("input debug: unknow method type %d\n",
-                            p_cfg->i_method);
-            return( NULL );
+#ifdef STATS
+    /* Initialize statistics */
+    p_input->c_loops                    = 0;    
+    p_input->c_bytes                    = 0;
+    p_input->c_payload_bytes            = 0;
+    p_input->c_packets_read             = 0;
+    p_input->c_packets_trashed          = 0;
 #endif
-            break;
-    }
 
-    /* Initialize PSI decoder. */
-    intf_DbgMsg("Initializing PSI decoder\n");
-    if( input_PsiInit( p_input ) == -1 )
+    /* Initialize PSI and PCR decoders */
+    if( input_PsiInit( p_input ) )
     {
         free( p_input );
         return( NULL );
     }
 
-    /* Initialize PCR decoder. */
-    intf_DbgMsg("Initializing PCR decoder\n");
-    if( input_PcrInit( p_input ) == -1 )
+    if( input_PcrInit( p_input ) )
     {
-        input_PsiClean( p_input );
+        input_PsiEnd( p_input );
         free( p_input );
         return( NULL );
     }
 
-    /* Initialize netlists. */
-    if( input_NetlistOpen( p_input ) )
+    /* Initialize netlists */
+    if( input_NetlistInit( p_input ) )
     {
-        input_PsiClean( p_input );
-        input_PcrClean( p_input );
+        input_PsiEnd( p_input );
+        input_PcrEnd( p_input );
         free( p_input );
         return( NULL );
     }
 
-#ifdef STATS
-    /* Initialize counters. */
-    p_input->c_bytes = 0;
-    p_input->c_payload_bytes = 0;
-    p_input->c_ts_packets_read = 0;
-    p_input->c_ts_packets_trashed = 0;
-#ifdef DEBUG
-    p_input->c_loops = 0;
-#endif
-#endif
+    intf_DbgMsg("configuration: method=%d, source=%s, port=%d, vlan=%d\n", 
+                i_method, psz_source, i_port, i_vlan );    
 
     /* Let the appropriate method open the socket. */
-    if( (*(p_input->p_open))( p_input, p_cfg ) == -1 )
+    if( p_input->p_Open( p_input ) )
     {
-        input_NetlistClean( p_input );
-        input_PsiClean( p_input );
-        input_PcrClean( p_input );
+        input_NetlistEnd( p_input );
+        input_PsiEnd( p_input );
+        input_PcrEnd( p_input );
         free( p_input );
         return( NULL );
     }
 
-    intf_DbgMsg("input debug: method %d properly initialized the socket\n",
-                p_input->i_method);
-
     /* Create thread and set locks. */
-    p_input->b_die = 0;
     vlc_mutex_init( &p_input->netlist.lock );
     vlc_mutex_init( &p_input->programs_lock );
     vlc_mutex_init( &p_input->es_lock );
-#ifdef NO_THREAD
-    input_Thread( p_input );
-#else
-    if( vlc_thread_create(&p_input->thread_id, "input", (vlc_thread_func_t)input_Thread, 
-                       (void *) p_input) )
+    if( vlc_thread_create(&p_input->thread_id, "input", (void *) RunThread, (void *) p_input) )
     {
-        intf_ErrMsg("input error: can't spawn input thread (%s)\n", 
-                    strerror(errno) );
-        (*p_input->p_clean)( p_input );
-        input_NetlistClean( p_input );;
-        input_PsiClean( p_input );
-        input_PcrClean( p_input );
+        intf_ErrMsg("error: %s\n", strerror(errno) );
+        p_input->p_Close( p_input );
+        input_NetlistEnd( p_input );;
+        input_PsiEnd( p_input );
+        input_PcrEnd( p_input );
         free( p_input );
         return( NULL );
     }
-#endif
-
-    /* Default setting for new decoders */
-    p_input->p_aout = p_cfg->p_aout;
-
+    intf_Msg("Input initialized\n");
+    /* If status is NULL, wait until the thread is created */
+    if( pi_status == NULL )
+    {
+        do
+        {            
+            msleep( THREAD_SLEEP );
+        }while( (i_status != THREAD_READY) && (i_status != THREAD_ERROR) 
+                && (i_status != THREAD_FATAL) );
+        if( i_status != THREAD_READY )
+        {
+            return( NULL );            
+        }        
+    }
     return( p_input );
 }
 
@@ -221,13 +224,26 @@ input_thread_t *input_CreateThread( input_cfg_t *p_cfg )
  ******************************************************************************
  * This function should not return until the thread is effectively cancelled.
  ******************************************************************************/
-void input_DestroyThread( input_thread_t *p_input )
+void input_DestroyThread( input_thread_t *p_input, int *pi_status )
 {
-    intf_DbgMsg("input debug: requesting termination of input thread\n");
-    p_input->b_die = 1;                          /* ask thread to kill itself */
+    int         i_status;                                    /* thread status */
 
-    /* Remove this as soon as the "status" flag is implemented */
-    vlc_thread_join( p_input->thread_id );            /* wait until it's done */
+    /* Set status */
+    p_input->pi_status = (pi_status != NULL) ? pi_status : &i_status;
+    *p_input->pi_status = THREAD_DESTROY;    
+     
+    /* Request thread destruction */
+    p_input->b_die = 1;
+
+    /* If status is NULL, wait until thread has been destroyed */
+    if( pi_status == NULL )
+    {
+        do
+        {
+            msleep( THREAD_SLEEP );
+        }while( (i_status != THREAD_OVER) && (i_status != THREAD_ERROR) 
+                && (i_status != THREAD_FATAL) );   
+    }
 }
 
 #if 0
@@ -277,13 +293,42 @@ void input_CloseVideoStream( input_thread_t *p_input, int i_id )
 /* following functions are local */
 
 /*******************************************************************************
- * input_Thread: input thread
+ * InitThread: initialize input thread
+ *******************************************************************************
+ * This function is called from RunThread and performs the second step of the
+ * initialization. It returns 0 on success. Note that the thread's flag are not
+ * modified inside this function.
+ *******************************************************************************/
+static int InitThread( input_thread_t *p_input )
+{
+    /* Mark thread as running and return */
+    intf_DbgMsg("\n");
+    *p_input->pi_status =        THREAD_READY;    
+    intf_DbgMsg("thread ready\n");    
+    return( 0 );    
+}
+
+/*******************************************************************************
+ * RunThread: main thread loop
  *******************************************************************************
  * Thread in charge of processing the network packets and demultiplexing.
  *******************************************************************************/
-static void input_Thread( input_thread_t *p_input )
+static void RunThread( input_thread_t *p_input )
 {
-    intf_DbgMsg("input debug 11-1: thread %p is active\n", p_input);
+    /* 
+     * Initialize thread and free configuration 
+     */
+    p_input->b_error = InitThread( p_input );
+    if( p_input->b_error )
+    {
+        free( p_input );                                 /* destroy descriptor */
+        return;        
+    }
+
+    /*
+     * Main loop
+     */
+    intf_DbgMsg("\n");
     while( !p_input->b_die && !p_input->b_error )
     {
         /* Scatter read the UDP packet from the network or the file. */
@@ -299,27 +344,33 @@ static void input_Thread( input_thread_t *p_input )
 #endif
     }
 
+    /*
+     * Error loop
+     */
     if( p_input->b_error )
     {
         ErrorThread( p_input );
     }
 
-    /* Ohoh, we have to die as soon as possible. */
+    /* End of thread */
     EndThread( p_input );
-
-    intf_DbgMsg("input debug: thread %p destroyed\n", p_input);
-    vlc_thread_exit();
+    intf_DbgMsg("thread end\n");
 }
 
 
 /******************************************************************************
  * ErrorThread: RunThread() error loop
+ *******************************************************************************
+ * This function is called when an error occured during thread main's loop. 
  ******************************************************************************/
 static void ErrorThread( input_thread_t *p_input )
 {
+    /* Wait until a `die' order */
+    intf_DbgMsg("\n");
     while( !p_input->b_die )
     {
-        msleep( INPUT_IDLE_SLEEP );
+        /* Sleep a while */
+        msleep( VOUT_IDLE_SLEEP );
     }
 }
 
@@ -328,44 +379,61 @@ static void ErrorThread( input_thread_t *p_input )
  *******************************************************************************/
 static void EndThread( input_thread_t * p_input )
 {
-    int i_es_loop;
+    int *       pi_status;                                    /* threas status */
+    int         i_es_loop;                                         /* es index */
 
-    (*p_input->p_clean)( p_input );           /* close input method */
+    /* Store status */
+    intf_DbgMsg("\n");
+    pi_status = p_input->pi_status;    
+    *pi_status = THREAD_END;  
 
-    /* Destroy all decoder threads. */
-    for( i_es_loop = 0; i_es_loop < INPUT_MAX_ES; i_es_loop++ )
-    {
-        if( p_input->pp_selected_es[i_es_loop] )
-        {
-            switch( p_input->pp_selected_es[i_es_loop]->i_type )
-            {
-                case MPEG1_VIDEO_ES:
-                case MPEG2_VIDEO_ES:
-                    vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) /*, NULL */ );
-                    break;
+    /* Close input method */
+    p_input->p_Close( p_input );
 
-                case MPEG1_AUDIO_ES:
-                case MPEG2_AUDIO_ES:
-                    adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) );
-                    break;
-
-                default:
-                    break;
-            }
-        }
-        else
+    /* Destroy all decoder threads */
+    for( i_es_loop = 0; 
+         (i_es_loop < INPUT_MAX_ES) && (p_input->pp_selected_es[i_es_loop] != NULL) ; 
+         i_es_loop++ )
+    {
+        switch( p_input->pp_selected_es[i_es_loop]->i_type )
         {
-            /* pp_selected_es should not contain any hole. */
+        case MPEG1_VIDEO_ES:
+        case MPEG2_VIDEO_ES:
+#ifdef OLD_DECODER
+            vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) /*, NULL */ );
+#else
+            vpar_DestroyThread( (vpar_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) /*, NULL */ );
+#endif
+            break;            
+        case MPEG1_AUDIO_ES:
+        case MPEG2_AUDIO_ES:
+            adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) );
+            break;
+        case AC3_AUDIO_ES:
+            ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
+            break;
+        case DVD_SPU_ES:
+            fprintf(stderr, "input.h : destroying spudec\n");
+            spudec_DestroyThread( (spudec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
             break;
+        case 0:
+            /* Special streams for the PSI decoder, PID 0 and 1 */
+            break;
+#ifdef DEBUG
+        default:
+            intf_DbgMsg("error: unknown decoder type %d\n", p_input->pp_selected_es[i_es_loop]->i_type );
+            break;                
+#endif
         }
     }
 
-    input_NetlistClean( p_input );                           /* clean netlist */
-    input_PsiClean( p_input );                       /* clean PSI information */
-    input_PcrClean( p_input );                       /* clean PCR information */
-    free( p_input );                           /* free input_thread structure */
+    input_NetlistEnd( p_input );                              /* clean netlist */
+    input_PsiEnd( p_input );                          /* clean PSI information */
+    input_PcrEnd( p_input );                          /* clean PCR information */
+    free( p_input );                            /* free input_thread structure */
 
-    intf_DbgMsg("input debug: EndThread(%p)\n", p_input);
+    /* Update status */
+    *pi_status = THREAD_OVER;    
 }
 
 /*******************************************************************************
@@ -418,7 +486,7 @@ static __inline__ int input_ReadPacket( input_thread_t *p_input )
 #endif /* FIFO netlist */
 
     /* Scatter read the buffer. */
-    i_packet_size = (*p_input->p_read)( p_input,
+    i_packet_size = (*p_input->p_Read)( p_input,
                            &p_input->netlist.p_ts_free[i_base_index],
                            INPUT_TS_READ_ONCE );
     if( i_packet_size == (-1) )
@@ -510,10 +578,10 @@ static __inline__ int input_ReadPacket( input_thread_t *p_input )
 #endif
 
 #ifdef STATS
-    p_input->c_ts_packets_read += i_current_index - i_base_index;
+    p_input->c_packets_read += i_current_index - i_base_index;
     p_input->c_bytes += (i_current_index - i_base_index) * TS_PACKET_SIZE;
 #endif
-       return( 0 );
+    return( 0 );
 }
 
 /*******************************************************************************
@@ -580,7 +648,7 @@ static __inline__ void input_SortPacket( input_thread_t *p_input,
 //                     U16_AT(&p_ts_packet->buffer[1]) & 0x1fff);
     input_NetlistFreeTS( p_input, p_ts_packet );
 #ifdef STATS
-    p_input->c_ts_packets_trashed++;
+    p_input->c_packets_trashed++;
 #endif
 }
 
@@ -738,7 +806,7 @@ static __inline__ void input_DemuxTS( input_thread_t *p_input,
     {
         input_NetlistFreeTS( p_input, p_ts_packet );
 #ifdef STATS
-        p_input->c_ts_packets_trashed++;
+        p_input->c_packets_trashed++;
 #endif
     }
     else
@@ -910,7 +978,7 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
                 /* 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 = 9 + p_pes->p_pes_header[8];
+                i_pes_header_size = p_pes->p_pes_header[8] + 9;
 
                 /* Now parse the optional header extensions (in the limit of
                    the 14 bytes */
@@ -936,7 +1004,7 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
 
                             case SYNCHRO_START:
                                 p_pes->i_pts += p_pcr->delta_pcr;
-                                p_pcr->delta_absolute = mdate() - p_pes->i_pts + 500000;
+                                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;
@@ -975,24 +1043,44 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
             /* 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:
-                p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo);
-                break;
-            case MPEG1_AUDIO_ES:
-            case MPEG2_AUDIO_ES:
-                p_fifo = &(((adec_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;
+                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;
+                    fprintf(stderr, "input.h : launching spudec\n");
+                    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 )
@@ -1002,7 +1090,7 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
                 {
                     /* The FIFO is full !!! This should not happen. */
 #ifdef STATS
-                    p_input->c_ts_packets_trashed += p_pes->i_ts_packets;
+                    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 );
@@ -1025,7 +1113,7 @@ static __inline__ void input_DemuxPES( input_thread_t *p_input,
             {
                 intf_DbgMsg("No fifo to receive PES %p: trash\n", p_pes);
 #ifdef STATS
-                p_input->c_ts_packets_trashed += p_pes->i_ts_packets;
+                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 );