1 /*****************************************************************************
2 * ts.c: Transport Stream input module for VLC.
3 *****************************************************************************
4 * Copyright (C) 2004-2005 the VideoLAN team
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Jean-Paul Saman <jpsaman #_at_# m2x.nl>
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
38 #include <vlc_access.h> /* DVB-specific things */
39 #include <vlc_demux.h>
43 #include <vlc_iso_lang.h>
44 #include <vlc_network.h>
45 #include <vlc_charset.h>
48 #include "../mux/mpeg/csa.h"
50 /* Include dvbpsi headers */
51 #ifdef HAVE_DVBPSI_DR_H
52 # include <dvbpsi/dvbpsi.h>
53 # include <dvbpsi/demux.h>
54 # include <dvbpsi/descriptor.h>
55 # include <dvbpsi/pat.h>
56 # include <dvbpsi/pmt.h>
57 # include <dvbpsi/sdt.h>
58 # include <dvbpsi/dr.h>
59 # include <dvbpsi/psi.h>
63 # include "descriptor.h"
64 # include "tables/pat.h"
65 # include "tables/pmt.h"
66 # include "tables/sdt.h"
67 # include "descriptors/dr.h"
72 #ifdef _DVBPSI_DR_4D_H_
73 # define TS_USE_DVB_SI 1
74 # ifdef HAVE_DVBPSI_DR_H
75 # include <dvbpsi/eit.h>
77 # include "tables/eit.h"
82 #ifdef _DVBPSI_DR_58_H_
84 # ifdef HAVE_DVBPSI_DR_H
85 # include <dvbpsi/tot.h>
87 # include "tables/tot.h"
95 /*****************************************************************************
97 *****************************************************************************/
98 static int Open ( vlc_object_t
* );
99 static void Close ( vlc_object_t
* );
102 * - Rename "extra pmt" to "user pmt"
103 * - Update extra pmt description
104 * pmt_pid[:pmt_number][=pid_description[,pid_description]]
105 * where pid_description could take 3 forms:
106 * 1. pid:pcr (to force the pcr pid)
108 * 3. pid:type=fourcc where type=(video|audio|spu)
110 #define PMT_TEXT N_("Extra PMT")
111 #define PMT_LONGTEXT N_( \
112 "Allows a user to specify an extra pmt (pmt_pid=pid:stream_type[,...])." )
114 #define PID_TEXT N_("Set id of ES to PID")
115 #define PID_LONGTEXT N_("Set the internal ID of each elementary stream" \
116 " handled by VLC to the same value as the PID in" \
117 " the TS stream, instead of 1, 2, 3, etc. Useful to" \
118 " do \'#duplicate{..., select=\"es=<pid>\"}\'.")
120 #define TSOUT_TEXT N_("Fast udp streaming")
121 #define TSOUT_LONGTEXT N_( \
122 "Sends TS to specific ip:port by udp (you must know what you are doing).")
124 #define MTUOUT_TEXT N_("MTU for out mode")
125 #define MTUOUT_LONGTEXT N_("MTU for out mode.")
127 #define CSA_TEXT N_("CSA ck")
128 #define CSA_LONGTEXT N_("Control word for the CSA encryption algorithm")
130 #define CSA2_TEXT N_("Second CSA Key")
131 #define CSA2_LONGTEXT N_("The even CSA encryption key. This must be a " \
132 "16 char string (8 hexadecimal bytes).")
134 #define SILENT_TEXT N_("Silent mode")
135 #define SILENT_LONGTEXT N_("Do not complain on encrypted PES.")
137 #define CAPMT_SYSID_TEXT N_("CAPMT System ID")
138 #define CAPMT_SYSID_LONGTEXT N_("Only forward descriptors from this SysID to the CAM.")
140 #define CPKT_TEXT N_("Packet size in bytes to decrypt")
141 #define CPKT_LONGTEXT N_("Specify the size of the TS packet to decrypt. " \
142 "The decryption routines subtract the TS-header from the value before " \
145 #define TSDUMP_TEXT N_("Filename of dump")
146 #define TSDUMP_LONGTEXT N_("Specify a filename where to dump the TS in.")
148 #define APPEND_TEXT N_("Append")
149 #define APPEND_LONGTEXT N_( \
150 "If the file exists and this option is selected, the existing file " \
151 "will not be overwritten." )
153 #define DUMPSIZE_TEXT N_("Dump buffer size")
154 #define DUMPSIZE_LONGTEXT N_( \
155 "Tweak the buffer size for reading and writing an integer number of packets." \
156 "Specify the size of the buffer here and not the number of packets." )
158 #define SPLIT_ES_TEXT N_("Separate sub-streams")
159 #define SPLIT_ES_LONGTEXT N_( \
160 "Separate teletex/dvbs pages into independent ES. " \
161 "It can be useful to turn off this option when using stream output." )
164 set_description( N_("MPEG Transport Stream demuxer") )
165 set_shortname ( "MPEG-TS" )
166 set_category( CAT_INPUT
)
167 set_subcategory( SUBCAT_INPUT_DEMUX
)
169 add_string( "ts-extra-pmt", NULL
, NULL
, PMT_TEXT
, PMT_LONGTEXT
, true )
170 add_bool( "ts-es-id-pid", true, NULL
, PID_TEXT
, PID_LONGTEXT
, true )
171 add_string( "ts-out", NULL
, NULL
, TSOUT_TEXT
, TSOUT_LONGTEXT
, true )
172 add_integer( "ts-out-mtu", 1400, NULL
, MTUOUT_TEXT
,
173 MTUOUT_LONGTEXT
, true )
174 add_string( "ts-csa-ck", NULL
, NULL
, CSA_TEXT
, CSA_LONGTEXT
, true )
175 add_string( "ts-csa2-ck", NULL
, NULL
, CSA_TEXT
, CSA_LONGTEXT
, true )
176 add_integer( "ts-csa-pkt", 188, NULL
, CPKT_TEXT
, CPKT_LONGTEXT
, true )
177 add_bool( "ts-silent", false, NULL
, SILENT_TEXT
, SILENT_LONGTEXT
, true )
179 add_file( "ts-dump-file", NULL
, NULL
, TSDUMP_TEXT
, TSDUMP_LONGTEXT
, false )
180 add_bool( "ts-dump-append", false, NULL
, APPEND_TEXT
, APPEND_LONGTEXT
, false )
181 add_integer( "ts-dump-size", 16384, NULL
, DUMPSIZE_TEXT
,
182 DUMPSIZE_LONGTEXT
, true )
183 add_bool( "ts-split-es", true, NULL
, SPLIT_ES_TEXT
, SPLIT_ES_LONGTEXT
, false )
185 set_capability( "demux", 10 )
186 set_callbacks( Open
, Close
)
190 /*****************************************************************************
192 *****************************************************************************/
193 static const char *const ppsz_teletext_type
[] = {
196 N_("Teletext subtitles"),
197 N_("Teletext: additional information"),
198 N_("Teletext: program schedule"),
199 N_("Teletext subtitles: hearing impaired")
204 uint8_t i_objectTypeIndication
;
205 uint8_t i_streamType
;
207 uint32_t i_bufferSizeDB
;
208 uint32_t i_maxBitrate
;
209 uint32_t i_avgBitrate
;
211 int i_decoder_specific_info_len
;
212 uint8_t *p_decoder_specific_info
;
214 } decoder_config_descriptor_t
;
218 bool b_useAccessUnitStartFlag
;
219 bool b_useAccessUnitEndFlag
;
220 bool b_useRandomAccessPointFlag
;
221 bool b_useRandomAccessUnitsOnlyFlag
;
222 bool b_usePaddingFlag
;
223 bool b_useTimeStampsFlags
;
226 uint32_t i_timeStampResolution
;
227 uint32_t i_OCRResolution
;
228 uint8_t i_timeStampLength
;
231 uint8_t i_instantBitrateLength
;
232 uint8_t i_degradationPriorityLength
;
233 uint8_t i_AU_seqNumLength
;
234 uint8_t i_packetSeqNumLength
;
236 uint32_t i_timeScale
;
237 uint16_t i_accessUnitDuration
;
238 uint16_t i_compositionUnitDuration
;
240 uint64_t i_startDecodingTimeStamp
;
241 uint64_t i_startCompositionTimeStamp
;
243 } sl_config_descriptor_t
;
250 bool b_streamDependenceFlag
;
251 bool b_OCRStreamFlag
;
252 uint8_t i_streamPriority
;
256 uint16_t i_dependOn_es_id
;
257 uint16_t i_OCR_es_id
;
259 decoder_config_descriptor_t dec_descr
;
260 sl_config_descriptor_t sl_descr
;
262 } es_mpeg4_descriptor_t
;
266 uint8_t i_iod_label
, i_iod_label_scope
;
272 uint8_t i_ODProfileLevelIndication
;
273 uint8_t i_sceneProfileLevelIndication
;
274 uint8_t i_audioProfileLevelIndication
;
275 uint8_t i_visualProfileLevelIndication
;
276 uint8_t i_graphicsProfileLevelIndication
;
278 es_mpeg4_descriptor_t es_descr
[255];
284 dvbpsi_handle handle
;
290 /* IOD stuff (mpeg4) */
291 iod_descriptor_t
*iod
;
297 /* for special PAT/SDT case */
298 dvbpsi_handle handle
; /* PAT/SDT/EIT */
317 es_mpeg4_descriptor_t
*p_mpeg4desc
;
328 int i_cc
; /* countinuity counter */
331 /* PSI owner (ie PMT -> PAT, ES -> PMT */
339 /* Some private streams encapsulate several ES (eg. DVB subtitles)*/
347 vlc_mutex_t csa_lock
;
349 /* TS packet size (188, 192, 204) */
352 /* how many TS packet we read at once */
372 int fd
; /* udp socket */
376 bool b_access_control
;
382 int64_t i_dvb_length
;
383 bool b_broken_charset
; /* True if broken encoding is used in EPG/SDT */
386 int i_current_program
;
387 vlc_list_t programs_list
;
390 char *psz_file
; /* file to dump data in */
391 FILE *p_file
; /* filehandle */
392 uint64_t i_write
; /* bytes written */
393 bool b_file_out
; /* dump mode enabled */
399 static int Demux ( demux_t
*p_demux
);
400 static int DemuxFile( demux_t
*p_demux
);
401 static int Control( demux_t
*p_demux
, int i_query
, va_list args
);
403 static void PIDInit ( ts_pid_t
*pid
, bool b_psi
, ts_psi_t
*p_owner
);
404 static void PIDClean( demux_t
*, ts_pid_t
*pid
);
405 static int PIDFillFormat( ts_pid_t
*pid
, int i_stream_type
);
407 static void PATCallBack( demux_t
*, dvbpsi_pat_t
* );
408 static void PMTCallBack( demux_t
*p_demux
, dvbpsi_pmt_t
*p_pmt
);
410 static void PSINewTableCallBack( demux_t
*, dvbpsi_handle
,
411 uint8_t i_table_id
, uint16_t i_extension
);
413 static int ChangeKeyCallback( vlc_object_t
*, char const *, vlc_value_t
, vlc_value_t
, void * );
415 static inline int PIDGet( block_t
*p
)
417 return ( (p
->p_buffer
[1]&0x1f)<<8 )|p
->p_buffer
[2];
420 static bool GatherPES( demux_t
*p_demux
, ts_pid_t
*pid
, block_t
*p_bk
);
422 static void PCRHandle( demux_t
*p_demux
, ts_pid_t
*, block_t
* );
424 static iod_descriptor_t
*IODNew( int , uint8_t * );
425 static void IODFree( iod_descriptor_t
* );
427 #define TS_USER_PMT_NUMBER (0)
428 static int UserPmt( demux_t
*p_demux
, const char * );
430 static int SetPIDFilter( demux_t
*, int i_pid
, bool b_selected
);
431 static void SetPrgFilter( demux_t
*, int i_prg
, bool b_selected
);
433 #define TS_PACKET_SIZE_188 188
434 #define TS_PACKET_SIZE_192 192
435 #define TS_PACKET_SIZE_204 204
436 #define TS_PACKET_SIZE_MAX 204
437 #define TS_TOPFIELD_HEADER 1320
439 /*****************************************************************************
441 *****************************************************************************/
442 static int Open( vlc_object_t
*p_this
)
444 demux_t
*p_demux
= (demux_t
*)p_this
;
447 const uint8_t *p_peek
;
448 int i_sync
, i_peek
, i
;
452 const char *psz_mode
;
454 bool b_topfield
= false;
456 if( stream_Peek( p_demux
->s
, &p_peek
, TS_PACKET_SIZE_MAX
) <
457 TS_PACKET_SIZE_MAX
) return VLC_EGENERIC
;
459 if( memcmp( p_peek
, "TFrc", 4 ) == 0 )
462 msg_Dbg( p_demux
, "this is a topfield file" );
465 /* Search first sync byte */
466 for( i_sync
= 0; i_sync
< TS_PACKET_SIZE_MAX
; i_sync
++ )
468 if( p_peek
[i_sync
] == 0x47 ) break;
470 if( i_sync
>= TS_PACKET_SIZE_MAX
&& !b_topfield
)
472 if( !p_demux
->b_force
)
474 msg_Warn( p_demux
, "this does not look like a TS stream, continuing" );
479 /* Read the entire Topfield header */
480 i_peek
= TS_TOPFIELD_HEADER
;
484 /* Check next 3 sync bytes */
485 i_peek
= TS_PACKET_SIZE_MAX
* 3 + i_sync
+ 1;
488 if( ( stream_Peek( p_demux
->s
, &p_peek
, i_peek
) ) < i_peek
)
490 msg_Err( p_demux
, "cannot peek" );
493 if( p_peek
[i_sync
+ TS_PACKET_SIZE_188
] == 0x47 &&
494 p_peek
[i_sync
+ 2 * TS_PACKET_SIZE_188
] == 0x47 &&
495 p_peek
[i_sync
+ 3 * TS_PACKET_SIZE_188
] == 0x47 )
497 i_packet_size
= TS_PACKET_SIZE_188
;
499 else if( p_peek
[i_sync
+ TS_PACKET_SIZE_192
] == 0x47 &&
500 p_peek
[i_sync
+ 2 * TS_PACKET_SIZE_192
] == 0x47 &&
501 p_peek
[i_sync
+ 3 * TS_PACKET_SIZE_192
] == 0x47 )
503 i_packet_size
= TS_PACKET_SIZE_192
;
505 else if( p_peek
[i_sync
+ TS_PACKET_SIZE_204
] == 0x47 &&
506 p_peek
[i_sync
+ 2 * TS_PACKET_SIZE_204
] == 0x47 &&
507 p_peek
[i_sync
+ 3 * TS_PACKET_SIZE_204
] == 0x47 )
509 i_packet_size
= TS_PACKET_SIZE_204
;
511 else if( p_demux
->b_force
)
513 i_packet_size
= TS_PACKET_SIZE_188
;
515 else if( b_topfield
)
517 i_packet_size
= TS_PACKET_SIZE_188
;
519 /* I used the TF5000PVR 2004 Firmware .doc header documentation,
520 * http://www.i-topfield.com/data/product/firmware/Structure%20of%20Recorded%20File%20in%20TF5000PVR%20(Feb%2021%202004).doc
521 * but after the filename the offsets seem to be incorrect. - DJ */
522 int i_duration
, i_name
;
523 char *psz_name
= malloc(25);
524 char *psz_event_name
;
525 char *psz_event_text
= malloc(130);
526 char *psz_ext_text
= malloc(1025);
528 // 2 bytes version Uimsbf (4,5)
529 // 2 bytes reserved (6,7)
530 // 2 bytes duration in minutes Uimsbf (8,9(
531 i_duration
= (int) (p_peek
[8] << 8) | p_peek
[9];
532 msg_Dbg( p_demux
, "Topfield recording length: +/- %d minutes", i_duration
);
533 // 2 bytes service number in channel list (10, 11)
534 // 2 bytes service type Bslbf 0=TV 1=Radio Bslb (12, 13)
535 // 4 bytes of reserved + tuner info (14,15,16,17)
536 // 2 bytes of Service ID Bslbf (18,19)
537 // 2 bytes of PMT PID Uimsbf (20,21)
538 // 2 bytes of PCR PID Uimsbf (22,23)
539 // 2 bytes of Video PID Uimsbf (24,25)
540 // 2 bytes of Audio PID Uimsbf (26,27)
541 // 24 bytes filename Bslbf
542 memcpy( psz_name
, &p_peek
[28], 24 );
544 msg_Dbg( p_demux
, "recordingname=%s", psz_name
);
545 // 1 byte of sat index Uimsbf (52)
546 // 3 bytes (1 bit of polarity Bslbf +23 bits reserved)
547 // 4 bytes of freq. Uimsbf (56,57,58,59)
548 // 2 bytes of symbol rate Uimsbf (60,61)
549 // 2 bytes of TS stream ID Uimsbf (62,63)
552 // 2 bytes duration Uimsbf (70,71)
553 //i_duration = (int) (p_peek[70] << 8) | p_peek[71];
554 //msg_Dbg( p_demux, "Topfield 2nd duration field: +/- %d minutes", i_duration);
555 // 4 bytes EventID Uimsbf (72-75)
556 // 8 bytes of Start and End time info (76-83)
557 // 1 byte reserved (84)
558 // 1 byte event name length Uimsbf (89)
559 i_name
= (int)(p_peek
[89]&~0x81);
560 msg_Dbg( p_demux
, "event name length = %d", i_name
);
561 psz_event_name
= malloc( i_name
+1 );
562 // 1 byte parental rating (90)
563 // 129 bytes of event text
564 memcpy( psz_event_name
, &p_peek
[91], i_name
);
565 psz_event_name
[i_name
] = '\0';
566 memcpy( psz_event_text
, &p_peek
[91+i_name
], 129-i_name
);
567 psz_event_text
[129-i_name
] = '\0';
568 msg_Dbg( p_demux
, "event name=%s", psz_event_name
);
569 msg_Dbg( p_demux
, "event text=%s", psz_event_text
);
570 // 12 bytes reserved (220)
572 // 2 bytes Event Text Length Uimsbf
573 // 4 bytes EventID Uimsbf
574 // FIXME We just have 613 bytes. not enough for this entire text
575 // 1024 bytes Extended Event Text Bslbf
576 memcpy( psz_ext_text
, p_peek
+372, 1024 );
577 psz_ext_text
[1024] = '\0';
578 msg_Dbg( p_demux
, "extended event text=%s", psz_ext_text
);
579 // 52 bytes reserved Bslbf
584 msg_Warn( p_demux
, "TS module discarded (lost sync)" );
588 p_demux
->p_sys
= p_sys
= malloc( sizeof( demux_sys_t
) );
591 memset( p_sys
, 0, sizeof( demux_sys_t
) );
592 p_sys
->i_packet_size
= i_packet_size
;
593 vlc_mutex_init( &p_sys
->csa_lock
);
595 /* Fill dump mode fields */
597 p_sys
->buffer
= NULL
;
598 p_sys
->p_file
= NULL
;
599 p_sys
->b_file_out
= false;
600 p_sys
->psz_file
= var_CreateGetString( p_demux
, "ts-dump-file" );
601 if( *p_sys
->psz_file
!= '\0' )
603 p_sys
->b_file_out
= true;
605 b_append
= var_CreateGetBool( p_demux
, "ts-dump-append" );
611 if( !strcmp( p_sys
->psz_file
, "-" ) )
613 msg_Info( p_demux
, "dumping raw stream to standard output" );
614 p_sys
->p_file
= stdout
;
616 else if( ( p_sys
->p_file
= vlc_fopen( p_sys
->psz_file
, psz_mode
) ) == NULL
)
618 msg_Err( p_demux
, "cannot create `%s' for writing", p_sys
->psz_file
);
619 p_sys
->b_file_out
= false;
622 if( p_sys
->b_file_out
)
624 /* Determine how many packets to read. */
625 int bufsize
= var_CreateGetInteger( p_demux
, "ts-dump-size" );
626 p_sys
->i_ts_read
= (int) (bufsize
/ p_sys
->i_packet_size
);
627 if( p_sys
->i_ts_read
<= 0 )
629 p_sys
->i_ts_read
= 1500 / p_sys
->i_packet_size
;
631 p_sys
->buffer
= xmalloc( p_sys
->i_packet_size
* p_sys
->i_ts_read
);
632 msg_Info( p_demux
, "%s raw stream to file `%s' reading packets %d",
633 b_append
? "appending" : "dumping", p_sys
->psz_file
,
638 /* Fill p_demux field */
639 if( p_sys
->b_file_out
)
640 p_demux
->pf_demux
= DemuxFile
;
642 p_demux
->pf_demux
= Demux
;
643 p_demux
->pf_control
= Control
;
645 /* Init p_sys field */
646 p_sys
->b_dvb_meta
= true;
647 p_sys
->b_access_control
= true;
648 p_sys
->i_current_program
= 0;
649 p_sys
->programs_list
.i_count
= 0;
650 p_sys
->programs_list
.p_values
= NULL
;
651 p_sys
->i_tdt_delta
= 0;
652 p_sys
->i_dvb_start
= 0;
653 p_sys
->i_dvb_length
= 0;
655 p_sys
->b_broken_charset
= false;
657 for( i
= 0; i
< 8192; i
++ )
659 ts_pid_t
*pid
= &p_sys
->pid
[i
];
663 pid
->b_valid
= false;
665 /* PID 8191 is padding */
666 p_sys
->pid
[8191].b_seen
= true;
667 p_sys
->i_packet_size
= i_packet_size
;
668 p_sys
->b_udp_out
= false;
670 p_sys
->i_ts_read
= 50;
672 p_sys
->b_start_record
= false;
674 /* Init PAT handler */
675 pat
= &p_sys
->pid
[0];
676 PIDInit( pat
, true, NULL
);
677 pat
->psi
->handle
= dvbpsi_AttachPAT( (dvbpsi_pat_callback
)PATCallBack
,
680 if( p_sys
->b_dvb_meta
)
682 ts_pid_t
*sdt
= &p_sys
->pid
[0x11];
683 ts_pid_t
*eit
= &p_sys
->pid
[0x12];
685 PIDInit( sdt
, true, NULL
);
687 dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t
)PSINewTableCallBack
,
689 PIDInit( eit
, true, NULL
);
691 dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t
)PSINewTableCallBack
,
694 ts_pid_t
*tdt
= &p_sys
->pid
[0x14];
695 PIDInit( tdt
, true, NULL
);
697 dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t
)PSINewTableCallBack
,
700 if( p_sys
->b_access_control
)
702 if( SetPIDFilter( p_demux
, 0x11, true ) ||
704 SetPIDFilter( p_demux
, 0x14, true ) ||
706 SetPIDFilter( p_demux
, 0x12, true ) )
707 p_sys
->b_access_control
= false;
713 TAB_INIT( p_sys
->i_pmt
, p_sys
->pmt
);
717 p_sys
->b_es_id_pid
= var_CreateGetBool( p_demux
, "ts-es-id-pid" );
719 char* psz_string
= var_CreateGetString( p_demux
, "ts-out" );
720 if( psz_string
&& *psz_string
&& !p_sys
->b_file_out
)
722 char *psz
= strchr( psz_string
, ':' );
725 p_sys
->b_udp_out
= true;
730 i_port
= atoi( psz
);
732 if( i_port
<= 0 ) i_port
= 1234;
733 msg_Dbg( p_demux
, "resend ts to '%s:%d'", psz_string
, i_port
);
735 p_sys
->fd
= net_ConnectUDP( VLC_OBJECT(p_demux
), psz_string
, i_port
, -1 );
738 msg_Err( p_demux
, "failed to open udp socket, send disabled" );
739 p_sys
->b_udp_out
= false;
743 int i_mtu
= var_CreateGetInteger( p_demux
, "ts-out-mtu" );
744 p_sys
->i_ts_read
= i_mtu
/ p_sys
->i_packet_size
;
745 if( p_sys
->i_ts_read
<= 0 )
747 p_sys
->i_ts_read
= 1500 / p_sys
->i_packet_size
;
749 p_sys
->buffer
= malloc( p_sys
->i_packet_size
* p_sys
->i_ts_read
);
754 /* We handle description of an extra PMT */
755 psz_string
= var_CreateGetString( p_demux
, "ts-extra-pmt" );
756 p_sys
->b_user_pmt
= false;
757 if( psz_string
&& *psz_string
)
758 UserPmt( p_demux
, psz_string
);
761 psz_string
= var_CreateGetStringCommand( p_demux
, "ts-csa-ck" );
762 if( psz_string
&& *psz_string
)
767 p_sys
->csa
= csa_New();
769 psz_csa2
= var_CreateGetStringCommand( p_demux
, "ts-csa2-ck" );
770 i_res
= csa_SetCW( (vlc_object_t
*)p_demux
, p_sys
->csa
, psz_string
, true );
771 if( i_res
== VLC_SUCCESS
&& psz_csa2
&& *psz_csa2
)
773 if( csa_SetCW( (vlc_object_t
*)p_demux
, p_sys
->csa
, psz_csa2
, false ) != VLC_SUCCESS
)
775 csa_SetCW( (vlc_object_t
*)p_demux
, p_sys
->csa
, psz_string
, false );
778 else if ( i_res
== VLC_SUCCESS
)
780 csa_SetCW( (vlc_object_t
*)p_demux
, p_sys
->csa
, psz_string
, false );
784 csa_Delete( p_sys
->csa
);
790 var_AddCallback( p_demux
, "ts-csa-ck", ChangeKeyCallback
, (void *)1 );
791 var_AddCallback( p_demux
, "ts-csa2-ck", ChangeKeyCallback
, NULL
);
793 int i_pkt
= var_CreateGetInteger( p_demux
, "ts-csa-pkt" );
794 if( i_pkt
< 4 || i_pkt
> 188 )
796 msg_Err( p_demux
, "wrong packet size %d specified.", i_pkt
);
797 msg_Warn( p_demux
, "using default packet size of 188 bytes" );
798 p_sys
->i_csa_pkt_size
= 188;
801 p_sys
->i_csa_pkt_size
= i_pkt
;
802 msg_Dbg( p_demux
, "decrypting %d bytes of packet", p_sys
->i_csa_pkt_size
);
808 p_sys
->b_silent
= var_CreateGetBool( p_demux
, "ts-silent" );
809 p_sys
->b_split_es
= var_InheritBool( p_demux
, "ts-split-es" );
811 while( !p_sys
->b_file_out
&& p_sys
->i_pmt_es
<= 0 &&
812 vlc_object_alive( p_demux
) )
814 if( p_demux
->pf_demux( p_demux
) != 1 )
822 /*****************************************************************************
824 *****************************************************************************/
825 static void Close( vlc_object_t
*p_this
)
827 demux_t
*p_demux
= (demux_t
*)p_this
;
828 demux_sys_t
*p_sys
= p_demux
->p_sys
;
830 msg_Dbg( p_demux
, "pid list:" );
831 for( int i
= 0; i
< 8192; i
++ )
833 ts_pid_t
*pid
= &p_sys
->pid
[i
];
835 if( pid
->b_valid
&& pid
->psi
)
840 dvbpsi_DetachPAT( pid
->psi
->handle
);
847 if( p_sys
->b_dvb_meta
&& ( pid
->i_pid
== 0x11 || pid
->i_pid
== 0x12 || pid
->i_pid
== 0x14 ) )
849 /* SDT or EIT or TDT */
850 dvbpsi_DetachDemux( pid
->psi
->handle
);
855 PIDClean( p_demux
, pid
);
860 else if( pid
->b_valid
&& pid
->es
)
862 PIDClean( p_demux
, pid
);
867 msg_Dbg( p_demux
, " - pid[%d] seen", pid
->i_pid
);
872 SetPIDFilter( p_demux
, pid
->i_pid
, false );
875 vlc_mutex_lock( &p_sys
->csa_lock
);
878 var_DelCallback( p_demux
, "ts-csa-ck", ChangeKeyCallback
, NULL
);
879 var_DelCallback( p_demux
, "ts-csa2-ck", ChangeKeyCallback
, NULL
);
880 csa_Delete( p_sys
->csa
);
882 vlc_mutex_unlock( &p_sys
->csa_lock
);
884 TAB_CLEAN( p_sys
->i_pmt
, p_sys
->pmt
);
886 free( p_sys
->programs_list
.p_values
);
888 /* If in dump mode, then close the file */
889 if( p_sys
->b_file_out
)
891 msg_Info( p_demux
,"closing %s (%"PRId64
" KiB dumped)",
892 p_sys
->psz_file
, p_sys
->i_write
/ 1024 );
894 if( p_sys
->p_file
!= stdout
)
896 fclose( p_sys
->p_file
);
899 /* When streaming, close the port */
902 net_Close( p_sys
->fd
);
905 free( p_sys
->buffer
);
906 free( p_sys
->psz_file
);
908 vlc_mutex_destroy( &p_sys
->csa_lock
);
912 /*****************************************************************************
913 * ChangeKeyCallback: called when changing the odd encryption key on the fly.
914 *****************************************************************************/
915 static int ChangeKeyCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
916 vlc_value_t oldval
, vlc_value_t newval
,
919 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
);
920 demux_t
*p_demux
= (demux_t
*)p_this
;
921 demux_sys_t
*p_sys
= p_demux
->p_sys
;
922 int i_tmp
= (intptr_t)p_data
;
924 vlc_mutex_lock( &p_sys
->csa_lock
);
926 i_tmp
= csa_SetCW( p_this
, p_sys
->csa
, newval
.psz_string
, true );
928 i_tmp
= csa_SetCW( p_this
, p_sys
->csa
, newval
.psz_string
, false );
930 vlc_mutex_unlock( &p_sys
->csa_lock
);
934 /*****************************************************************************
936 *****************************************************************************/
937 static int DemuxFile( demux_t
*p_demux
)
939 demux_sys_t
*p_sys
= p_demux
->p_sys
;
940 const int i_bufsize
= p_sys
->i_packet_size
* p_sys
->i_ts_read
;
941 uint8_t *p_buffer
= p_sys
->buffer
; /* Put first on sync byte */
942 const int i_data
= stream_Read( p_demux
->s
, p_sys
->buffer
, i_bufsize
);
944 if( i_data
<= 0 && i_data
< p_sys
->i_packet_size
)
946 msg_Dbg( p_demux
, "error reading malformed packets" );
950 /* Test continuity counter */
951 for( int i_pos
= 0; i_pos
< i_data
; )
953 if( p_sys
->buffer
[i_pos
] != 0x47 )
955 msg_Warn( p_demux
, "lost sync" );
956 while( vlc_object_alive (p_demux
) && (i_pos
< i_data
) )
959 if( p_sys
->buffer
[i_pos
] == 0x47 )
962 if( vlc_object_alive (p_demux
) )
963 msg_Warn( p_demux
, "sync found" );
966 /* continuous when (one of this):
968 * diff == 0 and payload == 0
969 * diff == 0 and duplicate packet (playload != 0) <- should we
972 const int i_cc
= p_buffer
[i_pos
+3]&0x0f;
973 const bool b_payload
= p_buffer
[i_pos
+3]&0x10;
974 const bool b_adaptation
= p_buffer
[i_pos
+3]&0x20;
977 ts_pid_t
*p_pid
= &p_sys
->pid
[ ((p_buffer
[i_pos
+1]&0x1f)<<8)|p_buffer
[i_pos
+2] ];
979 /* Detect discontinuity indicator in adaptation field */
980 if( b_adaptation
&& p_buffer
[i_pos
+ 4] > 0 )
982 if( p_buffer
[i_pos
+5]&0x80 )
983 msg_Warn( p_demux
, "discontinuity indicator (pid=%d) ", p_pid
->i_pid
);
984 if( p_buffer
[i_pos
+5]&0x40 )
985 msg_Warn( p_demux
, "random access indicator (pid=%d) ", p_pid
->i_pid
);
988 const int i_diff
= ( i_cc
- p_pid
->i_cc
)&0x0f;
989 if( b_payload
&& i_diff
== 1 )
991 p_pid
->i_cc
= ( p_pid
->i_cc
+ 1 ) & 0xf;
995 if( p_pid
->i_cc
== 0xff )
997 msg_Warn( p_demux
, "first packet for pid=%d cc=0x%x",
998 p_pid
->i_pid
, i_cc
);
1001 else if( i_diff
!= 0 )
1003 /* FIXME what to do when discontinuity_indicator is set ? */
1004 msg_Warn( p_demux
, "transport error detected 0x%x instead of 0x%x",
1005 i_cc
, ( p_pid
->i_cc
+ 1 )&0x0f );
1008 /* Mark transport error in the TS packet. */
1009 p_buffer
[i_pos
+1] |= 0x80;
1013 /* Test if user wants to decrypt it first */
1016 vlc_mutex_lock( &p_sys
->csa_lock
);
1017 csa_Decrypt( p_demux
->p_sys
->csa
, &p_buffer
[i_pos
], p_demux
->p_sys
->i_csa_pkt_size
);
1018 vlc_mutex_unlock( &p_sys
->csa_lock
);
1021 i_pos
+= p_sys
->i_packet_size
;
1025 const int i_write
= fwrite( p_sys
->buffer
, 1, i_data
, p_sys
->p_file
);
1028 msg_Err( p_demux
, "failed to write data" );
1032 p_sys
->i_write
+= i_write
;
1036 /*****************************************************************************
1038 *****************************************************************************/
1039 static int Demux( demux_t
*p_demux
)
1041 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1042 bool b_wait_es
= p_sys
->i_pmt_es
<= 0;
1044 /* We read at most 100 TS packet or until a frame is completed */
1045 for( int i_pkt
= 0; i_pkt
< p_sys
->i_ts_read
; i_pkt
++ )
1047 bool b_frame
= false;
1050 /* Get a new TS packet */
1051 if( !( p_pkt
= stream_Block( p_demux
->s
, p_sys
->i_packet_size
) ) )
1053 msg_Dbg( p_demux
, "eof ?" );
1057 /* Check sync byte and re-sync if needed */
1058 if( p_pkt
->p_buffer
[0] != 0x47 )
1060 msg_Warn( p_demux
, "lost synchro" );
1061 block_Release( p_pkt
);
1063 while( vlc_object_alive (p_demux
) )
1065 const uint8_t *p_peek
;
1066 int i_peek
, i_skip
= 0;
1068 i_peek
= stream_Peek( p_demux
->s
, &p_peek
,
1069 p_sys
->i_packet_size
* 10 );
1070 if( i_peek
< p_sys
->i_packet_size
+ 1 )
1072 msg_Dbg( p_demux
, "eof ?" );
1076 while( i_skip
< i_peek
- p_sys
->i_packet_size
)
1078 if( p_peek
[i_skip
] == 0x47 &&
1079 p_peek
[i_skip
+ p_sys
->i_packet_size
] == 0x47 )
1086 msg_Dbg( p_demux
, "skipping %d bytes of garbage", i_skip
);
1087 stream_Read( p_demux
->s
, NULL
, i_skip
);
1089 if( i_skip
< i_peek
- p_sys
->i_packet_size
)
1095 if( !( p_pkt
= stream_Block( p_demux
->s
, p_sys
->i_packet_size
) ) )
1097 msg_Dbg( p_demux
, "eof ?" );
1102 if( p_sys
->b_start_record
)
1104 /* Enable recording once synchronized */
1105 stream_Control( p_demux
->s
, STREAM_SET_RECORD_STATE
, true, "ts" );
1106 p_sys
->b_start_record
= false;
1109 if( p_sys
->b_udp_out
)
1111 memcpy( &p_sys
->buffer
[i_pkt
* p_sys
->i_packet_size
],
1112 p_pkt
->p_buffer
, p_sys
->i_packet_size
);
1115 /* Parse the TS packet */
1116 ts_pid_t
*p_pid
= &p_sys
->pid
[PIDGet( p_pkt
)];
1118 if( p_pid
->b_valid
)
1122 if( p_pid
->i_pid
== 0 || ( p_sys
->b_dvb_meta
&& ( p_pid
->i_pid
== 0x11 || p_pid
->i_pid
== 0x12 || p_pid
->i_pid
== 0x14 ) ) )
1124 dvbpsi_PushPacket( p_pid
->psi
->handle
, p_pkt
->p_buffer
);
1128 for( int i_prg
= 0; i_prg
< p_pid
->psi
->i_prg
; i_prg
++ )
1130 dvbpsi_PushPacket( p_pid
->psi
->prg
[i_prg
]->handle
,
1134 block_Release( p_pkt
);
1136 else if( !p_sys
->b_udp_out
)
1138 b_frame
= GatherPES( p_demux
, p_pid
, p_pkt
);
1142 PCRHandle( p_demux
, p_pid
, p_pkt
);
1143 block_Release( p_pkt
);
1148 if( !p_pid
->b_seen
)
1150 msg_Dbg( p_demux
, "pid[%d] unknown", p_pid
->i_pid
);
1152 /* We have to handle PCR if present */
1153 PCRHandle( p_demux
, p_pid
, p_pkt
);
1154 block_Release( p_pkt
);
1156 p_pid
->b_seen
= true;
1158 if( b_frame
|| ( b_wait_es
&& p_sys
->i_pmt_es
> 0 ) )
1162 if( p_sys
->b_udp_out
)
1164 /* Send the complete block */
1165 net_Write( p_demux
, p_sys
->fd
, NULL
, p_sys
->buffer
,
1166 p_sys
->i_ts_read
* p_sys
->i_packet_size
);
1172 /*****************************************************************************
1174 *****************************************************************************/
1175 static int DVBEventInformation( demux_t
*p_demux
, int64_t *pi_time
, int64_t *pi_length
)
1177 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1183 if( p_sys
->i_dvb_length
> 0 )
1186 const int64_t t
= mdate() + p_sys
->i_tdt_delta
;
1188 const int64_t t
= CLOCK_FREQ
* time ( NULL
);
1191 if( p_sys
->i_dvb_start
<= t
&& t
< p_sys
->i_dvb_start
+ p_sys
->i_dvb_length
)
1194 *pi_length
= p_sys
->i_dvb_length
;
1196 *pi_time
= t
- p_sys
->i_dvb_start
;
1200 return VLC_EGENERIC
;
1203 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
1205 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1207 bool b_bool
, *pb_bool
;
1212 if( p_sys
->b_file_out
)
1213 return demux_vaControlHelper( p_demux
->s
, 0, -1, 0, 1, i_query
, args
);
1217 case DEMUX_GET_POSITION
:
1218 pf
= (double*) va_arg( args
, double* );
1219 i64
= stream_Size( p_demux
->s
);
1222 double f_current
= stream_Tell( p_demux
->s
);
1223 *pf
= f_current
/ (double)i64
;
1227 int64_t i_time
, i_length
;
1228 if( !DVBEventInformation( p_demux
, &i_time
, &i_length
) && i_length
> 0 )
1229 *pf
= (double)i_time
/(double)i_length
;
1234 case DEMUX_SET_POSITION
:
1235 f
= (double) va_arg( args
, double );
1236 i64
= stream_Size( p_demux
->s
);
1238 if( stream_Seek( p_demux
->s
, (int64_t)(i64
* f
) ) )
1239 return VLC_EGENERIC
;
1244 case DEMUX_GET_TIME
:
1245 pi64
= (int64_t*)va_arg( args
, int64_t * );
1246 if( p_sys
->i_time
< 0 )
1249 return VLC_EGENERIC
;
1251 *pi64
= p_sys
->i_time
;
1254 case DEMUX_GET_LENGTH
:
1255 pi64
= (int64_t*)va_arg( args
, int64_t * );
1256 if( p_sys
->i_mux_rate
> 0 )
1258 *pi64
= INT64_C(1000000) * ( stream_Size( p_demux
->s
) / 50 ) /
1263 return VLC_EGENERIC
;
1265 case DEMUX_GET_TIME
:
1266 pi64
= (int64_t*)va_arg( args
, int64_t * );
1267 if( DVBEventInformation( p_demux
, pi64
, NULL
) )
1271 case DEMUX_GET_LENGTH
:
1272 pi64
= (int64_t*)va_arg( args
, int64_t * );
1273 if( DVBEventInformation( p_demux
, NULL
, pi64
) )
1277 case DEMUX_SET_GROUP
:
1281 i_int
= (int)va_arg( args
, int );
1282 p_list
= (vlc_list_t
*)va_arg( args
, vlc_list_t
* );
1283 msg_Dbg( p_demux
, "DEMUX_SET_GROUP %d %p", i_int
, p_list
);
1285 if( i_int
== 0 && p_sys
->i_current_program
> 0 )
1286 i_int
= p_sys
->i_current_program
;
1288 if( p_sys
->i_current_program
> 0 )
1290 if( p_sys
->i_current_program
!= i_int
)
1291 SetPrgFilter( p_demux
, p_sys
->i_current_program
, false );
1293 else if( p_sys
->i_current_program
< 0 )
1295 for( int i
= 0; i
< p_sys
->programs_list
.i_count
; i
++ )
1296 SetPrgFilter( p_demux
, p_sys
->programs_list
.p_values
[i
].i_int
, false );
1301 p_sys
->i_current_program
= i_int
;
1302 SetPrgFilter( p_demux
, p_sys
->i_current_program
, true );
1304 else if( i_int
< 0 )
1306 p_sys
->i_current_program
= -1;
1307 p_sys
->programs_list
.i_count
= 0;
1310 vlc_list_t
*p_dst
= &p_sys
->programs_list
;
1311 free( p_dst
->p_values
);
1313 p_dst
->p_values
= calloc( p_list
->i_count
,
1314 sizeof(*p_dst
->p_values
) );
1315 if( p_dst
->p_values
)
1317 p_dst
->i_count
= p_list
->i_count
;
1318 for( int i
= 0; i
< p_list
->i_count
; i
++ )
1320 p_dst
->p_values
[i
] = p_list
->p_values
[i
];
1321 SetPrgFilter( p_demux
, p_dst
->p_values
[i
].i_int
, true );
1329 case DEMUX_CAN_RECORD
:
1330 pb_bool
= (bool*)va_arg( args
, bool * );
1334 case DEMUX_SET_RECORD_STATE
:
1335 b_bool
= (bool)va_arg( args
, int );
1338 stream_Control( p_demux
->s
, STREAM_SET_RECORD_STATE
, false );
1339 p_sys
->b_start_record
= b_bool
;
1343 case DEMUX_SET_TIME
:
1345 return VLC_EGENERIC
;
1349 /*****************************************************************************
1351 *****************************************************************************/
1352 static int UserPmt( demux_t
*p_demux
, const char *psz_fmt
)
1354 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1355 char *psz_dup
= strdup( psz_fmt
);
1356 char *psz
= psz_dup
;
1364 i_pid
= strtol( psz
, &psz
, 0 );
1365 if( i_pid
< 2 || i_pid
>= 8192 )
1368 /* Parse optional program number */
1371 i_number
= strtol( &psz
[1], &psz
, 0 );
1374 ts_pid_t
*pmt
= &p_sys
->pid
[i_pid
];
1377 msg_Dbg( p_demux
, "user pmt specified (pid=%d,number=%d)", i_pid
, i_number
);
1378 PIDInit( pmt
, true, NULL
);
1381 prg
= malloc( sizeof( ts_prg_psi_t
) );
1385 memset( prg
, 0, sizeof( ts_prg_psi_t
) );
1386 prg
->i_pid_pcr
= -1;
1387 prg
->i_pid_pmt
= -1;
1388 prg
->i_version
= -1;
1389 prg
->i_number
= i_number
!= 0 ? i_number
: TS_USER_PMT_NUMBER
;
1390 prg
->handle
= dvbpsi_AttachPMT( i_number
!= TS_USER_PMT_NUMBER
? i_number
: 1, (dvbpsi_pmt_callback
)PMTCallBack
, p_demux
);
1391 TAB_APPEND( pmt
->psi
->i_prg
, pmt
->psi
->prg
, prg
);
1393 psz
= strchr( psz
, '=' );
1396 while( psz
&& *psz
)
1398 char *psz_next
= strchr( psz
, ',' );
1404 i_pid
= strtol( psz
, &psz
, 0 );
1405 if( *psz
!= ':' || i_pid
< 2 || i_pid
>= 8192 )
1408 char *psz_opt
= &psz
[1];
1409 if( !strcmp( psz_opt
, "pcr" ) )
1411 prg
->i_pid_pcr
= i_pid
;
1413 else if( !p_sys
->pid
[i_pid
].b_valid
)
1415 ts_pid_t
*pid
= &p_sys
->pid
[i_pid
];
1417 char *psz_arg
= strchr( psz_opt
, '=' );
1421 PIDInit( pid
, false, pmt
->psi
);
1422 if( prg
->i_pid_pcr
<= 0 )
1423 prg
->i_pid_pcr
= i_pid
;
1425 if( psz_arg
&& strlen( psz_arg
) == 4 )
1427 const vlc_fourcc_t i_codec
= VLC_FOURCC( psz_arg
[0], psz_arg
[1],
1428 psz_arg
[2], psz_arg
[3] );
1429 int i_cat
= UNKNOWN_ES
;
1430 es_format_t
*fmt
= &pid
->es
->fmt
;
1432 if( !strcmp( psz_opt
, "video" ) )
1434 else if( !strcmp( psz_opt
, "audio" ) )
1436 else if( !strcmp( psz_opt
, "spu" ) )
1439 es_format_Init( fmt
, i_cat
, i_codec
);
1440 fmt
->b_packetized
= false;
1444 const int i_stream_type
= strtol( psz_opt
, NULL
, 0 );
1445 PIDFillFormat( pid
, i_stream_type
);
1447 pid
->es
->fmt
.i_group
= i_number
;
1448 if( p_sys
->b_es_id_pid
)
1449 pid
->es
->fmt
.i_id
= i_pid
;
1451 if( pid
->es
->fmt
.i_cat
!= UNKNOWN_ES
)
1453 msg_Dbg( p_demux
, " * es pid=%d fcc=%4.4s", i_pid
,
1454 (char*)&pid
->es
->fmt
.i_codec
);
1455 pid
->es
->id
= es_out_Add( p_demux
->out
,
1465 p_sys
->b_user_pmt
= true;
1466 TAB_APPEND( p_sys
->i_pmt
, p_sys
->pmt
, pmt
);
1472 return VLC_EGENERIC
;
1475 static int SetPIDFilter( demux_t
*p_demux
, int i_pid
, bool b_selected
)
1477 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1479 if( !p_sys
->b_access_control
)
1480 return VLC_EGENERIC
;
1482 return stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
1483 ACCESS_SET_PRIVATE_ID_STATE
, i_pid
, b_selected
);
1486 static void SetPrgFilter( demux_t
*p_demux
, int i_prg_id
, bool b_selected
)
1488 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1489 ts_prg_psi_t
*p_prg
= NULL
;
1492 /* Search pmt to be unselected */
1493 for( int i
= 0; i
< p_sys
->i_pmt
; i
++ )
1495 ts_pid_t
*pmt
= p_sys
->pmt
[i
];
1497 for( int i_prg
= 0; i_prg
< pmt
->psi
->i_prg
; i_prg
++ )
1499 if( pmt
->psi
->prg
[i_prg
]->i_number
== i_prg_id
)
1501 i_pmt_pid
= p_sys
->pmt
[i
]->i_pid
;
1502 p_prg
= p_sys
->pmt
[i
]->psi
->prg
[i_prg
];
1509 if( i_pmt_pid
<= 0 )
1513 SetPIDFilter( p_demux
, i_pmt_pid
, b_selected
);
1514 if( p_prg
->i_pid_pcr
> 0 )
1515 SetPIDFilter( p_demux
, p_prg
->i_pid_pcr
, b_selected
);
1518 for( int i
= 2; i
< 8192; i
++ )
1520 ts_pid_t
*pid
= &p_sys
->pid
[i
];
1522 if( !pid
->b_valid
|| pid
->psi
)
1525 for( int i_prg
= 0; i_prg
< pid
->p_owner
->i_prg
; i_prg
++ )
1527 if( pid
->p_owner
->prg
[i_prg
]->i_pid_pmt
== i_pmt_pid
&& pid
->es
->id
)
1529 /* We only remove/select es that aren't defined by extra pmt */
1530 SetPIDFilter( p_demux
, i
, b_selected
);
1537 static void PIDInit( ts_pid_t
*pid
, bool b_psi
, ts_psi_t
*p_owner
)
1539 bool b_old_valid
= pid
->b_valid
;
1541 pid
->b_valid
= true;
1543 pid
->b_scrambled
= false;
1544 pid
->p_owner
= p_owner
;
1545 pid
->i_owner_number
= 0;
1547 TAB_INIT( pid
->i_extra_es
, pid
->extra_es
);
1555 pid
->psi
= xmalloc( sizeof( ts_psi_t
) );
1558 pid
->psi
->handle
= NULL
;
1559 TAB_INIT( pid
->psi
->i_prg
, pid
->psi
->prg
);
1564 pid
->psi
->i_pat_version
= -1;
1565 pid
->psi
->i_sdt_version
= -1;
1568 ts_prg_psi_t
*prg
= malloc( sizeof( ts_prg_psi_t
) );
1572 prg
->i_version
= -1;
1574 prg
->i_pid_pcr
= -1;
1575 prg
->i_pid_pmt
= -1;
1579 TAB_APPEND( pid
->psi
->i_prg
, pid
->psi
->prg
, prg
);
1586 pid
->es
= malloc( sizeof( ts_es_t
) );
1589 es_format_Init( &pid
->es
->fmt
, UNKNOWN_ES
, 0 );
1591 pid
->es
->p_pes
= NULL
;
1592 pid
->es
->i_pes_size
= 0;
1593 pid
->es
->i_pes_gathered
= 0;
1594 pid
->es
->pp_last
= &pid
->es
->p_pes
;
1595 pid
->es
->p_mpeg4desc
= NULL
;
1596 pid
->es
->b_gather
= false;
1601 static void PIDClean( demux_t
*p_demux
, ts_pid_t
*pid
)
1603 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1604 es_out_t
*out
= p_demux
->out
;
1608 if( pid
->psi
->handle
)
1609 dvbpsi_DetachPMT( pid
->psi
->handle
);
1610 for( int i
= 0; i
< pid
->psi
->i_prg
; i
++ )
1612 if( pid
->psi
->prg
[i
]->iod
)
1613 IODFree( pid
->psi
->prg
[i
]->iod
);
1614 if( pid
->psi
->prg
[i
]->handle
)
1615 dvbpsi_DetachPMT( pid
->psi
->prg
[i
]->handle
);
1616 free( pid
->psi
->prg
[i
] );
1618 free( pid
->psi
->prg
);
1625 es_out_Del( out
, pid
->es
->id
);
1629 if( pid
->es
->p_pes
)
1630 block_ChainRelease( pid
->es
->p_pes
);
1632 es_format_Clean( &pid
->es
->fmt
);
1636 for( int i
= 0; i
< pid
->i_extra_es
; i
++ )
1638 if( pid
->extra_es
[i
]->id
)
1640 es_out_Del( out
, pid
->extra_es
[i
]->id
);
1644 if( pid
->extra_es
[i
]->p_pes
)
1645 block_ChainRelease( pid
->extra_es
[i
]->p_pes
);
1647 es_format_Clean( &pid
->extra_es
[i
]->fmt
);
1649 free( pid
->extra_es
[i
] );
1651 if( pid
->i_extra_es
)
1652 free( pid
->extra_es
);
1655 pid
->b_valid
= false;
1658 /****************************************************************************
1660 ****************************************************************************/
1661 static void ParsePES( demux_t
*p_demux
, ts_pid_t
*pid
)
1663 block_t
*p_pes
= pid
->es
->p_pes
;
1665 unsigned i_pes_size
= 0;
1666 unsigned i_skip
= 0;
1669 mtime_t i_length
= 0;
1671 /* remove the pes from pid */
1672 pid
->es
->p_pes
= NULL
;
1673 pid
->es
->i_pes_size
= 0;
1674 pid
->es
->i_pes_gathered
= 0;
1675 pid
->es
->pp_last
= &pid
->es
->p_pes
;
1677 /* FIXME find real max size */
1678 /* const int i_max = */ block_ChainExtract( p_pes
, header
, 34 );
1680 if( header
[0] != 0 || header
[1] != 0 || header
[2] != 1 )
1682 if( !p_demux
->p_sys
->b_silent
)
1683 msg_Warn( p_demux
, "invalid header [0x%x:%x:%x:%x] (pid: %d)",
1684 header
[0], header
[1],header
[2],header
[3], pid
->i_pid
);
1685 block_ChainRelease( p_pes
);
1689 /* TODO check size */
1692 case 0xBC: /* Program stream map */
1693 case 0xBE: /* Padding */
1694 case 0xBF: /* Private stream 2 */
1695 case 0xF0: /* ECM */
1696 case 0xF1: /* EMM */
1697 case 0xFF: /* Program stream directory */
1698 case 0xF2: /* DSMCC stream */
1699 case 0xF8: /* ITU-T H.222.1 type E stream */
1703 if( ( header
[6]&0xC0 ) == 0x80 )
1706 i_skip
= header
[8] + 9;
1708 if( header
[7]&0x80 ) /* has pts */
1710 i_pts
= ((mtime_t
)(header
[ 9]&0x0e ) << 29)|
1711 (mtime_t
)(header
[10] << 22)|
1712 ((mtime_t
)(header
[11]&0xfe) << 14)|
1713 (mtime_t
)(header
[12] << 7)|
1714 (mtime_t
)(header
[13] >> 1);
1716 if( header
[7]&0x40 ) /* has dts */
1718 i_dts
= ((mtime_t
)(header
[14]&0x0e ) << 29)|
1719 (mtime_t
)(header
[15] << 22)|
1720 ((mtime_t
)(header
[16]&0xfe) << 14)|
1721 (mtime_t
)(header
[17] << 7)|
1722 (mtime_t
)(header
[18] >> 1);
1729 while( i_skip
< 23 && header
[i_skip
] == 0xff )
1735 msg_Err( p_demux
, "too much MPEG-1 stuffing" );
1736 block_ChainRelease( p_pes
);
1739 if( ( header
[i_skip
] & 0xC0 ) == 0x40 )
1744 if( header
[i_skip
]&0x20 )
1746 i_pts
= ((mtime_t
)(header
[i_skip
]&0x0e ) << 29)|
1747 (mtime_t
)(header
[i_skip
+1] << 22)|
1748 ((mtime_t
)(header
[i_skip
+2]&0xfe) << 14)|
1749 (mtime_t
)(header
[i_skip
+3] << 7)|
1750 (mtime_t
)(header
[i_skip
+4] >> 1);
1752 if( header
[i_skip
]&0x10 ) /* has dts */
1754 i_dts
= ((mtime_t
)(header
[i_skip
+5]&0x0e ) << 29)|
1755 (mtime_t
)(header
[i_skip
+6] << 22)|
1756 ((mtime_t
)(header
[i_skip
+7]&0xfe) << 14)|
1757 (mtime_t
)(header
[i_skip
+8] << 7)|
1758 (mtime_t
)(header
[i_skip
+9] >> 1);
1774 if( pid
->es
->fmt
.i_codec
== VLC_FOURCC( 'a', '5', '2', 'b' ) ||
1775 pid
->es
->fmt
.i_codec
== VLC_FOURCC( 'd', 't', 's', 'b' ) )
1779 else if( pid
->es
->fmt
.i_codec
== VLC_FOURCC( 'l', 'p', 'c', 'b' ) ||
1780 pid
->es
->fmt
.i_codec
== VLC_FOURCC( 's', 'p', 'u', 'b' ) ||
1781 pid
->es
->fmt
.i_codec
== VLC_FOURCC( 's', 'd', 'd', 'b' ) )
1785 else if( pid
->es
->fmt
.i_codec
== VLC_CODEC_SUBT
&&
1786 pid
->es
->p_mpeg4desc
)
1788 decoder_config_descriptor_t
*dcd
= &pid
->es
->p_mpeg4desc
->dec_descr
;
1790 if( dcd
->i_decoder_specific_info_len
> 2 &&
1791 dcd
->p_decoder_specific_info
[0] == 0x10 &&
1792 ( dcd
->p_decoder_specific_info
[1]&0x10 ) )
1794 /* display length */
1795 if( p_pes
->i_buffer
+ 2 <= i_skip
)
1796 i_length
= GetWBE( &p_pes
->p_buffer
[i_skip
] );
1800 if( p_pes
->i_buffer
+ 2 <= i_skip
)
1801 i_pes_size
= GetWBE( &p_pes
->p_buffer
[i_skip
] );
1805 #ifdef ZVBI_COMPILED
1806 else if( pid
->es
->fmt
.i_codec
== VLC_CODEC_TELETEXT
)
1807 i_skip
= 0; /*hack for zvbi support */
1810 while( p_pes
&& i_skip
> 0 )
1812 if( p_pes
->i_buffer
<= i_skip
)
1814 block_t
*p_next
= p_pes
->p_next
;
1816 i_skip
-= p_pes
->i_buffer
;
1817 block_Release( p_pes
);
1822 p_pes
->i_buffer
-= i_skip
;
1823 p_pes
->p_buffer
+= i_skip
;
1828 /* ISO/IEC 13818-1 2.7.5: if no pts and no dts, then dts == pts */
1829 if( i_pts
>= 0 && i_dts
< 0 )
1838 p_pes
->i_dts
= VLC_TS_0
+ i_dts
* 100 / 9;
1841 p_pes
->i_pts
= VLC_TS_0
+ i_pts
* 100 / 9;
1843 p_pes
->i_length
= i_length
* 100 / 9;
1845 p_block
= block_ChainGather( p_pes
);
1846 if( pid
->es
->fmt
.i_codec
== VLC_CODEC_SUBT
)
1848 if( i_pes_size
> 0 && p_block
->i_buffer
> i_pes_size
)
1850 p_block
->i_buffer
= i_pes_size
;
1853 p_block
= block_Realloc( p_block
, 0, p_block
->i_buffer
+ 1 );
1854 p_block
->p_buffer
[p_block
->i_buffer
-1] = '\0';
1857 for( i
= 0; i
< pid
->i_extra_es
; i
++ )
1859 es_out_Send( p_demux
->out
, pid
->extra_es
[i
]->id
,
1860 block_Duplicate( p_block
) );
1863 es_out_Send( p_demux
->out
, pid
->es
->id
, p_block
);
1867 msg_Warn( p_demux
, "empty pes" );
1871 static void PCRHandle( demux_t
*p_demux
, ts_pid_t
*pid
, block_t
*p_bk
)
1873 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1874 const uint8_t *p
= p_bk
->p_buffer
;
1876 if( p_sys
->i_pmt_es
<= 0 )
1879 if( ( p
[3]&0x20 ) && /* adaptation */
1883 /* PCR is 33 bits */
1884 const mtime_t i_pcr
= ( (mtime_t
)p
[6] << 25 ) |
1885 ( (mtime_t
)p
[7] << 17 ) |
1886 ( (mtime_t
)p
[8] << 9 ) |
1887 ( (mtime_t
)p
[9] << 1 ) |
1888 ( (mtime_t
)p
[10] >> 7 );
1890 /* Search program and set the PCR */
1891 for( int i
= 0; i
< p_sys
->i_pmt
; i
++ )
1893 for( int i_prg
= 0; i_prg
< p_sys
->pmt
[i
]->psi
->i_prg
; i_prg
++ )
1895 if( pid
->i_pid
== p_sys
->pmt
[i
]->psi
->prg
[i_prg
]->i_pid_pcr
)
1897 es_out_Control( p_demux
->out
, ES_OUT_SET_GROUP_PCR
,
1898 (int)p_sys
->pmt
[i
]->psi
->prg
[i_prg
]->i_number
,
1899 (int64_t)(VLC_TS_0
+ i_pcr
* 100 / 9) );
1906 static bool GatherPES( demux_t
*p_demux
, ts_pid_t
*pid
, block_t
*p_bk
)
1908 const uint8_t *p
= p_bk
->p_buffer
;
1909 const bool b_unit_start
= p
[1]&0x40;
1910 const bool b_scrambled
= p
[3]&0x80;
1911 const bool b_adaptation
= p
[3]&0x20;
1912 const bool b_payload
= p
[3]&0x10;
1913 const int i_cc
= p
[3]&0x0f; /* continuity counter */
1914 bool b_discontinuity
= false; /* discontinuity */
1916 /* transport_scrambling_control is ignored */
1921 msg_Dbg( p_demux
, "pid=%d unit_start=%d adaptation=%d payload=%d "
1922 "cc=0x%x", pid
->i_pid
, b_unit_start
, b_adaptation
,
1926 /* For now, ignore additional error correction
1927 * TODO: handle Reed-Solomon 204,188 error correction */
1928 p_bk
->i_buffer
= TS_PACKET_SIZE_188
;
1932 msg_Dbg( p_demux
, "transport_error_indicator set (pid=%d)",
1934 if( pid
->es
->p_pes
) //&& pid->es->fmt.i_cat == VIDEO_ES )
1935 pid
->es
->p_pes
->i_flags
|= BLOCK_FLAG_CORRUPTED
;
1938 if( p_demux
->p_sys
->csa
)
1940 vlc_mutex_lock( &p_demux
->p_sys
->csa_lock
);
1941 csa_Decrypt( p_demux
->p_sys
->csa
, p_bk
->p_buffer
, p_demux
->p_sys
->i_csa_pkt_size
);
1942 vlc_mutex_unlock( &p_demux
->p_sys
->csa_lock
);
1947 /* We don't have any adaptation_field, so payload starts
1948 * immediately after the 4 byte TS header */
1953 /* p[4] is adaptation_field_length minus one */
1957 /* discontinuity indicator found in stream */
1958 b_discontinuity
= (p
[5]&0x80) ? true : false;
1959 if( b_discontinuity
&& pid
->es
->p_pes
)
1961 msg_Warn( p_demux
, "discontinuity indicator (pid=%d) ",
1963 /* pid->es->p_pes->i_flags |= BLOCK_FLAG_DISCONTINUITY; */
1967 msg_Dbg( p_demux
, "random access indicator (pid=%d) ", pid
->i_pid
);
1972 /* Test continuity counter */
1973 /* continuous when (one of this):
1975 * diff == 0 and payload == 0
1976 * diff == 0 and duplicate packet (playload != 0) <- should we
1977 * test the content ?
1979 const int i_diff
= ( i_cc
- pid
->i_cc
)&0x0f;
1980 if( b_payload
&& i_diff
== 1 )
1982 pid
->i_cc
= ( pid
->i_cc
+ 1 ) & 0xf;
1986 if( pid
->i_cc
== 0xff )
1988 msg_Warn( p_demux
, "first packet for pid=%d cc=0x%x",
1992 else if( i_diff
!= 0 && !b_discontinuity
)
1994 msg_Warn( p_demux
, "discontinuity received 0x%x instead of 0x%x (pid=%d)",
1995 i_cc
, ( pid
->i_cc
+ 1 )&0x0f, pid
->i_pid
);
1998 if( pid
->es
->p_pes
&& pid
->es
->fmt
.i_cat
!= VIDEO_ES
)
2000 /* Small video artifacts are usually better than
2001 * dropping full frames */
2002 pid
->es
->p_pes
->i_flags
|= BLOCK_FLAG_CORRUPTED
;
2007 PCRHandle( p_demux
, pid
, p_bk
);
2009 if( i_skip
>= 188 || pid
->es
->id
== NULL
|| p_demux
->p_sys
->b_udp_out
)
2011 block_Release( p_bk
);
2016 if( !pid
->b_scrambled
!= !b_scrambled
)
2018 msg_Warn( p_demux
, "scrambled state changed on pid %d (%d->%d)",
2019 pid
->i_pid
, pid
->b_scrambled
, b_scrambled
);
2021 pid
->b_scrambled
= b_scrambled
;
2023 for( int i
= 0; i
< pid
->i_extra_es
; i
++ )
2025 es_out_Control( p_demux
->out
, ES_OUT_SET_ES_SCRAMBLED_STATE
,
2026 pid
->extra_es
[i
]->id
, b_scrambled
);
2028 es_out_Control( p_demux
->out
, ES_OUT_SET_ES_SCRAMBLED_STATE
,
2029 pid
->es
->id
, b_scrambled
);
2032 /* We have to gather it */
2033 p_bk
->p_buffer
+= i_skip
;
2034 p_bk
->i_buffer
-= i_skip
;
2038 if( pid
->es
->p_pes
)
2040 ParsePES( p_demux
, pid
);
2044 block_ChainLastAppend( &pid
->es
->pp_last
, p_bk
);
2045 if( p_bk
->i_buffer
> 6 )
2047 pid
->es
->i_pes_size
= GetWBE( &p_bk
->p_buffer
[4] );
2048 if( pid
->es
->i_pes_size
> 0 )
2050 pid
->es
->i_pes_size
+= 6;
2053 pid
->es
->i_pes_gathered
+= p_bk
->i_buffer
;
2054 if( pid
->es
->i_pes_size
> 0 &&
2055 pid
->es
->i_pes_gathered
>= pid
->es
->i_pes_size
)
2057 ParsePES( p_demux
, pid
);
2063 if( pid
->es
->p_pes
== NULL
)
2065 /* msg_Dbg( p_demux, "broken packet" ); */
2066 block_Release( p_bk
);
2070 block_ChainLastAppend( &pid
->es
->pp_last
, p_bk
);
2071 pid
->es
->i_pes_gathered
+= p_bk
->i_buffer
;
2072 if( pid
->es
->i_pes_size
> 0 &&
2073 pid
->es
->i_pes_gathered
>= pid
->es
->i_pes_size
)
2075 ParsePES( p_demux
, pid
);
2084 static int PIDFillFormat( ts_pid_t
*pid
, int i_stream_type
)
2086 es_format_t
*fmt
= &pid
->es
->fmt
;
2088 switch( i_stream_type
)
2090 case 0x01: /* MPEG-1 video */
2091 case 0x02: /* MPEG-2 video */
2092 case 0x80: /* MPEG-2 MOTO video */
2093 es_format_Init( fmt
, VIDEO_ES
, VLC_CODEC_MPGV
);
2095 case 0x03: /* MPEG-1 audio */
2096 case 0x04: /* MPEG-2 audio */
2097 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_MPGA
);
2099 case 0x11: /* MPEG4 (audio) LATM */
2100 case 0x0f: /* ISO/IEC 13818-7 Audio with ADTS transport syntax */
2101 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_MP4A
);
2103 case 0x10: /* MPEG4 (video) */
2104 es_format_Init( fmt
, VIDEO_ES
, VLC_CODEC_MP4V
);
2105 pid
->es
->b_gather
= true;
2107 case 0x1B: /* H264 <- check transport syntax/needed descriptor */
2108 es_format_Init( fmt
, VIDEO_ES
, VLC_CODEC_H264
);
2111 case 0x81: /* A52 (audio) */
2112 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_A52
);
2114 case 0x82: /* DVD_SPU (sub) */
2115 es_format_Init( fmt
, SPU_ES
, VLC_CODEC_SPU
);
2117 case 0x83: /* LPCM (audio) */
2118 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_DVD_LPCM
);
2120 case 0x84: /* SDDS (audio) */
2121 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_SDDS
);
2123 case 0x85: /* DTS (audio) */
2124 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_DTS
);
2126 case 0x87: /* E-AC3 */
2127 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_EAC3
);
2130 case 0x91: /* A52 vls (audio) */
2131 es_format_Init( fmt
, AUDIO_ES
, VLC_FOURCC( 'a', '5', '2', 'b' ) );
2133 case 0x92: /* DVD_SPU vls (sub) */
2134 es_format_Init( fmt
, SPU_ES
, VLC_FOURCC( 's', 'p', 'u', 'b' ) );
2137 case 0x94: /* SDDS (audio) */
2138 es_format_Init( fmt
, AUDIO_ES
, VLC_FOURCC( 's', 'd', 'd', 'b' ) );
2141 case 0xa0: /* MSCODEC vlc (video) (fixed later) */
2142 es_format_Init( fmt
, UNKNOWN_ES
, 0 );
2143 pid
->es
->b_gather
= true;
2146 case 0x06: /* PES_PRIVATE (fixed later) */
2147 case 0x12: /* MPEG-4 generic (sub/scene/...) (fixed later) */
2148 case 0xEA: /* Privately managed ES (VC-1) (fixed later */
2150 es_format_Init( fmt
, UNKNOWN_ES
, 0 );
2154 /* PES packets usually contain truncated frames */
2155 fmt
->b_packetized
= false;
2157 return fmt
->i_cat
== UNKNOWN_ES
? VLC_EGENERIC
: VLC_SUCCESS
;
2160 /*****************************************************************************
2161 * MP4 specific functions (IOD parser)
2162 *****************************************************************************/
2163 static int IODDescriptorLength( int *pi_data
, uint8_t **pp_data
)
2166 unsigned int i_len
= 0;
2172 i_len
= ( i_len
<< 7 ) + ( i_b
&0x7f );
2174 } while( i_b
&0x80 );
2179 static int IODGetByte( int *pi_data
, uint8_t **pp_data
)
2183 const int i_b
= **pp_data
;
2191 static int IODGetWord( int *pi_data
, uint8_t **pp_data
)
2193 const int i1
= IODGetByte( pi_data
, pp_data
);
2194 const int i2
= IODGetByte( pi_data
, pp_data
);
2195 return( ( i1
<< 8 ) | i2
);
2198 static int IODGet3Bytes( int *pi_data
, uint8_t **pp_data
)
2200 const int i1
= IODGetByte( pi_data
, pp_data
);
2201 const int i2
= IODGetByte( pi_data
, pp_data
);
2202 const int i3
= IODGetByte( pi_data
, pp_data
);
2204 return( ( i1
<< 16 ) | ( i2
<< 8) | i3
);
2207 static uint32_t IODGetDWord( int *pi_data
, uint8_t **pp_data
)
2209 const uint32_t i1
= IODGetWord( pi_data
, pp_data
);
2210 const uint32_t i2
= IODGetWord( pi_data
, pp_data
);
2211 return( ( i1
<< 16 ) | i2
);
2214 static char* IODGetURL( int *pi_data
, uint8_t **pp_data
)
2219 i_url_len
= IODGetByte( pi_data
, pp_data
);
2220 url
= malloc( i_url_len
+ 1 );
2221 if( !url
) return NULL
;
2222 for( i
= 0; i
< i_url_len
; i
++ )
2224 url
[i
] = IODGetByte( pi_data
, pp_data
);
2226 url
[i_url_len
] = '\0';
2230 static iod_descriptor_t
*IODNew( int i_data
, uint8_t *p_data
)
2232 iod_descriptor_t
*p_iod
;
2235 uint8_t i_flags
, i_iod_tag
, byte1
, byte2
, byte3
;
2239 p_iod
= malloc( sizeof( iod_descriptor_t
) );
2240 if( !p_iod
) return NULL
;
2241 memset( p_iod
, 0, sizeof( iod_descriptor_t
) );
2244 fprintf( stderr
, "\n************ IOD ************" );
2246 for( i
= 0; i
< 255; i
++ )
2248 p_iod
->es_descr
[i
].b_ok
= 0;
2257 byte1
= IODGetByte( &i_data
, &p_data
);
2258 byte2
= IODGetByte( &i_data
, &p_data
);
2259 byte3
= IODGetByte( &i_data
, &p_data
);
2260 if( byte2
== 0x02 ) //old vlc's buggy implementation of the IOD_descriptor
2262 p_iod
->i_iod_label_scope
= 0x11;
2263 p_iod
->i_iod_label
= byte1
;
2266 else //correct implementation of the IOD_descriptor
2268 p_iod
->i_iod_label_scope
= byte1
;
2269 p_iod
->i_iod_label
= byte2
;
2273 fprintf( stderr
, "\n* iod_label:%d", p_iod
->i_iod_label
);
2274 fprintf( stderr
, "\n* ===========" );
2275 fprintf( stderr
, "\n* tag:0x%x", i_iod_tag
);
2277 if( i_iod_tag
!= 0x02 )
2280 fprintf( stderr
, "\n ERR: tag %02x != 0x02", i_iod_tag
);
2285 i_iod_length
= IODDescriptorLength( &i_data
, &p_data
);
2287 fprintf( stderr
, "\n* length:%d", i_iod_length
);
2289 if( i_iod_length
> i_data
)
2291 i_iod_length
= i_data
;
2294 p_iod
->i_od_id
= ( IODGetByte( &i_data
, &p_data
) << 2 );
2295 i_flags
= IODGetByte( &i_data
, &p_data
);
2296 p_iod
->i_od_id
|= i_flags
>> 6;
2297 b_url
= ( i_flags
>> 5 )&0x01;
2299 fprintf( stderr
, "\n* od_id:%d", p_iod
->i_od_id
);
2300 fprintf( stderr
, "\n* url flag:%d", b_url
);
2301 fprintf( stderr
, "\n* includeInlineProfileLevel flag:%d", ( i_flags
>> 4 )&0x01 );
2305 p_iod
->psz_url
= IODGetURL( &i_data
, &p_data
);
2307 fprintf( stderr
, "\n* url string:%s", p_iod
->psz_url
);
2308 fprintf( stderr
, "\n*****************************\n" );
2314 p_iod
->psz_url
= NULL
;
2317 p_iod
->i_ODProfileLevelIndication
= IODGetByte( &i_data
, &p_data
);
2318 p_iod
->i_sceneProfileLevelIndication
= IODGetByte( &i_data
, &p_data
);
2319 p_iod
->i_audioProfileLevelIndication
= IODGetByte( &i_data
, &p_data
);
2320 p_iod
->i_visualProfileLevelIndication
= IODGetByte( &i_data
, &p_data
);
2321 p_iod
->i_graphicsProfileLevelIndication
= IODGetByte( &i_data
, &p_data
);
2323 fprintf( stderr
, "\n* ODProfileLevelIndication:%d", p_iod
->i_ODProfileLevelIndication
);
2324 fprintf( stderr
, "\n* sceneProfileLevelIndication:%d", p_iod
->i_sceneProfileLevelIndication
);
2325 fprintf( stderr
, "\n* audioProfileLevelIndication:%d", p_iod
->i_audioProfileLevelIndication
);
2326 fprintf( stderr
, "\n* visualProfileLevelIndication:%d", p_iod
->i_visualProfileLevelIndication
);
2327 fprintf( stderr
, "\n* graphicsProfileLevelIndication:%d", p_iod
->i_graphicsProfileLevelIndication
);
2330 while( i_data
> 0 && i_es_index
< 255)
2332 int i_tag
, i_length
;
2334 uint8_t *p_data_sav
;
2336 i_tag
= IODGetByte( &i_data
, &p_data
);
2337 i_length
= IODDescriptorLength( &i_data
, &p_data
);
2339 i_data_sav
= i_data
;
2340 p_data_sav
= p_data
;
2348 #define es_descr p_iod->es_descr[i_es_index]
2349 int i_decoderConfigDescr_length
;
2351 fprintf( stderr
, "\n* - ES_Descriptor length:%d", i_length
);
2355 es_descr
.i_es_id
= IODGetWord( &i_data
, &p_data
);
2356 i_flags
= IODGetByte( &i_data
, &p_data
);
2357 es_descr
.b_streamDependenceFlag
= ( i_flags
>> 7 )&0x01;
2358 b_url
= ( i_flags
>> 6 )&0x01;
2359 es_descr
.b_OCRStreamFlag
= ( i_flags
>> 5 )&0x01;
2360 es_descr
.i_streamPriority
= i_flags
& 0x1f;
2362 fprintf( stderr
, "\n* * streamDependenceFlag:%d", es_descr
.b_streamDependenceFlag
);
2363 fprintf( stderr
, "\n* * OCRStreamFlag:%d", es_descr
.b_OCRStreamFlag
);
2364 fprintf( stderr
, "\n* * streamPriority:%d", es_descr
.i_streamPriority
);
2366 if( es_descr
.b_streamDependenceFlag
)
2368 es_descr
.i_dependOn_es_id
= IODGetWord( &i_data
, &p_data
);
2370 fprintf( stderr
, "\n* * dependOn_es_id:%d", es_descr
.i_dependOn_es_id
);
2376 es_descr
.psz_url
= IODGetURL( &i_data
, &p_data
);
2378 fprintf( stderr
, "\n* url string:%s", es_descr
.psz_url
);
2383 es_descr
.psz_url
= NULL
;
2386 if( es_descr
.b_OCRStreamFlag
)
2388 es_descr
.i_OCR_es_id
= IODGetWord( &i_data
, &p_data
);
2390 fprintf( stderr
, "\n* * OCR_es_id:%d", es_descr
.i_OCR_es_id
);
2394 if( IODGetByte( &i_data
, &p_data
) != 0x04 )
2397 fprintf( stderr
, "\n* ERR missing DecoderConfigDescr" );
2402 i_decoderConfigDescr_length
= IODDescriptorLength( &i_data
, &p_data
);
2404 fprintf( stderr
, "\n* - DecoderConfigDesc length:%d", i_decoderConfigDescr_length
);
2406 #define dec_descr es_descr.dec_descr
2407 dec_descr
.i_objectTypeIndication
= IODGetByte( &i_data
, &p_data
);
2408 i_flags
= IODGetByte( &i_data
, &p_data
);
2409 dec_descr
.i_streamType
= i_flags
>> 2;
2410 dec_descr
.b_upStream
= ( i_flags
>> 1 )&0x01;
2411 dec_descr
.i_bufferSizeDB
= IODGet3Bytes( &i_data
, &p_data
);
2412 dec_descr
.i_maxBitrate
= IODGetDWord( &i_data
, &p_data
);
2413 dec_descr
.i_avgBitrate
= IODGetDWord( &i_data
, &p_data
);
2415 fprintf( stderr
, "\n* * objectTypeIndication:0x%x", dec_descr
.i_objectTypeIndication
);
2416 fprintf( stderr
, "\n* * streamType:0x%x", dec_descr
.i_streamType
);
2417 fprintf( stderr
, "\n* * upStream:%d", dec_descr
.b_upStream
);
2418 fprintf( stderr
, "\n* * bufferSizeDB:%d", dec_descr
.i_bufferSizeDB
);
2419 fprintf( stderr
, "\n* * maxBitrate:%d", dec_descr
.i_maxBitrate
);
2420 fprintf( stderr
, "\n* * avgBitrate:%d", dec_descr
.i_avgBitrate
);
2422 if( i_decoderConfigDescr_length
> 13 && IODGetByte( &i_data
, &p_data
) == 0x05 )
2425 dec_descr
.i_decoder_specific_info_len
=
2426 IODDescriptorLength( &i_data
, &p_data
);
2427 if( dec_descr
.i_decoder_specific_info_len
> 0 )
2429 dec_descr
.p_decoder_specific_info
=
2430 malloc( dec_descr
.i_decoder_specific_info_len
);
2432 for( i
= 0; i
< dec_descr
.i_decoder_specific_info_len
; i
++ )
2434 dec_descr
.p_decoder_specific_info
[i
] = IODGetByte( &i_data
, &p_data
);
2439 dec_descr
.i_decoder_specific_info_len
= 0;
2440 dec_descr
.p_decoder_specific_info
= NULL
;
2444 #define sl_descr es_descr.sl_descr
2446 int i_SLConfigDescr_length
;
2449 if( IODGetByte( &i_data
, &p_data
) != 0x06 )
2452 fprintf( stderr
, "\n* ERR missing SLConfigDescr" );
2457 i_SLConfigDescr_length
= IODDescriptorLength( &i_data
, &p_data
);
2459 fprintf( stderr
, "\n* - SLConfigDescr length:%d", i_SLConfigDescr_length
);
2461 i_predefined
= IODGetByte( &i_data
, &p_data
);
2463 fprintf( stderr
, "\n* * i_predefined:0x%x", i_predefined
);
2465 switch( i_predefined
)
2469 sl_descr
.b_useAccessUnitStartFlag
= 0;
2470 sl_descr
.b_useAccessUnitEndFlag
= 0;
2471 sl_descr
.b_useRandomAccessPointFlag
= 0;
2472 //sl_descr.b_useRandomAccessUnitsOnlyFlag = 0;
2473 sl_descr
.b_usePaddingFlag
= 0;
2474 sl_descr
.b_useTimeStampsFlags
= 0;
2475 sl_descr
.b_useIdleFlag
= 0;
2476 sl_descr
.b_durationFlag
= 0; // FIXME FIXME
2477 sl_descr
.i_timeStampResolution
= 1000;
2478 sl_descr
.i_OCRResolution
= 0; // FIXME FIXME
2479 sl_descr
.i_timeStampLength
= 32;
2480 sl_descr
.i_OCRLength
= 0; // FIXME FIXME
2481 sl_descr
.i_AU_Length
= 0;
2482 sl_descr
.i_instantBitrateLength
= 0; // FIXME FIXME
2483 sl_descr
.i_degradationPriorityLength
= 0;
2484 sl_descr
.i_AU_seqNumLength
= 0;
2485 sl_descr
.i_packetSeqNumLength
= 0;
2486 if( sl_descr
.b_durationFlag
)
2488 sl_descr
.i_timeScale
= 0; // FIXME FIXME
2489 sl_descr
.i_accessUnitDuration
= 0; // FIXME FIXME
2490 sl_descr
.i_compositionUnitDuration
= 0; // FIXME FIXME
2492 if( !sl_descr
.b_useTimeStampsFlags
)
2494 sl_descr
.i_startDecodingTimeStamp
= 0; // FIXME FIXME
2495 sl_descr
.i_startCompositionTimeStamp
= 0; // FIXME FIXME
2501 fprintf( stderr
, "\n* ERR unsupported SLConfigDescr predefined" );
2512 fprintf( stderr
, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag
, i_length
);
2517 p_data
= p_data_sav
+ i_length
;
2518 i_data
= i_data_sav
- i_length
;
2522 fprintf( stderr
, "\n*****************************\n" );
2527 static void IODFree( iod_descriptor_t
*p_iod
)
2531 if( p_iod
->psz_url
)
2533 free( p_iod
->psz_url
);
2534 p_iod
->psz_url
= NULL
;
2539 for( i
= 0; i
< 255; i
++ )
2541 #define es_descr p_iod->es_descr[i]
2544 if( es_descr
.psz_url
)
2546 free( es_descr
.psz_url
);
2547 es_descr
.psz_url
= NULL
;
2551 free( es_descr
.dec_descr
.p_decoder_specific_info
);
2552 es_descr
.dec_descr
.p_decoder_specific_info
= NULL
;
2553 es_descr
.dec_descr
.i_decoder_specific_info_len
= 0;
2562 /****************************************************************************
2563 ****************************************************************************
2564 ** libdvbpsi callbacks
2565 ****************************************************************************
2566 ****************************************************************************/
2567 static bool ProgramIsSelected( demux_t
*p_demux
, uint16_t i_pgrm
)
2569 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2571 if( ( p_sys
->i_current_program
== -1 && p_sys
->programs_list
.i_count
== 0 ) ||
2572 p_sys
->i_current_program
== 0 )
2574 if( p_sys
->i_current_program
== i_pgrm
)
2577 if( p_sys
->programs_list
.i_count
!= 0 )
2579 for( int i
= 0; i
< p_sys
->programs_list
.i_count
; i
++ )
2581 if( i_pgrm
== p_sys
->programs_list
.p_values
[i
].i_int
)
2588 static void ValidateDVBMeta( demux_t
*p_demux
, int i_pid
)
2590 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2592 if( !p_sys
->b_dvb_meta
|| ( i_pid
!= 0x11 && i_pid
!= 0x12 && i_pid
!= 0x14 ) )
2595 msg_Warn( p_demux
, "Switching to non DVB mode" );
2597 /* This doesn't look like a DVB stream so don't try
2598 * parsing the SDT/EDT/TDT */
2600 for( int i
= 0x11; i
<= 0x14; i
++ )
2602 if( i
== 0x13 ) continue;
2603 ts_pid_t
*p_pid
= &p_sys
->pid
[i
];
2606 dvbpsi_DetachDemux( p_pid
->psi
->handle
);
2609 p_pid
->b_valid
= false;
2611 SetPIDFilter( p_demux
, i
, false );
2613 p_sys
->b_dvb_meta
= false;
2617 #ifdef TS_USE_DVB_SI
2618 /* FIXME same than dvbsi_to_utf8 from dvb access */
2619 static char *EITConvertToUTF8( const unsigned char *psz_instring
,
2623 const char *psz_encoding
;
2624 char *psz_outstring
;
2625 char psz_encbuf
[sizeof( "ISO_8859-123" )];
2626 size_t i_in
, i_out
, offset
= 1;
2627 vlc_iconv_t iconv_handle
;
2629 if( i_length
< 1 ) return NULL
;
2630 if( psz_instring
[0] >= 0x20 )
2632 /* According to ETSI EN 300 468 Annex A, this should be ISO6937,
2633 * but some broadcasters use different charset... */
2635 psz_encoding
= "ISO_8859-1";
2637 psz_encoding
= "ISO_6937";
2641 else switch( psz_instring
[0] )
2644 psz_encoding
= "ISO_8859-5";
2647 psz_encoding
= "ISO_8859-6";
2650 psz_encoding
= "ISO_8859-7";
2653 psz_encoding
= "ISO_8859-8";
2656 psz_encoding
= "ISO_8859-9";
2659 psz_encoding
= "ISO_8859-10";
2662 psz_encoding
= "ISO_8859-11";
2665 psz_encoding
= "ISO_8859-12";
2668 psz_encoding
= "ISO_8859-13";
2671 psz_encoding
= "ISO_8859-14";
2674 psz_encoding
= "ISO_8859-15";
2677 #warning Is Latin-10 (psz_instring[2] == 16) really illegal?
2678 if( i_length
< 3 || psz_instring
[1] != 0x00 || psz_instring
[2] > 15
2679 || psz_instring
[2] == 0 )
2681 psz_encoding
= "UTF-8";
2686 sprintf( psz_encbuf
, "ISO_8859-%u", psz_instring
[2] );
2687 psz_encoding
= psz_encbuf
;
2692 #warning Is there a BOM or do we use a fixed endianess?
2693 psz_encoding
= "UTF-16";
2696 psz_encoding
= "KSC5601-1987";
2699 psz_encoding
= "GB2312"; /* GB-2312-1980 */
2702 psz_encoding
= "BIG-5";
2705 psz_encoding
= "UTF-8";
2709 psz_encoding
= "UTF-8";
2713 i_in
= i_length
- offset
;
2714 i_out
= i_in
* 6 + 1;
2716 psz_outstring
= malloc( i_out
);
2717 if( !psz_outstring
)
2722 iconv_handle
= vlc_iconv_open( "UTF-8", psz_encoding
);
2723 if( iconv_handle
== (vlc_iconv_t
)(-1) )
2725 /* Invalid character set (e.g. ISO_8859-12) */
2726 memcpy( psz_outstring
, &psz_instring
[offset
], i_in
);
2727 psz_outstring
[i_in
] = '\0';
2728 EnsureUTF8( psz_outstring
);
2732 const char *psz_in
= (const char *)&psz_instring
[offset
];
2733 char *psz_out
= psz_outstring
;
2735 while( vlc_iconv( iconv_handle
, &psz_in
, &i_in
,
2736 &psz_out
, &i_out
) == (size_t)(-1) )
2738 /* skip naughty byte. This may fail terribly for multibyte stuff,
2739 * but what can we do anyway? */
2742 vlc_iconv( iconv_handle
, NULL
, NULL
, NULL
, NULL
); /* reset */
2744 vlc_iconv_close( iconv_handle
);
2748 /* Convert EIT-coded CR/LFs */
2749 unsigned char *pbuf
= (unsigned char *)psz_outstring
;
2750 for( ; pbuf
< (unsigned char *)psz_out
; pbuf
++)
2752 if( pbuf
[0] == 0xc2 && pbuf
[1] == 0x8a )
2761 return psz_outstring
;
2764 static void SDTCallBack( demux_t
*p_demux
, dvbpsi_sdt_t
*p_sdt
)
2766 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2767 ts_pid_t
*sdt
= &p_sys
->pid
[0x11];
2768 dvbpsi_sdt_service_t
*p_srv
;
2770 msg_Dbg( p_demux
, "SDTCallBack called" );
2772 if( sdt
->psi
->i_sdt_version
!= -1 &&
2773 ( !p_sdt
->b_current_next
||
2774 p_sdt
->i_version
== sdt
->psi
->i_sdt_version
) )
2776 dvbpsi_DeleteSDT( p_sdt
);
2780 msg_Dbg( p_demux
, "new SDT ts_id=%d version=%d current_next=%d "
2782 p_sdt
->i_ts_id
, p_sdt
->i_version
, p_sdt
->b_current_next
,
2783 p_sdt
->i_network_id
);
2785 p_sys
->b_broken_charset
= false;
2787 for( p_srv
= p_sdt
->p_first_service
; p_srv
; p_srv
= p_srv
->p_next
)
2790 dvbpsi_descriptor_t
*p_dr
;
2792 const char *psz_type
= NULL
;
2793 const char *psz_status
= NULL
;
2795 msg_Dbg( p_demux
, " * service id=%d eit schedule=%d present=%d "
2796 "running=%d free_ca=%d",
2797 p_srv
->i_service_id
, p_srv
->b_eit_schedule
,
2798 p_srv
->b_eit_present
, p_srv
->i_running_status
,
2801 p_meta
= vlc_meta_New();
2802 for( p_dr
= p_srv
->p_first_descriptor
; p_dr
; p_dr
= p_dr
->p_next
)
2804 if( p_dr
->i_tag
== 0x48 )
2806 static const char *ppsz_type
[17] = {
2808 "Digital television service",
2809 "Digital radio sound service",
2811 "NVOD reference service",
2812 "NVOD time-shifted service",
2815 "SECAM coded signal",
2818 "NTSC coded signal",
2819 "Data broadcast service",
2820 "Reserved for Common Interface Usage",
2821 "RCS Map (see EN 301 790 [35])",
2822 "RCS FLS (see EN 301 790 [35])",
2825 dvbpsi_service_dr_t
*pD
= dvbpsi_DecodeServiceDr( p_dr
);
2829 /* Workarounds for broadcasters with broken EPG */
2831 if( p_sdt
->i_network_id
== 133 )
2832 p_sys
->b_broken_charset
= true; /* SKY DE & BetaDigital use ISO8859-1 */
2834 /* List of providers using ISO8859-1 */
2835 static const char ppsz_broken_providers
[][8] = {
2836 "CSAT", /* CanalSat FR */
2837 "GR1", /* France televisions */
2839 "MR5", /* France 2/M6 HD */
2842 for( int i
= 0; *ppsz_broken_providers
[i
]; i
++ )
2844 const size_t i_length
= strlen(ppsz_broken_providers
[i
]);
2845 if( pD
->i_service_provider_name_length
== i_length
&&
2846 !strncmp( pD
->i_service_provider_name
, ppsz_broken_providers
[i
], i_length
) )
2847 p_sys
->b_broken_charset
= true;
2850 /* FIXME: Digital+ ES also uses ISO8859-1 */
2852 str1
= EITConvertToUTF8(pD
->i_service_provider_name
,
2853 pD
->i_service_provider_name_length
,
2854 p_sys
->b_broken_charset
);
2855 str2
= EITConvertToUTF8(pD
->i_service_name
,
2856 pD
->i_service_name_length
,
2857 p_sys
->b_broken_charset
);
2859 msg_Dbg( p_demux
, " - type=%d provider=%s name=%s",
2860 pD
->i_service_type
, str1
, str2
);
2862 vlc_meta_SetTitle( p_meta
, str2
);
2863 vlc_meta_SetPublisher( p_meta
, str1
);
2864 if( pD
->i_service_type
>= 0x01 && pD
->i_service_type
<= 0x10 )
2865 psz_type
= ppsz_type
[pD
->i_service_type
];
2871 if( p_srv
->i_running_status
>= 0x01 && p_srv
->i_running_status
<= 0x04 )
2873 static const char *ppsz_status
[5] = {
2876 "Starts in a few seconds",
2880 psz_status
= ppsz_status
[p_srv
->i_running_status
];
2884 vlc_meta_AddExtra( p_meta
, "Type", psz_type
);
2886 vlc_meta_AddExtra( p_meta
, "Status", psz_status
);
2888 es_out_Control( p_demux
->out
, ES_OUT_SET_GROUP_META
,
2889 p_srv
->i_service_id
, p_meta
);
2890 vlc_meta_Delete( p_meta
);
2893 sdt
->psi
->i_sdt_version
= p_sdt
->i_version
;
2894 dvbpsi_DeleteSDT( p_sdt
);
2897 /* i_year: year - 1900 i_month: 0-11 i_mday: 1-31 i_hour: 0-23 i_minute: 0-59 i_second: 0-59 */
2898 static int64_t vlc_timegm( int i_year
, int i_month
, int i_mday
, int i_hour
, int i_minute
, int i_second
)
2900 static const int pn_day
[12+1] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
2905 i_month
< 0 || i_month
> 11 || i_mday
< 1 || i_mday
> 31 ||
2906 i_hour
< 0 || i_hour
> 23 || i_minute
< 0 || i_minute
> 59 || i_second
< 0 || i_second
> 59 )
2909 /* Count the number of days */
2910 i_day
= 365 * (i_year
-70) + pn_day
[i_month
] + i_mday
- 1;
2911 #define LEAP(y) ( ((y)%4) == 0 && (((y)%100) != 0 || ((y)%400) == 0) ? 1 : 0)
2912 for( i
= 70; i
< i_year
; i
++ )
2913 i_day
+= LEAP(1900+i
);
2915 i_day
+= LEAP(1900+i_year
);
2918 return ((24*i_day
+ i_hour
)*60 + i_minute
)*60 + i_second
;
2921 static void EITDecodeMjd( int i_mjd
, int *p_y
, int *p_m
, int *p_d
)
2923 const int yp
= (int)( ( (double)i_mjd
- 15078.2)/365.25 );
2924 const int mp
= (int)( ((double)i_mjd
- 14956.1 - (int)(yp
* 365.25)) / 30.6001 );
2925 const int c
= ( mp
== 14 || mp
== 15 ) ? 1 : 0;
2927 *p_y
= 1900 + yp
+ c
*1;
2928 *p_m
= mp
- 1 - c
*12;
2929 *p_d
= i_mjd
- 14956 - (int)(yp
*365.25) - (int)(mp
*30.6001);
2931 #define CVT_FROM_BCD(v) ((((v) >> 4)&0xf)*10 + ((v)&0xf))
2932 static int64_t EITConvertStartTime( uint64_t i_date
)
2934 const int i_mjd
= i_date
>> 24;
2935 const int i_hour
= CVT_FROM_BCD(i_date
>> 16);
2936 const int i_minute
= CVT_FROM_BCD(i_date
>> 8);
2937 const int i_second
= CVT_FROM_BCD(i_date
);
2942 /* if all 40 bits are 1, the start is unknown */
2943 if( i_date
== UINT64_C(0xffffffffff) )
2946 EITDecodeMjd( i_mjd
, &i_year
, &i_month
, &i_day
);
2947 return vlc_timegm( i_year
- 1900, i_month
- 1, i_day
, i_hour
, i_minute
, i_second
);
2949 static int EITConvertDuration( uint32_t i_duration
)
2951 return CVT_FROM_BCD(i_duration
>> 16) * 3600 +
2952 CVT_FROM_BCD(i_duration
>> 8 ) * 60 +
2953 CVT_FROM_BCD(i_duration
);
2958 static void TDTCallBack( demux_t
*p_demux
, dvbpsi_tot_t
*p_tdt
)
2960 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2962 p_sys
->i_tdt_delta
= CLOCK_FREQ
* EITConvertStartTime( p_tdt
->i_utc_time
)
2964 dvbpsi_DeleteTOT(p_tdt
);
2969 static void EITCallBack( demux_t
*p_demux
,
2970 dvbpsi_eit_t
*p_eit
, bool b_current_following
)
2972 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2973 dvbpsi_eit_event_t
*p_evt
;
2976 msg_Dbg( p_demux
, "EITCallBack called" );
2977 if( !p_eit
->b_current_next
)
2979 dvbpsi_DeleteEIT( p_eit
);
2983 msg_Dbg( p_demux
, "new EIT service_id=%d version=%d current_next=%d "
2984 "ts_id=%d network_id=%d segment_last_section_number=%d "
2986 p_eit
->i_service_id
, p_eit
->i_version
, p_eit
->b_current_next
,
2987 p_eit
->i_ts_id
, p_eit
->i_network_id
,
2988 p_eit
->i_segment_last_section_number
, p_eit
->i_last_table_id
);
2990 p_epg
= vlc_epg_New( NULL
);
2991 for( p_evt
= p_eit
->p_first_event
; p_evt
; p_evt
= p_evt
->p_next
)
2993 dvbpsi_descriptor_t
*p_dr
;
2994 char *psz_name
= NULL
;
2995 char *psz_text
= NULL
;
2996 char *psz_extra
= strdup("");
3000 i_start
= EITConvertStartTime( p_evt
->i_start_time
);
3001 i_duration
= EITConvertDuration( p_evt
->i_duration
);
3003 msg_Dbg( p_demux
, " * event id=%d start_time:%d duration=%d "
3004 "running=%d free_ca=%d",
3005 p_evt
->i_event_id
, (int)i_start
, (int)i_duration
,
3006 p_evt
->i_running_status
, p_evt
->b_free_ca
);
3008 for( p_dr
= p_evt
->p_first_descriptor
; p_dr
; p_dr
= p_dr
->p_next
)
3010 if( p_dr
->i_tag
== 0x4d )
3012 dvbpsi_short_event_dr_t
*pE
= dvbpsi_DecodeShortEventDr( p_dr
);
3014 /* Only take first description, as we don't handle language-info
3016 if( pE
&& psz_name
== NULL
)
3018 psz_name
= EITConvertToUTF8( pE
->i_event_name
, pE
->i_event_name_length
,
3019 p_sys
->b_broken_charset
);
3020 psz_text
= EITConvertToUTF8( pE
->i_text
, pE
->i_text_length
,
3021 p_sys
->b_broken_charset
);
3022 msg_Dbg( p_demux
, " - short event lang=%3.3s '%s' : '%s'",
3023 pE
->i_iso_639_code
, psz_name
, psz_text
);
3026 else if( p_dr
->i_tag
== 0x4e )
3028 dvbpsi_extended_event_dr_t
*pE
= dvbpsi_DecodeExtendedEventDr( p_dr
);
3031 msg_Dbg( p_demux
, " - extended event lang=%3.3s [%d/%d]",
3033 pE
->i_descriptor_number
, pE
->i_last_descriptor_number
);
3035 if( pE
->i_text_length
> 0 )
3037 char *psz_text
= EITConvertToUTF8( pE
->i_text
, pE
->i_text_length
,
3038 p_sys
->b_broken_charset
);
3041 msg_Dbg( p_demux
, " - text='%s'", psz_text
);
3043 psz_extra
= xrealloc( psz_extra
,
3044 strlen(psz_extra
) + strlen(psz_text
) + 1 );
3045 strcat( psz_extra
, psz_text
);
3050 for( int i
= 0; i
< pE
->i_entry_count
; i
++ )
3052 char *psz_dsc
= EITConvertToUTF8( pE
->i_item_description
[i
],
3053 pE
->i_item_description_length
[i
],
3054 p_sys
->b_broken_charset
);
3055 char *psz_itm
= EITConvertToUTF8( pE
->i_item
[i
], pE
->i_item_length
[i
],
3056 p_sys
->b_broken_charset
);
3058 if( psz_dsc
&& psz_itm
)
3060 msg_Dbg( p_demux
, " - desc='%s' item='%s'", psz_dsc
, psz_itm
);
3062 psz_extra
= xrealloc( psz_extra
,
3063 strlen(psz_extra
) + strlen(psz_dsc
) +
3064 strlen(psz_itm
) + 3 + 1 );
3065 strcat( psz_extra
, "(" );
3066 strcat( psz_extra
, psz_dsc
);
3067 strcat( psz_extra
, " " );
3068 strcat( psz_extra
, psz_itm
);
3069 strcat( psz_extra
, ")" );
3079 msg_Dbg( p_demux
, " - tag=0x%x(%d)", p_dr
->i_tag
, p_dr
->i_tag
);
3085 vlc_epg_AddEvent( p_epg
, i_start
, i_duration
, psz_name
, psz_text
,
3086 *psz_extra
? psz_extra
: NULL
);
3088 /* Update "now playing" field */
3089 if( p_evt
->i_running_status
== 0x04 && i_start
> 0 )
3090 vlc_epg_SetCurrent( p_epg
, i_start
);
3097 if( p_epg
->i_event
> 0 )
3099 if( b_current_following
&&
3100 ( p_sys
->i_current_program
== -1 ||
3101 p_sys
->i_current_program
== p_eit
->i_service_id
) )
3103 p_sys
->i_dvb_length
= 0;
3104 p_sys
->i_dvb_start
= 0;
3106 if( p_epg
->p_current
)
3108 p_sys
->i_dvb_start
= CLOCK_FREQ
* p_epg
->p_current
->i_start
;
3109 p_sys
->i_dvb_length
= CLOCK_FREQ
* p_epg
->p_current
->i_duration
;
3112 es_out_Control( p_demux
->out
, ES_OUT_SET_GROUP_EPG
, p_eit
->i_service_id
, p_epg
);
3114 vlc_epg_Delete( p_epg
);
3116 dvbpsi_DeleteEIT( p_eit
);
3118 static void EITCallBackCurrentFollowing( demux_t
*p_demux
, dvbpsi_eit_t
*p_eit
)
3120 EITCallBack( p_demux
, p_eit
, true );
3122 static void EITCallBackSchedule( demux_t
*p_demux
, dvbpsi_eit_t
*p_eit
)
3124 EITCallBack( p_demux
, p_eit
, false );
3127 static void PSINewTableCallBack( demux_t
*p_demux
, dvbpsi_handle h
,
3128 uint8_t i_table_id
, uint16_t i_extension
)
3131 msg_Dbg( p_demux
, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
3132 i_table_id
, i_table_id
, i_extension
, i_extension
);
3134 if( p_demux
->p_sys
->pid
[0].psi
->i_pat_version
!= -1 && i_table_id
== 0x42 )
3136 msg_Dbg( p_demux
, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
3137 i_table_id
, i_table_id
, i_extension
, i_extension
);
3139 dvbpsi_AttachSDT( h
, i_table_id
, i_extension
,
3140 (dvbpsi_sdt_callback
)SDTCallBack
, p_demux
);
3142 else if( p_demux
->p_sys
->pid
[0x11].psi
->i_sdt_version
!= -1 &&
3143 ( i_table_id
== 0x4e || /* Current/Following */
3144 (i_table_id
>= 0x50 && i_table_id
<= 0x5f) ) ) /* Schedule */
3146 msg_Dbg( p_demux
, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
3147 i_table_id
, i_table_id
, i_extension
, i_extension
);
3149 dvbpsi_eit_callback cb
= i_table_id
== 0x4e ?
3150 (dvbpsi_eit_callback
)EITCallBackCurrentFollowing
:
3151 (dvbpsi_eit_callback
)EITCallBackSchedule
;
3152 dvbpsi_AttachEIT( h
, i_table_id
, i_extension
, cb
, p_demux
);
3155 else if( p_demux
->p_sys
->pid
[0x11].psi
->i_sdt_version
!= -1 &&
3156 i_table_id
== 0x70 ) /* TDT */
3158 msg_Dbg( p_demux
, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
3159 i_table_id
, i_table_id
, i_extension
, i_extension
);
3160 dvbpsi_AttachTOT( h
, i_table_id
, i_extension
,
3161 (dvbpsi_tot_callback
)TDTCallBack
, p_demux
);
3168 /*****************************************************************************
3169 * PMT callback and helpers
3170 *****************************************************************************/
3171 static dvbpsi_descriptor_t
*PMTEsFindDescriptor( const dvbpsi_pmt_es_t
*p_es
,
3174 dvbpsi_descriptor_t
*p_dr
= p_es
->p_first_descriptor
;;
3175 while( p_dr
&& ( p_dr
->i_tag
!= i_tag
) )
3176 p_dr
= p_dr
->p_next
;
3179 static bool PMTEsHasRegistration( demux_t
*p_demux
,
3180 const dvbpsi_pmt_es_t
*p_es
,
3181 const char *psz_tag
)
3183 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x05 );
3187 if( p_dr
->i_length
< 4 )
3189 msg_Warn( p_demux
, "invalid Registration Descriptor" );
3193 assert( strlen(psz_tag
) == 4 );
3194 return !memcmp( p_dr
->p_data
, psz_tag
, 4 );
3196 static void PMTSetupEsISO14496( demux_t
*p_demux
, ts_pid_t
*pid
,
3197 const ts_prg_psi_t
*prg
, const dvbpsi_pmt_es_t
*p_es
)
3199 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3201 /* MPEG-4 stream: search SL_DESCRIPTOR */
3202 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x1f );
3204 if( p_dr
&& p_dr
->i_length
== 2 )
3206 const int i_es_id
= ( p_dr
->p_data
[0] << 8 ) | p_dr
->p_data
[1];
3208 msg_Warn( p_demux
, "found SL_descriptor es_id=%d", i_es_id
);
3210 pid
->es
->p_mpeg4desc
= NULL
;
3212 for( int i
= 0; i
< 255; i
++ )
3214 iod_descriptor_t
*iod
= prg
->iod
;
3216 if( iod
->es_descr
[i
].b_ok
&&
3217 iod
->es_descr
[i
].i_es_id
== i_es_id
)
3219 pid
->es
->p_mpeg4desc
= &iod
->es_descr
[i
];
3224 if( !pid
->es
->p_mpeg4desc
)
3226 msg_Err( p_demux
, "MPEG-4 descriptor not found" );
3230 const decoder_config_descriptor_t
*dcd
= &pid
->es
->p_mpeg4desc
->dec_descr
;
3231 if( dcd
->i_streamType
== 0x04 ) /* VisualStream */
3233 p_fmt
->i_cat
= VIDEO_ES
;
3234 switch( dcd
->i_objectTypeIndication
)
3236 case 0x0B: /* mpeg4 sub */
3237 p_fmt
->i_cat
= SPU_ES
;
3238 p_fmt
->i_codec
= VLC_CODEC_SUBT
;
3241 case 0x20: /* mpeg4 */
3242 p_fmt
->i_codec
= VLC_CODEC_MP4V
;
3244 case 0x21: /* h264 */
3245 p_fmt
->i_codec
= VLC_CODEC_H264
;
3252 case 0x65: /* mpeg2 */
3253 p_fmt
->i_codec
= VLC_CODEC_MPGV
;
3255 case 0x6a: /* mpeg1 */
3256 p_fmt
->i_codec
= VLC_CODEC_MPGV
;
3258 case 0x6c: /* mpeg1 */
3259 p_fmt
->i_codec
= VLC_CODEC_JPEG
;
3262 p_fmt
->i_cat
= UNKNOWN_ES
;
3266 else if( dcd
->i_streamType
== 0x05 ) /* AudioStream */
3268 p_fmt
->i_cat
= AUDIO_ES
;
3269 switch( dcd
->i_objectTypeIndication
)
3271 case 0x40: /* mpeg4 */
3272 p_fmt
->i_codec
= VLC_CODEC_MP4A
;
3276 case 0x68: /* mpeg2 aac */
3277 p_fmt
->i_codec
= VLC_CODEC_MP4A
;
3279 case 0x69: /* mpeg2 */
3280 p_fmt
->i_codec
= VLC_CODEC_MPGA
;
3282 case 0x6b: /* mpeg1 */
3283 p_fmt
->i_codec
= VLC_CODEC_MPGA
;
3286 p_fmt
->i_cat
= UNKNOWN_ES
;
3292 p_fmt
->i_cat
= UNKNOWN_ES
;
3295 if( p_fmt
->i_cat
!= UNKNOWN_ES
)
3297 p_fmt
->i_extra
= dcd
->i_decoder_specific_info_len
;
3298 if( p_fmt
->i_extra
> 0 )
3300 p_fmt
->p_extra
= malloc( p_fmt
->i_extra
);
3301 if( p_fmt
->p_extra
)
3302 memcpy( p_fmt
->p_extra
,
3303 dcd
->p_decoder_specific_info
,
3317 } ts_teletext_page_t
;
3319 static void PMTSetupEsTeletext( demux_t
*p_demux
, ts_pid_t
*pid
,
3320 const dvbpsi_pmt_es_t
*p_es
)
3322 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3324 ts_teletext_page_t p_page
[2 * 64 + 20];
3325 unsigned i_page
= 0;
3327 /* Gather pages information */
3328 #if defined _DVBPSI_DR_56_H_ && \
3329 defined DVBPSI_VERSION && DVBPSI_VERSION_INT > ((0<<16)+(1<<8)+5)
3330 for( unsigned i_tag_idx
= 0; i_tag_idx
< 2; i_tag_idx
++ )
3332 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, i_tag_idx
== 0 ? 0x46 : 0x56 );
3336 dvbpsi_teletext_dr_t
*p_sub
= dvbpsi_DecodeTeletextDr( p_dr
);
3340 for( int i
= 0; i
< p_sub
->i_pages_number
; i
++ )
3342 const dvbpsi_teletextpage_t
*p_src
= &p_sub
->p_pages
[i
];
3344 if( p_src
->i_teletext_type
>= 0x06 )
3347 assert( i_page
< sizeof(p_page
)/sizeof(*p_page
) );
3349 ts_teletext_page_t
*p_dst
= &p_page
[i_page
++];
3351 p_dst
->i_type
= p_src
->i_teletext_type
;
3352 p_dst
->i_magazine
= p_src
->i_teletext_magazine_number
3353 ? p_src
->i_teletext_magazine_number
: 8;
3354 p_dst
->i_page
= p_src
->i_teletext_page_number
;
3355 memcpy( p_dst
->p_iso639
, p_src
->i_iso6392_language_code
, 3 );
3360 #ifdef _DVBPSI_DR_59_H_
3361 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x59 );
3364 dvbpsi_subtitling_dr_t
*p_sub
= dvbpsi_DecodeSubtitlingDr( p_dr
);
3365 for( int i
= 0; p_sub
&& i
< p_sub
->i_subtitles_number
; i
++ )
3367 dvbpsi_subtitle_t
*p_src
= &p_sub
->p_subtitle
[i
];
3369 if( p_src
->i_subtitling_type
< 0x01 || p_src
->i_subtitling_type
> 0x03 )
3372 assert( i_page
< sizeof(p_page
)/sizeof(*p_page
) );
3374 ts_teletext_page_t
*p_dst
= &p_page
[i_page
++];
3376 switch( p_src
->i_subtitling_type
)
3379 p_dst
->i_type
= 0x02;
3382 p_dst
->i_type
= 0x03;
3385 /* FIXME check if it is the right split */
3386 p_dst
->i_magazine
= (p_src
->i_composition_page_id
>> 8)
3387 ? (p_src
->i_composition_page_id
>> 8) : 8;
3388 p_dst
->i_page
= p_src
->i_composition_page_id
& 0xff;
3389 memcpy( p_dst
->p_iso639
, p_src
->i_iso6392_language_code
, 3 );
3395 es_format_Init( p_fmt
, SPU_ES
, VLC_CODEC_TELETEXT
);
3397 if( !p_demux
->p_sys
->b_split_es
|| i_page
<= 0 )
3399 p_fmt
->subs
.teletext
.i_magazine
= -1;
3400 p_fmt
->subs
.teletext
.i_page
= 0;
3401 p_fmt
->psz_description
= strdup( vlc_gettext(ppsz_teletext_type
[1]) );
3403 dvbpsi_descriptor_t
*p_dr
;
3404 p_dr
= PMTEsFindDescriptor( p_es
, 0x46 );
3406 p_dr
= PMTEsFindDescriptor( p_es
, 0x56 );
3408 if( !p_demux
->p_sys
->b_split_es
&& p_dr
&& p_dr
->i_length
> 0 )
3410 /* Descriptor pass-through */
3411 p_fmt
->p_extra
= malloc( p_dr
->i_length
);
3412 if( p_fmt
->p_extra
)
3414 p_fmt
->i_extra
= p_dr
->i_length
;
3415 memcpy( p_fmt
->p_extra
, p_dr
->p_data
, p_dr
->i_length
);
3421 for( unsigned i
= 0; i
< i_page
; i
++ )
3432 p_es
= malloc( sizeof(*p_es
) );
3436 es_format_Copy( &p_es
->fmt
, &pid
->es
->fmt
);
3437 free( p_es
->fmt
.psz_language
);
3438 free( p_es
->fmt
.psz_description
);
3439 p_es
->fmt
.psz_language
= NULL
;
3440 p_es
->fmt
.psz_description
= NULL
;
3444 p_es
->i_pes_size
= 0;
3445 p_es
->i_pes_gathered
= 0;
3446 p_es
->pp_last
= &p_es
->p_pes
;
3447 p_es
->p_mpeg4desc
= NULL
;
3448 p_es
->b_gather
= false;
3450 TAB_APPEND( pid
->i_extra_es
, pid
->extra_es
, p_es
);
3454 const ts_teletext_page_t
*p
= &p_page
[i
];
3455 p_es
->fmt
.i_priority
= (p
->i_type
== 0x02 || p
->i_type
== 0x05) ? 0 : -1;
3456 p_es
->fmt
.psz_language
= strndup( p
->p_iso639
, 3 );
3457 p_es
->fmt
.psz_description
= strdup(vlc_gettext(ppsz_teletext_type
[p
->i_type
]));
3458 p_es
->fmt
.subs
.teletext
.i_magazine
= p
->i_magazine
;
3459 p_es
->fmt
.subs
.teletext
.i_page
= p
->i_page
;
3462 " * ttxt type=%s lan=%s page=%d%02x",
3463 p_es
->fmt
.psz_description
,
3464 p_es
->fmt
.psz_language
,
3465 p
->i_magazine
, p
->i_page
);
3469 static void PMTSetupEsDvbSubtitle( demux_t
*p_demux
, ts_pid_t
*pid
,
3470 const dvbpsi_pmt_es_t
*p_es
)
3472 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3474 es_format_Init( p_fmt
, SPU_ES
, VLC_CODEC_DVBS
);
3476 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x59 );
3478 #ifdef _DVBPSI_DR_59_H_
3479 dvbpsi_subtitling_dr_t
*p_sub
= dvbpsi_DecodeSubtitlingDr( p_dr
);
3480 for( int i
= 0; p_sub
&& i
< p_sub
->i_subtitles_number
; i
++ )
3482 const int i_type
= p_sub
->p_subtitle
[i
].i_subtitling_type
;
3483 if( ( i_type
>= 0x10 && i_type
<= 0x14 ) ||
3484 ( i_type
>= 0x20 && i_type
<= 0x24 ) )
3489 if( !p_demux
->p_sys
->b_split_es
|| i_page
<= 0 )
3491 p_fmt
->subs
.dvb
.i_id
= -1;
3492 p_fmt
->psz_description
= strdup( _("DVB subtitles") );
3494 if( !p_demux
->p_sys
->b_split_es
&& p_dr
&& p_dr
->i_length
> 0 )
3496 /* Descriptor pass-through */
3497 p_fmt
->p_extra
= malloc( p_dr
->i_length
);
3498 if( p_fmt
->p_extra
)
3500 p_fmt
->i_extra
= p_dr
->i_length
;
3501 memcpy( p_fmt
->p_extra
, p_dr
->p_data
, p_dr
->i_length
);
3507 #ifdef _DVBPSI_DR_59_H_
3508 for( int i
= 0; i
< p_sub
->i_subtitles_number
; i
++ )
3519 p_es
= malloc( sizeof(*p_es
) );
3523 es_format_Copy( &p_es
->fmt
, &pid
->es
->fmt
);
3524 free( p_es
->fmt
.psz_language
);
3525 free( p_es
->fmt
.psz_description
);
3526 p_es
->fmt
.psz_language
= NULL
;
3527 p_es
->fmt
.psz_description
= NULL
;
3531 p_es
->i_pes_size
= 0;
3532 p_es
->i_pes_gathered
= 0;
3533 p_es
->pp_last
= &p_es
->p_pes
;
3534 p_es
->p_mpeg4desc
= NULL
;
3535 p_es
->b_gather
= false;
3537 TAB_APPEND( pid
->i_extra_es
, pid
->extra_es
, p_es
);
3541 const dvbpsi_subtitle_t
*p
= &p_sub
->p_subtitle
[i
];
3542 p_es
->fmt
.psz_language
= strndup( p
->i_iso6392_language_code
, 3 );
3543 switch( p
->i_subtitling_type
)
3545 case 0x10: /* unspec. */
3546 case 0x11: /* 4:3 */
3547 case 0x12: /* 16:9 */
3548 case 0x13: /* 2.21:1 */
3549 case 0x14: /* HD monitor */
3550 p_es
->fmt
.psz_description
= strdup( _("DVB subtitles") );
3552 case 0x20: /* Hearing impaired unspec. */
3553 case 0x21: /* h.i. 4:3 */
3554 case 0x22: /* h.i. 16:9 */
3555 case 0x23: /* h.i. 2.21:1 */
3556 case 0x24: /* h.i. HD monitor */
3557 p_es
->fmt
.psz_description
= strdup( _("DVB subtitles: hearing impaired") );
3564 p_es
->fmt
.subs
.dvb
.i_id
= ( p
->i_composition_page_id
<< 0 ) |
3565 ( p
->i_ancillary_page_id
<< 16 );
3570 static void PMTSetupEs0x06( demux_t
*p_demux
, ts_pid_t
*pid
,
3571 const dvbpsi_pmt_es_t
*p_es
)
3573 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3575 if( PMTEsHasRegistration( p_demux
, p_es
, "AC-3" ) ||
3576 PMTEsFindDescriptor( p_es
, 0x6a ) ||
3577 PMTEsFindDescriptor( p_es
, 0x81 ) )
3579 p_fmt
->i_cat
= AUDIO_ES
;
3580 p_fmt
->i_codec
= VLC_CODEC_A52
;
3582 else if( PMTEsFindDescriptor( p_es
, 0x7a ) )
3584 /* DVB with stream_type 0x06 (ETS EN 300 468) */
3585 p_fmt
->i_cat
= AUDIO_ES
;
3586 p_fmt
->i_codec
= VLC_CODEC_EAC3
;
3588 else if( PMTEsHasRegistration( p_demux
, p_es
, "DTS1" ) ||
3589 PMTEsHasRegistration( p_demux
, p_es
, "DTS2" ) ||
3590 PMTEsHasRegistration( p_demux
, p_es
, "DTS3" ) ||
3591 PMTEsFindDescriptor( p_es
, 0x73 ) )
3593 /*registration descriptor(ETSI TS 101 154 Annex F)*/
3594 p_fmt
->i_cat
= AUDIO_ES
;
3595 p_fmt
->i_codec
= VLC_CODEC_DTS
;
3597 else if( PMTEsHasRegistration( p_demux
, p_es
, "BSSD" ) )
3599 p_fmt
->i_cat
= AUDIO_ES
;
3600 p_fmt
->b_packetized
= true;
3601 p_fmt
->i_codec
= VLC_CODEC_302M
;
3605 /* Subtitle/Teletext/VBI fallbacks */
3606 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x59 );
3608 #ifdef _DVBPSI_DR_59_H_
3609 dvbpsi_subtitling_dr_t
*p_sub
;
3610 if( p_dr
&& ( p_sub
= dvbpsi_DecodeSubtitlingDr( p_dr
) ) )
3612 for( int i
= 0; i
< p_sub
->i_subtitles_number
; i
++ )
3614 if( p_fmt
->i_cat
!= UNKNOWN_ES
)
3617 switch( p_sub
->p_subtitle
[i
].i_subtitling_type
)
3619 case 0x01: /* EBU Teletext subtitles */
3620 case 0x02: /* Associated EBU Teletext */
3621 case 0x03: /* VBI data */
3622 PMTSetupEsTeletext( p_demux
, pid
, p_es
);
3624 case 0x10: /* DVB Subtitle (normal) with no monitor AR critical */
3625 case 0x11: /* ... on 4:3 AR monitor */
3626 case 0x12: /* ... on 16:9 AR monitor */
3627 case 0x13: /* ... on 2.21:1 AR monitor */
3628 case 0x14: /* ... for display on a high definition monitor */
3629 case 0x20: /* DVB Subtitle (impaired) with no monitor AR critical */
3630 case 0x21: /* ... on 4:3 AR monitor */
3631 case 0x22: /* ... on 16:9 AR monitor */
3632 case 0x23: /* ... on 2.21:1 AR monitor */
3633 case 0x24: /* ... for display on a high definition monitor */
3634 PMTSetupEsDvbSubtitle( p_demux
, pid
, p_es
);
3637 msg_Err( p_demux
, "Unrecognized DVB subtitle type (0x%x)",
3638 p_sub
->p_subtitle
[i
].i_subtitling_type
);
3644 if( p_fmt
->i_cat
== UNKNOWN_ES
&& p_dr
)
3645 PMTSetupEsDvbSubtitle( p_demux
, pid
, p_es
);
3647 if( p_fmt
->i_cat
== UNKNOWN_ES
&&
3648 ( PMTEsFindDescriptor( p_es
, 0x45 ) || /* VBI Data descriptor */
3649 PMTEsFindDescriptor( p_es
, 0x46 ) || /* VBI Teletext descriptor */
3650 PMTEsFindDescriptor( p_es
, 0x56 ) ) ) /* EBU Teletext descriptor */
3653 PMTSetupEsTeletext( p_demux
, pid
, p_es
);
3657 #ifdef _DVBPSI_DR_52_H_
3658 /* FIXME is it useful ? */
3659 if( PMTEsFindDescriptor( p_es
, 0x52 ) )
3661 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x52 );
3662 dvbpsi_stream_identifier_dr_t
*p_si
= dvbpsi_DecodeStreamIdentifierDr( p_dr
);
3664 msg_Dbg( p_demux
, " * Stream Component Identifier: %d", p_si
->i_component_tag
);
3669 static void PMTSetupEs0xEA( demux_t
*p_demux
, ts_pid_t
*pid
,
3670 const dvbpsi_pmt_es_t
*p_es
)
3672 /* Registration Descriptor */
3673 if( !PMTEsHasRegistration( p_demux
, p_es
, "VC-1" ) )
3675 msg_Err( p_demux
, "Registration descriptor not found or invalid" );
3679 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3681 /* registration descriptor for VC-1 (SMPTE rp227) */
3682 p_fmt
->i_cat
= VIDEO_ES
;
3683 p_fmt
->i_codec
= VLC_CODEC_VC1
;
3685 /* XXX With Simple and Main profile the SEQUENCE
3686 * header is modified: video width and height are
3687 * inserted just after the start code as 2 int16_t
3688 * The packetizer will take care of that. */
3691 static void PMTSetupEs0xD1( demux_t
*p_demux
, ts_pid_t
*pid
,
3692 const dvbpsi_pmt_es_t
*p_es
)
3694 /* Registration Descriptor */
3695 if( !PMTEsHasRegistration( p_demux
, p_es
, "drac" ) )
3697 msg_Err( p_demux
, "Registration descriptor not found or invalid" );
3701 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3703 /* registration descriptor for Dirac
3704 * (backwards compatable with VC-2 (SMPTE Sxxxx:2008)) */
3705 p_fmt
->i_cat
= VIDEO_ES
;
3706 p_fmt
->i_codec
= VLC_CODEC_DIRAC
;
3709 static void PMTSetupEs0xA0( demux_t
*p_demux
, ts_pid_t
*pid
,
3710 const dvbpsi_pmt_es_t
*p_es
)
3712 /* MSCODEC sent by vlc */
3713 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0xa0 );
3714 if( !p_dr
|| p_dr
->i_length
< 10 )
3717 "private MSCODEC (vlc) without bih private descriptor" );
3721 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3722 p_fmt
->i_cat
= VIDEO_ES
;
3723 p_fmt
->i_codec
= VLC_FOURCC( p_dr
->p_data
[0], p_dr
->p_data
[1],
3724 p_dr
->p_data
[2], p_dr
->p_data
[3] );
3725 p_fmt
->video
.i_width
= GetWBE( &p_dr
->p_data
[4] );
3726 p_fmt
->video
.i_height
= GetWBE( &p_dr
->p_data
[6] );
3727 p_fmt
->i_extra
= GetWBE( &p_dr
->p_data
[8] );
3729 if( p_fmt
->i_extra
> 0 )
3731 p_fmt
->p_extra
= malloc( p_fmt
->i_extra
);
3732 if( p_fmt
->p_extra
)
3733 memcpy( p_fmt
->p_extra
, &p_dr
->p_data
[10],
3734 __MIN( p_fmt
->i_extra
, p_dr
->i_length
- 10 ) );
3738 /* For such stream we will gather them ourself and don't launch a
3740 * Yes it's ugly but it's the only way to have DIV3 working */
3741 p_fmt
->b_packetized
= true;
3744 static void PMTSetupEsHDMV( demux_t
*p_demux
, ts_pid_t
*pid
,
3745 const dvbpsi_pmt_es_t
*p_es
)
3747 VLC_UNUSED(p_demux
);
3748 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3750 /* Blu-Ray mapping */
3751 switch( p_es
->i_type
)
3754 p_fmt
->i_cat
= AUDIO_ES
;
3755 p_fmt
->i_codec
= VLC_CODEC_BD_LPCM
;
3758 case 0x85: /* DTS-HD High resolution audio */
3759 case 0x86: /* DTS-HD Master audio */
3760 case 0xA2: /* Secondary DTS audio */
3761 p_fmt
->i_cat
= AUDIO_ES
;
3762 p_fmt
->i_codec
= VLC_CODEC_DTS
;
3765 case 0x83: /* TrueHD AC3 */
3766 p_fmt
->i_cat
= AUDIO_ES
;
3767 p_fmt
->i_codec
= VLC_CODEC_TRUEHD
;
3770 case 0x84: /* E-AC3 */
3771 case 0xA1: /* Secondary E-AC3 */
3772 p_fmt
->i_cat
= AUDIO_ES
;
3773 p_fmt
->i_codec
= VLC_CODEC_EAC3
;
3775 case 0x90: /* Presentation graphics */
3776 p_fmt
->i_cat
= SPU_ES
;
3777 p_fmt
->i_codec
= VLC_CODEC_BD_PG
;
3779 case 0x91: /* Interactive graphics */
3780 case 0x92: /* Subtitle */
3786 static void PMTSetupEsRegistration( demux_t
*p_demux
, ts_pid_t
*pid
,
3787 const dvbpsi_pmt_es_t
*p_es
)
3793 vlc_fourcc_t i_codec
;
3795 { "AC-3", AUDIO_ES
, VLC_CODEC_A52
},
3796 { "DTS1", AUDIO_ES
, VLC_CODEC_DTS
},
3797 { "DTS2", AUDIO_ES
, VLC_CODEC_DTS
},
3798 { "DTS3", AUDIO_ES
, VLC_CODEC_DTS
},
3799 { "BSSD", AUDIO_ES
, VLC_CODEC_302M
},
3800 { "VC-1", VIDEO_ES
, VLC_CODEC_VC1
},
3801 { "drac", VIDEO_ES
, VLC_CODEC_DIRAC
},
3802 { "", UNKNOWN_ES
, 0 }
3804 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3806 for( int i
= 0; p_regs
[i
].i_cat
!= UNKNOWN_ES
; i
++ )
3808 if( PMTEsHasRegistration( p_demux
, p_es
, p_regs
[i
].psz_tag
) )
3810 p_fmt
->i_cat
= p_regs
[i
].i_cat
;
3811 p_fmt
->i_codec
= p_regs
[i
].i_codec
;
3817 static void PMTParseEsIso639( demux_t
*p_demux
, ts_pid_t
*pid
,
3818 const dvbpsi_pmt_es_t
*p_es
)
3820 /* get language descriptor */
3821 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x0a );
3826 dvbpsi_iso639_dr_t
*p_decoded
= dvbpsi_DecodeISO639Dr( p_dr
);
3829 msg_Err( p_demux
, "Failed to decode a ISO 639 descriptor" );
3833 #if defined(DR_0A_API_VER) && (DR_0A_API_VER >= 2)
3834 pid
->es
->fmt
.psz_language
= malloc( 4 );
3835 if( pid
->es
->fmt
.psz_language
)
3837 memcpy( pid
->es
->fmt
.psz_language
,
3838 p_decoded
->code
[0].iso_639_code
, 3 );
3839 pid
->es
->fmt
.psz_language
[3] = 0;
3840 msg_Dbg( p_demux
, "found language: %s", pid
->es
->fmt
.psz_language
);
3842 switch( p_decoded
->code
[0].i_audio_type
)
3845 pid
->es
->fmt
.i_priority
= 1; // prioritize normal audio tracks
3846 pid
->es
->fmt
.psz_description
= NULL
;
3849 pid
->es
->fmt
.psz_description
=
3850 strdup(_("clean effects"));
3853 pid
->es
->fmt
.psz_description
=
3854 strdup(_("hearing impaired"));
3857 pid
->es
->fmt
.psz_description
=
3858 strdup(_("visual impaired commentary"));
3861 msg_Dbg( p_demux
, "unknown audio type: %d",
3862 p_decoded
->code
[0].i_audio_type
);
3863 pid
->es
->fmt
.psz_description
= NULL
;
3866 pid
->es
->fmt
.i_extra_languages
= p_decoded
->i_code_count
-1;
3867 if( pid
->es
->fmt
.i_extra_languages
> 0 )
3868 pid
->es
->fmt
.p_extra_languages
=
3869 malloc( sizeof(*pid
->es
->fmt
.p_extra_languages
) *
3870 pid
->es
->fmt
.i_extra_languages
);
3871 if( pid
->es
->fmt
.p_extra_languages
)
3873 for( int i
= 0; i
< pid
->es
->fmt
.i_extra_languages
; i
++ )
3875 msg_Dbg( p_demux
, "bang" );
3876 pid
->es
->fmt
.p_extra_languages
[i
].psz_language
=
3878 if( pid
->es
->fmt
.p_extra_languages
[i
].psz_language
)
3880 memcpy( pid
->es
->fmt
.p_extra_languages
[i
].psz_language
,
3881 p_decoded
->code
[i
+1].iso_639_code
, 3 );
3882 pid
->es
->fmt
.p_extra_languages
[i
].psz_language
[3] = '\0';
3884 switch( p_decoded
->code
[i
].i_audio_type
)
3887 pid
->es
->fmt
.p_extra_languages
[i
].psz_description
=
3891 pid
->es
->fmt
.p_extra_languages
[i
].psz_description
=
3892 strdup(_("clean effects"));
3895 pid
->es
->fmt
.p_extra_languages
[i
].psz_description
=
3896 strdup(_("hearing impaired"));
3899 pid
->es
->fmt
.p_extra_languages
[i
].psz_description
=
3900 strdup(_("visual impaired commentary"));
3903 msg_Dbg( p_demux
, "unknown audio type: %d",
3904 p_decoded
->code
[i
].i_audio_type
);
3905 pid
->es
->fmt
.psz_description
= NULL
;
3912 pid
->es
->fmt
.psz_language
= malloc( 4 );
3913 if( pid
->es
->fmt
.psz_language
)
3915 memcpy( pid
->es
->fmt
.psz_language
,
3916 p_decoded
->i_iso_639_code
, 3 );
3917 pid
->es
->fmt
.psz_language
[3] = 0;
3922 static void PMTCallBack( demux_t
*p_demux
, dvbpsi_pmt_t
*p_pmt
)
3924 demux_sys_t
*p_sys
= p_demux
->p_sys
;
3925 dvbpsi_descriptor_t
*p_dr
;
3926 dvbpsi_pmt_es_t
*p_es
;
3928 ts_pid_t
*pmt
= NULL
;
3929 ts_prg_psi_t
*prg
= NULL
;
3931 ts_pid_t
**pp_clean
= NULL
;
3933 bool b_hdmv
= false;
3935 msg_Dbg( p_demux
, "PMTCallBack called" );
3937 /* First find this PMT declared in PAT */
3938 for( int i
= 0; i
< p_sys
->i_pmt
; i
++ )
3941 for( i_prg
= 0; i_prg
< p_sys
->pmt
[i
]->psi
->i_prg
; i_prg
++ )
3943 const int i_pmt_number
= p_sys
->pmt
[i
]->psi
->prg
[i_prg
]->i_number
;
3944 if( i_pmt_number
!= TS_USER_PMT_NUMBER
&& i_pmt_number
== p_pmt
->i_program_number
)
3946 pmt
= p_sys
->pmt
[i
];
3947 prg
= p_sys
->pmt
[i
]->psi
->prg
[i_prg
];
3957 msg_Warn( p_demux
, "unreferenced program (broken stream)" );
3958 dvbpsi_DeletePMT(p_pmt
);
3962 if( prg
->i_version
!= -1 &&
3963 ( !p_pmt
->b_current_next
|| prg
->i_version
== p_pmt
->i_version
) )
3965 dvbpsi_DeletePMT( p_pmt
);
3969 /* Clean this program (remove all es) */
3970 for( int i
= 0; i
< 8192; i
++ )
3972 ts_pid_t
*pid
= &p_sys
->pid
[i
];
3974 if( pid
->b_valid
&& pid
->p_owner
== pmt
->psi
&&
3975 pid
->i_owner_number
== prg
->i_number
&& pid
->psi
== NULL
)
3977 TAB_APPEND( i_clean
, pp_clean
, pid
);
3982 IODFree( prg
->iod
);
3986 msg_Dbg( p_demux
, "new PMT program number=%d version=%d pid_pcr=%d",
3987 p_pmt
->i_program_number
, p_pmt
->i_version
, p_pmt
->i_pcr_pid
);
3988 prg
->i_pid_pcr
= p_pmt
->i_pcr_pid
;
3989 prg
->i_version
= p_pmt
->i_version
;
3991 ValidateDVBMeta( p_demux
, prg
->i_pid_pcr
);
3992 if( ProgramIsSelected( p_demux
, prg
->i_number
) )
3994 /* Set demux filter */
3995 SetPIDFilter( p_demux
, prg
->i_pid_pcr
, true );
3998 /* Parse descriptor */
3999 for( p_dr
= p_pmt
->p_first_descriptor
; p_dr
!= NULL
; p_dr
= p_dr
->p_next
)
4001 if( p_dr
->i_tag
== 0x1d )
4003 /* We have found an IOD descriptor */
4004 msg_Dbg( p_demux
, " * descriptor : IOD (0x1d)" );
4006 prg
->iod
= IODNew( p_dr
->i_length
, p_dr
->p_data
);
4008 else if( p_dr
->i_tag
== 0x9 )
4010 uint16_t i_sysid
= ((uint16_t)p_dr
->p_data
[0] << 8)
4012 msg_Dbg( p_demux
, " * descriptor : CA (0x9) SysID 0x%x", i_sysid
);
4014 else if( p_dr
->i_tag
== 0x05 )
4016 /* Registration Descriptor */
4017 if( p_dr
->i_length
!= 4 )
4019 msg_Warn( p_demux
, "invalid Registration Descriptor" );
4023 msg_Dbg( p_demux
, " * descriptor : registration %4.4s", p_dr
->p_data
);
4024 if( !memcmp( p_dr
->p_data
, "HDMV", 4 ) )
4033 msg_Dbg( p_demux
, " * descriptor : unknown (0x%x)", p_dr
->i_tag
);
4037 for( p_es
= p_pmt
->p_first_es
; p_es
!= NULL
; p_es
= p_es
->p_next
)
4039 ts_pid_t tmp_pid
, *old_pid
= 0, *pid
= &tmp_pid
;
4041 /* Find out if the PID was already declared */
4042 for( int i
= 0; i
< i_clean
; i
++ )
4044 if( pp_clean
[i
] == &p_sys
->pid
[p_es
->i_pid
] )
4046 old_pid
= pp_clean
[i
];
4050 ValidateDVBMeta( p_demux
, p_es
->i_pid
);
4052 if( !old_pid
&& p_sys
->pid
[p_es
->i_pid
].b_valid
)
4054 msg_Warn( p_demux
, "pmt error: pid=%d already defined",
4059 for( p_dr
= p_es
->p_first_descriptor
; p_dr
!= NULL
;
4060 p_dr
= p_dr
->p_next
)
4062 msg_Dbg( p_demux
, " * es pid=%d type=%d dr->i_tag=0x%x",
4063 p_es
->i_pid
, p_es
->i_type
, p_dr
->i_tag
);
4066 PIDInit( pid
, false, pmt
->psi
);
4067 PIDFillFormat( pid
, p_es
->i_type
);
4068 pid
->i_owner_number
= prg
->i_number
;
4069 pid
->i_pid
= p_es
->i_pid
;
4070 pid
->b_seen
= p_sys
->pid
[p_es
->i_pid
].b_seen
;
4072 if( p_es
->i_type
== 0x10 || p_es
->i_type
== 0x11 ||
4073 p_es
->i_type
== 0x12 || p_es
->i_type
== 0x0f )
4075 PMTSetupEsISO14496( p_demux
, pid
, prg
, p_es
);
4077 else if( p_es
->i_type
== 0x06 )
4079 PMTSetupEs0x06( p_demux
, pid
, p_es
);
4081 else if( p_es
->i_type
== 0xEA )
4083 PMTSetupEs0xEA( p_demux
, pid
, p_es
);
4085 else if( p_es
->i_type
== 0xd1 )
4087 PMTSetupEs0xD1( p_demux
, pid
, p_es
);
4089 else if( p_es
->i_type
== 0xa0 )
4091 PMTSetupEs0xA0( p_demux
, pid
, p_es
);
4095 PMTSetupEsHDMV( p_demux
, pid
, p_es
);
4097 else if( p_es
->i_type
>= 0x80 )
4099 PMTSetupEsRegistration( p_demux
, pid
, p_es
);
4102 if( pid
->es
->fmt
.i_cat
== AUDIO_ES
||
4103 ( pid
->es
->fmt
.i_cat
== SPU_ES
&&
4104 pid
->es
->fmt
.i_codec
!= VLC_CODEC_DVBS
&&
4105 pid
->es
->fmt
.i_codec
!= VLC_CODEC_TELETEXT
) )
4107 PMTParseEsIso639( p_demux
, pid
, p_es
);
4110 pid
->es
->fmt
.i_group
= p_pmt
->i_program_number
;
4111 for( int i
= 0; i
< pid
->i_extra_es
; i
++ )
4112 pid
->extra_es
[i
]->fmt
.i_group
= p_pmt
->i_program_number
;
4114 if( pid
->es
->fmt
.i_cat
== UNKNOWN_ES
)
4116 msg_Dbg( p_demux
, " * es pid=%d type=%d *unknown*",
4117 p_es
->i_pid
, p_es
->i_type
);
4119 else if( !p_sys
->b_udp_out
)
4121 msg_Dbg( p_demux
, " * es pid=%d type=%d fcc=%4.4s",
4122 p_es
->i_pid
, p_es
->i_type
, (char*)&pid
->es
->fmt
.i_codec
);
4124 if( p_sys
->b_es_id_pid
) pid
->es
->fmt
.i_id
= p_es
->i_pid
;
4126 /* Check if we can avoid restarting the ES */
4128 pid
->es
->fmt
.i_codec
== old_pid
->es
->fmt
.i_codec
&&
4129 pid
->es
->fmt
.i_extra
== old_pid
->es
->fmt
.i_extra
&&
4130 pid
->es
->fmt
.i_extra
== 0 &&
4131 pid
->i_extra_es
== old_pid
->i_extra_es
&&
4132 ( ( !pid
->es
->fmt
.psz_language
&&
4133 !old_pid
->es
->fmt
.psz_language
) ||
4134 ( pid
->es
->fmt
.psz_language
&&
4135 old_pid
->es
->fmt
.psz_language
&&
4136 !strcmp( pid
->es
->fmt
.psz_language
,
4137 old_pid
->es
->fmt
.psz_language
) ) ) )
4139 pid
->es
->id
= old_pid
->es
->id
;
4140 old_pid
->es
->id
= NULL
;
4141 for( int i
= 0; i
< pid
->i_extra_es
; i
++ )
4143 pid
->extra_es
[i
]->id
= old_pid
->extra_es
[i
]->id
;
4144 old_pid
->extra_es
[i
]->id
= NULL
;
4151 PIDClean( p_demux
, old_pid
);
4152 TAB_REMOVE( i_clean
, pp_clean
, old_pid
);
4156 pid
->es
->id
= es_out_Add( p_demux
->out
, &pid
->es
->fmt
);
4157 for( int i
= 0; i
< pid
->i_extra_es
; i
++ )
4159 pid
->extra_es
[i
]->id
=
4160 es_out_Add( p_demux
->out
, &pid
->extra_es
[i
]->fmt
);
4162 p_sys
->i_pmt_es
+= 1 + pid
->i_extra_es
;
4166 /* Add ES to the list */
4169 PIDClean( p_demux
, old_pid
);
4170 TAB_REMOVE( i_clean
, pp_clean
, old_pid
);
4172 p_sys
->pid
[p_es
->i_pid
] = *pid
;
4174 p_dr
= PMTEsFindDescriptor( p_es
, 0x09 );
4175 if( p_dr
&& p_dr
->i_length
>= 2 )
4177 uint16_t i_sysid
= (p_dr
->p_data
[0] << 8) | p_dr
->p_data
[1];
4178 msg_Dbg( p_demux
, " * descriptor : CA (0x9) SysID 0x%x",
4182 if( ProgramIsSelected( p_demux
, prg
->i_number
) &&
4183 ( pid
->es
->id
!= NULL
|| p_sys
->b_udp_out
) )
4185 /* Set demux filter */
4186 SetPIDFilter( p_demux
, p_es
->i_pid
, true );
4190 /* Set CAM descrambling */
4191 if( !ProgramIsSelected( p_demux
, prg
->i_number
)
4192 || stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
4193 ACCESS_SET_PRIVATE_ID_CA
, p_pmt
) != VLC_SUCCESS
)
4194 dvbpsi_DeletePMT( p_pmt
);
4196 for( int i
= 0; i
< i_clean
; i
++ )
4198 if( ProgramIsSelected( p_demux
, prg
->i_number
) )
4200 SetPIDFilter( p_demux
, pp_clean
[i
]->i_pid
, false );
4203 PIDClean( p_demux
, pp_clean
[i
] );
4209 static void PATCallBack( demux_t
*p_demux
, dvbpsi_pat_t
*p_pat
)
4211 demux_sys_t
*p_sys
= p_demux
->p_sys
;
4212 dvbpsi_pat_program_t
*p_program
;
4213 ts_pid_t
*pat
= &p_sys
->pid
[0];
4215 msg_Dbg( p_demux
, "PATCallBack called" );
4217 if( ( pat
->psi
->i_pat_version
!= -1 &&
4218 ( !p_pat
->b_current_next
||
4219 p_pat
->i_version
== pat
->psi
->i_pat_version
) ) ||
4222 dvbpsi_DeletePAT( p_pat
);
4226 msg_Dbg( p_demux
, "new PAT ts_id=%d version=%d current_next=%d",
4227 p_pat
->i_ts_id
, p_pat
->i_version
, p_pat
->b_current_next
);
4230 if( p_sys
->i_pmt
> 0 )
4233 ts_pid_t
**pmt_rm
= NULL
;
4235 /* Search pmt to be deleted */
4236 for( int i
= 0; i
< p_sys
->i_pmt
; i
++ )
4238 ts_pid_t
*pmt
= p_sys
->pmt
[i
];
4239 bool b_keep
= false;
4241 for( p_program
= p_pat
->p_first_program
; p_program
!= NULL
;
4242 p_program
= p_program
->p_next
)
4244 if( p_program
->i_pid
== pmt
->i_pid
)
4246 for( int i_prg
= 0; i_prg
< pmt
->psi
->i_prg
; i_prg
++ )
4248 if( p_program
->i_number
==
4249 pmt
->psi
->prg
[i_prg
]->i_number
)
4262 TAB_APPEND( i_pmt_rm
, pmt_rm
, pmt
);
4266 /* Delete all ES attached to thoses PMT */
4267 for( int i
= 2; i
< 8192; i
++ )
4269 ts_pid_t
*pid
= &p_sys
->pid
[i
];
4271 if( !pid
->b_valid
|| pid
->psi
)
4274 for( int j
= 0; j
< i_pmt_rm
&& pid
->b_valid
; j
++ )
4276 for( int i_prg
= 0; i_prg
< pid
->p_owner
->i_prg
; i_prg
++ )
4278 /* We only remove es that aren't defined by extra pmt */
4279 if( pid
->p_owner
->prg
[i_prg
]->i_pid_pmt
!= pmt_rm
[j
]->i_pid
)
4283 SetPIDFilter( p_demux
, i
, false );
4285 PIDClean( p_demux
, pid
);
4291 /* Delete PMT pid */
4292 for( int i
= 0; i
< i_pmt_rm
; i
++ )
4294 SetPIDFilter( p_demux
, pmt_rm
[i
]->i_pid
, false );
4296 for( int i_prg
= 0; i_prg
< pmt_rm
[i
]->psi
->i_prg
; i_prg
++ )
4298 const int i_number
= pmt_rm
[i
]->psi
->prg
[i_prg
]->i_number
;
4299 es_out_Control( p_demux
->out
, ES_OUT_DEL_GROUP
, i_number
);
4302 PIDClean( p_demux
, &p_sys
->pid
[pmt_rm
[i
]->i_pid
] );
4303 TAB_REMOVE( p_sys
->i_pmt
, p_sys
->pmt
, pmt_rm
[i
] );
4309 /* now create programs */
4310 for( p_program
= p_pat
->p_first_program
; p_program
!= NULL
;
4311 p_program
= p_program
->p_next
)
4313 msg_Dbg( p_demux
, " * number=%d pid=%d", p_program
->i_number
,
4315 if( p_program
->i_number
!= 0 )
4317 ts_pid_t
*pmt
= &p_sys
->pid
[p_program
->i_pid
];
4320 ValidateDVBMeta( p_demux
, p_program
->i_pid
);
4325 for( i_prg
= 0; i_prg
< pmt
->psi
->i_prg
; i_prg
++ )
4327 if( pmt
->psi
->prg
[i_prg
]->i_number
== p_program
->i_number
)
4336 TAB_APPEND( p_sys
->i_pmt
, p_sys
->pmt
, pmt
);
4341 PIDInit( pmt
, true, pat
->psi
);
4342 pmt
->psi
->prg
[pmt
->psi
->i_prg
-1]->handle
=
4343 dvbpsi_AttachPMT( p_program
->i_number
,
4344 (dvbpsi_pmt_callback
)PMTCallBack
,
4346 pmt
->psi
->prg
[pmt
->psi
->i_prg
-1]->i_number
=
4347 p_program
->i_number
;
4348 pmt
->psi
->prg
[pmt
->psi
->i_prg
-1]->i_pid_pmt
=
4351 /* Now select PID at access level */
4352 if( ProgramIsSelected( p_demux
, p_program
->i_number
) )
4354 if( p_sys
->i_current_program
== 0 )
4355 p_sys
->i_current_program
= p_program
->i_number
;
4357 if( SetPIDFilter( p_demux
, p_program
->i_pid
, true ) )
4358 p_sys
->b_access_control
= false;
4363 pat
->psi
->i_pat_version
= p_pat
->i_version
;
4365 dvbpsi_DeletePAT( p_pat
);