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