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