1 /*****************************************************************************
2 * demuxstream.c: Read an MPEG stream from the satellite and stream it
3 *****************************************************************************
4 * Copyright (C) 2003 VideoLAN
5 * $Id: demuxstream.c,v 1.1 2003/11/06 16:06:28 massiot Exp $
7 * Authors: Henri Fallon <henri@via.ecp.fr>
8 * Johan Bilien <jobi@via.ecp.fr>
9 * Laurent Aimar <fenrir@via.ecp.fr>
10 * Christophe Massiot <massiot@via.ecp.fr>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
25 *****************************************************************************/
29 * The goal of this module is to stream packets coming from a DVB interface
30 * as fast as possible onto the network, like VLS does. This is a copy/paste
31 * from modules/demux/mpeg/ts.c, because I need to parse the PMT to set
32 * the demux filters in the satellite module. So I need the full TS module.
33 * It would probably have been better not to copy/paste and use some kind
34 * of hooks, but it is too complicated for me. Use this module that way :
36 * vlc satellite/demuxstream: --program 4242 --demuxstream-mrl \
37 * udp:192.168.255.1:1234
39 * Also note that this module doesn't rebuild the PAT/PMT, and doesn't
40 * filter the PIDs : it just takes whatever comes from the DVB interface
41 * and sends it to the network. The client VLC should have no problem to
42 * deal with it, but other implementations will probably die.
44 * This file is part of the Dreambox port of VLC.
48 /*****************************************************************************
50 *****************************************************************************/
55 #include <vlc/input.h>
59 #if defined MODULE_NAME_IS_demuxstream
60 # ifdef HAVE_DVBPSI_DR_H
61 # include <dvbpsi/dvbpsi.h>
62 # include <dvbpsi/descriptor.h>
63 # include <dvbpsi/pat.h>
64 # include <dvbpsi/pmt.h>
65 # include <dvbpsi/dr.h>
68 # include "descriptor.h"
69 # include "tables/pat.h"
70 # include "tables/pmt.h"
71 # include "descriptors/dr.h"
75 #include "mpeg/system.h"
79 /*****************************************************************************
81 *****************************************************************************/
82 #define TS_READ_ONCE 7
83 #define DEFAULT_PORT 1234
85 /*****************************************************************************
87 *****************************************************************************/
96 /*****************************************************************************
98 *****************************************************************************/
99 static int Activate ( vlc_object_t * );
100 static void Deactivate ( vlc_object_t * );
101 static int Demux ( input_thread_t * );
103 #if defined MODULE_NAME_IS_demuxstream_old
104 static void TSDemuxPSI ( input_thread_t *, data_packet_t *,
105 es_descriptor_t *, vlc_bool_t );
106 static void TSDecodePAT( input_thread_t *, es_descriptor_t *);
107 static void TSDecodePMT( input_thread_t *, es_descriptor_t *);
108 #define PSI_CALLBACK TSDemuxPSI
109 #elif defined MODULE_NAME_IS_demuxstream
110 static void TS_DVBPSI_DemuxPSI ( input_thread_t *, data_packet_t *,
111 es_descriptor_t *, vlc_bool_t );
112 static void TS_DVBPSI_HandlePAT ( input_thread_t *, dvbpsi_pat_t * );
113 static void TS_DVBPSI_HandlePMT ( input_thread_t *, dvbpsi_pmt_t * );
114 #define PSI_CALLBACK TS_DVBPSI_DemuxPSI
117 /*****************************************************************************
119 *****************************************************************************/
120 #define VLS_BACKWARDS_COMPAT_TEXT N_("Compatibility with pre-0.4 VLS")
121 #define VLS_BACKWARDS_COMPAT_LONGTEXT N_( \
122 "The protocol for transmitting A/52 audio streams changed between VLC " \
123 "0.3.x and 0.4. By default VLC assumes you have the latest VLS. In case " \
124 "you're using an old version, select this option.")
126 #define BUGGY_PSI_TEXT N_("Buggy PSI")
127 #define BUGGY_PSI_LONGTEXT N_( \
128 "If you have a stream whose PSI packets do not feature incremented " \
129 "continuity counters, select this option.")
131 #define MRL_TEXT N_("Output MRL")
134 #if defined MODULE_NAME_IS_demuxstream_old
135 set_description( _("ISO 13818-1 MPEG Transport Stream demuxstream") );
136 set_capability( "demux", 0 );
137 add_shortcut( "demuxstream_old" );
138 #elif defined MODULE_NAME_IS_demuxstream
139 set_description( _("ISO 13818-1 MPEG Transport Stream demuxstream (libdvbpsi)") );
140 set_capability( "demux", 0 );
141 add_shortcut( "demuxstream" );
143 add_category_hint( N_("Miscellaneous"), NULL, VLC_TRUE );
144 add_bool( "vls-backwards-compat", 0, NULL,
145 VLS_BACKWARDS_COMPAT_TEXT, VLS_BACKWARDS_COMPAT_LONGTEXT, VLC_TRUE );
146 add_bool( "buggy-psi", 0, NULL, BUGGY_PSI_TEXT, BUGGY_PSI_LONGTEXT, VLC_TRUE );
147 add_string( "demuxstream-mrl", "", NULL, MRL_TEXT, NULL, VLC_FALSE );
148 set_callbacks( Activate, Deactivate );
151 /*****************************************************************************
152 * Activate: initialize TS structures
153 *****************************************************************************/
154 static int Activate( vlc_object_t * p_this )
156 input_thread_t * p_input = (input_thread_t *)p_this;
157 demux_sys_t * p_demux;
158 es_descriptor_t * p_pat_es;
159 es_ts_data_t * p_demux_data;
160 stream_ts_data_t * p_stream_data;
162 char * psz_mrl = config_GetPsz( p_input, "demuxstream-mrl" );
163 char * psz_parser = psz_mrl;
167 network_socket_t socket_desc;
169 /* Open the output socket */
170 if ( psz_mrl == NULL || !*psz_mrl )
172 msg_Err( p_input, "invalid demuxstream-mrl" );
176 if ( strncmp( psz_mrl, "udp:", 4 ) )
178 msg_Err( p_input, "demuxstream-mrl should start with udp: (%s)",
184 while ( *psz_parser == '/' )
189 psz_dst_addr = psz_parser;
192 if ( *psz_parser == '[' )
194 while( *psz_parser && *psz_parser != ']' )
199 while( *psz_parser && *psz_parser != ':' )
203 if( *psz_parser == ':' )
207 i_dst_port = atoi( psz_parser );
209 if( i_dst_port <= 0 )
211 i_dst_port = DEFAULT_PORT;
214 socket_desc.i_type = NETWORK_UDP;
215 socket_desc.psz_server_addr = psz_dst_addr;
216 socket_desc.i_server_port = i_dst_port;
217 socket_desc.psz_bind_addr = "";
218 socket_desc.i_bind_port = 0;
219 socket_desc.i_ttl = 0;
220 p_input->p_private = (void*)&socket_desc;
221 if( !( p_network = module_Need( p_input,
224 msg_Err( p_input, "failed to open a connection (udp)" );
225 return( VLC_EGENERIC );
227 module_Unneed( p_input, p_network );
229 /* Set the demux function */
230 p_input->pf_demux = Demux;
231 p_input->pf_demux_control = demux_vaControlDefault;
234 /* XXX Unused already done by src/input.c */
235 /* Initialize access plug-in structures. */
236 if( p_input->i_mtu == 0 )
239 msg_Dbg( p_input, "using default mtu (%d) with bufsize (%d)\n",
240 p_input->i_mtu, INPUT_DEFAULT_BUFSIZE );
241 p_input->i_bufsize = INPUT_DEFAULT_BUFSIZE;
245 /* Have a peep at the show. */
246 if( input_Peek( p_input, &p_peek, 1 ) < 1 )
248 msg_Err( p_input, "cannot peek()" );
252 if( *p_peek != TS_SYNC_CODE )
254 msg_Err( p_input, "this does not look like a TS stream, continuing" );
257 /* Adapt the bufsize for our only use. */
258 if( p_input->i_mtu != 0 )
260 /* Have minimum granularity to avoid bottlenecks at the input level. */
261 p_input->i_bufsize = (p_input->i_mtu / TS_PACKET_SIZE) * TS_PACKET_SIZE;
264 p_demux = p_input->p_demux_data = malloc( sizeof(demux_sys_t ) );
265 if( p_demux == NULL )
270 p_demux->i_handle = socket_desc.i_handle;
272 p_input->p_private = (void*)&p_demux->mpeg;
273 p_demux->p_module = module_Need( p_input, "mpeg-system", NULL );
274 if( p_demux->p_module == NULL )
276 free( p_input->p_demux_data );
280 vlc_mutex_lock( &p_input->stream.stream_lock );
282 if( input_InitStream( p_input, sizeof( stream_ts_data_t ) ) == -1 )
284 module_Unneed( p_input, p_demux->p_module );
285 free( p_input->p_demux_data );
289 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
290 p_stream_data->i_pat_version = PAT_UNINITIALIZED ;
291 p_stream_data->b_buggy_psi = config_GetInt( p_input, "buggy-psi" );
293 #ifdef MODULE_NAME_IS_demuxstream
294 p_stream_data->p_pat_handle = (dvbpsi_handle *)
295 dvbpsi_AttachPAT( (dvbpsi_pat_callback) &TS_DVBPSI_HandlePAT, p_input );
297 if( p_stream_data->p_pat_handle == NULL )
299 msg_Err( p_input, "could not create PAT decoder" );
300 module_Unneed( p_input, p_demux->p_module );
301 free( p_input->p_demux_data );
306 /* We'll have to catch the PAT in order to continue
307 * Then the input will catch the PMT and then the others ES
308 * The PAT es is indepedent of any program. */
309 p_pat_es = input_AddES( p_input, NULL, 0x00,
310 UNKNOWN_ES, NULL, sizeof( es_ts_data_t ) );
311 p_pat_es->i_fourcc = VLC_FOURCC( 'p', 'a', 't', ' ' );
312 p_demux_data = (es_ts_data_t *)p_pat_es->p_demux_data;
313 p_demux_data->b_psi = 1;
314 p_demux_data->i_psi_type = PSI_IS_PAT;
315 p_demux_data->p_psi_section = malloc(sizeof(psi_section_t));
316 p_demux_data->p_psi_section->b_is_complete = 1;
317 p_demux_data->i_continuity_counter = 0xFF;
319 vlc_mutex_unlock( &p_input->stream.stream_lock );
324 /*****************************************************************************
325 * Deactivate: deinitialize TS structures
326 *****************************************************************************/
327 static void Deactivate( vlc_object_t * p_this )
329 input_thread_t * p_input = (input_thread_t *)p_this;
331 module_Unneed( p_input, p_input->p_demux_data->p_module );
332 close( p_input->p_demux_data->i_handle );
333 free( p_input->p_demux_data );
336 /*****************************************************************************
337 * Demux: reads and demuxes data packets
338 *****************************************************************************
339 * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
341 *****************************************************************************/
342 static int Demux( input_thread_t * p_input )
344 demux_sys_t * p_demux = p_input->p_demux_data;
345 int i_read_once = TS_READ_ONCE;
347 data_packet_t * p_data[i_read_once];
348 struct iovec vector[i_read_once];
350 for( i = 0; i < i_read_once; i++ )
354 i_result = p_demux->mpeg.pf_read_ts( p_input, &p_data[i] );
361 vector[i].iov_base = p_data[i]->p_demux_start;
362 vector[i].iov_len = TS_PACKET_SIZE;
365 /* Send the buffer immediately. */
366 writev( p_demux->i_handle, vector, i );
368 for( j = 0; j < i; j++ )
370 p_demux->mpeg.pf_demux_ts( p_input, p_data[j],
371 (psi_callback_t) &PSI_CALLBACK );
378 #if defined MODULE_NAME_IS_demuxstream_old
380 * PSI demultiplexing and decoding without libdvbpsi
383 /*****************************************************************************
384 * DemuxPSI : makes up complete PSI data
385 *****************************************************************************/
386 static void TSDemuxPSI( input_thread_t * p_input, data_packet_t * p_data,
387 es_descriptor_t * p_es, vlc_bool_t b_unit_start )
389 es_ts_data_t * p_demux_data;
391 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
393 #define p_psi (p_demux_data->p_psi_section)
394 #define p (p_data->p_payload_start)
398 /* unit_start set to 1 -> presence of a pointer field
399 * (see ISO/IEC 13818 (2.4.4.2) which should be set to 0x00 */
400 if( (uint8_t)p[0] != 0x00 )
403 "non-zero pointer field found, trying to continue" );
411 /* This is the begining of a new section */
413 if( ((uint8_t)(p[1]) & 0xc0) != 0x80 )
415 msg_Warn( p_input, "invalid PSI packet" );
420 p_psi->i_section_length = ((p[1] & 0xF) << 8) | p[2];
421 p_psi->b_section_complete = 0;
422 p_psi->i_read_in_section = 0;
423 p_psi->i_section_number = (uint8_t)p[6];
425 if( p_psi->b_is_complete || p_psi->i_section_number == 0 )
427 /* This is a new PSI packet */
428 p_psi->b_is_complete = 0;
430 p_psi->i_version_number = ( p[5] >> 1 ) & 0x1f;
431 p_psi->i_last_section_number = (uint8_t)p[7];
433 /* We'll write at the begining of the buffer */
434 p_psi->p_current = p_psi->buffer;
438 if( p_psi->b_section_complete )
440 /* New Section of an already started PSI */
441 p_psi->b_section_complete = 0;
443 if( p_psi->i_version_number != (( p[5] >> 1 ) & 0x1f) )
446 "PSI version differs inside same PAT" );
449 if( p_psi->i_section_number + 1 != (uint8_t)p[6] )
452 "PSI Section discontinuity, packet lost?" );
456 p_psi->i_section_number++;
460 msg_Warn( p_input, "got unexpected new PSI section" );
467 if( !p_psi->b_trash )
470 if( (p_data->p_payload_end - p) >=
471 ( p_psi->i_section_length - p_psi->i_read_in_section ) )
473 /* The end of the section is in this TS packet */
474 memcpy( p_psi->p_current, p,
475 (p_psi->i_section_length - p_psi->i_read_in_section) );
477 p_psi->b_section_complete = 1;
479 (p_psi->i_section_length - p_psi->i_read_in_section);
481 if( p_psi->i_section_number == p_psi->i_last_section_number )
483 /* This was the last section of PSI */
484 p_psi->b_is_complete = 1;
486 switch( p_demux_data->i_psi_type)
489 TSDecodePAT( p_input, p_es );
492 TSDecodePMT( p_input, p_es );
495 msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
501 memcpy( p_psi->buffer, p, p_data->p_payload_end - p );
502 p_psi->i_read_in_section += p_data->p_payload_end - p;
504 p_psi->p_current += p_data->p_payload_end - p;
511 input_DeletePacket( p_input->p_method_data, p_data );
516 /*****************************************************************************
517 * DecodePAT : Decodes Programm association table and deal with it
518 *****************************************************************************/
519 static void TSDecodePAT( input_thread_t * p_input, es_descriptor_t * p_es )
521 stream_ts_data_t * p_stream_data;
522 es_ts_data_t * p_demux_data;
524 pgrm_descriptor_t * p_pgrm;
525 es_descriptor_t * p_current_es;
526 byte_t * p_current_data;
528 int i_section_length, i_program_id, i_pmt_pid;
529 int i_loop, i_current_section;
531 vlc_bool_t b_changed = 0;
533 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
534 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
536 #define p_psi (p_demux_data->p_psi_section)
538 /* Not so fast, Mike ! If the PAT version has changed, we first check
539 * that its content has really changed before doing anything */
540 if( p_stream_data->i_pat_version != p_psi->i_version_number )
542 int i_programs = p_input->stream.i_pgrm_number;
544 p_current_data = p_psi->buffer;
548 i_section_length = ((uint32_t)(p_current_data[1] & 0xF) << 8) |
550 i_current_section = (uint8_t)p_current_data[6];
553 ( i_loop < (i_section_length - 9) / 4 ) && !b_changed;
556 i_program_id = ( (uint32_t)*(p_current_data + i_loop * 4 + 8) << 8 )
557 | *(p_current_data + i_loop * 4 + 9);
558 i_pmt_pid = ( ((uint32_t)*(p_current_data + i_loop * 4 + 10) & 0x1F)
560 | *(p_current_data + i_loop * 4 + 11);
564 if( (p_pgrm = input_FindProgram( p_input, i_program_id ))
565 && (p_current_es = input_FindES( p_input, i_pmt_pid ))
566 && p_current_es->p_pgrm == p_pgrm
567 && p_current_es->i_id == i_pmt_pid
568 && ((es_ts_data_t *)p_current_es->p_demux_data)->b_psi
569 && ((es_ts_data_t *)p_current_es->p_demux_data)
570 ->i_psi_type == PSI_IS_PMT )
581 p_current_data += 3 + i_section_length;
583 } while( ( i_current_section < p_psi->i_last_section_number )
586 /* If we didn't find the expected amount of programs, the PAT has
587 * changed. Otherwise, it only changed if b_changed is already != 0 */
588 b_changed = b_changed || i_programs;
593 /* PAT has changed. We are going to delete all programs and
594 * create new ones. We chose not to only change what was needed
595 * as a PAT change may mean the stream is radically changing and
596 * this is a secure method to avoid crashes */
597 es_ts_data_t * p_es_demux;
598 pgrm_ts_data_t * p_pgrm_demux;
600 p_current_data = p_psi->buffer;
602 /* Delete all programs */
603 while( p_input->stream.i_pgrm_number )
605 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
610 i_section_length = ((uint32_t)(p_current_data[1] & 0xF) << 8) |
612 i_current_section = (uint8_t)p_current_data[6];
614 for( i_loop = 0; i_loop < (i_section_length - 9) / 4 ; i_loop++ )
616 i_program_id = ( (uint32_t)*(p_current_data + i_loop * 4 + 8) << 8 )
617 | *(p_current_data + i_loop * 4 + 9);
618 i_pmt_pid = ( ((uint32_t)*(p_current_data + i_loop * 4 + 10) & 0x1F)
620 | *(p_current_data + i_loop * 4 + 11);
622 /* If program = 0, we're having info about NIT not PMT */
625 /* Add this program */
626 p_pgrm = input_AddProgram( p_input, i_program_id,
627 sizeof( pgrm_ts_data_t ) );
629 /* whatis the PID of the PMT of this program */
630 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
631 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
633 /* Add the PMT ES to this program */
634 p_current_es = input_AddES( p_input, p_pgrm,(uint16_t)i_pmt_pid,
635 UNKNOWN_ES, NULL, sizeof( es_ts_data_t) );
636 p_current_es->i_fourcc = VLC_FOURCC( 'p', 'm', 't', ' ' );
637 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
638 p_es_demux->b_psi = 1;
639 p_es_demux->i_psi_type = PSI_IS_PMT;
641 p_es_demux->p_psi_section =
642 malloc( sizeof( psi_section_t ) );
643 p_es_demux->p_psi_section->b_is_complete = 0;
644 p_es_demux->i_continuity_counter = 0xFF;
648 p_current_data += 3 + i_section_length;
650 } while( i_current_section < p_psi->i_last_section_number );
652 /* Go to the beginning of the next section */
653 p_stream_data->i_pat_version = p_psi->i_version_number;
660 /*****************************************************************************
661 * DecodePMT : decode a given Program Stream Map
662 * ***************************************************************************
663 * When the PMT changes, it may mean a deep change in the stream, and it is
664 * careful to delete the ES and add them again. If the PMT doesn't change,
665 * there no need to do anything.
666 *****************************************************************************/
667 static void TSDecodePMT( input_thread_t * p_input, es_descriptor_t * p_es )
670 pgrm_ts_data_t * p_pgrm_data;
671 es_ts_data_t * p_demux_data;
672 vlc_bool_t b_vls_compat = config_GetInt( p_input, "vls-backwards-compat" );
674 p_demux_data = (es_ts_data_t *)p_es->p_demux_data;
675 p_pgrm_data = (pgrm_ts_data_t *)p_es->p_pgrm->p_demux_data;
677 #define p_psi (p_demux_data->p_psi_section)
679 if( p_psi->i_version_number != p_pgrm_data->i_pmt_version )
681 es_descriptor_t * p_new_es;
682 es_ts_data_t * p_es_demux;
683 byte_t * p_current_data, * p_current_section;
684 int i_section_length,i_current_section;
685 int i_prog_info_length, i_loop;
686 int i_es_info_length, i_pid, i_stream_type;
688 p_current_section = p_psi->buffer;
689 p_current_data = p_psi->buffer;
691 p_pgrm_data->i_pcr_pid = ( ((uint32_t)*(p_current_section + 8) & 0x1F) << 8 ) |
692 *(p_current_section + 9);
695 /* Lock stream information */
696 vlc_mutex_lock( &p_input->stream.stream_lock );
698 /* Delete all ES in this program except the PSI. We start from the
699 * end because i_es_number gets decremented after each deletion. */
700 for( i_loop = p_es->p_pgrm->i_es_number ; i_loop ; )
703 p_es_demux = (es_ts_data_t *)
704 p_es->p_pgrm->pp_es[i_loop]->p_demux_data;
705 if ( ! p_es_demux->b_psi )
707 input_DelES( p_input, p_es->p_pgrm->pp_es[i_loop] );
711 /* Then add what we received in this PMT */
714 i_section_length = ( ((uint32_t)*(p_current_data + 1) & 0xF) << 8 ) |
715 *(p_current_data + 2);
716 i_current_section = (uint8_t)p_current_data[6];
717 i_prog_info_length = ( ((uint32_t)*(p_current_data + 10) & 0xF) << 8 ) |
718 *(p_current_data + 11);
720 /* For the moment we ignore program descriptors */
721 p_current_data += 12 + i_prog_info_length;
723 /* The end of the section, before the CRC is at
724 * p_current_section + i_section_length -1 */
725 while( p_current_data < p_current_section + i_section_length -1 )
727 i_stream_type = (int)p_current_data[0];
728 i_pid = ( ((uint32_t)*(p_current_data + 1) & 0x1F) << 8 ) |
729 *(p_current_data + 2);
730 i_es_info_length = ( ((uint32_t)*(p_current_data + 3) & 0xF) << 8 ) |
731 *(p_current_data + 4);
733 /* Tell the interface what kind of stream it is and select
734 * the required ones */
736 int i_fourcc, i_cat, i_stream_id;
738 switch( i_stream_type )
742 case MPEG2_MOTO_VIDEO_ES:
743 /* This isn't real, but we don't actually use
746 i_fourcc = VLC_FOURCC('m','p','g','v');
751 /* This isn't real, but we don't actually use
754 i_fourcc = VLC_FOURCC('m','p','g','a');
759 i_fourcc = VLC_FOURCC('a','5','2',' ');
761 i_fourcc = VLC_FOURCC('a','5','2','b');
766 i_fourcc = VLC_FOURCC('l','p','c','m');
772 i_fourcc = VLC_FOURCC('s','p','u',' ');
774 i_fourcc = VLC_FOURCC('s','p','u','b');
779 i_fourcc = VLC_FOURCC('s','d','d','s');
784 i_fourcc = VLC_FOURCC('d','t','s',' ');
788 /* 'b' stands for 'buggy' */
790 i_fourcc = VLC_FOURCC('a','5','2','b');
795 i_fourcc = VLC_FOURCC('l','p','c','b');
800 i_fourcc = VLC_FOURCC('s','p','u','b');
804 case AAC_ADTS_AUDIO_ES:
805 i_fourcc = VLC_FOURCC('m','p','4','a');
817 /* Add this ES to the program */
818 p_new_es = input_AddES( p_input, p_es->p_pgrm, (uint16_t)i_pid,
819 i_cat, NULL, sizeof( es_ts_data_t ) );
821 ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter = 0xFF;
823 p_new_es->i_stream_id = i_stream_id;
824 p_new_es->i_fourcc = i_fourcc;
828 p_current_data += 5 + i_es_info_length;
831 /* Go to the beginning of the next section*/
832 p_current_data += 3 + i_section_length;
836 } while( i_current_section < p_psi->i_last_section_number );
838 p_pgrm_data->i_pmt_version = p_psi->i_version_number;
840 /* if no program is selected :*/
841 if( !p_input->stream.p_selected_program )
843 pgrm_descriptor_t * p_pgrm_to_select;
844 uint16_t i_id = (uint16_t)config_GetInt( p_input, "program" );
846 if( i_id != 0 ) /* if user specified a program */
848 p_pgrm_to_select = input_FindProgram( p_input, i_id );
850 if( p_pgrm_to_select && p_pgrm_to_select == p_es->p_pgrm )
851 p_input->pf_set_program( p_input, p_pgrm_to_select );
854 p_input->pf_set_program( p_input, p_es->p_pgrm );
857 /* if the pmt belongs to the currently selected program, we
858 * reselect it to update its ES */
859 else if( p_es->p_pgrm == p_input->stream.p_selected_program )
861 p_input->pf_set_program( p_input, p_es->p_pgrm );
864 /* inform interface that stream has changed */
865 p_input->stream.b_changed = 1;
867 vlc_mutex_unlock( &p_input->stream.stream_lock );
873 #elif defined MODULE_NAME_IS_demuxstream
875 * PSI Decoding using libdvbpsi
878 /*****************************************************************************
879 * DemuxPSI : send the PSI to the right libdvbpsi decoder
880 *****************************************************************************/
881 static void TS_DVBPSI_DemuxPSI( input_thread_t * p_input,
882 data_packet_t * p_data,
883 es_descriptor_t * p_es,
884 vlc_bool_t b_unit_start )
886 es_ts_data_t * p_es_demux_data;
887 pgrm_ts_data_t * p_pgrm_demux_data;
888 stream_ts_data_t * p_stream_demux_data;
890 p_es_demux_data = (es_ts_data_t *)p_es->p_demux_data;
891 p_stream_demux_data = (stream_ts_data_t *) p_input->stream.p_demux_data;
893 switch( p_es_demux_data->i_psi_type)
897 (dvbpsi_handle)p_stream_demux_data->p_pat_handle,
898 p_data->p_demux_start );
901 p_pgrm_demux_data = ( pgrm_ts_data_t * )p_es->p_pgrm->p_demux_data;
903 (dvbpsi_handle)p_pgrm_demux_data->p_pmt_handle,
904 p_data->p_demux_start );
907 msg_Warn( p_input, "received unknown PSI in DemuxPSI" );
910 input_DeletePacket( p_input->p_method_data, p_data );
912 /*****************************************************************************
913 * MP4 specific functions
914 *****************************************************************************/
915 static int MP4_DescriptorLength( int *pi_data, uint8_t **pp_data )
918 unsigned int i_len = 0;
924 i_len = ( i_len << 7 ) + ( i_b&0x7f );
930 static int MP4_GetByte( int *pi_data, uint8_t **pp_data )
945 static int MP4_GetWord( int *pi_data, uint8_t **pp_data )
948 i1 = MP4_GetByte( pi_data, pp_data );
949 i2 = MP4_GetByte( pi_data, pp_data );
950 return( ( i1 << 8 ) | i2 );
952 static int MP4_Get3Bytes( int *pi_data, uint8_t **pp_data )
955 i1 = MP4_GetByte( pi_data, pp_data );
956 i2 = MP4_GetByte( pi_data, pp_data );
957 i3 = MP4_GetByte( pi_data, pp_data );
958 return( ( i1 << 16 ) | ( i2 << 8) | i3 );
961 static uint32_t MP4_GetDWord( int *pi_data, uint8_t **pp_data )
964 i1 = MP4_GetWord( pi_data, pp_data );
965 i2 = MP4_GetWord( pi_data, pp_data );
966 return( ( i1 << 16 ) | i2 );
969 static char* MP4_GetURL( int *pi_data, uint8_t **pp_data )
974 i_url_len = MP4_GetByte( pi_data, pp_data );
975 url = malloc( i_url_len + 1 );
976 for( i = 0; i < i_url_len; i++ )
978 url[i] = MP4_GetByte( pi_data, pp_data );
980 url[i_url_len] = '\0';
984 static void MP4_IODParse( iod_descriptor_t *p_iod, int i_data, uint8_t *p_data )
992 fprintf( stderr, "\n************ IOD ************" );
993 for( i = 0; i < 255; i++ )
995 p_iod->es_descr[i].b_ok = 0;
1004 p_iod->i_iod_label = MP4_GetByte( &i_data, &p_data );
1005 fprintf( stderr, "\n* iod_label:%d", p_iod->i_iod_label );
1006 fprintf( stderr, "\n* ===========" );
1007 fprintf( stderr, "\n* tag:0x%x", p_data[0] );
1009 if( MP4_GetByte( &i_data, &p_data ) != 0x02 )
1011 fprintf( stderr, "\n ERR: tag != 0x02" );
1015 i_iod_length = MP4_DescriptorLength( &i_data, &p_data );
1016 fprintf( stderr, "\n* length:%d", i_iod_length );
1017 if( i_iod_length > i_data )
1019 i_iod_length = i_data;
1022 p_iod->i_od_id = ( MP4_GetByte( &i_data, &p_data ) << 2 );
1023 i_flags = MP4_GetByte( &i_data, &p_data );
1024 p_iod->i_od_id |= i_flags >> 6;
1025 b_url = ( i_flags >> 5 )&0x01;
1027 fprintf( stderr, "\n* od_id:%d", p_iod->i_od_id );
1028 fprintf( stderr, "\n* url flag:%d", b_url );
1029 fprintf( stderr, "\n* includeInlineProfileLevel flag:%d", ( i_flags >> 4 )&0x01 );
1033 p_iod->psz_url = MP4_GetURL( &i_data, &p_data );
1034 fprintf( stderr, "\n* url string:%s", p_iod->psz_url );
1035 fprintf( stderr, "\n*****************************\n" );
1040 p_iod->psz_url = NULL;
1043 p_iod->i_ODProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
1044 p_iod->i_sceneProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
1045 p_iod->i_audioProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
1046 p_iod->i_visualProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
1047 p_iod->i_graphicsProfileLevelIndication = MP4_GetByte( &i_data, &p_data );
1049 fprintf( stderr, "\n* ODProfileLevelIndication:%d", p_iod->i_ODProfileLevelIndication );
1050 fprintf( stderr, "\n* sceneProfileLevelIndication:%d", p_iod->i_sceneProfileLevelIndication );
1051 fprintf( stderr, "\n* audioProfileLevelIndication:%d", p_iod->i_audioProfileLevelIndication );
1052 fprintf( stderr, "\n* visualProfileLevelIndication:%d", p_iod->i_visualProfileLevelIndication );
1053 fprintf( stderr, "\n* graphicsProfileLevelIndication:%d", p_iod->i_graphicsProfileLevelIndication );
1056 while( i_data > 0 && i_es_index < 255)
1058 int i_tag, i_length;
1060 uint8_t *p_data_sav;
1062 i_tag = MP4_GetByte( &i_data, &p_data );
1063 i_length = MP4_DescriptorLength( &i_data, &p_data );
1065 i_data_sav = i_data;
1066 p_data_sav = p_data;
1074 #define es_descr p_iod->es_descr[i_es_index]
1075 int i_decoderConfigDescr_length;
1076 fprintf( stderr, "\n* - ES_Descriptor length:%d", i_length );
1079 es_descr.i_es_id = MP4_GetWord( &i_data, &p_data );
1080 i_flags = MP4_GetByte( &i_data, &p_data );
1081 es_descr.b_streamDependenceFlag = ( i_flags >> 7 )&0x01;
1082 b_url = ( i_flags >> 6 )&0x01;
1083 es_descr.b_OCRStreamFlag = ( i_flags >> 5 )&0x01;
1084 es_descr.i_streamPriority = i_flags & 0x1f;
1085 fprintf( stderr, "\n* * streamDependenceFlag:%d", es_descr.b_streamDependenceFlag );
1086 fprintf( stderr, "\n* * OCRStreamFlag:%d", es_descr.b_OCRStreamFlag );
1087 fprintf( stderr, "\n* * streamPriority:%d", es_descr.i_streamPriority );
1089 if( es_descr.b_streamDependenceFlag )
1091 es_descr.i_dependOn_es_id = MP4_GetWord( &i_data, &p_data );
1092 fprintf( stderr, "\n* * dependOn_es_id:%d", es_descr.i_dependOn_es_id );
1097 es_descr.psz_url = MP4_GetURL( &i_data, &p_data );
1098 fprintf( stderr, "\n* url string:%s", es_descr.psz_url );
1102 es_descr.psz_url = NULL;
1105 if( es_descr.b_OCRStreamFlag )
1107 es_descr.i_OCR_es_id = MP4_GetWord( &i_data, &p_data );
1108 fprintf( stderr, "\n* * OCR_es_id:%d", es_descr.i_OCR_es_id );
1111 if( MP4_GetByte( &i_data, &p_data ) != 0x04 )
1113 fprintf( stderr, "\n* ERR missing DecoderConfigDescr" );
1117 i_decoderConfigDescr_length = MP4_DescriptorLength( &i_data, &p_data );
1119 fprintf( stderr, "\n* - DecoderConfigDesc length:%d", i_decoderConfigDescr_length );
1120 #define dec_descr es_descr.dec_descr
1121 dec_descr.i_objectTypeIndication = MP4_GetByte( &i_data, &p_data );
1122 i_flags = MP4_GetByte( &i_data, &p_data );
1123 dec_descr.i_streamType = i_flags >> 2;
1124 dec_descr.b_upStream = ( i_flags >> 1 )&0x01;
1125 dec_descr.i_bufferSizeDB = MP4_Get3Bytes( &i_data, &p_data );
1126 dec_descr.i_maxBitrate = MP4_GetDWord( &i_data, &p_data );
1127 dec_descr.i_avgBitrate = MP4_GetDWord( &i_data, &p_data );
1128 fprintf( stderr, "\n* * objectTypeIndication:0x%x", dec_descr.i_objectTypeIndication );
1129 fprintf( stderr, "\n* * streamType:0x%x", dec_descr.i_streamType );
1130 fprintf( stderr, "\n* * upStream:%d", dec_descr.b_upStream );
1131 fprintf( stderr, "\n* * bufferSizeDB:%d", dec_descr.i_bufferSizeDB );
1132 fprintf( stderr, "\n* * maxBitrate:%d", dec_descr.i_maxBitrate );
1133 fprintf( stderr, "\n* * avgBitrate:%d", dec_descr.i_avgBitrate );
1134 if( i_decoderConfigDescr_length > 13 && MP4_GetByte( &i_data, &p_data ) == 0x05 )
1137 dec_descr.i_decoder_specific_info_len =
1138 MP4_DescriptorLength( &i_data, &p_data );
1139 if( dec_descr.i_decoder_specific_info_len > 0 )
1141 dec_descr.p_decoder_specific_info =
1142 malloc( dec_descr.i_decoder_specific_info_len );
1144 for( i = 0; i < dec_descr.i_decoder_specific_info_len; i++ )
1146 dec_descr.p_decoder_specific_info[i] = MP4_GetByte( &i_data, &p_data );
1151 dec_descr.i_decoder_specific_info_len = 0;
1152 dec_descr.p_decoder_specific_info = NULL;
1156 #define sl_descr es_descr.sl_descr
1158 int i_SLConfigDescr_length;
1161 if( MP4_GetByte( &i_data, &p_data ) != 0x06 )
1163 fprintf( stderr, "\n* ERR missing SLConfigDescr" );
1167 i_SLConfigDescr_length = MP4_DescriptorLength( &i_data, &p_data );
1169 fprintf( stderr, "\n* - SLConfigDescr length:%d", i_SLConfigDescr_length );
1170 i_predefined = MP4_GetByte( &i_data, &p_data );
1171 fprintf( stderr, "\n* * i_predefined:0x%x", i_predefined );
1172 switch( i_predefined )
1176 sl_descr.b_useAccessUnitStartFlag = 0;
1177 sl_descr.b_useAccessUnitEndFlag = 0;
1178 sl_descr.b_useRandomAccessPointFlag = 0;
1179 //sl_descr.b_useRandomAccessUnitsOnlyFlag = 0;
1180 sl_descr.b_usePaddingFlag = 0;
1181 sl_descr.b_useTimeStampsFlags = 0;
1182 sl_descr.b_useIdleFlag = 0;
1183 sl_descr.b_durationFlag = 0; // FIXME FIXME
1184 sl_descr.i_timeStampResolution = 1000;
1185 sl_descr.i_OCRResolution = 0; // FIXME FIXME
1186 sl_descr.i_timeStampLength = 32;
1187 sl_descr.i_OCRLength = 0; // FIXME FIXME
1188 sl_descr.i_AU_Length = 0;
1189 sl_descr.i_instantBitrateLength= 0; // FIXME FIXME
1190 sl_descr.i_degradationPriorityLength= 0;
1191 sl_descr.i_AU_seqNumLength = 0;
1192 sl_descr.i_packetSeqNumLength = 0;
1193 if( sl_descr.b_durationFlag )
1195 sl_descr.i_timeScale = 0; // FIXME FIXME
1196 sl_descr.i_accessUnitDuration = 0; // FIXME FIXME
1197 sl_descr.i_compositionUnitDuration= 0; // FIXME FIXME
1199 if( !sl_descr.b_useTimeStampsFlags )
1201 sl_descr.i_startDecodingTimeStamp = 0; // FIXME FIXME
1202 sl_descr.i_startCompositionTimeStamp= 0; // FIXME FIXME
1207 fprintf( stderr, "\n* ERR unsupported SLConfigDescr predefined" );
1216 fprintf( stderr, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag, i_length );
1220 p_data = p_data_sav + i_length;
1221 i_data = i_data_sav - i_length;
1226 fprintf( stderr, "\n*****************************\n" );
1229 static void MP4_IODClean( iod_descriptor_t *p_iod )
1233 if( p_iod->psz_url )
1235 free( p_iod->psz_url );
1236 p_iod->psz_url = NULL;
1240 for( i = 0; i < 255; i++ )
1242 #define es_descr p_iod->es_descr[i]
1245 if( es_descr.psz_url )
1247 free( es_descr.psz_url );
1248 es_descr.psz_url = NULL;
1252 if( es_descr.dec_descr.p_decoder_specific_info != NULL )
1254 free( es_descr.dec_descr.p_decoder_specific_info );
1255 es_descr.dec_descr.p_decoder_specific_info = NULL;
1256 es_descr.dec_descr.i_decoder_specific_info_len = 0;
1265 /*****************************************************************************
1266 * HandlePAT: will treat a PAT returned by dvbpsi
1267 *****************************************************************************/
1268 static void TS_DVBPSI_HandlePAT( input_thread_t * p_input,
1269 dvbpsi_pat_t * p_new_pat )
1271 dvbpsi_pat_program_t * p_pgrm;
1272 pgrm_descriptor_t * p_new_pgrm;
1273 pgrm_ts_data_t * p_pgrm_demux;
1274 es_descriptor_t * p_current_es;
1275 es_ts_data_t * p_es_demux;
1276 stream_ts_data_t * p_stream_data;
1278 vlc_mutex_lock( &p_input->stream.stream_lock );
1280 p_stream_data = (stream_ts_data_t *)p_input->stream.p_demux_data;
1282 if( ( p_new_pat->b_current_next &&
1283 ( p_new_pat->i_version != p_stream_data->i_pat_version ) ) ||
1284 p_stream_data->i_pat_version == PAT_UNINITIALIZED )
1286 msg_Dbg( p_input, "Processing PAT version %d", p_new_pat->i_version );
1288 /* Delete all programs */
1289 while( p_input->stream.i_pgrm_number )
1291 pgrm_ts_data_t *p_pgrm_demux_old =
1292 (pgrm_ts_data_t *)p_input->stream.pp_programs[0]->p_demux_data;
1294 if( p_pgrm_demux_old->b_mpeg4 )
1296 MP4_IODClean( &p_pgrm_demux_old->iod );
1299 /* Delete old PMT decoder */
1300 if( p_pgrm_demux_old->p_pmt_handle )
1301 dvbpsi_DetachPMT( p_pgrm_demux_old->p_pmt_handle );
1303 input_DelProgram( p_input, p_input->stream.pp_programs[0] );
1306 /* treat the new programs list */
1307 p_pgrm = p_new_pat->p_first_program;
1311 msg_Dbg( p_input, "New program: %d", p_pgrm->i_number );
1313 /* If program = 0, we're having info about NIT not PMT */
1314 if( p_pgrm->i_number )
1316 /* Add this program */
1317 p_new_pgrm = input_AddProgram( p_input, p_pgrm->i_number,
1318 sizeof( pgrm_ts_data_t ) );
1320 p_pgrm_demux = (pgrm_ts_data_t *)p_new_pgrm->p_demux_data;
1321 p_pgrm_demux->i_pmt_version = PMT_UNINITIALIZED;
1323 /* Add the PMT ES to this program */
1324 p_current_es = input_AddES( p_input, p_new_pgrm,
1325 (uint16_t)p_pgrm->i_pid, UNKNOWN_ES,
1326 NULL, sizeof(es_ts_data_t) );
1327 p_current_es->i_fourcc = VLC_FOURCC( 'p', 'm', 't', ' ' );
1328 p_es_demux = (es_ts_data_t *)p_current_es->p_demux_data;
1329 p_es_demux->b_psi = 1;
1330 p_es_demux->i_psi_type = PSI_IS_PMT;
1331 p_es_demux->p_psi_section = NULL;
1332 p_es_demux->i_continuity_counter = 0xFF;
1334 /* Create a PMT decoder */
1335 p_pgrm_demux->p_pmt_handle = (dvbpsi_handle *)
1336 dvbpsi_AttachPMT( p_pgrm->i_number,
1337 (dvbpsi_pmt_callback) &TS_DVBPSI_HandlePMT,
1340 if( p_pgrm_demux->p_pmt_handle == NULL )
1342 msg_Err( p_input, "could not create PMT decoder" );
1343 p_input->b_error = 1;
1348 p_pgrm = p_pgrm->p_next;
1351 p_stream_data->i_pat_version = p_new_pat->i_version;
1353 vlc_mutex_unlock( &p_input->stream.stream_lock );
1357 /*****************************************************************************
1358 * HandlePMT: will treat a PMT returned by dvbpsi
1359 *****************************************************************************/
1360 static void TS_DVBPSI_HandlePMT( input_thread_t * p_input,
1361 dvbpsi_pmt_t * p_new_pmt )
1363 dvbpsi_pmt_es_t * p_es;
1364 pgrm_descriptor_t * p_pgrm;
1365 es_descriptor_t * p_new_es;
1366 pgrm_ts_data_t * p_pgrm_demux;
1367 vlc_bool_t b_vls_compat = config_GetInt( p_input, "vls-backwards-compat" );
1369 vlc_mutex_lock( &p_input->stream.stream_lock );
1371 p_pgrm = input_FindProgram( p_input, p_new_pmt->i_program_number );
1373 if( p_pgrm == NULL )
1375 msg_Warn( p_input, "PMT of unreferenced program found" );
1379 p_pgrm_demux = (pgrm_ts_data_t *)p_pgrm->p_demux_data;
1380 p_pgrm_demux->i_pcr_pid = p_new_pmt->i_pcr_pid;
1382 if( ( p_new_pmt->b_current_next &&
1383 ( p_new_pmt->i_version != p_pgrm_demux->i_pmt_version ) ) ||
1384 p_pgrm_demux->i_pmt_version == PMT_UNINITIALIZED )
1386 dvbpsi_descriptor_t *p_dr = p_new_pmt->p_first_descriptor;
1389 msg_Dbg( p_input, "Processing PMT for program %d version %d",
1390 p_new_pmt->i_program_number, p_new_pmt->i_version );
1392 /* Delete all ES in this program except the PSI. We start from the
1393 * end because i_es_number gets decremented after each deletion. */
1394 for( i_loop = p_pgrm->i_es_number ; i_loop > 0 ; )
1396 es_ts_data_t * p_es_demux;
1399 p_es_demux = (es_ts_data_t *)
1400 p_pgrm->pp_es[i_loop]->p_demux_data;
1401 if ( !p_es_demux->b_psi )
1403 input_DelES( p_input, p_pgrm->pp_es[i_loop] );
1408 while( p_dr && ( p_dr->i_tag != 0x1d ) )
1409 p_dr = p_dr->p_next;
1412 msg_Warn( p_input, "found IOD descriptor" );
1413 MP4_IODParse( &p_pgrm_demux->iod, p_dr->i_length, p_dr->p_data );
1416 p_es = p_new_pmt->p_first_es;
1419 vlc_fourcc_t i_fourcc;
1420 int i_size, i_cat, i_stream_id = 0;
1421 es_ts_data_t demux_data;
1422 BITMAPINFOHEADER *p_bih = NULL;
1423 WAVEFORMATEX *p_wf = NULL;
1426 memset( &demux_data, 0, sizeof(es_ts_data_t) );
1428 msg_Dbg( p_input, "new PID 0x%x stream type 0x%x",
1429 p_es->i_pid, p_es->i_type );
1431 switch( p_es->i_type )
1433 case MPEG1_VIDEO_ES:
1434 case MPEG2_VIDEO_ES:
1435 case MPEG2_MOTO_VIDEO_ES:
1436 i_fourcc = VLC_FOURCC('m','p','g','v');
1439 case MPEG1_AUDIO_ES:
1440 case MPEG2_AUDIO_ES:
1441 i_fourcc = VLC_FOURCC('m','p','g','a');
1445 if ( !b_vls_compat )
1446 i_fourcc = VLC_FOURCC('a','5','2',' ');
1448 i_fourcc = VLC_FOURCC('a','5','2','b');
1453 if ( !b_vls_compat )
1454 i_fourcc = VLC_FOURCC('s','p','u',' ');
1456 i_fourcc = VLC_FOURCC('s','p','u','b');
1461 i_fourcc = VLC_FOURCC('l','p','c','m');
1466 i_fourcc = VLC_FOURCC('s','d','d','s');
1471 i_fourcc = VLC_FOURCC('d','t','s',' ');
1476 i_fourcc = VLC_FOURCC('a','5','2','b');
1481 i_fourcc = VLC_FOURCC('s','p','u','b');
1485 case LPCMB_AUDIO_ES:
1486 i_fourcc = VLC_FOURCC('l','p','c','b');
1490 case MPEG4_VIDEO_ES:
1491 i_fourcc = VLC_FOURCC('m','p','4','v');
1495 case MPEG4_AUDIO_ES:
1496 case AAC_ADTS_AUDIO_ES:
1497 i_fourcc = VLC_FOURCC('m','p','4','a');
1501 case MSCODEC_VIDEO_ES:
1502 i_fourcc = VLC_FOURCC(0,0,0,0); /* fixed later */
1506 case PES_PRIVATE_ES:
1507 /* We need to check a descriptor to find the real codec */
1508 i_fourcc = VLC_FOURCC(0,0,0,0); /* fixed later */
1518 if( p_es->i_type == MPEG4_VIDEO_ES ||
1519 p_es->i_type == MPEG4_AUDIO_ES )
1521 /* mpeg4 stream, search sl_descriptor */
1522 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1524 while( p_dr && ( p_dr->i_tag != 0x1f ) ) p_dr = p_dr->p_next;
1526 if( p_dr && p_dr->i_length == 2 )
1528 int i_es_descr_index;
1530 demux_data.i_es_id =
1531 ( p_dr->p_data[0] << 8 ) | p_dr->p_data[1];
1532 demux_data.p_es_descr = NULL;
1534 msg_Warn( p_input, "found SL_descriptor" );
1535 for( i_es_descr_index = 0; i_es_descr_index < 255;
1536 i_es_descr_index++ )
1538 if( p_pgrm_demux->iod.es_descr[i_es_descr_index].b_ok &&
1539 p_pgrm_demux->iod.es_descr[i_es_descr_index].i_es_id == demux_data.i_es_id )
1541 demux_data.p_es_descr =
1542 &p_pgrm_demux->iod.es_descr[i_es_descr_index];
1548 if( demux_data.p_es_descr != NULL )
1550 #define DESCR demux_data.p_es_descr->dec_descr
1551 demux_data.b_mpeg4 = 1;
1554 switch( DESCR.i_streamType )
1556 case 0x04: /* VisualStream */
1558 switch( DESCR.i_objectTypeIndication )
1561 i_fourcc = VLC_FOURCC('m','p','4','v'); // mpeg4
1569 i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg2
1572 i_fourcc = VLC_FOURCC( 'm','p','g','v' ); // mpeg1
1575 i_fourcc = VLC_FOURCC( 'j','p','e','g' ); // mpeg1
1582 case 0x05: /* AudioStream */
1584 switch( DESCR.i_objectTypeIndication )
1587 i_fourcc = VLC_FOURCC('m','p','4','a'); // mpeg4
1592 i_fourcc = VLC_FOURCC('m','p','4','a');// mpeg2 aac
1595 i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg2
1598 i_fourcc = VLC_FOURCC('m','p','g','a'); // mpeg1
1614 i_size = sizeof( BITMAPINFOHEADER ) +
1615 DESCR.i_decoder_specific_info_len;
1616 p_bih = malloc( i_size );
1617 p_bih->biSize = i_size;
1619 p_bih->biHeight = 0;
1620 p_bih->biPlanes = 1;
1621 p_bih->biBitCount = 0;
1622 p_bih->biCompression = 0;
1623 p_bih->biSizeImage = 0;
1624 p_bih->biXPelsPerMeter = 0;
1625 p_bih->biYPelsPerMeter = 0;
1626 p_bih->biClrUsed = 0;
1627 p_bih->biClrImportant = 0;
1629 DESCR.p_decoder_specific_info,
1630 DESCR.i_decoder_specific_info_len );
1633 i_size = sizeof( WAVEFORMATEX ) +
1634 DESCR.i_decoder_specific_info_len;
1635 p_wf = malloc( i_size );
1636 p_wf->wFormatTag = 0xffff;
1637 p_wf->nChannels = 0;
1638 p_wf->nSamplesPerSec = 0;
1639 p_wf->nAvgBytesPerSec = 0;
1640 p_wf->nBlockAlign = 1;
1641 p_wf->wBitsPerSample = 0;
1642 p_wf->cbSize = DESCR.i_decoder_specific_info_len;
1644 DESCR.p_decoder_specific_info,
1645 DESCR.i_decoder_specific_info_len );
1654 "mpeg4 stream without (valid) sl_descriptor" );
1655 demux_data.b_mpeg4 = 0;
1659 else if( p_es->i_type == MSCODEC_VIDEO_ES )
1661 /* crapy ms codec stream, search private descriptor */
1662 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1664 while( p_dr && ( p_dr->i_tag != 0xa0 ) ) p_dr = p_dr->p_next;
1666 if( p_dr && p_dr->i_length >= 8 )
1669 i_fourcc = VLC_FOURCC( p_dr->p_data[0], p_dr->p_data[1],
1670 p_dr->p_data[2], p_dr->p_data[3] );
1672 i_bih_size = (p_dr->p_data[8] << 8) | p_dr->p_data[9];
1673 i_size = sizeof( BITMAPINFOHEADER ) + i_bih_size;
1675 p_bih = malloc( i_size );
1676 p_bih->biSize = i_size;
1677 p_bih->biWidth = ( p_dr->p_data[4] << 8 )|p_dr->p_data[5];
1678 p_bih->biHeight = ( p_dr->p_data[6] << 8 )|p_dr->p_data[7];
1679 p_bih->biPlanes = 1;
1680 p_bih->biBitCount = 0;
1681 p_bih->biCompression = 0;
1682 p_bih->biSizeImage = 0;
1683 p_bih->biXPelsPerMeter = 0;
1684 p_bih->biYPelsPerMeter = 0;
1685 p_bih->biClrUsed = 0;
1686 p_bih->biClrImportant = 0;
1687 memcpy( &p_bih[1], &p_dr->p_data[10], i_bih_size );
1691 msg_Warn( p_input, "private ms-codec stream without bih "
1692 "private sl_descriptor" );
1697 else if( p_es->i_type == PES_PRIVATE_ES )
1699 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1700 /* We have to find a descriptor giving the right codec */
1702 for(p_dr = p_es->p_first_descriptor; p_dr; p_dr = p_dr->p_next)
1704 if( p_dr->i_tag == 0x6a )
1707 i_fourcc = VLC_FOURCC( 'a', '5', '2', ' ' );
1710 else if( p_dr->i_tag == 0x59 )
1713 i_fourcc = VLC_FOURCC( 'd', 'v', 'b', 's' );
1717 if( i_fourcc == VLC_FOURCC(0,0,0,0) )
1720 "Unknown codec/type for Private PES stream" );
1724 if( i_cat == AUDIO_ES || i_cat == SPU_ES )
1726 dvbpsi_descriptor_t *p_dr = p_es->p_first_descriptor;
1727 while( p_dr && ( p_dr->i_tag != 0x0a ) ) p_dr = p_dr->p_next;
1731 dvbpsi_iso639_dr_t *p_decoded =
1732 dvbpsi_DecodeISO639Dr( p_dr );
1733 if( p_decoded->i_code_count > 0 )
1735 const iso639_lang_t * p_iso;
1736 p_iso = GetLang_2T((char*)p_decoded->i_iso_639_code);
1738 if( p_iso && strcmp(p_iso->psz_native_name,"Unknown"))
1740 if( p_iso->psz_native_name[0] )
1742 p_iso->psz_native_name, 20 );
1745 p_iso->psz_eng_name, 20 );
1750 (char*)p_decoded->i_iso_639_code);
1753 if( p_iso->psz_native_name[0] )
1755 p_iso->psz_native_name, 20 );
1758 p_iso->psz_eng_name, 20 );
1762 strncpy( psz_desc, p_decoded->i_iso_639_code, 3 );
1767 switch( p_es->i_type )
1769 case MPEG1_AUDIO_ES:
1770 case MPEG2_AUDIO_ES:
1771 strcat( psz_desc, " (mpeg)" );
1774 case LPCMB_AUDIO_ES:
1775 strcat( psz_desc, " (lpcm)" );
1779 strcat( psz_desc, " (A52)" );
1781 case MPEG4_AUDIO_ES:
1782 case AAC_ADTS_AUDIO_ES:
1783 strcat( psz_desc, " (aac)" );
1789 p_new_es = input_AddES( p_input, p_pgrm, (uint16_t)p_es->i_pid,
1790 i_cat, psz_desc, sizeof( es_ts_data_t ) );
1791 if( p_new_es == NULL )
1793 msg_Err( p_input, "could not add ES %d", p_es->i_pid );
1794 p_input->b_error = 1;
1797 p_new_es->i_fourcc = i_fourcc;
1798 p_new_es->i_stream_id = i_stream_id;
1799 p_new_es->p_bitmapinfoheader = (void*)p_bih;
1800 p_new_es->p_waveformatex = (void*)p_wf;
1801 memcpy( p_new_es->p_demux_data, &demux_data,
1802 sizeof(es_ts_data_t) );
1804 ((es_ts_data_t *)p_new_es->p_demux_data)->i_continuity_counter =
1807 p_es = p_es->p_next;
1810 /* if no program is selected :*/
1811 if( !p_input->stream.p_selected_program )
1813 pgrm_descriptor_t * p_pgrm_to_select;
1814 uint16_t i_id = (uint16_t)config_GetInt( p_input, "program" );
1816 if( i_id != 0 ) /* if user specified a program */
1818 p_pgrm_to_select = input_FindProgram( p_input, i_id );
1820 if( p_pgrm_to_select && p_pgrm_to_select == p_pgrm )
1821 p_input->pf_set_program( p_input, p_pgrm_to_select );
1824 p_input->pf_set_program( p_input, p_pgrm );
1826 /* if the pmt belongs to the currently selected program, we
1827 * reselect it to update its ES */
1828 else if( p_pgrm == p_input->stream.p_selected_program )
1830 p_input->pf_set_program( p_input, p_pgrm );
1833 p_pgrm_demux->i_pmt_version = p_new_pmt->i_version;
1834 p_input->stream.b_changed = 1;
1836 vlc_mutex_unlock( &p_input->stream.stream_lock );