1 /*****************************************************************************
2 * mpeg_ts.c : Transport Stream input module for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2001 VideoLAN
5 * $Id: ts.c,v 1.14 2003/01/08 16:40:29 fenrir Exp $
7 * Authors: Henri Fallon <henri@via.ecp.fr>
8 * Johan Bilien <jobi@via.ecp.fr>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
32 # include <stdint.h> /* uint8_t */
36 #include <vlc/input.h>
40 #if defined MODULE_NAME_IS_ts_dvbpsi
41 # ifdef HAVE_DVBPSI_DR_H
42 # include <dvbpsi/dvbpsi.h>
43 # include <dvbpsi/descriptor.h>
44 # include <dvbpsi/pat.h>
45 # include <dvbpsi/pmt.h>
46 # include <dvbpsi/dr.h>
49 # include "descriptor.h"
50 # include "tables/pat.h"
51 # include "tables/pmt.h"
52 # include "descriptors/dr.h"
59 /*****************************************************************************
61 *****************************************************************************/
62 #define TS_READ_ONCE 200
64 /*****************************************************************************
66 *****************************************************************************/
73 /*****************************************************************************
75 *****************************************************************************/
76 static int Activate ( vlc_object_t * );
77 static void Deactivate ( vlc_object_t * );
78 static int Demux ( input_thread_t * );
80 #if defined MODULE_NAME_IS_ts
81 static void TSDemuxPSI ( input_thread_t *, data_packet_t *,
82 es_descriptor_t *, vlc_bool_t );
83 static void TSDecodePAT( input_thread_t *, es_descriptor_t *);
84 static void TSDecodePMT( input_thread_t *, es_descriptor_t *);
85 #define PSI_CALLBACK TSDemuxPSI
86 #elif defined MODULE_NAME_IS_ts_dvbpsi
87 static void TS_DVBPSI_DemuxPSI ( input_thread_t *, data_packet_t *,
88 es_descriptor_t *, vlc_bool_t );
89 static void TS_DVBPSI_HandlePAT ( input_thread_t *, dvbpsi_pat_t * );
90 static void TS_DVBPSI_HandlePMT ( input_thread_t *, dvbpsi_pmt_t * );
91 #define PSI_CALLBACK TS_DVBPSI_DemuxPSI
94 /*****************************************************************************
96 *****************************************************************************/
97 #define VLS_BACKWARDS_COMPAT_TEXT N_("compatibility with pre-0.4 VLS")
98 #define VLS_BACKWARDS_COMPAT_LONGTEXT N_( \
99 "The protocol for transmitting A/52 audio streams changed between VLC " \
100 "0.3.x and 0.4. By default VLC assumes you have the latest VLS. In case " \
101 "you're using an old version, select this option.")
104 #if defined MODULE_NAME_IS_ts
105 set_description( _("ISO 13818-1 MPEG Transport Stream input") );
106 set_capability( "demux", 160 );
107 add_shortcut( "ts" );
108 #elif defined MODULE_NAME_IS_ts_dvbpsi
109 set_description( _("ISO 13818-1 MPEG Transport Stream input (libdvbpsi)") );
110 set_capability( "demux", 170 );
111 add_shortcut( "ts_dvbpsi" );
113 add_category_hint( N_("Miscellaneous"), NULL );
114 add_bool( "vls-backwards-compat", 0, NULL,
115 VLS_BACKWARDS_COMPAT_TEXT, VLS_BACKWARDS_COMPAT_LONGTEXT );
116 set_callbacks( Activate, Deactivate );
119 /*****************************************************************************
120 * Activate: initialize TS structures
121 *****************************************************************************/
122 static int Activate( vlc_object_t * p_this )
124 input_thread_t * p_input = (input_thread_t *)p_this;
125 demux_sys_t * p_demux;
126 es_descriptor_t * p_pat_es;
127 es_ts_data_t * p_demux_data;
128 stream_ts_data_t * p_stream_data;
131 /* Set the demux function */
132 p_input->pf_demux = Demux;
134 /* Initialize access plug-in structures. */
135 if( p_input->i_mtu == 0 )
138 p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
141 /* Have a peep at the show. */
142 if( input_Peek( p_input, &p_peek, 1 ) < 1 )
144 msg_Err( p_input, "cannot peek()" );
148 if( *p_peek != TS_SYNC_CODE )
150 if( *p_input->psz_demux && ( !strncmp( p_input->psz_demux, "ts", 3 )
151 || !strncmp( p_input->psz_demux, "ts_dvbpsi", 10 ) ) )
154 msg_Err( p_input, "this does not look like a TS stream, continuing" );
158 msg_Warn( p_input, "TS module discarded (no sync)" );
163 /* Adapt the bufsize for our only use. */
164 if( p_input->i_mtu != 0 )
166 /* Have minimum granularity to avoid bottlenecks at the input level. */
167 p_input->i_bufsize = (p_input->i_mtu / TS_PACKET_SIZE) * TS_PACKET_SIZE;
170 p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );
171 if( p_demux == NULL )
176 p_input->p_private = (void*)&p_demux->mpeg;
177 p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );
178 if( p_demux->p_module == NULL )
180 free( p_input->p_demux_data );
184 vlc_mutex_lock( &p_input->stream.stream_lock );
186 if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
188 module_Unneed( p_input, p_demux->p_module );
189 free( p_input->p_demux_data );
193 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
194 p_stream_data->i_pat_version = PAT_UNINITIALIZED ;
196 #ifdef MODULE_NAME_IS_ts_dvbpsi
197 p_stream_data->p_pat_handle = (dvbpsi_handle *)
198 dvbpsi_AttachPAT( (dvbpsi_pat_callback) &TS_DVBPSI_HandlePAT, p_input );
200 if( p_stream_data->p_pat_handle == NULL )
202 msg_Err( p_input, "could not create PAT decoder" );
203 module_Unneed( p_input, p_demux->p_module );
204 free( p_input->p_demux_data );
209 /* We'll have to catch the PAT in order to continue
210 * Then the input will catch the PMT and then the others ES
211 * The PAT es is indepedent of any program. */
212 p_pat_es = input_AddES( p_input, NULL,
213 0x00, sizeof( es_ts_data_t ) );
214 p_demux_data = (es_ts_data_t *)p_pat_es->p_demux_data;
215 p_demux_data->b_psi = 1;
216 p_demux_data->i_psi_type = PSI_IS_PAT;
217 p_demux_data->p_psi_section = malloc(sizeof(psi_section_t));
218 p_demux_data->p_psi_section->b_is_complete = 1;
220 vlc_mutex_unlock( &p_input->stream.stream_lock );
225 /*****************************************************************************
226 * Deactivate: deinitialize TS structures
227 *****************************************************************************/
228 static void Deactivate( vlc_object_t * p_this )
230 input_thread_t * p_input = (input_thread_t *)p_this;
232 module_Unneed( p_input, p_input->p_demux_data->p_module );
233 free( p_input->p_demux_data );
236 /*****************************************************************************
237 * Demux: reads and demuxes data packets
238 *****************************************************************************
239 * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
241 *****************************************************************************/
242 static int Demux( input_thread_t * p_input )
244 demux_sys_t * p_demux = p_input->p_demux_data;
245 int i_read_once = (p_input->i_mtu ?
246 p_input->i_bufsize / TS_PACKET_SIZE :
250 for( i = 0; i < i_read_once; i++ )
252 data_packet_t * p_data;
255 i_result = p_demux->mpeg.pf_read_ts( p_input, &p_data );
262 p_demux->mpeg.pf_demux_ts( p_input, p_data,
263 (psi_callback_t) &PSI_CALLBACK );
270 #if defined MODULE_NAME_IS_ts
272 * PSI demultiplexing and decoding without libdvbpsi
275 /*****************************************************************************
276 * DemuxPSI : makes up complete PSI data
277 *****************************************************************************/
278 static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data,
279 es_descriptor_t * p_es, vlc_bool_t b_unit_start )
281 es_ts_data_t * p_demux_data;
283 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
285 #define p_psi (p_demux_data->p_psi_section)
286 #define p (p_data->p_payload_start)
290 /* unit_start set to 1 -> presence of a pointer field
291 * (see ISO/IEC 13818 (2.4.4.2) which should be set to 0x00 */
292 if( (u8)p[0] != 0x00 )
295 "non-zero pointer field found, trying to continue" );
303 /* This is the begining of a new section */
305 if( ((u8)(p[1]) & 0xc0) != 0x80 )
307 msg_Warn( p_input, "invalid PSI packet" );
312 p_psi->i_section_length = ((p[1] & 0xF) << 8) | p[2];
313 p_psi->b_section_complete = 0;
314 p_psi->i_read_in_section = 0;
315 p_psi->i_section_number = (u8)p[6];
317 if( p_psi->b_is_complete || p_psi->i_section_number == 0 )
319 /* This is a new PSI packet */
320 p_psi->b_is_complete = 0;
322 p_psi->i_version_number = ( p[5] >> 1 ) & 0x1f;
323 p_psi->i_last_section_number = (u8)p[7];
325 /* We'll write at the begining of the buffer */
326 p_psi->p_current = p_psi->buffer;
330 if( p_psi->b_section_complete )
332 /* New Section of an already started PSI */
333 p_psi->b_section_complete = 0;
335 if( p_psi->i_version_number != (( p[5] >> 1 ) & 0x1f) )
338 "PSI version differs inside same PAT" );
341 if( p_psi->i_section_number + 1 != (u8)p[6] )
344 "PSI Section discontinuity, packet lost?" );
348 p_psi->i_section_number++;
352 msg_Warn( p_input, "got unexpected new PSI section" );
359 if( !p_psi->b_trash )
362 if( (p_data->p_payload_end - p) >=
363 ( p_psi->i_section_length - p_psi->i_read_in_section ) )
365 /* The end of the section is in this TS packet */
366 memcpy( p_psi->p_current, p,
367 (p_psi->i_section_length - p_psi->i_read_in_section) );
369 p_psi->b_section_complete = 1;
371 (p_psi->i_section_length - p_psi->i_read_in_section);
373 if( p_psi->i_section_number == p_psi->i_last_section_number )
375 /* This was the last section of PSI */
376 p_psi->b_is_complete = 1;
378 switch( p_demux_data->i_psi_type)
381 TSDecodePAT( p_input, p_es );
384 TSDecodePMT( p_input, p_es );
387 msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
393 memcpy( p_psi->buffer, p, p_data->p_payload_end - p );
394 p_psi->i_read_in_section += p_data->p_payload_end - p;
396 p_psi->p_current += p_data->p_payload_end - p;
403 input_DeletePacket( p_input->p_method_data, p_data );
408 /*****************************************************************************
409 * DecodePAT : Decodes Programm association table and deal with it
410 *****************************************************************************/
411 static void TSDecodePAT( input_thread_t * p_input, es_descriptor_t * p_es )
413 stream_ts_data_t * p_stream_data;
414 es_ts_data_t * p_demux_data;
416 pgrm_descriptor_t * p_pgrm;
417 es_descriptor_t * p_current_es;
418 byte_t * p_current_data;
420 int i_section_length, i_program_id, i_pmt_pid;
421 int i_loop, i_current_section;
423 vlc_bool_t b_changed = 0;
425 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
426 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
428 #define p_psi (p_demux_data->p_psi_section)
430 /* Not so fast, Mike ! If the PAT version has changed, we first check
431 * that its content has really changed before doing anything */
432 if( p_stream_data->i_pat_version != p_psi->i_version_number )
434 int i_programs = p_input->stream.i_pgrm_number;
436 p_current_data = p_psi->buffer;
440 i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
442 i_current_section = (u8)p_current_data[6];
445 ( i_loop < (i_section_length - 9) / 4 ) && !b_changed;
448 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
449 | *(p_current_data + i_loop * 4 + 9);
450 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
452 | *(p_current_data + i_loop * 4 + 11);
456 if( (p_pgrm = input_FindProgram( p_input, i_program_id ))
457 && (p_current_es = input_FindES( p_input, i_pmt_pid ))
458 && p_current_es->p_pgrm == p_pgrm
459 && p_current_es->i_id == i_pmt_pid
460 && ((es_ts_data_t *)p_current_es->p_demux_data)->b_psi
461 && ((es_ts_data_t *)p_current_es->p_demux_data)
462 ->i_psi_type == PSI_IS_PMT )
473 p_current_data += 3 + i_section_length;
475 } while( ( i_current_section < p_psi->i_last_section_number )
478 /* If we didn't find the expected amount of programs, the PAT has
479 * changed. Otherwise, it only changed if b_changed is already != 0 */
480 b_changed = b_changed || i_programs;
485 /* PAT has changed. We are going to delete all programs and
486 * create new ones. We chose not to only change what was needed
487 * as a PAT change may mean the stream is radically changing and
488 * this is a secure method to avoid crashes */
489 es_ts_data_t * p_es_demux;
490 pgrm_ts_data_t * p_pgrm_demux;
492 p_current_data = p_psi->buffer;
494 /* Delete all programs */
495 while( p_input->stream.i_pgrm_number )
497 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
502 i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
504 i_current_section = (u8)p_current_data[6];
506 for( i_loop = 0; i_loop < (i_section_length - 9) / 4 ; i_loop++ )
508 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
509 | *(p_current_data + i_loop * 4 + 9);
510 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
512 | *(p_current_data + i_loop * 4 + 11);
514 /* If program = 0, we're having info about NIT not PMT */
517 /* Add this program */
518 p_pgrm = input_AddProgram( p_input, i_program_id,
519 sizeof( pgrm_ts_data_t ) );
521 /* whatis the PID of the PMT of this program */
522 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
523 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
525 /* Add the PMT ES to this program */
526 p_current_es = input_AddES( p_input, p_pgrm,(u16)i_pmt_pid,
527 sizeof( es_ts_data_t) );
528 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
529 p_es_demux->b_psi = 1;
530 p_es_demux->i_psi_type = PSI_IS_PMT;
532 p_es_demux->p_psi_section =
533 malloc( sizeof( psi_section_t ) );
534 p_es_demux->p_psi_section->b_is_complete = 0;
538 p_current_data += 3 + i_section_length;
540 } while( i_current_section < p_psi->i_last_section_number );
542 /* Go to the beginning of the next section */
543 p_stream_data->i_pat_version = p_psi->i_version_number;
550 /*****************************************************************************
551 * DecodePMT : decode a given Program Stream Map
552 * ***************************************************************************
553 * When the PMT changes, it may mean a deep change in the stream, and it is
554 * careful to delete the ES and add them again. If the PMT doesn't change,
555 * there no need to do anything.
556 *****************************************************************************/
557 static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es )
560 pgrm_ts_data_t * p_pgrm_data;
561 es_ts_data_t * p_demux_data;
562 vlc_bool_t b_vls_compat = config_GetInt( p_input, "vls-backwards-compat" );
564 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
565 p_pgrm_data = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;
567 #define p_psi (p_demux_data->p_psi_section)
569 if( p_psi->i_version_number != p_pgrm_data->i_pmt_version )
571 es_descriptor_t * p_new_es;
572 es_ts_data_t * p_es_demux;
573 byte_t * p_current_data, * p_current_section;
574 int i_section_length,i_current_section;
575 int i_prog_info_length, i_loop;
576 int i_es_info_length, i_pid, i_stream_type;
578 p_current_section = p_psi->buffer;
579 p_current_data = p_psi->buffer;
581 p_pgrm_data->i_pcr_pid = ( ((u32)*(p_current_section + 8) & 0x1F) << 8 ) |
582 *(p_current_section + 9);
585 /* Lock stream information */
586 vlc_mutex_lock( &p_input->stream.stream_lock );
588 /* Delete all ES in this program except the PSI. We start from the
589 * end because i_es_number gets decremented after each deletion. */
590 for( i_loop = p_es->p_pgrm->i_es_number ; i_loop ; )
593 p_es_demux = (es_ts_data_t *)
594 p_es->p_pgrm->pp_es[i_loop]->p_demux_data;
595 if ( ! p_es_demux->b_psi )
597 input_DelES( p_input, p_es->p_pgrm->pp_es[i_loop] );
601 /* Then add what we received in this PMT */
604 i_section_length = ( ((u32)*(p_current_data + 1) & 0xF) << 8 ) |
605 *(p_current_data + 2);
606 i_current_section = (u8)p_current_data[6];
607 i_prog_info_length = ( ((u32)*(p_current_data + 10) & 0xF) << 8 ) |
608 *(p_current_data + 11);
610 /* For the moment we ignore program descriptors */
611 p_current_data += 12 + i_prog_info_length;
613 /* The end of the section, before the CRC is at
614 * p_current_section + i_section_length -1 */
615 while( p_current_data < p_current_section + i_section_length -1 )
617 i_stream_type = (int)p_current_data[0];
618 i_pid = ( ((u32)*(p_current_data + 1) & 0x1F) << 8 ) |
619 *(p_current_data + 2);
620 i_es_info_length = ( ((u32)*(p_current_data + 3) & 0xF) << 8 ) |
621 *(p_current_data + 4);
623 /* Add this ES to the program */
624 p_new_es = input_AddES( p_input, p_es->p_pgrm,
625 (u16)i_pid, sizeof( es_ts_data_t ) );
627 /* Tell the interface what kind of stream it is and select
628 * the required ones */
630 switch( i_stream_type )
634 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','v');
635 p_new_es->i_cat = VIDEO_ES;
639 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','a');
640 p_new_es->i_cat = AUDIO_ES;
643 case A52DVB_AUDIO_ES:
645 p_new_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
647 p_new_es->i_fourcc = VLC_FOURCC('a','5','2','b');
648 p_new_es->i_stream_id = 0xBD;
649 p_new_es->i_cat = AUDIO_ES;
652 p_new_es->i_fourcc = VLC_FOURCC('l','p','c','m');
653 p_new_es->i_stream_id = 0xBD;
654 p_new_es->i_cat = AUDIO_ES;
658 p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
660 p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
661 p_new_es->i_stream_id = 0xBD;
662 p_new_es->i_cat = SPU_ES;
665 p_new_es->i_fourcc = VLC_FOURCC('s','d','d','s');
666 p_new_es->i_stream_id = 0xBD;
667 p_new_es->i_cat = AUDIO_ES;
670 p_new_es->i_fourcc = VLC_FOURCC('d','t','s',' ');
671 p_new_es->i_stream_id = 0xBD;
672 p_new_es->i_cat = AUDIO_ES;
674 /* 'b' stands for 'buggy' */
676 p_new_es->i_fourcc = VLC_FOURCC('a','5','2','b');
677 p_new_es->i_stream_id = 0xBD;
678 p_new_es->i_cat = AUDIO_ES;
681 p_new_es->i_fourcc = VLC_FOURCC('l','p','c','b');
682 p_new_es->i_stream_id = 0xBD;
683 p_new_es->i_cat = AUDIO_ES;
686 p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
687 p_new_es->i_stream_id = 0xBD;
688 p_new_es->i_cat = SPU_ES;
692 p_new_es->i_fourcc = 0;
693 p_new_es->i_cat = UNKNOWN_ES;
698 p_current_data += 5 + i_es_info_length;
701 /* Go to the beginning of the next section*/
702 p_current_data += 3 + i_section_length;
706 } while( i_current_section < p_psi->i_last_section_number );
708 p_pgrm_data->i_pmt_version = p_psi->i_version_number;
710 /* if no program is selected :*/
711 if( !p_input->stream.p_selected_program )
713 pgrm_descriptor_t * p_pgrm_to_select;
714 u16 i_id = (u16)config_GetInt( p_input, "program" );
716 if( i_id != 0 ) /* if user specified a program */
718 p_pgrm_to_select = input_FindProgram( p_input, i_id );
720 if( p_pgrm_to_select && p_pgrm_to_select == p_es->p_pgrm )
721 p_input->pf_set_program( p_input, p_pgrm_to_select );
724 p_input->pf_set_program( p_input, p_es->p_pgrm );
727 /* inform interface that stream has changed */
728 p_input->stream.b_changed = 1;
730 vlc_mutex_unlock( &p_input->stream.stream_lock );
736 #elif defined MODULE_NAME_IS_ts_dvbpsi
738 * PSI Decoding using libdvbpsi
741 /*****************************************************************************
742 * DemuxPSI : send the PSI to the right libdvbpsi decoder
743 *****************************************************************************/
744 static void TS_DVBPSI_DemuxPSI( input_thread_t * p_input,
745 data_packet_t * p_data,
746 es_descriptor_t * p_es,
747 vlc_bool_t b_unit_start )
749 es_ts_data_t * p_es_demux_data;
750 pgrm_ts_data_t * p_pgrm_demux_data;
751 stream_ts_data_t * p_stream_demux_data;
753 p_es_demux_data = ( es_ts_data_t * ) p_es->p_demux_data;
754 p_stream_demux_data = ( stream_ts_data_t * ) p_input->stream.p_demux_data;
756 switch( p_es_demux_data->i_psi_type)
760 ( dvbpsi_handle ) p_stream_demux_data->p_pat_handle,
761 p_data->p_demux_start );
764 p_pgrm_demux_data = ( pgrm_ts_data_t * )p_es->p_pgrm->p_demux_data;
766 ( dvbpsi_handle ) p_pgrm_demux_data->p_pmt_handle,
767 p_data->p_demux_start );
770 msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
773 input_DeletePacket( p_input->p_method_data, p_data );
775 /*****************************************************************************
776 * MP4 specific functions
777 *****************************************************************************/
778 static int MP4_DescriptorLength( int *pi_data, uint8_t **pp_data )
781 unsigned int i_len = 0;
787 i_len = ( i_len << 7 ) + ( i_b&0x7f );
793 static int MP4_GetByte( int *pi_data, uint8_t **pp_data )
808 static int MP4_GetWord( int *pi_data, uint8_t **pp_data )
811 i1 = MP4_GetByte( pi_data, pp_data );
812 i2 = MP4_GetByte( pi_data, pp_data );
813 return( ( i1 << 8 ) | i2 );
815 static int MP4_Get3Bytes( int *pi_data, uint8_t **pp_data )
818 i1 = MP4_GetByte( pi_data, pp_data );
819 i2 = MP4_GetByte( pi_data, pp_data );
820 i3 = MP4_GetByte( pi_data, pp_data );
821 return( ( i1 << 16 ) | ( i2 << 8) | i3 );
824 static uint32_t MP4_GetDWord( int *pi_data, uint8_t **pp_data )
827 i1 = MP4_GetWord( pi_data, pp_data );
828 i2 = MP4_GetWord( pi_data, pp_data );
829 return( ( i1 << 16 ) | i2 );
832 static char* MP4_GetURL( int *pi_data, uint8_t **pp_data )
837 i_url_len = MP4_GetByte( pi_data, pp_data );
838 url = malloc( i_url_len + 1 );
839 for( i = 0; i < i_url_len; i++ )
841 url[i] = MP4_GetByte( pi_data, pp_data );
843 url[i_url_len] = '\0';
847 static void MP4_IODParse( iod_descriptor_t *p_iod, int i_data, uint8_t *p_data )
855 fprintf( stderr, "\n************ IOD ************" );
856 for( i = 0; i < 255; i++ )
858 p_iod->es_descr[i].b_ok = 0;
867 p_iod->i_iod_label = MP4_GetByte( &i_data, &p_data );
868 fprintf( stderr, "\n* iod_label:%d", p_iod->i_iod_label );
869 fprintf( stderr, "\n* ===========" );
870 fprintf( stderr, "\n* tag:0x%x", p_data[0] );
872 if( MP4_GetByte( &i_data, &p_data ) != 0x02 )
874 fprintf( stderr, "\n ERR: tag != 0x02" );
878 i_iod_length = MP4_DescriptorLength( &i_data, &p_data );
879 fprintf( stderr, "\n* length:%d", i_iod_length );
880 if( i_iod_length > i_data )
882 i_iod_length = i_data;
885 p_iod->i_od_id = ( MP4_GetByte( &i_data, &p_data ) << 2 );
886 i_flags = MP4_GetByte( &i_data, &p_data );
887 p_iod->i_od_id |= i_flags >> 6;
888 b_url = ( i_flags >> 5 )&0x01;
890 fprintf( stderr, "\n* od_id:%d", p_iod->i_od_id );
891 fprintf( stderr, "\n* url flag:%d", b_url );
892 fprintf( stderr, "\n* includeInlineProfileLevel flag:%d", ( i_flags >> 4 )&0x01 );
896 p_iod->psz_url = MP4_GetURL( &i_data, &p_data );
897 fprintf( stderr, "\n* url string:%s", p_iod->psz_url );
898 fprintf( stderr, "\n*****************************\n" );
903 p_iod->psz_url = NULL;
906 p_iod->i_ODProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
907 p_iod->i_sceneProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
908 p_iod->i_audioProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
909 p_iod->i_visualProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
910 p_iod->i_graphicsProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
912 fprintf( stderr, "\n* ODProfileLevelIndication:%d", p_iod->i_ODProfileLevelIndication );
913 fprintf( stderr, "\n* sceneProfileLevelIndication:%d", p_iod->i_sceneProfileLevelIndication );
914 fprintf( stderr, "\n* audioProfileLevelIndication:%d", p_iod->i_audioProfileLevelIndication );
915 fprintf( stderr, "\n* visualProfileLevelIndication:%d", p_iod->i_visualProfileLevelIndication );
916 fprintf( stderr, "\n* graphicsProfileLevelIndication:%d", p_iod->i_graphicsProfileLevelIndication );
919 while( i_data > 0 && i_es_index < 255)
925 i_tag = MP4_GetByte( &i_data, &p_data );
926 i_length = MP4_DescriptorLength( &i_data, &p_data );
937 #define es_descr p_iod->es_descr[i_es_index]
938 int i_decoderConfigDescr_length;
939 fprintf( stderr, "\n* - ES_Descriptor length:%d", i_length );
942 es_descr.i_es_id = MP4_GetWord( &i_data, &p_data );
943 i_flags = MP4_GetByte( &i_data, &p_data );
944 es_descr.b_streamDependenceFlag = ( i_flags >> 7 )&0x01;
945 b_url = ( i_flags >> 6 )&0x01;
946 es_descr.b_OCRStreamFlag = ( i_flags >> 5 )&0x01;
947 es_descr.i_streamPriority = i_flags & 0x1f;
948 fprintf( stderr, "\n* * streamDependenceFlag:%d", es_descr.b_streamDependenceFlag );
949 fprintf( stderr, "\n* * OCRStreamFlag:%d", es_descr.b_OCRStreamFlag );
950 fprintf( stderr, "\n* * streamPriority:%d", es_descr.i_streamPriority );
952 if( es_descr.b_streamDependenceFlag )
954 es_descr.i_dependOn_es_id = MP4_GetWord( &i_data, &p_data );
955 fprintf( stderr, "\n* * dependOn_es_id:%d", es_descr.i_dependOn_es_id );
960 es_descr.psz_url = MP4_GetURL( &i_data, &p_data );
961 fprintf( stderr, "\n* url string:%s", es_descr.psz_url );
965 es_descr.psz_url = NULL;
968 if( es_descr.b_OCRStreamFlag )
970 es_descr.i_OCR_es_id = MP4_GetWord( &i_data, &p_data );
971 fprintf( stderr, "\n* * OCR_es_id:%d", es_descr.i_OCR_es_id );
974 if( MP4_GetByte( &i_data, &p_data ) != 0x04 )
976 fprintf( stderr, "\n* ERR missing DecoderConfigDescr" );
980 i_decoderConfigDescr_length = MP4_DescriptorLength( &i_data, &p_data );
982 fprintf( stderr, "\n* - DecoderConfigDesc length:%d", i_decoderConfigDescr_length );
983 #define dec_descr es_descr.dec_descr
984 dec_descr.i_objectTypeIndication = MP4_GetByte( &i_data, &p_data );
985 i_flags = MP4_GetByte( &i_data, &p_data );
986 dec_descr.i_streamType = i_flags >> 2;
987 dec_descr.b_upStream = ( i_flags >> 1 )&0x01;
988 dec_descr.i_bufferSizeDB = MP4_Get3Bytes( &i_data, &p_data );
989 dec_descr.i_maxBitrate = MP4_GetDWord( &i_data, &p_data );
990 dec_descr.i_avgBitrate = MP4_GetDWord( &i_data, &p_data );
991 fprintf( stderr, "\n* * objectTypeIndication:0x%x", dec_descr.i_objectTypeIndication );
992 fprintf( stderr, "\n* * streamType:0x%x", dec_descr.i_streamType );
993 fprintf( stderr, "\n* * upStream:%d", dec_descr.b_upStream );
994 fprintf( stderr, "\n* * bufferSizeDB:%d", dec_descr.i_bufferSizeDB );
995 fprintf( stderr, "\n* * maxBitrate:%d", dec_descr.i_maxBitrate );
996 fprintf( stderr, "\n* * avgBitrate:%d", dec_descr.i_avgBitrate );
997 if( i_decoderConfigDescr_length > 13 && MP4_GetByte( &i_data, &p_data ) == 0x05 )
1000 dec_descr.i_decoder_specific_info_len =
1001 MP4_DescriptorLength( &i_data, &p_data );
1002 if( dec_descr.i_decoder_specific_info_len > 0 )
1004 dec_descr.p_decoder_specific_info =
1005 malloc( dec_descr.i_decoder_specific_info_len );
1007 for( i = 0; i < dec_descr.i_decoder_specific_info_len; i++ )
1009 dec_descr.p_decoder_specific_info[i] = MP4_GetByte( &i_data, &p_data );
1014 dec_descr.i_decoder_specific_info_len = 0;
1015 dec_descr.p_decoder_specific_info = NULL;
1019 #define sl_descr es_descr.sl_descr
1021 int i_SLConfigDescr_length;
1024 if( MP4_GetByte( &i_data, &p_data ) != 0x06 )
1026 fprintf( stderr, "\n* ERR missing SLConfigDescr" );
1030 i_SLConfigDescr_length = MP4_DescriptorLength( &i_data, &p_data );
1032 fprintf( stderr, "\n* - SLConfigDescr length:%d", i_SLConfigDescr_length );
1033 i_predefined = MP4_GetByte( &i_data, &p_data );
1034 fprintf( stderr, "\n* * i_predefined:0x%x", i_predefined );
1035 switch( i_predefined )
1039 sl_descr.b_useAccessUnitStartFlag = 0;
1040 sl_descr.b_useAccessUnitEndFlag = 0;
1041 sl_descr.b_useRandomAccessPointFlag = 0;
1042 //sl_descr.b_useRandomAccessUnitsOnlyFlag = 0;
1043 sl_descr.b_usePaddingFlag = 0;
1044 sl_descr.b_useTimeStampsFlags = 0;
1045 sl_descr.b_useIdleFlag = 0;
1046 sl_descr.b_durationFlag = 0; // FIXME FIXME
1047 sl_descr.i_timeStampResolution = 1000;
1048 sl_descr.i_OCRResolution = 0; // FIXME FIXME
1049 sl_descr.i_timeStampLength = 32;
1050 sl_descr.i_OCRLength = 0; // FIXME FIXME
1051 sl_descr.i_AU_Length = 0;
1052 sl_descr.i_instantBitrateLength= 0; // FIXME FIXME
1053 sl_descr.i_degradationPriorityLength= 0;
1054 sl_descr.i_AU_seqNumLength = 0;
1055 sl_descr.i_packetSeqNumLength = 0;
1056 if( sl_descr.b_durationFlag )
1058 sl_descr.i_timeScale = 0; // FIXME FIXME
1059 sl_descr.i_accessUnitDuration = 0; // FIXME FIXME
1060 sl_descr.i_compositionUnitDuration= 0; // FIXME FIXME
1062 if( !sl_descr.b_useTimeStampsFlags )
1064 sl_descr.i_startDecodingTimeStamp = 0; // FIXME FIXME
1065 sl_descr.i_startCompositionTimeStamp= 0; // FIXME FIXME
1070 fprintf( stderr, "\n* ERR unsupported SLConfigDescr predefined" );
1079 fprintf( stderr, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag, i_length );
1083 p_data = p_data_sav + i_length;
1084 i_data = i_data_sav - i_length;
1089 fprintf( stderr, "\n*****************************\n" );
1092 static void MP4_IODClean( iod_descriptor_t *p_iod )
1096 if( p_iod->psz_url )
1098 free( p_iod->psz_url );
1099 p_iod->psz_url = NULL;
1103 for( i = 0; i < 255; i++ )
1105 #define es_descr p_iod->es_descr[i]
1108 if( es_descr.psz_url )
1110 free( es_descr.psz_url );
1111 es_descr.psz_url = NULL;
1115 if( es_descr.dec_descr.p_decoder_specific_info != NULL )
1117 free( es_descr.dec_descr.p_decoder_specific_info );
1118 es_descr.dec_descr.p_decoder_specific_info = NULL;
1119 es_descr.dec_descr.i_decoder_specific_info_len = 0;
1128 /*****************************************************************************
1129 * HandlePAT: will treat a PAT returned by dvbpsi
1130 *****************************************************************************/
1131 static void TS_DVBPSI_HandlePAT( input_thread_t * p_input,
1132 dvbpsi_pat_t * p_new_pat )
1134 dvbpsi_pat_program_t * p_pgrm;
1135 pgrm_descriptor_t * p_new_pgrm;
1136 pgrm_ts_data_t * p_pgrm_demux;
1137 es_descriptor_t * p_current_es;
1138 es_ts_data_t * p_es_demux;
1139 stream_ts_data_t * p_stream_data;
1141 vlc_mutex_lock( &p_input->stream.stream_lock );
1143 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
1145 if ( !p_new_pat->b_current_next ||
1146 p_stream_data->i_pat_version == PAT_UNINITIALIZED )
1148 /* Delete all programs */
1149 while( p_input->stream.i_pgrm_number )
1151 pgrm_ts_data_t *p_pgrm_demux_old =
1152 (pgrm_ts_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
1154 if( p_pgrm_demux_old->b_mpeg4 )
1156 MP4_IODClean( &p_pgrm_demux_old->iod );
1159 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
1162 /* treat the new programs list */
1163 p_pgrm = p_new_pat->p_first_program;
1167 /* If program = 0, we're having info about NIT not PMT */
1168 if( p_pgrm->i_number )
1170 /* Add this program */
1171 p_new_pgrm = input_AddProgram( p_input, p_pgrm->i_number,
1172 sizeof( pgrm_ts_data_t ) );
1174 p_pgrm_demux = (pgrm_ts_data_t *)p_new_pgrm->p_demux_data;
1175 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
1177 /* Add the PMT ES to this program */
1178 p_current_es = input_AddES( p_input, p_new_pgrm,
1179 (u16) p_pgrm->i_pid,
1180 sizeof( es_ts_data_t) );
1181 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
1182 p_es_demux->b_psi = 1;
1183 p_es_demux->i_psi_type = PSI_IS_PMT;
1185 p_es_demux->p_psi_section = malloc( sizeof( psi_section_t ) );
1186 if ( p_es_demux->p_psi_section == NULL )
1188 msg_Err( p_input, "out of memory" );
1189 p_input->b_error = 1;
1193 p_es_demux->p_psi_section->b_is_complete = 0;
1195 /* Create a PMT decoder */
1196 p_pgrm_demux->p_pmt_handle = (dvbpsi_handle *)
1197 dvbpsi_AttachPMT( p_pgrm->i_number,
1198 (dvbpsi_pmt_callback) &TS_DVBPSI_HandlePMT,
1201 if( p_pgrm_demux->p_pmt_handle == NULL )
1203 msg_Err( p_input, "could not create PMT decoder" );
1204 p_input->b_error = 1;
1209 p_pgrm = p_pgrm->p_next;
1212 p_stream_data->i_pat_version = p_new_pat->i_version;
1214 vlc_mutex_unlock( &p_input->stream.stream_lock );
1218 /*****************************************************************************
1219 * HandlePMT: will treat a PMT returned by dvbpsi
1220 *****************************************************************************/
1221 static void TS_DVBPSI_HandlePMT( input_thread_t * p_input,
1222 dvbpsi_pmt_t * p_new_pmt )
1224 dvbpsi_pmt_es_t * p_es;
1225 pgrm_descriptor_t * p_pgrm;
1226 es_descriptor_t * p_new_es;
1227 pgrm_ts_data_t * p_pgrm_demux;
1228 vlc_bool_t b_vls_compat = config_GetInt( p_input, "vls-backwards-compat" );
1230 vlc_mutex_lock( &p_input->stream.stream_lock );
1232 p_pgrm = input_FindProgram( p_input, p_new_pmt->i_program_number );
1234 if( p_pgrm == NULL )
1236 msg_Warn( p_input, "PMT of unreferenced program found" );
1240 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
1241 p_pgrm_demux->i_pcr_pid = p_new_pmt->i_pcr_pid;
1243 if( !p_new_pmt->b_current_next ||
1244 p_pgrm_demux->i_pmt_version == PMT_UNINITIALIZED )
1246 dvbpsi_descriptor_t *p_dr = p_new_pmt->p_first_descriptor;
1248 while( p_dr && ( p_dr->i_tag != 0x1d ) )
1249 p_dr = p_dr->p_next;
1252 msg_Warn( p_input, "found IOD descriptor" );
1253 MP4_IODParse( &p_pgrm_demux->iod, p_dr->i_length, p_dr->p_data );
1256 p_es = p_new_pmt->p_first_es;
1260 p_new_es = input_AddES( p_input, p_pgrm,
1261 (u16)p_es->i_pid, sizeof( es_ts_data_t ) );
1262 if( p_new_es == NULL )
1264 msg_Err( p_input, "could not add ES %d", p_es->i_pid );
1265 p_input->b_error = 1;
1268 switch( p_es->i_type )
1270 case MPEG1_VIDEO_ES:
1271 case MPEG2_VIDEO_ES:
1272 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','v');
1273 p_new_es->i_cat = VIDEO_ES;
1275 case MPEG1_AUDIO_ES:
1276 case MPEG2_AUDIO_ES:
1277 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','a');
1278 p_new_es->i_cat = AUDIO_ES;
1281 case A52DVB_AUDIO_ES:
1282 if ( !b_vls_compat )
1283 p_new_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
1285 p_new_es->i_fourcc = VLC_FOURCC('a','5','2','b');
1286 p_new_es->i_cat = AUDIO_ES;
1287 p_new_es->i_stream_id = 0xBD;
1290 if ( !b_vls_compat )
1291 p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
1293 p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
1294 p_new_es->i_cat = SPU_ES;
1295 p_new_es->i_stream_id = 0xBD;
1298 p_new_es->i_fourcc = VLC_FOURCC('l','p','c','m');
1299 p_new_es->i_cat = AUDIO_ES;
1300 p_new_es->i_stream_id = 0xBD;
1303 p_new_es->i_fourcc = VLC_FOURCC('s','d','d','s');
1304 p_new_es->i_stream_id = 0xBD;
1305 p_new_es->i_cat = AUDIO_ES;
1308 p_new_es->i_fourcc = VLC_FOURCC('d','t','s',' ');
1309 p_new_es->i_stream_id = 0xBD;
1310 p_new_es->i_cat = AUDIO_ES;
1313 p_new_es->i_fourcc = VLC_FOURCC('a','5','2','b');
1314 p_new_es->i_cat = AUDIO_ES;
1315 p_new_es->i_stream_id = 0xBD;
1318 p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
1319 p_new_es->i_cat = SPU_ES;
1320 p_new_es->i_stream_id = 0xBD;
1322 case LPCMB_AUDIO_ES:
1323 p_new_es->i_fourcc = VLC_FOURCC('l','p','c','b');
1324 p_new_es->i_cat = AUDIO_ES;
1325 p_new_es->i_stream_id = 0xBD;
1327 case MPEG4_VIDEO_ES:
1328 p_new_es->i_fourcc = VLC_FOURCC('m','p','4','v');
1329 p_new_es->i_cat = VIDEO_ES;
1330 p_new_es->i_stream_id = 0xfa;
1332 case MPEG4_AUDIO_ES:
1333 p_new_es->i_fourcc = VLC_FOURCC('m','p','4','a');
1334 p_new_es->i_cat = AUDIO_ES;
1335 p_new_es->i_stream_id = 0xfa;
1339 p_new_es->i_fourcc = 0;
1340 p_new_es->i_cat = UNKNOWN_ES;
1343 if( p_es->i_type == MPEG4_VIDEO_ES || p_es->i_type == MPEG4_AUDIO_ES )
1345 /* mpeg4 stream, search sl_descriptor */
1346 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1347 es_ts_data_t *p_es_demux =
1348 (es_ts_data_t*)p_new_es->p_demux_data;
1350 while( p_dr && ( p_dr->i_tag != 0x1f ) )
1351 p_dr = p_dr->p_next;
1352 if( p_dr && p_dr->i_length == 2 )
1354 int i_es_descr_index;
1356 p_es_demux->i_es_id =
1357 ( p_dr->p_data[0] << 8 ) | p_dr->p_data[1];
1358 p_es_demux->p_es_descr = NULL;
1360 msg_Warn( p_input, "found SL_descriptor" );
1361 for( i_es_descr_index = 0; i_es_descr_index < 255; i_es_descr_index++ )
1363 if( p_pgrm_demux->iod.es_descr[i_es_descr_index].b_ok &&
1364 p_pgrm_demux->iod.es_descr[i_es_descr_index].i_es_id == p_es_demux->i_es_id )
1366 p_es_demux->p_es_descr = &p_pgrm_demux->iod.es_descr[i_es_descr_index];
1371 if( p_es_demux->p_es_descr != NULL )
1373 vlc_fourcc_t i_fourcc;
1375 p_es_demux->b_mpeg4 = 1;
1378 switch( p_es_demux->p_es_descr->dec_descr.i_streamType )
1380 case 0x04: /* VisualStream */
1382 switch( p_es_demux->p_es_descr->dec_descr.i_objectTypeIndication )
1385 i_fourcc = VLC_FOURCC('m','p','4','v'); // mpeg4
1393 i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg2
1396 i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg1
1399 i_fourcc = VLC_FOURCC( 'j','p','e','g' ); // mpeg1
1406 case 0x05: /* AudioStream */
1408 switch( p_es_demux->p_es_descr->dec_descr.i_objectTypeIndication )
1411 i_fourcc = VLC_FOURCC('m','p','4','a'); // mpeg4
1416 i_fourcc = VLC_FOURCC('m','p','4','a'); // mpeg2 aac
1419 i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg2
1422 i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg1
1435 p_new_es->i_fourcc = i_fourcc;
1436 p_new_es->i_cat = i_cat;
1442 BITMAPINFOHEADER *p_bih;
1444 i_size = sizeof( BITMAPINFOHEADER ) +
1445 p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len;
1446 p_new_es->p_bitmapinfoheader = (void*)p_bih = malloc( i_size );
1447 p_bih->biSize = i_size;
1449 p_bih->biHeight = 0;
1450 p_bih->biPlanes = 1;
1451 p_bih->biBitCount = 0;
1452 p_bih->biCompression = 0;
1453 p_bih->biSizeImage = 0;
1454 p_bih->biXPelsPerMeter = 0;
1455 p_bih->biYPelsPerMeter = 0;
1456 p_bih->biClrUsed = 0;
1457 p_bih->biClrImportant = 0;
1459 p_es_demux->p_es_descr->dec_descr.p_decoder_specific_info,
1460 p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len );
1468 i_size = sizeof( WAVEFORMATEX ) +
1469 p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len;
1470 p_new_es->p_waveformatex = (void*)p_wf = malloc( i_size );
1471 p_wf->wFormatTag = 0xffff;
1472 p_wf->nChannels = 0;
1473 p_wf->nSamplesPerSec = 0;
1474 p_wf->nAvgBytesPerSec = 0;
1475 p_wf->nBlockAlign = 1;
1476 p_wf->wBitsPerSample = 0;
1477 p_wf->cbSize = p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len;
1479 p_es_demux->p_es_descr->dec_descr.p_decoder_specific_info,
1480 p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len );
1489 msg_Warn( p_input, "mpeg4 stream without (valid) sl_descriptor" );
1490 p_es_demux->b_mpeg4 = 0;
1495 if( ( p_new_es->i_cat == AUDIO_ES )
1496 || (p_new_es->i_cat == SPU_ES ) )
1498 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1499 while( p_dr && ( p_dr->i_tag != 0x0a ) )
1500 p_dr = p_dr->p_next;
1503 dvbpsi_iso639_dr_t *p_decoded =
1504 dvbpsi_DecodeISO639Dr( p_dr );
1505 if( p_decoded->i_code_count > 0 )
1507 const iso639_lang_t * p_iso;
1508 p_iso = GetLang_2T((char*)p_decoded->i_iso_639_code);
1511 if(p_iso->psz_native_name[0])
1512 strcpy( p_new_es->psz_desc,
1513 p_iso->psz_native_name );
1515 strcpy( p_new_es->psz_desc,
1516 p_iso->psz_eng_name );
1520 strncpy( p_new_es->psz_desc,
1521 p_decoded->i_iso_639_code, 3 );
1525 switch( p_es->i_type )
1527 case MPEG1_AUDIO_ES:
1528 case MPEG2_AUDIO_ES:
1529 strcat( p_new_es->psz_desc, " (mpeg)" );
1532 case LPCMB_AUDIO_ES:
1533 strcat( p_new_es->psz_desc, " (lpcm)" );
1536 case A52DVB_AUDIO_ES:
1538 strcat( p_new_es->psz_desc, " (A52)" );
1540 case MPEG4_AUDIO_ES:
1541 strcat( p_new_es->psz_desc, " (aac)" );
1546 p_es = p_es->p_next;
1549 /* if no program is selected :*/
1550 if( !p_input->stream.p_selected_program )
1552 pgrm_descriptor_t * p_pgrm_to_select;
1553 u16 i_id = (u16)config_GetInt( p_input, "program" );
1555 if( i_id != 0 ) /* if user specified a program */
1557 p_pgrm_to_select = input_FindProgram( p_input, i_id );
1559 if( p_pgrm_to_select && p_pgrm_to_select == p_pgrm )
1560 p_input->pf_set_program( p_input, p_pgrm_to_select );
1563 p_input->pf_set_program( p_input, p_pgrm );
1565 /* if the pmt belongs to the currently selected program, we
1566 * reselect it to update its ES */
1567 else if( p_pgrm == p_input->stream.p_selected_program )
1569 p_input->pf_set_program( p_input, p_pgrm );
1572 p_pgrm_demux->i_pmt_version = p_new_pmt->i_version;
1573 p_input->stream.b_changed = 1;
1575 vlc_mutex_unlock( &p_input->stream.stream_lock );