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 2002/05/21 01:27:26 sam 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 <videolan/vlc.h>
34 #include "stream_control.h"
35 #include "input_ext-intf.h"
36 #include "input_ext-dec.h"
37 #include "input_ext-plugins.h"
41 #if defined MODULE_NAME_IS_mpeg_ts_dvbpsi
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>
48 /*****************************************************************************
50 *****************************************************************************/
51 #define TS_READ_ONCE 200
53 /*****************************************************************************
55 *****************************************************************************/
56 static void input_getfunctions( function_list_t * p_function_list );
57 static int TSInit ( struct input_thread_s * );
58 static void TSEnd ( struct input_thread_s * );
59 static int TSDemux ( struct input_thread_s * );
61 #if defined MODULE_NAME_IS_mpeg_ts
62 static void TSDemuxPSI ( struct input_thread_s *, struct data_packet_s *,
63 struct es_descriptor_s *, boolean_t );
64 static void TSDecodePAT( input_thread_t *, es_descriptor_t *);
65 static void TSDecodePMT( input_thread_t *, es_descriptor_t *);
66 #define PSI_CALLBACK TSDemuxPSI
67 #elif defined MODULE_NAME_IS_mpeg_ts_dvbpsi
68 static void TS_DVBPSI_DemuxPSI
69 ( struct input_thread_s *, struct data_packet_s *,
70 struct es_descriptor_s *, boolean_t );
71 static void TS_DVBPSI_HandlePAT
72 ( struct input_thread_s *, dvbpsi_pat_t * );
73 static void TS_DVBPSI_HandlePMT
74 ( struct input_thread_s *, dvbpsi_pmt_t * );
75 #define PSI_CALLBACK TS_DVBPSI_DemuxPSI
78 /*****************************************************************************
79 * Build configuration tree.
80 *****************************************************************************/
85 #if defined MODULE_NAME_IS_mpeg_ts
86 SET_DESCRIPTION( _("ISO 13818-1 MPEG Transport Stream input") )
87 ADD_CAPABILITY( DEMUX, 160 )
89 #elif defined MODULE_NAME_IS_mpeg_ts_dvbpsi
90 SET_DESCRIPTION( _("ISO 13818-1 MPEG Transport Stream input (libdvbpsi)") )
91 ADD_CAPABILITY( DEMUX, 170 )
92 ADD_SHORTCUT( "ts_dvbpsi" )
97 input_getfunctions( &p_module->p_functions->demux );
100 MODULE_DEACTIVATE_START
101 MODULE_DEACTIVATE_STOP
103 /*****************************************************************************
104 * Functions exported as capabilities. They are declared as static so that
105 * we don't pollute the namespace too much.
106 *****************************************************************************/
107 static void input_getfunctions( function_list_t * p_function_list )
109 #define input p_function_list->functions.demux
110 input.pf_init = TSInit;
111 input.pf_end = TSEnd;
112 input.pf_demux = TSDemux;
113 input.pf_rewind = NULL;
117 /*****************************************************************************
118 * TSInit: initializes TS structures
119 *****************************************************************************/
120 static int TSInit( input_thread_t * p_input )
122 es_descriptor_t * p_pat_es;
123 es_ts_data_t * p_demux_data;
124 stream_ts_data_t * p_stream_data;
127 /* Initialize access plug-in structures. */
128 if( p_input->i_mtu == 0 )
131 p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
134 /* Have a peep at the show. */
135 if( input_Peek( p_input, &p_peek, 1 ) < 1 )
137 intf_ErrMsg( "input error: cannot peek() (mpeg_ts)" );
141 if( *p_peek != TS_SYNC_CODE )
143 if( *p_input->psz_demux && !strncmp( p_input->psz_demux, "ts", 3 ) )
146 intf_ErrMsg( "input error: this doesn't look like a TS stream, continuing" );
150 intf_WarnMsg( 2, "input: TS plug-in discarded (no sync)" );
155 /* Adapt the bufsize for our only use. */
156 if( p_input->i_mtu != 0 )
158 /* Have minimum granularity to avoid bottlenecks at the input level. */
159 p_input->i_bufsize = (p_input->i_mtu / TS_PACKET_SIZE) * TS_PACKET_SIZE;
162 vlc_mutex_lock( &p_input->stream.stream_lock );
164 if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
169 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
170 p_stream_data->i_pat_version = PAT_UNINITIALIZED ;
172 #ifdef MODULE_NAME_IS_mpeg_ts_dvbpsi
173 p_stream_data->p_pat_handle = (dvbpsi_handle *)
174 dvbpsi_AttachPAT( (dvbpsi_pat_callback) &TS_DVBPSI_HandlePAT, p_input );
176 if( p_stream_data->p_pat_handle == NULL )
178 intf_ErrMsg( "input: ts: could not create PAT decoder" );
183 /* We'll have to catch the PAT in order to continue
184 * Then the input will catch the PMT and then the others ES
185 * The PAT es is indepedent of any program. */
186 p_pat_es = input_AddES( p_input, NULL,
187 0x00, sizeof( es_ts_data_t ) );
188 p_demux_data = (es_ts_data_t *)p_pat_es->p_demux_data;
189 p_demux_data->b_psi = 1;
190 p_demux_data->i_psi_type = PSI_IS_PAT;
191 p_demux_data->p_psi_section = malloc(sizeof(psi_section_t));
192 p_demux_data->p_psi_section->b_is_complete = 1;
194 vlc_mutex_unlock( &p_input->stream.stream_lock );
199 /*****************************************************************************
200 * TSEnd: frees unused data
201 *****************************************************************************/
202 static void TSEnd( input_thread_t * p_input )
206 /*****************************************************************************
207 * TSDemux: reads and demuxes data packets
208 *****************************************************************************
209 * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
211 *****************************************************************************/
212 static int TSDemux( input_thread_t * p_input )
214 int i_read_once = (p_input->i_mtu ?
215 p_input->i_bufsize / TS_PACKET_SIZE :
219 for( i = 0; i < i_read_once; i++ )
221 data_packet_t * p_data;
224 i_result = input_ReadTS( p_input, &p_data );
231 input_DemuxTS( p_input, p_data, (psi_callback_t) &PSI_CALLBACK );
234 return( i_read_once );
238 #if defined MODULE_NAME_IS_mpeg_ts
240 * PSI demultiplexing and decoding without libdvbpsi
243 /*****************************************************************************
244 * DemuxPSI : makes up complete PSI data
245 *****************************************************************************/
246 static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data,
247 es_descriptor_t * p_es, boolean_t b_unit_start )
249 es_ts_data_t * p_demux_data;
251 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
253 #define p_psi (p_demux_data->p_psi_section)
254 #define p (p_data->p_payload_start)
258 /* unit_start set to 1 -> presence of a pointer field
259 * (see ISO/IEC 13818 (2.4.4.2) which should be set to 0x00 */
260 if( (u8)p[0] != 0x00 )
262 intf_WarnMsg( 2, "input: non zero pointer field found, "
263 "trying to continue" );
271 /* This is the begining of a new section */
273 if( ((u8)(p[1]) & 0xc0) != 0x80 )
275 intf_WarnMsg( 2, "input: invalid PSI packet" );
280 p_psi->i_section_length = ((p[1] & 0xF) << 8) | p[2];
281 p_psi->b_section_complete = 0;
282 p_psi->i_read_in_section = 0;
283 p_psi->i_section_number = (u8)p[6];
285 if( p_psi->b_is_complete || p_psi->i_section_number == 0 )
287 /* This is a new PSI packet */
288 p_psi->b_is_complete = 0;
290 p_psi->i_version_number = ( p[5] >> 1 ) & 0x1f;
291 p_psi->i_last_section_number = (u8)p[7];
293 /* We'll write at the begining of the buffer */
294 p_psi->p_current = p_psi->buffer;
298 if( p_psi->b_section_complete )
300 /* New Section of an already started PSI */
301 p_psi->b_section_complete = 0;
303 if( p_psi->i_version_number != (( p[5] >> 1 ) & 0x1f) )
305 intf_WarnMsg( 2, "input: PSI version differs "
309 if( p_psi->i_section_number + 1 != (u8)p[6] )
311 intf_WarnMsg( 2, "input: PSI Section discontinuity, "
316 p_psi->i_section_number++;
320 intf_WarnMsg( 2, "input: got unexpected new PSI section" );
327 if( !p_psi->b_trash )
330 if( (p_data->p_payload_end - p) >=
331 ( p_psi->i_section_length - p_psi->i_read_in_section ) )
333 /* The end of the section is in this TS packet */
334 memcpy( p_psi->p_current, p,
335 (p_psi->i_section_length - p_psi->i_read_in_section) );
337 p_psi->b_section_complete = 1;
339 (p_psi->i_section_length - p_psi->i_read_in_section);
341 if( p_psi->i_section_number == p_psi->i_last_section_number )
343 /* This was the last section of PSI */
344 p_psi->b_is_complete = 1;
346 switch( p_demux_data->i_psi_type)
349 TSDecodePAT( p_input, p_es );
352 TSDecodePMT( p_input, p_es );
355 intf_WarnMsg(2, "Received unknown PSI in DemuxPSI");
361 memcpy( p_psi->buffer, p, p_data->p_payload_end - p );
362 p_psi->i_read_in_section += p_data->p_payload_end - p;
364 p_psi->p_current += p_data->p_payload_end - p;
371 input_DeletePacket( p_input->p_method_data, p_data );
376 /*****************************************************************************
377 * DecodePAT : Decodes Programm association table and deal with it
378 *****************************************************************************/
379 static void TSDecodePAT( input_thread_t * p_input, es_descriptor_t * p_es )
381 stream_ts_data_t * p_stream_data;
382 es_ts_data_t * p_demux_data;
384 pgrm_descriptor_t * p_pgrm;
385 es_descriptor_t * p_current_es;
386 byte_t * p_current_data;
388 int i_section_length, i_program_id, i_pmt_pid;
389 int i_loop, i_current_section;
391 boolean_t b_changed = 0;
393 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
394 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
396 #define p_psi (p_demux_data->p_psi_section)
398 /* Not so fast, Mike ! If the PAT version has changed, we first check
399 * that its content has really changed before doing anything */
400 if( p_stream_data->i_pat_version != p_psi->i_version_number )
402 int i_programs = p_input->stream.i_pgrm_number;
404 p_current_data = p_psi->buffer;
408 i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
410 i_current_section = (u8)p_current_data[6];
413 ( i_loop < (i_section_length - 9) / 4 ) && !b_changed;
416 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
417 | *(p_current_data + i_loop * 4 + 9);
418 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
420 | *(p_current_data + i_loop * 4 + 11);
424 if( (p_pgrm = input_FindProgram( p_input, i_program_id ))
425 && (p_current_es = input_FindES( p_input, i_pmt_pid ))
426 && p_current_es->p_pgrm == p_pgrm
427 && p_current_es->i_id == i_pmt_pid
428 && ((es_ts_data_t *)p_current_es->p_demux_data)->b_psi
429 && ((es_ts_data_t *)p_current_es->p_demux_data)
430 ->i_psi_type == PSI_IS_PMT )
441 p_current_data += 3 + i_section_length;
443 } while( ( i_current_section < p_psi->i_last_section_number )
446 /* If we didn't find the expected amount of programs, the PAT has
447 * changed. Otherwise, it only changed if b_changed is already != 0 */
448 b_changed = b_changed || i_programs;
453 /* PAT has changed. We are going to delete all programs and
454 * create new ones. We chose not to only change what was needed
455 * as a PAT change may mean the stream is radically changing and
456 * this is a secure method to avoid crashes */
457 es_ts_data_t * p_es_demux;
458 pgrm_ts_data_t * p_pgrm_demux;
460 p_current_data = p_psi->buffer;
462 /* Delete all programs */
463 while( p_input->stream.i_pgrm_number )
465 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
470 i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
472 i_current_section = (u8)p_current_data[6];
474 for( i_loop = 0; i_loop < (i_section_length - 9) / 4 ; i_loop++ )
476 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
477 | *(p_current_data + i_loop * 4 + 9);
478 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
480 | *(p_current_data + i_loop * 4 + 11);
482 /* If program = 0, we're having info about NIT not PMT */
485 /* Add this program */
486 p_pgrm = input_AddProgram( p_input, i_program_id,
487 sizeof( pgrm_ts_data_t ) );
489 /* whatis the PID of the PMT of this program */
490 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
491 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
493 /* Add the PMT ES to this program */
494 p_current_es = input_AddES( p_input, p_pgrm,(u16)i_pmt_pid,
495 sizeof( es_ts_data_t) );
496 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
497 p_es_demux->b_psi = 1;
498 p_es_demux->i_psi_type = PSI_IS_PMT;
500 p_es_demux->p_psi_section =
501 malloc( sizeof( psi_section_t ) );
502 p_es_demux->p_psi_section->b_is_complete = 0;
506 p_current_data += 3 + i_section_length;
508 } while( i_current_section < p_psi->i_last_section_number );
510 /* Go to the beginning of the next section */
511 p_stream_data->i_pat_version = p_psi->i_version_number;
518 /*****************************************************************************
519 * DecodePMT : decode a given Program Stream Map
520 * ***************************************************************************
521 * When the PMT changes, it may mean a deep change in the stream, and it is
522 * careful to delete the ES and add them again. If the PMT doesn't change,
523 * there no need to do anything.
524 *****************************************************************************/
525 static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es )
528 pgrm_ts_data_t * p_pgrm_data;
529 es_ts_data_t * p_demux_data;
531 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
532 p_pgrm_data = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;
534 #define p_psi (p_demux_data->p_psi_section)
536 if( p_psi->i_version_number != p_pgrm_data->i_pmt_version )
538 es_descriptor_t * p_new_es;
539 es_ts_data_t * p_es_demux;
540 byte_t * p_current_data, * p_current_section;
541 int i_section_length,i_current_section;
542 int i_prog_info_length, i_loop;
543 int i_es_info_length, i_pid, i_stream_type;
545 p_current_section = p_psi->buffer;
546 p_current_data = p_psi->buffer;
548 p_pgrm_data->i_pcr_pid = ( ((u32)*(p_current_section + 8) & 0x1F) << 8 ) |
549 *(p_current_section + 9);
552 /* Lock stream information */
553 vlc_mutex_lock( &p_input->stream.stream_lock );
555 /* Delete all ES in this program except the PSI. We start from the
556 * end because i_es_number gets decremented after each deletion. */
557 for( i_loop = p_es->p_pgrm->i_es_number ; i_loop ; )
560 p_es_demux = (es_ts_data_t *)
561 p_es->p_pgrm->pp_es[i_loop]->p_demux_data;
562 if ( ! p_es_demux->b_psi )
564 input_DelES( p_input, p_es->p_pgrm->pp_es[i_loop] );
568 /* Then add what we received in this PMT */
571 i_section_length = ( ((u32)*(p_current_data + 1) & 0xF) << 8 ) |
572 *(p_current_data + 2);
573 i_current_section = (u8)p_current_data[6];
574 i_prog_info_length = ( ((u32)*(p_current_data + 10) & 0xF) << 8 ) |
575 *(p_current_data + 11);
577 /* For the moment we ignore program descriptors */
578 p_current_data += 12 + i_prog_info_length;
580 /* The end of the section, before the CRC is at
581 * p_current_section + i_section_length -1 */
582 while( p_current_data < p_current_section + i_section_length -1 )
584 i_stream_type = (int)p_current_data[0];
585 i_pid = ( ((u32)*(p_current_data + 1) & 0x1F) << 8 ) |
586 *(p_current_data + 2);
587 i_es_info_length = ( ((u32)*(p_current_data + 3) & 0xF) << 8 ) |
588 *(p_current_data + 4);
590 /* Add this ES to the program */
591 p_new_es = input_AddES( p_input, p_es->p_pgrm,
592 (u16)i_pid, sizeof( es_ts_data_t ) );
594 /* Tell the decoders what kind of stream it is */
595 p_new_es->i_type = i_stream_type;
597 /* Tell the interface what kind of stream it is and select
598 * the required ones */
600 switch( i_stream_type )
604 p_new_es->i_cat = VIDEO_ES;
608 p_new_es->i_cat = AUDIO_ES;
612 p_new_es->i_stream_id = 0xBD;
613 p_new_es->i_cat = AUDIO_ES;
615 /* Not sure this one is fully specification-compliant */
617 p_new_es->i_stream_id = 0xBD;
618 p_new_es->i_cat = SPU_ES;
621 p_new_es->i_cat = UNKNOWN_ES;
626 p_current_data += 5 + i_es_info_length;
629 /* Go to the beginning of the next section*/
630 p_current_data += 3 + i_section_length;
634 } while( i_current_section < p_psi->i_last_section_number );
636 p_pgrm_data->i_pmt_version = p_psi->i_version_number;
638 /* if no program is selected :*/
639 if( !p_input->stream.p_selected_program )
641 pgrm_descriptor_t * p_pgrm_to_select;
642 u16 i_id = (u16)config_GetIntVariable( "program" );
644 if( i_id != 0 ) /* if user specified a program */
646 p_pgrm_to_select = input_FindProgram( p_input, i_id );
648 if( p_pgrm_to_select && p_pgrm_to_select == p_es->p_pgrm )
649 p_input->pf_set_program( p_input, p_pgrm_to_select );
652 p_input->pf_set_program( p_input, p_es->p_pgrm );
655 /* inform interface that stream has changed */
656 p_input->stream.b_changed = 1;
658 vlc_mutex_unlock( &p_input->stream.stream_lock );
664 #elif defined MODULE_NAME_IS_mpeg_ts_dvbpsi
666 * PSI Decoding using libdvbcss
669 /*****************************************************************************
670 * DemuxPSI : send the PSI to the right libdvbpsi decoder
671 *****************************************************************************/
672 static void TS_DVBPSI_DemuxPSI( input_thread_t * p_input,
673 data_packet_t * p_data,
674 es_descriptor_t * p_es,
675 boolean_t b_unit_start )
677 es_ts_data_t * p_es_demux_data;
678 pgrm_ts_data_t * p_pgrm_demux_data;
679 stream_ts_data_t * p_stream_demux_data;
681 p_es_demux_data = ( es_ts_data_t * ) p_es->p_demux_data;
682 p_stream_demux_data = ( stream_ts_data_t * ) p_input->stream.p_demux_data;
684 switch( p_es_demux_data->i_psi_type)
688 ( dvbpsi_handle ) p_stream_demux_data->p_pat_handle,
689 p_data->p_demux_start );
692 p_pgrm_demux_data = ( pgrm_ts_data_t * )p_es->p_pgrm->p_demux_data;
694 ( dvbpsi_handle ) p_pgrm_demux_data->p_pmt_handle,
695 p_data->p_demux_start );
698 intf_WarnMsg( 2, "Received unknown PSI in DemuxPSI" );
701 input_DeletePacket( p_input->p_method_data, p_data );
704 /*****************************************************************************
705 * HandlePAT: will treat a PAT returned by dvbpsi
706 *****************************************************************************/
708 void TS_DVBPSI_HandlePAT( input_thread_t * p_input, dvbpsi_pat_t * p_new_pat )
710 dvbpsi_pat_program_t * p_pgrm;
711 pgrm_descriptor_t * p_new_pgrm;
712 pgrm_ts_data_t * p_pgrm_demux;
713 es_descriptor_t * p_current_es;
714 es_ts_data_t * p_es_demux;
715 stream_ts_data_t * p_stream_data;
717 vlc_mutex_lock( &p_input->stream.stream_lock );
719 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
721 if ( !p_new_pat->b_current_next ||
722 p_stream_data->i_pat_version == PAT_UNINITIALIZED )
724 /* Delete all programs */
725 while( p_input->stream.i_pgrm_number )
727 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
730 /* treat the new programs list */
731 p_pgrm = p_new_pat->p_first_program;
735 /* If program = 0, we're having info about NIT not PMT */
736 if( p_pgrm->i_number )
738 /* Add this program */
739 p_new_pgrm = input_AddProgram( p_input, p_pgrm->i_number,
740 sizeof( pgrm_ts_data_t ) );
742 p_pgrm_demux = (pgrm_ts_data_t *)p_new_pgrm->p_demux_data;
743 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
745 /* Add the PMT ES to this program */
746 p_current_es = input_AddES( p_input, p_new_pgrm,
748 sizeof( es_ts_data_t) );
749 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
750 p_es_demux->b_psi = 1;
751 p_es_demux->i_psi_type = PSI_IS_PMT;
753 p_es_demux->p_psi_section = malloc( sizeof( psi_section_t ) );
754 if ( p_es_demux->p_psi_section == NULL )
756 intf_ErrMsg( "input: ts: could not malloc pmt section" );
757 p_input->b_error = 1;
761 p_es_demux->p_psi_section->b_is_complete = 0;
763 /* Create a PMT decoder */
764 p_pgrm_demux->p_pmt_handle = (dvbpsi_handle *)
765 dvbpsi_AttachPMT( p_pgrm->i_number,
766 (dvbpsi_pmt_callback) &TS_DVBPSI_HandlePMT,
769 if( p_pgrm_demux->p_pmt_handle == NULL )
771 intf_ErrMsg( "input: ts: could not create PMT decoder" );
772 p_input->b_error = 1;
777 p_pgrm = p_pgrm->p_next;
780 p_stream_data->i_pat_version = p_new_pat->i_version;
782 vlc_mutex_unlock( &p_input->stream.stream_lock );
785 /*****************************************************************************
786 * HandlePMT: will treat a PMT returned by dvbpsi
787 *****************************************************************************/
788 void TS_DVBPSI_HandlePMT( input_thread_t * p_input, dvbpsi_pmt_t * p_new_pmt )
790 dvbpsi_pmt_es_t * p_es;
791 pgrm_descriptor_t * p_pgrm;
792 es_descriptor_t * p_new_es;
793 pgrm_ts_data_t * p_pgrm_demux;
795 vlc_mutex_lock( &p_input->stream.stream_lock );
797 p_pgrm = input_FindProgram( p_input, p_new_pmt->i_program_number );
801 intf_WarnMsg( 2, "input: ts: PMT of unreferenced program found" );
805 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
806 p_pgrm_demux->i_pcr_pid = p_new_pmt->i_pcr_pid;
808 if( !p_new_pmt->b_current_next ||
809 p_pgrm_demux->i_pmt_version == PMT_UNINITIALIZED )
811 p_es = p_new_pmt->p_first_es;
815 p_new_es = input_AddES( p_input, p_pgrm,
816 (u16)p_es->i_pid, sizeof( es_ts_data_t ) );
817 if( p_new_es == NULL )
819 intf_ErrMsg( "input: ts: Could not add ES %d", p_es->i_pid );
820 p_input->b_error = 1;
824 p_new_es->i_type = p_es->i_type;
825 switch( p_es->i_type )
829 p_new_es->i_cat = VIDEO_ES;
833 p_new_es->i_cat = AUDIO_ES;
837 p_new_es->i_cat = AUDIO_ES;
838 p_new_es->i_stream_id = 0xBD;
841 p_new_es->i_cat = SPU_ES;
842 p_new_es->i_stream_id = 0xBD;
845 p_new_es->i_cat = UNKNOWN_ES;
848 if( ( p_new_es->i_cat == AUDIO_ES )
849 || (p_new_es->i_cat == SPU_ES ) )
851 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
852 while( p_dr && ( p_dr->i_tag != 0x0a ) )
856 dvbpsi_iso639_dr_t *p_decoded =
857 dvbpsi_DecodeISO639Dr( p_dr );
858 if( p_decoded->i_code_count > 0 )
860 const iso639_lang_t * p_iso;
861 p_iso = GetLang_2T(p_decoded->i_iso_639_code);
864 if(p_iso->psz_native_name[0])
865 strcpy( p_new_es->psz_desc,
866 p_iso->psz_native_name );
868 strcpy( p_new_es->psz_desc,
869 p_iso->psz_eng_name );
873 strncpy( p_new_es->psz_desc,
874 p_decoded->i_iso_639_code, 3 );
878 switch( p_es->i_type )
882 strcat( p_new_es->psz_desc, " (mpeg)" );
885 strcat( p_new_es->psz_desc, " (lpcm)" );
888 strcat( p_new_es->psz_desc, " (ac3)" );
896 /* if no program is selected :*/
897 if( !p_input->stream.p_selected_program )
899 pgrm_descriptor_t * p_pgrm_to_select;
900 u16 i_id = (u16)config_GetIntVariable( "program" );
902 if( i_id != 0 ) /* if user specified a program */
904 p_pgrm_to_select = input_FindProgram( p_input, i_id );
906 if( p_pgrm_to_select && p_pgrm_to_select == p_pgrm )
907 p_input->pf_set_program( p_input, p_pgrm_to_select );
910 p_input->pf_set_program( p_input, p_pgrm );
912 /* if the pmt belongs to the currently selected program, we
913 * reselect it to update its ES */
914 else if( p_pgrm == p_input->stream.p_selected_program )
916 p_input->pf_set_program( p_input, p_pgrm );
919 p_pgrm_demux->i_pmt_version = p_new_pmt->i_version;
920 p_input->stream.b_changed = 1;
922 vlc_mutex_unlock( &p_input->stream.stream_lock );