]> git.sesse.net Git - vlc/blob - src/input/input_psi.c
le bug de input_psi �tait fourbement r�apparu.
[vlc] / src / input / input_psi.c
1 /*******************************************************************************
2  * psi.c: PSI management 
3  * (c)1999 VideoLAN
4  *******************************************************************************
5  * Manages structures containing PSI information, and affiliated decoders.
6  * TO DO: Fonctions d'init des structures
7  ******************************************************************************/
8
9 /*******************************************************************************
10  * Preamble
11  *******************************************************************************/
12 #include "vlc.h"
13
14 /*
15 #include <errno.h>
16 #include <pthread.h>
17 #include <errno.h>
18 #include <stdio.h>
19 #include <sys/uio.h>                                                 
20 #include <stdlib.h>                              
21 #include <string.h>
22 #include <netinet/in.h>                                             
23 #include <sys/soundcard.h>
24 #include <X11/Xlib.h>
25 #include <X11/extensions/XShm.h>
26
27 #include "common.h"
28 #include "config.h"
29 #include "mtime.h"
30 #include "vlc_thread.h"
31 #include "intf_msg.h"
32 #include "debug.h"
33
34 #include "input.h"
35 #include "input_ctrl.h"
36 #include "input_psi.h"
37 #include "input_vlan.h"
38
39 #include "audio_output.h"
40 #include "video.h"
41 #include "video_output.h"
42 #include "xconsole.h"
43 #include "interface.h"
44
45 #include "pgm_data.h"*/
46
47 /*
48  * Precalculated 32-bits CRC table, shared by all instances of the PSI decoder
49  */
50 boolean_t b_crc_initialised = 0;
51 u32 i_crc_32_table[256];
52
53 /*
54  * Global configuration variable, need by AUTO_SPAWN to determine
55  * the option (audio and video) passed to the VideoLAN client.
56  */
57 #ifdef AUTO_SPAWN
58 //??extern program_data_t *p_main;
59 #endif
60
61 /*
62  * Locale type definitions
63  */
64 #define PSI_VIDEO_STREAM_DESCRIPTOR                 0x02
65 #define PSI_AUDIO_STREAM_DESCRIPTOR                 0x03
66 #define PSI_TARGET_BACKGROUND_GRID_DESCRIPTOR       0x07
67 #define PSI_VIDEO_WINDOW_DESCRIPTOR                 0x08
68
69 #ifdef DVB_EXTENSIONS
70 #define PSI_SERVICE_DESCRIPTOR                      0x48
71 #endif
72
73 /* That info must be stored in the version field since it contains
74    unused bits */
75 #define PSI_UNINITIALISED                           0xFF
76
77 /*
78  * Local prototypes
79  */
80 static int input_AddPsiPID( input_thread_t *p_input, int i_pid );
81 static int input_DelPsiPID( input_thread_t *p_input, int i_pid );
82 static void DecodePgrmAssocSection( byte_t* p_pas, input_thread_t *p_input );
83 static void DecodePgrmMapSection( byte_t* p_pms, input_thread_t *p_input );
84 static void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input );
85 static void DecodePgrmDescriptor( byte_t* p_descr, pgrm_descriptor_t* p_pgrm );
86 static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es );
87
88 static stream_descriptor_t* AddStreamDescr( input_thread_t* p_input,
89                                             u16 i_stream_id );
90 static void DestroyStreamDescr( input_thread_t* p_input, u16 i_stream_id );
91 static pgrm_descriptor_t* AddPgrmDescr( stream_descriptor_t* p_stream,
92                                        u16 i_pgrm_id );
93 static void DestroyPgrmDescr( input_thread_t* p_input, 
94                               stream_descriptor_t* p_stream, u16 i_pgrm_id );
95 static es_descriptor_t* AddESDescr( input_thread_t* p_input,
96                                     pgrm_descriptor_t* p_pgrm, u16 i_es_pid );
97 static void DestroyESDescr( input_thread_t* p_input, pgrm_descriptor_t* p_pgrm,
98                             u16 i_es_pid);
99
100 static void BuildCrc32Table();
101 static int CheckCRC32( u8* p_pms, int i_size);
102 static boolean_t Is_known( byte_t* a_known_section, u8 i_section );
103 static void Set_known( byte_t* a_known_section, u8 i_section );
104 static void Unset_known( byte_t* a_known_section, u8 i_section );
105
106 /******************************************************************************
107  * input_PsiInit: Initialize PSI decoder
108  ******************************************************************************
109  * Init the structures in which the PSI decoder will put the informations it
110  * got from PSI tables and request for the reception of the PAT.
111  ******************************************************************************/
112 int input_PsiInit( input_thread_t *p_input )
113 {
114   ASSERT(p_input);
115   
116   /* Precalculate the 32-bit CRC table if not already done ???
117      TO DO -> Put a lock or do that at pgrm init */
118   if( !b_crc_initialised )
119   {
120     BuildCrc32Table();
121     b_crc_initialised = 1;
122   }
123   
124   /* Init the structure that describes the stream we are receiving */
125   AddStreamDescr( p_input, PSI_UNINITIALISED );
126
127   /* Request for reception of the program association table */
128   input_AddPsiPID( p_input, 0 );
129
130 #ifdef DVB_EXTENSIONS
131   /* Request for reception of the service description table */
132   input_AddPsiPID( p_input, 17 );
133 #endif
134
135   return( 0 );
136 }
137
138 /******************************************************************************
139  * input_PsiClean: Clean PSI structures before dying
140  ******************************************************************************/
141 int input_PsiClean( input_thread_t *p_input )
142 {
143   ASSERT(p_input);
144
145   /* Stop to receive all the PSI tables associated with that program */
146   /* TO DO ??? -> Not really usefull */
147
148   /* Clean also descriptors for programs associated with that stream */
149   /* TO DO ??? -> Not really usefull and maybe buggy */
150
151   /* Destroy the stream description */
152   DestroyStreamDescr( p_input, p_input->p_stream->i_stream_id );
153
154   return( 0 );
155 }
156
157 /******************************************************************************
158  * input_PsiRead: Read the table of programs
159  ******************************************************************************
160  * Ugly debugging function at that time ???????
161  ******************************************************************************/
162 void input_PsiRead( input_thread_t *p_input /* ??? */ )
163 {
164   int i_index;
165   int i_index2;
166   pgrm_descriptor_t* p_pgrm;
167   
168   ASSERT( p_input );
169  
170   /* Lock the tables, since this method can be called from any thread */
171   //vlc_mutex_lock()
172
173   /* Check if the table is complete or not */
174   if( !p_input->p_stream->b_is_PMT_complete )
175   {
176     intf_IntfMsg( "Warning: PMT not yet complete\n" );
177   }
178   
179   /* Read the table */
180   for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ )
181   {
182     p_pgrm = p_input->p_stream->ap_programs[i_index];
183     intf_DbgMsg("Printing info for program %d\n", p_pgrm->i_number );
184     intf_IntfMsg("Printing info for program %d\n", p_pgrm->i_number );
185
186     for( i_index2 = 0; i_index2 < p_pgrm->i_es_number; i_index2++ )
187     {
188       intf_DbgMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n",
189                    p_pgrm->ap_es[i_index2]->i_id,
190                    p_pgrm->ap_es[i_index2]->i_type,
191                    p_pgrm->ap_es[i_index2]->b_pcr,
192                    p_pgrm->ap_es[i_index2]->b_psi);
193
194       intf_IntfMsg( " ->Pid %d: type %d, PCR: %d, PSI: %d\n",
195                     p_pgrm->ap_es[i_index2]->i_id,
196                     p_pgrm->ap_es[i_index2]->i_type,
197                     p_pgrm->ap_es[i_index2]->b_pcr,
198                     p_pgrm->ap_es[i_index2]->b_psi);
199     }
200   }
201
202   /* Unock the tables */
203   //vlc_mutex_unlock()
204 }
205
206 /******************************************************************************
207  * input_PsiDecode: Decode a PSI section
208  ******************************************************************************
209  * This funtion is essentially a wrapper that will  perform basic checks on
210  * the section and then call the right function according to its type.
211  ******************************************************************************/
212 void input_PsiDecode( input_thread_t *p_input, psi_section_t* p_psi_section )
213 {
214   ASSERT(p_input);
215   ASSERT(p_psi_section);
216
217   /* Hexa dump of the beginning of the section (for real men) */
218   //intf_DbgMsg( "Section: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n", (u8)p_psi_section->buffer[0], (u8)p_psi_section->buffer[1], (u8)p_psi_section->buffer[2], (u8)p_psi_section->buffer[3], (u8)p_psi_section->buffer[4], (u8)p_psi_section->buffer[5], (u8)p_psi_section->buffer[6], (u8)p_psi_section->buffer[7], (u8)p_psi_section->buffer[8], (u8)p_psi_section->buffer[9], (u8)p_psi_section->buffer[10], (u8)p_psi_section->buffer[11], (u8)p_psi_section->buffer[12], (u8)p_psi_section->buffer[13], (u8)p_psi_section->buffer[14], (u8)p_psi_section->buffer[15], (u8)p_psi_section->buffer[16], (u8)p_psi_section->buffer[17], (u8)p_psi_section->buffer[18], (u8)p_psi_section->buffer[19] );
219
220   /* Check the CRC validity if any CRC is carried */
221 #if 0
222   if( p_psi_section->buffer[1] & 0x80 )
223   {
224     if( CheckCRC32 (p_psi_section->buffer, p_psi_section->i_length) )
225     {
226       intf_DbgMsg("iSize: %d, CRC: %d\n", p_psi_section->i_length,
227                   U32_AT(&p_psi_section->buffer[p_psi_section->i_length-4]));
228       intf_DbgMsg( "Invalid CRC for PSI\n" );
229       return;
230     }
231   }
232 #endif
233   
234   /* If the section is not immediatly applicable, trash it (DVB drafts disallow
235      transmission of such sections, so we didn't implement it) */
236   if( !p_psi_section->buffer[5] & 0x01 )
237   {
238     intf_DbgMsg( "PSI not yet applicable: trash it\n" );
239     return;
240   }
241   
242   /* Handle the packet according to it's type given it the table_id  */
243   switch ( p_psi_section->buffer[0] )
244   {
245     case 0x00:
246       //intf_DbgMsg("Program association section received\n");
247       DecodePgrmAssocSection(p_psi_section->buffer, p_input);
248       break;
249     case 0x01:
250       //intf_DbgMsg("Conditional access section received\n");
251       break;
252     case 0x02:
253       //intf_DbgMsg("Program map section received\n");
254       DecodePgrmMapSection(p_psi_section->buffer, p_input);
255       break;
256     case 0x42:
257       //intf_DbgMsg("Service description section received\n");
258       DecodeSrvDescrSection(p_psi_section->buffer, p_input);
259       break;
260     default:
261       //intf_DbgMsg("Private PSI data received (type %x), ignoring it\n",
262       //            p_psi_section->buffer[0]);
263   }
264 }
265
266 /******************************************************************************
267  * DecodeAssocSection: Decode a PAS
268  ******************************************************************************
269  * No check is made to known if the table is currently applicable or not, so
270  * that unapplicable sections must be filtered before calling this function
271  * The Program Association Table can be segmented to occupy multiple sections
272  * so that we have to know which sections we have already received (IsKnown() /
273  * SetKnown() calls)
274  ******************************************************************************/
275 static void DecodePgrmAssocSection(u8* p_pas, input_thread_t *p_input )
276 {
277     u8 i_stream_id;             /* Id of the stream described in that section */
278     u8 i_version;              /* Version of the table carried in the section */
279
280     u16 i_pgrm_id;                       /* Id of the current described  pgrm */
281     u16 i_pgrm_map_pid;            /* PID of the associated program map table */
282     int i_pgrm_number;         /* Number of programs described in the section */
283
284     boolean_t b_is_invalid = 0;
285     
286     u8 i_current_section;
287     u8 i_last_section;
288
289     int i_pgrm_index;
290     int i_es_index;
291
292     ASSERT(p_pas);
293     ASSERT(p_input);
294
295 #define p_descr (p_input->p_stream)
296
297     /* Read stream id and version number immediately, to be sure they will be
298        initialised in all cases we will need it */
299     i_stream_id = U16_AT(&p_pas[3]);
300     i_version = (p_pas[5] >> 1) & 0x1F;
301     //intf_DbgMsg("TS Id: %d, version: %d\n", U16_AT(&p_pas[3]),(p_pas[5] >> 1) & 0x1F);
302
303     /* Test if the stream has not changed by looking at the stream_id */
304     if( p_descr->i_stream_id != i_stream_id )
305     {
306         /* This can either mean that the PSI decoder has just started or that
307            the stream has changed */
308         if( p_descr->i_PAT_version== PSI_UNINITIALISED )
309             intf_DbgMsg("Building Program Association table\n");
310         else
311             intf_ErrMsg( "Stream Id has suddently changed ! Rebuilding PAT\n" );
312
313         /* Whatever it is, ask the PSI decoder to rebuild the table */
314         b_is_invalid = 1;
315     }
316     else
317     {
318         /* Stream has not changed, test if the PMT is up to date */
319         if( p_descr->i_PAT_version != i_version )
320         {
321             intf_DbgMsg("PAT has been updated, rebuilding it\n");
322             /* Ask the PSI decoder to rebuild the table */
323             b_is_invalid = 1;
324         }
325     }
326     
327     /* Clear the table if needed */
328     if( b_is_invalid )
329     {
330         intf_DbgMsg("Updating PAT table\n");
331
332         /* Any program in the stream may have disapeared, or a new one
333            can have been added. The good way to handle such a case would be
334            to build a temporary table and to make a diff */
335
336         /* Stop the reception of all programs and PSI informations
337            associated with this stream, excepted the PAT on PID 0 and the SDT
338            on PID 17 */
339         for( i_es_index = 0; i_es_index < INPUT_MAX_SELECTED_ES && 
340              p_input->pp_selected_es[i_es_index]; i_es_index++ )
341         {
342           if( p_input->pp_selected_es[i_es_index]->b_psi )
343           {
344             if( p_input->pp_selected_es[i_es_index]->i_id != 0
345 #ifdef DVB_EXTENSIONS
346                 && p_input->pp_selected_es[i_es_index]->i_id != 17
347 #endif
348             )
349               input_DelPsiPID( p_input,
350                                p_input->pp_selected_es[i_es_index]->i_id );
351           }
352           else
353             input_DelPgrmElem( p_input,
354                                p_input->pp_selected_es[i_es_index]->i_id );
355         }
356
357         /* Recreate a new stream description. Since it is virgin, the decoder
358            will rebuild it entirely on is own */
359         DestroyStreamDescr(p_input, p_descr->i_stream_id);
360         AddStreamDescr(p_input, i_stream_id);
361
362         /* Record the new version for that table */
363         p_descr->i_PAT_version = i_version;
364     }
365
366     /* Build the table if not already complete or if it was cleared */
367     if( p_descr->b_is_PAT_complete )
368     {
369         /* Nothing to do */
370         if( b_is_invalid )
371             intf_DbgMsg("Bug: table invalid but PAT said to be complete\n");
372     }
373     else
374     {
375         /* Check if we already heard about that section */
376         i_last_section = p_pas[7];
377         i_current_section = p_pas[6];
378
379 //        intf_DbgMsg( "Section %d (last section %d)\n",
380 //                     i_current_section, i_last_section );
381
382         if( Is_known(p_descr->a_known_PAT_sections, i_current_section) )
383         {
384           /* Nothing to do */
385 //          intf_DbgMsg("Section already received, skipping\n");
386         }
387         else
388         {
389           /* Compute the number of program_map PID carried in this section */
390           i_pgrm_number = ((U16_AT(&p_pas[1]) & 0xFFF) - 9) / 4;
391           intf_DbgMsg("Number of Pgrm in that section: %d\n", i_pgrm_number);
392
393           /* Start the reception of those program map PID */
394           for( i_pgrm_index = 0; i_pgrm_index < i_pgrm_number; i_pgrm_index++ )
395           {
396             i_pgrm_id = U16_AT(&p_pas[8+4*i_pgrm_index]);
397             i_pgrm_map_pid = U16_AT(&p_pas[8+4*i_pgrm_index+2]) & 0x1fff;
398             intf_DbgMsg("Pgrm %d described on pid %d\n", i_pgrm_id,
399                         i_pgrm_map_pid);
400
401             /* Check we are not already receiving that pid because it carries
402                info for another program */
403             for( i_es_index = 0; i_es_index < INPUT_MAX_ES; i_es_index++ )
404             {
405               if( p_input->p_es[i_es_index].i_id == i_pgrm_map_pid)
406               {
407                 intf_DbgMsg("Already receiving pid %d", i_pgrm_map_pid);
408                 i_es_index = INPUT_MAX_ES+1;
409                 break;
410               } 
411             }
412             /* Start to receive that PID if we're not already doing it */
413             if( i_es_index <= INPUT_MAX_ES )
414               input_AddPsiPID( p_input, i_pgrm_map_pid );
415
416             /* Append an entry to the pgrm_descriptor table to later store
417                the description of this program, unless program number is 0
418                (Network information table) */
419             if( i_pgrm_id != 0 )
420             {
421               intf_DbgMsg("Adding program %d to the PMT\n", i_pgrm_id);
422               AddPgrmDescr(p_descr, i_pgrm_id);
423             }
424           }
425           
426           /* We now know the info carried in this section */
427           Set_known(p_descr->a_known_PAT_sections, i_current_section);
428         
429           /* Check if the table is now complete */
430           p_descr->i_known_PAT_sections++;
431           if( p_descr->i_known_PAT_sections >= i_last_section)
432             p_descr->b_is_PAT_complete = 1;
433         }
434     }
435
436 #undef p_descr
437 }
438
439 /******************************************************************************
440  * DecodePgrmMapSection: Decode a PMS
441  ******************************************************************************
442  * No check is made to known if the table is currently applicable or not, so
443  * that unapplicable sections must be filtered before calling this function
444  * The Program Map Table can be segmented to occupy multiple sections so that
445  * we have to know which sections we have already received (IsKnown() /
446  * SetKnown() calls)
447  * Note that the processing of those sections is different from the one of the
448  * others since here a section refers to a single program, and a program cannot
449  * be segmented into multiple sections
450  ******************************************************************************/
451 static void DecodePgrmMapSection( u8* p_pms, input_thread_t* p_input )
452 {
453   u16 i_pgrm_number;           /* Id of the program described in that section */
454   u8 i_version;                /* Version of the description for that program */
455   
456   u16 i_offset;
457   u16 i_section_length;
458   u16 i_descr_end;
459   
460   u8 i_last_section;
461   u8 i_current_section;
462
463   u16 i_es_pid;
464
465   int i_index = 0;
466 #ifdef AUTO_SPAWN
467   int i_es_loop;
468 #endif
469   pgrm_descriptor_t* p_pgrm;
470   es_descriptor_t* p_es;
471
472 #define p_descr (p_input->p_stream)
473
474   /* Read the id of the program described in that section */
475   i_pgrm_number = U16_AT(&p_pms[3]);
476 //  intf_DbgMsg( "PMT section received for program %d\n", i_pgrm_number );
477
478   /* Find where is stored the description of this program */
479   for( i_index = 0; i_index < p_descr->i_pgrm_number &&
480        i_pgrm_number != p_descr->ap_programs[i_index]->i_number; i_index++ );
481
482   if( i_index >= p_descr->i_pgrm_number )
483   {
484     /* If none entry exists, this simply means that the PAT is not complete,
485        so skip this section since it is the responsability of the PAT decoder
486        to add pgrm_descriptor slots to the table of known pgrms */
487     intf_DbgMsg( "Unknown pgrm %d: skipping its description\n", i_pgrm_number );
488     return;
489   }
490
491   /* We now have the slot which is the program described: we can begin with
492      the decoding of its description */
493   p_pgrm = p_descr->ap_programs[i_index];
494
495   /* Which section of the description of that program did we receive ? */
496   i_last_section = p_pms[7];
497   i_current_section = p_pms[6];
498 //  intf_DbgMsg("Section %d (last section %d)\n", i_current_section, i_last_section);
499
500   /* Is this an update of the description for this program ? */
501   i_version = (p_pms[5] >> 1) & 0x1F;
502     if( p_pgrm->i_version != i_version )
503     {
504         intf_DbgMsg("Updating PMT for program %d\n", i_pgrm_number);
505
506         for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
507         {
508           /* Stop the reception of the ES if needed by calling the function
509              normally used by the interface to manage this */
510           if( input_IsElemRecv(p_input, p_pgrm->ap_es[i_index]->i_id) )
511           {
512             intf_DbgMsg( "PID %d is no more valid: stopping its reception\n",
513                       p_pgrm->ap_es[i_index]->i_id );
514             input_DelPgrmElem( p_input, p_pgrm->ap_es[i_index]->i_id );
515           }
516
517           /* Remove the descriptor associated to the es of this programs */
518           intf_DbgMsg( "Invalidating PID %d\n", p_pgrm->ap_es[i_index]->i_id );
519           DestroyESDescr(p_input, p_pgrm, p_pgrm->ap_es[i_index]->i_id);
520         }
521         
522        /* Update version number */
523         p_pgrm->i_version = i_version;
524
525         /* Ask the decoder to update the description of that program */
526         p_descr->i_known_PMT_sections--;
527         Unset_known( p_descr->a_known_PMT_sections, i_current_section );
528         p_pgrm->b_is_ok = 0;
529     }
530
531     /* Read the info for that pgrm is the one we have is not up to date or
532        if we don't have any */
533     if( p_pgrm->b_is_ok )
534     {
535       /* Nothing to do */
536 //      intf_DbgMsg("Program description OK, nothing to do\n");
537     }
538     else
539     {
540         /* Check if we already heard about that section */
541         if( Is_known(p_descr->a_known_PMT_sections, i_current_section) )
542         {
543           /* Nothing to do */
544 //          intf_DbgMsg("Section already received, skipping\n");
545         }
546         else
547         {
548           /* Read the corresponding PCR */
549           p_pgrm->i_pcr_pid = U16_AT(&p_pms[8]) & 0x1fff;
550           intf_DbgMsg("PCR at PID: %d\n", p_pgrm->i_pcr_pid);
551
552           /* Compute the length of the section minus the final CRC */
553           i_section_length = (U16_AT(&p_pms[1]) & 0xfff) + 3 - 4;
554           intf_DbgMsg("Section length (without CRC): %d\n", i_section_length);
555
556           /* Read additional info stored in the descriptors if any */
557           intf_DbgMsg("Description length for program %d: %d\n",
558                       p_pgrm->i_number, (U16_AT(&p_pms[10]) & 0x0fff));
559           i_descr_end = (U16_AT(&p_pms[10]) & 0x0fff) + 12;
560           intf_DbgMsg("description ends at offset: %d\n",  i_descr_end);
561
562           i_offset = 12;
563           while( i_offset < i_descr_end )
564           {
565             DecodePgrmDescriptor(&p_pms[i_offset], p_pgrm);
566             i_offset += p_pms[i_offset+1] + 2;
567           }
568
569           /* Read all the ES descriptions */
570           while( i_offset < i_section_length )
571           {
572             /* Read type of that ES */
573             intf_DbgMsg("ES Type: %d\n", p_pms[i_offset]);
574
575             /* Read PID of that ES */
576             i_es_pid = U16_AT(&p_pms[i_offset+1]) & 0x1fff;
577             intf_DbgMsg("ES PID: %d\n", i_es_pid);
578
579             /* Add the ES to the program description and reserve a slot in the
580                table of ES to store its description */
581             p_es = AddESDescr(p_input, p_pgrm, i_es_pid);
582             if (!p_es)
583             {
584               intf_ErrMsg("Warning: definition for pgrm %d won't be complete\n",
585                           p_pgrm->i_number);
586               /* The best way to handle this is to stop decoding the info for
587                  that section but do as if everything is ok. Thus we will
588                  eventually have an uncomplete ES table marked as being
589                  complete and some error msgs */
590               break;
591             }
592             else
593             {
594               /* Store the description of that PID in the slot */
595               p_es->i_type = p_pms[i_offset];
596               p_es->b_psi = 0;
597               if( i_es_pid == p_pgrm->i_pcr_pid )
598                 p_es->b_pcr = 1;
599               else
600                 p_es->b_pcr = 0;
601               
602               /* Read additional info given by the descriptors */
603               i_offset += 5;
604               intf_DbgMsg("description length for PID %d: %d\n", p_es->i_id,
605                        (U16_AT(&p_pms[i_offset-2]) & 0x0fff));
606               i_descr_end = (U16_AT(&p_pms[i_offset-2]) & 0x0fff) + i_offset;
607               intf_DbgMsg("description ends at offset: %d\n",  i_descr_end);
608               while( i_offset < i_descr_end )
609               {
610                 DecodeESDescriptor(&p_pms[i_offset], p_es);
611                 i_offset += p_pms[i_offset+1] + 2;
612               }
613             }
614
615             /* Jump to next ES description */
616           }
617
618           /* We now know the info carried in this section */
619           intf_DbgMsg("Description of program %d complete\n", p_pgrm->i_number);
620           p_pgrm->b_is_ok = 1;
621           Set_known(p_descr->a_known_PMT_sections, i_current_section);
622         
623           /* Check if the PMT is now complete */
624           p_descr->i_known_PMT_sections++;
625           if( p_descr->i_known_PMT_sections >= i_last_section)
626           {
627               p_descr->b_is_PMT_complete = 1;
628
629 #ifdef AUTO_SPAWN
630               /* Spawn an audio and a video thread, if possible. */
631               for( i_es_loop = 0; i_es_loop < INPUT_MAX_ES; i_es_loop++ )
632               {
633                   switch( p_input->p_es[i_es_loop].i_type )
634                   {
635                       case MPEG1_VIDEO_ES:
636                       case MPEG2_VIDEO_ES:
637                           if( p_main->b_video )
638                           {
639                               /* Spawn a video thread */
640                               input_AddPgrmElem( p_input,
641                                   p_input->p_es[i_es_loop].i_id );
642                           }
643                           break;
644
645                       case AC3_AUDIO_ES:
646                           if ( p_main->b_audio )
647                           {
648                               /* Spawn an ac3 thread */
649                               input_AddPgrmElem( p_input,
650                                   p_input->p_es[i_es_loop].i_id );
651                               }
652                           break;
653
654                       case MPEG1_AUDIO_ES:
655                       case MPEG2_AUDIO_ES:
656                           if( p_main->b_audio )
657                           {
658                               /* Spawn an audio thread */
659                               input_AddPgrmElem( p_input,
660                                   p_input->p_es[i_es_loop].i_id );
661                           }
662                           break;
663
664                       default:
665                           break;
666                   }
667               }
668 #endif
669           }
670         }
671     }
672
673 #undef p_descr
674 }
675
676 /******************************************************************************
677  * DecodeSrvDescrSection
678  ******************************************************************************
679  * A finir et a refaire proprement ????
680  ******************************************************************************/
681 void DecodeSrvDescrSection( byte_t* p_sdt, input_thread_t *p_input )
682 {
683   u16 i_stream_id;
684   u8 i_version;
685   u16 i_length;
686   
687   int i_index;
688   int i_offset;
689   boolean_t b_must_update = 0;
690   
691   int i_descr_end;
692
693   ASSERT(p_sdt);
694   ASSERT(p_input);
695
696 #define p_stream (p_input->p_stream)
697   
698    /* Read stream id and version number immediately, to be sure they will be
699       initialised in all the cases in which we will need them */
700    i_stream_id = U16_AT(&p_sdt[3]);
701    i_version = (p_sdt[5] >> 1) & 0x1F;
702    intf_DbgMsg("TS Id: %d, version: %d\n", i_stream_id, i_version);
703
704    /* Take the descriptor into account only if it describes the streams we are
705       receiving */
706    if( p_stream->i_stream_id != i_stream_id )
707    {
708      intf_DbgMsg("SDT doen't apply to our TS but to %s: aborting\n",
709                   U16_AT(&p_sdt[3]));
710    }
711    else
712    {
713      /* Section applyies to our TS, test if the SDT is up to date */
714      if( p_stream->i_SDT_version != i_version )
715      {
716        intf_DbgMsg("SDT has been updated, NOT YET IMPLEMENTED\n");
717
718        /* Ask the PSI decoder to rebuild the table */
719         b_must_update = 1;
720      }
721    }
722
723    /* Rebuild the table if needed */
724    if( b_must_update )
725    {
726      intf_DbgMsg("Updating SDT table\n");
727
728      i_length = p_sdt[1] & 0x0FFF;
729      i_offset = 11;
730
731      while(i_offset < i_length)
732      {
733        
734        /* Find the program to which the description applies */
735        for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
736        {
737          if( p_stream->ap_programs[i_index]->i_number ==
738              U16_AT(&p_sdt[i_offset]) )
739          {
740            /* Here we are */
741            intf_DbgMsg("FOUND: %d\n", p_stream->ap_programs[i_index]->i_number);
742            break;
743          }
744        }
745
746        /* Copy the info to the description of that program */
747        i_offset += 5;
748        intf_DbgMsg("description length for SDT: %d\n",
749                    (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF));
750        i_descr_end = (U16_AT(&p_sdt[i_offset-2]) & 0x0FFF) + i_offset;
751        intf_DbgMsg("description ends at offset: %d\n",  i_descr_end);
752        while( i_offset < i_descr_end )
753        {
754          DecodePgrmDescriptor(&p_sdt[i_offset], p_stream->ap_programs[i_index]);
755          i_offset += p_sdt[i_offset+1] + 2;
756        }
757      }
758    }
759 #undef p_stream
760 }
761
762 /******************************************************************************
763  * DecodePgrmDescr
764  ******************************************************************************
765  * Decode any descriptor applying to the definition of a program
766  ******************************************************************************/
767 static void DecodePgrmDescriptor( byte_t* p_descriptor,
768                                   pgrm_descriptor_t* p_pgrm )
769 {
770     u8 i_type;                                     /* Type of the descriptor */
771     u8 i_length;                                 /* Length of the descriptor */
772 #ifdef DVB_EXTENSIONS
773     int i_offset;                      /* Current position in the descriptor */
774 #endif
775
776     ASSERT(p_descriptor);
777     ASSERT(p_pgrm);
778
779     /* Read type and length of the descriptor */
780     i_type = p_descriptor[0];
781     i_length = p_descriptor[1];
782
783     /* Handle specific descriptor info */
784     switch(i_type)
785     {
786 #ifdef DVB_EXTENSIONS        
787     case PSI_SERVICE_DESCRIPTOR:
788     {
789         /* Store service type */
790         p_pgrm->i_srv_type = p_descriptor[2];
791
792         /* Jump to the beginning of the service name */
793         i_offset = p_descriptor[3] + 5;
794
795         /* Check that the charset used is the normal one (latin) by testing the
796            first byte of the name */
797         if( p_descriptor[i_offset] >= 0x20 )
798         {
799             /* The charset is the one of our computer: just dup the string */
800             p_pgrm->psz_srv_name = malloc(i_length - i_offset +1);
801             memcpy(p_pgrm->psz_srv_name, &p_descriptor[i_offset],
802                    i_length - i_offset);
803             p_pgrm->psz_srv_name[i_length - i_offset + 1] = '\0';
804         }
805         else
806         {
807             /* Indicate that the name couldn't be printed */
808             p_pgrm->psz_srv_name = "Ununderstandable :)";
809         }
810         break;
811     }
812 #endif
813     default:
814 //        intf_DbgMsg("Unhandled program descriptor received (type: %d)\n", i_type);
815 //        intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
816     }
817 }
818
819 /******************************************************************************
820  * DecodeESDescriptor
821  ******************************************************************************
822  * Decode any descriptor applying to the definition of an ES
823  ******************************************************************************/
824 static void DecodeESDescriptor( byte_t* p_descriptor, es_descriptor_t* p_es )
825 {
826     u8 i_type;                                     /* Type of the descriptor */
827     u8 i_length;                                 /* Length of the descriptor */
828 //    int i_offset;                    /* Current position in the descriptor */
829
830     ASSERT(p_descriptor);
831     ASSERT(p_es);
832
833     /* Read type and length of the descriptor */
834     i_type = p_descriptor[0];
835     i_length = p_descriptor[1];
836
837     switch( i_type )
838     {
839     case PSI_VIDEO_STREAM_DESCRIPTOR:
840     {
841         intf_DbgMsg("Video stream descriptor received\n");
842         break;
843     }
844     case PSI_AUDIO_STREAM_DESCRIPTOR:
845     {
846         intf_DbgMsg("Audio stream descriptor received\n");
847         break;
848     }
849     case PSI_TARGET_BACKGROUND_GRID_DESCRIPTOR:
850     {
851         intf_DbgMsg("Target background descriptor received\n");
852         break;
853     }   
854     case PSI_VIDEO_WINDOW_DESCRIPTOR:
855     {
856         intf_DbgMsg("Video window descriptor received\n");
857         break;
858     }
859     default:
860 //        intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
861 //        intf_DbgMsg("Unhandled ES descriptor received (type: %d)\n", i_type);
862     }
863 }
864
865 /******************************************************************************
866  * input_AddPsiPID: Start to receive the PSI info contained in a PID
867  ******************************************************************************
868  * Add a descriptor to the table of es descriptor for that es and mark the es
869  * as being to be received by the input (since all PSI must be received to
870  * build the description of the program)
871  ******************************************************************************/
872 static int input_AddPsiPID( input_thread_t *p_input, int i_pid )
873 {
874   int i_index;
875   es_descriptor_t* p_psi_es;
876   int i_rc = 0;  
877
878   /* Store the description of this stream in the input thread */
879   p_psi_es = AddESDescr(p_input, NULL, i_pid);
880   
881   if(p_psi_es)
882   {
883     /* Precise this ES carries PSI */
884     p_psi_es->b_psi = 1;
885
886     /* Create the buffer needed by the PSI decoder */
887     p_psi_es->p_psi_section = malloc( sizeof( psi_section_t) );
888     if( !p_psi_es->p_psi_section )
889     {
890       intf_ErrMsg( "Malloc error\n" );
891       i_rc = -1;
892     }
893     else
894     {
895       /* Init the reception for that PID */
896       p_psi_es->p_psi_section->b_running_section = 0;
897 //      p_psi_es->p_psi_section->b_discard_payload = 0;
898
899       /* Ask the input thread to demultiplex it: since the interface
900          can also access the table of selected es, lock the elementary
901          stream structure */
902       vlc_mutex_lock( &p_input->es_lock );
903       for( i_index = 0; i_index < INPUT_MAX_SELECTED_ES; i_index++ )
904       {
905         if( !p_input->pp_selected_es[i_index] )
906         {
907           intf_DbgMsg( "Free Selected ES slot found at offset %d for PID %d\n",
908                        i_index, i_pid );
909           p_input->pp_selected_es[i_index] = p_psi_es;
910           break;
911         }
912       }
913       vlc_mutex_unlock( &p_input->es_lock );
914
915       if( i_index >= INPUT_MAX_SELECTED_ES )
916       {
917         intf_ErrMsg( "Stream carries to many PID for our decoder\n" );
918         i_rc = -1;
919       }
920     }
921   }
922
923   return( i_rc );
924 }
925
926 /******************************************************************************
927  * input_DelPsiPID: Stop to receive the PSI info contained in a PID
928  ******************************************************************************
929  * Remove the PID from the list of ES descriptors and from the list of ES that
930  * the input must receive.
931  * Known PID for PSI should always be received, so that their description
932  * should be pointed out by a member of pp_selected_es. But as INPUT_MAX_ES
933  * can be different of INPUT_MAX_SELECTED_ES, this may happen, so that we must
934  * do 2 loops.
935  ******************************************************************************/
936 static int input_DelPsiPID( input_thread_t *p_input, int i_pid )
937 {
938   int i_es_index, i_last_sel;  
939
940   intf_DbgMsg( "Deleting PSI PID %d\n", i_pid );
941
942   /* Stop to receive the ES. Since the interface can also access the table
943      of selected es, lock the elementary stream structure */
944   vlc_mutex_lock( &p_input->es_lock );
945   
946   for( i_es_index = 0; i_es_index < INPUT_MAX_SELECTED_ES; i_es_index++ )
947   {
948     if( p_input->pp_selected_es[i_es_index] &&
949         p_input->pp_selected_es[i_es_index]->i_id == i_pid )
950     {
951       /* Unmark the stream */
952       p_input->pp_selected_es[i_es_index] = NULL;
953
954       /* There must not be any gap in the pp_selected_es, so move the last
955          selected stream to this slot */
956       for( i_last_sel = i_es_index; p_input->pp_selected_es[i_last_sel] &&
957             i_last_sel < INPUT_MAX_SELECTED_ES; i_last_sel++ );
958       p_input->pp_selected_es[i_es_index] = p_input->pp_selected_es[i_last_sel];
959       p_input->pp_selected_es[i_last_sel] = NULL;
960       break;
961     }
962   }
963
964   vlc_mutex_unlock( &p_input->es_lock );
965
966 #ifdef DEBUG
967   /* Check if the pp_selected_es table may be corrupted */
968   if( i_es_index >= INPUT_MAX_PROGRAM_ES )
969   {
970     intf_ErrMsg( "DelPsiPID error: PID %d is not currently received\n", i_pid );
971   }
972 #endif
973
974   /* Remove the desription of that ES from the table of ES */
975   DestroyESDescr(p_input, NULL, i_pid);
976
977   return( 0 );
978 }
979
980 /******************************************************************************
981  * Precalculate the 32-bit CRC table
982  ******************************************************************************
983  * This table is a global variable shared by all decoders, so it has to be
984  * initialised only once
985  ******************************************************************************/
986 void BuildCrc32Table( )
987 {
988     u32 i, j, k;
989     for( i = 0 ; i < 256 ; i++ )
990     {
991         k = 0;
992         for (j = (i << 24) | 0x800000 ; j != 0x80000000 ; j <<= 1)
993             k = (k << 1) ^ (((k ^ j) & 0x80000000) ? 0x04c11db7 : 0);
994         i_crc_32_table[i] = k;
995     }
996 }
997
998 /******************************************************************************
999  * Test the validity of a checksum
1000  ******************************************************************************
1001  * The checksum must be stored at the end of the data, and the given size must
1002  * include the 32 bits of the CRC.
1003  * Return 0 if the checksum is OK, any other value if the data are corrupted
1004  ******************************************************************************/
1005 int CheckCRC32(byte_t* p_data, int i_data_size)
1006 {  
1007   int i;
1008   u32 i_crc = 0xffffffff;
1009
1010   ASSERT(p_data);
1011
1012   for (i = 0; i < i_data_size; i++)
1013     i_crc = (i_crc << 8) ^ i_crc_32_table[(i_crc >> 24) ^ p_data[i]];
1014
1015   return i_crc;
1016 }
1017
1018 /******************************************************************************
1019  * Is_known: check if a given section has already been received
1020  ******************************************************************************
1021  * As a table cannot be segmented into more than 256 sections, we store a 256
1022  * bits long table, each bit set to one indicating that the corresponding
1023  * saction has been received
1024  ******************************************************************************/
1025 boolean_t Is_known( byte_t* a_known_section, u8 i_section )
1026 {
1027   byte_t mask;
1028   boolean_t b_is_known;
1029   
1030   /* Where to get the information ? */
1031   int i_bit_in_byte = i_section % 8;
1032   int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1033
1034   /* Build mask to read the Is_known flag */
1035   mask = 0x01 << i_bit_in_byte;
1036   
1037   /* Read the flag */
1038   b_is_known = a_known_section[i_byte_in_table] & mask;
1039
1040   return b_is_known;
1041 }
1042
1043 /******************************************************************************
1044  * Set_known: mark a given section has having been received
1045  ******************************************************************************
1046  *
1047  ******************************************************************************/
1048 static void Set_known( byte_t* a_known_section, u8 i_section )
1049 {
1050   byte_t mask;
1051   
1052   /* Where to get the information ? */
1053   int i_bit_in_byte = i_section % 8;
1054   int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1055
1056   /* Build mask to read the Is_known flag */
1057   mask = 0x01 << i_bit_in_byte;
1058   
1059   /* Set the flag */
1060   a_known_section[i_byte_in_table] |= mask;
1061 }
1062
1063 /******************************************************************************
1064  * Unset_known: remove the 'received' mark for a given section
1065  ******************************************************************************
1066  * 
1067  ******************************************************************************/
1068 static void Unset_known( byte_t* a_known_section, u8 i_section )
1069 {
1070   byte_t mask;
1071   
1072   /* Where to get the information ? */
1073   int i_bit_in_byte = i_section % 8;
1074   int i_byte_in_table = (i_section - i_bit_in_byte) / 8;
1075
1076   /* Build mask to read the Is_known flag */
1077   mask = 0x01 << i_bit_in_byte;
1078   mask = ~mask;
1079   
1080   /* Unset the flag */
1081   a_known_section[i_byte_in_table] &= mask;
1082 }
1083
1084 /******************************************************************************
1085  * AddStreamDescr: add and init the stream descriptor of the given input
1086  ******************************************************************************
1087  * 
1088  ******************************************************************************/
1089 static stream_descriptor_t* AddStreamDescr(input_thread_t* p_input,
1090                                            u16 i_stream_id)
1091 {
1092   ASSERT(p_input);
1093   
1094   intf_DbgMsg("Adding description for stream %d\n", i_stream_id);
1095
1096   p_input->p_stream = malloc( sizeof(stream_descriptor_t) );
1097
1098   p_input->p_stream->i_stream_id = i_stream_id;
1099
1100   p_input->p_stream->i_PAT_version = PSI_UNINITIALISED;
1101   p_input->p_stream->i_known_PAT_sections = 0;
1102   bzero( p_input->p_stream->a_known_PAT_sections,
1103          sizeof(*p_input->p_stream->a_known_PAT_sections) );
1104   p_input->p_stream->b_is_PAT_complete = 0;
1105
1106   p_input->p_stream->i_known_PMT_sections = 0;
1107   bzero( p_input->p_stream->a_known_PMT_sections,
1108          sizeof(*p_input->p_stream->a_known_PMT_sections) );
1109   p_input->p_stream->b_is_PMT_complete = 0;
1110
1111 #ifdef DVB_EXTENSIONS
1112   p_input->p_stream->i_SDT_version = PSI_UNINITIALISED;
1113   p_input->p_stream->i_known_SDT_sections = 0;
1114   bzero( p_input->p_stream->a_known_SDT_sections,
1115          sizeof(*p_input->p_stream->a_known_SDT_sections) );
1116   p_input->p_stream->b_is_SDT_complete = 0;
1117 #endif
1118
1119   p_input->p_stream->i_pgrm_number = 0;
1120   p_input->p_stream->ap_programs = NULL;
1121
1122   return p_input->p_stream;
1123 }
1124
1125 /******************************************************************************
1126  * DestroyStreamDescr: destroy the stream desciptor of the given input
1127  ******************************************************************************
1128  * 
1129  ******************************************************************************/
1130 static void DestroyStreamDescr(input_thread_t* p_input, u16 i_stream_id)
1131 {
1132   int i_index;
1133
1134   ASSERT(p_input);
1135
1136   /* Free the structures that describes the programs of that stream */
1137   for( i_index = 0; i_index < p_input->p_stream->i_pgrm_number; i_index++ )
1138   {
1139     DestroyPgrmDescr( p_input, p_input->p_stream,
1140                       p_input->p_stream->ap_programs[i_index]->i_number );
1141   }
1142
1143   /* Free the table of pgrm descriptors */
1144   free( p_input->p_stream->ap_programs );
1145
1146   /* Free the structure that describes the stream itself */
1147   free( p_input->p_stream );
1148
1149   /* Input thread has no more stream descriptor */
1150   p_input->p_stream = NULL;
1151 }
1152
1153 /******************************************************************************
1154  * AddPgrmDescr: add and init a program descriptor
1155  ******************************************************************************
1156  * This program descriptor will be referenced in the given stream descriptor
1157  ******************************************************************************/
1158 static pgrm_descriptor_t* AddPgrmDescr( stream_descriptor_t* p_stream,
1159                                         u16 i_pgrm_id)
1160 {
1161   int i_pgrm_index = p_stream->i_pgrm_number;        /* Where to add the pgrm */
1162   
1163   ASSERT(p_stream);
1164
1165   intf_DbgMsg("Adding description for pgrm %d\n", i_pgrm_id);
1166
1167   /* Add an entry to the list of program associated with the stream */
1168   p_stream->i_pgrm_number++;
1169   p_stream->ap_programs = realloc( p_stream->ap_programs,
1170                           p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t*) );
1171
1172   /* Allocate the structure to store this description */
1173   p_stream->ap_programs[i_pgrm_index] = malloc(sizeof(pgrm_descriptor_t));
1174
1175   /* Init this entry */
1176   p_stream->ap_programs[i_pgrm_index]->i_number = i_pgrm_id;
1177   p_stream->ap_programs[i_pgrm_index]->i_version = PSI_UNINITIALISED;
1178   p_stream->ap_programs[i_pgrm_index]->b_is_ok = 0;
1179
1180   p_stream->ap_programs[i_pgrm_index]->i_es_number = 0;
1181   p_stream->ap_programs[i_pgrm_index]->ap_es = NULL;
1182
1183   /* descriptors ???? */
1184
1185   return p_stream->ap_programs[i_pgrm_index];
1186 }
1187
1188 /******************************************************************************
1189  * AddPgrmDescr: destroy a program descriptor
1190  ******************************************************************************
1191  * All ES descriptions referenced in the descriptor will be deleted.
1192  ******************************************************************************/
1193 static void DestroyPgrmDescr( input_thread_t * p_input,
1194                               stream_descriptor_t * p_stream, u16 i_pgrm_id )
1195 {
1196   int i_index, i_pgrm_index = -1;
1197   pgrm_descriptor_t* p_pgrm = NULL;
1198
1199   ASSERT( p_stream );
1200
1201   intf_DbgMsg("Deleting description for pgrm %d\n", i_pgrm_id);
1202
1203   /* Find where this program is described */
1204   for( i_index = 0; i_index < p_stream->i_pgrm_number; i_index++ )
1205   {
1206     if( p_stream->ap_programs[i_index]->i_number == i_pgrm_id )
1207     {
1208       i_pgrm_index = i_index;
1209       p_pgrm = p_stream->ap_programs[ i_pgrm_index ];
1210       break;
1211     }
1212   }
1213
1214   /* Make sure that the pgrm exists */
1215   ASSERT(i_pgrm_index >= 0);
1216   ASSERT(p_pgrm);
1217   
1218   /* Free the structures that describe the es that belongs to that program */
1219   for( i_index = 0; i_index < p_pgrm->i_es_number; i_index++ )
1220   {
1221     DestroyESDescr( p_input, p_pgrm, p_pgrm->ap_es[i_index]->i_id );
1222   }
1223
1224   /* Free the table of es descriptors */
1225   free( p_pgrm->ap_es );
1226
1227   /* Free the description of this stream */
1228   free( p_pgrm );
1229
1230   /* Remove this program from the stream's list of programs */
1231   p_stream->i_pgrm_number--;
1232   p_stream->ap_programs[i_pgrm_index] = 
1233                                  p_stream->ap_programs[p_stream->i_pgrm_number];
1234   p_stream->ap_programs = realloc( p_stream->ap_programs,
1235                           p_stream->i_pgrm_number*sizeof(pgrm_descriptor_t *) );
1236 }
1237
1238 /******************************************************************************
1239  * AddESDescr:
1240  ******************************************************************************
1241  * Reserve a slot in the table of ES descritors for the ES and add it to the
1242  * list of ES of p_pgrm. If p_pgrm if NULL, then the ES is considered as stand
1243  * alone (PSI ?)
1244  ******************************************************************************/
1245 static es_descriptor_t* AddESDescr(input_thread_t* p_input,
1246                                    pgrm_descriptor_t* p_pgrm, u16 i_es_pid)
1247 {
1248   int i_index;
1249   es_descriptor_t* p_es = NULL;
1250   
1251   ASSERT(p_input);
1252   
1253   intf_DbgMsg("Adding description for ES %d\n", i_es_pid);
1254
1255   /* Find an empty slot to store the description of that es */
1256   for( i_index = 0; i_index < INPUT_MAX_ES &&
1257         p_input->p_es[i_index].i_id != EMPTY_PID; i_index++ );
1258
1259   if( i_index >= INPUT_MAX_ES )
1260   {
1261     /* No slot is empty */
1262     intf_ErrMsg("Stream carries to many PID for our decoder\n");
1263   }
1264   else
1265   {
1266     /* Reserve the slot for that ES */
1267     p_es = &p_input->p_es[i_index];
1268     p_es->i_id = i_es_pid;
1269     intf_DbgMsg("Slot %d in p_es table assigned to ES %d\n", i_index, i_es_pid);
1270     
1271     /* Init its values */
1272     p_es->i_type = 0;  /* ??? */
1273     p_es->b_psi = 0;
1274     p_es->b_pcr = 0;
1275     p_es->i_continuity_counter = 0xFF;
1276     
1277     p_es->p_pes_packet = NULL;
1278 //    p_es->p_next_pes_packet = NULL;
1279     p_es->p_dec = NULL;
1280
1281     /* Add this ES to the program definition if one is given */
1282     if( p_pgrm )
1283     {
1284       p_pgrm->i_es_number++;
1285       p_pgrm->ap_es = realloc( p_pgrm->ap_es,
1286                                p_pgrm->i_es_number*sizeof(es_descriptor_t *) );
1287       p_pgrm->ap_es[p_pgrm->i_es_number-1] = p_es;
1288       intf_DbgMsg( "Added ES %d to definition of pgrm %d\n",
1289                    i_es_pid, p_pgrm->i_number );
1290     }
1291     else
1292       intf_DbgMsg( "Added ES %d not added to the definition of any pgrm\n",
1293                    i_es_pid );
1294   }
1295   
1296   return p_es;
1297 }
1298
1299 /******************************************************************************
1300  * DestroyESDescr:
1301  ******************************************************************************
1302  * 
1303  ******************************************************************************/
1304 static void DestroyESDescr(input_thread_t* p_input,
1305                            pgrm_descriptor_t* p_pgrm, u16 i_pid)
1306 {
1307   int i_index;
1308   
1309   /* Look for the description of the ES */
1310   for(i_index = 0; i_index < INPUT_MAX_ES; i_index++)
1311   {
1312     if( p_input->p_es[i_index].i_id == i_pid )
1313     {
1314       /* The table of stream descriptors is static, so don't free memory
1315          but just mark the slot as unused */
1316       p_input->p_es[i_index].i_id = EMPTY_PID;
1317       break;
1318     }
1319   }
1320
1321   /* Remove this ES from the description of the program if it is associated to
1322      one */
1323   if( p_pgrm )
1324   {
1325     for( i_index = 0; i_index < INPUT_MAX_ES; i_index++ )
1326     {
1327       if( p_input->p_es[i_index].i_id == i_pid )
1328       {
1329         p_pgrm->i_es_number--;
1330         p_pgrm->ap_es[i_index] = p_pgrm->ap_es[p_pgrm->i_es_number];
1331         p_pgrm->ap_es = realloc(p_pgrm->ap_es, p_pgrm->i_es_number);
1332         break;
1333       }
1334     }
1335   }
1336 }