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