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