5152eacff52295b0bebc75d5a1bbb7117c8f5dd8
[vlc.git] / modules / demux / mpeg / ts.c
1 /*****************************************************************************
2  * mpeg_ts.c : Transport Stream input module for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2001 VideoLAN
5  * $Id: ts.c,v 1.25 2003/05/31 00:10:11 fenrir Exp $
6  *
7  * Authors: Henri Fallon <henri@via.ecp.fr>
8  *          Johan Bilien <jobi@via.ecp.fr>
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
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28 #include <stdlib.h>
29 #include <string.h>
30
31 #ifdef HAVE_STDINT_H
32 #   include <stdint.h>                                            /* uint8_t */
33 #endif
34
35 #include <vlc/vlc.h>
36 #include <vlc/input.h>
37
38 #include "iso_lang.h"
39
40 #if defined MODULE_NAME_IS_ts_dvbpsi
41 #   ifdef HAVE_DVBPSI_DR_H
42 #       include <dvbpsi/dvbpsi.h>
43 #       include <dvbpsi/descriptor.h>
44 #       include <dvbpsi/pat.h>
45 #       include <dvbpsi/pmt.h>
46 #       include <dvbpsi/dr.h>
47 #   else
48 #       include "dvbpsi.h"
49 #       include "descriptor.h"
50 #       include "tables/pat.h"
51 #       include "tables/pmt.h"
52 #       include "descriptors/dr.h"
53 #   endif
54 #endif
55
56 #include "system.h"
57 #include "codecs.h"
58
59 /*****************************************************************************
60  * Constants
61  *****************************************************************************/
62 #define TS_READ_ONCE 200
63
64 /*****************************************************************************
65  * Private structure
66  *****************************************************************************/
67 struct demux_sys_t
68 {
69     module_t *   p_module;
70     mpeg_demux_t mpeg;
71 };
72
73 /*****************************************************************************
74  * Local prototypes
75  *****************************************************************************/
76 static int  Activate   ( vlc_object_t * );
77 static void Deactivate ( vlc_object_t * );
78 static int  Demux      ( input_thread_t * );
79
80 #if defined MODULE_NAME_IS_ts
81 static void TSDemuxPSI ( input_thread_t *, data_packet_t *,
82                           es_descriptor_t *, vlc_bool_t );
83 static void TSDecodePAT( input_thread_t *, es_descriptor_t *);
84 static void TSDecodePMT( input_thread_t *, es_descriptor_t *);
85 #define PSI_CALLBACK TSDemuxPSI
86 #elif defined MODULE_NAME_IS_ts_dvbpsi
87 static void TS_DVBPSI_DemuxPSI  ( input_thread_t *, data_packet_t *,
88                                   es_descriptor_t *, vlc_bool_t );
89 static void TS_DVBPSI_HandlePAT ( input_thread_t *, dvbpsi_pat_t * );
90 static void TS_DVBPSI_HandlePMT ( input_thread_t *, dvbpsi_pmt_t * );
91 #define PSI_CALLBACK TS_DVBPSI_DemuxPSI
92 #endif
93
94 /*****************************************************************************
95  * Module descriptor
96  *****************************************************************************/
97 #define VLS_BACKWARDS_COMPAT_TEXT N_("Compatibility with pre-0.4 VLS")
98 #define VLS_BACKWARDS_COMPAT_LONGTEXT N_( \
99     "The protocol for transmitting A/52 audio streams changed between VLC " \
100     "0.3.x and 0.4. By default VLC assumes you have the latest VLS. In case " \
101     "you're using an old version, select this option.")
102
103 #define BUGGY_PSI_TEXT N_("Buggy PSI")
104 #define BUGGY_PSI_LONGTEXT N_( \
105     "If you have a stream whose PSI packets do not feature incremented " \
106     "continuity counters, select this option.")
107
108 vlc_module_begin();
109 #if defined MODULE_NAME_IS_ts
110     set_description( _("ISO 13818-1 MPEG Transport Stream input") );
111     set_capability( "demux", 160 );
112     add_shortcut( "ts" );
113 #elif defined MODULE_NAME_IS_ts_dvbpsi
114     set_description( _("ISO 13818-1 MPEG Transport Stream input (libdvbpsi)") );
115     set_capability( "demux", 170 );
116     add_shortcut( "ts_dvbpsi" );
117 #endif
118     add_category_hint( N_("Miscellaneous"), NULL, VLC_TRUE );
119     add_bool( "vls-backwards-compat", 0, NULL,
120               VLS_BACKWARDS_COMPAT_TEXT, VLS_BACKWARDS_COMPAT_LONGTEXT, VLC_TRUE );
121     add_bool( "buggy-psi", 0, NULL, BUGGY_PSI_TEXT, BUGGY_PSI_LONGTEXT, VLC_TRUE );
122     set_callbacks( Activate, Deactivate );
123 vlc_module_end();
124
125 /*****************************************************************************
126  * Activate: initialize TS structures
127  *****************************************************************************/
128 static int Activate( vlc_object_t * p_this )
129 {
130     input_thread_t *    p_input = (input_thread_t *)p_this;
131     demux_sys_t *       p_demux;
132     es_descriptor_t *   p_pat_es;
133     es_ts_data_t *      p_demux_data;
134     stream_ts_data_t *  p_stream_data;
135     byte_t *            p_peek;
136
137     /* Set the demux function */
138     p_input->pf_demux = Demux;
139
140     /* Initialize access plug-in structures. */
141     if( p_input->i_mtu == 0 )
142     {
143         /* Improve speed. */
144         p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
145     }
146
147     /* Have a peep at the show. */
148     if( input_Peek( p_input, &p_peek, 1 ) < 1 )
149     {
150         msg_Err( p_input, "cannot peek()" );
151         return -1;
152     }
153
154     if( *p_peek != TS_SYNC_CODE )
155     {
156         if( *p_input->psz_demux && ( !strncmp( p_input->psz_demux, "ts", 3 )
157                          || !strncmp( p_input->psz_demux, "ts_dvbpsi", 10 ) ) )
158         {
159             /* User forced */
160             msg_Err( p_input, "this does not look like a TS stream, continuing" );
161         }
162         else
163         {
164             msg_Warn( p_input, "TS module discarded (no sync)" );
165             return -1;
166         }
167     }
168
169     /* Adapt the bufsize for our only use. */
170     if( p_input->i_mtu != 0 )
171     {
172         /* Have minimum granularity to avoid bottlenecks at the input level. */
173         p_input->i_bufsize = (p_input->i_mtu / TS_PACKET_SIZE) * TS_PACKET_SIZE;
174     }
175
176     p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );
177     if( p_demux == NULL )
178     {
179         return -1;
180     }
181
182     p_input->p_private = (void*)&p_demux->mpeg;
183     p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );
184     if( p_demux->p_module == NULL )
185     {
186         free( p_input->p_demux_data );
187         return -1;
188     }
189
190     vlc_mutex_lock( &p_input->stream.stream_lock );
191
192     if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
193     {
194         module_Unneed( p_input, p_demux->p_module );
195         free( p_input->p_demux_data );
196         return -1;
197     }
198
199     p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
200     p_stream_data->i_pat_version = PAT_UNINITIALIZED ;
201     p_stream_data->b_buggy_psi = config_GetInt( p_input, "buggy-psi" );
202
203 #ifdef MODULE_NAME_IS_ts_dvbpsi
204     p_stream_data->p_pat_handle = (dvbpsi_handle *)
205       dvbpsi_AttachPAT( (dvbpsi_pat_callback) &TS_DVBPSI_HandlePAT, p_input );
206
207     if( p_stream_data->p_pat_handle == NULL )
208     {
209         msg_Err( p_input, "could not create PAT decoder" );
210         module_Unneed( p_input, p_demux->p_module );
211         free( p_input->p_demux_data );
212         return -1;
213     }
214 #endif
215
216     /* We'll have to catch the PAT in order to continue
217      * Then the input will catch the PMT and then the others ES
218      * The PAT es is indepedent of any program. */
219     p_pat_es = input_AddES( p_input, NULL, 0x00,
220                             UNKNOWN_ES, NULL, sizeof( es_ts_data_t ) );
221     p_demux_data = (es_ts_data_t *)p_pat_es->p_demux_data;
222     p_demux_data->b_psi = 1;
223     p_demux_data->i_psi_type = PSI_IS_PAT;
224     p_demux_data->p_psi_section = malloc(sizeof(psi_section_t));
225     p_demux_data->p_psi_section->b_is_complete = 1;
226     p_demux_data->i_continuity_counter = 0xFF;
227
228     vlc_mutex_unlock( &p_input->stream.stream_lock );
229
230     return 0;
231 }
232
233 /*****************************************************************************
234  * Deactivate: deinitialize TS structures
235  *****************************************************************************/
236 static void Deactivate( vlc_object_t * p_this )
237 {
238     input_thread_t *    p_input = (input_thread_t *)p_this;
239
240     module_Unneed( p_input, p_input->p_demux_data->p_module );
241     free( p_input->p_demux_data );
242 }
243
244 /*****************************************************************************
245  * Demux: reads and demuxes data packets
246  *****************************************************************************
247  * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
248  * packets.
249  *****************************************************************************/
250 static int Demux( input_thread_t * p_input )
251 {
252     demux_sys_t *   p_demux = p_input->p_demux_data;
253     int             i_read_once = (p_input->i_mtu ?
254                                    p_input->i_bufsize / TS_PACKET_SIZE :
255                                    TS_READ_ONCE);
256     int             i;
257
258     for( i = 0; i < i_read_once; i++ )
259     {
260         data_packet_t *     p_data;
261         ssize_t             i_result;
262
263         i_result = p_demux->mpeg.pf_read_ts( p_input, &p_data );
264
265         if( i_result <= 0 )
266         {
267             return i_result;
268         }
269
270         p_demux->mpeg.pf_demux_ts( p_input, p_data,
271                                    (psi_callback_t) &PSI_CALLBACK );
272     }
273
274     return i_read_once;
275 }
276
277
278 #if defined MODULE_NAME_IS_ts
279 /*
280  * PSI demultiplexing and decoding without libdvbpsi
281  */
282
283 /*****************************************************************************
284  * DemuxPSI : makes up complete PSI data
285  *****************************************************************************/
286 static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data,
287         es_descriptor_t * p_es, vlc_bool_t b_unit_start )
288 {
289     es_ts_data_t  * p_demux_data;
290
291     p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
292
293 #define p_psi (p_demux_data->p_psi_section)
294 #define p (p_data->p_payload_start)
295
296     if( b_unit_start )
297     {
298         /* unit_start set to 1 -> presence of a pointer field
299          * (see ISO/IEC 13818 (2.4.4.2) which should be set to 0x00 */
300         if( (u8)p[0] != 0x00 )
301         {
302             msg_Warn( p_input,
303                       "non-zero pointer field found, trying to continue" );
304             p+=(u8)p[0];
305         }
306         else
307         {
308             p++;
309         }
310
311         /* This is the begining of a new section */
312
313         if( ((u8)(p[1]) & 0xc0) != 0x80 )
314         {
315             msg_Warn( p_input, "invalid PSI packet" );
316             p_psi->b_trash = 1;
317         }
318         else
319         {
320             p_psi->i_section_length = ((p[1] & 0xF) << 8) | p[2];
321             p_psi->b_section_complete = 0;
322             p_psi->i_read_in_section = 0;
323             p_psi->i_section_number = (u8)p[6];
324
325             if( p_psi->b_is_complete || p_psi->i_section_number == 0 )
326             {
327                 /* This is a new PSI packet */
328                 p_psi->b_is_complete = 0;
329                 p_psi->b_trash = 0;
330                 p_psi->i_version_number = ( p[5] >> 1 ) & 0x1f;
331                 p_psi->i_last_section_number = (u8)p[7];
332
333                 /* We'll write at the begining of the buffer */
334                 p_psi->p_current = p_psi->buffer;
335             }
336             else
337             {
338                 if( p_psi->b_section_complete )
339                 {
340                     /* New Section of an already started PSI */
341                     p_psi->b_section_complete = 0;
342
343                     if( p_psi->i_version_number != (( p[5] >> 1 ) & 0x1f) )
344                     {
345                         msg_Warn( p_input,
346                                   "PSI version differs inside same PAT" );
347                         p_psi->b_trash = 1;
348                     }
349                     if( p_psi->i_section_number + 1 != (u8)p[6] )
350                     {
351                         msg_Warn( p_input,
352                                   "PSI Section discontinuity, packet lost?" );
353                         p_psi->b_trash = 1;
354                     }
355                     else
356                         p_psi->i_section_number++;
357                 }
358                 else
359                 {
360                     msg_Warn( p_input, "got unexpected new PSI section" );
361                     p_psi->b_trash = 1;
362                 }
363             }
364         }
365     } /* b_unit_start */
366
367     if( !p_psi->b_trash )
368     {
369         /* read */
370         if( (p_data->p_payload_end - p) >=
371             ( p_psi->i_section_length - p_psi->i_read_in_section ) )
372         {
373             /* The end of the section is in this TS packet */
374             memcpy( p_psi->p_current, p,
375             (p_psi->i_section_length - p_psi->i_read_in_section) );
376
377             p_psi->b_section_complete = 1;
378             p_psi->p_current +=
379                 (p_psi->i_section_length - p_psi->i_read_in_section);
380
381             if( p_psi->i_section_number == p_psi->i_last_section_number )
382             {
383                 /* This was the last section of PSI */
384                 p_psi->b_is_complete = 1;
385
386                 switch( p_demux_data->i_psi_type)
387                 {
388                 case PSI_IS_PAT:
389                     TSDecodePAT( p_input, p_es );
390                     break;
391                 case PSI_IS_PMT:
392                     TSDecodePMT( p_input, p_es );
393                     break;
394                 default:
395                     msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
396                 }
397             }
398         }
399         else
400         {
401             memcpy( p_psi->buffer, p, p_data->p_payload_end - p );
402             p_psi->i_read_in_section += p_data->p_payload_end - p;
403
404             p_psi->p_current += p_data->p_payload_end - p;
405         }
406     }
407
408 #undef p_psi
409 #undef p
410
411     input_DeletePacket( p_input->p_method_data, p_data );
412
413     return ;
414 }
415
416 /*****************************************************************************
417  * DecodePAT : Decodes Programm association table and deal with it
418  *****************************************************************************/
419 static void TSDecodePAT( input_thread_t * p_input, es_descriptor_t * p_es )
420 {
421     stream_ts_data_t  * p_stream_data;
422     es_ts_data_t      * p_demux_data;
423
424     pgrm_descriptor_t * p_pgrm;
425     es_descriptor_t   * p_current_es;
426     byte_t            * p_current_data;
427
428     int                 i_section_length, i_program_id, i_pmt_pid;
429     int                 i_loop, i_current_section;
430
431     vlc_bool_t          b_changed = 0;
432
433     p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
434     p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
435
436 #define p_psi (p_demux_data->p_psi_section)
437
438     /* Not so fast, Mike ! If the PAT version has changed, we first check
439      * that its content has really changed before doing anything */
440     if( p_stream_data->i_pat_version != p_psi->i_version_number )
441     {
442         int i_programs = p_input->stream.i_pgrm_number;
443
444         p_current_data = p_psi->buffer;
445
446         do
447         {
448             i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
449                                  p_current_data[2];
450             i_current_section = (u8)p_current_data[6];
451
452             for( i_loop = 0;
453                  ( i_loop < (i_section_length - 9) / 4 ) && !b_changed;
454                  i_loop++ )
455             {
456                 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
457                                  | *(p_current_data + i_loop * 4 + 9);
458                 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
459                                     << 8 )
460                                | *(p_current_data + i_loop * 4 + 11);
461
462                 if( i_program_id )
463                 {
464                     if( (p_pgrm = input_FindProgram( p_input, i_program_id ))
465                         && (p_current_es = input_FindES( p_input, i_pmt_pid ))
466                         && p_current_es->p_pgrm == p_pgrm
467                         && p_current_es->i_id == i_pmt_pid
468                         && ((es_ts_data_t *)p_current_es->p_demux_data)->b_psi
469                         && ((es_ts_data_t *)p_current_es->p_demux_data)
470                             ->i_psi_type == PSI_IS_PMT )
471                     {
472                         i_programs--;
473                     }
474                     else
475                     {
476                         b_changed = 1;
477                     }
478                 }
479             }
480
481             p_current_data += 3 + i_section_length;
482
483         } while( ( i_current_section < p_psi->i_last_section_number )
484                   && !b_changed );
485
486         /* If we didn't find the expected amount of programs, the PAT has
487          * changed. Otherwise, it only changed if b_changed is already != 0 */
488         b_changed = b_changed || i_programs;
489     }
490
491     if( b_changed )
492     {
493         /* PAT has changed. We are going to delete all programs and
494          * create new ones. We chose not to only change what was needed
495          * as a PAT change may mean the stream is radically changing and
496          * this is a secure method to avoid crashes */
497         es_ts_data_t      * p_es_demux;
498         pgrm_ts_data_t    * p_pgrm_demux;
499
500         p_current_data = p_psi->buffer;
501
502         /* Delete all programs */
503         while( p_input->stream.i_pgrm_number )
504         {
505             input_DelProgram( p_input, p_input->stream.pp_programs[0] );
506         }
507
508         do
509         {
510             i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
511                                  p_current_data[2];
512             i_current_section = (u8)p_current_data[6];
513
514             for( i_loop = 0; i_loop < (i_section_length - 9) / 4 ; i_loop++ )
515             {
516                 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
517                                  | *(p_current_data + i_loop * 4 + 9);
518                 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
519                                     << 8 )
520                                | *(p_current_data + i_loop * 4 + 11);
521
522                 /* If program = 0, we're having info about NIT not PMT */
523                 if( i_program_id )
524                 {
525                     /* Add this program */
526                     p_pgrm = input_AddProgram( p_input, i_program_id,
527                                                sizeof( pgrm_ts_data_t ) );
528
529                     /* whatis the PID of the PMT of this program */
530                     p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
531                     p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
532
533                     /* Add the PMT ES to this program */
534                     p_current_es = input_AddES( p_input, p_pgrm,(u16)i_pmt_pid,
535                         UNKNOWN_ES, NULL, sizeof( es_ts_data_t) );
536                     p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
537                     p_es_demux->b_psi = 1;
538                     p_es_demux->i_psi_type = PSI_IS_PMT;
539
540                     p_es_demux->p_psi_section =
541                                             malloc( sizeof( psi_section_t ) );
542                     p_es_demux->p_psi_section->b_is_complete = 0;
543                     p_es_demux->i_continuity_counter = 0xFF;
544                 }
545             }
546
547             p_current_data += 3 + i_section_length;
548
549         } while( i_current_section < p_psi->i_last_section_number );
550
551         /* Go to the beginning of the next section */
552         p_stream_data->i_pat_version = p_psi->i_version_number;
553
554     }
555 #undef p_psi
556
557 }
558
559 /*****************************************************************************
560  * DecodePMT : decode a given Program Stream Map
561  * ***************************************************************************
562  * When the PMT changes, it may mean a deep change in the stream, and it is
563  * careful to delete the ES and add them again. If the PMT doesn't change,
564  * there no need to do anything.
565  *****************************************************************************/
566 static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es )
567 {
568
569     pgrm_ts_data_t            * p_pgrm_data;
570     es_ts_data_t              * p_demux_data;
571     vlc_bool_t b_vls_compat = config_GetInt( p_input, "vls-backwards-compat" );
572
573     p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
574     p_pgrm_data = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;
575
576 #define p_psi (p_demux_data->p_psi_section)
577
578     if( p_psi->i_version_number != p_pgrm_data->i_pmt_version )
579     {
580         es_descriptor_t   * p_new_es;
581         es_ts_data_t      * p_es_demux;
582         byte_t            * p_current_data, * p_current_section;
583         int                 i_section_length,i_current_section;
584         int                 i_prog_info_length, i_loop;
585         int                 i_es_info_length, i_pid, i_stream_type;
586
587         p_current_section = p_psi->buffer;
588         p_current_data = p_psi->buffer;
589
590         p_pgrm_data->i_pcr_pid = ( ((u32)*(p_current_section + 8) & 0x1F) << 8 ) |
591                                     *(p_current_section + 9);
592
593
594         /* Lock stream information */
595         vlc_mutex_lock( &p_input->stream.stream_lock );
596
597         /* Delete all ES in this program  except the PSI. We start from the
598          * end because i_es_number gets decremented after each deletion. */
599         for( i_loop = p_es->p_pgrm->i_es_number ; i_loop ; )
600         {
601             i_loop--;
602             p_es_demux = (es_ts_data_t *)
603                          p_es->p_pgrm->pp_es[i_loop]->p_demux_data;
604             if ( ! p_es_demux->b_psi )
605             {
606                 input_DelES( p_input, p_es->p_pgrm->pp_es[i_loop] );
607             }
608         }
609
610         /* Then add what we received in this PMT */
611         do
612         {
613             i_section_length = ( ((u32)*(p_current_data + 1) & 0xF) << 8 ) |
614                                   *(p_current_data + 2);
615             i_current_section = (u8)p_current_data[6];
616             i_prog_info_length = ( ((u32)*(p_current_data + 10) & 0xF) << 8 ) |
617                                     *(p_current_data + 11);
618
619             /* For the moment we ignore program descriptors */
620             p_current_data += 12 + i_prog_info_length;
621
622             /* The end of the section, before the CRC is at
623              * p_current_section + i_section_length -1 */
624             while( p_current_data < p_current_section + i_section_length -1 )
625             {
626                 i_stream_type = (int)p_current_data[0];
627                 i_pid = ( ((u32)*(p_current_data + 1) & 0x1F) << 8 ) |
628                            *(p_current_data + 2);
629                 i_es_info_length = ( ((u32)*(p_current_data + 3) & 0xF) << 8 ) |
630                                       *(p_current_data + 4);
631
632                 /* Tell the interface what kind of stream it is and select
633                  * the required ones */
634                 {
635                     int i_fourcc, i_cat, i_stream_id;
636
637                     switch( i_stream_type )
638                     {
639                         case MPEG1_VIDEO_ES:
640                         case MPEG2_VIDEO_ES:
641                         case MPEG2_MOTO_VIDEO_ES:
642                             /* This isn't real, but we don't actually use
643                              * it. */
644                             i_stream_id = 0xE0;
645                             i_fourcc = VLC_FOURCC('m','p','g','v');
646                             i_cat = VIDEO_ES;
647                             break;
648                         case MPEG1_AUDIO_ES:
649                         case MPEG2_AUDIO_ES:
650                             /* This isn't real, but we don't actually use
651                              * it. */
652                             i_stream_id = 0xC0;
653                             i_fourcc = VLC_FOURCC('m','p','g','a');
654                             i_cat = AUDIO_ES;
655                             break;
656                         case A52_AUDIO_ES:
657                         case A52DVB_AUDIO_ES:
658                             if ( !b_vls_compat )
659                                 i_fourcc = VLC_FOURCC('a','5','2',' ');
660                             else
661                                 i_fourcc = VLC_FOURCC('a','5','2','b');
662                             i_stream_id = 0xBD;
663                             i_cat = AUDIO_ES;
664                             break;
665                         case LPCM_AUDIO_ES:
666                             i_fourcc = VLC_FOURCC('l','p','c','m');
667                             i_stream_id = 0xBD;
668                             i_cat = AUDIO_ES;
669                             break;
670                         case DVD_SPU_ES:
671                             if ( !b_vls_compat )
672                                 i_fourcc = VLC_FOURCC('s','p','u',' ');
673                             else
674                                 i_fourcc = VLC_FOURCC('s','p','u','b');
675                             i_stream_id = 0xBD;
676                             i_cat = SPU_ES;
677                             break;
678                         case SDDS_AUDIO_ES:
679                             i_fourcc = VLC_FOURCC('s','d','d','s');
680                             i_stream_id = 0xBD;
681                             i_cat = AUDIO_ES;
682                             break;
683                         case DTS_AUDIO_ES:
684                             i_fourcc = VLC_FOURCC('d','t','s',' ');
685                             i_stream_id = 0xBD;
686                             i_cat = AUDIO_ES;
687                             break;
688                         /* 'b' stands for 'buggy' */
689                         case A52B_AUDIO_ES:
690                             i_fourcc = VLC_FOURCC('a','5','2','b');
691                             i_stream_id = 0xBD;
692                             i_cat = AUDIO_ES;
693                             break;
694                         case LPCMB_AUDIO_ES:
695                             i_fourcc = VLC_FOURCC('l','p','c','b');
696                             i_stream_id = 0xBD;
697                             i_cat = AUDIO_ES;
698                             break;
699                         case DVDB_SPU_ES:
700                             i_fourcc = VLC_FOURCC('s','p','u','b');
701                             i_stream_id = 0xBD;
702                             i_cat = SPU_ES;
703                             break;
704
705                         default :
706                             i_stream_id = 0;
707                             i_fourcc = 0;
708                             i_cat = UNKNOWN_ES;
709                             break;
710                     }
711
712                     /* Add this ES to the program */
713                     p_new_es = input_AddES( p_input, p_es->p_pgrm, (u16)i_pid,
714                                    i_cat, NULL, sizeof( es_ts_data_t ) );
715
716                     ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter = 0xFF;
717
718                     p_new_es->i_stream_id = i_stream_id;
719                     p_new_es->i_fourcc = i_fourcc;
720
721                 }
722
723                 p_current_data += 5 + i_es_info_length;
724             }
725
726             /* Go to the beginning of the next section*/
727             p_current_data += 3 + i_section_length;
728
729             p_current_section++;
730
731         } while( i_current_section < p_psi->i_last_section_number );
732
733         p_pgrm_data->i_pmt_version = p_psi->i_version_number;
734
735         /* if no program is selected :*/
736         if( !p_input->stream.p_selected_program )
737         {
738             pgrm_descriptor_t *     p_pgrm_to_select;
739             u16 i_id = (u16)config_GetInt( p_input, "program" );
740
741             if( i_id != 0 ) /* if user specified a program */
742             {
743                 p_pgrm_to_select = input_FindProgram( p_input, i_id );
744
745                 if( p_pgrm_to_select && p_pgrm_to_select == p_es->p_pgrm )
746                     p_input->pf_set_program( p_input, p_pgrm_to_select );
747             }
748             else
749                     p_input->pf_set_program( p_input, p_es->p_pgrm );
750         }
751
752         /* if the pmt belongs to the currently selected program, we
753          * reselect it to update its ES */
754         else if( p_es->p_pgrm == p_input->stream.p_selected_program )
755         {
756             p_input->pf_set_program( p_input, p_es->p_pgrm );
757         }
758
759         /* inform interface that stream has changed */
760         p_input->stream.b_changed = 1;
761         /*  Remove lock */
762         vlc_mutex_unlock( &p_input->stream.stream_lock );
763     }
764
765 #undef p_psi
766 }
767
768 #elif defined MODULE_NAME_IS_ts_dvbpsi
769 /*
770  * PSI Decoding using libdvbpsi
771  */
772
773 /*****************************************************************************
774  * DemuxPSI : send the PSI to the right libdvbpsi decoder
775  *****************************************************************************/
776 static void TS_DVBPSI_DemuxPSI( input_thread_t  * p_input,
777                                 data_packet_t   * p_data,
778                                 es_descriptor_t * p_es,
779                                 vlc_bool_t        b_unit_start )
780 {
781     es_ts_data_t        * p_es_demux_data;
782     pgrm_ts_data_t      * p_pgrm_demux_data;
783     stream_ts_data_t    * p_stream_demux_data;
784
785     p_es_demux_data = (es_ts_data_t *)p_es->p_demux_data;
786     p_stream_demux_data = (stream_ts_data_t *) p_input->stream.p_demux_data;
787
788     switch( p_es_demux_data->i_psi_type)
789     {
790         case PSI_IS_PAT:
791             dvbpsi_PushPacket(
792                     (dvbpsi_handle)p_stream_demux_data->p_pat_handle,
793                     p_data->p_demux_start );
794             break;
795         case PSI_IS_PMT:
796             p_pgrm_demux_data = ( pgrm_ts_data_t * )p_es->p_pgrm->p_demux_data;
797             dvbpsi_PushPacket(
798                     (dvbpsi_handle)p_pgrm_demux_data->p_pmt_handle,
799                     p_data->p_demux_start );
800             break;
801         default:
802             msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
803     }
804
805     input_DeletePacket( p_input->p_method_data, p_data );
806 }
807 /*****************************************************************************
808  * MP4 specific functions
809  *****************************************************************************/
810 static int  MP4_DescriptorLength( int *pi_data, uint8_t **pp_data )
811 {
812     unsigned int i_b;
813     unsigned int i_len = 0;
814     do
815     {
816         i_b = **pp_data;
817         (*pp_data)++;
818         (*pi_data)--;
819         i_len = ( i_len << 7 ) + ( i_b&0x7f );
820
821     } while( i_b&0x80 );
822
823     return( i_len );
824 }
825 static int MP4_GetByte( int *pi_data, uint8_t **pp_data )
826 {
827     if( *pi_data > 0 )
828     {
829         int i_b = **pp_data;
830         (*pp_data)++;
831         (*pi_data)--;
832         return( i_b );
833     }
834     else
835     {
836         return( 0 );
837     }
838 }
839
840 static int MP4_GetWord( int *pi_data, uint8_t **pp_data )
841 {
842     int i1, i2;
843     i1 = MP4_GetByte( pi_data, pp_data );
844     i2 = MP4_GetByte( pi_data, pp_data );
845     return( ( i1 << 8 ) | i2 );
846 }
847 static int MP4_Get3Bytes( int *pi_data, uint8_t **pp_data )
848 {
849     int i1, i2, i3;
850     i1 = MP4_GetByte( pi_data, pp_data );
851     i2 = MP4_GetByte( pi_data, pp_data );
852     i3 = MP4_GetByte( pi_data, pp_data );
853     return( ( i1 << 16 ) | ( i2 << 8) | i3 );
854 }
855
856 static uint32_t MP4_GetDWord( int *pi_data, uint8_t **pp_data )
857 {
858     uint32_t i1, i2;
859     i1 = MP4_GetWord( pi_data, pp_data );
860     i2 = MP4_GetWord( pi_data, pp_data );
861     return( ( i1 << 16 ) | i2 );
862 }
863
864 static char* MP4_GetURL( int *pi_data, uint8_t **pp_data )
865 {
866     char *url;
867     int i_url_len, i;
868
869     i_url_len = MP4_GetByte( pi_data, pp_data );
870     url = malloc( i_url_len + 1 );
871     for( i = 0; i < i_url_len; i++ )
872     {
873         url[i] = MP4_GetByte( pi_data, pp_data );
874     }
875     url[i_url_len] = '\0';
876     return( url );
877 }
878
879 static void MP4_IODParse( iod_descriptor_t *p_iod, int i_data, uint8_t *p_data )
880 {
881     int i;
882     int i_es_index;
883     uint8_t     i_flags;
884     vlc_bool_t  b_url;
885     int         i_iod_length;
886
887     fprintf( stderr, "\n************ IOD ************" );
888     for( i = 0; i < 255; i++ )
889     {
890         p_iod->es_descr[i].b_ok = 0;
891     }
892     i_es_index = 0;
893
894     if( i_data < 3 )
895     {
896         return;
897     }
898
899     p_iod->i_iod_label = MP4_GetByte( &i_data, &p_data );
900     fprintf( stderr, "\n* iod_label:%d", p_iod->i_iod_label );
901     fprintf( stderr, "\n* ===========" );
902     fprintf( stderr, "\n* tag:0x%x", p_data[0] );
903
904     if( MP4_GetByte( &i_data, &p_data ) != 0x02 )
905     {
906         fprintf( stderr, "\n ERR: tag != 0x02" );
907         return;
908     }
909
910     i_iod_length = MP4_DescriptorLength( &i_data, &p_data );
911     fprintf( stderr, "\n* length:%d", i_iod_length );
912     if( i_iod_length > i_data )
913     {
914         i_iod_length = i_data;
915     }
916
917     p_iod->i_od_id = ( MP4_GetByte( &i_data, &p_data ) << 2 );
918     i_flags = MP4_GetByte( &i_data, &p_data );
919     p_iod->i_od_id |= i_flags >> 6;
920     b_url = ( i_flags >> 5  )&0x01;
921
922     fprintf( stderr, "\n* od_id:%d", p_iod->i_od_id );
923     fprintf( stderr, "\n* url flag:%d", b_url );
924     fprintf( stderr, "\n* includeInlineProfileLevel flag:%d", ( i_flags >> 4 )&0x01 );
925
926     if( b_url )
927     {
928         p_iod->psz_url = MP4_GetURL( &i_data, &p_data );
929         fprintf( stderr, "\n* url string:%s", p_iod->psz_url );
930         fprintf( stderr, "\n*****************************\n" );
931         return;
932     }
933     else
934     {
935         p_iod->psz_url = NULL;
936     }
937
938     p_iod->i_ODProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
939     p_iod->i_sceneProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
940     p_iod->i_audioProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
941     p_iod->i_visualProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
942     p_iod->i_graphicsProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
943
944     fprintf( stderr, "\n* ODProfileLevelIndication:%d", p_iod->i_ODProfileLevelIndication );
945     fprintf( stderr, "\n* sceneProfileLevelIndication:%d", p_iod->i_sceneProfileLevelIndication );
946     fprintf( stderr, "\n* audioProfileLevelIndication:%d", p_iod->i_audioProfileLevelIndication );
947     fprintf( stderr, "\n* visualProfileLevelIndication:%d", p_iod->i_visualProfileLevelIndication );
948     fprintf( stderr, "\n* graphicsProfileLevelIndication:%d", p_iod->i_graphicsProfileLevelIndication );
949
950
951     while( i_data > 0 && i_es_index < 255)
952     {
953         int i_tag, i_length;
954         int     i_data_sav;
955         uint8_t *p_data_sav;
956
957         i_tag = MP4_GetByte( &i_data, &p_data );
958         i_length = MP4_DescriptorLength( &i_data, &p_data );
959
960         i_data_sav = i_data;
961         p_data_sav = p_data;
962
963         i_data = i_length;
964
965         switch( i_tag )
966         {
967             case 0x03:
968                 {
969 #define es_descr    p_iod->es_descr[i_es_index]
970                     int i_decoderConfigDescr_length;
971                     fprintf( stderr, "\n* - ES_Descriptor length:%d", i_length );
972                     es_descr.b_ok = 1;
973
974                     es_descr.i_es_id = MP4_GetWord( &i_data, &p_data );
975                     i_flags = MP4_GetByte( &i_data, &p_data );
976                     es_descr.b_streamDependenceFlag = ( i_flags >> 7 )&0x01;
977                     b_url = ( i_flags >> 6 )&0x01;
978                     es_descr.b_OCRStreamFlag = ( i_flags >> 5 )&0x01;
979                     es_descr.i_streamPriority = i_flags & 0x1f;
980                     fprintf( stderr, "\n*   * streamDependenceFlag:%d", es_descr.b_streamDependenceFlag );
981                     fprintf( stderr, "\n*   * OCRStreamFlag:%d", es_descr.b_OCRStreamFlag );
982                     fprintf( stderr, "\n*   * streamPriority:%d", es_descr.i_streamPriority );
983
984                     if( es_descr.b_streamDependenceFlag )
985                     {
986                         es_descr.i_dependOn_es_id = MP4_GetWord( &i_data, &p_data );
987                         fprintf( stderr, "\n*   * dependOn_es_id:%d", es_descr.i_dependOn_es_id );
988                     }
989
990                     if( b_url )
991                     {
992                         es_descr.psz_url = MP4_GetURL( &i_data, &p_data );
993                         fprintf( stderr, "\n* url string:%s", es_descr.psz_url );
994                     }
995                     else
996                     {
997                         es_descr.psz_url = NULL;
998                     }
999
1000                     if( es_descr.b_OCRStreamFlag )
1001                     {
1002                         es_descr.i_OCR_es_id = MP4_GetWord( &i_data, &p_data );
1003                         fprintf( stderr, "\n*   * OCR_es_id:%d", es_descr.i_OCR_es_id );
1004                     }
1005
1006                     if( MP4_GetByte( &i_data, &p_data ) != 0x04 )
1007                     {
1008                         fprintf( stderr, "\n* ERR missing DecoderConfigDescr" );
1009                         es_descr.b_ok = 0;
1010                         break;
1011                     }
1012                     i_decoderConfigDescr_length = MP4_DescriptorLength( &i_data, &p_data );
1013
1014                     fprintf( stderr, "\n*   - DecoderConfigDesc length:%d", i_decoderConfigDescr_length );
1015 #define dec_descr   es_descr.dec_descr
1016                     dec_descr.i_objectTypeIndication = MP4_GetByte( &i_data, &p_data );
1017                     i_flags = MP4_GetByte( &i_data, &p_data );
1018                     dec_descr.i_streamType = i_flags >> 2;
1019                     dec_descr.b_upStream = ( i_flags >> 1 )&0x01;
1020                     dec_descr.i_bufferSizeDB = MP4_Get3Bytes( &i_data, &p_data );
1021                     dec_descr.i_maxBitrate = MP4_GetDWord( &i_data, &p_data );
1022                     dec_descr.i_avgBitrate = MP4_GetDWord( &i_data, &p_data );
1023                     fprintf( stderr, "\n*     * objectTypeIndication:0x%x", dec_descr.i_objectTypeIndication  );
1024                     fprintf( stderr, "\n*     * streamType:0x%x", dec_descr.i_streamType );
1025                     fprintf( stderr, "\n*     * upStream:%d", dec_descr.b_upStream );
1026                     fprintf( stderr, "\n*     * bufferSizeDB:%d", dec_descr.i_bufferSizeDB );
1027                     fprintf( stderr, "\n*     * maxBitrate:%d", dec_descr.i_maxBitrate );
1028                     fprintf( stderr, "\n*     * avgBitrate:%d", dec_descr.i_avgBitrate );
1029                     if( i_decoderConfigDescr_length > 13 && MP4_GetByte( &i_data, &p_data ) == 0x05 )
1030                     {
1031                         int i;
1032                         dec_descr.i_decoder_specific_info_len =
1033                             MP4_DescriptorLength( &i_data, &p_data );
1034                         if( dec_descr.i_decoder_specific_info_len > 0 )
1035                         {
1036                             dec_descr.p_decoder_specific_info =
1037                                 malloc( dec_descr.i_decoder_specific_info_len );
1038                         }
1039                         for( i = 0; i < dec_descr.i_decoder_specific_info_len; i++ )
1040                         {
1041                             dec_descr.p_decoder_specific_info[i] = MP4_GetByte( &i_data, &p_data );
1042                         }
1043                     }
1044                     else
1045                     {
1046                         dec_descr.i_decoder_specific_info_len = 0;
1047                         dec_descr.p_decoder_specific_info = NULL;
1048                     }
1049                 }
1050 #undef  dec_descr
1051 #define sl_descr    es_descr.sl_descr
1052                 {
1053                     int i_SLConfigDescr_length;
1054                     int i_predefined;
1055
1056                     if( MP4_GetByte( &i_data, &p_data ) != 0x06 )
1057                     {
1058                         fprintf( stderr, "\n* ERR missing SLConfigDescr" );
1059                         es_descr.b_ok = 0;
1060                         break;
1061                     }
1062                     i_SLConfigDescr_length = MP4_DescriptorLength( &i_data, &p_data );
1063
1064                     fprintf( stderr, "\n*   - SLConfigDescr length:%d", i_SLConfigDescr_length );
1065                     i_predefined = MP4_GetByte( &i_data, &p_data );
1066                     fprintf( stderr, "\n*     * i_predefined:0x%x", i_predefined  );
1067                     switch( i_predefined )
1068                     {
1069                         case 0x01:
1070                             {
1071                                 sl_descr.b_useAccessUnitStartFlag   = 0;
1072                                 sl_descr.b_useAccessUnitEndFlag     = 0;
1073                                 sl_descr.b_useRandomAccessPointFlag = 0;
1074                                 //sl_descr.b_useRandomAccessUnitsOnlyFlag = 0;
1075                                 sl_descr.b_usePaddingFlag           = 0;
1076                                 sl_descr.b_useTimeStampsFlags       = 0;
1077                                 sl_descr.b_useIdleFlag              = 0;
1078                                 sl_descr.b_durationFlag     = 0;    // FIXME FIXME
1079                                 sl_descr.i_timeStampResolution      = 1000;
1080                                 sl_descr.i_OCRResolution    = 0;    // FIXME FIXME
1081                                 sl_descr.i_timeStampLength          = 32;
1082                                 sl_descr.i_OCRLength        = 0;    // FIXME FIXME
1083                                 sl_descr.i_AU_Length                = 0;
1084                                 sl_descr.i_instantBitrateLength= 0; // FIXME FIXME
1085                                 sl_descr.i_degradationPriorityLength= 0;
1086                                 sl_descr.i_AU_seqNumLength          = 0;
1087                                 sl_descr.i_packetSeqNumLength       = 0;
1088                                 if( sl_descr.b_durationFlag )
1089                                 {
1090                                     sl_descr.i_timeScale            = 0;    // FIXME FIXME
1091                                     sl_descr.i_accessUnitDuration   = 0;    // FIXME FIXME
1092                                     sl_descr.i_compositionUnitDuration= 0;    // FIXME FIXME
1093                                 }
1094                                 if( !sl_descr.b_useTimeStampsFlags )
1095                                 {
1096                                     sl_descr.i_startDecodingTimeStamp   = 0;    // FIXME FIXME
1097                                     sl_descr.i_startCompositionTimeStamp= 0;    // FIXME FIXME
1098                                 }
1099                             }
1100                             break;
1101                         default:
1102                             fprintf( stderr, "\n* ERR unsupported SLConfigDescr predefined" );
1103                             es_descr.b_ok = 0;
1104                             break;
1105                     }
1106                 }
1107                 break;
1108 #undef  sl_descr
1109 #undef  es_descr
1110             default:
1111                 fprintf( stderr, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag, i_length );
1112                 break;
1113         }
1114
1115         p_data = p_data_sav + i_length;
1116         i_data = i_data_sav - i_length;
1117         i_es_index++;
1118     }
1119
1120
1121     fprintf( stderr, "\n*****************************\n" );
1122 }
1123
1124 static void MP4_IODClean( iod_descriptor_t *p_iod )
1125 {
1126     int i;
1127
1128     if( p_iod->psz_url )
1129     {
1130         free( p_iod->psz_url );
1131         p_iod->psz_url = NULL;
1132         return;
1133     }
1134
1135     for( i = 0; i < 255; i++ )
1136     {
1137 #define es_descr p_iod->es_descr[i]
1138         if( es_descr.b_ok )
1139         {
1140             if( es_descr.psz_url )
1141             {
1142                 free( es_descr.psz_url );
1143                 es_descr.psz_url = NULL;
1144             }
1145             else
1146             {
1147                 if( es_descr.dec_descr.p_decoder_specific_info != NULL )
1148                 {
1149                     free( es_descr.dec_descr.p_decoder_specific_info );
1150                     es_descr.dec_descr.p_decoder_specific_info = NULL;
1151                     es_descr.dec_descr.i_decoder_specific_info_len = 0;
1152                 }
1153             }
1154         }
1155         es_descr.b_ok = 0;
1156 #undef  es_descr
1157     }
1158 }
1159
1160 /*****************************************************************************
1161  * HandlePAT: will treat a PAT returned by dvbpsi
1162  *****************************************************************************/
1163 static void TS_DVBPSI_HandlePAT( input_thread_t * p_input,
1164                                  dvbpsi_pat_t * p_new_pat )
1165 {
1166     dvbpsi_pat_program_t *      p_pgrm;
1167     pgrm_descriptor_t *         p_new_pgrm;
1168     pgrm_ts_data_t *            p_pgrm_demux;
1169     es_descriptor_t *           p_current_es;
1170     es_ts_data_t *              p_es_demux;
1171     stream_ts_data_t *          p_stream_data;
1172
1173     vlc_mutex_lock( &p_input->stream.stream_lock );
1174
1175     p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
1176
1177     if ( ( p_new_pat->b_current_next && ( p_new_pat->i_version != p_stream_data->i_pat_version ) ) ||
1178             p_stream_data->i_pat_version == PAT_UNINITIALIZED  )
1179     {
1180         /* Delete all programs */
1181         while( p_input->stream.i_pgrm_number )
1182         {
1183             pgrm_ts_data_t *p_pgrm_demux_old =
1184                 (pgrm_ts_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
1185
1186             if( p_pgrm_demux_old->b_mpeg4 )
1187             {
1188                 MP4_IODClean( &p_pgrm_demux_old->iod );
1189             }
1190
1191             input_DelProgram( p_input, p_input->stream.pp_programs[0] );
1192         }
1193
1194         /* treat the new programs list */
1195         p_pgrm = p_new_pat->p_first_program;
1196
1197         while( p_pgrm )
1198         {
1199             /* If program = 0, we're having info about NIT not PMT */
1200             if( p_pgrm->i_number )
1201             {
1202                 /* Add this program */
1203                 p_new_pgrm = input_AddProgram( p_input, p_pgrm->i_number,
1204                                             sizeof( pgrm_ts_data_t ) );
1205
1206                 p_pgrm_demux = (pgrm_ts_data_t *)p_new_pgrm->p_demux_data;
1207                 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
1208
1209                 /* Add the PMT ES to this program */
1210                 p_current_es = input_AddES( p_input, p_new_pgrm,
1211                                             (u16)p_pgrm->i_pid, UNKNOWN_ES,
1212                                             NULL, sizeof(es_ts_data_t) );
1213                 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
1214                 p_es_demux->b_psi = 1;
1215                 p_es_demux->i_psi_type = PSI_IS_PMT;
1216
1217                 p_es_demux->p_psi_section = malloc( sizeof( psi_section_t ) );
1218                 if ( p_es_demux->p_psi_section == NULL )
1219                 {
1220                     msg_Err( p_input, "out of memory" );
1221                     p_input->b_error = 1;
1222                     return;
1223                 }
1224
1225                 p_es_demux->p_psi_section->b_is_complete = 0;
1226                 p_es_demux->i_continuity_counter = 0xFF;
1227
1228                 /* Create a PMT decoder */
1229                 p_pgrm_demux->p_pmt_handle = (dvbpsi_handle *)
1230                     dvbpsi_AttachPMT( p_pgrm->i_number,
1231                             (dvbpsi_pmt_callback) &TS_DVBPSI_HandlePMT,
1232                             p_input );
1233
1234                 if( p_pgrm_demux->p_pmt_handle == NULL )
1235                 {
1236                     msg_Err( p_input, "could not create PMT decoder" );
1237                     p_input->b_error = 1;
1238                     return;
1239                 }
1240
1241             }
1242             p_pgrm = p_pgrm->p_next;
1243         }
1244
1245         p_stream_data->i_pat_version = p_new_pat->i_version;
1246     }
1247     vlc_mutex_unlock( &p_input->stream.stream_lock );
1248 }
1249
1250
1251 /*****************************************************************************
1252  * HandlePMT: will treat a PMT returned by dvbpsi
1253  *****************************************************************************/
1254 static void TS_DVBPSI_HandlePMT( input_thread_t * p_input,
1255                                  dvbpsi_pmt_t * p_new_pmt )
1256 {
1257     dvbpsi_pmt_es_t *       p_es;
1258     pgrm_descriptor_t *     p_pgrm;
1259     es_descriptor_t *       p_new_es;
1260     pgrm_ts_data_t *        p_pgrm_demux;
1261     vlc_bool_t b_vls_compat = config_GetInt( p_input, "vls-backwards-compat" );
1262
1263     vlc_mutex_lock( &p_input->stream.stream_lock );
1264
1265     p_pgrm = input_FindProgram( p_input, p_new_pmt->i_program_number );
1266
1267     if( p_pgrm == NULL )
1268     {
1269         msg_Warn( p_input, "PMT of unreferenced program found" );
1270         return;
1271     }
1272
1273     p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
1274     p_pgrm_demux->i_pcr_pid = p_new_pmt->i_pcr_pid;
1275
1276     if( ( p_new_pmt->b_current_next &&
1277           ( p_new_pmt->i_version != p_pgrm_demux->i_pmt_version ) ) ||
1278           p_pgrm_demux->i_pmt_version == PMT_UNINITIALIZED )
1279     {
1280         dvbpsi_descriptor_t *p_dr = p_new_pmt->p_first_descriptor;
1281         /* IOD */
1282         while( p_dr && ( p_dr->i_tag != 0x1d ) )
1283             p_dr = p_dr->p_next;
1284         if( p_dr)
1285         {
1286             msg_Warn( p_input, "found IOD descriptor" );
1287             MP4_IODParse( &p_pgrm_demux->iod, p_dr->i_length, p_dr->p_data );
1288         }
1289
1290         p_es = p_new_pmt->p_first_es;
1291         while( p_es )
1292         {
1293             vlc_fourcc_t i_fourcc;
1294             int i_size, i_cat, i_stream_id = 0;
1295             es_ts_data_t demux_data;
1296             BITMAPINFOHEADER *p_bih = NULL;
1297             WAVEFORMATEX *p_wf = NULL;
1298             char psz_desc[30];
1299
1300             memset( &demux_data, 0, sizeof(es_ts_data_t) );
1301             *psz_desc = 0;
1302
1303             switch( p_es->i_type )
1304             {
1305                 case MPEG1_VIDEO_ES:
1306                 case MPEG2_VIDEO_ES:
1307                 case MPEG2_MOTO_VIDEO_ES:
1308                     i_fourcc = VLC_FOURCC('m','p','g','v');
1309                     i_cat = VIDEO_ES;
1310                     break;
1311                 case MPEG1_AUDIO_ES:
1312                 case MPEG2_AUDIO_ES:
1313                     i_fourcc = VLC_FOURCC('m','p','g','a');
1314                     i_cat = AUDIO_ES;
1315                     break;
1316                 case A52_AUDIO_ES:
1317                 case A52DVB_AUDIO_ES:
1318                     if ( !b_vls_compat )
1319                         i_fourcc = VLC_FOURCC('a','5','2',' ');
1320                     else
1321                         i_fourcc = VLC_FOURCC('a','5','2','b');
1322                     i_cat = AUDIO_ES;
1323                     i_stream_id = 0xBD;
1324                     break;
1325                 case DVD_SPU_ES:
1326                     if ( !b_vls_compat )
1327                         i_fourcc = VLC_FOURCC('s','p','u',' ');
1328                     else
1329                         i_fourcc = VLC_FOURCC('s','p','u','b');
1330                     i_cat = SPU_ES;
1331                     i_stream_id = 0xBD;
1332                     break;
1333                 case LPCM_AUDIO_ES:
1334                     i_fourcc = VLC_FOURCC('l','p','c','m');
1335                     i_cat = AUDIO_ES;
1336                     i_stream_id = 0xBD;
1337                     break;
1338                 case SDDS_AUDIO_ES:
1339                     i_fourcc = VLC_FOURCC('s','d','d','s');
1340                     i_stream_id = 0xBD;
1341                     i_cat = AUDIO_ES;
1342                     break;
1343                 case DTS_AUDIO_ES:
1344                     i_fourcc = VLC_FOURCC('d','t','s',' ');
1345                     i_stream_id = 0xBD;
1346                     i_cat = AUDIO_ES;
1347                     break;
1348                 case A52B_AUDIO_ES:
1349                     i_fourcc = VLC_FOURCC('a','5','2','b');
1350                     i_cat = AUDIO_ES;
1351                     i_stream_id = 0xBD;
1352                     break;
1353                 case DVDB_SPU_ES:
1354                     i_fourcc = VLC_FOURCC('s','p','u','b');
1355                     i_cat = SPU_ES;
1356                     i_stream_id = 0xBD;
1357                     break;
1358                 case LPCMB_AUDIO_ES:
1359                     i_fourcc = VLC_FOURCC('l','p','c','b');
1360                     i_cat = AUDIO_ES;
1361                     i_stream_id = 0xBD;
1362                     break;
1363                 case MPEG4_VIDEO_ES:
1364                     i_fourcc = VLC_FOURCC('m','p','4','v');
1365                     i_cat = VIDEO_ES;
1366                     i_stream_id = 0xfa;
1367                     break;
1368                 case MPEG4_AUDIO_ES:
1369                     i_fourcc = VLC_FOURCC('m','p','4','a');
1370                     i_cat = AUDIO_ES;
1371                     i_stream_id = 0xfa;
1372                     break;
1373                 case MSCODEC_VIDEO_ES:
1374                     i_fourcc = VLC_FOURCC(0,0,0,0);   // fixed later
1375                     i_cat = VIDEO_ES;
1376                     i_stream_id = 0xa0;
1377                     break;
1378                 default:
1379                     i_fourcc = 0;
1380                     i_cat = UNKNOWN_ES;
1381                     i_stream_id = 0;
1382             }
1383
1384             if( p_es->i_type == MPEG4_VIDEO_ES ||
1385                 p_es->i_type == MPEG4_AUDIO_ES )
1386             {
1387                 /* mpeg4 stream, search sl_descriptor */
1388                 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1389
1390                 while( p_dr && ( p_dr->i_tag != 0x1f ) ) p_dr = p_dr->p_next;
1391
1392                 if( p_dr && p_dr->i_length == 2 )
1393                 {
1394                     int i_es_descr_index;
1395
1396                     demux_data.i_es_id =
1397                         ( p_dr->p_data[0] << 8 ) | p_dr->p_data[1];
1398                     demux_data.p_es_descr = NULL;
1399
1400                     msg_Warn( p_input, "found SL_descriptor" );
1401                     for( i_es_descr_index = 0; i_es_descr_index < 255;
1402                          i_es_descr_index++ )
1403                     {
1404                         if( p_pgrm_demux->iod.es_descr[i_es_descr_index].b_ok &&
1405                             p_pgrm_demux->iod.es_descr[i_es_descr_index].i_es_id == demux_data.i_es_id )
1406                         {
1407                             demux_data.p_es_descr =
1408                                 &p_pgrm_demux->iod.es_descr[i_es_descr_index];
1409                             break;
1410                         }
1411                     }
1412                 }
1413
1414                 if( demux_data.p_es_descr != NULL )
1415                 {
1416 #define DESCR demux_data.p_es_descr->dec_descr
1417                     demux_data.b_mpeg4 = 1;
1418
1419                     /* fix fourcc */
1420                     switch( DESCR.i_streamType )
1421                     {
1422                     case 0x04:  /* VisualStream */
1423                         i_cat = VIDEO_ES;
1424                         switch( DESCR.i_objectTypeIndication )
1425                         {
1426                         case 0x20:
1427                             i_fourcc = VLC_FOURCC('m','p','4','v');    // mpeg4
1428                             break;
1429                         case 0x60:
1430                         case 0x61:
1431                         case 0x62:
1432                         case 0x63:
1433                         case 0x64:
1434                         case 0x65:
1435                             i_fourcc = VLC_FOURCC( 'm','p','g','v' );  // mpeg2
1436                             break;
1437                         case 0x6a:
1438                             i_fourcc = VLC_FOURCC( 'm','p','g','v' );  // mpeg1
1439                             break;
1440                         case 0x6c:
1441                             i_fourcc = VLC_FOURCC( 'j','p','e','g' );  // mpeg1
1442                             break;
1443                         default:
1444                             i_fourcc = 0;
1445                             break;
1446                         }
1447                         break;
1448                     case 0x05:  /* AudioStream */
1449                         i_cat = AUDIO_ES;
1450                         switch( DESCR.i_objectTypeIndication )
1451                         {
1452                         case 0x40:
1453                             i_fourcc = VLC_FOURCC('m','p','4','a');    // mpeg4
1454                             break;
1455                         case 0x66:
1456                         case 0x67:
1457                         case 0x68:
1458                             i_fourcc = VLC_FOURCC('m','p','4','a');// mpeg2 aac
1459                             break;
1460                         case 0x69:
1461                             i_fourcc = VLC_FOURCC('m','p','g','a');    // mpeg2
1462                             break;
1463                         case 0x6b:
1464                             i_fourcc = VLC_FOURCC('m','p','g','a');    // mpeg1
1465                             break;
1466                         default:
1467                             i_fourcc = 0;
1468                             break;
1469                         }
1470                         break;
1471                     default:
1472                         i_cat = UNKNOWN_ES;
1473                         i_fourcc = 0;
1474                         break;
1475                     }
1476
1477                     switch( i_cat )
1478                     {
1479                     case VIDEO_ES:
1480                         i_size = sizeof( BITMAPINFOHEADER ) +
1481                                  DESCR.i_decoder_specific_info_len;
1482                         p_bih = malloc( i_size );
1483                         p_bih->biSize = i_size;
1484                         p_bih->biWidth = 0;
1485                         p_bih->biHeight = 0;
1486                         p_bih->biPlanes = 1;
1487                         p_bih->biBitCount = 0;
1488                         p_bih->biCompression = 0;
1489                         p_bih->biSizeImage = 0;
1490                         p_bih->biXPelsPerMeter = 0;
1491                         p_bih->biYPelsPerMeter = 0;
1492                         p_bih->biClrUsed = 0;
1493                         p_bih->biClrImportant = 0;
1494                         memcpy( &p_bih[1],
1495                                 DESCR.p_decoder_specific_info,
1496                                 DESCR.i_decoder_specific_info_len );
1497                         break;
1498                     case AUDIO_ES:
1499                         i_size = sizeof( WAVEFORMATEX ) +
1500                                  DESCR.i_decoder_specific_info_len;
1501                         p_wf = malloc( i_size );
1502                         p_wf->wFormatTag = 0xffff;
1503                         p_wf->nChannels = 0;
1504                         p_wf->nSamplesPerSec = 0;
1505                         p_wf->nAvgBytesPerSec = 0;
1506                         p_wf->nBlockAlign = 1;
1507                         p_wf->wBitsPerSample = 0;
1508                         p_wf->cbSize = DESCR.i_decoder_specific_info_len;
1509                         memcpy( &p_wf[1],
1510                                 DESCR.p_decoder_specific_info,
1511                                 DESCR.i_decoder_specific_info_len );
1512                         break;
1513                     default:
1514                         break;
1515                     }
1516                 }
1517                 else
1518                 {
1519                     msg_Warn( p_input,
1520                               "mpeg4 stream without (valid) sl_descriptor" );
1521                     demux_data.b_mpeg4 = 0;
1522                 }
1523
1524             }
1525             else if( p_es->i_type == MSCODEC_VIDEO_ES )
1526             {
1527                 /* crapy ms codec stream, search private descriptor */
1528                 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1529
1530                 while( p_dr && ( p_dr->i_tag != 0xa0 ) ) p_dr = p_dr->p_next;
1531
1532                 if( p_dr && p_dr->i_length >= 8 )
1533                 {
1534                     int i_bih_size;
1535                     i_fourcc = VLC_FOURCC( p_dr->p_data[0], p_dr->p_data[1], p_dr->p_data[2], p_dr->p_data[3] );
1536
1537                     i_bih_size = (p_dr->p_data[8] << 8) | p_dr->p_data[9];
1538                     i_size = sizeof( BITMAPINFOHEADER ) + i_bih_size;
1539
1540                     p_bih = malloc( i_size );
1541                     p_bih->biSize = i_size;
1542                     p_bih->biWidth = ( p_dr->p_data[4] << 8 )|p_dr->p_data[5];
1543                     p_bih->biHeight = ( p_dr->p_data[6] << 8 )|p_dr->p_data[7];
1544                     p_bih->biPlanes = 1;
1545                     p_bih->biBitCount = 0;
1546                     p_bih->biCompression = 0;
1547                     p_bih->biSizeImage = 0;
1548                     p_bih->biXPelsPerMeter = 0;
1549                     p_bih->biYPelsPerMeter = 0;
1550                     p_bih->biClrUsed = 0;
1551                     p_bih->biClrImportant = 0;
1552                     memcpy( &p_bih[1], &p_dr->p_data[10], i_bih_size );
1553                 }
1554                 else
1555                 {
1556                     msg_Warn( p_input, "private ms-codec stream without bih "
1557                               "private sl_descriptor" );
1558                     i_fourcc = 0;
1559                     i_cat = UNKNOWN_ES;
1560                 }
1561             }
1562
1563             if( i_cat == AUDIO_ES || i_cat == SPU_ES )
1564             {
1565                 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1566                 while( p_dr && ( p_dr->i_tag != 0x0a ) ) p_dr = p_dr->p_next;
1567
1568                 if( p_dr )
1569                 {
1570                     dvbpsi_iso639_dr_t *p_decoded =
1571                                                 dvbpsi_DecodeISO639Dr( p_dr );
1572                     if( p_decoded->i_code_count > 0 )
1573                     {
1574                         const iso639_lang_t * p_iso;
1575                         p_iso = GetLang_2T((char*)p_decoded->i_iso_639_code);
1576
1577                         if( p_iso )
1578                         {
1579                             if( p_iso->psz_native_name[0] )
1580                                 strncpy( psz_desc,
1581                                          p_iso->psz_native_name, 20 );
1582                             else
1583                                 strncpy( psz_desc,
1584                                          p_iso->psz_eng_name, 20 );
1585                         }
1586                         else
1587                         {
1588                             strncpy( psz_desc, p_decoded->i_iso_639_code, 3 );
1589                         }
1590                     }
1591                 }
1592                 switch( p_es->i_type )
1593                 {
1594                     case MPEG1_AUDIO_ES:
1595                     case MPEG2_AUDIO_ES:
1596                         strcat( psz_desc, " (mpeg)" );
1597                         break;
1598                     case LPCM_AUDIO_ES:
1599                     case LPCMB_AUDIO_ES:
1600                         strcat( psz_desc, " (lpcm)" );
1601                         break;
1602                     case A52_AUDIO_ES:
1603                     case A52DVB_AUDIO_ES:
1604                     case A52B_AUDIO_ES:
1605                         strcat( psz_desc, " (A52)" );
1606                         break;
1607                     case MPEG4_AUDIO_ES:
1608                         strcat( psz_desc, " (aac)" );
1609                         break;
1610                 }
1611             }
1612
1613             /* Add this ES */
1614             p_new_es = input_AddES( p_input, p_pgrm, (u16)p_es->i_pid,
1615                                     i_cat, psz_desc, sizeof( es_ts_data_t ) );
1616             if( p_new_es == NULL )
1617             {
1618                 msg_Err( p_input, "could not add ES %d", p_es->i_pid );
1619                 p_input->b_error = 1;
1620                 return;
1621             }
1622             p_new_es->i_fourcc = i_fourcc;
1623             p_new_es->i_stream_id = i_stream_id;
1624             p_new_es->p_bitmapinfoheader = (void*)p_bih;
1625             p_new_es->p_waveformatex = (void*)p_wf;
1626             memcpy( p_new_es->p_demux_data, &demux_data,
1627                     sizeof(es_ts_data_t) );
1628
1629             ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter =
1630                 0xFF;
1631
1632             p_es = p_es->p_next;
1633         }
1634
1635         /* if no program is selected :*/
1636         if( !p_input->stream.p_selected_program )
1637         {
1638             pgrm_descriptor_t *     p_pgrm_to_select;
1639             u16 i_id = (u16)config_GetInt( p_input, "program" );
1640
1641             if( i_id != 0 ) /* if user specified a program */
1642             {
1643                 p_pgrm_to_select = input_FindProgram( p_input, i_id );
1644
1645                 if( p_pgrm_to_select && p_pgrm_to_select == p_pgrm )
1646                     p_input->pf_set_program( p_input, p_pgrm_to_select );
1647             }
1648             else
1649                     p_input->pf_set_program( p_input, p_pgrm );
1650         }
1651         /* if the pmt belongs to the currently selected program, we
1652          * reselect it to update its ES */
1653         else if( p_pgrm == p_input->stream.p_selected_program )
1654         {
1655             p_input->pf_set_program( p_input, p_pgrm );
1656         }
1657
1658         p_pgrm_demux->i_pmt_version = p_new_pmt->i_version;
1659         p_input->stream.b_changed = 1;
1660     }
1661     vlc_mutex_unlock( &p_input->stream.stream_lock );
1662 }
1663 #endif