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