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