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