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