1 /*****************************************************************************
2 * mpeg_ts.c : Transport Stream input module for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2001 VideoLAN
5 * $Id: ts.c,v 1.20 2003/03/18 23:59:07 massiot 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.")
103 #define BUGGY_PSI_TEXT N_("buggy PSI")
104 #define BUGGY_PSI_LONGTEXT N_( \
105 "If you have a stream whose PSI packets do not feature incremented " \
106 "continuity counters, select this option.")
109 #if defined MODULE_NAME_IS_ts
110 set_description( _("ISO 13818-1 MPEG Transport Stream input") );
111 set_capability( "demux", 160 );
112 add_shortcut( "ts" );
113 #elif defined MODULE_NAME_IS_ts_dvbpsi
114 set_description( _("ISO 13818-1 MPEG Transport Stream input (libdvbpsi)") );
115 set_capability( "demux", 170 );
116 add_shortcut( "ts_dvbpsi" );
118 add_category_hint( N_("Miscellaneous"), NULL, VLC_TRUE );
119 add_bool( "vls-backwards-compat", 0, NULL,
120 VLS_BACKWARDS_COMPAT_TEXT, VLS_BACKWARDS_COMPAT_LONGTEXT, VLC_TRUE );
121 add_bool( "buggy-psi", 0, NULL, BUGGY_PSI_TEXT, BUGGY_PSI_LONGTEXT, VLC_TRUE );
122 set_callbacks( Activate, Deactivate );
125 /*****************************************************************************
126 * Activate: initialize TS structures
127 *****************************************************************************/
128 static int Activate( vlc_object_t * p_this )
130 input_thread_t * p_input = (input_thread_t *)p_this;
131 demux_sys_t * p_demux;
132 es_descriptor_t * p_pat_es;
133 es_ts_data_t * p_demux_data;
134 stream_ts_data_t * p_stream_data;
137 /* Set the demux function */
138 p_input->pf_demux = Demux;
140 /* Initialize access plug-in structures. */
141 if( p_input->i_mtu == 0 )
144 p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
147 /* Have a peep at the show. */
148 if( input_Peek( p_input, &p_peek, 1 ) < 1 )
150 msg_Err( p_input, "cannot peek()" );
154 if( *p_peek != TS_SYNC_CODE )
156 if( *p_input->psz_demux && ( !strncmp( p_input->psz_demux, "ts", 3 )
157 || !strncmp( p_input->psz_demux, "ts_dvbpsi", 10 ) ) )
160 msg_Err( p_input, "this does not look like a TS stream, continuing" );
164 msg_Warn( p_input, "TS module discarded (no sync)" );
169 /* Adapt the bufsize for our only use. */
170 if( p_input->i_mtu != 0 )
172 /* Have minimum granularity to avoid bottlenecks at the input level. */
173 p_input->i_bufsize = (p_input->i_mtu / TS_PACKET_SIZE) * TS_PACKET_SIZE;
176 p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );
177 if( p_demux == NULL )
182 p_input->p_private = (void*)&p_demux->mpeg;
183 p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );
184 if( p_demux->p_module == NULL )
186 free( p_input->p_demux_data );
190 vlc_mutex_lock( &p_input->stream.stream_lock );
192 if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
194 module_Unneed( p_input, p_demux->p_module );
195 free( p_input->p_demux_data );
199 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
200 p_stream_data->i_pat_version = PAT_UNINITIALIZED ;
201 p_stream_data->b_buggy_psi = config_GetInt( p_input, "buggy-psi" );
203 #ifdef MODULE_NAME_IS_ts_dvbpsi
204 p_stream_data->p_pat_handle = (dvbpsi_handle *)
205 dvbpsi_AttachPAT( (dvbpsi_pat_callback) &TS_DVBPSI_HandlePAT, p_input );
207 if( p_stream_data->p_pat_handle == NULL )
209 msg_Err( p_input, "could not create PAT decoder" );
210 module_Unneed( p_input, p_demux->p_module );
211 free( p_input->p_demux_data );
216 /* We'll have to catch the PAT in order to continue
217 * Then the input will catch the PMT and then the others ES
218 * The PAT es is indepedent of any program. */
219 p_pat_es = input_AddES( p_input, NULL,
220 0x00, sizeof( es_ts_data_t ) );
221 p_demux_data = (es_ts_data_t *)p_pat_es->p_demux_data;
222 p_demux_data->b_psi = 1;
223 p_demux_data->i_psi_type = PSI_IS_PAT;
224 p_demux_data->p_psi_section = malloc(sizeof(psi_section_t));
225 p_demux_data->p_psi_section->b_is_complete = 1;
226 p_demux_data->i_continuity_counter = 0xFF;
228 vlc_mutex_unlock( &p_input->stream.stream_lock );
233 /*****************************************************************************
234 * Deactivate: deinitialize TS structures
235 *****************************************************************************/
236 static void Deactivate( vlc_object_t * p_this )
238 input_thread_t * p_input = (input_thread_t *)p_this;
240 module_Unneed( p_input, p_input->p_demux_data->p_module );
241 free( p_input->p_demux_data );
244 /*****************************************************************************
245 * Demux: reads and demuxes data packets
246 *****************************************************************************
247 * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
249 *****************************************************************************/
250 static int Demux( input_thread_t * p_input )
252 demux_sys_t * p_demux = p_input->p_demux_data;
253 int i_read_once = (p_input->i_mtu ?
254 p_input->i_bufsize / TS_PACKET_SIZE :
258 for( i = 0; i < i_read_once; i++ )
260 data_packet_t * p_data;
263 i_result = p_demux->mpeg.pf_read_ts( p_input, &p_data );
270 p_demux->mpeg.pf_demux_ts( p_input, p_data,
271 (psi_callback_t) &PSI_CALLBACK );
278 #if defined MODULE_NAME_IS_ts
280 * PSI demultiplexing and decoding without libdvbpsi
283 /*****************************************************************************
284 * DemuxPSI : makes up complete PSI data
285 *****************************************************************************/
286 static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data,
287 es_descriptor_t * p_es, vlc_bool_t b_unit_start )
289 es_ts_data_t * p_demux_data;
291 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
293 #define p_psi (p_demux_data->p_psi_section)
294 #define p (p_data->p_payload_start)
298 /* unit_start set to 1 -> presence of a pointer field
299 * (see ISO/IEC 13818 (2.4.4.2) which should be set to 0x00 */
300 if( (u8)p[0] != 0x00 )
303 "non-zero pointer field found, trying to continue" );
311 /* This is the begining of a new section */
313 if( ((u8)(p[1]) & 0xc0) != 0x80 )
315 msg_Warn( p_input, "invalid PSI packet" );
320 p_psi->i_section_length = ((p[1] & 0xF) << 8) | p[2];
321 p_psi->b_section_complete = 0;
322 p_psi->i_read_in_section = 0;
323 p_psi->i_section_number = (u8)p[6];
325 if( p_psi->b_is_complete || p_psi->i_section_number == 0 )
327 /* This is a new PSI packet */
328 p_psi->b_is_complete = 0;
330 p_psi->i_version_number = ( p[5] >> 1 ) & 0x1f;
331 p_psi->i_last_section_number = (u8)p[7];
333 /* We'll write at the begining of the buffer */
334 p_psi->p_current = p_psi->buffer;
338 if( p_psi->b_section_complete )
340 /* New Section of an already started PSI */
341 p_psi->b_section_complete = 0;
343 if( p_psi->i_version_number != (( p[5] >> 1 ) & 0x1f) )
346 "PSI version differs inside same PAT" );
349 if( p_psi->i_section_number + 1 != (u8)p[6] )
352 "PSI Section discontinuity, packet lost?" );
356 p_psi->i_section_number++;
360 msg_Warn( p_input, "got unexpected new PSI section" );
367 if( !p_psi->b_trash )
370 if( (p_data->p_payload_end - p) >=
371 ( p_psi->i_section_length - p_psi->i_read_in_section ) )
373 /* The end of the section is in this TS packet */
374 memcpy( p_psi->p_current, p,
375 (p_psi->i_section_length - p_psi->i_read_in_section) );
377 p_psi->b_section_complete = 1;
379 (p_psi->i_section_length - p_psi->i_read_in_section);
381 if( p_psi->i_section_number == p_psi->i_last_section_number )
383 /* This was the last section of PSI */
384 p_psi->b_is_complete = 1;
386 switch( p_demux_data->i_psi_type)
389 TSDecodePAT( p_input, p_es );
392 TSDecodePMT( p_input, p_es );
395 msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
401 memcpy( p_psi->buffer, p, p_data->p_payload_end - p );
402 p_psi->i_read_in_section += p_data->p_payload_end - p;
404 p_psi->p_current += p_data->p_payload_end - p;
411 input_DeletePacket( p_input->p_method_data, p_data );
416 /*****************************************************************************
417 * DecodePAT : Decodes Programm association table and deal with it
418 *****************************************************************************/
419 static void TSDecodePAT( input_thread_t * p_input, es_descriptor_t * p_es )
421 stream_ts_data_t * p_stream_data;
422 es_ts_data_t * p_demux_data;
424 pgrm_descriptor_t * p_pgrm;
425 es_descriptor_t * p_current_es;
426 byte_t * p_current_data;
428 int i_section_length, i_program_id, i_pmt_pid;
429 int i_loop, i_current_section;
431 vlc_bool_t b_changed = 0;
433 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
434 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
436 #define p_psi (p_demux_data->p_psi_section)
438 /* Not so fast, Mike ! If the PAT version has changed, we first check
439 * that its content has really changed before doing anything */
440 if( p_stream_data->i_pat_version != p_psi->i_version_number )
442 int i_programs = p_input->stream.i_pgrm_number;
444 p_current_data = p_psi->buffer;
448 i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
450 i_current_section = (u8)p_current_data[6];
453 ( i_loop < (i_section_length - 9) / 4 ) && !b_changed;
456 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
457 | *(p_current_data + i_loop * 4 + 9);
458 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
460 | *(p_current_data + i_loop * 4 + 11);
464 if( (p_pgrm = input_FindProgram( p_input, i_program_id ))
465 && (p_current_es = input_FindES( p_input, i_pmt_pid ))
466 && p_current_es->p_pgrm == p_pgrm
467 && p_current_es->i_id == i_pmt_pid
468 && ((es_ts_data_t *)p_current_es->p_demux_data)->b_psi
469 && ((es_ts_data_t *)p_current_es->p_demux_data)
470 ->i_psi_type == PSI_IS_PMT )
481 p_current_data += 3 + i_section_length;
483 } while( ( i_current_section < p_psi->i_last_section_number )
486 /* If we didn't find the expected amount of programs, the PAT has
487 * changed. Otherwise, it only changed if b_changed is already != 0 */
488 b_changed = b_changed || i_programs;
493 /* PAT has changed. We are going to delete all programs and
494 * create new ones. We chose not to only change what was needed
495 * as a PAT change may mean the stream is radically changing and
496 * this is a secure method to avoid crashes */
497 es_ts_data_t * p_es_demux;
498 pgrm_ts_data_t * p_pgrm_demux;
500 p_current_data = p_psi->buffer;
502 /* Delete all programs */
503 while( p_input->stream.i_pgrm_number )
505 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
510 i_section_length = ((u32)(p_current_data[1] & 0xF) << 8) |
512 i_current_section = (u8)p_current_data[6];
514 for( i_loop = 0; i_loop < (i_section_length - 9) / 4 ; i_loop++ )
516 i_program_id = ( (u32)*(p_current_data + i_loop * 4 + 8) << 8 )
517 | *(p_current_data + i_loop * 4 + 9);
518 i_pmt_pid = ( ((u32)*(p_current_data + i_loop * 4 + 10) & 0x1F)
520 | *(p_current_data + i_loop * 4 + 11);
522 /* If program = 0, we're having info about NIT not PMT */
525 /* Add this program */
526 p_pgrm = input_AddProgram( p_input, i_program_id,
527 sizeof( pgrm_ts_data_t ) );
529 /* whatis the PID of the PMT of this program */
530 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
531 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
533 /* Add the PMT ES to this program */
534 p_current_es = input_AddES( p_input, p_pgrm,(u16)i_pmt_pid,
535 sizeof( es_ts_data_t) );
536 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
537 p_es_demux->b_psi = 1;
538 p_es_demux->i_psi_type = PSI_IS_PMT;
540 p_es_demux->p_psi_section =
541 malloc( sizeof( psi_section_t ) );
542 p_es_demux->p_psi_section->b_is_complete = 0;
543 p_es_demux->i_continuity_counter = 0xFF;
547 p_current_data += 3 + i_section_length;
549 } while( i_current_section < p_psi->i_last_section_number );
551 /* Go to the beginning of the next section */
552 p_stream_data->i_pat_version = p_psi->i_version_number;
559 /*****************************************************************************
560 * DecodePMT : decode a given Program Stream Map
561 * ***************************************************************************
562 * When the PMT changes, it may mean a deep change in the stream, and it is
563 * careful to delete the ES and add them again. If the PMT doesn't change,
564 * there no need to do anything.
565 *****************************************************************************/
566 static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es )
569 pgrm_ts_data_t * p_pgrm_data;
570 es_ts_data_t * p_demux_data;
571 vlc_bool_t b_vls_compat = config_GetInt( p_input, "vls-backwards-compat" );
573 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
574 p_pgrm_data = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;
576 #define p_psi (p_demux_data->p_psi_section)
578 if( p_psi->i_version_number != p_pgrm_data->i_pmt_version )
580 es_descriptor_t * p_new_es;
581 es_ts_data_t * p_es_demux;
582 byte_t * p_current_data, * p_current_section;
583 int i_section_length,i_current_section;
584 int i_prog_info_length, i_loop;
585 int i_es_info_length, i_pid, i_stream_type;
587 p_current_section = p_psi->buffer;
588 p_current_data = p_psi->buffer;
590 p_pgrm_data->i_pcr_pid = ( ((u32)*(p_current_section + 8) & 0x1F) << 8 ) |
591 *(p_current_section + 9);
594 /* Lock stream information */
595 vlc_mutex_lock( &p_input->stream.stream_lock );
597 /* Delete all ES in this program except the PSI. We start from the
598 * end because i_es_number gets decremented after each deletion. */
599 for( i_loop = p_es->p_pgrm->i_es_number ; i_loop ; )
602 p_es_demux = (es_ts_data_t *)
603 p_es->p_pgrm->pp_es[i_loop]->p_demux_data;
604 if ( ! p_es_demux->b_psi )
606 input_DelES( p_input, p_es->p_pgrm->pp_es[i_loop] );
610 /* Then add what we received in this PMT */
613 i_section_length = ( ((u32)*(p_current_data + 1) & 0xF) << 8 ) |
614 *(p_current_data + 2);
615 i_current_section = (u8)p_current_data[6];
616 i_prog_info_length = ( ((u32)*(p_current_data + 10) & 0xF) << 8 ) |
617 *(p_current_data + 11);
619 /* For the moment we ignore program descriptors */
620 p_current_data += 12 + i_prog_info_length;
622 /* The end of the section, before the CRC is at
623 * p_current_section + i_section_length -1 */
624 while( p_current_data < p_current_section + i_section_length -1 )
626 i_stream_type = (int)p_current_data[0];
627 i_pid = ( ((u32)*(p_current_data + 1) & 0x1F) << 8 ) |
628 *(p_current_data + 2);
629 i_es_info_length = ( ((u32)*(p_current_data + 3) & 0xF) << 8 ) |
630 *(p_current_data + 4);
632 /* Add this ES to the program */
633 p_new_es = input_AddES( p_input, p_es->p_pgrm,
634 (u16)i_pid, sizeof( es_ts_data_t ) );
635 ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter = 0xFF;
637 /* Tell the interface what kind of stream it is and select
638 * the required ones */
640 switch( i_stream_type )
644 case MPEG2_MOTO_VIDEO_ES:
645 /* This isn't real, but we don't actually use
647 p_new_es->i_stream_id = 0xE0;
648 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','v');
649 p_new_es->i_cat = VIDEO_ES;
653 /* This isn't real, but we don't actually use
655 p_new_es->i_stream_id = 0xC0;
656 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','a');
657 p_new_es->i_cat = AUDIO_ES;
660 case A52DVB_AUDIO_ES:
662 p_new_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
664 p_new_es->i_fourcc = VLC_FOURCC('a','5','2','b');
665 p_new_es->i_stream_id = 0xBD;
666 p_new_es->i_cat = AUDIO_ES;
669 p_new_es->i_fourcc = VLC_FOURCC('l','p','c','m');
670 p_new_es->i_stream_id = 0xBD;
671 p_new_es->i_cat = AUDIO_ES;
675 p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
677 p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
678 p_new_es->i_stream_id = 0xBD;
679 p_new_es->i_cat = SPU_ES;
682 p_new_es->i_fourcc = VLC_FOURCC('s','d','d','s');
683 p_new_es->i_stream_id = 0xBD;
684 p_new_es->i_cat = AUDIO_ES;
687 p_new_es->i_fourcc = VLC_FOURCC('d','t','s',' ');
688 p_new_es->i_stream_id = 0xBD;
689 p_new_es->i_cat = AUDIO_ES;
691 /* 'b' stands for 'buggy' */
693 p_new_es->i_fourcc = VLC_FOURCC('a','5','2','b');
694 p_new_es->i_stream_id = 0xBD;
695 p_new_es->i_cat = AUDIO_ES;
698 p_new_es->i_fourcc = VLC_FOURCC('l','p','c','b');
699 p_new_es->i_stream_id = 0xBD;
700 p_new_es->i_cat = AUDIO_ES;
703 p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
704 p_new_es->i_stream_id = 0xBD;
705 p_new_es->i_cat = SPU_ES;
709 p_new_es->i_fourcc = 0;
710 p_new_es->i_cat = UNKNOWN_ES;
715 p_current_data += 5 + i_es_info_length;
718 /* Go to the beginning of the next section*/
719 p_current_data += 3 + i_section_length;
723 } while( i_current_section < p_psi->i_last_section_number );
725 p_pgrm_data->i_pmt_version = p_psi->i_version_number;
727 /* if no program is selected :*/
728 if( !p_input->stream.p_selected_program )
730 pgrm_descriptor_t * p_pgrm_to_select;
731 u16 i_id = (u16)config_GetInt( p_input, "program" );
733 if( i_id != 0 ) /* if user specified a program */
735 p_pgrm_to_select = input_FindProgram( p_input, i_id );
737 if( p_pgrm_to_select && p_pgrm_to_select == p_es->p_pgrm )
738 p_input->pf_set_program( p_input, p_pgrm_to_select );
741 p_input->pf_set_program( p_input, p_es->p_pgrm );
744 /* if the pmt belongs to the currently selected program, we
745 * reselect it to update its ES */
746 else if( p_es->p_pgrm == p_input->stream.p_selected_program )
748 p_input->pf_set_program( p_input, p_es->p_pgrm );
751 /* inform interface that stream has changed */
752 p_input->stream.b_changed = 1;
754 vlc_mutex_unlock( &p_input->stream.stream_lock );
760 #elif defined MODULE_NAME_IS_ts_dvbpsi
762 * PSI Decoding using libdvbpsi
765 /*****************************************************************************
766 * DemuxPSI : send the PSI to the right libdvbpsi decoder
767 *****************************************************************************/
768 static void TS_DVBPSI_DemuxPSI( input_thread_t * p_input,
769 data_packet_t * p_data,
770 es_descriptor_t * p_es,
771 vlc_bool_t b_unit_start )
773 es_ts_data_t * p_es_demux_data;
774 pgrm_ts_data_t * p_pgrm_demux_data;
775 stream_ts_data_t * p_stream_demux_data;
777 p_es_demux_data = (es_ts_data_t *)p_es->p_demux_data;
778 p_stream_demux_data = (stream_ts_data_t *) p_input->stream.p_demux_data;
780 switch( p_es_demux_data->i_psi_type)
784 (dvbpsi_handle)p_stream_demux_data->p_pat_handle,
785 p_data->p_demux_start );
788 p_pgrm_demux_data = ( pgrm_ts_data_t * )p_es->p_pgrm->p_demux_data;
790 (dvbpsi_handle)p_pgrm_demux_data->p_pmt_handle,
791 p_data->p_demux_start );
794 msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
797 input_DeletePacket( p_input->p_method_data, p_data );
799 /*****************************************************************************
800 * MP4 specific functions
801 *****************************************************************************/
802 static int MP4_DescriptorLength( int *pi_data, uint8_t **pp_data )
805 unsigned int i_len = 0;
811 i_len = ( i_len << 7 ) + ( i_b&0x7f );
817 static int MP4_GetByte( int *pi_data, uint8_t **pp_data )
832 static int MP4_GetWord( int *pi_data, uint8_t **pp_data )
835 i1 = MP4_GetByte( pi_data, pp_data );
836 i2 = MP4_GetByte( pi_data, pp_data );
837 return( ( i1 << 8 ) | i2 );
839 static int MP4_Get3Bytes( int *pi_data, uint8_t **pp_data )
842 i1 = MP4_GetByte( pi_data, pp_data );
843 i2 = MP4_GetByte( pi_data, pp_data );
844 i3 = MP4_GetByte( pi_data, pp_data );
845 return( ( i1 << 16 ) | ( i2 << 8) | i3 );
848 static uint32_t MP4_GetDWord( int *pi_data, uint8_t **pp_data )
851 i1 = MP4_GetWord( pi_data, pp_data );
852 i2 = MP4_GetWord( pi_data, pp_data );
853 return( ( i1 << 16 ) | i2 );
856 static char* MP4_GetURL( int *pi_data, uint8_t **pp_data )
861 i_url_len = MP4_GetByte( pi_data, pp_data );
862 url = malloc( i_url_len + 1 );
863 for( i = 0; i < i_url_len; i++ )
865 url[i] = MP4_GetByte( pi_data, pp_data );
867 url[i_url_len] = '\0';
871 static void MP4_IODParse( iod_descriptor_t *p_iod, int i_data, uint8_t *p_data )
879 fprintf( stderr, "\n************ IOD ************" );
880 for( i = 0; i < 255; i++ )
882 p_iod->es_descr[i].b_ok = 0;
891 p_iod->i_iod_label = MP4_GetByte( &i_data, &p_data );
892 fprintf( stderr, "\n* iod_label:%d", p_iod->i_iod_label );
893 fprintf( stderr, "\n* ===========" );
894 fprintf( stderr, "\n* tag:0x%x", p_data[0] );
896 if( MP4_GetByte( &i_data, &p_data ) != 0x02 )
898 fprintf( stderr, "\n ERR: tag != 0x02" );
902 i_iod_length = MP4_DescriptorLength( &i_data, &p_data );
903 fprintf( stderr, "\n* length:%d", i_iod_length );
904 if( i_iod_length > i_data )
906 i_iod_length = i_data;
909 p_iod->i_od_id = ( MP4_GetByte( &i_data, &p_data ) << 2 );
910 i_flags = MP4_GetByte( &i_data, &p_data );
911 p_iod->i_od_id |= i_flags >> 6;
912 b_url = ( i_flags >> 5 )&0x01;
914 fprintf( stderr, "\n* od_id:%d", p_iod->i_od_id );
915 fprintf( stderr, "\n* url flag:%d", b_url );
916 fprintf( stderr, "\n* includeInlineProfileLevel flag:%d", ( i_flags >> 4 )&0x01 );
920 p_iod->psz_url = MP4_GetURL( &i_data, &p_data );
921 fprintf( stderr, "\n* url string:%s", p_iod->psz_url );
922 fprintf( stderr, "\n*****************************\n" );
927 p_iod->psz_url = NULL;
930 p_iod->i_ODProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
931 p_iod->i_sceneProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
932 p_iod->i_audioProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
933 p_iod->i_visualProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
934 p_iod->i_graphicsProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
936 fprintf( stderr, "\n* ODProfileLevelIndication:%d", p_iod->i_ODProfileLevelIndication );
937 fprintf( stderr, "\n* sceneProfileLevelIndication:%d", p_iod->i_sceneProfileLevelIndication );
938 fprintf( stderr, "\n* audioProfileLevelIndication:%d", p_iod->i_audioProfileLevelIndication );
939 fprintf( stderr, "\n* visualProfileLevelIndication:%d", p_iod->i_visualProfileLevelIndication );
940 fprintf( stderr, "\n* graphicsProfileLevelIndication:%d", p_iod->i_graphicsProfileLevelIndication );
943 while( i_data > 0 && i_es_index < 255)
949 i_tag = MP4_GetByte( &i_data, &p_data );
950 i_length = MP4_DescriptorLength( &i_data, &p_data );
961 #define es_descr p_iod->es_descr[i_es_index]
962 int i_decoderConfigDescr_length;
963 fprintf( stderr, "\n* - ES_Descriptor length:%d", i_length );
966 es_descr.i_es_id = MP4_GetWord( &i_data, &p_data );
967 i_flags = MP4_GetByte( &i_data, &p_data );
968 es_descr.b_streamDependenceFlag = ( i_flags >> 7 )&0x01;
969 b_url = ( i_flags >> 6 )&0x01;
970 es_descr.b_OCRStreamFlag = ( i_flags >> 5 )&0x01;
971 es_descr.i_streamPriority = i_flags & 0x1f;
972 fprintf( stderr, "\n* * streamDependenceFlag:%d", es_descr.b_streamDependenceFlag );
973 fprintf( stderr, "\n* * OCRStreamFlag:%d", es_descr.b_OCRStreamFlag );
974 fprintf( stderr, "\n* * streamPriority:%d", es_descr.i_streamPriority );
976 if( es_descr.b_streamDependenceFlag )
978 es_descr.i_dependOn_es_id = MP4_GetWord( &i_data, &p_data );
979 fprintf( stderr, "\n* * dependOn_es_id:%d", es_descr.i_dependOn_es_id );
984 es_descr.psz_url = MP4_GetURL( &i_data, &p_data );
985 fprintf( stderr, "\n* url string:%s", es_descr.psz_url );
989 es_descr.psz_url = NULL;
992 if( es_descr.b_OCRStreamFlag )
994 es_descr.i_OCR_es_id = MP4_GetWord( &i_data, &p_data );
995 fprintf( stderr, "\n* * OCR_es_id:%d", es_descr.i_OCR_es_id );
998 if( MP4_GetByte( &i_data, &p_data ) != 0x04 )
1000 fprintf( stderr, "\n* ERR missing DecoderConfigDescr" );
1004 i_decoderConfigDescr_length = MP4_DescriptorLength( &i_data, &p_data );
1006 fprintf( stderr, "\n* - DecoderConfigDesc length:%d", i_decoderConfigDescr_length );
1007 #define dec_descr es_descr.dec_descr
1008 dec_descr.i_objectTypeIndication = MP4_GetByte( &i_data, &p_data );
1009 i_flags = MP4_GetByte( &i_data, &p_data );
1010 dec_descr.i_streamType = i_flags >> 2;
1011 dec_descr.b_upStream = ( i_flags >> 1 )&0x01;
1012 dec_descr.i_bufferSizeDB = MP4_Get3Bytes( &i_data, &p_data );
1013 dec_descr.i_maxBitrate = MP4_GetDWord( &i_data, &p_data );
1014 dec_descr.i_avgBitrate = MP4_GetDWord( &i_data, &p_data );
1015 fprintf( stderr, "\n* * objectTypeIndication:0x%x", dec_descr.i_objectTypeIndication );
1016 fprintf( stderr, "\n* * streamType:0x%x", dec_descr.i_streamType );
1017 fprintf( stderr, "\n* * upStream:%d", dec_descr.b_upStream );
1018 fprintf( stderr, "\n* * bufferSizeDB:%d", dec_descr.i_bufferSizeDB );
1019 fprintf( stderr, "\n* * maxBitrate:%d", dec_descr.i_maxBitrate );
1020 fprintf( stderr, "\n* * avgBitrate:%d", dec_descr.i_avgBitrate );
1021 if( i_decoderConfigDescr_length > 13 && MP4_GetByte( &i_data, &p_data ) == 0x05 )
1024 dec_descr.i_decoder_specific_info_len =
1025 MP4_DescriptorLength( &i_data, &p_data );
1026 if( dec_descr.i_decoder_specific_info_len > 0 )
1028 dec_descr.p_decoder_specific_info =
1029 malloc( dec_descr.i_decoder_specific_info_len );
1031 for( i = 0; i < dec_descr.i_decoder_specific_info_len; i++ )
1033 dec_descr.p_decoder_specific_info[i] = MP4_GetByte( &i_data, &p_data );
1038 dec_descr.i_decoder_specific_info_len = 0;
1039 dec_descr.p_decoder_specific_info = NULL;
1043 #define sl_descr es_descr.sl_descr
1045 int i_SLConfigDescr_length;
1048 if( MP4_GetByte( &i_data, &p_data ) != 0x06 )
1050 fprintf( stderr, "\n* ERR missing SLConfigDescr" );
1054 i_SLConfigDescr_length = MP4_DescriptorLength( &i_data, &p_data );
1056 fprintf( stderr, "\n* - SLConfigDescr length:%d", i_SLConfigDescr_length );
1057 i_predefined = MP4_GetByte( &i_data, &p_data );
1058 fprintf( stderr, "\n* * i_predefined:0x%x", i_predefined );
1059 switch( i_predefined )
1063 sl_descr.b_useAccessUnitStartFlag = 0;
1064 sl_descr.b_useAccessUnitEndFlag = 0;
1065 sl_descr.b_useRandomAccessPointFlag = 0;
1066 //sl_descr.b_useRandomAccessUnitsOnlyFlag = 0;
1067 sl_descr.b_usePaddingFlag = 0;
1068 sl_descr.b_useTimeStampsFlags = 0;
1069 sl_descr.b_useIdleFlag = 0;
1070 sl_descr.b_durationFlag = 0; // FIXME FIXME
1071 sl_descr.i_timeStampResolution = 1000;
1072 sl_descr.i_OCRResolution = 0; // FIXME FIXME
1073 sl_descr.i_timeStampLength = 32;
1074 sl_descr.i_OCRLength = 0; // FIXME FIXME
1075 sl_descr.i_AU_Length = 0;
1076 sl_descr.i_instantBitrateLength= 0; // FIXME FIXME
1077 sl_descr.i_degradationPriorityLength= 0;
1078 sl_descr.i_AU_seqNumLength = 0;
1079 sl_descr.i_packetSeqNumLength = 0;
1080 if( sl_descr.b_durationFlag )
1082 sl_descr.i_timeScale = 0; // FIXME FIXME
1083 sl_descr.i_accessUnitDuration = 0; // FIXME FIXME
1084 sl_descr.i_compositionUnitDuration= 0; // FIXME FIXME
1086 if( !sl_descr.b_useTimeStampsFlags )
1088 sl_descr.i_startDecodingTimeStamp = 0; // FIXME FIXME
1089 sl_descr.i_startCompositionTimeStamp= 0; // FIXME FIXME
1094 fprintf( stderr, "\n* ERR unsupported SLConfigDescr predefined" );
1103 fprintf( stderr, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag, i_length );
1107 p_data = p_data_sav + i_length;
1108 i_data = i_data_sav - i_length;
1113 fprintf( stderr, "\n*****************************\n" );
1116 static void MP4_IODClean( iod_descriptor_t *p_iod )
1120 if( p_iod->psz_url )
1122 free( p_iod->psz_url );
1123 p_iod->psz_url = NULL;
1127 for( i = 0; i < 255; i++ )
1129 #define es_descr p_iod->es_descr[i]
1132 if( es_descr.psz_url )
1134 free( es_descr.psz_url );
1135 es_descr.psz_url = NULL;
1139 if( es_descr.dec_descr.p_decoder_specific_info != NULL )
1141 free( es_descr.dec_descr.p_decoder_specific_info );
1142 es_descr.dec_descr.p_decoder_specific_info = NULL;
1143 es_descr.dec_descr.i_decoder_specific_info_len = 0;
1152 /*****************************************************************************
1153 * HandlePAT: will treat a PAT returned by dvbpsi
1154 *****************************************************************************/
1155 static void TS_DVBPSI_HandlePAT( input_thread_t * p_input,
1156 dvbpsi_pat_t * p_new_pat )
1158 dvbpsi_pat_program_t * p_pgrm;
1159 pgrm_descriptor_t * p_new_pgrm;
1160 pgrm_ts_data_t * p_pgrm_demux;
1161 es_descriptor_t * p_current_es;
1162 es_ts_data_t * p_es_demux;
1163 stream_ts_data_t * p_stream_data;
1165 vlc_mutex_lock( &p_input->stream.stream_lock );
1167 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
1169 if ( ( p_new_pat->b_current_next && ( p_new_pat->i_version != p_stream_data->i_pat_version ) ) ||
1170 p_stream_data->i_pat_version == PAT_UNINITIALIZED )
1172 /* Delete all programs */
1173 while( p_input->stream.i_pgrm_number )
1175 pgrm_ts_data_t *p_pgrm_demux_old =
1176 (pgrm_ts_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
1178 if( p_pgrm_demux_old->b_mpeg4 )
1180 MP4_IODClean( &p_pgrm_demux_old->iod );
1183 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
1186 /* treat the new programs list */
1187 p_pgrm = p_new_pat->p_first_program;
1191 /* If program = 0, we're having info about NIT not PMT */
1192 if( p_pgrm->i_number )
1194 /* Add this program */
1195 p_new_pgrm = input_AddProgram( p_input, p_pgrm->i_number,
1196 sizeof( pgrm_ts_data_t ) );
1198 p_pgrm_demux = (pgrm_ts_data_t *)p_new_pgrm->p_demux_data;
1199 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
1201 /* Add the PMT ES to this program */
1202 p_current_es = input_AddES( p_input, p_new_pgrm,
1203 (u16) p_pgrm->i_pid,
1204 sizeof( es_ts_data_t) );
1205 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
1206 p_es_demux->b_psi = 1;
1207 p_es_demux->i_psi_type = PSI_IS_PMT;
1209 p_es_demux->p_psi_section = malloc( sizeof( psi_section_t ) );
1210 if ( p_es_demux->p_psi_section == NULL )
1212 msg_Err( p_input, "out of memory" );
1213 p_input->b_error = 1;
1217 p_es_demux->p_psi_section->b_is_complete = 0;
1218 p_es_demux->i_continuity_counter = 0xFF;
1220 /* Create a PMT decoder */
1221 p_pgrm_demux->p_pmt_handle = (dvbpsi_handle *)
1222 dvbpsi_AttachPMT( p_pgrm->i_number,
1223 (dvbpsi_pmt_callback) &TS_DVBPSI_HandlePMT,
1226 if( p_pgrm_demux->p_pmt_handle == NULL )
1228 msg_Err( p_input, "could not create PMT decoder" );
1229 p_input->b_error = 1;
1234 p_pgrm = p_pgrm->p_next;
1237 p_stream_data->i_pat_version = p_new_pat->i_version;
1239 vlc_mutex_unlock( &p_input->stream.stream_lock );
1243 /*****************************************************************************
1244 * HandlePMT: will treat a PMT returned by dvbpsi
1245 *****************************************************************************/
1246 static void TS_DVBPSI_HandlePMT( input_thread_t * p_input,
1247 dvbpsi_pmt_t * p_new_pmt )
1249 dvbpsi_pmt_es_t * p_es;
1250 pgrm_descriptor_t * p_pgrm;
1251 es_descriptor_t * p_new_es;
1252 pgrm_ts_data_t * p_pgrm_demux;
1253 vlc_bool_t b_vls_compat = config_GetInt( p_input, "vls-backwards-compat" );
1255 vlc_mutex_lock( &p_input->stream.stream_lock );
1257 p_pgrm = input_FindProgram( p_input, p_new_pmt->i_program_number );
1259 if( p_pgrm == NULL )
1261 msg_Warn( p_input, "PMT of unreferenced program found" );
1265 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
1266 p_pgrm_demux->i_pcr_pid = p_new_pmt->i_pcr_pid;
1268 if( ( p_new_pmt->b_current_next && ( p_new_pmt->i_version != p_pgrm_demux->i_pmt_version ) ) ||
1269 p_pgrm_demux->i_pmt_version == PMT_UNINITIALIZED )
1271 dvbpsi_descriptor_t *p_dr = p_new_pmt->p_first_descriptor;
1273 while( p_dr && ( p_dr->i_tag != 0x1d ) )
1274 p_dr = p_dr->p_next;
1277 msg_Warn( p_input, "found IOD descriptor" );
1278 MP4_IODParse( &p_pgrm_demux->iod, p_dr->i_length, p_dr->p_data );
1281 p_es = p_new_pmt->p_first_es;
1285 p_new_es = input_AddES( p_input, p_pgrm,
1286 (u16)p_es->i_pid, sizeof( es_ts_data_t ) );
1287 if( p_new_es == NULL )
1289 msg_Err( p_input, "could not add ES %d", p_es->i_pid );
1290 p_input->b_error = 1;
1293 ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter = 0xFF;
1295 switch( p_es->i_type )
1297 case MPEG1_VIDEO_ES:
1298 case MPEG2_VIDEO_ES:
1299 case MPEG2_MOTO_VIDEO_ES:
1300 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','v');
1301 p_new_es->i_cat = VIDEO_ES;
1303 case MPEG1_AUDIO_ES:
1304 case MPEG2_AUDIO_ES:
1305 p_new_es->i_fourcc = VLC_FOURCC('m','p','g','a');
1306 p_new_es->i_cat = AUDIO_ES;
1309 case A52DVB_AUDIO_ES:
1310 if ( !b_vls_compat )
1311 p_new_es->i_fourcc = VLC_FOURCC('a','5','2',' ');
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 if ( !b_vls_compat )
1319 p_new_es->i_fourcc = VLC_FOURCC('s','p','u',' ');
1321 p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
1322 p_new_es->i_cat = SPU_ES;
1323 p_new_es->i_stream_id = 0xBD;
1326 p_new_es->i_fourcc = VLC_FOURCC('l','p','c','m');
1327 p_new_es->i_cat = AUDIO_ES;
1328 p_new_es->i_stream_id = 0xBD;
1331 p_new_es->i_fourcc = VLC_FOURCC('s','d','d','s');
1332 p_new_es->i_stream_id = 0xBD;
1333 p_new_es->i_cat = AUDIO_ES;
1336 p_new_es->i_fourcc = VLC_FOURCC('d','t','s',' ');
1337 p_new_es->i_stream_id = 0xBD;
1338 p_new_es->i_cat = AUDIO_ES;
1341 p_new_es->i_fourcc = VLC_FOURCC('a','5','2','b');
1342 p_new_es->i_cat = AUDIO_ES;
1343 p_new_es->i_stream_id = 0xBD;
1346 p_new_es->i_fourcc = VLC_FOURCC('s','p','u','b');
1347 p_new_es->i_cat = SPU_ES;
1348 p_new_es->i_stream_id = 0xBD;
1350 case LPCMB_AUDIO_ES:
1351 p_new_es->i_fourcc = VLC_FOURCC('l','p','c','b');
1352 p_new_es->i_cat = AUDIO_ES;
1353 p_new_es->i_stream_id = 0xBD;
1355 case MPEG4_VIDEO_ES:
1356 p_new_es->i_fourcc = VLC_FOURCC('m','p','4','v');
1357 p_new_es->i_cat = VIDEO_ES;
1358 p_new_es->i_stream_id = 0xfa;
1360 case MPEG4_AUDIO_ES:
1361 p_new_es->i_fourcc = VLC_FOURCC('m','p','4','a');
1362 p_new_es->i_cat = AUDIO_ES;
1363 p_new_es->i_stream_id = 0xfa;
1365 case MSCODEC_VIDEO_ES:
1366 p_new_es->i_fourcc = VLC_FOURCC(0,0,0,0); // fixed later
1367 p_new_es->i_cat = VIDEO_ES;
1368 p_new_es->i_stream_id = 0xa0;
1371 p_new_es->i_fourcc = 0;
1372 p_new_es->i_cat = UNKNOWN_ES;
1375 if( p_es->i_type == MPEG4_VIDEO_ES || p_es->i_type == MPEG4_AUDIO_ES )
1377 /* mpeg4 stream, search sl_descriptor */
1378 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1379 es_ts_data_t *p_es_demux =
1380 (es_ts_data_t*)p_new_es->p_demux_data;
1382 while( p_dr && ( p_dr->i_tag != 0x1f ) )
1383 p_dr = p_dr->p_next;
1384 if( p_dr && p_dr->i_length == 2 )
1386 int i_es_descr_index;
1388 p_es_demux->i_es_id =
1389 ( p_dr->p_data[0] << 8 ) | p_dr->p_data[1];
1390 p_es_demux->p_es_descr = NULL;
1392 msg_Warn( p_input, "found SL_descriptor" );
1393 for( i_es_descr_index = 0; i_es_descr_index < 255; i_es_descr_index++ )
1395 if( p_pgrm_demux->iod.es_descr[i_es_descr_index].b_ok &&
1396 p_pgrm_demux->iod.es_descr[i_es_descr_index].i_es_id == p_es_demux->i_es_id )
1398 p_es_demux->p_es_descr = &p_pgrm_demux->iod.es_descr[i_es_descr_index];
1403 if( p_es_demux->p_es_descr != NULL )
1405 vlc_fourcc_t i_fourcc;
1407 p_es_demux->b_mpeg4 = 1;
1410 switch( p_es_demux->p_es_descr->dec_descr.i_streamType )
1412 case 0x04: /* VisualStream */
1414 switch( p_es_demux->p_es_descr->dec_descr.i_objectTypeIndication )
1417 i_fourcc = VLC_FOURCC('m','p','4','v'); // mpeg4
1425 i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg2
1428 i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg1
1431 i_fourcc = VLC_FOURCC( 'j','p','e','g' ); // mpeg1
1438 case 0x05: /* AudioStream */
1440 switch( p_es_demux->p_es_descr->dec_descr.i_objectTypeIndication )
1443 i_fourcc = VLC_FOURCC('m','p','4','a'); // mpeg4
1448 i_fourcc = VLC_FOURCC('m','p','4','a'); // mpeg2 aac
1451 i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg2
1454 i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg1
1467 p_new_es->i_fourcc = i_fourcc;
1468 p_new_es->i_cat = i_cat;
1474 BITMAPINFOHEADER *p_bih;
1476 i_size = sizeof( BITMAPINFOHEADER ) +
1477 p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len;
1478 p_new_es->p_bitmapinfoheader = (void*)p_bih = malloc( i_size );
1479 p_bih->biSize = i_size;
1481 p_bih->biHeight = 0;
1482 p_bih->biPlanes = 1;
1483 p_bih->biBitCount = 0;
1484 p_bih->biCompression = 0;
1485 p_bih->biSizeImage = 0;
1486 p_bih->biXPelsPerMeter = 0;
1487 p_bih->biYPelsPerMeter = 0;
1488 p_bih->biClrUsed = 0;
1489 p_bih->biClrImportant = 0;
1491 p_es_demux->p_es_descr->dec_descr.p_decoder_specific_info,
1492 p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len );
1500 i_size = sizeof( WAVEFORMATEX ) +
1501 p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len;
1502 p_new_es->p_waveformatex = (void*)p_wf = malloc( i_size );
1503 p_wf->wFormatTag = 0xffff;
1504 p_wf->nChannels = 0;
1505 p_wf->nSamplesPerSec = 0;
1506 p_wf->nAvgBytesPerSec = 0;
1507 p_wf->nBlockAlign = 1;
1508 p_wf->wBitsPerSample = 0;
1509 p_wf->cbSize = p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len;
1511 p_es_demux->p_es_descr->dec_descr.p_decoder_specific_info,
1512 p_es_demux->p_es_descr->dec_descr.i_decoder_specific_info_len );
1521 msg_Warn( p_input, "mpeg4 stream without (valid) sl_descriptor" );
1522 p_es_demux->b_mpeg4 = 0;
1526 else if( p_es->i_type == MSCODEC_VIDEO_ES )
1528 /* crapy ms codec stream, search private descriptor */
1529 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1530 es_ts_data_t *p_es_demux =
1531 (es_ts_data_t*)p_new_es->p_demux_data;
1533 while( p_dr && ( p_dr->i_tag != 0xa0 ) )
1534 p_dr = p_dr->p_next;
1535 if( p_dr && p_dr->i_length >= 8 )
1539 BITMAPINFOHEADER *p_bih;
1541 p_new_es->i_fourcc = ( p_dr->p_data[0] << 24 )| ( p_dr->p_data[1] << 16 )|
1542 ( p_dr->p_data[2] << 8 )| ( p_dr->p_data[3] );
1544 i_bih_size = ( ( p_dr->p_data[8] << 8)|( p_dr->p_data[9] ) );
1545 i_size = sizeof( BITMAPINFOHEADER ) + i_bih_size;
1547 p_new_es->p_bitmapinfoheader = (void*)p_bih = malloc( i_size );
1548 p_bih->biSize = i_size;
1549 p_bih->biWidth = ( p_dr->p_data[4] << 8 )|p_dr->p_data[5];
1550 p_bih->biHeight = ( p_dr->p_data[6] << 8 )|p_dr->p_data[7];
1551 p_bih->biPlanes = 1;
1552 p_bih->biBitCount = 0;
1553 p_bih->biCompression = 0;
1554 p_bih->biSizeImage = 0;
1555 p_bih->biXPelsPerMeter = 0;
1556 p_bih->biYPelsPerMeter = 0;
1557 p_bih->biClrUsed = 0;
1558 p_bih->biClrImportant = 0;
1565 msg_Warn( p_input, "private ms-codec stream without bih private sl_descriptor" );
1566 p_new_es->i_fourcc = 0;
1567 p_new_es->i_cat = UNKNOWN_ES;
1571 if( ( p_new_es->i_cat == AUDIO_ES )
1572 || (p_new_es->i_cat == SPU_ES ) )
1574 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1575 while( p_dr && ( p_dr->i_tag != 0x0a ) )
1576 p_dr = p_dr->p_next;
1579 dvbpsi_iso639_dr_t *p_decoded =
1580 dvbpsi_DecodeISO639Dr( p_dr );
1581 if( p_decoded->i_code_count > 0 )
1583 const iso639_lang_t * p_iso;
1584 p_iso = GetLang_2T((char*)p_decoded->i_iso_639_code);
1587 if(p_iso->psz_native_name[0])
1588 strcpy( p_new_es->psz_desc,
1589 p_iso->psz_native_name );
1591 strcpy( p_new_es->psz_desc,
1592 p_iso->psz_eng_name );
1596 strncpy( p_new_es->psz_desc,
1597 p_decoded->i_iso_639_code, 3 );
1601 switch( p_es->i_type )
1603 case MPEG1_AUDIO_ES:
1604 case MPEG2_AUDIO_ES:
1605 strcat( p_new_es->psz_desc, " (mpeg)" );
1608 case LPCMB_AUDIO_ES:
1609 strcat( p_new_es->psz_desc, " (lpcm)" );
1612 case A52DVB_AUDIO_ES:
1614 strcat( p_new_es->psz_desc, " (A52)" );
1616 case MPEG4_AUDIO_ES:
1617 strcat( p_new_es->psz_desc, " (aac)" );
1622 p_es = p_es->p_next;
1625 /* if no program is selected :*/
1626 if( !p_input->stream.p_selected_program )
1628 pgrm_descriptor_t * p_pgrm_to_select;
1629 u16 i_id = (u16)config_GetInt( p_input, "program" );
1631 if( i_id != 0 ) /* if user specified a program */
1633 p_pgrm_to_select = input_FindProgram( p_input, i_id );
1635 if( p_pgrm_to_select && p_pgrm_to_select == p_pgrm )
1636 p_input->pf_set_program( p_input, p_pgrm_to_select );
1639 p_input->pf_set_program( p_input, p_pgrm );
1641 /* if the pmt belongs to the currently selected program, we
1642 * reselect it to update its ES */
1643 else if( p_pgrm == p_input->stream.p_selected_program )
1645 p_input->pf_set_program( p_input, p_pgrm );
1648 p_pgrm_demux->i_pmt_version = p_new_pmt->i_version;
1649 p_input->stream.b_changed = 1;
1651 vlc_mutex_unlock( &p_input->stream.stream_lock );