1 /*****************************************************************************
2 * mpeg_ts.c : Transport Stream input module for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2001 VideoLAN
5 * $Id: ts.c,v 1.37 2003/09/20 17:35:38 gbazin Exp $
7 * Authors: Henri Fallon <henri@via.ecp.fr>
8 * Johan Bilien <jobi@via.ecp.fr>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
30 #include <vlc/input.h>
34 #if defined MODULE_NAME_IS_ts_dvbpsi
35 # ifdef HAVE_DVBPSI_DR_H
36 # include <dvbpsi/dvbpsi.h>
37 # include <dvbpsi/descriptor.h>
38 # include <dvbpsi/pat.h>
39 # include <dvbpsi/pmt.h>
40 # include <dvbpsi/dr.h>
43 # include "descriptor.h"
44 # include "tables/pat.h"
45 # include "tables/pmt.h"
46 # include "descriptors/dr.h"
53 /*****************************************************************************
55 *****************************************************************************/
56 #define TS_READ_ONCE 200
58 /*****************************************************************************
60 *****************************************************************************/
67 /*****************************************************************************
69 *****************************************************************************/
70 static int Activate ( vlc_object_t * );
71 static void Deactivate ( vlc_object_t * );
72 static int Demux ( input_thread_t * );
74 #if defined MODULE_NAME_IS_ts
75 static void TSDemuxPSI ( input_thread_t *, data_packet_t *,
76 es_descriptor_t *, vlc_bool_t );
77 static void TSDecodePAT( input_thread_t *, es_descriptor_t *);
78 static void TSDecodePMT( input_thread_t *, es_descriptor_t *);
79 #define PSI_CALLBACK TSDemuxPSI
80 #elif defined MODULE_NAME_IS_ts_dvbpsi
81 static void TS_DVBPSI_DemuxPSI ( input_thread_t *, data_packet_t *,
82 es_descriptor_t *, vlc_bool_t );
83 static void TS_DVBPSI_HandlePAT ( input_thread_t *, dvbpsi_pat_t * );
84 static void TS_DVBPSI_HandlePMT ( input_thread_t *, dvbpsi_pmt_t * );
85 #define PSI_CALLBACK TS_DVBPSI_DemuxPSI
88 /*****************************************************************************
90 *****************************************************************************/
91 #define VLS_BACKWARDS_COMPAT_TEXT N_("Compatibility with pre-0.4 VLS")
92 #define VLS_BACKWARDS_COMPAT_LONGTEXT N_( \
93 "The protocol for transmitting A/52 audio streams changed between VLC " \
94 "0.3.x and 0.4. By default VLC assumes you have the latest VLS. In case " \
95 "you're using an old version, select this option.")
97 #define BUGGY_PSI_TEXT N_("Buggy PSI")
98 #define BUGGY_PSI_LONGTEXT N_( \
99 "If you have a stream whose PSI packets do not feature incremented " \
100 "continuity counters, select this option.")
103 #if defined MODULE_NAME_IS_ts
104 set_description( _("ISO 13818-1 MPEG Transport Stream input") );
105 set_capability( "demux", 160 );
106 add_shortcut( "ts" );
107 #elif defined MODULE_NAME_IS_ts_dvbpsi
108 set_description( _("ISO 13818-1 MPEG Transport Stream input (libdvbpsi)") );
109 set_capability( "demux", 170 );
110 add_shortcut( "ts_dvbpsi" );
112 add_category_hint( N_("Miscellaneous"), NULL, VLC_TRUE );
113 add_bool( "vls-backwards-compat", 0, NULL,
114 VLS_BACKWARDS_COMPAT_TEXT, VLS_BACKWARDS_COMPAT_LONGTEXT, VLC_TRUE );
115 add_bool( "buggy-psi", 0, NULL, BUGGY_PSI_TEXT, BUGGY_PSI_LONGTEXT, VLC_TRUE );
116 set_callbacks( Activate, Deactivate );
119 /*****************************************************************************
120 * Activate: initialize TS structures
121 *****************************************************************************/
122 static int Activate( vlc_object_t * p_this )
124 input_thread_t * p_input = (input_thread_t *)p_this;
125 demux_sys_t * p_demux;
126 es_descriptor_t * p_pat_es;
127 es_ts_data_t * p_demux_data;
128 stream_ts_data_t * p_stream_data;
131 /* Set the demux function */
132 p_input->pf_demux = Demux;
133 p_input->pf_demux_control = demux_vaControlDefault;
136 /* XXX Unused already done by src/input.c */
137 /* Initialize access plug-in structures. */
138 if( p_input->i_mtu == 0 )
141 msg_Dbg( p_input, "using default mtu (%d) with bufsize (%d)\n",
142 p_input->i_mtu, INPUT_DEFAULT_BUFSIZE );
143 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, 0x00,
220 UNKNOWN_ES, NULL, sizeof( es_ts_data_t ) );
221 p_pat_es->i_fourcc = VLC_FOURCC( 'p', 'a', 't', ' ' );
222 p_demux_data = (es_ts_data_t *)p_pat_es->p_demux_data;
223 p_demux_data->b_psi = 1;
224 p_demux_data->i_psi_type = PSI_IS_PAT;
225 p_demux_data->p_psi_section = malloc(sizeof(psi_section_t));
226 p_demux_data->p_psi_section->b_is_complete = 1;
227 p_demux_data->i_continuity_counter = 0xFF;
229 vlc_mutex_unlock( &p_input->stream.stream_lock );
234 /*****************************************************************************
235 * Deactivate: deinitialize TS structures
236 *****************************************************************************/
237 static void Deactivate( vlc_object_t * p_this )
239 input_thread_t * p_input = (input_thread_t *)p_this;
241 module_Unneed( p_input, p_input->p_demux_data->p_module );
242 free( p_input->p_demux_data );
245 /*****************************************************************************
246 * Demux: reads and demuxes data packets
247 *****************************************************************************
248 * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
250 *****************************************************************************/
251 static int Demux( input_thread_t * p_input )
253 demux_sys_t * p_demux = p_input->p_demux_data;
254 int i_read_once = (p_input->i_mtu ?
255 p_input->i_bufsize / TS_PACKET_SIZE :
259 for( i = 0; i < i_read_once; i++ )
261 data_packet_t * p_data;
264 i_result = p_demux->mpeg.pf_read_ts( p_input, &p_data );
271 p_demux->mpeg.pf_demux_ts( p_input, p_data,
272 (psi_callback_t) &PSI_CALLBACK );
279 #if defined MODULE_NAME_IS_ts
281 * PSI demultiplexing and decoding without libdvbpsi
284 /*****************************************************************************
285 * DemuxPSI : makes up complete PSI data
286 *****************************************************************************/
287 static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data,
288 es_descriptor_t * p_es, vlc_bool_t b_unit_start )
290 es_ts_data_t * p_demux_data;
292 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
294 #define p_psi (p_demux_data->p_psi_section)
295 #define p (p_data->p_payload_start)
299 /* unit_start set to 1 -> presence of a pointer field
300 * (see ISO/IEC 13818 (2.4.4.2) which should be set to 0x00 */
301 if( (uint8_t)p[0] != 0x00 )
304 "non-zero pointer field found, trying to continue" );
312 /* This is the begining of a new section */
314 if( ((uint8_t)(p[1]) & 0xc0) != 0x80 )
316 msg_Warn( p_input, "invalid PSI packet" );
321 p_psi->i_section_length = ((p[1] & 0xF) << 8) | p[2];
322 p_psi->b_section_complete = 0;
323 p_psi->i_read_in_section = 0;
324 p_psi->i_section_number = (uint8_t)p[6];
326 if( p_psi->b_is_complete || p_psi->i_section_number == 0 )
328 /* This is a new PSI packet */
329 p_psi->b_is_complete = 0;
331 p_psi->i_version_number = ( p[5] >> 1 ) & 0x1f;
332 p_psi->i_last_section_number = (uint8_t)p[7];
334 /* We'll write at the begining of the buffer */
335 p_psi->p_current = p_psi->buffer;
339 if( p_psi->b_section_complete )
341 /* New Section of an already started PSI */
342 p_psi->b_section_complete = 0;
344 if( p_psi->i_version_number != (( p[5] >> 1 ) & 0x1f) )
347 "PSI version differs inside same PAT" );
350 if( p_psi->i_section_number + 1 != (uint8_t)p[6] )
353 "PSI Section discontinuity, packet lost?" );
357 p_psi->i_section_number++;
361 msg_Warn( p_input, "got unexpected new PSI section" );
368 if( !p_psi->b_trash )
371 if( (p_data->p_payload_end - p) >=
372 ( p_psi->i_section_length - p_psi->i_read_in_section ) )
374 /* The end of the section is in this TS packet */
375 memcpy( p_psi->p_current, p,
376 (p_psi->i_section_length - p_psi->i_read_in_section) );
378 p_psi->b_section_complete = 1;
380 (p_psi->i_section_length - p_psi->i_read_in_section);
382 if( p_psi->i_section_number == p_psi->i_last_section_number )
384 /* This was the last section of PSI */
385 p_psi->b_is_complete = 1;
387 switch( p_demux_data->i_psi_type)
390 TSDecodePAT( p_input, p_es );
393 TSDecodePMT( p_input, p_es );
396 msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
402 memcpy( p_psi->buffer, p, p_data->p_payload_end - p );
403 p_psi->i_read_in_section += p_data->p_payload_end - p;
405 p_psi->p_current += p_data->p_payload_end - p;
412 input_DeletePacket( p_input->p_method_data, p_data );
417 /*****************************************************************************
418 * DecodePAT : Decodes Programm association table and deal with it
419 *****************************************************************************/
420 static void TSDecodePAT( input_thread_t * p_input, es_descriptor_t * p_es )
422 stream_ts_data_t * p_stream_data;
423 es_ts_data_t * p_demux_data;
425 pgrm_descriptor_t * p_pgrm;
426 es_descriptor_t * p_current_es;
427 byte_t * p_current_data;
429 int i_section_length, i_program_id, i_pmt_pid;
430 int i_loop, i_current_section;
432 vlc_bool_t b_changed = 0;
434 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
435 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
437 #define p_psi (p_demux_data->p_psi_section)
439 /* Not so fast, Mike ! If the PAT version has changed, we first check
440 * that its content has really changed before doing anything */
441 if( p_stream_data->i_pat_version != p_psi->i_version_number )
443 int i_programs = p_input->stream.i_pgrm_number;
445 p_current_data = p_psi->buffer;
449 i_section_length = ((uint32_t)(p_current_data[1] & 0xF) << 8) |
451 i_current_section = (uint8_t)p_current_data[6];
454 ( i_loop < (i_section_length - 9) / 4 ) && !b_changed;
457 i_program_id = ( (uint32_t)*(p_current_data + i_loop * 4 + 8) << 8 )
458 | *(p_current_data + i_loop * 4 + 9);
459 i_pmt_pid = ( ((uint32_t)*(p_current_data + i_loop * 4 + 10) & 0x1F)
461 | *(p_current_data + i_loop * 4 + 11);
465 if( (p_pgrm = input_FindProgram( p_input, i_program_id ))
466 && (p_current_es = input_FindES( p_input, i_pmt_pid ))
467 && p_current_es->p_pgrm == p_pgrm
468 && p_current_es->i_id == i_pmt_pid
469 && ((es_ts_data_t *)p_current_es->p_demux_data)->b_psi
470 && ((es_ts_data_t *)p_current_es->p_demux_data)
471 ->i_psi_type == PSI_IS_PMT )
482 p_current_data += 3 + i_section_length;
484 } while( ( i_current_section < p_psi->i_last_section_number )
487 /* If we didn't find the expected amount of programs, the PAT has
488 * changed. Otherwise, it only changed if b_changed is already != 0 */
489 b_changed = b_changed || i_programs;
494 /* PAT has changed. We are going to delete all programs and
495 * create new ones. We chose not to only change what was needed
496 * as a PAT change may mean the stream is radically changing and
497 * this is a secure method to avoid crashes */
498 es_ts_data_t * p_es_demux;
499 pgrm_ts_data_t * p_pgrm_demux;
501 p_current_data = p_psi->buffer;
503 /* Delete all programs */
504 while( p_input->stream.i_pgrm_number )
506 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
511 i_section_length = ((uint32_t)(p_current_data[1] & 0xF) << 8) |
513 i_current_section = (uint8_t)p_current_data[6];
515 for( i_loop = 0; i_loop < (i_section_length - 9) / 4 ; i_loop++ )
517 i_program_id = ( (uint32_t)*(p_current_data + i_loop * 4 + 8) << 8 )
518 | *(p_current_data + i_loop * 4 + 9);
519 i_pmt_pid = ( ((uint32_t)*(p_current_data + i_loop * 4 + 10) & 0x1F)
521 | *(p_current_data + i_loop * 4 + 11);
523 /* If program = 0, we're having info about NIT not PMT */
526 /* Add this program */
527 p_pgrm = input_AddProgram( p_input, i_program_id,
528 sizeof( pgrm_ts_data_t ) );
530 /* whatis the PID of the PMT of this program */
531 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
532 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
534 /* Add the PMT ES to this program */
535 p_current_es = input_AddES( p_input, p_pgrm,(uint16_t)i_pmt_pid,
536 UNKNOWN_ES, NULL, sizeof( es_ts_data_t) );
537 p_current_es->i_fourcc = VLC_FOURCC( 'p', 'm', 't', ' ' );
538 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
539 p_es_demux->b_psi = 1;
540 p_es_demux->i_psi_type = PSI_IS_PMT;
542 p_es_demux->p_psi_section =
543 malloc( sizeof( psi_section_t ) );
544 p_es_demux->p_psi_section->b_is_complete = 0;
545 p_es_demux->i_continuity_counter = 0xFF;
549 p_current_data += 3 + i_section_length;
551 } while( i_current_section < p_psi->i_last_section_number );
553 /* Go to the beginning of the next section */
554 p_stream_data->i_pat_version = p_psi->i_version_number;
561 /*****************************************************************************
562 * DecodePMT : decode a given Program Stream Map
563 * ***************************************************************************
564 * When the PMT changes, it may mean a deep change in the stream, and it is
565 * careful to delete the ES and add them again. If the PMT doesn't change,
566 * there no need to do anything.
567 *****************************************************************************/
568 static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es )
571 pgrm_ts_data_t * p_pgrm_data;
572 es_ts_data_t * p_demux_data;
573 vlc_bool_t b_vls_compat = config_GetInt( p_input, "vls-backwards-compat" );
575 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
576 p_pgrm_data = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;
578 #define p_psi (p_demux_data->p_psi_section)
580 if( p_psi->i_version_number != p_pgrm_data->i_pmt_version )
582 es_descriptor_t * p_new_es;
583 es_ts_data_t * p_es_demux;
584 byte_t * p_current_data, * p_current_section;
585 int i_section_length,i_current_section;
586 int i_prog_info_length, i_loop;
587 int i_es_info_length, i_pid, i_stream_type;
589 p_current_section = p_psi->buffer;
590 p_current_data = p_psi->buffer;
592 p_pgrm_data->i_pcr_pid = ( ((uint32_t)*(p_current_section + 8) & 0x1F) << 8 ) |
593 *(p_current_section + 9);
596 /* Lock stream information */
597 vlc_mutex_lock( &p_input->stream.stream_lock );
599 /* Delete all ES in this program except the PSI. We start from the
600 * end because i_es_number gets decremented after each deletion. */
601 for( i_loop = p_es->p_pgrm->i_es_number ; i_loop ; )
604 p_es_demux = (es_ts_data_t *)
605 p_es->p_pgrm->pp_es[i_loop]->p_demux_data;
606 if ( ! p_es_demux->b_psi )
608 input_DelES( p_input, p_es->p_pgrm->pp_es[i_loop] );
612 /* Then add what we received in this PMT */
615 i_section_length = ( ((uint32_t)*(p_current_data + 1) & 0xF) << 8 ) |
616 *(p_current_data + 2);
617 i_current_section = (uint8_t)p_current_data[6];
618 i_prog_info_length = ( ((uint32_t)*(p_current_data + 10) & 0xF) << 8 ) |
619 *(p_current_data + 11);
621 /* For the moment we ignore program descriptors */
622 p_current_data += 12 + i_prog_info_length;
624 /* The end of the section, before the CRC is at
625 * p_current_section + i_section_length -1 */
626 while( p_current_data < p_current_section + i_section_length -1 )
628 i_stream_type = (int)p_current_data[0];
629 i_pid = ( ((uint32_t)*(p_current_data + 1) & 0x1F) << 8 ) |
630 *(p_current_data + 2);
631 i_es_info_length = ( ((uint32_t)*(p_current_data + 3) & 0xF) << 8 ) |
632 *(p_current_data + 4);
634 /* Tell the interface what kind of stream it is and select
635 * the required ones */
637 int i_fourcc, i_cat, i_stream_id;
639 switch( i_stream_type )
643 case MPEG2_MOTO_VIDEO_ES:
644 /* This isn't real, but we don't actually use
647 i_fourcc = VLC_FOURCC('m','p','g','v');
652 /* This isn't real, but we don't actually use
655 i_fourcc = VLC_FOURCC('m','p','g','a');
660 i_fourcc = VLC_FOURCC('a','5','2',' ');
662 i_fourcc = VLC_FOURCC('a','5','2','b');
667 i_fourcc = VLC_FOURCC('l','p','c','m');
673 i_fourcc = VLC_FOURCC('s','p','u',' ');
675 i_fourcc = VLC_FOURCC('s','p','u','b');
680 i_fourcc = VLC_FOURCC('s','d','d','s');
685 i_fourcc = VLC_FOURCC('d','t','s',' ');
689 /* 'b' stands for 'buggy' */
691 i_fourcc = VLC_FOURCC('a','5','2','b');
696 i_fourcc = VLC_FOURCC('l','p','c','b');
701 i_fourcc = VLC_FOURCC('s','p','u','b');
713 /* Add this ES to the program */
714 p_new_es = input_AddES( p_input, p_es->p_pgrm, (uint16_t)i_pid,
715 i_cat, NULL, sizeof( es_ts_data_t ) );
717 ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter = 0xFF;
719 p_new_es->i_stream_id = i_stream_id;
720 p_new_es->i_fourcc = i_fourcc;
724 p_current_data += 5 + i_es_info_length;
727 /* Go to the beginning of the next section*/
728 p_current_data += 3 + i_section_length;
732 } while( i_current_section < p_psi->i_last_section_number );
734 p_pgrm_data->i_pmt_version = p_psi->i_version_number;
736 /* if no program is selected :*/
737 if( !p_input->stream.p_selected_program )
739 pgrm_descriptor_t * p_pgrm_to_select;
740 uint16_t i_id = (uint16_t)config_GetInt( p_input, "program" );
742 if( i_id != 0 ) /* if user specified a program */
744 p_pgrm_to_select = input_FindProgram( p_input, i_id );
746 if( p_pgrm_to_select && p_pgrm_to_select == p_es->p_pgrm )
747 p_input->pf_set_program( p_input, p_pgrm_to_select );
750 p_input->pf_set_program( p_input, p_es->p_pgrm );
753 /* if the pmt belongs to the currently selected program, we
754 * reselect it to update its ES */
755 else if( p_es->p_pgrm == p_input->stream.p_selected_program )
757 p_input->pf_set_program( p_input, p_es->p_pgrm );
760 /* inform interface that stream has changed */
761 p_input->stream.b_changed = 1;
763 vlc_mutex_unlock( &p_input->stream.stream_lock );
769 #elif defined MODULE_NAME_IS_ts_dvbpsi
771 * PSI Decoding using libdvbpsi
774 /*****************************************************************************
775 * DemuxPSI : send the PSI to the right libdvbpsi decoder
776 *****************************************************************************/
777 static void TS_DVBPSI_DemuxPSI( input_thread_t * p_input,
778 data_packet_t * p_data,
779 es_descriptor_t * p_es,
780 vlc_bool_t b_unit_start )
782 es_ts_data_t * p_es_demux_data;
783 pgrm_ts_data_t * p_pgrm_demux_data;
784 stream_ts_data_t * p_stream_demux_data;
786 p_es_demux_data = (es_ts_data_t *)p_es->p_demux_data;
787 p_stream_demux_data = (stream_ts_data_t *) p_input->stream.p_demux_data;
789 switch( p_es_demux_data->i_psi_type)
793 (dvbpsi_handle)p_stream_demux_data->p_pat_handle,
794 p_data->p_demux_start );
797 p_pgrm_demux_data = ( pgrm_ts_data_t * )p_es->p_pgrm->p_demux_data;
799 (dvbpsi_handle)p_pgrm_demux_data->p_pmt_handle,
800 p_data->p_demux_start );
803 msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
806 input_DeletePacket( p_input->p_method_data, p_data );
808 /*****************************************************************************
809 * MP4 specific functions
810 *****************************************************************************/
811 static int MP4_DescriptorLength( int *pi_data, uint8_t **pp_data )
814 unsigned int i_len = 0;
820 i_len = ( i_len << 7 ) + ( i_b&0x7f );
826 static int MP4_GetByte( int *pi_data, uint8_t **pp_data )
841 static int MP4_GetWord( int *pi_data, uint8_t **pp_data )
844 i1 = MP4_GetByte( pi_data, pp_data );
845 i2 = MP4_GetByte( pi_data, pp_data );
846 return( ( i1 << 8 ) | i2 );
848 static int MP4_Get3Bytes( int *pi_data, uint8_t **pp_data )
851 i1 = MP4_GetByte( pi_data, pp_data );
852 i2 = MP4_GetByte( pi_data, pp_data );
853 i3 = MP4_GetByte( pi_data, pp_data );
854 return( ( i1 << 16 ) | ( i2 << 8) | i3 );
857 static uint32_t MP4_GetDWord( int *pi_data, uint8_t **pp_data )
860 i1 = MP4_GetWord( pi_data, pp_data );
861 i2 = MP4_GetWord( pi_data, pp_data );
862 return( ( i1 << 16 ) | i2 );
865 static char* MP4_GetURL( int *pi_data, uint8_t **pp_data )
870 i_url_len = MP4_GetByte( pi_data, pp_data );
871 url = malloc( i_url_len + 1 );
872 for( i = 0; i < i_url_len; i++ )
874 url[i] = MP4_GetByte( pi_data, pp_data );
876 url[i_url_len] = '\0';
880 static void MP4_IODParse( iod_descriptor_t *p_iod, int i_data, uint8_t *p_data )
888 fprintf( stderr, "\n************ IOD ************" );
889 for( i = 0; i < 255; i++ )
891 p_iod->es_descr[i].b_ok = 0;
900 p_iod->i_iod_label = MP4_GetByte( &i_data, &p_data );
901 fprintf( stderr, "\n* iod_label:%d", p_iod->i_iod_label );
902 fprintf( stderr, "\n* ===========" );
903 fprintf( stderr, "\n* tag:0x%x", p_data[0] );
905 if( MP4_GetByte( &i_data, &p_data ) != 0x02 )
907 fprintf( stderr, "\n ERR: tag != 0x02" );
911 i_iod_length = MP4_DescriptorLength( &i_data, &p_data );
912 fprintf( stderr, "\n* length:%d", i_iod_length );
913 if( i_iod_length > i_data )
915 i_iod_length = i_data;
918 p_iod->i_od_id = ( MP4_GetByte( &i_data, &p_data ) << 2 );
919 i_flags = MP4_GetByte( &i_data, &p_data );
920 p_iod->i_od_id |= i_flags >> 6;
921 b_url = ( i_flags >> 5 )&0x01;
923 fprintf( stderr, "\n* od_id:%d", p_iod->i_od_id );
924 fprintf( stderr, "\n* url flag:%d", b_url );
925 fprintf( stderr, "\n* includeInlineProfileLevel flag:%d", ( i_flags >> 4 )&0x01 );
929 p_iod->psz_url = MP4_GetURL( &i_data, &p_data );
930 fprintf( stderr, "\n* url string:%s", p_iod->psz_url );
931 fprintf( stderr, "\n*****************************\n" );
936 p_iod->psz_url = NULL;
939 p_iod->i_ODProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
940 p_iod->i_sceneProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
941 p_iod->i_audioProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
942 p_iod->i_visualProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
943 p_iod->i_graphicsProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
945 fprintf( stderr, "\n* ODProfileLevelIndication:%d", p_iod->i_ODProfileLevelIndication );
946 fprintf( stderr, "\n* sceneProfileLevelIndication:%d", p_iod->i_sceneProfileLevelIndication );
947 fprintf( stderr, "\n* audioProfileLevelIndication:%d", p_iod->i_audioProfileLevelIndication );
948 fprintf( stderr, "\n* visualProfileLevelIndication:%d", p_iod->i_visualProfileLevelIndication );
949 fprintf( stderr, "\n* graphicsProfileLevelIndication:%d", p_iod->i_graphicsProfileLevelIndication );
952 while( i_data > 0 && i_es_index < 255)
958 i_tag = MP4_GetByte( &i_data, &p_data );
959 i_length = MP4_DescriptorLength( &i_data, &p_data );
970 #define es_descr p_iod->es_descr[i_es_index]
971 int i_decoderConfigDescr_length;
972 fprintf( stderr, "\n* - ES_Descriptor length:%d", i_length );
975 es_descr.i_es_id = MP4_GetWord( &i_data, &p_data );
976 i_flags = MP4_GetByte( &i_data, &p_data );
977 es_descr.b_streamDependenceFlag = ( i_flags >> 7 )&0x01;
978 b_url = ( i_flags >> 6 )&0x01;
979 es_descr.b_OCRStreamFlag = ( i_flags >> 5 )&0x01;
980 es_descr.i_streamPriority = i_flags & 0x1f;
981 fprintf( stderr, "\n* * streamDependenceFlag:%d", es_descr.b_streamDependenceFlag );
982 fprintf( stderr, "\n* * OCRStreamFlag:%d", es_descr.b_OCRStreamFlag );
983 fprintf( stderr, "\n* * streamPriority:%d", es_descr.i_streamPriority );
985 if( es_descr.b_streamDependenceFlag )
987 es_descr.i_dependOn_es_id = MP4_GetWord( &i_data, &p_data );
988 fprintf( stderr, "\n* * dependOn_es_id:%d", es_descr.i_dependOn_es_id );
993 es_descr.psz_url = MP4_GetURL( &i_data, &p_data );
994 fprintf( stderr, "\n* url string:%s", es_descr.psz_url );
998 es_descr.psz_url = NULL;
1001 if( es_descr.b_OCRStreamFlag )
1003 es_descr.i_OCR_es_id = MP4_GetWord( &i_data, &p_data );
1004 fprintf( stderr, "\n* * OCR_es_id:%d", es_descr.i_OCR_es_id );
1007 if( MP4_GetByte( &i_data, &p_data ) != 0x04 )
1009 fprintf( stderr, "\n* ERR missing DecoderConfigDescr" );
1013 i_decoderConfigDescr_length = MP4_DescriptorLength( &i_data, &p_data );
1015 fprintf( stderr, "\n* - DecoderConfigDesc length:%d", i_decoderConfigDescr_length );
1016 #define dec_descr es_descr.dec_descr
1017 dec_descr.i_objectTypeIndication = MP4_GetByte( &i_data, &p_data );
1018 i_flags = MP4_GetByte( &i_data, &p_data );
1019 dec_descr.i_streamType = i_flags >> 2;
1020 dec_descr.b_upStream = ( i_flags >> 1 )&0x01;
1021 dec_descr.i_bufferSizeDB = MP4_Get3Bytes( &i_data, &p_data );
1022 dec_descr.i_maxBitrate = MP4_GetDWord( &i_data, &p_data );
1023 dec_descr.i_avgBitrate = MP4_GetDWord( &i_data, &p_data );
1024 fprintf( stderr, "\n* * objectTypeIndication:0x%x", dec_descr.i_objectTypeIndication );
1025 fprintf( stderr, "\n* * streamType:0x%x", dec_descr.i_streamType );
1026 fprintf( stderr, "\n* * upStream:%d", dec_descr.b_upStream );
1027 fprintf( stderr, "\n* * bufferSizeDB:%d", dec_descr.i_bufferSizeDB );
1028 fprintf( stderr, "\n* * maxBitrate:%d", dec_descr.i_maxBitrate );
1029 fprintf( stderr, "\n* * avgBitrate:%d", dec_descr.i_avgBitrate );
1030 if( i_decoderConfigDescr_length > 13 && MP4_GetByte( &i_data, &p_data ) == 0x05 )
1033 dec_descr.i_decoder_specific_info_len =
1034 MP4_DescriptorLength( &i_data, &p_data );
1035 if( dec_descr.i_decoder_specific_info_len > 0 )
1037 dec_descr.p_decoder_specific_info =
1038 malloc( dec_descr.i_decoder_specific_info_len );
1040 for( i = 0; i < dec_descr.i_decoder_specific_info_len; i++ )
1042 dec_descr.p_decoder_specific_info[i] = MP4_GetByte( &i_data, &p_data );
1047 dec_descr.i_decoder_specific_info_len = 0;
1048 dec_descr.p_decoder_specific_info = NULL;
1052 #define sl_descr es_descr.sl_descr
1054 int i_SLConfigDescr_length;
1057 if( MP4_GetByte( &i_data, &p_data ) != 0x06 )
1059 fprintf( stderr, "\n* ERR missing SLConfigDescr" );
1063 i_SLConfigDescr_length = MP4_DescriptorLength( &i_data, &p_data );
1065 fprintf( stderr, "\n* - SLConfigDescr length:%d", i_SLConfigDescr_length );
1066 i_predefined = MP4_GetByte( &i_data, &p_data );
1067 fprintf( stderr, "\n* * i_predefined:0x%x", i_predefined );
1068 switch( i_predefined )
1072 sl_descr.b_useAccessUnitStartFlag = 0;
1073 sl_descr.b_useAccessUnitEndFlag = 0;
1074 sl_descr.b_useRandomAccessPointFlag = 0;
1075 //sl_descr.b_useRandomAccessUnitsOnlyFlag = 0;
1076 sl_descr.b_usePaddingFlag = 0;
1077 sl_descr.b_useTimeStampsFlags = 0;
1078 sl_descr.b_useIdleFlag = 0;
1079 sl_descr.b_durationFlag = 0; // FIXME FIXME
1080 sl_descr.i_timeStampResolution = 1000;
1081 sl_descr.i_OCRResolution = 0; // FIXME FIXME
1082 sl_descr.i_timeStampLength = 32;
1083 sl_descr.i_OCRLength = 0; // FIXME FIXME
1084 sl_descr.i_AU_Length = 0;
1085 sl_descr.i_instantBitrateLength= 0; // FIXME FIXME
1086 sl_descr.i_degradationPriorityLength= 0;
1087 sl_descr.i_AU_seqNumLength = 0;
1088 sl_descr.i_packetSeqNumLength = 0;
1089 if( sl_descr.b_durationFlag )
1091 sl_descr.i_timeScale = 0; // FIXME FIXME
1092 sl_descr.i_accessUnitDuration = 0; // FIXME FIXME
1093 sl_descr.i_compositionUnitDuration= 0; // FIXME FIXME
1095 if( !sl_descr.b_useTimeStampsFlags )
1097 sl_descr.i_startDecodingTimeStamp = 0; // FIXME FIXME
1098 sl_descr.i_startCompositionTimeStamp= 0; // FIXME FIXME
1103 fprintf( stderr, "\n* ERR unsupported SLConfigDescr predefined" );
1112 fprintf( stderr, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag, i_length );
1116 p_data = p_data_sav + i_length;
1117 i_data = i_data_sav - i_length;
1122 fprintf( stderr, "\n*****************************\n" );
1125 static void MP4_IODClean( iod_descriptor_t *p_iod )
1129 if( p_iod->psz_url )
1131 free( p_iod->psz_url );
1132 p_iod->psz_url = NULL;
1136 for( i = 0; i < 255; i++ )
1138 #define es_descr p_iod->es_descr[i]
1141 if( es_descr.psz_url )
1143 free( es_descr.psz_url );
1144 es_descr.psz_url = NULL;
1148 if( es_descr.dec_descr.p_decoder_specific_info != NULL )
1150 free( es_descr.dec_descr.p_decoder_specific_info );
1151 es_descr.dec_descr.p_decoder_specific_info = NULL;
1152 es_descr.dec_descr.i_decoder_specific_info_len = 0;
1161 /*****************************************************************************
1162 * HandlePAT: will treat a PAT returned by dvbpsi
1163 *****************************************************************************/
1164 static void TS_DVBPSI_HandlePAT( input_thread_t * p_input,
1165 dvbpsi_pat_t * p_new_pat )
1167 dvbpsi_pat_program_t * p_pgrm;
1168 pgrm_descriptor_t * p_new_pgrm;
1169 pgrm_ts_data_t * p_pgrm_demux;
1170 es_descriptor_t * p_current_es;
1171 es_ts_data_t * p_es_demux;
1172 stream_ts_data_t * p_stream_data;
1174 vlc_mutex_lock( &p_input->stream.stream_lock );
1176 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
1178 if( ( p_new_pat->b_current_next &&
1179 ( p_new_pat->i_version != p_stream_data->i_pat_version ) ) ||
1180 p_stream_data->i_pat_version == PAT_UNINITIALIZED )
1182 msg_Dbg( p_input, "Processing PAT version %d", p_new_pat->i_version );
1184 /* Delete all programs */
1185 while( p_input->stream.i_pgrm_number )
1187 pgrm_ts_data_t *p_pgrm_demux_old =
1188 (pgrm_ts_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
1190 if( p_pgrm_demux_old->b_mpeg4 )
1192 MP4_IODClean( &p_pgrm_demux_old->iod );
1195 /* Delete old PMT decoder */
1196 if( p_pgrm_demux_old->p_pmt_handle )
1197 dvbpsi_DetachPMT( p_pgrm_demux_old->p_pmt_handle );
1199 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
1202 /* treat the new programs list */
1203 p_pgrm = p_new_pat->p_first_program;
1207 msg_Dbg( p_input, "New program: %d", p_pgrm->i_number );
1209 /* If program = 0, we're having info about NIT not PMT */
1210 if( p_pgrm->i_number )
1212 /* Add this program */
1213 p_new_pgrm = input_AddProgram( p_input, p_pgrm->i_number,
1214 sizeof( pgrm_ts_data_t ) );
1216 p_pgrm_demux = (pgrm_ts_data_t *)p_new_pgrm->p_demux_data;
1217 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
1219 /* Add the PMT ES to this program */
1220 p_current_es = input_AddES( p_input, p_new_pgrm,
1221 (uint16_t)p_pgrm->i_pid, UNKNOWN_ES,
1222 NULL, sizeof(es_ts_data_t) );
1223 p_current_es->i_fourcc = VLC_FOURCC( 'p', 'm', 't', ' ' );
1224 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
1225 p_es_demux->b_psi = 1;
1226 p_es_demux->i_psi_type = PSI_IS_PMT;
1227 p_es_demux->p_psi_section = NULL;
1228 p_es_demux->i_continuity_counter = 0xFF;
1230 /* Create a PMT decoder */
1231 p_pgrm_demux->p_pmt_handle = (dvbpsi_handle *)
1232 dvbpsi_AttachPMT( p_pgrm->i_number,
1233 (dvbpsi_pmt_callback) &TS_DVBPSI_HandlePMT,
1236 if( p_pgrm_demux->p_pmt_handle == NULL )
1238 msg_Err( p_input, "could not create PMT decoder" );
1239 p_input->b_error = 1;
1244 p_pgrm = p_pgrm->p_next;
1247 p_stream_data->i_pat_version = p_new_pat->i_version;
1249 vlc_mutex_unlock( &p_input->stream.stream_lock );
1253 /*****************************************************************************
1254 * HandlePMT: will treat a PMT returned by dvbpsi
1255 *****************************************************************************/
1256 static void TS_DVBPSI_HandlePMT( input_thread_t * p_input,
1257 dvbpsi_pmt_t * p_new_pmt )
1259 dvbpsi_pmt_es_t * p_es;
1260 pgrm_descriptor_t * p_pgrm;
1261 es_descriptor_t * p_new_es;
1262 pgrm_ts_data_t * p_pgrm_demux;
1263 vlc_bool_t b_vls_compat = config_GetInt( p_input, "vls-backwards-compat" );
1265 vlc_mutex_lock( &p_input->stream.stream_lock );
1267 p_pgrm = input_FindProgram( p_input, p_new_pmt->i_program_number );
1269 if( p_pgrm == NULL )
1271 msg_Warn( p_input, "PMT of unreferenced program found" );
1275 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
1276 p_pgrm_demux->i_pcr_pid = p_new_pmt->i_pcr_pid;
1278 if( ( p_new_pmt->b_current_next &&
1279 ( p_new_pmt->i_version != p_pgrm_demux->i_pmt_version ) ) ||
1280 p_pgrm_demux->i_pmt_version == PMT_UNINITIALIZED )
1282 dvbpsi_descriptor_t *p_dr = p_new_pmt->p_first_descriptor;
1285 msg_Dbg( p_input, "Processing PMT for program %d version %d",
1286 p_new_pmt->i_program_number, p_new_pmt->i_version );
1288 /* Delete all ES in this program except the PSI. We start from the
1289 * end because i_es_number gets decremented after each deletion. */
1290 for( i_loop = p_pgrm->i_es_number ; i_loop > 0 ; )
1292 es_ts_data_t * p_es_demux;
1295 p_es_demux = (es_ts_data_t *)
1296 p_pgrm->pp_es[i_loop]->p_demux_data;
1297 if ( !p_es_demux->b_psi )
1299 input_DelES( p_input, p_pgrm->pp_es[i_loop] );
1304 while( p_dr && ( p_dr->i_tag != 0x1d ) )
1305 p_dr = p_dr->p_next;
1308 msg_Warn( p_input, "found IOD descriptor" );
1309 MP4_IODParse( &p_pgrm_demux->iod, p_dr->i_length, p_dr->p_data );
1312 p_es = p_new_pmt->p_first_es;
1315 vlc_fourcc_t i_fourcc;
1316 int i_size, i_cat, i_stream_id = 0;
1317 es_ts_data_t demux_data;
1318 BITMAPINFOHEADER *p_bih = NULL;
1319 WAVEFORMATEX *p_wf = NULL;
1322 memset( &demux_data, 0, sizeof(es_ts_data_t) );
1325 switch( p_es->i_type )
1327 case MPEG1_VIDEO_ES:
1328 case MPEG2_VIDEO_ES:
1329 case MPEG2_MOTO_VIDEO_ES:
1330 i_fourcc = VLC_FOURCC('m','p','g','v');
1333 case MPEG1_AUDIO_ES:
1334 case MPEG2_AUDIO_ES:
1335 i_fourcc = VLC_FOURCC('m','p','g','a');
1339 if ( !b_vls_compat )
1340 i_fourcc = VLC_FOURCC('a','5','2',' ');
1342 i_fourcc = VLC_FOURCC('a','5','2','b');
1347 if ( !b_vls_compat )
1348 i_fourcc = VLC_FOURCC('s','p','u',' ');
1350 i_fourcc = VLC_FOURCC('s','p','u','b');
1355 i_fourcc = VLC_FOURCC('l','p','c','m');
1360 i_fourcc = VLC_FOURCC('s','d','d','s');
1365 i_fourcc = VLC_FOURCC('d','t','s',' ');
1370 i_fourcc = VLC_FOURCC('a','5','2','b');
1375 i_fourcc = VLC_FOURCC('s','p','u','b');
1379 case LPCMB_AUDIO_ES:
1380 i_fourcc = VLC_FOURCC('l','p','c','b');
1384 case MPEG4_VIDEO_ES:
1385 i_fourcc = VLC_FOURCC('m','p','4','v');
1389 case MPEG4_AUDIO_ES:
1390 i_fourcc = VLC_FOURCC('m','p','4','a');
1394 case MSCODEC_VIDEO_ES:
1395 i_fourcc = VLC_FOURCC(0,0,0,0); /* fixed later */
1399 case PES_PRIVATE_ES:
1400 /* We need to check a descriptor to find the real codec */
1401 i_fourcc = VLC_FOURCC(0,0,0,0); /* fixed later */
1411 if( p_es->i_type == MPEG4_VIDEO_ES ||
1412 p_es->i_type == MPEG4_AUDIO_ES )
1414 /* mpeg4 stream, search sl_descriptor */
1415 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1417 while( p_dr && ( p_dr->i_tag != 0x1f ) ) p_dr = p_dr->p_next;
1419 if( p_dr && p_dr->i_length == 2 )
1421 int i_es_descr_index;
1423 demux_data.i_es_id =
1424 ( p_dr->p_data[0] << 8 ) | p_dr->p_data[1];
1425 demux_data.p_es_descr = NULL;
1427 msg_Warn( p_input, "found SL_descriptor" );
1428 for( i_es_descr_index = 0; i_es_descr_index < 255;
1429 i_es_descr_index++ )
1431 if( p_pgrm_demux->iod.es_descr[i_es_descr_index].b_ok &&
1432 p_pgrm_demux->iod.es_descr[i_es_descr_index].i_es_id == demux_data.i_es_id )
1434 demux_data.p_es_descr =
1435 &p_pgrm_demux->iod.es_descr[i_es_descr_index];
1441 if( demux_data.p_es_descr != NULL )
1443 #define DESCR demux_data.p_es_descr->dec_descr
1444 demux_data.b_mpeg4 = 1;
1447 switch( DESCR.i_streamType )
1449 case 0x04: /* VisualStream */
1451 switch( DESCR.i_objectTypeIndication )
1454 i_fourcc = VLC_FOURCC('m','p','4','v'); // mpeg4
1462 i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg2
1465 i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg1
1468 i_fourcc = VLC_FOURCC( 'j','p','e','g' ); // mpeg1
1475 case 0x05: /* AudioStream */
1477 switch( DESCR.i_objectTypeIndication )
1480 i_fourcc = VLC_FOURCC('m','p','4','a'); // mpeg4
1485 i_fourcc = VLC_FOURCC('m','p','4','a');// mpeg2 aac
1488 i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg2
1491 i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg1
1507 i_size = sizeof( BITMAPINFOHEADER ) +
1508 DESCR.i_decoder_specific_info_len;
1509 p_bih = malloc( i_size );
1510 p_bih->biSize = i_size;
1512 p_bih->biHeight = 0;
1513 p_bih->biPlanes = 1;
1514 p_bih->biBitCount = 0;
1515 p_bih->biCompression = 0;
1516 p_bih->biSizeImage = 0;
1517 p_bih->biXPelsPerMeter = 0;
1518 p_bih->biYPelsPerMeter = 0;
1519 p_bih->biClrUsed = 0;
1520 p_bih->biClrImportant = 0;
1522 DESCR.p_decoder_specific_info,
1523 DESCR.i_decoder_specific_info_len );
1526 i_size = sizeof( WAVEFORMATEX ) +
1527 DESCR.i_decoder_specific_info_len;
1528 p_wf = malloc( i_size );
1529 p_wf->wFormatTag = 0xffff;
1530 p_wf->nChannels = 0;
1531 p_wf->nSamplesPerSec = 0;
1532 p_wf->nAvgBytesPerSec = 0;
1533 p_wf->nBlockAlign = 1;
1534 p_wf->wBitsPerSample = 0;
1535 p_wf->cbSize = DESCR.i_decoder_specific_info_len;
1537 DESCR.p_decoder_specific_info,
1538 DESCR.i_decoder_specific_info_len );
1547 "mpeg4 stream without (valid) sl_descriptor" );
1548 demux_data.b_mpeg4 = 0;
1552 else if( p_es->i_type == MSCODEC_VIDEO_ES )
1554 /* crapy ms codec stream, search private descriptor */
1555 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1557 while( p_dr && ( p_dr->i_tag != 0xa0 ) ) p_dr = p_dr->p_next;
1559 if( p_dr && p_dr->i_length >= 8 )
1562 i_fourcc = VLC_FOURCC( p_dr->p_data[0], p_dr->p_data[1],
1563 p_dr->p_data[2], p_dr->p_data[3] );
1565 i_bih_size = (p_dr->p_data[8] << 8) | p_dr->p_data[9];
1566 i_size = sizeof( BITMAPINFOHEADER ) + i_bih_size;
1568 p_bih = malloc( i_size );
1569 p_bih->biSize = i_size;
1570 p_bih->biWidth = ( p_dr->p_data[4] << 8 )|p_dr->p_data[5];
1571 p_bih->biHeight = ( p_dr->p_data[6] << 8 )|p_dr->p_data[7];
1572 p_bih->biPlanes = 1;
1573 p_bih->biBitCount = 0;
1574 p_bih->biCompression = 0;
1575 p_bih->biSizeImage = 0;
1576 p_bih->biXPelsPerMeter = 0;
1577 p_bih->biYPelsPerMeter = 0;
1578 p_bih->biClrUsed = 0;
1579 p_bih->biClrImportant = 0;
1580 memcpy( &p_bih[1], &p_dr->p_data[10], i_bih_size );
1584 msg_Warn( p_input, "private ms-codec stream without bih "
1585 "private sl_descriptor" );
1590 else if( p_es->i_type == PES_PRIVATE_ES )
1592 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1593 /* We have to find a descriptor giving the right codec */
1595 for(p_dr = p_es->p_first_descriptor; p_dr; p_dr = p_dr->p_next)
1597 if( p_dr->i_tag == 0x6a )
1600 i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' );
1603 else if( p_dr->i_tag == 0x59 )
1606 i_fourcc = VLC_FOURCC( 'd', 'v', 'b', 's' );
1610 if( i_fourcc == VLC_FOURCC(0,0,0,0) )
1613 "Unknown codec/type for Private PES stream" );
1617 if( i_cat == AUDIO_ES || i_cat == SPU_ES )
1619 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1620 while( p_dr && ( p_dr->i_tag != 0x0a ) ) p_dr = p_dr->p_next;
1624 dvbpsi_iso639_dr_t *p_decoded =
1625 dvbpsi_DecodeISO639Dr( p_dr );
1626 if( p_decoded->i_code_count > 0 )
1628 const iso639_lang_t * p_iso;
1629 p_iso = GetLang_2T((char*)p_decoded->i_iso_639_code);
1633 if( p_iso->psz_native_name[0] )
1635 p_iso->psz_native_name, 20 );
1638 p_iso->psz_eng_name, 20 );
1642 strncpy( psz_desc, p_decoded->i_iso_639_code, 3 );
1646 switch( p_es->i_type )
1648 case MPEG1_AUDIO_ES:
1649 case MPEG2_AUDIO_ES:
1650 strcat( psz_desc, " (mpeg)" );
1653 case LPCMB_AUDIO_ES:
1654 strcat( psz_desc, " (lpcm)" );
1658 strcat( psz_desc, " (A52)" );
1660 case MPEG4_AUDIO_ES:
1661 strcat( psz_desc, " (aac)" );
1667 p_new_es = input_AddES( p_input, p_pgrm, (uint16_t)p_es->i_pid,
1668 i_cat, psz_desc, sizeof( es_ts_data_t ) );
1669 if( p_new_es == NULL )
1671 msg_Err( p_input, "could not add ES %d", p_es->i_pid );
1672 p_input->b_error = 1;
1675 p_new_es->i_fourcc = i_fourcc;
1676 p_new_es->i_stream_id = i_stream_id;
1677 p_new_es->p_bitmapinfoheader = (void*)p_bih;
1678 p_new_es->p_waveformatex = (void*)p_wf;
1679 memcpy( p_new_es->p_demux_data, &demux_data,
1680 sizeof(es_ts_data_t) );
1682 ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter =
1685 p_es = p_es->p_next;
1688 /* if no program is selected :*/
1689 if( !p_input->stream.p_selected_program )
1691 pgrm_descriptor_t * p_pgrm_to_select;
1692 uint16_t i_id = (uint16_t)config_GetInt( p_input, "program" );
1694 if( i_id != 0 ) /* if user specified a program */
1696 p_pgrm_to_select = input_FindProgram( p_input, i_id );
1698 if( p_pgrm_to_select && p_pgrm_to_select == p_pgrm )
1699 p_input->pf_set_program( p_input, p_pgrm_to_select );
1702 p_input->pf_set_program( p_input, p_pgrm );
1704 /* if the pmt belongs to the currently selected program, we
1705 * reselect it to update its ES */
1706 else if( p_pgrm == p_input->stream.p_selected_program )
1708 p_input->pf_set_program( p_input, p_pgrm );
1711 p_pgrm_demux->i_pmt_version = p_new_pmt->i_version;
1712 p_input->stream.b_changed = 1;
1714 vlc_mutex_unlock( &p_input->stream.stream_lock );