1 /*****************************************************************************
2 * mpeg_ts.c : Transport Stream input module for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2001 VideoLAN
5 * $Id: ts.c,v 1.3 2002/08/08 22:28:22 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 *****************************************************************************/
33 #include <vlc/input.h>
37 #if defined MODULE_NAME_IS_ts_dvbpsi
38 # ifdef HAVE_DVBPSI_DR_H
39 # include <dvbpsi/dvbpsi.h>
40 # include <dvbpsi/descriptor.h>
41 # include <dvbpsi/pat.h>
42 # include <dvbpsi/pmt.h>
43 # include <dvbpsi/dr.h>
46 # include "descriptor.h"
47 # include "tables/pat.h"
48 # include "tables/pmt.h"
49 # include "descriptors/dr.h"
55 /*****************************************************************************
57 *****************************************************************************/
58 #define TS_READ_ONCE 200
60 /*****************************************************************************
62 *****************************************************************************/
69 /*****************************************************************************
71 *****************************************************************************/
72 static int Activate ( vlc_object_t * );
73 static void Deactivate ( vlc_object_t * );
74 static int Demux ( input_thread_t * );
76 #if defined MODULE_NAME_IS_ts
77 static void TSDemuxPSI ( input_thread_t *, data_packet_t *,
78 es_descriptor_t *, vlc_bool_t );
79 static void TSDecodePAT( input_thread_t *, es_descriptor_t *);
80 static void TSDecodePMT( input_thread_t *, es_descriptor_t *);
81 #define PSI_CALLBACK TSDemuxPSI
82 #elif defined MODULE_NAME_IS_ts_dvbpsi
83 static void TS_DVBPSI_DemuxPSI ( input_thread_t *, data_packet_t *,
84 es_descriptor_t *, vlc_bool_t );
85 static void TS_DVBPSI_HandlePAT ( input_thread_t *, dvbpsi_pat_t * );
86 static void TS_DVBPSI_HandlePMT ( input_thread_t *, dvbpsi_pmt_t * );
87 #define PSI_CALLBACK TS_DVBPSI_DemuxPSI
90 /*****************************************************************************
92 *****************************************************************************/
94 #if defined MODULE_NAME_IS_ts
95 set_description( _("ISO 13818-1 MPEG Transport Stream input") );
96 set_capability( "demux", 160 );
98 #elif defined MODULE_NAME_IS_ts_dvbpsi
99 set_description( _("ISO 13818-1 MPEG Transport Stream input (libdvbpsi)") );
100 set_capability( "demux", 170 );
101 add_shortcut( "ts_dvbpsi" );
103 set_callbacks( Activate, Deactivate );
106 /*****************************************************************************
107 * Activate: initialize TS structures
108 *****************************************************************************/
109 static int Activate( vlc_object_t * p_this )
111 input_thread_t * p_input = (input_thread_t *)p_this;
112 demux_sys_t * p_demux;
113 es_descriptor_t * p_pat_es;
114 es_ts_data_t * p_demux_data;
115 stream_ts_data_t * p_stream_data;
118 /* Set the demux function */
119 p_input->pf_demux = Demux;
121 /* Initialize access plug-in structures. */
122 if( p_input->i_mtu == 0 )
125 p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
128 /* Have a peep at the show. */
129 if( input_Peek( p_input, &p_peek, 1 ) < 1 )
131 msg_Err( p_input, "cannot peek()" );
135 if( *p_peek != TS_SYNC_CODE )
137 if( *p_input->psz_demux && !strncmp( p_input->psz_demux, "ts", 3 ) )
140 msg_Err( p_input, "this does not look like a TS stream, continuing" );
144 msg_Warn( p_input, "TS module discarded (no sync)" );
149 /* Adapt the bufsize for our only use. */
150 if( p_input->i_mtu != 0 )
152 /* Have minimum granularity to avoid bottlenecks at the input level. */
153 p_input->i_bufsize = (p_input->i_mtu / TS_PACKET_SIZE) * TS_PACKET_SIZE;
156 p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );
157 if( p_demux == NULL )
162 p_input->p_private = (void*)&p_demux->mpeg;
163 p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );
164 if( p_demux->p_module == NULL )
166 free( p_input->p_demux_data );
170 vlc_mutex_lock( &p_input->stream.stream_lock );
172 if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
174 module_Unneed( p_input, p_demux->p_module );
175 free( p_input->p_demux_data );
179 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
180 p_stream_data->i_pat_version = PAT_UNINITIALIZED ;
182 #ifdef MODULE_NAME_IS_ts_dvbpsi
183 p_stream_data->p_pat_handle = (dvbpsi_handle *)
184 dvbpsi_AttachPAT( (dvbpsi_pat_callback) &TS_DVBPSI_HandlePAT, p_input );
186 if( p_stream_data->p_pat_handle == NULL )
188 msg_Err( p_input, "could not create PAT decoder" );
189 module_Unneed( p_input, p_demux->p_module );
190 free( p_input->p_demux_data );
195 /* We'll have to catch the PAT in order to continue
196 * Then the input will catch the PMT and then the others ES
197 * The PAT es is indepedent of any program. */
198 p_pat_es = input_AddES( p_input, NULL,
199 0x00, sizeof( es_ts_data_t ) );
200 p_demux_data = (es_ts_data_t *)p_pat_es->p_demux_data;
201 p_demux_data->b_psi = 1;
202 p_demux_data->i_psi_type = PSI_IS_PAT;
203 p_demux_data->p_psi_section = malloc(sizeof(psi_section_t));
204 p_demux_data->p_psi_section->b_is_complete = 1;
206 vlc_mutex_unlock( &p_input->stream.stream_lock );
211 /*****************************************************************************
212 * Deactivate: deinitialize TS structures
213 *****************************************************************************/
214 static void Deactivate( vlc_object_t * p_this )
216 input_thread_t * p_input = (input_thread_t *)p_this;
218 module_Unneed( p_input, p_input->p_demux_data->p_module );
219 free( p_input->p_demux_data );
222 /*****************************************************************************
223 * Demux: reads and demuxes data packets
224 *****************************************************************************
225 * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
227 *****************************************************************************/
228 static int Demux( input_thread_t * p_input )
230 demux_sys_t * p_demux = p_input->p_demux_data;
231 int i_read_once = (p_input->i_mtu ?
232 p_input->i_bufsize / TS_PACKET_SIZE :
236 for( i = 0; i < i_read_once; i++ )
238 data_packet_t * p_data;
241 i_result = p_demux->mpeg.pf_read_ts( p_input, &p_data );
248 p_demux->mpeg.pf_demux_ts( p_input, p_data,
249 (psi_callback_t) &PSI_CALLBACK );
256 #if defined MODULE_NAME_IS_ts
258 * PSI demultiplexing and decoding without libdvbpsi
261 /*****************************************************************************
262 * DemuxPSI : makes up complete PSI data
263 *****************************************************************************/
264 static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data,
265 es_descriptor_t * p_es, vlc_bool_t b_unit_start )
267 es_ts_data_t * p_demux_data;
269 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
271 #define p_psi (p_demux_data->p_psi_section)
272 #define p (p_data->p_payload_start)
276 /* unit_start set to 1 -> presence of a pointer field
277 * (see ISO/IEC 13818 (2.4.4.2) which should be set to 0x00 */
278 if( (u8)p[0] != 0x00 )
281 "non-zero pointer field found, trying to continue" );
289 /* This is the begining of a new section */
291 if( ((u8)(p[1]) & 0xc0) != 0x80 )
293 msg_Warn( p_input, "invalid PSI packet" );
298 p_psi->i_section_length = ((p[1] & 0xF) << 8) | p[2];
299 p_psi->b_section_complete = 0;
300 p_psi->i_read_in_section = 0;
301 p_psi->i_section_number = (u8)p[6];
303 if( p_psi->b_is_complete || p_psi->i_section_number == 0 )
305 /* This is a new PSI packet */
306 p_psi->b_is_complete = 0;
308 p_psi->i_version_number = ( p[5] >> 1 ) & 0x1f;
309 p_psi->i_last_section_number = (u8)p[7];
311 /* We'll write at the begining of the buffer */
312 p_psi->p_current = p_psi->buffer;
316 if( p_psi->b_section_complete )
318 /* New Section of an already started PSI */
319 p_psi->b_section_complete = 0;
321 if( p_psi->i_version_number != (( p[5] >> 1 ) & 0x1f) )
324 "PSI version differs inside same PAT" );
327 if( p_psi->i_section_number + 1 != (u8)p[6] )
330 "PSI Section discontinuity, packet lost?" );
334 p_psi->i_section_number++;
338 msg_Warn( p_input, "got unexpected new PSI section" );
345 if( !p_psi->b_trash )
348 if( (p_data->p_payload_end - p) >=
349 ( p_psi->i_section_length - p_psi->i_read_in_section ) )
351 /* The end of the section is in this TS packet */
352 memcpy( p_psi->p_current, p,
353 (p_psi->i_section_length - p_psi->i_read_in_section) );
355 p_psi->b_section_complete = 1;
357 (p_psi->i_section_length - p_psi->i_read_in_section);
359 if( p_psi->i_section_number == p_psi->i_last_section_number )
361 /* This was the last section of PSI */
362 p_psi->b_is_complete = 1;
364 switch( p_demux_data->i_psi_type)
367 TSDecodePAT( p_input, p_es );
370 TSDecodePMT( p_input, p_es );
373 msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
379 memcpy( p_psi->buffer, p, p_data->p_payload_end - p );
380 p_psi->i_read_in_section += p_data->p_payload_end - p;
382 p_psi->p_current += p_data->p_payload_end - p;
389 input_DeletePacket( p_input->p_method_data, p_data );
394 /*****************************************************************************
395 * DecodePAT : Decodes Programm association table and deal with it
396 *****************************************************************************/
397 static void TSDecodePAT( input_thread_t * p_input, es_descriptor_t * p_es )
399 stream_ts_data_t * p_stream_data;
400 es_ts_data_t * p_demux_data;
402 pgrm_descriptor_t * p_pgrm;
403 es_descriptor_t * p_current_es;
404 byte_t * p_current_data;
406 int i_section_length, i_program_id, i_pmt_pid;
407 int i_loop, i_current_section;
409 vlc_bool_t b_changed = 0;
411 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
412 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
414 #define p_psi (p_demux_data->p_psi_section)
416 /* Not so fast, Mike ! If the PAT version has changed, we first check
417 * that its content has really changed before doing anything */
418 if( p_stream_data->i_pat_version != p_psi->i_version_number )
420 int i_programs = p_input->stream.i_pgrm_number;
422 p_current_data = p_psi->buffer;
426 i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
428 i_current_section = (u8)p_current_data[6];
431 ( i_loop < (i_section_length - 9) / 4 ) && !b_changed;
434 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
435 | *(p_current_data + i_loop * 4 + 9);
436 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
438 | *(p_current_data + i_loop * 4 + 11);
442 if( (p_pgrm = input_FindProgram( p_input, i_program_id ))
443 && (p_current_es = input_FindES( p_input, i_pmt_pid ))
444 && p_current_es->p_pgrm == p_pgrm
445 && p_current_es->i_id == i_pmt_pid
446 && ((es_ts_data_t *)p_current_es->p_demux_data)->b_psi
447 && ((es_ts_data_t *)p_current_es->p_demux_data)
448 ->i_psi_type == PSI_IS_PMT )
459 p_current_data += 3 + i_section_length;
461 } while( ( i_current_section < p_psi->i_last_section_number )
464 /* If we didn't find the expected amount of programs, the PAT has
465 * changed. Otherwise, it only changed if b_changed is already != 0 */
466 b_changed = b_changed || i_programs;
471 /* PAT has changed. We are going to delete all programs and
472 * create new ones. We chose not to only change what was needed
473 * as a PAT change may mean the stream is radically changing and
474 * this is a secure method to avoid crashes */
475 es_ts_data_t * p_es_demux;
476 pgrm_ts_data_t * p_pgrm_demux;
478 p_current_data = p_psi->buffer;
480 /* Delete all programs */
481 while( p_input->stream.i_pgrm_number )
483 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
488 i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
490 i_current_section = (u8)p_current_data[6];
492 for( i_loop = 0; i_loop < (i_section_length - 9) / 4 ; i_loop++ )
494 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
495 | *(p_current_data + i_loop * 4 + 9);
496 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
498 | *(p_current_data + i_loop * 4 + 11);
500 /* If program = 0, we're having info about NIT not PMT */
503 /* Add this program */
504 p_pgrm = input_AddProgram( p_input, i_program_id,
505 sizeof( pgrm_ts_data_t ) );
507 /* whatis the PID of the PMT of this program */
508 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
509 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
511 /* Add the PMT ES to this program */
512 p_current_es = input_AddES( p_input, p_pgrm,(u16)i_pmt_pid,
513 sizeof( es_ts_data_t) );
514 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
515 p_es_demux->b_psi = 1;
516 p_es_demux->i_psi_type = PSI_IS_PMT;
518 p_es_demux->p_psi_section =
519 malloc( sizeof( psi_section_t ) );
520 p_es_demux->p_psi_section->b_is_complete = 0;
524 p_current_data += 3 + i_section_length;
526 } while( i_current_section < p_psi->i_last_section_number );
528 /* Go to the beginning of the next section */
529 p_stream_data->i_pat_version = p_psi->i_version_number;
536 /*****************************************************************************
537 * DecodePMT : decode a given Program Stream Map
538 * ***************************************************************************
539 * When the PMT changes, it may mean a deep change in the stream, and it is
540 * careful to delete the ES and add them again. If the PMT doesn't change,
541 * there no need to do anything.
542 *****************************************************************************/
543 static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es )
546 pgrm_ts_data_t * p_pgrm_data;
547 es_ts_data_t * p_demux_data;
549 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
550 p_pgrm_data = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;
552 #define p_psi (p_demux_data->p_psi_section)
554 if( p_psi->i_version_number != p_pgrm_data->i_pmt_version )
556 es_descriptor_t * p_new_es;
557 es_ts_data_t * p_es_demux;
558 byte_t * p_current_data, * p_current_section;
559 int i_section_length,i_current_section;
560 int i_prog_info_length, i_loop;
561 int i_es_info_length, i_pid, i_stream_type;
563 p_current_section = p_psi->buffer;
564 p_current_data = p_psi->buffer;
566 p_pgrm_data->i_pcr_pid = ( ((u32)*(p_current_section + 8) & 0x1F) << 8 ) |
567 *(p_current_section + 9);
570 /* Lock stream information */
571 vlc_mutex_lock( &p_input->stream.stream_lock );
573 /* Delete all ES in this program except the PSI. We start from the
574 * end because i_es_number gets decremented after each deletion. */
575 for( i_loop = p_es->p_pgrm->i_es_number ; i_loop ; )
578 p_es_demux = (es_ts_data_t *)
579 p_es->p_pgrm->pp_es[i_loop]->p_demux_data;
580 if ( ! p_es_demux->b_psi )
582 input_DelES( p_input, p_es->p_pgrm->pp_es[i_loop] );
586 /* Then add what we received in this PMT */
589 i_section_length = ( ((u32)*(p_current_data + 1) & 0xF) << 8 ) |
590 *(p_current_data + 2);
591 i_current_section = (u8)p_current_data[6];
592 i_prog_info_length = ( ((u32)*(p_current_data + 10) & 0xF) << 8 ) |
593 *(p_current_data + 11);
595 /* For the moment we ignore program descriptors */
596 p_current_data += 12 + i_prog_info_length;
598 /* The end of the section, before the CRC is at
599 * p_current_section + i_section_length -1 */
600 while( p_current_data < p_current_section + i_section_length -1 )
602 i_stream_type = (int)p_current_data[0];
603 i_pid = ( ((u32)*(p_current_data + 1) & 0x1F) << 8 ) |
604 *(p_current_data + 2);
605 i_es_info_length = ( ((u32)*(p_current_data + 3) & 0xF) << 8 ) |
606 *(p_current_data + 4);
608 /* Add this ES to the program */
609 p_new_es = input_AddES( p_input, p_es->p_pgrm,
610 (u16)i_pid, sizeof( es_ts_data_t ) );
612 /* Tell the interface what kind of stream it is and select
613 * the required ones */
615 switch( i_stream_type )
619 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','v');
620 p_new_es->i_cat = VIDEO_ES;
624 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','a');
625 p_new_es->i_cat = AUDIO_ES;
628 p_new_es->i_fourcc = VLC_FOURCC('l','p','c','m');
629 p_new_es->i_stream_id = 0xBD;
630 p_new_es->i_cat = AUDIO_ES;
633 p_new_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
634 p_new_es->i_stream_id = 0xBD;
635 p_new_es->i_cat = AUDIO_ES;
637 /* Not sure this one is fully specification-compliant */
639 p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
640 p_new_es->i_stream_id = 0xBD;
641 p_new_es->i_cat = SPU_ES;
644 p_new_es->i_fourcc = 0;
645 p_new_es->i_cat = UNKNOWN_ES;
650 p_current_data += 5 + i_es_info_length;
653 /* Go to the beginning of the next section*/
654 p_current_data += 3 + i_section_length;
658 } while( i_current_section < p_psi->i_last_section_number );
660 p_pgrm_data->i_pmt_version = p_psi->i_version_number;
662 /* if no program is selected :*/
663 if( !p_input->stream.p_selected_program )
665 pgrm_descriptor_t * p_pgrm_to_select;
666 u16 i_id = (u16)config_GetInt( p_input, "program" );
668 if( i_id != 0 ) /* if user specified a program */
670 p_pgrm_to_select = input_FindProgram( p_input, i_id );
672 if( p_pgrm_to_select && p_pgrm_to_select == p_es->p_pgrm )
673 p_input->pf_set_program( p_input, p_pgrm_to_select );
676 p_input->pf_set_program( p_input, p_es->p_pgrm );
679 /* inform interface that stream has changed */
680 p_input->stream.b_changed = 1;
682 vlc_mutex_unlock( &p_input->stream.stream_lock );
688 #elif defined MODULE_NAME_IS_ts_dvbpsi
690 * PSI Decoding using libdvbcss
693 /*****************************************************************************
694 * DemuxPSI : send the PSI to the right libdvbpsi decoder
695 *****************************************************************************/
696 static void TS_DVBPSI_DemuxPSI( input_thread_t * p_input,
697 data_packet_t * p_data,
698 es_descriptor_t * p_es,
699 vlc_bool_t b_unit_start )
701 es_ts_data_t * p_es_demux_data;
702 pgrm_ts_data_t * p_pgrm_demux_data;
703 stream_ts_data_t * p_stream_demux_data;
705 p_es_demux_data = ( es_ts_data_t * ) p_es->p_demux_data;
706 p_stream_demux_data = ( stream_ts_data_t * ) p_input->stream.p_demux_data;
708 switch( p_es_demux_data->i_psi_type)
712 ( dvbpsi_handle ) p_stream_demux_data->p_pat_handle,
713 p_data->p_demux_start );
716 p_pgrm_demux_data = ( pgrm_ts_data_t * )p_es->p_pgrm->p_demux_data;
718 ( dvbpsi_handle ) p_pgrm_demux_data->p_pmt_handle,
719 p_data->p_demux_start );
722 msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
725 input_DeletePacket( p_input->p_method_data, p_data );
728 /*****************************************************************************
729 * HandlePAT: will treat a PAT returned by dvbpsi
730 *****************************************************************************/
732 void TS_DVBPSI_HandlePAT( input_thread_t * p_input, dvbpsi_pat_t * p_new_pat )
734 dvbpsi_pat_program_t * p_pgrm;
735 pgrm_descriptor_t * p_new_pgrm;
736 pgrm_ts_data_t * p_pgrm_demux;
737 es_descriptor_t * p_current_es;
738 es_ts_data_t * p_es_demux;
739 stream_ts_data_t * p_stream_data;
741 vlc_mutex_lock( &p_input->stream.stream_lock );
743 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
745 if ( !p_new_pat->b_current_next ||
746 p_stream_data->i_pat_version == PAT_UNINITIALIZED )
748 /* Delete all programs */
749 while( p_input->stream.i_pgrm_number )
751 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
754 /* treat the new programs list */
755 p_pgrm = p_new_pat->p_first_program;
759 /* If program = 0, we're having info about NIT not PMT */
760 if( p_pgrm->i_number )
762 /* Add this program */
763 p_new_pgrm = input_AddProgram( p_input, p_pgrm->i_number,
764 sizeof( pgrm_ts_data_t ) );
766 p_pgrm_demux = (pgrm_ts_data_t *)p_new_pgrm->p_demux_data;
767 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
769 /* Add the PMT ES to this program */
770 p_current_es = input_AddES( p_input, p_new_pgrm,
772 sizeof( es_ts_data_t) );
773 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
774 p_es_demux->b_psi = 1;
775 p_es_demux->i_psi_type = PSI_IS_PMT;
777 p_es_demux->p_psi_section = malloc( sizeof( psi_section_t ) );
778 if ( p_es_demux->p_psi_section == NULL )
780 msg_Err( p_input, "out of memory" );
781 p_input->b_error = 1;
785 p_es_demux->p_psi_section->b_is_complete = 0;
787 /* Create a PMT decoder */
788 p_pgrm_demux->p_pmt_handle = (dvbpsi_handle *)
789 dvbpsi_AttachPMT( p_pgrm->i_number,
790 (dvbpsi_pmt_callback) &TS_DVBPSI_HandlePMT,
793 if( p_pgrm_demux->p_pmt_handle == NULL )
795 msg_Err( p_input, "could not create PMT decoder" );
796 p_input->b_error = 1;
801 p_pgrm = p_pgrm->p_next;
804 p_stream_data->i_pat_version = p_new_pat->i_version;
806 vlc_mutex_unlock( &p_input->stream.stream_lock );
809 /*****************************************************************************
810 * HandlePMT: will treat a PMT returned by dvbpsi
811 *****************************************************************************/
812 void TS_DVBPSI_HandlePMT( input_thread_t * p_input, dvbpsi_pmt_t * p_new_pmt )
814 dvbpsi_pmt_es_t * p_es;
815 pgrm_descriptor_t * p_pgrm;
816 es_descriptor_t * p_new_es;
817 pgrm_ts_data_t * p_pgrm_demux;
819 vlc_mutex_lock( &p_input->stream.stream_lock );
821 p_pgrm = input_FindProgram( p_input, p_new_pmt->i_program_number );
825 msg_Warn( p_input, "PMT of unreferenced program found" );
829 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
830 p_pgrm_demux->i_pcr_pid = p_new_pmt->i_pcr_pid;
832 if( !p_new_pmt->b_current_next ||
833 p_pgrm_demux->i_pmt_version == PMT_UNINITIALIZED )
835 p_es = p_new_pmt->p_first_es;
839 p_new_es = input_AddES( p_input, p_pgrm,
840 (u16)p_es->i_pid, sizeof( es_ts_data_t ) );
841 if( p_new_es == NULL )
843 msg_Err( p_input, "could not add ES %d", p_es->i_pid );
844 p_input->b_error = 1;
848 switch( p_es->i_type )
852 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','v');
853 p_new_es->i_cat = VIDEO_ES;
857 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','a');
858 p_new_es->i_cat = AUDIO_ES;
861 p_new_es->i_fourcc = VLC_FOURCC('l','p','c','m');
862 p_new_es->i_cat = AUDIO_ES;
863 p_new_es->i_stream_id = 0xBD;
866 p_new_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
867 p_new_es->i_cat = AUDIO_ES;
868 p_new_es->i_stream_id = 0xBD;
871 p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
872 p_new_es->i_cat = SPU_ES;
873 p_new_es->i_stream_id = 0xBD;
876 p_new_es->i_fourcc = 0;
877 p_new_es->i_cat = UNKNOWN_ES;
880 if( ( p_new_es->i_cat == AUDIO_ES )
881 || (p_new_es->i_cat == SPU_ES ) )
883 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
884 while( p_dr && ( p_dr->i_tag != 0x0a ) )
888 dvbpsi_iso639_dr_t *p_decoded =
889 dvbpsi_DecodeISO639Dr( p_dr );
890 if( p_decoded->i_code_count > 0 )
892 const iso639_lang_t * p_iso;
893 p_iso = GetLang_2T((char*)p_decoded->i_iso_639_code);
896 if(p_iso->psz_native_name[0])
897 strcpy( p_new_es->psz_desc,
898 p_iso->psz_native_name );
900 strcpy( p_new_es->psz_desc,
901 p_iso->psz_eng_name );
905 strncpy( p_new_es->psz_desc,
906 p_decoded->i_iso_639_code, 3 );
910 switch( p_es->i_type )
914 strcat( p_new_es->psz_desc, " (mpeg)" );
917 strcat( p_new_es->psz_desc, " (lpcm)" );
920 strcat( p_new_es->psz_desc, " (A52)" );
928 /* if no program is selected :*/
929 if( !p_input->stream.p_selected_program )
931 pgrm_descriptor_t * p_pgrm_to_select;
932 u16 i_id = (u16)config_GetInt( p_input, "program" );
934 if( i_id != 0 ) /* if user specified a program */
936 p_pgrm_to_select = input_FindProgram( p_input, i_id );
938 if( p_pgrm_to_select && p_pgrm_to_select == p_pgrm )
939 p_input->pf_set_program( p_input, p_pgrm_to_select );
942 p_input->pf_set_program( p_input, p_pgrm );
944 /* if the pmt belongs to the currently selected program, we
945 * reselect it to update its ES */
946 else if( p_pgrm == p_input->stream.p_selected_program )
948 p_input->pf_set_program( p_input, p_pgrm );
951 p_pgrm_demux->i_pmt_version = p_new_pmt->i_version;
952 p_input->stream.b_changed = 1;
954 vlc_mutex_unlock( &p_input->stream.stream_lock );