1 /*****************************************************************************
2 * mpeg_ts.c : Transport Stream input module for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2001 VideoLAN
5 * $Id: mpeg_ts.c,v 1.13.2.3 2002/10/12 21:26:26 gbazin 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 *****************************************************************************/
33 # include <stdint.h> /* uint8_t */
36 #include <videolan/vlc.h>
38 #include "stream_control.h"
39 #include "input_ext-intf.h"
40 #include "input_ext-dec.h"
41 #include "input_ext-plugins.h"
45 #if defined MODULE_NAME_IS_mpeg_ts_dvbpsi
46 # ifdef HAVE_DVBPSI_DR_H
47 # include <dvbpsi/dvbpsi.h>
48 # include <dvbpsi/descriptor.h>
49 # include <dvbpsi/pat.h>
50 # include <dvbpsi/pmt.h>
51 # include <dvbpsi/dr.h>
54 # include "descriptor.h"
55 # include "tables/pat.h"
56 # include "tables/pmt.h"
57 # include "descriptors/dr.h"
61 /*****************************************************************************
63 *****************************************************************************/
64 #define TS_READ_ONCE 200
66 /*****************************************************************************
68 *****************************************************************************/
69 static void input_getfunctions( function_list_t * p_function_list );
70 static int TSInit ( struct input_thread_s * );
71 static void TSEnd ( struct input_thread_s * );
72 static int TSDemux ( struct input_thread_s * );
74 #if defined MODULE_NAME_IS_mpeg_ts
75 static void TSDemuxPSI ( struct input_thread_s *, struct data_packet_s *,
76 struct es_descriptor_s *, boolean_t );
77 static void TSDecodePAT( input_thread_t *, es_descriptor_t *);
78 static void TSDecodePMT( input_thread_t *, es_descriptor_t *);
79 #define PSI_CALLBACK TSDemuxPSI
80 #elif defined MODULE_NAME_IS_mpeg_ts_dvbpsi
81 static void TS_DVBPSI_DemuxPSI
82 ( struct input_thread_s *, struct data_packet_s *,
83 struct es_descriptor_s *, boolean_t );
84 static void TS_DVBPSI_HandlePAT
85 ( struct input_thread_s *, dvbpsi_pat_t * );
86 static void TS_DVBPSI_HandlePMT
87 ( struct input_thread_s *, dvbpsi_pmt_t * );
88 #define PSI_CALLBACK TS_DVBPSI_DemuxPSI
91 /*****************************************************************************
92 * Build configuration tree.
93 *****************************************************************************/
94 #define VLS_BACKWARDS_COMPAT_TEXT N_("compatibility with pre-0.4 VLS")
95 #define VLS_BACKWARDS_COMPAT_LONGTEXT N_( \
96 "The protocol for transmitting A/52 audio streams changed between VLC " \
97 "0.3.x and 0.4. By default VLC assumes you have the latest VLS. In case " \
98 "you're using an old version, select this option.")
101 ADD_CATEGORY_HINT( N_("Input"), NULL )
102 ADD_BOOL ( "vls-backwards-compat", 0, NULL, VLS_BACKWARDS_COMPAT_TEXT, VLS_BACKWARDS_COMPAT_LONGTEXT )
106 #if defined MODULE_NAME_IS_mpeg_ts
107 SET_DESCRIPTION( _("ISO 13818-1 MPEG Transport Stream input") )
108 ADD_CAPABILITY( DEMUX, 160 )
110 #elif defined MODULE_NAME_IS_mpeg_ts_dvbpsi
111 SET_DESCRIPTION( _("ISO 13818-1 MPEG Transport Stream input (libdvbpsi)") )
112 ADD_CAPABILITY( DEMUX, 170 )
113 ADD_SHORTCUT( "ts_dvbpsi" )
117 MODULE_ACTIVATE_START
118 input_getfunctions( &p_module->p_functions->demux );
121 MODULE_DEACTIVATE_START
122 MODULE_DEACTIVATE_STOP
124 /*****************************************************************************
125 * Functions exported as capabilities. They are declared as static so that
126 * we don't pollute the namespace too much.
127 *****************************************************************************/
128 static void input_getfunctions( function_list_t * p_function_list )
130 #define input p_function_list->functions.demux
131 input.pf_init = TSInit;
132 input.pf_end = TSEnd;
133 input.pf_demux = TSDemux;
134 input.pf_rewind = NULL;
138 /*****************************************************************************
139 * TSInit: initializes TS structures
140 *****************************************************************************/
141 static int TSInit( input_thread_t * p_input )
143 es_descriptor_t * p_pat_es;
144 es_ts_data_t * p_demux_data;
145 stream_ts_data_t * p_stream_data;
148 /* Initialize access plug-in structures. */
149 if( p_input->i_mtu == 0 )
152 p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
155 /* Have a peep at the show. */
156 if( input_Peek( p_input, &p_peek, 1 ) < 1 )
158 intf_ErrMsg( "input error: cannot peek() (mpeg_ts)" );
162 if( *p_peek != TS_SYNC_CODE )
164 if( *p_input->psz_demux && !strncmp( p_input->psz_demux, "ts", 3 ) )
167 intf_ErrMsg( "input error: this doesn't look like a TS stream, continuing" );
171 intf_WarnMsg( 2, "input: TS plug-in discarded (no sync)" );
176 /* Adapt the bufsize for our only use. */
177 if( p_input->i_mtu != 0 )
179 /* Have minimum granularity to avoid bottlenecks at the input level. */
180 p_input->i_bufsize = (p_input->i_mtu / TS_PACKET_SIZE) * TS_PACKET_SIZE;
183 vlc_mutex_lock( &p_input->stream.stream_lock );
185 if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
190 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
191 p_stream_data->i_pat_version = PAT_UNINITIALIZED ;
193 #ifdef MODULE_NAME_IS_mpeg_ts_dvbpsi
194 p_stream_data->p_pat_handle = (dvbpsi_handle *)
195 dvbpsi_AttachPAT( (dvbpsi_pat_callback) &TS_DVBPSI_HandlePAT, p_input );
197 if( p_stream_data->p_pat_handle == NULL )
199 intf_ErrMsg( "input: ts: could not create PAT decoder" );
204 /* We'll have to catch the PAT in order to continue
205 * Then the input will catch the PMT and then the others ES
206 * The PAT es is indepedent of any program. */
207 p_pat_es = input_AddES( p_input, NULL,
208 0x00, sizeof( es_ts_data_t ) );
209 p_demux_data = (es_ts_data_t *)p_pat_es->p_demux_data;
210 p_demux_data->b_psi = 1;
211 p_demux_data->i_psi_type = PSI_IS_PAT;
212 p_demux_data->p_psi_section = malloc(sizeof(psi_section_t));
213 p_demux_data->p_psi_section->b_is_complete = 1;
215 vlc_mutex_unlock( &p_input->stream.stream_lock );
220 /*****************************************************************************
221 * TSEnd: frees unused data
222 *****************************************************************************/
223 static void TSEnd( input_thread_t * p_input )
227 /*****************************************************************************
228 * TSDemux: reads and demuxes data packets
229 *****************************************************************************
230 * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
232 *****************************************************************************/
233 static int TSDemux( input_thread_t * p_input )
235 int i_read_once = (p_input->i_mtu ?
236 p_input->i_bufsize / TS_PACKET_SIZE :
240 for( i = 0; i < i_read_once; i++ )
242 data_packet_t * p_data;
245 i_result = input_ReadTS( p_input, &p_data );
252 input_DemuxTS( p_input, p_data, (psi_callback_t) &PSI_CALLBACK );
255 return( i_read_once );
259 #if defined MODULE_NAME_IS_mpeg_ts
261 * PSI demultiplexing and decoding without libdvbpsi
264 /*****************************************************************************
265 * DemuxPSI : makes up complete PSI data
266 *****************************************************************************/
267 static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data,
268 es_descriptor_t * p_es, boolean_t b_unit_start )
270 es_ts_data_t * p_demux_data;
272 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
274 #define p_psi (p_demux_data->p_psi_section)
275 #define p (p_data->p_payload_start)
279 /* unit_start set to 1 -> presence of a pointer field
280 * (see ISO/IEC 13818 (2.4.4.2) which should be set to 0x00 */
281 if( (u8)p[0] != 0x00 )
283 intf_WarnMsg( 2, "input: non zero pointer field found, "
284 "trying to continue" );
292 /* This is the begining of a new section */
294 if( ((u8)(p[1]) & 0xc0) != 0x80 )
296 intf_WarnMsg( 2, "input: invalid PSI packet" );
301 p_psi->i_section_length = ((p[1] & 0xF) << 8) | p[2];
302 p_psi->b_section_complete = 0;
303 p_psi->i_read_in_section = 0;
304 p_psi->i_section_number = (u8)p[6];
306 if( p_psi->b_is_complete || p_psi->i_section_number == 0 )
308 /* This is a new PSI packet */
309 p_psi->b_is_complete = 0;
311 p_psi->i_version_number = ( p[5] >> 1 ) & 0x1f;
312 p_psi->i_last_section_number = (u8)p[7];
314 /* We'll write at the begining of the buffer */
315 p_psi->p_current = p_psi->buffer;
319 if( p_psi->b_section_complete )
321 /* New Section of an already started PSI */
322 p_psi->b_section_complete = 0;
324 if( p_psi->i_version_number != (( p[5] >> 1 ) & 0x1f) )
326 intf_WarnMsg( 2, "input: PSI version differs "
330 if( p_psi->i_section_number + 1 != (u8)p[6] )
332 intf_WarnMsg( 2, "input: PSI Section discontinuity, "
337 p_psi->i_section_number++;
341 intf_WarnMsg( 2, "input: got unexpected new PSI section" );
348 if( !p_psi->b_trash )
351 if( (p_data->p_payload_end - p) >=
352 ( p_psi->i_section_length - p_psi->i_read_in_section ) )
354 /* The end of the section is in this TS packet */
355 memcpy( p_psi->p_current, p,
356 (p_psi->i_section_length - p_psi->i_read_in_section) );
358 p_psi->b_section_complete = 1;
360 (p_psi->i_section_length - p_psi->i_read_in_section);
362 if( p_psi->i_section_number == p_psi->i_last_section_number )
364 /* This was the last section of PSI */
365 p_psi->b_is_complete = 1;
367 switch( p_demux_data->i_psi_type)
370 TSDecodePAT( p_input, p_es );
373 TSDecodePMT( p_input, p_es );
376 intf_WarnMsg(2, "Received unknown PSI in DemuxPSI");
382 memcpy( p_psi->buffer, p, p_data->p_payload_end - p );
383 p_psi->i_read_in_section += p_data->p_payload_end - p;
385 p_psi->p_current += p_data->p_payload_end - p;
392 input_DeletePacket( p_input->p_method_data, p_data );
397 /*****************************************************************************
398 * DecodePAT : Decodes Programm association table and deal with it
399 *****************************************************************************/
400 static void TSDecodePAT( input_thread_t * p_input, es_descriptor_t * p_es )
402 stream_ts_data_t * p_stream_data;
403 es_ts_data_t * p_demux_data;
405 pgrm_descriptor_t * p_pgrm;
406 es_descriptor_t * p_current_es;
407 byte_t * p_current_data;
409 int i_section_length, i_program_id, i_pmt_pid;
410 int i_loop, i_current_section;
412 boolean_t b_changed = 0;
414 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
415 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
417 #define p_psi (p_demux_data->p_psi_section)
419 /* Not so fast, Mike ! If the PAT version has changed, we first check
420 * that its content has really changed before doing anything */
421 if( p_stream_data->i_pat_version != p_psi->i_version_number )
423 int i_programs = p_input->stream.i_pgrm_number;
425 p_current_data = p_psi->buffer;
429 i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
431 i_current_section = (u8)p_current_data[6];
434 ( i_loop < (i_section_length - 9) / 4 ) && !b_changed;
437 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
438 | *(p_current_data + i_loop * 4 + 9);
439 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
441 | *(p_current_data + i_loop * 4 + 11);
445 if( (p_pgrm = input_FindProgram( p_input, i_program_id ))
446 && (p_current_es = input_FindES( p_input, i_pmt_pid ))
447 && p_current_es->p_pgrm == p_pgrm
448 && p_current_es->i_id == i_pmt_pid
449 && ((es_ts_data_t *)p_current_es->p_demux_data)->b_psi
450 && ((es_ts_data_t *)p_current_es->p_demux_data)
451 ->i_psi_type == PSI_IS_PMT )
462 p_current_data += 3 + i_section_length;
464 } while( ( i_current_section < p_psi->i_last_section_number )
467 /* If we didn't find the expected amount of programs, the PAT has
468 * changed. Otherwise, it only changed if b_changed is already != 0 */
469 b_changed = b_changed || i_programs;
474 /* PAT has changed. We are going to delete all programs and
475 * create new ones. We chose not to only change what was needed
476 * as a PAT change may mean the stream is radically changing and
477 * this is a secure method to avoid crashes */
478 es_ts_data_t * p_es_demux;
479 pgrm_ts_data_t * p_pgrm_demux;
481 p_current_data = p_psi->buffer;
483 /* Delete all programs */
484 while( p_input->stream.i_pgrm_number )
486 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
491 i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
493 i_current_section = (u8)p_current_data[6];
495 for( i_loop = 0; i_loop < (i_section_length - 9) / 4 ; i_loop++ )
497 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
498 | *(p_current_data + i_loop * 4 + 9);
499 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
501 | *(p_current_data + i_loop * 4 + 11);
503 /* If program = 0, we're having info about NIT not PMT */
506 /* Add this program */
507 p_pgrm = input_AddProgram( p_input, i_program_id,
508 sizeof( pgrm_ts_data_t ) );
510 /* whatis the PID of the PMT of this program */
511 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
512 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
514 /* Add the PMT ES to this program */
515 p_current_es = input_AddES( p_input, p_pgrm,(u16)i_pmt_pid,
516 sizeof( es_ts_data_t) );
517 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
518 p_es_demux->b_psi = 1;
519 p_es_demux->i_psi_type = PSI_IS_PMT;
521 p_es_demux->p_psi_section =
522 malloc( sizeof( psi_section_t ) );
523 p_es_demux->p_psi_section->b_is_complete = 0;
527 p_current_data += 3 + i_section_length;
529 } while( i_current_section < p_psi->i_last_section_number );
531 /* Go to the beginning of the next section */
532 p_stream_data->i_pat_version = p_psi->i_version_number;
539 /*****************************************************************************
540 * DecodePMT : decode a given Program Stream Map
541 * ***************************************************************************
542 * When the PMT changes, it may mean a deep change in the stream, and it is
543 * careful to delete the ES and add them again. If the PMT doesn't change,
544 * there no need to do anything.
545 *****************************************************************************/
546 static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es )
549 pgrm_ts_data_t * p_pgrm_data;
550 es_ts_data_t * p_demux_data;
551 boolean_t b_vls_compat = config_GetIntVariable( "vls-backwards-compat" );
553 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
554 p_pgrm_data = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;
556 #define p_psi (p_demux_data->p_psi_section)
558 if( p_psi->i_version_number != p_pgrm_data->i_pmt_version )
560 es_descriptor_t * p_new_es;
561 es_ts_data_t * p_es_demux;
562 byte_t * p_current_data, * p_current_section;
563 int i_section_length,i_current_section;
564 int i_prog_info_length, i_loop;
565 int i_es_info_length, i_pid, i_stream_type;
567 p_current_section = p_psi->buffer;
568 p_current_data = p_psi->buffer;
570 p_pgrm_data->i_pcr_pid = ( ((u32)*(p_current_section + 8) & 0x1F) << 8 ) |
571 *(p_current_section + 9);
574 /* Lock stream information */
575 vlc_mutex_lock( &p_input->stream.stream_lock );
577 /* Delete all ES in this program except the PSI. We start from the
578 * end because i_es_number gets decremented after each deletion. */
579 for( i_loop = p_es->p_pgrm->i_es_number ; i_loop ; )
582 p_es_demux = (es_ts_data_t *)
583 p_es->p_pgrm->pp_es[i_loop]->p_demux_data;
584 if ( ! p_es_demux->b_psi )
586 input_DelES( p_input, p_es->p_pgrm->pp_es[i_loop] );
590 /* Then add what we received in this PMT */
593 i_section_length = ( ((u32)*(p_current_data + 1) & 0xF) << 8 ) |
594 *(p_current_data + 2);
595 i_current_section = (u8)p_current_data[6];
596 i_prog_info_length = ( ((u32)*(p_current_data + 10) & 0xF) << 8 ) |
597 *(p_current_data + 11);
599 /* For the moment we ignore program descriptors */
600 p_current_data += 12 + i_prog_info_length;
602 /* The end of the section, before the CRC is at
603 * p_current_section + i_section_length -1 */
604 while( p_current_data < p_current_section + i_section_length -1 )
606 i_stream_type = (int)p_current_data[0];
607 i_pid = ( ((u32)*(p_current_data + 1) & 0x1F) << 8 ) |
608 *(p_current_data + 2);
609 i_es_info_length = ( ((u32)*(p_current_data + 3) & 0xF) << 8 ) |
610 *(p_current_data + 4);
612 /* Add this ES to the program */
613 p_new_es = input_AddES( p_input, p_es->p_pgrm,
614 (u16)i_pid, sizeof( es_ts_data_t ) );
616 /* Tell the decoders what kind of stream it is */
617 p_new_es->i_type = i_stream_type;
619 /* Tell the interface what kind of stream it is and select
620 * the required ones */
622 switch( i_stream_type )
626 p_new_es->i_cat = VIDEO_ES;
630 p_new_es->i_cat = AUDIO_ES;
634 p_new_es->i_type = A52B_AUDIO_ES;
638 p_new_es->i_stream_id = 0xBD;
639 p_new_es->i_cat = AUDIO_ES;
641 /* Not sure this one is fully specification-compliant */
644 p_new_es->i_type = DVDB_SPU_ES;
647 p_new_es->i_stream_id = 0xBD;
648 p_new_es->i_cat = SPU_ES;
651 p_new_es->i_cat = UNKNOWN_ES;
656 p_current_data += 5 + i_es_info_length;
659 /* Go to the beginning of the next section*/
660 p_current_data += 3 + i_section_length;
664 } while( i_current_section < p_psi->i_last_section_number );
666 p_pgrm_data->i_pmt_version = p_psi->i_version_number;
668 /* if no program is selected :*/
669 if( !p_input->stream.p_selected_program )
671 pgrm_descriptor_t * p_pgrm_to_select;
672 u16 i_id = (u16)config_GetIntVariable( "program" );
674 if( i_id != 0 ) /* if user specified a program */
676 p_pgrm_to_select = input_FindProgram( p_input, i_id );
678 if( p_pgrm_to_select && p_pgrm_to_select == p_es->p_pgrm )
679 p_input->pf_set_program( p_input, p_pgrm_to_select );
682 p_input->pf_set_program( p_input, p_es->p_pgrm );
685 /* inform interface that stream has changed */
686 p_input->stream.b_changed = 1;
688 vlc_mutex_unlock( &p_input->stream.stream_lock );
694 #elif defined MODULE_NAME_IS_mpeg_ts_dvbpsi
696 * PSI Decoding using libdvbcss
699 /*****************************************************************************
700 * DemuxPSI : send the PSI to the right libdvbpsi decoder
701 *****************************************************************************/
702 static void TS_DVBPSI_DemuxPSI( input_thread_t * p_input,
703 data_packet_t * p_data,
704 es_descriptor_t * p_es,
705 boolean_t b_unit_start )
707 es_ts_data_t * p_es_demux_data;
708 pgrm_ts_data_t * p_pgrm_demux_data;
709 stream_ts_data_t * p_stream_demux_data;
711 p_es_demux_data = ( es_ts_data_t * ) p_es->p_demux_data;
712 p_stream_demux_data = ( stream_ts_data_t * ) p_input->stream.p_demux_data;
714 switch( p_es_demux_data->i_psi_type)
718 ( dvbpsi_handle ) p_stream_demux_data->p_pat_handle,
719 p_data->p_demux_start );
722 p_pgrm_demux_data = ( pgrm_ts_data_t * )p_es->p_pgrm->p_demux_data;
724 ( dvbpsi_handle ) p_pgrm_demux_data->p_pmt_handle,
725 p_data->p_demux_start );
728 intf_WarnMsg( 2, "Received unknown PSI in DemuxPSI" );
731 input_DeletePacket( p_input->p_method_data, p_data );
734 /*****************************************************************************
735 * HandlePAT: will treat a PAT returned by dvbpsi
736 *****************************************************************************/
738 void TS_DVBPSI_HandlePAT( input_thread_t * p_input, dvbpsi_pat_t * p_new_pat )
740 dvbpsi_pat_program_t * p_pgrm;
741 pgrm_descriptor_t * p_new_pgrm;
742 pgrm_ts_data_t * p_pgrm_demux;
743 es_descriptor_t * p_current_es;
744 es_ts_data_t * p_es_demux;
745 stream_ts_data_t * p_stream_data;
747 vlc_mutex_lock( &p_input->stream.stream_lock );
749 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
751 if ( !p_new_pat->b_current_next ||
752 p_stream_data->i_pat_version == PAT_UNINITIALIZED )
754 /* Delete all programs */
755 while( p_input->stream.i_pgrm_number )
757 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
760 /* treat the new programs list */
761 p_pgrm = p_new_pat->p_first_program;
765 /* If program = 0, we're having info about NIT not PMT */
766 if( p_pgrm->i_number )
768 /* Add this program */
769 p_new_pgrm = input_AddProgram( p_input, p_pgrm->i_number,
770 sizeof( pgrm_ts_data_t ) );
772 p_pgrm_demux = (pgrm_ts_data_t *)p_new_pgrm->p_demux_data;
773 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
775 /* Add the PMT ES to this program */
776 p_current_es = input_AddES( p_input, p_new_pgrm,
778 sizeof( es_ts_data_t) );
779 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
780 p_es_demux->b_psi = 1;
781 p_es_demux->i_psi_type = PSI_IS_PMT;
783 p_es_demux->p_psi_section = malloc( sizeof( psi_section_t ) );
784 if ( p_es_demux->p_psi_section == NULL )
786 intf_ErrMsg( "input: ts: could not malloc pmt section" );
787 p_input->b_error = 1;
791 p_es_demux->p_psi_section->b_is_complete = 0;
793 /* Create a PMT decoder */
794 p_pgrm_demux->p_pmt_handle = (dvbpsi_handle *)
795 dvbpsi_AttachPMT( p_pgrm->i_number,
796 (dvbpsi_pmt_callback) &TS_DVBPSI_HandlePMT,
799 if( p_pgrm_demux->p_pmt_handle == NULL )
801 intf_ErrMsg( "input: ts: could not create PMT decoder" );
802 p_input->b_error = 1;
807 p_pgrm = p_pgrm->p_next;
810 p_stream_data->i_pat_version = p_new_pat->i_version;
812 vlc_mutex_unlock( &p_input->stream.stream_lock );
815 /*****************************************************************************
816 * HandlePMT: will treat a PMT returned by dvbpsi
817 *****************************************************************************/
818 void TS_DVBPSI_HandlePMT( input_thread_t * p_input, dvbpsi_pmt_t * p_new_pmt )
820 dvbpsi_pmt_es_t * p_es;
821 pgrm_descriptor_t * p_pgrm;
822 es_descriptor_t * p_new_es;
823 pgrm_ts_data_t * p_pgrm_demux;
824 boolean_t b_vls_compat = config_GetIntVariable( "vls-backwards-compat" );
826 vlc_mutex_lock( &p_input->stream.stream_lock );
828 p_pgrm = input_FindProgram( p_input, p_new_pmt->i_program_number );
832 intf_WarnMsg( 2, "input: ts: PMT of unreferenced program found" );
836 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
837 p_pgrm_demux->i_pcr_pid = p_new_pmt->i_pcr_pid;
839 if( !p_new_pmt->b_current_next ||
840 p_pgrm_demux->i_pmt_version == PMT_UNINITIALIZED )
842 p_es = p_new_pmt->p_first_es;
846 p_new_es = input_AddES( p_input, p_pgrm,
847 (u16)p_es->i_pid, sizeof( es_ts_data_t ) );
848 if( p_new_es == NULL )
850 intf_ErrMsg( "input: ts: Could not add ES %d", p_es->i_pid );
851 p_input->b_error = 1;
855 p_new_es->i_type = p_es->i_type;
856 switch( p_es->i_type )
860 p_new_es->i_cat = VIDEO_ES;
864 p_new_es->i_cat = AUDIO_ES;
868 p_new_es->i_type = A52B_AUDIO_ES;
872 p_new_es->i_cat = AUDIO_ES;
873 p_new_es->i_stream_id = 0xBD;
877 p_new_es->i_type = DVDB_SPU_ES;
880 p_new_es->i_cat = SPU_ES;
881 p_new_es->i_stream_id = 0xBD;
884 p_new_es->i_cat = UNKNOWN_ES;
887 if( ( p_new_es->i_cat == AUDIO_ES )
888 || (p_new_es->i_cat == SPU_ES ) )
890 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
891 while( p_dr && ( p_dr->i_tag != 0x0a ) )
895 dvbpsi_iso639_dr_t *p_decoded =
896 dvbpsi_DecodeISO639Dr( p_dr );
897 if( p_decoded->i_code_count > 0 )
899 const iso639_lang_t * p_iso;
900 p_iso = GetLang_2T(p_decoded->i_iso_639_code);
903 if(p_iso->psz_native_name[0])
904 strcpy( p_new_es->psz_desc,
905 p_iso->psz_native_name );
907 strcpy( p_new_es->psz_desc,
908 p_iso->psz_eng_name );
912 strncpy( p_new_es->psz_desc,
913 p_decoded->i_iso_639_code, 3 );
917 switch( p_es->i_type )
921 strcat( p_new_es->psz_desc, " (mpeg)" );
924 strcat( p_new_es->psz_desc, " (lpcm)" );
928 strcat( p_new_es->psz_desc, " (ac3)" );
936 /* if no program is selected :*/
937 if( !p_input->stream.p_selected_program )
939 pgrm_descriptor_t * p_pgrm_to_select;
940 u16 i_id = (u16)config_GetIntVariable( "program" );
942 if( i_id != 0 ) /* if user specified a program */
944 p_pgrm_to_select = input_FindProgram( p_input, i_id );
946 if( p_pgrm_to_select && p_pgrm_to_select == p_pgrm )
947 p_input->pf_set_program( p_input, p_pgrm_to_select );
950 p_input->pf_set_program( p_input, p_pgrm );
952 /* if the pmt belongs to the currently selected program, we
953 * reselect it to update its ES */
954 else if( p_pgrm == p_input->stream.p_selected_program )
956 p_input->pf_set_program( p_input, p_pgrm );
959 p_pgrm_demux->i_pmt_version = p_new_pmt->i_version;
960 p_input->stream.b_changed = 1;
962 vlc_mutex_unlock( &p_input->stream.stream_lock );