]> git.sesse.net Git - vlc/blob - src/input/input.c
588995729e27b0b1a47f50325817ac1f2b028a3e
[vlc] / src / input / input.c
1 /*****************************************************************************
2  * input.c: input thread
3  * (c)1998 VideoLAN
4  *****************************************************************************
5  * Read an MPEG2 stream, demultiplex and parse it before sending it to
6  * decoders.
7  *****************************************************************************/
8
9 /*****************************************************************************
10  * Preamble
11  *****************************************************************************/
12 #include <errno.h>
13 #include <sys/uio.h>
14 #include <string.h>
15
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <sys/ioctl.h>
19 #include <net/if.h>
20 #include <netinet/in.h>
21
22 #include "common.h"
23 #include "config.h"
24 #include "mtime.h"
25 #include "vlc_thread.h"
26 #include "intf_msg.h"
27 #include "debug.h"
28
29 #include "input.h"
30 #include "input_psi.h"
31 #include "input_pcr.h"
32 #include "input_netlist.h"
33 #include "decoder_fifo.h"
34 #include "input_file.h"
35 #include "input_network.h"
36
37 #include "audio_output.h"
38 #include "audio_decoder.h"
39
40 #include "video.h"
41 #include "video_output.h"
42 #include "vdec_idct.h"
43 #include "vdec_motion.h"
44 #include "video_decoder.h"
45 #include "vpar_blocks.h"
46 #include "vpar_headers.h"
47 #include "vpar_synchro.h"
48 #include "video_parser.h"
49
50 #include "ac3_decoder.h"
51 #include "ac3_decoder_thread.h"
52 #include "spu_decoder.h"
53
54 #include "main.h"
55
56 /*****************************************************************************
57  * Local prototypes
58  *****************************************************************************/
59 static void RunThread   ( input_thread_t *p_input );
60 static void ErrorThread ( input_thread_t *p_input );
61 static void EndThread   ( input_thread_t *p_input );
62
63 static __inline__ int   input_ReadPacket( input_thread_t *p_input );
64 static __inline__ void  input_SortPacket( input_thread_t *p_input,
65                                           ts_packet_t *ts_packet );
66 static __inline__ void  input_DemuxTS( input_thread_t *p_input,
67                                        ts_packet_t *ts_packet,
68                                        es_descriptor_t *es_descriptor );
69 static __inline__ void  input_DemuxPES( input_thread_t *p_input,
70                                         ts_packet_t *ts_packet,
71                                         es_descriptor_t *p_es_descriptor,
72                                         boolean_t b_unit_start, boolean_t b_packet_lost );
73 static __inline__ void  input_DemuxPSI( input_thread_t *p_input,
74                                         ts_packet_t *ts_packet,
75                                         es_descriptor_t *p_es_descriptor,
76                                         boolean_t b_unit_start, boolean_t b_packet_lost );
77
78 /*****************************************************************************
79  * input_CreateThread: creates a new input thread
80  *****************************************************************************
81  * This function creates a new input, and returns a pointer
82  * to its description. On error, it returns NULL.
83  * If pi_status is NULL, then the function will block until the thread is ready.
84  * If not, it will be updated using one of the THREAD_* constants.
85  *****************************************************************************/
86 input_thread_t *input_CreateThread ( int i_method, char *psz_source, int i_port, int i_vlan,
87                                      p_vout_thread_t p_vout, p_aout_thread_t p_aout, int *pi_status )
88 {
89     input_thread_t *    p_input;                        /* thread descriptor */
90     int                 i_status;                           /* thread status */
91     int                 i_index;          /* index for tables initialization */
92
93     /* Allocate descriptor */
94     intf_DbgMsg("\n");
95     p_input = (input_thread_t *)malloc( sizeof(input_thread_t) );
96     if( p_input == NULL )
97     {
98         intf_ErrMsg("error: %s\n", strerror(ENOMEM));
99         return( NULL );
100     }
101
102     /* Initialize thread properties */
103     p_input->b_die              = 0;
104     p_input->b_error            = 0;
105     p_input->pi_status          = (pi_status != NULL) ? pi_status : &i_status;
106     *p_input->pi_status         = THREAD_CREATE;
107
108     /* Initialize input method description */
109     p_input->i_method           = i_method;
110     p_input->psz_source         = psz_source;
111     p_input->i_port             = i_port;
112     p_input->i_vlan             = i_vlan;
113     switch( i_method )
114     {
115     case INPUT_METHOD_TS_FILE:                               /* file methods */
116         p_input->p_Open =   input_FileOpen;
117         p_input->p_Read =   input_FileRead;
118         p_input->p_Close =  input_FileClose;
119         break;
120     case INPUT_METHOD_TS_VLAN_BCAST:                  /* vlan network method */
121         if( !p_main->b_vlans )
122         {
123             intf_ErrMsg("error: vlans are not activated\n");
124             free( p_input );
125             return( NULL );
126         }
127         /* ... pass through */
128     case INPUT_METHOD_TS_UCAST:                           /* network methods */
129     case INPUT_METHOD_TS_MCAST:
130     case INPUT_METHOD_TS_BCAST:
131         p_input->p_Open =   input_NetworkOpen;
132         p_input->p_Read =   input_NetworkRead;
133         p_input->p_Close =  input_NetworkClose;
134         break;
135     default:
136         intf_ErrMsg("error: unknow input method\n");
137         free( p_input );
138         return( NULL );
139         break;
140     }
141
142     /* Initialize stream description */
143     for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ )
144     {
145         p_input->p_es[i_index].i_id = EMPTY_PID;
146         p_input->pp_selected_es[i_index] = NULL;
147     }
148
149     /* Initialize default settings for spawned decoders */
150     p_input->p_aout                     = p_aout;
151     p_input->p_vout                     = p_vout;
152
153 #ifdef STATS
154     /* Initialize statistics */
155     p_input->c_loops                    = 0;
156     p_input->c_bytes                    = 0;
157     p_input->c_payload_bytes            = 0;
158     p_input->c_packets_read             = 0;
159     p_input->c_packets_trashed          = 0;
160 #endif
161
162     /* Initialize PSI and PCR decoders */
163     if( input_PsiInit( p_input ) )
164     {
165         free( p_input );
166         return( NULL );
167     }
168
169     if( input_PcrInit( p_input ) )
170     {
171         input_PsiEnd( p_input );
172         free( p_input );
173         return( NULL );
174     }
175
176     /* Initialize netlists */
177     if( input_NetlistInit( p_input ) )
178     {
179         input_PsiEnd( p_input );
180         input_PcrEnd( p_input );
181         free( p_input );
182         return( NULL );
183     }
184
185     intf_DbgMsg("configuration: method=%d, source=%s, port=%d, vlan=%d\n",
186                 i_method, psz_source, i_port, i_vlan );
187
188     /* Let the appropriate method open the socket. */
189     if( p_input->p_Open( p_input ) )
190     {
191         input_NetlistEnd( p_input );
192         input_PsiEnd( p_input );
193         input_PcrEnd( p_input );
194         free( p_input );
195         return( NULL );
196     }
197
198     /* Create thread and set locks. */
199     vlc_mutex_init( &p_input->netlist.lock );
200     vlc_mutex_init( &p_input->programs_lock );
201     vlc_mutex_init( &p_input->es_lock );
202     if( vlc_thread_create(&p_input->thread_id, "input", (void *) RunThread, (void *) p_input) )
203     {
204         intf_ErrMsg("error: %s\n", strerror(errno) );
205         p_input->p_Close( p_input );
206         input_NetlistEnd( p_input );;
207         input_PsiEnd( p_input );
208         input_PcrEnd( p_input );
209         free( p_input );
210         return( NULL );
211     }
212
213     intf_Msg("Input initialized\n");
214
215     /* If status is NULL, wait until the thread is created */
216     if( pi_status == NULL )
217     {
218         do
219         {
220             msleep( THREAD_SLEEP );
221         }while( (i_status != THREAD_READY) && (i_status != THREAD_ERROR)
222                 && (i_status != THREAD_FATAL) );
223         if( i_status != THREAD_READY )
224         {
225             return( NULL );
226         }
227     }
228     return( p_input );
229 }
230
231 /*****************************************************************************
232  * input_DestroyThread: mark an input thread as zombie
233  *****************************************************************************
234  * This function should not return until the thread is effectively cancelled.
235  *****************************************************************************/
236 void input_DestroyThread( input_thread_t *p_input, int *pi_status )
237 {
238     int         i_status;                                   /* thread status */
239
240     /* Set status */
241     p_input->pi_status = (pi_status != NULL) ? pi_status : &i_status;
242     *p_input->pi_status = THREAD_DESTROY;
243
244     /* Request thread destruction */
245     p_input->b_die = 1;
246
247     /* If status is NULL, wait until thread has been destroyed */
248     if( pi_status == NULL )
249     {
250         do
251         {
252             msleep( THREAD_SLEEP );
253         }while( (i_status != THREAD_OVER) && (i_status != THREAD_ERROR)
254                 && (i_status != THREAD_FATAL) );
255     }
256 }
257
258 #if 0
259 /*****************************************************************************
260  * input_OpenAudioStream: open an audio stream
261  *****************************************************************************
262  * This function spawns an audio decoder and plugs it on the audio output
263  * thread.
264  *****************************************************************************/
265 int input_OpenAudioStream( input_thread_t *p_input, int i_id )
266 {
267     /* XXX?? */
268 }
269
270 /*****************************************************************************
271  * input_CloseAudioStream: close an audio stream
272  *****************************************************************************
273  * This function destroys an audio decoder.
274  *****************************************************************************/
275 void input_CloseAudioStream( input_thread_t *p_input, int i_id )
276 {
277     /* XXX?? */
278 }
279
280 /*****************************************************************************
281  * input_OpenVideoStream: open a video stream
282  *****************************************************************************
283  * This function spawns a video decoder and plugs it on a video output thread.
284  *****************************************************************************/
285 int input_OpenVideoStream( input_thread_t *p_input,
286                            struct vout_thread_s *p_vout, struct video_cfg_s * p_cfg )
287 {
288     /* XXX?? */
289 }
290
291 /*****************************************************************************
292  * input_CloseVideoStream: close a video stream
293  *****************************************************************************
294  * This function destroys an video decoder.
295  *****************************************************************************/
296 void input_CloseVideoStream( input_thread_t *p_input, int i_id )
297 {
298     /* XXX?? */
299 }
300 #endif
301
302 /* following functions are local */
303
304 /*****************************************************************************
305  * InitThread: initialize input thread
306  *****************************************************************************
307  * This function is called from RunThread and performs the second step of the
308  * initialization. It returns 0 on success. Note that the thread's flag are not
309  * modified inside this function.
310  *****************************************************************************/
311 static int InitThread( input_thread_t *p_input )
312 {
313     /* Mark thread as running and return */
314     intf_DbgMsg("\n");
315     *p_input->pi_status =        THREAD_READY;
316     intf_DbgMsg("thread ready\n");
317     return( 0 );
318 }
319
320 /*****************************************************************************
321  * RunThread: main thread loop
322  *****************************************************************************
323  * Thread in charge of processing the network packets and demultiplexing.
324  *****************************************************************************/
325 static void RunThread( input_thread_t *p_input )
326 {
327     /*
328      * Initialize thread and free configuration
329      */
330     p_input->b_error = InitThread( p_input );
331     if( p_input->b_error )
332     {
333         free( p_input );                               /* destroy descriptor */
334         return;
335     }
336
337     /*
338      * Main loop
339      */
340     intf_DbgMsg("\n");
341     while( !p_input->b_die && !p_input->b_error )
342     {
343         /* Scatter read the UDP packet from the network or the file. */
344         if( (input_ReadPacket( p_input )) == (-1) )
345         {
346             /* FIXME??: Normally, a thread can't kill itself, but we don't have
347              * any method in case of an error condition ... */
348             p_input->b_error = 1;
349         }
350
351 #ifdef STATS
352         p_input->c_loops++;
353 #endif
354     }
355
356     /*
357      * Error loop
358      */
359     if( p_input->b_error )
360     {
361         ErrorThread( p_input );
362     }
363
364     /* End of thread */
365     EndThread( p_input );
366     intf_DbgMsg("thread end\n");
367 }
368
369
370 /*****************************************************************************
371  * ErrorThread: RunThread() error loop
372  *****************************************************************************
373  * This function is called when an error occured during thread main's loop.
374  *****************************************************************************/
375 static void ErrorThread( input_thread_t *p_input )
376 {
377     /* Wait until a `die' order */
378     intf_DbgMsg("\n");
379     while( !p_input->b_die )
380     {
381         /* Sleep a while */
382         msleep( VOUT_IDLE_SLEEP );
383     }
384 }
385
386 /*****************************************************************************
387  * EndThread: end the input thread
388  *****************************************************************************/
389 static void EndThread( input_thread_t * p_input )
390 {
391     int *       pi_status;                                  /* threas status */
392     int         i_es_loop;                                       /* es index */
393
394     /* Store status */
395     intf_DbgMsg("\n");
396     pi_status = p_input->pi_status;
397     *pi_status = THREAD_END;
398
399     /* Close input method */
400     p_input->p_Close( p_input );
401
402     /* Destroy all decoder threads */
403     for( i_es_loop = 0;
404          (i_es_loop < INPUT_MAX_ES) && (p_input->pp_selected_es[i_es_loop] != NULL) ;
405          i_es_loop++ )
406     {
407         switch( p_input->pp_selected_es[i_es_loop]->i_type )
408         {
409         case MPEG1_VIDEO_ES:
410         case MPEG2_VIDEO_ES:
411 #ifdef OLD_DECODER
412             vdec_DestroyThread( (vdec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) /*, NULL */ );
413 #else
414             vpar_DestroyThread( (vpar_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) /*, NULL */ );
415 #endif
416             break;
417         case MPEG1_AUDIO_ES:
418         case MPEG2_AUDIO_ES:
419             adec_DestroyThread( (adec_thread_t*)(p_input->pp_selected_es[i_es_loop]->p_dec) );
420             break;
421         case AC3_AUDIO_ES:
422             ac3dec_DestroyThread( (ac3dec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
423             break;
424         case DVD_SPU_ES:
425             spudec_DestroyThread( (spudec_thread_t *)(p_input->pp_selected_es[i_es_loop]->p_dec) );
426             break;
427         case 0:
428             /* Special streams for the PSI decoder, PID 0 and 1 */
429             break;
430 #ifdef DEBUG
431         default:
432             intf_DbgMsg("error: unknown decoder type %d\n", p_input->pp_selected_es[i_es_loop]->i_type );
433             break;
434 #endif
435         }
436     }
437
438     input_NetlistEnd( p_input );                            /* clean netlist */
439     input_PsiEnd( p_input );                        /* clean PSI information */
440     input_PcrEnd( p_input );                        /* clean PCR information */
441     free( p_input );                          /* free input_thread structure */
442
443     /* Update status */
444     *pi_status = THREAD_OVER;
445 }
446
447 /*****************************************************************************
448  * input_ReadPacket: reads a packet from the network or the file
449  *****************************************************************************/
450 static __inline__ int input_ReadPacket( input_thread_t *p_input )
451 {
452     int                 i_base_index; /* index of the first free iovec */
453     int                 i_current_index;
454     int                 i_packet_size;
455 #ifdef INPUT_LIFO_TS_NETLIST
456     int                 i_meanwhile_released;
457     int                 i_currently_removed;
458 #endif
459     ts_packet_t *       p_ts_packet;
460
461     /* In this function, we only care about the TS netlist. PES netlist
462      * is for the demultiplexer. */
463 #ifdef INPUT_LIFO_TS_NETLIST
464     i_base_index = p_input->netlist.i_ts_index;
465
466     /* Verify that we still have packets in the TS netlist */
467     if( (INPUT_MAX_TS + INPUT_TS_READ_ONCE - 1 - p_input->netlist.i_ts_index) <= INPUT_TS_READ_ONCE )
468     {
469         intf_ErrMsg("input error: TS netlist is empty !\n");
470         return( -1 );
471     }
472
473 #else /* FIFO netlist */
474     i_base_index = p_input->netlist.i_ts_start;
475     if( p_input->netlist.i_ts_start + INPUT_TS_READ_ONCE -1 > INPUT_MAX_TS )
476     {
477         /* The netlist is splitted in 2 parts. We must gather them to consolidate
478            the FIFO (we make the loop easily in having the same iovec at the far
479            end and in the beginning of netlist_free).
480            That's why the netlist is (INPUT_MAX_TS +1) + (INPUT_TS_READ_ONCE -1)
481            large. */
482         memcpy( p_input->netlist.p_ts_free + INPUT_MAX_TS + 1,
483                 p_input->netlist.p_ts_free,
484                 (p_input->netlist.i_ts_start + INPUT_TS_READ_ONCE - 1 - INPUT_MAX_TS)
485                   * sizeof(struct iovec) );
486     }
487
488     /* Verify that we still have packets in the TS netlist */
489     if( ((p_input->netlist.i_ts_end -1 - p_input->netlist.i_ts_start) & INPUT_MAX_TS) <= INPUT_TS_READ_ONCE )
490     {
491         intf_ErrMsg("input error: TS netlist is empty !\n");
492         return( -1 );
493     }
494 #endif /* FIFO netlist */
495
496     /* Scatter read the buffer. */
497     i_packet_size = (*p_input->p_Read)( p_input,
498                            &p_input->netlist.p_ts_free[i_base_index],
499                            INPUT_TS_READ_ONCE );
500     if( i_packet_size == (-1) )
501     {
502 #if 0
503         intf_DbgMsg("Read packet %d %p %d %d\n", i_base_index,
504                     &p_input->netlist.p_ts_free[i_base_index],
505                     p_input->netlist.i_ts_start,
506                     p_input->netlist.i_ts_end);
507 #endif
508         intf_ErrMsg("input error: readv() failed (%s)\n", strerror(errno));
509         return( -1 );
510     }
511
512     if( i_packet_size == 0 )
513     {
514         /* No packet has been received, so stop here. */
515         return( 0 );
516     }
517
518     /* Demultiplex the TS packets (1..INPUT_TS_READ_ONCE) received. */
519     for( i_current_index = i_base_index;
520          (i_packet_size -= TS_PACKET_SIZE) >= 0;
521          i_current_index++ )
522     {
523         /* BTW, something REALLY bad could happen if we receive packets with
524            a wrong size. */
525         p_ts_packet = (ts_packet_t*)(p_input->netlist.p_ts_free[i_current_index].iov_base);
526         /* Don't cry :-), we are allowed to do that cast, because initially,
527            our buffer was malloc'ed with sizeof(ts_packet_t) */
528
529         /* Find out if we need this packet and demultiplex. */
530         input_SortPacket( p_input /* for current PIDs and netlist */,
531                           p_ts_packet);
532     }
533
534     if( i_packet_size > 0 )
535     {
536         intf_ErrMsg("input error: wrong size\n");
537         return( -1 );
538     }
539
540     /* Remove the TS packets we have just filled from the netlist */
541 #ifdef INPUT_LIFO_TS_NETLIST
542     /* We need to take a lock here while we're calculating index positions. */
543     vlc_mutex_lock( &p_input->netlist.lock );
544
545     i_meanwhile_released = i_base_index - p_input->netlist.i_ts_index;
546     if( i_meanwhile_released )
547     {
548         /* That's where it becomes funny :-). Since we didn't take locks for
549            efficiency reasons, other threads (including ourselves, with
550            input_DemuxPacket) might have released packets to the netlist.
551            So we have to copy these iovec where they should go.
552
553            BTW, that explains why the TS netlist is
554            (INPUT_MAX_TS +1) + (TS_READ_ONCE -1) large. */
555
556         i_currently_removed = i_current_index - i_base_index;
557         if( i_meanwhile_released < i_currently_removed )
558         {
559             /* Copy all iovecs in that case */
560             memcpy( &p_input->netlist.p_ts_free[p_input->netlist.i_ts_index]
561                      + i_currently_removed,
562                     &p_input->netlist.p_ts_free[p_input->netlist.i_ts_index],
563                     i_meanwhile_released * sizeof(struct iovec) );
564         }
565         else
566         {
567             /* We have fewer places than items, so we only move
568                i_currently_removed of them. */
569             memcpy( &p_input->netlist.p_ts_free[i_base_index],
570                     &p_input->netlist.p_ts_free[p_input->netlist.i_ts_index],
571                     i_currently_removed * sizeof(struct iovec) );
572         }
573
574         /* Update i_netlist_index with the information gathered above. */
575         p_input->netlist.i_ts_index += i_currently_removed;
576     }
577     else
578     {
579         /* Nothing happened. */
580         p_input->netlist.i_ts_index = i_current_index;
581     }
582
583     vlc_mutex_unlock( &p_input->netlist.lock );
584
585 #else /* FIFO netlist */
586     /* & is modulo ; that's where we make the loop. */
587     p_input->netlist.i_ts_start = i_current_index & INPUT_MAX_TS;
588 #endif
589
590 #ifdef STATS
591     p_input->c_packets_read += i_current_index - i_base_index;
592     p_input->c_bytes += (i_current_index - i_base_index) * TS_PACKET_SIZE;
593 #endif
594     return( 0 );
595 }
596
597 /*****************************************************************************
598  * input_SortPacket: find out whether we need that packet
599  *****************************************************************************/
600 static __inline__ void input_SortPacket( input_thread_t *p_input,
601                                          ts_packet_t *p_ts_packet )
602 {
603     int             i_current_pid;
604     int             i_es_loop;
605
606     /* Verify that sync_byte, error_indicator and scrambling_control are
607        what we expected. */
608     if( !(p_ts_packet->buffer[0] == 0x47) || (p_ts_packet->buffer[1] & 0x80) ||
609         (p_ts_packet->buffer[3] & 0xc0) )
610     {
611         intf_DbgMsg("input debug: invalid TS header (%p)\n", p_ts_packet);
612     }
613     else
614     {
615         /* Get the PID of the packet. Note that ntohs is needed, for endianness
616            purposes (see man page). */
617         i_current_pid = U16_AT(&p_ts_packet->buffer[1]) & 0x1fff;
618
619         //intf_DbgMsg("input debug: pid %d received (%p)\n",
620         //            i_current_pid, p_ts_packet);
621
622         /* Lock current ES state. */
623         vlc_mutex_lock( &p_input->es_lock );
624
625     /* Verify that we actually want this PID. */
626         for( i_es_loop = 0; i_es_loop < INPUT_MAX_SELECTED_ES; i_es_loop++ )
627         {
628             if( p_input->pp_selected_es[i_es_loop] != NULL)
629             {
630                 if( (*p_input->pp_selected_es[i_es_loop]).i_id
631                      == i_current_pid )
632                 {
633                     /* Don't need the lock anymore, since the value pointed
634                        out by p_input->pp_selected_es[i_es_loop] can only be
635                        modified from inside the input_thread (by the PSI
636                        decoder): interface thread is only allowed to modify
637                        the pp_selected_es table */
638                     vlc_mutex_unlock( &p_input->es_lock );
639
640                     /* We're interested. Pass it to the demultiplexer. */
641                     input_DemuxTS( p_input, p_ts_packet,
642                                    p_input->pp_selected_es[i_es_loop] );
643                     return;
644                 }
645             }
646             else
647             {
648                 /* pp_selected_es should not contain any hole. */
649                 break;
650             }
651         }
652         vlc_mutex_unlock( &p_input->es_lock );
653     }
654
655     /* We weren't interested in receiving this packet. Give it back to the
656        netlist. */
657     //intf_DbgMsg("SortPacket: freeing unwanted TS %p (pid %d)\n", p_ts_packet,
658     //                 U16_AT(&p_ts_packet->buffer[1]) & 0x1fff);
659     input_NetlistFreeTS( p_input, p_ts_packet );
660 #ifdef STATS
661     p_input->c_packets_trashed++;
662 #endif
663 }
664
665 /*****************************************************************************
666  * input_DemuxTS: first step of demultiplexing: the TS header
667  *****************************************************************************
668  * Stream must also only contain PES and PSI, so PID must have been filtered
669  *****************************************************************************/
670 static __inline__ void input_DemuxTS( input_thread_t *p_input,
671                                       ts_packet_t *p_ts_packet,
672                                       es_descriptor_t *p_es_descriptor )
673 {
674     int         i_dummy;
675     boolean_t   b_adaption;                     /* Adaption field is present */
676     boolean_t   b_payload;                         /* Packet carries payload */
677     boolean_t   b_unit_start;          /* A PSI or a PES start in the packet */
678     boolean_t   b_trash = 0;                 /* Must the packet be trashed ? */
679     boolean_t   b_lost = 0;                     /* Was there a packet lost ? */
680
681     ASSERT(p_input);
682     ASSERT(p_ts_packet);
683     ASSERT(p_es_descriptor);
684
685 #define p (p_ts_packet->buffer)
686
687     //intf_DbgMsg("input debug: TS-demultiplexing packet %p, pid %d, number %d\n",
688     //            p_ts_packet, U16_AT(&p[1]) & 0x1fff, p[3] & 0x0f);
689
690 #ifdef STATS
691     p_es_descriptor->c_packets++;
692     p_es_descriptor->c_bytes += TS_PACKET_SIZE;
693 #endif
694
695     /* Extract flags values from TS common header. */
696     b_unit_start = (p[1] & 0x40);
697     b_adaption = (p[3] & 0x20);
698     b_payload = (p[3] & 0x10);
699
700     /* Extract adaption field informations if any */
701     if( !b_adaption )
702     {
703         /* We don't have any adaptation_field, so payload start immediately
704          after the 4 byte TS header */
705         p_ts_packet->i_payload_start = 4;
706     }
707     else
708     {
709         /* p[4] is adaptation_field_length minus one */
710         p_ts_packet->i_payload_start = 5 + p[4];
711
712         /* The adaption field can be limited to the adaptation_field_length byte,
713            so that there is nothing to do: skip this possibility */
714         if( p[4] )
715         {
716             /* If the packet has both adaptation_field and payload, adaptation_field
717                cannot be more than 182 bytes long; if there is only an
718            adaptation_field, it must fill the next 183 bytes. */
719             if( b_payload ? (p[4] > 182) : (p[4] != 183) )
720             {
721                 intf_DbgMsg("input debug: invalid TS adaptation field (%p)\n",
722                             p_ts_packet);
723 #ifdef STATS
724                 p_es_descriptor->c_invalid_packets++;
725 #endif
726                 b_trash = 1;
727             }
728
729             /* No we are sure that the byte containing flags is present: read it */
730             else
731             {
732                 /* discontinuity_indicator */
733                 if( p[5] & 0x80 )
734                 {
735                     intf_DbgMsg("discontinuity_indicator encountered by TS demux " \
736                                 "(position read: %d, saved: %d)\n", p[5] & 0x80,
737                                 p_es_descriptor->i_continuity_counter);
738
739                     /* If the PID carries the PCR, there will be a system time-base
740                        discontinuity. We let the PCR decoder handle that. */
741                     p_es_descriptor->b_discontinuity = 1;
742
743                     /* There also may be a continuity_counter discontinuity:
744                resynchronise our counter with the one of the stream */
745                     p_es_descriptor->i_continuity_counter = (p[3] & 0x0f) - 1;
746                 }
747
748                 /* random_access_indicator */
749                 p_es_descriptor->b_random |= p[5] & 0x40;
750
751                 /* If this is a PCR_PID, and this TS packet contains a PCR,
752            we pass it along to the PCR decoder. */
753                 if( (p_es_descriptor->b_pcr) && (p[5] & 0x10) )
754                 {
755                     /* There should be a PCR field in the packet, check if the
756                adaption field is long enough to carry it */
757                     if( p[4] >= 7 )
758                     {
759                         /* Call the PCR decoder */
760                         input_PcrDecode( p_input, p_es_descriptor, &p[6] );
761                     }
762                 }
763             }
764         }
765     }
766
767     /* Check the continuity of the stream. */
768     i_dummy = ((p[3] & 0x0f) - p_es_descriptor->i_continuity_counter) & 0x0f;
769     if( i_dummy == 1 )
770     {
771         /* Everything is ok, just increase our counter */
772         p_es_descriptor->i_continuity_counter++;
773     }
774     else
775     {
776         if( !b_payload && i_dummy == 0 )
777         {
778             /* This is a packet without payload, this is allowed by the draft
779                As there is nothing interessant in this packet (except PCR that
780                have already been handled), we can trash the packet. */
781             intf_DbgMsg("Packet without payload received by TS demux\n");
782             b_trash = 1;
783         }
784         else if( i_dummy <= 0 )
785         {
786             /* Duplicate packet: mark it as being to be trashed. */
787             intf_DbgMsg("Duplicate packet received by TS demux\n");
788             b_trash = 1;
789         }
790         else if( p_es_descriptor->i_continuity_counter == 0xFF )
791         {
792             /* This means that the packet is the first one we receive for this
793                ES since the continuity counter ranges between 0 and 0x0F
794                excepts when it has been initialized by the input: Init the
795                counter to the correct value. */
796             intf_DbgMsg("First packet for PID %d received by TS demux\n",
797                         p_es_descriptor->i_id);
798             p_es_descriptor->i_continuity_counter = (p[3] & 0x0f);
799         }
800         else
801         {
802             /* This can indicate that we missed a packet or that the
803                continuity_counter wrapped and we received a dup packet: as we
804                don't know, do as if we missed a packet to be sure to recover
805                from this situation */
806             intf_DbgMsg("Packet lost by TS demux: current %d, packet %d\n",
807                         p_es_descriptor->i_continuity_counter & 0x0f,
808                         p[3] & 0x0f);
809             b_lost = 1;
810             p_es_descriptor->i_continuity_counter = p[3] & 0x0f;
811         }
812     }
813
814     /* Trash the packet if it has no payload or if it is bad */
815     if( b_trash )
816     {
817         input_NetlistFreeTS( p_input, p_ts_packet );
818 #ifdef STATS
819         p_input->c_packets_trashed++;
820 #endif
821     }
822     else
823     {
824         if( p_es_descriptor->b_psi )
825         {
826             /* The payload contains PSI tables */
827             input_DemuxPSI( p_input, p_ts_packet, p_es_descriptor,
828                             b_unit_start, b_lost );
829         }
830         else
831         {
832             /* The payload carries a PES stream */
833             input_DemuxPES( p_input, p_ts_packet, p_es_descriptor,
834                             b_unit_start, b_lost );
835         }
836     }
837
838 #undef p
839 }
840
841
842
843
844 /*****************************************************************************
845  * input_DemuxPES:
846  *****************************************************************************
847  * Gather a PES packet and analyzes its header.
848  *****************************************************************************/
849 static __inline__ void input_DemuxPES( input_thread_t *p_input,
850                                        ts_packet_t *p_ts_packet,
851                                        es_descriptor_t *p_es_descriptor,
852                                        boolean_t b_unit_start,
853                                        boolean_t b_packet_lost )
854 {
855     decoder_fifo_t *            p_fifo;
856     u8                          i_pes_header_size;
857     int                         i_dummy;
858     pes_packet_t*               p_last_pes;
859     ts_packet_t *               p_ts;
860     int                         i_ts_payload_size;
861
862
863 #define p_pes (p_es_descriptor->p_pes_packet)
864
865     ASSERT(p_input);
866     ASSERT(p_ts_packet);
867     ASSERT(p_es_descriptor);
868
869     //intf_DbgMsg("PES-demultiplexing %p (%p)\n", p_ts_packet, p_pes);
870
871     /* If we lost data, discard the PES packet we are trying to reassemble
872        if any and wait for the beginning of a new one in order to synchronise
873        again */
874     if( b_packet_lost && p_pes != NULL )
875     {
876         intf_DbgMsg("PES %p trashed because of packet lost\n", p_pes);
877         input_NetlistFreePES( p_input, p_pes );
878         p_pes = NULL;
879     }
880
881     /* If the TS packet contains the begining of a new PES packet, and if we
882        were reassembling a PES packet, then the PES should be complete now,
883        so parse its header and give it to the decoders */
884     if( b_unit_start && p_pes != NULL )
885     {
886         //intf_DbgMsg("End of PES packet %p\n", p_pes);
887
888         /* Parse the header. The header has a variable length, but in order
889            to improve the algorithm, we will read the 14 bytes we may be
890            interested in */
891         p_ts = p_pes->p_first_ts;
892         i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
893         i_dummy = 0;
894
895         if(i_ts_payload_size >= PES_HEADER_SIZE)
896         {
897             /* This part of the header entirely fits in the payload of
898                the first TS packet */
899             p_pes->p_pes_header = &(p_ts->buffer[p_ts->i_payload_start]);
900         }
901         else
902         {
903             /* This part of the header does not fit in the current TS packet:
904                copy the part of the header we are interested in to the
905                p_pes_header_save buffer. The buffer is dynamicly allocated if
906                needed so it's time expensive but this situation almost never occur. */
907             intf_DbgMsg("Code never tested encountered, WARNING ! (benny)\n");
908             if( !p_pes->p_pes_header_save )
909             {
910                 p_pes->p_pes_header_save = malloc(PES_HEADER_SIZE);
911             }
912
913             do
914             {
915                 memcpy(p_pes->p_pes_header_save + i_dummy,
916                        &p_ts->buffer[p_ts->i_payload_start], i_ts_payload_size);
917                 i_dummy += i_ts_payload_size;
918
919                 p_ts = p_ts->p_next_ts;
920                 if(!p_ts)
921                 {
922                   /* The payload of the PES packet is shorter than the 14 bytes
923                      we would read. This means that high packet lost occured
924                      so the PES won't be usefull for any decoder. Moreover,
925                      this should never happen so we can trash the packet and
926                      exit roughly without regrets */
927                   intf_DbgMsg("PES packet too short: trashed\n");
928                   input_NetlistFreePES( p_input, p_pes );
929                   p_pes = NULL;
930                   /* Stats XXX?? */
931                   return;
932                 }
933
934                 i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
935             }
936             while(i_ts_payload_size + i_dummy < PES_HEADER_SIZE);
937
938             /* This last TS packet is partly header, partly payload, so just
939                copy the header part */
940             memcpy(p_pes->p_pes_header_save + i_dummy,
941                    &p_ts->buffer[p_ts->i_payload_start],
942                    PES_HEADER_SIZE - i_dummy);
943
944             /* The header must be read in the buffer not in any TS packet */
945            p_pes->p_pes_header = p_pes->p_pes_header_save;
946         }
947
948         /* Now we have the part of the PES header we were interested in:
949            parse it */
950
951         /* First read the 6 header bytes common to all PES packets:
952            use them to test the PES validity */
953         if( (p_pes->p_pes_header[0] || p_pes->p_pes_header[1] ||
954             (p_pes->p_pes_header[2] != 1)) ||
955                                      /* packet_start_code_prefix != 0x000001 */
956             ((i_dummy = U16_AT(p_pes->p_pes_header + 4)) &&
957              (i_dummy + 6 != p_pes->i_pes_size)) )
958                    /* PES_packet_length is set and != total received payload */
959         {
960           /* Trash the packet and set p_pes to NULL to be sure the next PES
961              packet will have its b_data_lost flag set */
962           intf_DbgMsg("Corrupted PES packet received: trashed\n");
963           input_NetlistFreePES( p_input, p_pes );
964           p_pes = NULL;
965           /* Stats XXX?? */
966         }
967         else
968         {
969             /* The PES packet is valid. Check its type to test if it may
970                carry additional informations in a header extension */
971             p_pes->i_stream_id =  p_pes->p_pes_header[3];
972
973             switch( p_pes->i_stream_id )
974             {
975             case 0xBE:  /* Padding */
976             case 0xBC:  /* Program stream map */
977             case 0xBF:  /* Private stream 2 */
978             case 0xB0:  /* ECM */
979             case 0xB1:  /* EMM */
980             case 0xFF:  /* Program stream directory */
981             case 0xF2:  /* DSMCC stream */
982             case 0xF8:  /* ITU-T H.222.1 type E stream */
983                 /* The payload begins immediatly after the 6 bytes header, so
984                    we have finished with the parsing */
985                 i_pes_header_size = 6;
986                 break;
987
988             default:
989                 /* The PES header contains at least 3 more bytes: parse them */
990                 p_pes->b_data_alignment = p_pes->p_pes_header[6] & 0x04;
991                 p_pes->b_has_pts = p_pes->p_pes_header[7] & 0x80;
992                 i_pes_header_size = p_pes->p_pes_header[8] + 9;
993
994                 /* Now parse the optional header extensions (in the limit of
995                    the 14 bytes */
996                 if( p_pes->b_has_pts )
997                 {
998                     pcr_descriptor_t * p_pcr;
999
1000                     p_pcr = p_input->p_pcr;
1001
1002                     p_pes->i_pts =
1003                         ( ((mtime_t)(p_pes->p_pes_header[9] & 0x0E) << 29) |
1004                           (((mtime_t)U16_AT(p_pes->p_pes_header + 10) << 14) - (1 << 14)) |
1005                           ((mtime_t)U16_AT(p_pes->p_pes_header + 12) >> 1) ) * 300;
1006                     p_pes->i_pts /= 27;
1007
1008                     if( p_pcr->i_synchro_state )
1009                     {
1010                         switch( p_pcr->i_synchro_state )
1011                         {
1012                             case SYNCHRO_NOT_STARTED:
1013                                 p_pes->b_has_pts = 0;
1014                                 break;
1015
1016                             case SYNCHRO_START:
1017                                 p_pes->i_pts += p_pcr->delta_pcr;
1018                                 p_pcr->delta_absolute = mdate() - p_pes->i_pts + INPUT_PTS_DELAY;
1019                                 p_pes->i_pts += p_pcr->delta_absolute;
1020                                 p_pcr->i_synchro_state = 0;
1021                                 break;
1022
1023                             case SYNCHRO_REINIT: /* We skip a PES */
1024                                 p_pes->b_has_pts = 0;
1025                                 p_pcr->i_synchro_state = SYNCHRO_START;
1026                                 break;
1027                         }
1028                     }
1029                     else
1030                     {
1031                         p_pes->i_pts += p_pcr->delta_pcr + p_pcr->delta_absolute;
1032                     }
1033                 }
1034                 break;
1035             }
1036
1037             /* Now we've parsed the header, we just have to indicate in some
1038                specific TS packets where the PES payload begins (renumber
1039                i_payload_start), so that the decoders can find the beginning
1040                of their data right out of the box. */
1041             p_ts = p_pes->p_first_ts;
1042             i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
1043             while( i_pes_header_size > i_ts_payload_size )
1044             {
1045                 /* These packets are entirely filled by the PES header. */
1046                 i_pes_header_size -= i_ts_payload_size;
1047                 p_ts->i_payload_start = p_ts->i_payload_end;
1048                 /* Go to the next TS packet: here we won't have to test it is
1049                    not NULL because we trash the PES packets when packet lost
1050                    occurs */
1051                 p_ts = p_ts->p_next_ts;
1052                 i_ts_payload_size = p_ts->i_payload_end - p_ts->i_payload_start;
1053             }
1054             /* This last packet is partly header, partly payload. */
1055             p_ts->i_payload_start += i_pes_header_size;
1056
1057
1058             /* Now we can eventually put the PES packet in the decoder's
1059                PES fifo */
1060             switch( p_es_descriptor->i_type )
1061             {
1062                 case MPEG1_VIDEO_ES:
1063                 case MPEG2_VIDEO_ES:
1064 #ifdef OLD_DECODER
1065                     p_fifo = &(((vdec_thread_t*)(p_es_descriptor->p_dec))->fifo);
1066 #else
1067                     p_fifo = &(((vpar_thread_t*)(p_es_descriptor->p_dec))->fifo);
1068 #endif
1069                     break;
1070
1071                 case MPEG1_AUDIO_ES:
1072                 case MPEG2_AUDIO_ES:
1073                     p_fifo = &(((adec_thread_t*)(p_es_descriptor->p_dec))->fifo);
1074                     break;
1075
1076                 case AC3_AUDIO_ES:
1077 #if 0
1078                     /* we skip 4 bytes at the beginning of the AC3 payload */
1079                     p_ts->i_payload_start += 4;
1080 #endif
1081                     p_fifo = &(((ac3dec_thread_t *)(p_es_descriptor->p_dec))->fifo);
1082                     break;
1083
1084                 case DVD_SPU_ES:
1085                     /* we skip 4 bytes at the beginning of the subpicture payload */
1086                     p_ts->i_payload_start += 4;
1087                     p_fifo = &(((spudec_thread_t *)(p_es_descriptor->p_dec))->fifo);
1088                     break;
1089
1090                 default:
1091                     /* This should never happen */
1092                     intf_DbgMsg("Unknown stream type (%d, %d): PES trashed\n",
1093                         p_es_descriptor->i_id, p_es_descriptor->i_type);
1094                     p_fifo = NULL;
1095                     break;
1096             }
1097
1098             if( p_fifo != NULL )
1099             {
1100                 vlc_mutex_lock( &p_fifo->data_lock );
1101                 if( DECODER_FIFO_ISFULL( *p_fifo ) )
1102                 {
1103                     /* The FIFO is full !!! This should not happen. */
1104 #ifdef STATS
1105                     p_input->c_packets_trashed += p_pes->i_ts_packets;
1106                     p_es_descriptor->c_invalid_packets += p_pes->i_ts_packets;
1107 #endif
1108                     input_NetlistFreePES( p_input, p_pes );
1109                     intf_DbgMsg("PES trashed - fifo full ! (%d, %d)\n",
1110                                p_es_descriptor->i_id, p_es_descriptor->i_type);
1111                 }
1112         else
1113                 {
1114                     //intf_DbgMsg("Putting %p into fifo %p/%d\n",
1115                     //            p_pes, p_fifo, p_fifo->i_end);
1116                     p_fifo->buffer[p_fifo->i_end] = p_pes;
1117                     DECODER_FIFO_INCEND( *p_fifo );
1118
1119                     /* Warn the decoder that it's got work to do. */
1120                     vlc_cond_signal( &p_fifo->data_wait );
1121                 }
1122                 vlc_mutex_unlock( &p_fifo->data_lock );
1123             }
1124             else
1125             {
1126                 intf_DbgMsg("No fifo to receive PES %p: trash\n", p_pes);
1127 #ifdef STATS
1128                 p_input->c_packets_trashed += p_pes->i_ts_packets;
1129                 p_es_descriptor->c_invalid_packets += p_pes->i_ts_packets;
1130 #endif
1131                 input_NetlistFreePES( p_input, p_pes );
1132             }
1133         }
1134     }
1135
1136
1137     /* If we are at the beginning of a new PES packet, we must fetch a new
1138        PES buffer to begin with the reassembly of this PES packet. This is
1139        also here that we can synchronise with the stream if we we lost
1140        packets or if the decoder has just started */
1141     if( b_unit_start )
1142     {
1143         p_last_pes = p_pes;
1144
1145         /* Get a new one PES from the PES netlist. */
1146         if( (p_pes = input_NetlistGetPES( p_input )) == (NULL) )
1147         {
1148             /* PES netlist is empty ! */
1149             p_input->b_error = 1;
1150         }
1151         else
1152         {
1153             //intf_DbgMsg("New PES packet %p (first TS: %p)\n", p_pes, p_ts_packet);
1154
1155             /* Init the PES fields so that the first TS packet could be correctly
1156                added to the PES packet (see below) */
1157             p_pes->p_first_ts = p_ts_packet;
1158             p_pes->p_last_ts = NULL;
1159
1160             /* If the last pes packet was null, this means that the synchronisation
1161                was lost and so warn the decoder that he will have to find a way to
1162                recover */
1163             if( !p_last_pes )
1164                 p_pes->b_data_loss = 1;
1165
1166             /* Read the b_random_access flag status and then reinit it */
1167             p_pes->b_random_access = p_es_descriptor->b_random;
1168             p_es_descriptor->b_random = 0;
1169         }
1170     }
1171
1172
1173     /* If we are synchronised with the stream, and so if we are ready to
1174        receive correctly the data, add the TS packet to the current PES
1175        packet */
1176     if( p_pes != NULL )
1177     {
1178         //intf_DbgMsg("Adding TS %p to PES %p\n", p_ts_packet, p_pes);
1179
1180         /* Size of the payload carried in the TS packet */
1181         i_ts_payload_size = p_ts_packet->i_payload_end -
1182                             p_ts_packet->i_payload_start;
1183
1184         /* Update the relations between the TS packets */
1185         p_ts_packet->p_prev_ts = p_pes->p_last_ts;
1186         p_ts_packet->p_next_ts = NULL;
1187         if( p_pes->i_ts_packets != 0 )
1188         {
1189             /* Regarder si il serait pas plus efficace de ne creer que les liens
1190                precedent->suivant pour le moment, et les liens suivant->precedent
1191                quand le paquet est termine */
1192             /* Otherwise it is the first TS packet. */
1193             p_pes->p_last_ts->p_next_ts = p_ts_packet;
1194         }
1195         /* Now add the TS to the PES packet */
1196         p_pes->p_last_ts = p_ts_packet;
1197         p_pes->i_ts_packets++;
1198         p_pes->i_pes_size += i_ts_payload_size;
1199
1200         /* Stats */
1201 #ifdef STATS
1202         i_dummy = p_ts_packet->i_payload_end - p_ts_packet->i_payload_start;
1203         p_es_descriptor->c_payload_bytes += i_dummy;
1204 #endif
1205     }
1206     else
1207     {
1208         /* Since we don't use the TS packet to build a PES packet, we don't
1209            need it anymore, so give it back to the netlist */
1210         //intf_DbgMsg("Trashing TS %p: no PES being build\n", p_ts_packet);
1211         input_NetlistFreeTS( p_input, p_ts_packet );
1212     }
1213
1214 #undef p_pes
1215 }
1216
1217
1218
1219
1220 /*****************************************************************************
1221  * input_DemuxPSI:
1222  *****************************************************************************
1223  * Notice that current ES state has been locked by input_SortPacket. (No more true,
1224  * changed by benny - FIXME: See if it's ok, and definitely change the code ?? )
1225  *****************************************************************************/
1226 static __inline__ void input_DemuxPSI( input_thread_t *p_input,
1227                                        ts_packet_t *p_ts_packet,
1228                                        es_descriptor_t *p_es_descriptor,
1229                                        boolean_t b_unit_start, boolean_t b_packet_lost )
1230 {
1231     int i_data_offset;    /* Offset of the interesting data in the TS packet */
1232     u16 i_data_length;                               /* Length of those data */
1233     //boolean_t b_first_section; /* Was there another section in the TS packet ? */
1234
1235     ASSERT(p_input);
1236     ASSERT(p_ts_packet);
1237     ASSERT(p_es_descriptor);
1238
1239 #define p_psi (p_es_descriptor->p_psi_section)
1240
1241     //intf_DbgMsg( "input debug: PSI demultiplexing %p (%p)\n", p_ts_packet, p_input);
1242
1243     //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);
1244
1245
1246     /* Try to find the beginning of the payload in the packet to initialise
1247        the do-while loop that follows -> Compute the i_data_offset variable:
1248        by default, the value is set so that we won't enter in the while loop.
1249        It will be set to a correct value if the data are not corrupted */
1250     i_data_offset = TS_PACKET_SIZE;
1251
1252     /* Has the reassembly of a section already began in a previous packet ? */
1253     if( p_psi->b_running_section )
1254     {
1255         /* Was data lost since the last TS packet ? */
1256         if( b_packet_lost )
1257         {
1258             /* Discard the packet and wait for the begining of a new one to resynch */
1259             p_psi->b_running_section = 0;
1260             p_psi->i_current_position = 0;
1261             intf_DbgMsg( "PSI section(s) discarded due to packet loss\n" );
1262         }
1263         else
1264         {
1265             /* The data that complete a previously began section are always at
1266                the beginning of the TS payload... */
1267             i_data_offset = p_ts_packet->i_payload_start;
1268             /* ...Unless there is a pointer field, that we have to bypass */
1269             if( b_unit_start )
1270                 i_data_offset++;
1271             //intf_DbgMsg( "New part of the section received at offset %d\n", i_data_offset );
1272         }
1273     }
1274     /* We are looking for the beginning of a new section */
1275     else
1276     {
1277         if( b_unit_start )
1278         {
1279             /* Get the offset at which the data for that section can be found
1280                The offset is stored in the pointer_field since we are interested in
1281                the first section of the TS packet. Note that the +1 is to bypass
1282                the pointer field */
1283             i_data_offset = p_ts_packet->i_payload_start +
1284                             p_ts_packet->buffer[p_ts_packet->i_payload_start] + 1;
1285             //intf_DbgMsg( "New section beginning at offset %d in TS packet\n", i_data_offset );
1286         }
1287         else
1288         {
1289             /* This may either mean that the TS is bad or that the packet contains
1290                the end of a section that had been discarded in a previous loop:
1291                trash the TS packet since we cannot do anything with those data: */
1292             p_psi->b_running_section = 0;
1293             p_psi->i_current_position = 0;
1294             intf_DbgMsg( "PSI packet discarded due to lack of synchronisation\n" );
1295         }
1296     }
1297
1298     /* The section we will deal with during the first iteration of the following
1299        loop is the first one contained in the TS packet */
1300     //    b_first_section = 1;
1301
1302     /* Reassemble the pieces of sections contained in the TS packet and decode
1303        the sections that could have been completed.
1304        Stop when we reach the end of the packet or stuffing bytes */
1305     while( i_data_offset < TS_PACKET_SIZE && p_ts_packet->buffer[i_data_offset] != 0xFF )
1306     {
1307         /* If the current section is a new one, reinit the data fields of the p_psi
1308            struct to start its decoding */
1309         if( !p_psi->b_running_section )
1310         {
1311             /* Read the length of the new section */
1312             p_psi->i_length = (U16_AT(&p_ts_packet->buffer[i_data_offset+1]) & 0xFFF) + 3;
1313             //intf_DbgMsg( "Section length %d\n", p_psi->i_length );
1314             if( p_psi->i_length > PSI_SECTION_SIZE )
1315             {
1316                 /* The TS packet is corrupted, stop here to avoid possible a seg fault */
1317                 intf_DbgMsg( "PSI Section size is too big, aborting its reception\n" );
1318                 break;
1319             }
1320
1321             /* Init the reassembly of that section */
1322             p_psi->b_running_section = 1;
1323             p_psi->i_current_position = 0;
1324         }
1325
1326       /* Compute the length of data related to the section in this TS packet */
1327         if( p_psi->i_length - p_psi->i_current_position > TS_PACKET_SIZE - i_data_offset)
1328             i_data_length = TS_PACKET_SIZE - i_data_offset;
1329         else
1330           i_data_length = p_psi->i_length - p_psi->i_current_position;
1331
1332         /* Copy those data in the section buffer */
1333         memcpy( &p_psi->buffer[p_psi->i_current_position], &p_ts_packet->buffer[i_data_offset],
1334                 i_data_length );
1335
1336         /* Interesting data are now after the ones we copied, since no gap is
1337            allowed between 2 sections in a TS packets */
1338         i_data_offset += i_data_length;
1339
1340         /* Decode the packet if it is now complete */
1341         if (p_psi->i_length == p_psi->i_current_position + i_data_length)
1342         {
1343             /* Packet is complete, decode it */
1344             //intf_DbgMsg( "SECTION COMPLETE: starting decoding of its data\n" );
1345             input_PsiDecode( p_input, p_psi );
1346
1347             /* Prepare the buffer to receive a new section */
1348             p_psi->i_current_position = 0;
1349             p_psi->b_running_section = 0;
1350
1351             /* The new section won't be the first anymore */
1352             //b_first_section = 0;
1353         }
1354         else
1355         {
1356             /* Prepare the buffer to receive the next part of the section */
1357           p_psi->i_current_position += i_data_length;
1358           //intf_DbgMsg( "Section not complete, waiting for the end\n" );
1359         }
1360
1361         //intf_DbgMsg( "Must loop ? Next data offset: %d, stuffing: %d\n",
1362         //             i_data_offset, p_ts_packet->buffer[i_data_offset] );
1363     }
1364
1365     /* Relase the TS packet, we don't need it anymore */
1366     input_NetlistFreeTS( p_input, p_ts_packet );
1367
1368 #undef p_psi
1369 }