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