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 #define TS_PACKET_SIZE_188 188
431 #define TS_PACKET_SIZE_192 192
432 #define TS_PACKET_SIZE_204 204
433 #define TS_PACKET_SIZE_MAX 204
434 #define TS_TOPFIELD_HEADER 1320
436 /*****************************************************************************
438 *****************************************************************************/
439 static int Open( vlc_object_t
*p_this
)
441 demux_t
*p_demux
= (demux_t
*)p_this
;
444 const uint8_t *p_peek
;
445 int i_sync
, i_peek
, i
;
449 const char *psz_mode
;
451 bool b_topfield
= false;
453 if( stream_Peek( p_demux
->s
, &p_peek
, TS_PACKET_SIZE_MAX
) <
454 TS_PACKET_SIZE_MAX
) return VLC_EGENERIC
;
456 if( memcmp( p_peek
, "TFrc", 4 ) == 0 )
459 msg_Dbg( p_demux
, "this is a topfield file" );
462 /* Search first sync byte */
463 for( i_sync
= 0; i_sync
< TS_PACKET_SIZE_MAX
; i_sync
++ )
465 if( p_peek
[i_sync
] == 0x47 ) break;
467 if( i_sync
>= TS_PACKET_SIZE_MAX
&& !b_topfield
)
469 if( !p_demux
->b_force
)
471 msg_Warn( p_demux
, "this does not look like a TS stream, continuing" );
476 /* Read the entire Topfield header */
477 i_peek
= TS_TOPFIELD_HEADER
;
481 /* Check next 3 sync bytes */
482 i_peek
= TS_PACKET_SIZE_MAX
* 3 + i_sync
+ 1;
485 if( ( stream_Peek( p_demux
->s
, &p_peek
, i_peek
) ) < i_peek
)
487 msg_Err( p_demux
, "cannot peek" );
490 if( p_peek
[i_sync
+ TS_PACKET_SIZE_188
] == 0x47 &&
491 p_peek
[i_sync
+ 2 * TS_PACKET_SIZE_188
] == 0x47 &&
492 p_peek
[i_sync
+ 3 * TS_PACKET_SIZE_188
] == 0x47 )
494 i_packet_size
= TS_PACKET_SIZE_188
;
496 else if( p_peek
[i_sync
+ TS_PACKET_SIZE_192
] == 0x47 &&
497 p_peek
[i_sync
+ 2 * TS_PACKET_SIZE_192
] == 0x47 &&
498 p_peek
[i_sync
+ 3 * TS_PACKET_SIZE_192
] == 0x47 )
500 i_packet_size
= TS_PACKET_SIZE_192
;
502 else if( p_peek
[i_sync
+ TS_PACKET_SIZE_204
] == 0x47 &&
503 p_peek
[i_sync
+ 2 * TS_PACKET_SIZE_204
] == 0x47 &&
504 p_peek
[i_sync
+ 3 * TS_PACKET_SIZE_204
] == 0x47 )
506 i_packet_size
= TS_PACKET_SIZE_204
;
508 else if( p_demux
->b_force
)
510 i_packet_size
= TS_PACKET_SIZE_188
;
512 else if( b_topfield
)
514 i_packet_size
= TS_PACKET_SIZE_188
;
516 /* I used the TF5000PVR 2004 Firmware .doc header documentation,
517 * http://www.i-topfield.com/data/product/firmware/Structure%20of%20Recorded%20File%20in%20TF5000PVR%20(Feb%2021%202004).doc
518 * but after the filename the offsets seem to be incorrect. - DJ */
519 int i_duration
, i_name
;
520 char *psz_name
= malloc(25);
521 char *psz_event_name
;
522 char *psz_event_text
= malloc(130);
523 char *psz_ext_text
= malloc(1025);
525 // 2 bytes version Uimsbf (4,5)
526 // 2 bytes reserved (6,7)
527 // 2 bytes duration in minutes Uimsbf (8,9(
528 i_duration
= (int) (p_peek
[8] << 8) | p_peek
[9];
529 msg_Dbg( p_demux
, "Topfield recording length: +/- %d minutes", i_duration
);
530 // 2 bytes service number in channel list (10, 11)
531 // 2 bytes service type Bslbf 0=TV 1=Radio Bslb (12, 13)
532 // 4 bytes of reserved + tuner info (14,15,16,17)
533 // 2 bytes of Service ID Bslbf (18,19)
534 // 2 bytes of PMT PID Uimsbf (20,21)
535 // 2 bytes of PCR PID Uimsbf (22,23)
536 // 2 bytes of Video PID Uimsbf (24,25)
537 // 2 bytes of Audio PID Uimsbf (26,27)
538 // 24 bytes filename Bslbf
539 memcpy( psz_name
, &p_peek
[28], 24 );
541 msg_Dbg( p_demux
, "recordingname=%s", psz_name
);
542 // 1 byte of sat index Uimsbf (52)
543 // 3 bytes (1 bit of polarity Bslbf +23 bits reserved)
544 // 4 bytes of freq. Uimsbf (56,57,58,59)
545 // 2 bytes of symbol rate Uimsbf (60,61)
546 // 2 bytes of TS stream ID Uimsbf (62,63)
549 // 2 bytes duration Uimsbf (70,71)
550 //i_duration = (int) (p_peek[70] << 8) | p_peek[71];
551 //msg_Dbg( p_demux, "Topfield 2nd duration field: +/- %d minutes", i_duration);
552 // 4 bytes EventID Uimsbf (72-75)
553 // 8 bytes of Start and End time info (76-83)
554 // 1 byte reserved (84)
555 // 1 byte event name length Uimsbf (89)
556 i_name
= (int)(p_peek
[89]&~0x81);
557 msg_Dbg( p_demux
, "event name length = %d", i_name
);
558 psz_event_name
= malloc( i_name
+1 );
559 // 1 byte parental rating (90)
560 // 129 bytes of event text
561 memcpy( psz_event_name
, &p_peek
[91], i_name
);
562 psz_event_name
[i_name
] = '\0';
563 memcpy( psz_event_text
, &p_peek
[91+i_name
], 129-i_name
);
564 psz_event_text
[129-i_name
] = '\0';
565 msg_Dbg( p_demux
, "event name=%s", psz_event_name
);
566 msg_Dbg( p_demux
, "event text=%s", psz_event_text
);
567 // 12 bytes reserved (220)
569 // 2 bytes Event Text Length Uimsbf
570 // 4 bytes EventID Uimsbf
571 // FIXME We just have 613 bytes. not enough for this entire text
572 // 1024 bytes Extended Event Text Bslbf
573 memcpy( psz_ext_text
, p_peek
+372, 1024 );
574 psz_ext_text
[1024] = '\0';
575 msg_Dbg( p_demux
, "extended event text=%s", psz_ext_text
);
576 // 52 bytes reserved Bslbf
581 msg_Warn( p_demux
, "TS module discarded (lost sync)" );
585 p_demux
->p_sys
= p_sys
= malloc( sizeof( demux_sys_t
) );
588 memset( p_sys
, 0, sizeof( demux_sys_t
) );
589 p_sys
->i_packet_size
= i_packet_size
;
590 vlc_mutex_init( &p_sys
->csa_lock
);
592 /* Fill dump mode fields */
594 p_sys
->buffer
= NULL
;
595 p_sys
->p_file
= NULL
;
596 p_sys
->b_file_out
= false;
597 p_sys
->psz_file
= var_CreateGetString( p_demux
, "ts-dump-file" );
598 if( *p_sys
->psz_file
!= '\0' )
600 p_sys
->b_file_out
= true;
602 b_append
= var_CreateGetBool( p_demux
, "ts-dump-append" );
608 if( !strcmp( p_sys
->psz_file
, "-" ) )
610 msg_Info( p_demux
, "dumping raw stream to standard output" );
611 p_sys
->p_file
= stdout
;
613 else if( ( p_sys
->p_file
= vlc_fopen( p_sys
->psz_file
, psz_mode
) ) == NULL
)
615 msg_Err( p_demux
, "cannot create `%s' for writing", p_sys
->psz_file
);
616 p_sys
->b_file_out
= false;
619 if( p_sys
->b_file_out
)
621 /* Determine how many packets to read. */
622 int bufsize
= var_CreateGetInteger( p_demux
, "ts-dump-size" );
623 p_sys
->i_ts_read
= (int) (bufsize
/ p_sys
->i_packet_size
);
624 if( p_sys
->i_ts_read
<= 0 )
626 p_sys
->i_ts_read
= 1500 / p_sys
->i_packet_size
;
628 p_sys
->buffer
= xmalloc( p_sys
->i_packet_size
* p_sys
->i_ts_read
);
629 msg_Info( p_demux
, "%s raw stream to file `%s' reading packets %d",
630 b_append
? "appending" : "dumping", p_sys
->psz_file
,
635 /* Fill p_demux field */
636 if( p_sys
->b_file_out
)
637 p_demux
->pf_demux
= DemuxFile
;
639 p_demux
->pf_demux
= Demux
;
640 p_demux
->pf_control
= Control
;
642 /* Init p_sys field */
643 p_sys
->b_dvb_meta
= true;
644 p_sys
->b_access_control
= true;
645 p_sys
->i_current_program
= 0;
646 p_sys
->programs_list
.i_count
= 0;
647 p_sys
->programs_list
.p_values
= NULL
;
648 p_sys
->i_tdt_delta
= 0;
649 p_sys
->i_dvb_start
= 0;
650 p_sys
->i_dvb_length
= 0;
652 p_sys
->b_broken_charset
= false;
654 for( i
= 0; i
< 8192; i
++ )
656 ts_pid_t
*pid
= &p_sys
->pid
[i
];
660 pid
->b_valid
= false;
662 /* PID 8191 is padding */
663 p_sys
->pid
[8191].b_seen
= true;
664 p_sys
->i_packet_size
= i_packet_size
;
665 p_sys
->b_udp_out
= false;
667 p_sys
->i_ts_read
= 50;
669 p_sys
->b_start_record
= false;
671 /* Init PAT handler */
672 pat
= &p_sys
->pid
[0];
673 PIDInit( pat
, true, NULL
);
674 pat
->psi
->handle
= dvbpsi_AttachPAT( (dvbpsi_pat_callback
)PATCallBack
,
677 if( p_sys
->b_dvb_meta
)
679 ts_pid_t
*sdt
= &p_sys
->pid
[0x11];
680 ts_pid_t
*eit
= &p_sys
->pid
[0x12];
682 PIDInit( sdt
, true, NULL
);
684 dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t
)PSINewTableCallBack
,
686 PIDInit( eit
, true, NULL
);
688 dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t
)PSINewTableCallBack
,
691 ts_pid_t
*tdt
= &p_sys
->pid
[0x14];
692 PIDInit( tdt
, true, NULL
);
694 dvbpsi_AttachDemux( (dvbpsi_demux_new_cb_t
)PSINewTableCallBack
,
697 if( p_sys
->b_access_control
)
699 if( stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
700 ACCESS_SET_PRIVATE_ID_STATE
, 0x11, true ) ||
702 stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
703 ACCESS_SET_PRIVATE_ID_STATE
, 0x14, true ) ||
705 stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
706 ACCESS_SET_PRIVATE_ID_STATE
, 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
);
870 if( p_sys
->b_access_control
&& pid
->i_pid
> 0 )
873 stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
874 ACCESS_SET_PRIVATE_ID_STATE
, pid
->i_pid
,
879 vlc_mutex_lock( &p_sys
->csa_lock
);
882 var_DelCallback( p_demux
, "ts-csa-ck", ChangeKeyCallback
, NULL
);
883 var_DelCallback( p_demux
, "ts-csa2-ck", ChangeKeyCallback
, NULL
);
884 csa_Delete( p_sys
->csa
);
886 vlc_mutex_unlock( &p_sys
->csa_lock
);
888 TAB_CLEAN( p_sys
->i_pmt
, p_sys
->pmt
);
890 free( p_sys
->programs_list
.p_values
);
892 /* If in dump mode, then close the file */
893 if( p_sys
->b_file_out
)
895 msg_Info( p_demux
,"closing %s (%"PRId64
" KiB dumped)",
896 p_sys
->psz_file
, p_sys
->i_write
/ 1024 );
898 if( p_sys
->p_file
!= stdout
)
900 fclose( p_sys
->p_file
);
903 /* When streaming, close the port */
906 net_Close( p_sys
->fd
);
909 free( p_sys
->buffer
);
910 free( p_sys
->psz_file
);
912 vlc_mutex_destroy( &p_sys
->csa_lock
);
916 /*****************************************************************************
917 * ChangeKeyCallback: called when changing the odd encryption key on the fly.
918 *****************************************************************************/
919 static int ChangeKeyCallback( vlc_object_t
*p_this
, char const *psz_cmd
,
920 vlc_value_t oldval
, vlc_value_t newval
,
923 VLC_UNUSED(psz_cmd
); VLC_UNUSED(oldval
);
924 demux_t
*p_demux
= (demux_t
*)p_this
;
925 demux_sys_t
*p_sys
= p_demux
->p_sys
;
926 int i_tmp
= (intptr_t)p_data
;
928 vlc_mutex_lock( &p_sys
->csa_lock
);
930 i_tmp
= csa_SetCW( p_this
, p_sys
->csa
, newval
.psz_string
, true );
932 i_tmp
= csa_SetCW( p_this
, p_sys
->csa
, newval
.psz_string
, false );
934 vlc_mutex_unlock( &p_sys
->csa_lock
);
938 /*****************************************************************************
940 *****************************************************************************/
941 static int DemuxFile( demux_t
*p_demux
)
943 demux_sys_t
*p_sys
= p_demux
->p_sys
;
944 const int i_bufsize
= p_sys
->i_packet_size
* p_sys
->i_ts_read
;
945 uint8_t *p_buffer
= p_sys
->buffer
; /* Put first on sync byte */
946 const int i_data
= stream_Read( p_demux
->s
, p_sys
->buffer
, i_bufsize
);
948 if( i_data
<= 0 && i_data
< p_sys
->i_packet_size
)
950 msg_Dbg( p_demux
, "error reading malformed packets" );
954 /* Test continuity counter */
955 for( int i_pos
= 0; i_pos
< i_data
; )
957 if( p_sys
->buffer
[i_pos
] != 0x47 )
959 msg_Warn( p_demux
, "lost sync" );
960 while( vlc_object_alive (p_demux
) && (i_pos
< i_data
) )
963 if( p_sys
->buffer
[i_pos
] == 0x47 )
966 if( vlc_object_alive (p_demux
) )
967 msg_Warn( p_demux
, "sync found" );
970 /* continuous when (one of this):
972 * diff == 0 and payload == 0
973 * diff == 0 and duplicate packet (playload != 0) <- should we
976 const int i_cc
= p_buffer
[i_pos
+3]&0x0f;
977 const bool b_payload
= p_buffer
[i_pos
+3]&0x10;
978 const bool b_adaptation
= p_buffer
[i_pos
+3]&0x20;
981 ts_pid_t
*p_pid
= &p_sys
->pid
[ ((p_buffer
[i_pos
+1]&0x1f)<<8)|p_buffer
[i_pos
+2] ];
983 /* Detect discontinuity indicator in adaptation field */
984 if( b_adaptation
&& p_buffer
[i_pos
+ 4] > 0 )
986 if( p_buffer
[i_pos
+5]&0x80 )
987 msg_Warn( p_demux
, "discontinuity indicator (pid=%d) ", p_pid
->i_pid
);
988 if( p_buffer
[i_pos
+5]&0x40 )
989 msg_Warn( p_demux
, "random access indicator (pid=%d) ", p_pid
->i_pid
);
992 const int i_diff
= ( i_cc
- p_pid
->i_cc
)&0x0f;
993 if( b_payload
&& i_diff
== 1 )
995 p_pid
->i_cc
= ( p_pid
->i_cc
+ 1 ) & 0xf;
999 if( p_pid
->i_cc
== 0xff )
1001 msg_Warn( p_demux
, "first packet for pid=%d cc=0x%x",
1002 p_pid
->i_pid
, i_cc
);
1005 else if( i_diff
!= 0 )
1007 /* FIXME what to do when discontinuity_indicator is set ? */
1008 msg_Warn( p_demux
, "transport error detected 0x%x instead of 0x%x",
1009 i_cc
, ( p_pid
->i_cc
+ 1 )&0x0f );
1012 /* Mark transport error in the TS packet. */
1013 p_buffer
[i_pos
+1] |= 0x80;
1017 /* Test if user wants to decrypt it first */
1020 vlc_mutex_lock( &p_sys
->csa_lock
);
1021 csa_Decrypt( p_demux
->p_sys
->csa
, &p_buffer
[i_pos
], p_demux
->p_sys
->i_csa_pkt_size
);
1022 vlc_mutex_unlock( &p_sys
->csa_lock
);
1025 i_pos
+= p_sys
->i_packet_size
;
1029 const int i_write
= fwrite( p_sys
->buffer
, 1, i_data
, p_sys
->p_file
);
1032 msg_Err( p_demux
, "failed to write data" );
1036 p_sys
->i_write
+= i_write
;
1040 /*****************************************************************************
1042 *****************************************************************************/
1043 static int Demux( demux_t
*p_demux
)
1045 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1046 bool b_wait_es
= p_sys
->i_pmt_es
<= 0;
1048 /* We read at most 100 TS packet or until a frame is completed */
1049 for( int i_pkt
= 0; i_pkt
< p_sys
->i_ts_read
; i_pkt
++ )
1051 bool b_frame
= false;
1054 /* Get a new TS packet */
1055 if( !( p_pkt
= stream_Block( p_demux
->s
, p_sys
->i_packet_size
) ) )
1057 msg_Dbg( p_demux
, "eof ?" );
1061 /* Check sync byte and re-sync if needed */
1062 if( p_pkt
->p_buffer
[0] != 0x47 )
1064 msg_Warn( p_demux
, "lost synchro" );
1065 block_Release( p_pkt
);
1067 while( vlc_object_alive (p_demux
) )
1069 const uint8_t *p_peek
;
1070 int i_peek
, i_skip
= 0;
1072 i_peek
= stream_Peek( p_demux
->s
, &p_peek
,
1073 p_sys
->i_packet_size
* 10 );
1074 if( i_peek
< p_sys
->i_packet_size
+ 1 )
1076 msg_Dbg( p_demux
, "eof ?" );
1080 while( i_skip
< i_peek
- p_sys
->i_packet_size
)
1082 if( p_peek
[i_skip
] == 0x47 &&
1083 p_peek
[i_skip
+ p_sys
->i_packet_size
] == 0x47 )
1090 msg_Dbg( p_demux
, "skipping %d bytes of garbage", i_skip
);
1091 stream_Read( p_demux
->s
, NULL
, i_skip
);
1093 if( i_skip
< i_peek
- p_sys
->i_packet_size
)
1099 if( !( p_pkt
= stream_Block( p_demux
->s
, p_sys
->i_packet_size
) ) )
1101 msg_Dbg( p_demux
, "eof ?" );
1106 if( p_sys
->b_start_record
)
1108 /* Enable recording once synchronized */
1109 stream_Control( p_demux
->s
, STREAM_SET_RECORD_STATE
, true, "ts" );
1110 p_sys
->b_start_record
= false;
1113 if( p_sys
->b_udp_out
)
1115 memcpy( &p_sys
->buffer
[i_pkt
* p_sys
->i_packet_size
],
1116 p_pkt
->p_buffer
, p_sys
->i_packet_size
);
1119 /* Parse the TS packet */
1120 ts_pid_t
*p_pid
= &p_sys
->pid
[PIDGet( p_pkt
)];
1122 if( p_pid
->b_valid
)
1126 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 ) ) )
1128 dvbpsi_PushPacket( p_pid
->psi
->handle
, p_pkt
->p_buffer
);
1132 for( int i_prg
= 0; i_prg
< p_pid
->psi
->i_prg
; i_prg
++ )
1134 dvbpsi_PushPacket( p_pid
->psi
->prg
[i_prg
]->handle
,
1138 block_Release( p_pkt
);
1140 else if( !p_sys
->b_udp_out
)
1142 b_frame
= GatherPES( p_demux
, p_pid
, p_pkt
);
1146 PCRHandle( p_demux
, p_pid
, p_pkt
);
1147 block_Release( p_pkt
);
1152 if( !p_pid
->b_seen
)
1154 msg_Dbg( p_demux
, "pid[%d] unknown", p_pid
->i_pid
);
1156 /* We have to handle PCR if present */
1157 PCRHandle( p_demux
, p_pid
, p_pkt
);
1158 block_Release( p_pkt
);
1160 p_pid
->b_seen
= true;
1162 if( b_frame
|| ( b_wait_es
&& p_sys
->i_pmt_es
> 0 ) )
1166 if( p_sys
->b_udp_out
)
1168 /* Send the complete block */
1169 net_Write( p_demux
, p_sys
->fd
, NULL
, p_sys
->buffer
,
1170 p_sys
->i_ts_read
* p_sys
->i_packet_size
);
1176 /*****************************************************************************
1178 *****************************************************************************/
1179 static int DVBEventInformation( demux_t
*p_demux
, int64_t *pi_time
, int64_t *pi_length
)
1181 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1187 if( p_sys
->i_dvb_length
> 0 )
1190 const int64_t t
= mdate() + p_sys
->i_tdt_delta
;
1192 const int64_t t
= CLOCK_FREQ
* time ( NULL
);
1195 if( p_sys
->i_dvb_start
<= t
&& t
< p_sys
->i_dvb_start
+ p_sys
->i_dvb_length
)
1198 *pi_length
= p_sys
->i_dvb_length
;
1200 *pi_time
= t
- p_sys
->i_dvb_start
;
1204 return VLC_EGENERIC
;
1207 static int Control( demux_t
*p_demux
, int i_query
, va_list args
)
1209 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1211 bool b_bool
, *pb_bool
;
1216 if( p_sys
->b_file_out
)
1217 return demux_vaControlHelper( p_demux
->s
, 0, -1, 0, 1, i_query
, args
);
1221 case DEMUX_GET_POSITION
:
1222 pf
= (double*) va_arg( args
, double* );
1223 i64
= stream_Size( p_demux
->s
);
1226 double f_current
= stream_Tell( p_demux
->s
);
1227 *pf
= f_current
/ (double)i64
;
1231 int64_t i_time
, i_length
;
1232 if( !DVBEventInformation( p_demux
, &i_time
, &i_length
) && i_length
> 0 )
1233 *pf
= (double)i_time
/(double)i_length
;
1238 case DEMUX_SET_POSITION
:
1239 f
= (double) va_arg( args
, double );
1240 i64
= stream_Size( p_demux
->s
);
1242 if( stream_Seek( p_demux
->s
, (int64_t)(i64
* f
) ) )
1243 return VLC_EGENERIC
;
1248 case DEMUX_GET_TIME
:
1249 pi64
= (int64_t*)va_arg( args
, int64_t * );
1250 if( p_sys
->i_time
< 0 )
1253 return VLC_EGENERIC
;
1255 *pi64
= p_sys
->i_time
;
1258 case DEMUX_GET_LENGTH
:
1259 pi64
= (int64_t*)va_arg( args
, int64_t * );
1260 if( p_sys
->i_mux_rate
> 0 )
1262 *pi64
= INT64_C(1000000) * ( stream_Size( p_demux
->s
) / 50 ) /
1267 return VLC_EGENERIC
;
1269 case DEMUX_GET_TIME
:
1270 pi64
= (int64_t*)va_arg( args
, int64_t * );
1271 if( DVBEventInformation( p_demux
, pi64
, NULL
) )
1275 case DEMUX_GET_LENGTH
:
1276 pi64
= (int64_t*)va_arg( args
, int64_t * );
1277 if( DVBEventInformation( p_demux
, NULL
, pi64
) )
1281 case DEMUX_SET_GROUP
:
1283 uint16_t i_vpid
= 0, i_apid1
= 0, i_apid2
= 0, i_apid3
= 0;
1284 ts_prg_psi_t
*p_prg
= NULL
;
1287 i_int
= (int)va_arg( args
, int );
1288 p_list
= (vlc_list_t
*)va_arg( args
, vlc_list_t
* );
1289 msg_Dbg( p_demux
, "DEMUX_SET_GROUP %d %p", i_int
, p_list
);
1291 if( p_sys
->b_access_control
&& i_int
> 0 && i_int
!= p_sys
->i_current_program
)
1295 /* Search pmt to be unselected */
1296 for( int i
= 0; i
< p_sys
->i_pmt
; i
++ )
1298 ts_pid_t
*pmt
= p_sys
->pmt
[i
];
1300 for( int i_prg
= 0; i_prg
< pmt
->psi
->i_prg
; i_prg
++ )
1302 if( pmt
->psi
->prg
[i_prg
]->i_number
== p_sys
->i_current_program
)
1304 i_pmt_pid
= p_sys
->pmt
[i
]->i_pid
;
1308 if( i_pmt_pid
> 0 ) break;
1313 stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
1314 ACCESS_SET_PRIVATE_ID_STATE
, i_pmt_pid
,
1317 for( int i
= 2; i
< 8192; i
++ )
1319 ts_pid_t
*pid
= &p_sys
->pid
[i
];
1321 if( !pid
->b_valid
|| pid
->psi
)
1324 for( int i_prg
= 0; i_prg
< pid
->p_owner
->i_prg
; i_prg
++ )
1326 if( pid
->p_owner
->prg
[i_prg
]->i_pid_pmt
== i_pmt_pid
&& pid
->es
->id
)
1328 /* We only remove es that aren't defined by extra pmt */
1329 stream_Control( p_demux
->s
,
1330 STREAM_CONTROL_ACCESS
,
1331 ACCESS_SET_PRIVATE_ID_STATE
,
1339 /* select new program */
1340 p_sys
->i_current_program
= i_int
;
1342 for( int i
= 0; i
< p_sys
->i_pmt
; i
++ )
1344 ts_pid_t
*pmt
= p_sys
->pmt
[i
];
1346 for( int i_prg
= 0; i_prg
< pmt
->psi
->i_prg
; i_prg
++ )
1348 if( pmt
->psi
->prg
[i_prg
]->i_number
== i_int
)
1350 i_pmt_pid
= p_sys
->pmt
[i
]->i_pid
;
1351 p_prg
= p_sys
->pmt
[i
]->psi
->prg
[i_prg
];
1360 stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
1361 ACCESS_SET_PRIVATE_ID_STATE
, i_pmt_pid
,
1363 stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
1364 ACCESS_SET_PRIVATE_ID_STATE
, p_prg
->i_pid_pcr
,
1367 for( int i
= 2; i
< 8192; i
++ )
1369 ts_pid_t
*pid
= &p_sys
->pid
[i
];
1371 if( !pid
->b_valid
|| pid
->psi
)
1374 for( int i_prg
= 0; i_prg
< pid
->p_owner
->i_prg
; i_prg
++ )
1376 if( pid
->p_owner
->prg
[i_prg
]->i_pid_pmt
== i_pmt_pid
&& pid
->es
->id
)
1378 if ( pid
->es
->fmt
.i_cat
== VIDEO_ES
&& !i_vpid
)
1380 if ( pid
->es
->fmt
.i_cat
== AUDIO_ES
&& !i_apid1
)
1382 else if ( pid
->es
->fmt
.i_cat
== AUDIO_ES
&& !i_apid2
)
1384 else if ( pid
->es
->fmt
.i_cat
== AUDIO_ES
&& !i_apid3
)
1387 stream_Control( p_demux
->s
,
1388 STREAM_CONTROL_ACCESS
,
1389 ACCESS_SET_PRIVATE_ID_STATE
,
1399 p_sys
->i_current_program
= -1;
1400 p_sys
->programs_list
.i_count
= 0;
1403 vlc_list_t
*p_dst
= &p_sys
->programs_list
;
1404 free( p_dst
->p_values
);
1406 p_dst
->p_values
= calloc( p_list
->i_count
,
1407 sizeof(*p_dst
->p_values
) );
1408 if( p_dst
->p_values
)
1410 p_dst
->i_count
= p_list
->i_count
;
1411 for( int i
= 0; i
< p_list
->i_count
; i
++ )
1412 p_dst
->p_values
[i
] = p_list
->p_values
[i
];
1419 case DEMUX_CAN_RECORD
:
1420 pb_bool
= (bool*)va_arg( args
, bool * );
1424 case DEMUX_SET_RECORD_STATE
:
1425 b_bool
= (bool)va_arg( args
, int );
1428 stream_Control( p_demux
->s
, STREAM_SET_RECORD_STATE
, false );
1429 p_sys
->b_start_record
= b_bool
;
1433 case DEMUX_SET_TIME
:
1435 return VLC_EGENERIC
;
1439 /*****************************************************************************
1441 *****************************************************************************/
1442 static int UserPmt( demux_t
*p_demux
, const char *psz_fmt
)
1444 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1445 char *psz_dup
= strdup( psz_fmt
);
1446 char *psz
= psz_dup
;
1454 i_pid
= strtol( psz
, &psz
, 0 );
1455 if( i_pid
< 2 || i_pid
>= 8192 )
1458 /* Parse optional program number */
1461 i_number
= strtol( &psz
[1], &psz
, 0 );
1464 ts_pid_t
*pmt
= &p_sys
->pid
[i_pid
];
1467 msg_Dbg( p_demux
, "user pmt specified (pid=%d,number=%d)", i_pid
, i_number
);
1468 PIDInit( pmt
, true, NULL
);
1471 prg
= malloc( sizeof( ts_prg_psi_t
) );
1475 memset( prg
, 0, sizeof( ts_prg_psi_t
) );
1476 prg
->i_pid_pcr
= -1;
1477 prg
->i_pid_pmt
= -1;
1478 prg
->i_version
= -1;
1479 prg
->i_number
= i_number
!= 0 ? i_number
: TS_USER_PMT_NUMBER
;
1480 prg
->handle
= dvbpsi_AttachPMT( i_number
!= TS_USER_PMT_NUMBER
? i_number
: 1, (dvbpsi_pmt_callback
)PMTCallBack
, p_demux
);
1481 TAB_APPEND( pmt
->psi
->i_prg
, pmt
->psi
->prg
, prg
);
1483 psz
= strchr( psz
, '=' );
1486 while( psz
&& *psz
)
1488 char *psz_next
= strchr( psz
, ',' );
1494 i_pid
= strtol( psz
, &psz
, 0 );
1495 if( *psz
!= ':' || i_pid
< 2 || i_pid
>= 8192 )
1498 char *psz_opt
= &psz
[1];
1499 if( !strcmp( psz_opt
, "pcr" ) )
1501 prg
->i_pid_pcr
= i_pid
;
1503 else if( !p_sys
->pid
[i_pid
].b_valid
)
1505 ts_pid_t
*pid
= &p_sys
->pid
[i_pid
];
1507 char *psz_arg
= strchr( psz_opt
, '=' );
1511 PIDInit( pid
, false, pmt
->psi
);
1512 if( prg
->i_pid_pcr
<= 0 )
1513 prg
->i_pid_pcr
= i_pid
;
1515 if( psz_arg
&& strlen( psz_arg
) == 4 )
1517 const vlc_fourcc_t i_codec
= VLC_FOURCC( psz_arg
[0], psz_arg
[1],
1518 psz_arg
[2], psz_arg
[3] );
1519 int i_cat
= UNKNOWN_ES
;
1520 es_format_t
*fmt
= &pid
->es
->fmt
;
1522 if( !strcmp( psz_opt
, "video" ) )
1524 else if( !strcmp( psz_opt
, "audio" ) )
1526 else if( !strcmp( psz_opt
, "spu" ) )
1529 es_format_Init( fmt
, i_cat
, i_codec
);
1530 fmt
->b_packetized
= false;
1534 const int i_stream_type
= strtol( psz_opt
, NULL
, 0 );
1535 PIDFillFormat( pid
, i_stream_type
);
1537 pid
->es
->fmt
.i_group
= i_number
;
1538 if( p_sys
->b_es_id_pid
)
1539 pid
->es
->fmt
.i_id
= i_pid
;
1541 if( pid
->es
->fmt
.i_cat
!= UNKNOWN_ES
)
1543 msg_Dbg( p_demux
, " * es pid=%d fcc=%4.4s", i_pid
,
1544 (char*)&pid
->es
->fmt
.i_codec
);
1545 pid
->es
->id
= es_out_Add( p_demux
->out
,
1555 p_sys
->b_user_pmt
= true;
1556 TAB_APPEND( p_sys
->i_pmt
, p_sys
->pmt
, pmt
);
1562 return VLC_EGENERIC
;
1565 static void PIDInit( ts_pid_t
*pid
, bool b_psi
, ts_psi_t
*p_owner
)
1567 bool b_old_valid
= pid
->b_valid
;
1569 pid
->b_valid
= true;
1571 pid
->b_scrambled
= false;
1572 pid
->p_owner
= p_owner
;
1573 pid
->i_owner_number
= 0;
1575 TAB_INIT( pid
->i_extra_es
, pid
->extra_es
);
1583 pid
->psi
= xmalloc( sizeof( ts_psi_t
) );
1586 pid
->psi
->handle
= NULL
;
1587 TAB_INIT( pid
->psi
->i_prg
, pid
->psi
->prg
);
1592 pid
->psi
->i_pat_version
= -1;
1593 pid
->psi
->i_sdt_version
= -1;
1596 ts_prg_psi_t
*prg
= malloc( sizeof( ts_prg_psi_t
) );
1600 prg
->i_version
= -1;
1602 prg
->i_pid_pcr
= -1;
1603 prg
->i_pid_pmt
= -1;
1607 TAB_APPEND( pid
->psi
->i_prg
, pid
->psi
->prg
, prg
);
1614 pid
->es
= malloc( sizeof( ts_es_t
) );
1617 es_format_Init( &pid
->es
->fmt
, UNKNOWN_ES
, 0 );
1619 pid
->es
->p_pes
= NULL
;
1620 pid
->es
->i_pes_size
= 0;
1621 pid
->es
->i_pes_gathered
= 0;
1622 pid
->es
->pp_last
= &pid
->es
->p_pes
;
1623 pid
->es
->p_mpeg4desc
= NULL
;
1624 pid
->es
->b_gather
= false;
1629 static void PIDClean( demux_t
*p_demux
, ts_pid_t
*pid
)
1631 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1632 es_out_t
*out
= p_demux
->out
;
1636 if( pid
->psi
->handle
)
1637 dvbpsi_DetachPMT( pid
->psi
->handle
);
1638 for( int i
= 0; i
< pid
->psi
->i_prg
; i
++ )
1640 if( pid
->psi
->prg
[i
]->iod
)
1641 IODFree( pid
->psi
->prg
[i
]->iod
);
1642 if( pid
->psi
->prg
[i
]->handle
)
1643 dvbpsi_DetachPMT( pid
->psi
->prg
[i
]->handle
);
1644 free( pid
->psi
->prg
[i
] );
1646 free( pid
->psi
->prg
);
1653 es_out_Del( out
, pid
->es
->id
);
1657 if( pid
->es
->p_pes
)
1658 block_ChainRelease( pid
->es
->p_pes
);
1660 es_format_Clean( &pid
->es
->fmt
);
1664 for( int i
= 0; i
< pid
->i_extra_es
; i
++ )
1666 if( pid
->extra_es
[i
]->id
)
1668 es_out_Del( out
, pid
->extra_es
[i
]->id
);
1672 if( pid
->extra_es
[i
]->p_pes
)
1673 block_ChainRelease( pid
->extra_es
[i
]->p_pes
);
1675 es_format_Clean( &pid
->extra_es
[i
]->fmt
);
1677 free( pid
->extra_es
[i
] );
1679 if( pid
->i_extra_es
)
1680 free( pid
->extra_es
);
1683 pid
->b_valid
= false;
1686 /****************************************************************************
1688 ****************************************************************************/
1689 static void ParsePES( demux_t
*p_demux
, ts_pid_t
*pid
)
1691 block_t
*p_pes
= pid
->es
->p_pes
;
1693 unsigned i_pes_size
= 0;
1694 unsigned i_skip
= 0;
1697 mtime_t i_length
= 0;
1699 /* remove the pes from pid */
1700 pid
->es
->p_pes
= NULL
;
1701 pid
->es
->i_pes_size
= 0;
1702 pid
->es
->i_pes_gathered
= 0;
1703 pid
->es
->pp_last
= &pid
->es
->p_pes
;
1705 /* FIXME find real max size */
1706 /* const int i_max = */ block_ChainExtract( p_pes
, header
, 34 );
1708 if( header
[0] != 0 || header
[1] != 0 || header
[2] != 1 )
1710 if( !p_demux
->p_sys
->b_silent
)
1711 msg_Warn( p_demux
, "invalid header [0x%x:%x:%x:%x] (pid: %d)",
1712 header
[0], header
[1],header
[2],header
[3], pid
->i_pid
);
1713 block_ChainRelease( p_pes
);
1717 /* TODO check size */
1720 case 0xBC: /* Program stream map */
1721 case 0xBE: /* Padding */
1722 case 0xBF: /* Private stream 2 */
1723 case 0xF0: /* ECM */
1724 case 0xF1: /* EMM */
1725 case 0xFF: /* Program stream directory */
1726 case 0xF2: /* DSMCC stream */
1727 case 0xF8: /* ITU-T H.222.1 type E stream */
1731 if( ( header
[6]&0xC0 ) == 0x80 )
1734 i_skip
= header
[8] + 9;
1736 if( header
[7]&0x80 ) /* has pts */
1738 i_pts
= ((mtime_t
)(header
[ 9]&0x0e ) << 29)|
1739 (mtime_t
)(header
[10] << 22)|
1740 ((mtime_t
)(header
[11]&0xfe) << 14)|
1741 (mtime_t
)(header
[12] << 7)|
1742 (mtime_t
)(header
[13] >> 1);
1744 if( header
[7]&0x40 ) /* has dts */
1746 i_dts
= ((mtime_t
)(header
[14]&0x0e ) << 29)|
1747 (mtime_t
)(header
[15] << 22)|
1748 ((mtime_t
)(header
[16]&0xfe) << 14)|
1749 (mtime_t
)(header
[17] << 7)|
1750 (mtime_t
)(header
[18] >> 1);
1757 while( i_skip
< 23 && header
[i_skip
] == 0xff )
1763 msg_Err( p_demux
, "too much MPEG-1 stuffing" );
1764 block_ChainRelease( p_pes
);
1767 if( ( header
[i_skip
] & 0xC0 ) == 0x40 )
1772 if( header
[i_skip
]&0x20 )
1774 i_pts
= ((mtime_t
)(header
[i_skip
]&0x0e ) << 29)|
1775 (mtime_t
)(header
[i_skip
+1] << 22)|
1776 ((mtime_t
)(header
[i_skip
+2]&0xfe) << 14)|
1777 (mtime_t
)(header
[i_skip
+3] << 7)|
1778 (mtime_t
)(header
[i_skip
+4] >> 1);
1780 if( header
[i_skip
]&0x10 ) /* has dts */
1782 i_dts
= ((mtime_t
)(header
[i_skip
+5]&0x0e ) << 29)|
1783 (mtime_t
)(header
[i_skip
+6] << 22)|
1784 ((mtime_t
)(header
[i_skip
+7]&0xfe) << 14)|
1785 (mtime_t
)(header
[i_skip
+8] << 7)|
1786 (mtime_t
)(header
[i_skip
+9] >> 1);
1802 if( pid
->es
->fmt
.i_codec
== VLC_FOURCC( 'a', '5', '2', 'b' ) ||
1803 pid
->es
->fmt
.i_codec
== VLC_FOURCC( 'd', 't', 's', 'b' ) )
1807 else if( pid
->es
->fmt
.i_codec
== VLC_FOURCC( 'l', 'p', 'c', 'b' ) ||
1808 pid
->es
->fmt
.i_codec
== VLC_FOURCC( 's', 'p', 'u', 'b' ) ||
1809 pid
->es
->fmt
.i_codec
== VLC_FOURCC( 's', 'd', 'd', 'b' ) )
1813 else if( pid
->es
->fmt
.i_codec
== VLC_CODEC_SUBT
&&
1814 pid
->es
->p_mpeg4desc
)
1816 decoder_config_descriptor_t
*dcd
= &pid
->es
->p_mpeg4desc
->dec_descr
;
1818 if( dcd
->i_decoder_specific_info_len
> 2 &&
1819 dcd
->p_decoder_specific_info
[0] == 0x10 &&
1820 ( dcd
->p_decoder_specific_info
[1]&0x10 ) )
1822 /* display length */
1823 if( p_pes
->i_buffer
+ 2 <= i_skip
)
1824 i_length
= GetWBE( &p_pes
->p_buffer
[i_skip
] );
1828 if( p_pes
->i_buffer
+ 2 <= i_skip
)
1829 i_pes_size
= GetWBE( &p_pes
->p_buffer
[i_skip
] );
1833 #ifdef ZVBI_COMPILED
1834 else if( pid
->es
->fmt
.i_codec
== VLC_CODEC_TELETEXT
)
1835 i_skip
= 0; /*hack for zvbi support */
1838 while( p_pes
&& i_skip
> 0 )
1840 if( p_pes
->i_buffer
<= i_skip
)
1842 block_t
*p_next
= p_pes
->p_next
;
1844 i_skip
-= p_pes
->i_buffer
;
1845 block_Release( p_pes
);
1850 p_pes
->i_buffer
-= i_skip
;
1851 p_pes
->p_buffer
+= i_skip
;
1856 /* ISO/IEC 13818-1 2.7.5: if no pts and no dts, then dts == pts */
1857 if( i_pts
>= 0 && i_dts
< 0 )
1866 p_pes
->i_dts
= VLC_TS_0
+ i_dts
* 100 / 9;
1869 p_pes
->i_pts
= VLC_TS_0
+ i_pts
* 100 / 9;
1871 p_pes
->i_length
= i_length
* 100 / 9;
1873 p_block
= block_ChainGather( p_pes
);
1874 if( pid
->es
->fmt
.i_codec
== VLC_CODEC_SUBT
)
1876 if( i_pes_size
> 0 && p_block
->i_buffer
> i_pes_size
)
1878 p_block
->i_buffer
= i_pes_size
;
1881 p_block
= block_Realloc( p_block
, 0, p_block
->i_buffer
+ 1 );
1882 p_block
->p_buffer
[p_block
->i_buffer
-1] = '\0';
1885 for( i
= 0; i
< pid
->i_extra_es
; i
++ )
1887 es_out_Send( p_demux
->out
, pid
->extra_es
[i
]->id
,
1888 block_Duplicate( p_block
) );
1891 es_out_Send( p_demux
->out
, pid
->es
->id
, p_block
);
1895 msg_Warn( p_demux
, "empty pes" );
1899 static void PCRHandle( demux_t
*p_demux
, ts_pid_t
*pid
, block_t
*p_bk
)
1901 demux_sys_t
*p_sys
= p_demux
->p_sys
;
1902 const uint8_t *p
= p_bk
->p_buffer
;
1904 if( p_sys
->i_pmt_es
<= 0 )
1907 if( ( p
[3]&0x20 ) && /* adaptation */
1911 /* PCR is 33 bits */
1912 const mtime_t i_pcr
= ( (mtime_t
)p
[6] << 25 ) |
1913 ( (mtime_t
)p
[7] << 17 ) |
1914 ( (mtime_t
)p
[8] << 9 ) |
1915 ( (mtime_t
)p
[9] << 1 ) |
1916 ( (mtime_t
)p
[10] >> 7 );
1918 /* Search program and set the PCR */
1919 for( int i
= 0; i
< p_sys
->i_pmt
; i
++ )
1921 for( int i_prg
= 0; i_prg
< p_sys
->pmt
[i
]->psi
->i_prg
; i_prg
++ )
1923 if( pid
->i_pid
== p_sys
->pmt
[i
]->psi
->prg
[i_prg
]->i_pid_pcr
)
1925 es_out_Control( p_demux
->out
, ES_OUT_SET_GROUP_PCR
,
1926 (int)p_sys
->pmt
[i
]->psi
->prg
[i_prg
]->i_number
,
1927 (int64_t)(VLC_TS_0
+ i_pcr
* 100 / 9) );
1934 static bool GatherPES( demux_t
*p_demux
, ts_pid_t
*pid
, block_t
*p_bk
)
1936 const uint8_t *p
= p_bk
->p_buffer
;
1937 const bool b_unit_start
= p
[1]&0x40;
1938 const bool b_scrambled
= p
[3]&0x80;
1939 const bool b_adaptation
= p
[3]&0x20;
1940 const bool b_payload
= p
[3]&0x10;
1941 const int i_cc
= p
[3]&0x0f; /* continuity counter */
1942 bool b_discontinuity
= false; /* discontinuity */
1944 /* transport_scrambling_control is ignored */
1949 msg_Dbg( p_demux
, "pid=%d unit_start=%d adaptation=%d payload=%d "
1950 "cc=0x%x", pid
->i_pid
, b_unit_start
, b_adaptation
,
1954 /* For now, ignore additional error correction
1955 * TODO: handle Reed-Solomon 204,188 error correction */
1956 p_bk
->i_buffer
= TS_PACKET_SIZE_188
;
1960 msg_Dbg( p_demux
, "transport_error_indicator set (pid=%d)",
1962 if( pid
->es
->p_pes
) //&& pid->es->fmt.i_cat == VIDEO_ES )
1963 pid
->es
->p_pes
->i_flags
|= BLOCK_FLAG_CORRUPTED
;
1966 if( p_demux
->p_sys
->csa
)
1968 vlc_mutex_lock( &p_demux
->p_sys
->csa_lock
);
1969 csa_Decrypt( p_demux
->p_sys
->csa
, p_bk
->p_buffer
, p_demux
->p_sys
->i_csa_pkt_size
);
1970 vlc_mutex_unlock( &p_demux
->p_sys
->csa_lock
);
1975 /* We don't have any adaptation_field, so payload starts
1976 * immediately after the 4 byte TS header */
1981 /* p[4] is adaptation_field_length minus one */
1985 /* discontinuity indicator found in stream */
1986 b_discontinuity
= (p
[5]&0x80) ? true : false;
1987 if( b_discontinuity
&& pid
->es
->p_pes
)
1989 msg_Warn( p_demux
, "discontinuity indicator (pid=%d) ",
1991 /* pid->es->p_pes->i_flags |= BLOCK_FLAG_DISCONTINUITY; */
1995 msg_Dbg( p_demux
, "random access indicator (pid=%d) ", pid
->i_pid
);
2000 /* Test continuity counter */
2001 /* continuous when (one of this):
2003 * diff == 0 and payload == 0
2004 * diff == 0 and duplicate packet (playload != 0) <- should we
2005 * test the content ?
2007 const int i_diff
= ( i_cc
- pid
->i_cc
)&0x0f;
2008 if( b_payload
&& i_diff
== 1 )
2010 pid
->i_cc
= ( pid
->i_cc
+ 1 ) & 0xf;
2014 if( pid
->i_cc
== 0xff )
2016 msg_Warn( p_demux
, "first packet for pid=%d cc=0x%x",
2020 else if( i_diff
!= 0 && !b_discontinuity
)
2022 msg_Warn( p_demux
, "discontinuity received 0x%x instead of 0x%x (pid=%d)",
2023 i_cc
, ( pid
->i_cc
+ 1 )&0x0f, pid
->i_pid
);
2026 if( pid
->es
->p_pes
&& pid
->es
->fmt
.i_cat
!= VIDEO_ES
)
2028 /* Small video artifacts are usually better than
2029 * dropping full frames */
2030 pid
->es
->p_pes
->i_flags
|= BLOCK_FLAG_CORRUPTED
;
2035 PCRHandle( p_demux
, pid
, p_bk
);
2037 if( i_skip
>= 188 || pid
->es
->id
== NULL
|| p_demux
->p_sys
->b_udp_out
)
2039 block_Release( p_bk
);
2044 if( !pid
->b_scrambled
!= !b_scrambled
)
2046 msg_Warn( p_demux
, "scrambled state changed on pid %d (%d->%d)",
2047 pid
->i_pid
, pid
->b_scrambled
, b_scrambled
);
2049 pid
->b_scrambled
= b_scrambled
;
2051 for( int i
= 0; i
< pid
->i_extra_es
; i
++ )
2053 es_out_Control( p_demux
->out
, ES_OUT_SET_ES_SCRAMBLED_STATE
,
2054 pid
->extra_es
[i
]->id
, b_scrambled
);
2056 es_out_Control( p_demux
->out
, ES_OUT_SET_ES_SCRAMBLED_STATE
,
2057 pid
->es
->id
, b_scrambled
);
2060 /* We have to gather it */
2061 p_bk
->p_buffer
+= i_skip
;
2062 p_bk
->i_buffer
-= i_skip
;
2066 if( pid
->es
->p_pes
)
2068 ParsePES( p_demux
, pid
);
2072 block_ChainLastAppend( &pid
->es
->pp_last
, p_bk
);
2073 if( p_bk
->i_buffer
> 6 )
2075 pid
->es
->i_pes_size
= GetWBE( &p_bk
->p_buffer
[4] );
2076 if( pid
->es
->i_pes_size
> 0 )
2078 pid
->es
->i_pes_size
+= 6;
2081 pid
->es
->i_pes_gathered
+= p_bk
->i_buffer
;
2082 if( pid
->es
->i_pes_size
> 0 &&
2083 pid
->es
->i_pes_gathered
>= pid
->es
->i_pes_size
)
2085 ParsePES( p_demux
, pid
);
2091 if( pid
->es
->p_pes
== NULL
)
2093 /* msg_Dbg( p_demux, "broken packet" ); */
2094 block_Release( p_bk
);
2098 block_ChainLastAppend( &pid
->es
->pp_last
, p_bk
);
2099 pid
->es
->i_pes_gathered
+= p_bk
->i_buffer
;
2100 if( pid
->es
->i_pes_size
> 0 &&
2101 pid
->es
->i_pes_gathered
>= pid
->es
->i_pes_size
)
2103 ParsePES( p_demux
, pid
);
2112 static int PIDFillFormat( ts_pid_t
*pid
, int i_stream_type
)
2114 es_format_t
*fmt
= &pid
->es
->fmt
;
2116 switch( i_stream_type
)
2118 case 0x01: /* MPEG-1 video */
2119 case 0x02: /* MPEG-2 video */
2120 case 0x80: /* MPEG-2 MOTO video */
2121 es_format_Init( fmt
, VIDEO_ES
, VLC_CODEC_MPGV
);
2123 case 0x03: /* MPEG-1 audio */
2124 case 0x04: /* MPEG-2 audio */
2125 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_MPGA
);
2127 case 0x11: /* MPEG4 (audio) LATM */
2128 case 0x0f: /* ISO/IEC 13818-7 Audio with ADTS transport syntax */
2129 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_MP4A
);
2131 case 0x10: /* MPEG4 (video) */
2132 es_format_Init( fmt
, VIDEO_ES
, VLC_CODEC_MP4V
);
2133 pid
->es
->b_gather
= true;
2135 case 0x1B: /* H264 <- check transport syntax/needed descriptor */
2136 es_format_Init( fmt
, VIDEO_ES
, VLC_CODEC_H264
);
2139 case 0x81: /* A52 (audio) */
2140 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_A52
);
2142 case 0x82: /* DVD_SPU (sub) */
2143 es_format_Init( fmt
, SPU_ES
, VLC_CODEC_SPU
);
2145 case 0x83: /* LPCM (audio) */
2146 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_DVD_LPCM
);
2148 case 0x84: /* SDDS (audio) */
2149 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_SDDS
);
2151 case 0x85: /* DTS (audio) */
2152 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_DTS
);
2154 case 0x87: /* E-AC3 */
2155 es_format_Init( fmt
, AUDIO_ES
, VLC_CODEC_EAC3
);
2158 case 0x91: /* A52 vls (audio) */
2159 es_format_Init( fmt
, AUDIO_ES
, VLC_FOURCC( 'a', '5', '2', 'b' ) );
2161 case 0x92: /* DVD_SPU vls (sub) */
2162 es_format_Init( fmt
, SPU_ES
, VLC_FOURCC( 's', 'p', 'u', 'b' ) );
2165 case 0x94: /* SDDS (audio) */
2166 es_format_Init( fmt
, AUDIO_ES
, VLC_FOURCC( 's', 'd', 'd', 'b' ) );
2169 case 0xa0: /* MSCODEC vlc (video) (fixed later) */
2170 es_format_Init( fmt
, UNKNOWN_ES
, 0 );
2171 pid
->es
->b_gather
= true;
2174 case 0x06: /* PES_PRIVATE (fixed later) */
2175 case 0x12: /* MPEG-4 generic (sub/scene/...) (fixed later) */
2176 case 0xEA: /* Privately managed ES (VC-1) (fixed later */
2178 es_format_Init( fmt
, UNKNOWN_ES
, 0 );
2182 /* PES packets usually contain truncated frames */
2183 fmt
->b_packetized
= false;
2185 return fmt
->i_cat
== UNKNOWN_ES
? VLC_EGENERIC
: VLC_SUCCESS
;
2188 /*****************************************************************************
2189 * MP4 specific functions (IOD parser)
2190 *****************************************************************************/
2191 static int IODDescriptorLength( int *pi_data
, uint8_t **pp_data
)
2194 unsigned int i_len
= 0;
2200 i_len
= ( i_len
<< 7 ) + ( i_b
&0x7f );
2202 } while( i_b
&0x80 );
2207 static int IODGetByte( int *pi_data
, uint8_t **pp_data
)
2211 const int i_b
= **pp_data
;
2219 static int IODGetWord( int *pi_data
, uint8_t **pp_data
)
2221 const int i1
= IODGetByte( pi_data
, pp_data
);
2222 const int i2
= IODGetByte( pi_data
, pp_data
);
2223 return( ( i1
<< 8 ) | i2
);
2226 static int IODGet3Bytes( int *pi_data
, uint8_t **pp_data
)
2228 const int i1
= IODGetByte( pi_data
, pp_data
);
2229 const int i2
= IODGetByte( pi_data
, pp_data
);
2230 const int i3
= IODGetByte( pi_data
, pp_data
);
2232 return( ( i1
<< 16 ) | ( i2
<< 8) | i3
);
2235 static uint32_t IODGetDWord( int *pi_data
, uint8_t **pp_data
)
2237 const uint32_t i1
= IODGetWord( pi_data
, pp_data
);
2238 const uint32_t i2
= IODGetWord( pi_data
, pp_data
);
2239 return( ( i1
<< 16 ) | i2
);
2242 static char* IODGetURL( int *pi_data
, uint8_t **pp_data
)
2247 i_url_len
= IODGetByte( pi_data
, pp_data
);
2248 url
= malloc( i_url_len
+ 1 );
2249 if( !url
) return NULL
;
2250 for( i
= 0; i
< i_url_len
; i
++ )
2252 url
[i
] = IODGetByte( pi_data
, pp_data
);
2254 url
[i_url_len
] = '\0';
2258 static iod_descriptor_t
*IODNew( int i_data
, uint8_t *p_data
)
2260 iod_descriptor_t
*p_iod
;
2263 uint8_t i_flags
, i_iod_tag
, byte1
, byte2
, byte3
;
2267 p_iod
= malloc( sizeof( iod_descriptor_t
) );
2268 if( !p_iod
) return NULL
;
2269 memset( p_iod
, 0, sizeof( iod_descriptor_t
) );
2272 fprintf( stderr
, "\n************ IOD ************" );
2274 for( i
= 0; i
< 255; i
++ )
2276 p_iod
->es_descr
[i
].b_ok
= 0;
2285 byte1
= IODGetByte( &i_data
, &p_data
);
2286 byte2
= IODGetByte( &i_data
, &p_data
);
2287 byte3
= IODGetByte( &i_data
, &p_data
);
2288 if( byte2
== 0x02 ) //old vlc's buggy implementation of the IOD_descriptor
2290 p_iod
->i_iod_label_scope
= 0x11;
2291 p_iod
->i_iod_label
= byte1
;
2294 else //correct implementation of the IOD_descriptor
2296 p_iod
->i_iod_label_scope
= byte1
;
2297 p_iod
->i_iod_label
= byte2
;
2301 fprintf( stderr
, "\n* iod_label:%d", p_iod
->i_iod_label
);
2302 fprintf( stderr
, "\n* ===========" );
2303 fprintf( stderr
, "\n* tag:0x%x", i_iod_tag
);
2305 if( i_iod_tag
!= 0x02 )
2308 fprintf( stderr
, "\n ERR: tag %02x != 0x02", i_iod_tag
);
2313 i_iod_length
= IODDescriptorLength( &i_data
, &p_data
);
2315 fprintf( stderr
, "\n* length:%d", i_iod_length
);
2317 if( i_iod_length
> i_data
)
2319 i_iod_length
= i_data
;
2322 p_iod
->i_od_id
= ( IODGetByte( &i_data
, &p_data
) << 2 );
2323 i_flags
= IODGetByte( &i_data
, &p_data
);
2324 p_iod
->i_od_id
|= i_flags
>> 6;
2325 b_url
= ( i_flags
>> 5 )&0x01;
2327 fprintf( stderr
, "\n* od_id:%d", p_iod
->i_od_id
);
2328 fprintf( stderr
, "\n* url flag:%d", b_url
);
2329 fprintf( stderr
, "\n* includeInlineProfileLevel flag:%d", ( i_flags
>> 4 )&0x01 );
2333 p_iod
->psz_url
= IODGetURL( &i_data
, &p_data
);
2335 fprintf( stderr
, "\n* url string:%s", p_iod
->psz_url
);
2336 fprintf( stderr
, "\n*****************************\n" );
2342 p_iod
->psz_url
= NULL
;
2345 p_iod
->i_ODProfileLevelIndication
= IODGetByte( &i_data
, &p_data
);
2346 p_iod
->i_sceneProfileLevelIndication
= IODGetByte( &i_data
, &p_data
);
2347 p_iod
->i_audioProfileLevelIndication
= IODGetByte( &i_data
, &p_data
);
2348 p_iod
->i_visualProfileLevelIndication
= IODGetByte( &i_data
, &p_data
);
2349 p_iod
->i_graphicsProfileLevelIndication
= IODGetByte( &i_data
, &p_data
);
2351 fprintf( stderr
, "\n* ODProfileLevelIndication:%d", p_iod
->i_ODProfileLevelIndication
);
2352 fprintf( stderr
, "\n* sceneProfileLevelIndication:%d", p_iod
->i_sceneProfileLevelIndication
);
2353 fprintf( stderr
, "\n* audioProfileLevelIndication:%d", p_iod
->i_audioProfileLevelIndication
);
2354 fprintf( stderr
, "\n* visualProfileLevelIndication:%d", p_iod
->i_visualProfileLevelIndication
);
2355 fprintf( stderr
, "\n* graphicsProfileLevelIndication:%d", p_iod
->i_graphicsProfileLevelIndication
);
2358 while( i_data
> 0 && i_es_index
< 255)
2360 int i_tag
, i_length
;
2362 uint8_t *p_data_sav
;
2364 i_tag
= IODGetByte( &i_data
, &p_data
);
2365 i_length
= IODDescriptorLength( &i_data
, &p_data
);
2367 i_data_sav
= i_data
;
2368 p_data_sav
= p_data
;
2376 #define es_descr p_iod->es_descr[i_es_index]
2377 int i_decoderConfigDescr_length
;
2379 fprintf( stderr
, "\n* - ES_Descriptor length:%d", i_length
);
2383 es_descr
.i_es_id
= IODGetWord( &i_data
, &p_data
);
2384 i_flags
= IODGetByte( &i_data
, &p_data
);
2385 es_descr
.b_streamDependenceFlag
= ( i_flags
>> 7 )&0x01;
2386 b_url
= ( i_flags
>> 6 )&0x01;
2387 es_descr
.b_OCRStreamFlag
= ( i_flags
>> 5 )&0x01;
2388 es_descr
.i_streamPriority
= i_flags
& 0x1f;
2390 fprintf( stderr
, "\n* * streamDependenceFlag:%d", es_descr
.b_streamDependenceFlag
);
2391 fprintf( stderr
, "\n* * OCRStreamFlag:%d", es_descr
.b_OCRStreamFlag
);
2392 fprintf( stderr
, "\n* * streamPriority:%d", es_descr
.i_streamPriority
);
2394 if( es_descr
.b_streamDependenceFlag
)
2396 es_descr
.i_dependOn_es_id
= IODGetWord( &i_data
, &p_data
);
2398 fprintf( stderr
, "\n* * dependOn_es_id:%d", es_descr
.i_dependOn_es_id
);
2404 es_descr
.psz_url
= IODGetURL( &i_data
, &p_data
);
2406 fprintf( stderr
, "\n* url string:%s", es_descr
.psz_url
);
2411 es_descr
.psz_url
= NULL
;
2414 if( es_descr
.b_OCRStreamFlag
)
2416 es_descr
.i_OCR_es_id
= IODGetWord( &i_data
, &p_data
);
2418 fprintf( stderr
, "\n* * OCR_es_id:%d", es_descr
.i_OCR_es_id
);
2422 if( IODGetByte( &i_data
, &p_data
) != 0x04 )
2425 fprintf( stderr
, "\n* ERR missing DecoderConfigDescr" );
2430 i_decoderConfigDescr_length
= IODDescriptorLength( &i_data
, &p_data
);
2432 fprintf( stderr
, "\n* - DecoderConfigDesc length:%d", i_decoderConfigDescr_length
);
2434 #define dec_descr es_descr.dec_descr
2435 dec_descr
.i_objectTypeIndication
= IODGetByte( &i_data
, &p_data
);
2436 i_flags
= IODGetByte( &i_data
, &p_data
);
2437 dec_descr
.i_streamType
= i_flags
>> 2;
2438 dec_descr
.b_upStream
= ( i_flags
>> 1 )&0x01;
2439 dec_descr
.i_bufferSizeDB
= IODGet3Bytes( &i_data
, &p_data
);
2440 dec_descr
.i_maxBitrate
= IODGetDWord( &i_data
, &p_data
);
2441 dec_descr
.i_avgBitrate
= IODGetDWord( &i_data
, &p_data
);
2443 fprintf( stderr
, "\n* * objectTypeIndication:0x%x", dec_descr
.i_objectTypeIndication
);
2444 fprintf( stderr
, "\n* * streamType:0x%x", dec_descr
.i_streamType
);
2445 fprintf( stderr
, "\n* * upStream:%d", dec_descr
.b_upStream
);
2446 fprintf( stderr
, "\n* * bufferSizeDB:%d", dec_descr
.i_bufferSizeDB
);
2447 fprintf( stderr
, "\n* * maxBitrate:%d", dec_descr
.i_maxBitrate
);
2448 fprintf( stderr
, "\n* * avgBitrate:%d", dec_descr
.i_avgBitrate
);
2450 if( i_decoderConfigDescr_length
> 13 && IODGetByte( &i_data
, &p_data
) == 0x05 )
2453 dec_descr
.i_decoder_specific_info_len
=
2454 IODDescriptorLength( &i_data
, &p_data
);
2455 if( dec_descr
.i_decoder_specific_info_len
> 0 )
2457 dec_descr
.p_decoder_specific_info
=
2458 malloc( dec_descr
.i_decoder_specific_info_len
);
2460 for( i
= 0; i
< dec_descr
.i_decoder_specific_info_len
; i
++ )
2462 dec_descr
.p_decoder_specific_info
[i
] = IODGetByte( &i_data
, &p_data
);
2467 dec_descr
.i_decoder_specific_info_len
= 0;
2468 dec_descr
.p_decoder_specific_info
= NULL
;
2472 #define sl_descr es_descr.sl_descr
2474 int i_SLConfigDescr_length
;
2477 if( IODGetByte( &i_data
, &p_data
) != 0x06 )
2480 fprintf( stderr
, "\n* ERR missing SLConfigDescr" );
2485 i_SLConfigDescr_length
= IODDescriptorLength( &i_data
, &p_data
);
2487 fprintf( stderr
, "\n* - SLConfigDescr length:%d", i_SLConfigDescr_length
);
2489 i_predefined
= IODGetByte( &i_data
, &p_data
);
2491 fprintf( stderr
, "\n* * i_predefined:0x%x", i_predefined
);
2493 switch( i_predefined
)
2497 sl_descr
.b_useAccessUnitStartFlag
= 0;
2498 sl_descr
.b_useAccessUnitEndFlag
= 0;
2499 sl_descr
.b_useRandomAccessPointFlag
= 0;
2500 //sl_descr.b_useRandomAccessUnitsOnlyFlag = 0;
2501 sl_descr
.b_usePaddingFlag
= 0;
2502 sl_descr
.b_useTimeStampsFlags
= 0;
2503 sl_descr
.b_useIdleFlag
= 0;
2504 sl_descr
.b_durationFlag
= 0; // FIXME FIXME
2505 sl_descr
.i_timeStampResolution
= 1000;
2506 sl_descr
.i_OCRResolution
= 0; // FIXME FIXME
2507 sl_descr
.i_timeStampLength
= 32;
2508 sl_descr
.i_OCRLength
= 0; // FIXME FIXME
2509 sl_descr
.i_AU_Length
= 0;
2510 sl_descr
.i_instantBitrateLength
= 0; // FIXME FIXME
2511 sl_descr
.i_degradationPriorityLength
= 0;
2512 sl_descr
.i_AU_seqNumLength
= 0;
2513 sl_descr
.i_packetSeqNumLength
= 0;
2514 if( sl_descr
.b_durationFlag
)
2516 sl_descr
.i_timeScale
= 0; // FIXME FIXME
2517 sl_descr
.i_accessUnitDuration
= 0; // FIXME FIXME
2518 sl_descr
.i_compositionUnitDuration
= 0; // FIXME FIXME
2520 if( !sl_descr
.b_useTimeStampsFlags
)
2522 sl_descr
.i_startDecodingTimeStamp
= 0; // FIXME FIXME
2523 sl_descr
.i_startCompositionTimeStamp
= 0; // FIXME FIXME
2529 fprintf( stderr
, "\n* ERR unsupported SLConfigDescr predefined" );
2540 fprintf( stderr
, "\n* - OD tag:0x%x length:%d (Unsupported)", i_tag
, i_length
);
2545 p_data
= p_data_sav
+ i_length
;
2546 i_data
= i_data_sav
- i_length
;
2550 fprintf( stderr
, "\n*****************************\n" );
2555 static void IODFree( iod_descriptor_t
*p_iod
)
2559 if( p_iod
->psz_url
)
2561 free( p_iod
->psz_url
);
2562 p_iod
->psz_url
= NULL
;
2567 for( i
= 0; i
< 255; i
++ )
2569 #define es_descr p_iod->es_descr[i]
2572 if( es_descr
.psz_url
)
2574 free( es_descr
.psz_url
);
2575 es_descr
.psz_url
= NULL
;
2579 free( es_descr
.dec_descr
.p_decoder_specific_info
);
2580 es_descr
.dec_descr
.p_decoder_specific_info
= NULL
;
2581 es_descr
.dec_descr
.i_decoder_specific_info_len
= 0;
2590 /****************************************************************************
2591 ****************************************************************************
2592 ** libdvbpsi callbacks
2593 ****************************************************************************
2594 ****************************************************************************/
2595 static bool ProgramIsSelected( demux_t
*p_demux
, uint16_t i_pgrm
)
2597 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2599 if( !p_sys
->b_access_control
)
2601 if( ( p_sys
->i_current_program
== -1 && p_sys
->programs_list
.i_count
== 0 ) ||
2602 p_sys
->i_current_program
== 0 )
2604 if( p_sys
->i_current_program
== i_pgrm
)
2607 if( p_sys
->programs_list
.i_count
!= 0 )
2609 for( int i
= 0; i
< p_sys
->programs_list
.i_count
; i
++ )
2611 if( i_pgrm
== p_sys
->programs_list
.p_values
[i
].i_int
)
2618 static void ValidateDVBMeta( demux_t
*p_demux
, int i_pid
)
2620 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2622 if( !p_sys
->b_dvb_meta
|| ( i_pid
!= 0x11 && i_pid
!= 0x12 && i_pid
!= 0x14 ) )
2625 msg_Warn( p_demux
, "Switching to non DVB mode" );
2627 /* This doesn't look like a DVB stream so don't try
2628 * parsing the SDT/EDT/TDT */
2630 for( int i
= 0x11; i
<= 0x14; i
++ )
2632 if( i
== 0x13 ) continue;
2633 ts_pid_t
*p_pid
= &p_sys
->pid
[i
];
2636 dvbpsi_DetachDemux( p_pid
->psi
->handle
);
2639 p_pid
->b_valid
= false;
2641 if( p_sys
->b_access_control
)
2642 stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
2643 ACCESS_SET_PRIVATE_ID_STATE
, i
, false );
2646 p_sys
->b_dvb_meta
= false;
2650 #ifdef TS_USE_DVB_SI
2651 /* FIXME same than dvbsi_to_utf8 from dvb access */
2652 static char *EITConvertToUTF8( const unsigned char *psz_instring
,
2656 const char *psz_encoding
;
2657 char *psz_outstring
;
2658 char psz_encbuf
[sizeof( "ISO_8859-123" )];
2659 size_t i_in
, i_out
, offset
= 1;
2660 vlc_iconv_t iconv_handle
;
2662 if( i_length
< 1 ) return NULL
;
2663 if( psz_instring
[0] >= 0x20 )
2665 /* According to ETSI EN 300 468 Annex A, this should be ISO6937,
2666 * but some broadcasters use different charset... */
2668 psz_encoding
= "ISO_8859-1";
2670 psz_encoding
= "ISO_6937";
2674 else switch( psz_instring
[0] )
2677 psz_encoding
= "ISO_8859-5";
2680 psz_encoding
= "ISO_8859-6";
2683 psz_encoding
= "ISO_8859-7";
2686 psz_encoding
= "ISO_8859-8";
2689 psz_encoding
= "ISO_8859-9";
2692 psz_encoding
= "ISO_8859-10";
2695 psz_encoding
= "ISO_8859-11";
2698 psz_encoding
= "ISO_8859-12";
2701 psz_encoding
= "ISO_8859-13";
2704 psz_encoding
= "ISO_8859-14";
2707 psz_encoding
= "ISO_8859-15";
2710 #warning Is Latin-10 (psz_instring[2] == 16) really illegal?
2711 if( i_length
< 3 || psz_instring
[1] != 0x00 || psz_instring
[2] > 15
2712 || psz_instring
[2] == 0 )
2714 psz_encoding
= "UTF-8";
2719 sprintf( psz_encbuf
, "ISO_8859-%u", psz_instring
[2] );
2720 psz_encoding
= psz_encbuf
;
2725 #warning Is there a BOM or do we use a fixed endianess?
2726 psz_encoding
= "UTF-16";
2729 psz_encoding
= "KSC5601-1987";
2732 psz_encoding
= "GB2312"; /* GB-2312-1980 */
2735 psz_encoding
= "BIG-5";
2738 psz_encoding
= "UTF-8";
2742 psz_encoding
= "UTF-8";
2746 i_in
= i_length
- offset
;
2747 i_out
= i_in
* 6 + 1;
2749 psz_outstring
= malloc( i_out
);
2750 if( !psz_outstring
)
2755 iconv_handle
= vlc_iconv_open( "UTF-8", psz_encoding
);
2756 if( iconv_handle
== (vlc_iconv_t
)(-1) )
2758 /* Invalid character set (e.g. ISO_8859-12) */
2759 memcpy( psz_outstring
, &psz_instring
[offset
], i_in
);
2760 psz_outstring
[i_in
] = '\0';
2761 EnsureUTF8( psz_outstring
);
2765 const char *psz_in
= (const char *)&psz_instring
[offset
];
2766 char *psz_out
= psz_outstring
;
2768 while( vlc_iconv( iconv_handle
, &psz_in
, &i_in
,
2769 &psz_out
, &i_out
) == (size_t)(-1) )
2771 /* skip naughty byte. This may fail terribly for multibyte stuff,
2772 * but what can we do anyway? */
2775 vlc_iconv( iconv_handle
, NULL
, NULL
, NULL
, NULL
); /* reset */
2777 vlc_iconv_close( iconv_handle
);
2781 /* Convert EIT-coded CR/LFs */
2782 unsigned char *pbuf
= (unsigned char *)psz_outstring
;
2783 for( ; pbuf
< (unsigned char *)psz_out
; pbuf
++)
2785 if( pbuf
[0] == 0xc2 && pbuf
[1] == 0x8a )
2794 return psz_outstring
;
2797 static void SDTCallBack( demux_t
*p_demux
, dvbpsi_sdt_t
*p_sdt
)
2799 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2800 ts_pid_t
*sdt
= &p_sys
->pid
[0x11];
2801 dvbpsi_sdt_service_t
*p_srv
;
2803 msg_Dbg( p_demux
, "SDTCallBack called" );
2805 if( sdt
->psi
->i_sdt_version
!= -1 &&
2806 ( !p_sdt
->b_current_next
||
2807 p_sdt
->i_version
== sdt
->psi
->i_sdt_version
) )
2809 dvbpsi_DeleteSDT( p_sdt
);
2813 msg_Dbg( p_demux
, "new SDT ts_id=%d version=%d current_next=%d "
2815 p_sdt
->i_ts_id
, p_sdt
->i_version
, p_sdt
->b_current_next
,
2816 p_sdt
->i_network_id
);
2818 p_sys
->b_broken_charset
= false;
2820 for( p_srv
= p_sdt
->p_first_service
; p_srv
; p_srv
= p_srv
->p_next
)
2823 dvbpsi_descriptor_t
*p_dr
;
2825 const char *psz_type
= NULL
;
2826 const char *psz_status
= NULL
;
2828 msg_Dbg( p_demux
, " * service id=%d eit schedule=%d present=%d "
2829 "running=%d free_ca=%d",
2830 p_srv
->i_service_id
, p_srv
->b_eit_schedule
,
2831 p_srv
->b_eit_present
, p_srv
->i_running_status
,
2834 if( p_sys
->i_current_program
!= -1 && p_sys
->i_current_program
!= p_srv
->i_service_id
)
2837 p_meta
= vlc_meta_New();
2838 for( p_dr
= p_srv
->p_first_descriptor
; p_dr
; p_dr
= p_dr
->p_next
)
2840 if( p_dr
->i_tag
== 0x48 )
2842 static const char *ppsz_type
[17] = {
2844 "Digital television service",
2845 "Digital radio sound service",
2847 "NVOD reference service",
2848 "NVOD time-shifted service",
2851 "SECAM coded signal",
2854 "NTSC coded signal",
2855 "Data broadcast service",
2856 "Reserved for Common Interface Usage",
2857 "RCS Map (see EN 301 790 [35])",
2858 "RCS FLS (see EN 301 790 [35])",
2861 dvbpsi_service_dr_t
*pD
= dvbpsi_DecodeServiceDr( p_dr
);
2865 /* Workarounds for broadcasters with broken EPG */
2867 if( p_sdt
->i_network_id
== 133 )
2868 p_sys
->b_broken_charset
= true; /* SKY DE & BetaDigital use ISO8859-1 */
2870 /* List of providers using ISO8859-1 */
2871 static const char ppsz_broken_providers
[][8] = {
2872 "CSAT", /* CanalSat FR */
2873 "GR1", /* France televisions */
2875 "MR5", /* France 2/M6 HD */
2878 for( int i
= 0; *ppsz_broken_providers
[i
]; i
++ )
2880 const size_t i_length
= strlen(ppsz_broken_providers
[i
]);
2881 if( pD
->i_service_provider_name_length
== i_length
&&
2882 !strncmp( pD
->i_service_provider_name
, ppsz_broken_providers
[i
], i_length
) )
2883 p_sys
->b_broken_charset
= true;
2886 /* FIXME: Digital+ ES also uses ISO8859-1 */
2888 str1
= EITConvertToUTF8(pD
->i_service_provider_name
,
2889 pD
->i_service_provider_name_length
,
2890 p_sys
->b_broken_charset
);
2891 str2
= EITConvertToUTF8(pD
->i_service_name
,
2892 pD
->i_service_name_length
,
2893 p_sys
->b_broken_charset
);
2895 msg_Dbg( p_demux
, " - type=%d provider=%s name=%s",
2896 pD
->i_service_type
, str1
, str2
);
2898 vlc_meta_SetTitle( p_meta
, str2
);
2899 vlc_meta_SetPublisher( p_meta
, str1
);
2900 if( pD
->i_service_type
>= 0x01 && pD
->i_service_type
<= 0x10 )
2901 psz_type
= ppsz_type
[pD
->i_service_type
];
2907 if( p_srv
->i_running_status
>= 0x01 && p_srv
->i_running_status
<= 0x04 )
2909 static const char *ppsz_status
[5] = {
2912 "Starts in a few seconds",
2916 psz_status
= ppsz_status
[p_srv
->i_running_status
];
2920 vlc_meta_AddExtra( p_meta
, "Type", psz_type
);
2922 vlc_meta_AddExtra( p_meta
, "Status", psz_status
);
2924 es_out_Control( p_demux
->out
, ES_OUT_SET_GROUP_META
,
2925 p_srv
->i_service_id
, p_meta
);
2926 vlc_meta_Delete( p_meta
);
2929 sdt
->psi
->i_sdt_version
= p_sdt
->i_version
;
2930 dvbpsi_DeleteSDT( p_sdt
);
2933 /* i_year: year - 1900 i_month: 0-11 i_mday: 1-31 i_hour: 0-23 i_minute: 0-59 i_second: 0-59 */
2934 static int64_t vlc_timegm( int i_year
, int i_month
, int i_mday
, int i_hour
, int i_minute
, int i_second
)
2936 static const int pn_day
[12+1] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
2941 i_month
< 0 || i_month
> 11 || i_mday
< 1 || i_mday
> 31 ||
2942 i_hour
< 0 || i_hour
> 23 || i_minute
< 0 || i_minute
> 59 || i_second
< 0 || i_second
> 59 )
2945 /* Count the number of days */
2946 i_day
= 365 * (i_year
-70) + pn_day
[i_month
] + i_mday
- 1;
2947 #define LEAP(y) ( ((y)%4) == 0 && (((y)%100) != 0 || ((y)%400) == 0) ? 1 : 0)
2948 for( i
= 70; i
< i_year
; i
++ )
2949 i_day
+= LEAP(1900+i
);
2951 i_day
+= LEAP(1900+i_year
);
2954 return ((24*i_day
+ i_hour
)*60 + i_minute
)*60 + i_second
;
2957 static void EITDecodeMjd( int i_mjd
, int *p_y
, int *p_m
, int *p_d
)
2959 const int yp
= (int)( ( (double)i_mjd
- 15078.2)/365.25 );
2960 const int mp
= (int)( ((double)i_mjd
- 14956.1 - (int)(yp
* 365.25)) / 30.6001 );
2961 const int c
= ( mp
== 14 || mp
== 15 ) ? 1 : 0;
2963 *p_y
= 1900 + yp
+ c
*1;
2964 *p_m
= mp
- 1 - c
*12;
2965 *p_d
= i_mjd
- 14956 - (int)(yp
*365.25) - (int)(mp
*30.6001);
2967 #define CVT_FROM_BCD(v) ((((v) >> 4)&0xf)*10 + ((v)&0xf))
2968 static int64_t EITConvertStartTime( uint64_t i_date
)
2970 const int i_mjd
= i_date
>> 24;
2971 const int i_hour
= CVT_FROM_BCD(i_date
>> 16);
2972 const int i_minute
= CVT_FROM_BCD(i_date
>> 8);
2973 const int i_second
= CVT_FROM_BCD(i_date
);
2978 /* if all 40 bits are 1, the start is unknown */
2979 if( i_date
== UINT64_C(0xffffffffff) )
2982 EITDecodeMjd( i_mjd
, &i_year
, &i_month
, &i_day
);
2983 return vlc_timegm( i_year
- 1900, i_month
- 1, i_day
, i_hour
, i_minute
, i_second
);
2985 static int EITConvertDuration( uint32_t i_duration
)
2987 return CVT_FROM_BCD(i_duration
>> 16) * 3600 +
2988 CVT_FROM_BCD(i_duration
>> 8 ) * 60 +
2989 CVT_FROM_BCD(i_duration
);
2994 static void TDTCallBack( demux_t
*p_demux
, dvbpsi_tot_t
*p_tdt
)
2996 demux_sys_t
*p_sys
= p_demux
->p_sys
;
2998 p_sys
->i_tdt_delta
= CLOCK_FREQ
* EITConvertStartTime( p_tdt
->i_utc_time
)
3000 dvbpsi_DeleteTOT(p_tdt
);
3005 static void EITCallBack( demux_t
*p_demux
,
3006 dvbpsi_eit_t
*p_eit
, bool b_current_following
)
3008 demux_sys_t
*p_sys
= p_demux
->p_sys
;
3009 dvbpsi_eit_event_t
*p_evt
;
3012 msg_Dbg( p_demux
, "EITCallBack called" );
3013 if( !p_eit
->b_current_next
|| ( p_sys
->i_current_program
!= -1 && p_sys
->i_current_program
!= p_eit
->i_service_id
) )
3015 dvbpsi_DeleteEIT( p_eit
);
3019 msg_Dbg( p_demux
, "new EIT service_id=%d version=%d current_next=%d "
3020 "ts_id=%d network_id=%d segment_last_section_number=%d "
3022 p_eit
->i_service_id
, p_eit
->i_version
, p_eit
->b_current_next
,
3023 p_eit
->i_ts_id
, p_eit
->i_network_id
,
3024 p_eit
->i_segment_last_section_number
, p_eit
->i_last_table_id
);
3026 p_epg
= vlc_epg_New( NULL
);
3027 for( p_evt
= p_eit
->p_first_event
; p_evt
; p_evt
= p_evt
->p_next
)
3029 dvbpsi_descriptor_t
*p_dr
;
3030 char *psz_name
= NULL
;
3031 char *psz_text
= NULL
;
3032 char *psz_extra
= strdup("");
3036 i_start
= EITConvertStartTime( p_evt
->i_start_time
);
3037 i_duration
= EITConvertDuration( p_evt
->i_duration
);
3039 msg_Dbg( p_demux
, " * event id=%d start_time:%d duration=%d "
3040 "running=%d free_ca=%d",
3041 p_evt
->i_event_id
, (int)i_start
, (int)i_duration
,
3042 p_evt
->i_running_status
, p_evt
->b_free_ca
);
3044 for( p_dr
= p_evt
->p_first_descriptor
; p_dr
; p_dr
= p_dr
->p_next
)
3046 if( p_dr
->i_tag
== 0x4d )
3048 dvbpsi_short_event_dr_t
*pE
= dvbpsi_DecodeShortEventDr( p_dr
);
3050 /* Only take first description, as we don't handle language-info
3052 if( pE
&& psz_name
== NULL
)
3054 psz_name
= EITConvertToUTF8( pE
->i_event_name
, pE
->i_event_name_length
,
3055 p_sys
->b_broken_charset
);
3056 psz_text
= EITConvertToUTF8( pE
->i_text
, pE
->i_text_length
,
3057 p_sys
->b_broken_charset
);
3058 msg_Dbg( p_demux
, " - short event lang=%3.3s '%s' : '%s'",
3059 pE
->i_iso_639_code
, psz_name
, psz_text
);
3062 else if( p_dr
->i_tag
== 0x4e )
3064 dvbpsi_extended_event_dr_t
*pE
= dvbpsi_DecodeExtendedEventDr( p_dr
);
3067 msg_Dbg( p_demux
, " - extended event lang=%3.3s [%d/%d]",
3069 pE
->i_descriptor_number
, pE
->i_last_descriptor_number
);
3071 if( pE
->i_text_length
> 0 )
3073 char *psz_text
= EITConvertToUTF8( pE
->i_text
, pE
->i_text_length
,
3074 p_sys
->b_broken_charset
);
3077 msg_Dbg( p_demux
, " - text='%s'", psz_text
);
3079 psz_extra
= xrealloc( psz_extra
,
3080 strlen(psz_extra
) + strlen(psz_text
) + 1 );
3081 strcat( psz_extra
, psz_text
);
3086 for( int i
= 0; i
< pE
->i_entry_count
; i
++ )
3088 char *psz_dsc
= EITConvertToUTF8( pE
->i_item_description
[i
],
3089 pE
->i_item_description_length
[i
],
3090 p_sys
->b_broken_charset
);
3091 char *psz_itm
= EITConvertToUTF8( pE
->i_item
[i
], pE
->i_item_length
[i
],
3092 p_sys
->b_broken_charset
);
3094 if( psz_dsc
&& psz_itm
)
3096 msg_Dbg( p_demux
, " - desc='%s' item='%s'", psz_dsc
, psz_itm
);
3098 psz_extra
= xrealloc( psz_extra
,
3099 strlen(psz_extra
) + strlen(psz_dsc
) +
3100 strlen(psz_itm
) + 3 + 1 );
3101 strcat( psz_extra
, "(" );
3102 strcat( psz_extra
, psz_dsc
);
3103 strcat( psz_extra
, " " );
3104 strcat( psz_extra
, psz_itm
);
3105 strcat( psz_extra
, ")" );
3115 msg_Dbg( p_demux
, " - tag=0x%x(%d)", p_dr
->i_tag
, p_dr
->i_tag
);
3121 vlc_epg_AddEvent( p_epg
, i_start
, i_duration
, psz_name
, psz_text
,
3122 *psz_extra
? psz_extra
: NULL
);
3124 /* Update "now playing" field */
3125 if( p_evt
->i_running_status
== 0x04 && i_start
> 0 )
3126 vlc_epg_SetCurrent( p_epg
, i_start
);
3133 if( p_epg
->i_event
> 0 )
3135 if( b_current_following
&&
3136 ( p_sys
->i_current_program
== -1 ||
3137 p_sys
->i_current_program
== p_eit
->i_service_id
) )
3139 p_sys
->i_dvb_length
= 0;
3140 p_sys
->i_dvb_start
= 0;
3142 if( p_epg
->p_current
)
3144 p_sys
->i_dvb_start
= CLOCK_FREQ
* p_epg
->p_current
->i_start
;
3145 p_sys
->i_dvb_length
= CLOCK_FREQ
* p_epg
->p_current
->i_duration
;
3148 es_out_Control( p_demux
->out
, ES_OUT_SET_GROUP_EPG
, p_eit
->i_service_id
, p_epg
);
3150 vlc_epg_Delete( p_epg
);
3152 dvbpsi_DeleteEIT( p_eit
);
3154 static void EITCallBackCurrentFollowing( demux_t
*p_demux
, dvbpsi_eit_t
*p_eit
)
3156 EITCallBack( p_demux
, p_eit
, true );
3158 static void EITCallBackSchedule( demux_t
*p_demux
, dvbpsi_eit_t
*p_eit
)
3160 EITCallBack( p_demux
, p_eit
, false );
3163 static void PSINewTableCallBack( demux_t
*p_demux
, dvbpsi_handle h
,
3164 uint8_t i_table_id
, uint16_t i_extension
)
3167 msg_Dbg( p_demux
, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
3168 i_table_id
, i_table_id
, i_extension
, i_extension
);
3170 if( p_demux
->p_sys
->pid
[0].psi
->i_pat_version
!= -1 && i_table_id
== 0x42 )
3172 msg_Dbg( p_demux
, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
3173 i_table_id
, i_table_id
, i_extension
, i_extension
);
3175 dvbpsi_AttachSDT( h
, i_table_id
, i_extension
,
3176 (dvbpsi_sdt_callback
)SDTCallBack
, p_demux
);
3178 else if( p_demux
->p_sys
->pid
[0x11].psi
->i_sdt_version
!= -1 &&
3179 ( i_table_id
== 0x4e || /* Current/Following */
3180 (i_table_id
>= 0x50 && i_table_id
<= 0x5f) ) ) /* Schedule */
3182 msg_Dbg( p_demux
, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
3183 i_table_id
, i_table_id
, i_extension
, i_extension
);
3185 dvbpsi_eit_callback cb
= i_table_id
== 0x4e ?
3186 (dvbpsi_eit_callback
)EITCallBackCurrentFollowing
:
3187 (dvbpsi_eit_callback
)EITCallBackSchedule
;
3188 dvbpsi_AttachEIT( h
, i_table_id
, i_extension
, cb
, p_demux
);
3191 else if( p_demux
->p_sys
->pid
[0x11].psi
->i_sdt_version
!= -1 &&
3192 i_table_id
== 0x70 ) /* TDT */
3194 msg_Dbg( p_demux
, "PSINewTableCallBack: table 0x%x(%d) ext=0x%x(%d)",
3195 i_table_id
, i_table_id
, i_extension
, i_extension
);
3196 dvbpsi_AttachTOT( h
, i_table_id
, i_extension
,
3197 (dvbpsi_tot_callback
)TDTCallBack
, p_demux
);
3204 /*****************************************************************************
3205 * PMT callback and helpers
3206 *****************************************************************************/
3207 static dvbpsi_descriptor_t
*PMTEsFindDescriptor( const dvbpsi_pmt_es_t
*p_es
,
3210 dvbpsi_descriptor_t
*p_dr
= p_es
->p_first_descriptor
;;
3211 while( p_dr
&& ( p_dr
->i_tag
!= i_tag
) )
3212 p_dr
= p_dr
->p_next
;
3215 static bool PMTEsHasRegistration( demux_t
*p_demux
,
3216 const dvbpsi_pmt_es_t
*p_es
,
3217 const char *psz_tag
)
3219 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x05 );
3223 if( p_dr
->i_length
< 4 )
3225 msg_Warn( p_demux
, "invalid Registration Descriptor" );
3229 assert( strlen(psz_tag
) == 4 );
3230 return !memcmp( p_dr
->p_data
, psz_tag
, 4 );
3232 static void PMTSetupEsISO14496( demux_t
*p_demux
, ts_pid_t
*pid
,
3233 const ts_prg_psi_t
*prg
, const dvbpsi_pmt_es_t
*p_es
)
3235 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3237 /* MPEG-4 stream: search SL_DESCRIPTOR */
3238 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x1f );
3240 if( p_dr
&& p_dr
->i_length
== 2 )
3242 const int i_es_id
= ( p_dr
->p_data
[0] << 8 ) | p_dr
->p_data
[1];
3244 msg_Warn( p_demux
, "found SL_descriptor es_id=%d", i_es_id
);
3246 pid
->es
->p_mpeg4desc
= NULL
;
3248 for( int i
= 0; i
< 255; i
++ )
3250 iod_descriptor_t
*iod
= prg
->iod
;
3252 if( iod
->es_descr
[i
].b_ok
&&
3253 iod
->es_descr
[i
].i_es_id
== i_es_id
)
3255 pid
->es
->p_mpeg4desc
= &iod
->es_descr
[i
];
3260 if( !pid
->es
->p_mpeg4desc
)
3262 msg_Err( p_demux
, "MPEG-4 descriptor not found" );
3266 const decoder_config_descriptor_t
*dcd
= &pid
->es
->p_mpeg4desc
->dec_descr
;
3267 if( dcd
->i_streamType
== 0x04 ) /* VisualStream */
3269 p_fmt
->i_cat
= VIDEO_ES
;
3270 switch( dcd
->i_objectTypeIndication
)
3272 case 0x0B: /* mpeg4 sub */
3273 p_fmt
->i_cat
= SPU_ES
;
3274 p_fmt
->i_codec
= VLC_CODEC_SUBT
;
3277 case 0x20: /* mpeg4 */
3278 p_fmt
->i_codec
= VLC_CODEC_MP4V
;
3280 case 0x21: /* h264 */
3281 p_fmt
->i_codec
= VLC_CODEC_H264
;
3288 case 0x65: /* mpeg2 */
3289 p_fmt
->i_codec
= VLC_CODEC_MPGV
;
3291 case 0x6a: /* mpeg1 */
3292 p_fmt
->i_codec
= VLC_CODEC_MPGV
;
3294 case 0x6c: /* mpeg1 */
3295 p_fmt
->i_codec
= VLC_CODEC_JPEG
;
3298 p_fmt
->i_cat
= UNKNOWN_ES
;
3302 else if( dcd
->i_streamType
== 0x05 ) /* AudioStream */
3304 p_fmt
->i_cat
= AUDIO_ES
;
3305 switch( dcd
->i_objectTypeIndication
)
3307 case 0x40: /* mpeg4 */
3308 p_fmt
->i_codec
= VLC_CODEC_MP4A
;
3312 case 0x68: /* mpeg2 aac */
3313 p_fmt
->i_codec
= VLC_CODEC_MP4A
;
3315 case 0x69: /* mpeg2 */
3316 p_fmt
->i_codec
= VLC_CODEC_MPGA
;
3318 case 0x6b: /* mpeg1 */
3319 p_fmt
->i_codec
= VLC_CODEC_MPGA
;
3322 p_fmt
->i_cat
= UNKNOWN_ES
;
3328 p_fmt
->i_cat
= UNKNOWN_ES
;
3331 if( p_fmt
->i_cat
!= UNKNOWN_ES
)
3333 p_fmt
->i_extra
= dcd
->i_decoder_specific_info_len
;
3334 if( p_fmt
->i_extra
> 0 )
3336 p_fmt
->p_extra
= malloc( p_fmt
->i_extra
);
3337 if( p_fmt
->p_extra
)
3338 memcpy( p_fmt
->p_extra
,
3339 dcd
->p_decoder_specific_info
,
3353 } ts_teletext_page_t
;
3355 static void PMTSetupEsTeletext( demux_t
*p_demux
, ts_pid_t
*pid
,
3356 const dvbpsi_pmt_es_t
*p_es
)
3358 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3360 ts_teletext_page_t p_page
[2 * 64 + 20];
3361 unsigned i_page
= 0;
3363 /* Gather pages informations */
3364 #if defined _DVBPSI_DR_56_H_ && \
3365 defined DVBPSI_VERSION && DVBPSI_VERSION_INT > ((0<<16)+(1<<8)+5)
3366 for( unsigned i_tag_idx
= 0; i_tag_idx
< 2; i_tag_idx
++ )
3368 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, i_tag_idx
== 0 ? 0x46 : 0x56 );
3372 dvbpsi_teletext_dr_t
*p_sub
= dvbpsi_DecodeTeletextDr( p_dr
);
3376 for( int i
= 0; i
< p_sub
->i_pages_number
; i
++ )
3378 const dvbpsi_teletextpage_t
*p_src
= &p_sub
->p_pages
[i
];
3380 if( p_src
->i_teletext_type
>= 0x06 )
3383 assert( i_page
< sizeof(p_page
)/sizeof(*p_page
) );
3385 ts_teletext_page_t
*p_dst
= &p_page
[i_page
++];
3387 p_dst
->i_type
= p_src
->i_teletext_type
;
3388 p_dst
->i_magazine
= p_src
->i_teletext_magazine_number
3389 ? p_src
->i_teletext_magazine_number
: 8;
3390 p_dst
->i_page
= p_src
->i_teletext_page_number
;
3391 memcpy( p_dst
->p_iso639
, p_src
->i_iso6392_language_code
, 3 );
3396 #ifdef _DVBPSI_DR_59_H_
3397 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x59 );
3400 dvbpsi_subtitling_dr_t
*p_sub
= dvbpsi_DecodeSubtitlingDr( p_dr
);
3401 for( int i
= 0; p_sub
&& i
< p_sub
->i_subtitles_number
; i
++ )
3403 dvbpsi_subtitle_t
*p_src
= &p_sub
->p_subtitle
[i
];
3405 if( p_src
->i_subtitling_type
< 0x01 || p_src
->i_subtitling_type
> 0x03 )
3408 assert( i_page
< sizeof(p_page
)/sizeof(*p_page
) );
3410 ts_teletext_page_t
*p_dst
= &p_page
[i_page
++];
3412 switch( p_src
->i_subtitling_type
)
3415 p_dst
->i_type
= 0x02;
3418 p_dst
->i_type
= 0x03;
3421 /* FIXME check if it is the right split */
3422 p_dst
->i_magazine
= (p_src
->i_composition_page_id
>> 8)
3423 ? (p_src
->i_composition_page_id
>> 8) : 8;
3424 p_dst
->i_page
= p_src
->i_composition_page_id
& 0xff;
3425 memcpy( p_dst
->p_iso639
, p_src
->i_iso6392_language_code
, 3 );
3431 es_format_Init( p_fmt
, SPU_ES
, VLC_CODEC_TELETEXT
);
3433 if( !p_demux
->p_sys
->b_split_es
|| i_page
<= 0 )
3435 p_fmt
->subs
.teletext
.i_magazine
= -1;
3436 p_fmt
->subs
.teletext
.i_page
= 0;
3437 p_fmt
->psz_description
= strdup( vlc_gettext(ppsz_teletext_type
[1]) );
3439 dvbpsi_descriptor_t
*p_dr
;
3440 p_dr
= PMTEsFindDescriptor( p_es
, 0x46 );
3442 p_dr
= PMTEsFindDescriptor( p_es
, 0x56 );
3444 if( !p_demux
->p_sys
->b_split_es
&& p_dr
&& p_dr
->i_length
> 0 )
3446 /* Descriptor pass-through */
3447 p_fmt
->p_extra
= malloc( p_dr
->i_length
);
3448 if( p_fmt
->p_extra
)
3450 p_fmt
->i_extra
= p_dr
->i_length
;
3451 memcpy( p_fmt
->p_extra
, p_dr
->p_data
, p_dr
->i_length
);
3457 for( unsigned i
= 0; i
< i_page
; i
++ )
3468 p_es
= malloc( sizeof(*p_es
) );
3472 es_format_Copy( &p_es
->fmt
, &pid
->es
->fmt
);
3473 free( p_es
->fmt
.psz_language
);
3474 free( p_es
->fmt
.psz_description
);
3475 p_es
->fmt
.psz_language
= NULL
;
3476 p_es
->fmt
.psz_description
= NULL
;
3480 p_es
->i_pes_size
= 0;
3481 p_es
->i_pes_gathered
= 0;
3482 p_es
->pp_last
= &p_es
->p_pes
;
3483 p_es
->p_mpeg4desc
= NULL
;
3484 p_es
->b_gather
= false;
3486 TAB_APPEND( pid
->i_extra_es
, pid
->extra_es
, p_es
);
3490 const ts_teletext_page_t
*p
= &p_page
[i
];
3491 p_es
->fmt
.i_priority
= (p
->i_type
== 0x02 || p
->i_type
== 0x05) ? 0 : -1;
3492 p_es
->fmt
.psz_language
= strndup( p
->p_iso639
, 3 );
3493 p_es
->fmt
.psz_description
= strdup(vlc_gettext(ppsz_teletext_type
[p
->i_type
]));
3494 p_es
->fmt
.subs
.teletext
.i_magazine
= p
->i_magazine
;
3495 p_es
->fmt
.subs
.teletext
.i_page
= p
->i_page
;
3498 " * ttxt type=%s lan=%s page=%d%02x",
3499 p_es
->fmt
.psz_description
,
3500 p_es
->fmt
.psz_language
,
3501 p
->i_magazine
, p
->i_page
);
3505 static void PMTSetupEsDvbSubtitle( demux_t
*p_demux
, ts_pid_t
*pid
,
3506 const dvbpsi_pmt_es_t
*p_es
)
3508 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3510 es_format_Init( p_fmt
, SPU_ES
, VLC_CODEC_DVBS
);
3512 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x59 );
3514 #ifdef _DVBPSI_DR_59_H_
3515 dvbpsi_subtitling_dr_t
*p_sub
= dvbpsi_DecodeSubtitlingDr( p_dr
);
3516 for( int i
= 0; p_sub
&& i
< p_sub
->i_subtitles_number
; i
++ )
3518 const int i_type
= p_sub
->p_subtitle
[i
].i_subtitling_type
;
3519 if( ( i_type
>= 0x10 && i_type
<= 0x14 ) ||
3520 ( i_type
>= 0x20 && i_type
<= 0x24 ) )
3525 if( !p_demux
->p_sys
->b_split_es
|| i_page
<= 0 )
3527 p_fmt
->subs
.dvb
.i_id
= -1;
3528 p_fmt
->psz_description
= strdup( _("DVB subtitles") );
3530 if( !p_demux
->p_sys
->b_split_es
&& p_dr
&& p_dr
->i_length
> 0 )
3532 /* Descriptor pass-through */
3533 p_fmt
->p_extra
= malloc( p_dr
->i_length
);
3534 if( p_fmt
->p_extra
)
3536 p_fmt
->i_extra
= p_dr
->i_length
;
3537 memcpy( p_fmt
->p_extra
, p_dr
->p_data
, p_dr
->i_length
);
3543 #ifdef _DVBPSI_DR_59_H_
3544 for( int i
= 0; i
< p_sub
->i_subtitles_number
; i
++ )
3555 p_es
= malloc( sizeof(*p_es
) );
3559 es_format_Copy( &p_es
->fmt
, &pid
->es
->fmt
);
3560 free( p_es
->fmt
.psz_language
);
3561 free( p_es
->fmt
.psz_description
);
3562 p_es
->fmt
.psz_language
= NULL
;
3563 p_es
->fmt
.psz_description
= NULL
;
3567 p_es
->i_pes_size
= 0;
3568 p_es
->i_pes_gathered
= 0;
3569 p_es
->pp_last
= &p_es
->p_pes
;
3570 p_es
->p_mpeg4desc
= NULL
;
3571 p_es
->b_gather
= false;
3573 TAB_APPEND( pid
->i_extra_es
, pid
->extra_es
, p_es
);
3577 const dvbpsi_subtitle_t
*p
= &p_sub
->p_subtitle
[i
];
3578 p_es
->fmt
.psz_language
= strndup( p
->i_iso6392_language_code
, 3 );
3579 switch( p
->i_subtitling_type
)
3581 case 0x10: /* unspec. */
3582 case 0x11: /* 4:3 */
3583 case 0x12: /* 16:9 */
3584 case 0x13: /* 2.21:1 */
3585 case 0x14: /* HD monitor */
3586 p_es
->fmt
.psz_description
= strdup( _("DVB subtitles") );
3588 case 0x20: /* Hearing impaired unspec. */
3589 case 0x21: /* h.i. 4:3 */
3590 case 0x22: /* h.i. 16:9 */
3591 case 0x23: /* h.i. 2.21:1 */
3592 case 0x24: /* h.i. HD monitor */
3593 p_es
->fmt
.psz_description
= strdup( _("DVB subtitles: hearing impaired") );
3600 p_es
->fmt
.subs
.dvb
.i_id
= ( p
->i_composition_page_id
<< 0 ) |
3601 ( p
->i_ancillary_page_id
<< 16 );
3606 static void PMTSetupEs0x06( demux_t
*p_demux
, ts_pid_t
*pid
,
3607 const dvbpsi_pmt_es_t
*p_es
)
3609 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3611 if( PMTEsHasRegistration( p_demux
, p_es
, "AC-3" ) ||
3612 PMTEsFindDescriptor( p_es
, 0x6a ) ||
3613 PMTEsFindDescriptor( p_es
, 0x81 ) )
3615 p_fmt
->i_cat
= AUDIO_ES
;
3616 p_fmt
->i_codec
= VLC_CODEC_A52
;
3618 else if( PMTEsFindDescriptor( p_es
, 0x7a ) )
3620 /* DVB with stream_type 0x06 (ETS EN 300 468) */
3621 p_fmt
->i_cat
= AUDIO_ES
;
3622 p_fmt
->i_codec
= VLC_CODEC_EAC3
;
3624 else if( PMTEsHasRegistration( p_demux
, p_es
, "DTS1" ) ||
3625 PMTEsHasRegistration( p_demux
, p_es
, "DTS2" ) ||
3626 PMTEsHasRegistration( p_demux
, p_es
, "DTS3" ) ||
3627 PMTEsFindDescriptor( p_es
, 0x73 ) )
3629 /*registration descriptor(ETSI TS 101 154 Annex F)*/
3630 p_fmt
->i_cat
= AUDIO_ES
;
3631 p_fmt
->i_codec
= VLC_CODEC_DTS
;
3633 else if( PMTEsHasRegistration( p_demux
, p_es
, "BSSD" ) )
3635 p_fmt
->i_cat
= AUDIO_ES
;
3636 p_fmt
->b_packetized
= true;
3637 p_fmt
->i_codec
= VLC_CODEC_302M
;
3641 /* Subtitle/Teletext/VBI fallbacks */
3642 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x59 );
3644 #ifdef _DVBPSI_DR_59_H_
3645 dvbpsi_subtitling_dr_t
*p_sub
;
3646 if( p_dr
&& ( p_sub
= dvbpsi_DecodeSubtitlingDr( p_dr
) ) )
3648 for( int i
= 0; i
< p_sub
->i_subtitles_number
; i
++ )
3650 if( p_fmt
->i_cat
!= UNKNOWN_ES
)
3653 switch( p_sub
->p_subtitle
[i
].i_subtitling_type
)
3655 case 0x01: /* EBU Teletext subtitles */
3656 case 0x02: /* Associated EBU Teletext */
3657 case 0x03: /* VBI data */
3658 PMTSetupEsTeletext( p_demux
, pid
, p_es
);
3660 case 0x10: /* DVB Subtitle (normal) with no monitor AR critical */
3661 case 0x11: /* ... on 4:3 AR monitor */
3662 case 0x12: /* ... on 16:9 AR monitor */
3663 case 0x13: /* ... on 2.21:1 AR monitor */
3664 case 0x14: /* ... for display on a high definition monitor */
3665 case 0x20: /* DVB Subtitle (impaired) with no monitor AR critical */
3666 case 0x21: /* ... on 4:3 AR monitor */
3667 case 0x22: /* ... on 16:9 AR monitor */
3668 case 0x23: /* ... on 2.21:1 AR monitor */
3669 case 0x24: /* ... for display on a high definition monitor */
3670 PMTSetupEsDvbSubtitle( p_demux
, pid
, p_es
);
3673 msg_Err( p_demux
, "Unrecognized DVB subtitle type (0x%x)",
3674 p_sub
->p_subtitle
[i
].i_subtitling_type
);
3680 if( p_fmt
->i_cat
== UNKNOWN_ES
&& p_dr
)
3681 PMTSetupEsDvbSubtitle( p_demux
, pid
, p_es
);
3683 if( p_fmt
->i_cat
== UNKNOWN_ES
&&
3684 ( PMTEsFindDescriptor( p_es
, 0x45 ) || /* VBI Data descriptor */
3685 PMTEsFindDescriptor( p_es
, 0x46 ) || /* VBI Teletext descriptor */
3686 PMTEsFindDescriptor( p_es
, 0x56 ) ) ) /* EBU Teletext descriptor */
3689 PMTSetupEsTeletext( p_demux
, pid
, p_es
);
3693 #ifdef _DVBPSI_DR_52_H_
3694 /* FIXME is it useful ? */
3695 if( PMTEsFindDescriptor( p_es
, 0x52 ) )
3697 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x52 );
3698 dvbpsi_stream_identifier_dr_t
*p_si
= dvbpsi_DecodeStreamIdentifierDr( p_dr
);
3700 msg_Dbg( p_demux
, " * Stream Component Identifier: %d", p_si
->i_component_tag
);
3705 static void PMTSetupEs0xEA( demux_t
*p_demux
, ts_pid_t
*pid
,
3706 const dvbpsi_pmt_es_t
*p_es
)
3708 /* Registration Descriptor */
3709 if( !PMTEsHasRegistration( p_demux
, p_es
, "VC-1" ) )
3711 msg_Err( p_demux
, "Registration descriptor not found or invalid" );
3715 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3717 /* registration descriptor for VC-1 (SMPTE rp227) */
3718 p_fmt
->i_cat
= VIDEO_ES
;
3719 p_fmt
->i_codec
= VLC_CODEC_VC1
;
3721 /* XXX With Simple and Main profile the SEQUENCE
3722 * header is modified: video width and height are
3723 * inserted just after the start code as 2 int16_t
3724 * The packetizer will take care of that. */
3727 static void PMTSetupEs0xD1( demux_t
*p_demux
, ts_pid_t
*pid
,
3728 const dvbpsi_pmt_es_t
*p_es
)
3730 /* Registration Descriptor */
3731 if( !PMTEsHasRegistration( p_demux
, p_es
, "drac" ) )
3733 msg_Err( p_demux
, "Registration descriptor not found or invalid" );
3737 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3739 /* registration descriptor for Dirac
3740 * (backwards compatable with VC-2 (SMPTE Sxxxx:2008)) */
3741 p_fmt
->i_cat
= VIDEO_ES
;
3742 p_fmt
->i_codec
= VLC_CODEC_DIRAC
;
3745 static void PMTSetupEs0xA0( demux_t
*p_demux
, ts_pid_t
*pid
,
3746 const dvbpsi_pmt_es_t
*p_es
)
3748 /* MSCODEC sent by vlc */
3749 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0xa0 );
3750 if( !p_dr
|| p_dr
->i_length
< 10 )
3753 "private MSCODEC (vlc) without bih private descriptor" );
3757 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3758 p_fmt
->i_cat
= VIDEO_ES
;
3759 p_fmt
->i_codec
= VLC_FOURCC( p_dr
->p_data
[0], p_dr
->p_data
[1],
3760 p_dr
->p_data
[2], p_dr
->p_data
[3] );
3761 p_fmt
->video
.i_width
= GetWBE( &p_dr
->p_data
[4] );
3762 p_fmt
->video
.i_height
= GetWBE( &p_dr
->p_data
[6] );
3763 p_fmt
->i_extra
= GetWBE( &p_dr
->p_data
[8] );
3765 if( p_fmt
->i_extra
> 0 )
3767 p_fmt
->p_extra
= malloc( p_fmt
->i_extra
);
3768 if( p_fmt
->p_extra
)
3769 memcpy( p_fmt
->p_extra
, &p_dr
->p_data
[10],
3770 __MIN( p_fmt
->i_extra
, p_dr
->i_length
- 10 ) );
3774 /* For such stream we will gather them ourself and don't launch a
3776 * Yes it's ugly but it's the only way to have DIV3 working */
3777 p_fmt
->b_packetized
= true;
3780 static void PMTSetupEsHDMV( demux_t
*p_demux
, ts_pid_t
*pid
,
3781 const dvbpsi_pmt_es_t
*p_es
)
3783 VLC_UNUSED(p_demux
);
3784 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3786 /* Blu-Ray mapping */
3787 switch( p_es
->i_type
)
3790 p_fmt
->i_cat
= AUDIO_ES
;
3791 p_fmt
->i_codec
= VLC_CODEC_BD_LPCM
;
3794 case 0x85: /* DTS-HD High resolution audio */
3795 case 0x86: /* DTS-HD Master audio */
3796 case 0xA2: /* Secondary DTS audio */
3797 p_fmt
->i_cat
= AUDIO_ES
;
3798 p_fmt
->i_codec
= VLC_CODEC_DTS
;
3801 case 0x83: /* TrueHD AC3 */
3802 p_fmt
->i_cat
= AUDIO_ES
;
3803 p_fmt
->i_codec
= VLC_CODEC_TRUEHD
;
3806 case 0x84: /* E-AC3 */
3807 case 0xA1: /* Secondary E-AC3 */
3808 p_fmt
->i_cat
= AUDIO_ES
;
3809 p_fmt
->i_codec
= VLC_CODEC_EAC3
;
3811 case 0x90: /* Presentation graphics */
3812 p_fmt
->i_cat
= SPU_ES
;
3813 p_fmt
->i_codec
= VLC_CODEC_BD_PG
;
3815 case 0x91: /* Interactive graphics */
3816 case 0x92: /* Subtitle */
3822 static void PMTSetupEsRegistration( demux_t
*p_demux
, ts_pid_t
*pid
,
3823 const dvbpsi_pmt_es_t
*p_es
)
3829 vlc_fourcc_t i_codec
;
3831 { "AC-3", AUDIO_ES
, VLC_CODEC_A52
},
3832 { "DTS1", AUDIO_ES
, VLC_CODEC_DTS
},
3833 { "DTS2", AUDIO_ES
, VLC_CODEC_DTS
},
3834 { "DTS3", AUDIO_ES
, VLC_CODEC_DTS
},
3835 { "BSSD", AUDIO_ES
, VLC_CODEC_302M
},
3836 { "VC-1", VIDEO_ES
, VLC_CODEC_VC1
},
3837 { "drac", VIDEO_ES
, VLC_CODEC_DIRAC
},
3838 { "", UNKNOWN_ES
, 0 }
3840 es_format_t
*p_fmt
= &pid
->es
->fmt
;
3842 for( int i
= 0; p_regs
[i
].i_cat
!= UNKNOWN_ES
; i
++ )
3844 if( PMTEsHasRegistration( p_demux
, p_es
, p_regs
[i
].psz_tag
) )
3846 p_fmt
->i_cat
= p_regs
[i
].i_cat
;
3847 p_fmt
->i_codec
= p_regs
[i
].i_codec
;
3853 static void PMTParseEsIso639( demux_t
*p_demux
, ts_pid_t
*pid
,
3854 const dvbpsi_pmt_es_t
*p_es
)
3856 /* get language descriptor */
3857 dvbpsi_descriptor_t
*p_dr
= PMTEsFindDescriptor( p_es
, 0x0a );
3862 dvbpsi_iso639_dr_t
*p_decoded
= dvbpsi_DecodeISO639Dr( p_dr
);
3865 msg_Err( p_demux
, "Failed to decode a ISO 639 descriptor" );
3869 #if defined(DR_0A_API_VER) && (DR_0A_API_VER >= 2)
3870 pid
->es
->fmt
.psz_language
= malloc( 4 );
3871 if( pid
->es
->fmt
.psz_language
)
3873 memcpy( pid
->es
->fmt
.psz_language
,
3874 p_decoded
->code
[0].iso_639_code
, 3 );
3875 pid
->es
->fmt
.psz_language
[3] = 0;
3876 msg_Dbg( p_demux
, "found language: %s", pid
->es
->fmt
.psz_language
);
3878 switch( p_decoded
->code
[0].i_audio_type
)
3881 pid
->es
->fmt
.psz_description
= NULL
;
3884 pid
->es
->fmt
.psz_description
=
3885 strdup(_("clean effects"));
3888 pid
->es
->fmt
.psz_description
=
3889 strdup(_("hearing impaired"));
3892 pid
->es
->fmt
.psz_description
=
3893 strdup(_("visual impaired commentary"));
3896 msg_Dbg( p_demux
, "unknown audio type: %d",
3897 p_decoded
->code
[0].i_audio_type
);
3898 pid
->es
->fmt
.psz_description
= NULL
;
3901 pid
->es
->fmt
.i_extra_languages
= p_decoded
->i_code_count
-1;
3902 if( pid
->es
->fmt
.i_extra_languages
> 0 )
3903 pid
->es
->fmt
.p_extra_languages
=
3904 malloc( sizeof(*pid
->es
->fmt
.p_extra_languages
) *
3905 pid
->es
->fmt
.i_extra_languages
);
3906 if( pid
->es
->fmt
.p_extra_languages
)
3908 for( int i
= 0; i
< pid
->es
->fmt
.i_extra_languages
; i
++ )
3910 msg_Dbg( p_demux
, "bang" );
3911 pid
->es
->fmt
.p_extra_languages
[i
].psz_language
=
3913 if( pid
->es
->fmt
.p_extra_languages
[i
].psz_language
)
3915 memcpy( pid
->es
->fmt
.p_extra_languages
[i
].psz_language
,
3916 p_decoded
->code
[i
+1].iso_639_code
, 3 );
3917 pid
->es
->fmt
.p_extra_languages
[i
].psz_language
[3] = '\0';
3919 switch( p_decoded
->code
[i
].i_audio_type
)
3922 pid
->es
->fmt
.p_extra_languages
[i
].psz_description
=
3926 pid
->es
->fmt
.p_extra_languages
[i
].psz_description
=
3927 strdup(_("clean effects"));
3930 pid
->es
->fmt
.p_extra_languages
[i
].psz_description
=
3931 strdup(_("hearing impaired"));
3934 pid
->es
->fmt
.p_extra_languages
[i
].psz_description
=
3935 strdup(_("visual impaired commentary"));
3938 msg_Dbg( p_demux
, "unknown audio type: %d",
3939 p_decoded
->code
[i
].i_audio_type
);
3940 pid
->es
->fmt
.psz_description
= NULL
;
3947 pid
->es
->fmt
.psz_language
= malloc( 4 );
3948 if( pid
->es
->fmt
.psz_language
)
3950 memcpy( pid
->es
->fmt
.psz_language
,
3951 p_decoded
->i_iso_639_code
, 3 );
3952 pid
->es
->fmt
.psz_language
[3] = 0;
3957 static void PMTCallBack( demux_t
*p_demux
, dvbpsi_pmt_t
*p_pmt
)
3959 demux_sys_t
*p_sys
= p_demux
->p_sys
;
3960 dvbpsi_descriptor_t
*p_dr
;
3961 dvbpsi_pmt_es_t
*p_es
;
3963 ts_pid_t
*pmt
= NULL
;
3964 ts_prg_psi_t
*prg
= NULL
;
3966 ts_pid_t
**pp_clean
= NULL
;
3968 bool b_hdmv
= false;
3970 msg_Dbg( p_demux
, "PMTCallBack called" );
3972 /* First find this PMT declared in PAT */
3973 for( int i
= 0; i
< p_sys
->i_pmt
; i
++ )
3976 for( i_prg
= 0; i_prg
< p_sys
->pmt
[i
]->psi
->i_prg
; i_prg
++ )
3978 const int i_pmt_number
= p_sys
->pmt
[i
]->psi
->prg
[i_prg
]->i_number
;
3979 if( i_pmt_number
!= TS_USER_PMT_NUMBER
&& i_pmt_number
== p_pmt
->i_program_number
)
3981 pmt
= p_sys
->pmt
[i
];
3982 prg
= p_sys
->pmt
[i
]->psi
->prg
[i_prg
];
3992 msg_Warn( p_demux
, "unreferenced program (broken stream)" );
3993 dvbpsi_DeletePMT(p_pmt
);
3997 if( prg
->i_version
!= -1 &&
3998 ( !p_pmt
->b_current_next
|| prg
->i_version
== p_pmt
->i_version
) )
4000 dvbpsi_DeletePMT( p_pmt
);
4004 /* Clean this program (remove all es) */
4005 for( int i
= 0; i
< 8192; i
++ )
4007 ts_pid_t
*pid
= &p_sys
->pid
[i
];
4009 if( pid
->b_valid
&& pid
->p_owner
== pmt
->psi
&&
4010 pid
->i_owner_number
== prg
->i_number
&& pid
->psi
== NULL
)
4012 TAB_APPEND( i_clean
, pp_clean
, pid
);
4017 IODFree( prg
->iod
);
4021 msg_Dbg( p_demux
, "new PMT program number=%d version=%d pid_pcr=%d",
4022 p_pmt
->i_program_number
, p_pmt
->i_version
, p_pmt
->i_pcr_pid
);
4023 prg
->i_pid_pcr
= p_pmt
->i_pcr_pid
;
4024 prg
->i_version
= p_pmt
->i_version
;
4026 ValidateDVBMeta( p_demux
, prg
->i_pid_pcr
);
4027 if( ProgramIsSelected( p_demux
, prg
->i_number
) )
4029 /* Set demux filter */
4030 stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
4031 ACCESS_SET_PRIVATE_ID_STATE
, prg
->i_pid_pcr
,
4034 else if ( p_sys
->b_access_control
)
4036 msg_Warn( p_demux
, "skipping program (not selected)" );
4037 dvbpsi_DeletePMT(p_pmt
);
4041 /* Parse descriptor */
4042 for( p_dr
= p_pmt
->p_first_descriptor
; p_dr
!= NULL
; p_dr
= p_dr
->p_next
)
4044 if( p_dr
->i_tag
== 0x1d )
4046 /* We have found an IOD descriptor */
4047 msg_Dbg( p_demux
, " * descriptor : IOD (0x1d)" );
4049 prg
->iod
= IODNew( p_dr
->i_length
, p_dr
->p_data
);
4051 else if( p_dr
->i_tag
== 0x9 )
4053 uint16_t i_sysid
= ((uint16_t)p_dr
->p_data
[0] << 8)
4055 msg_Dbg( p_demux
, " * descriptor : CA (0x9) SysID 0x%x", i_sysid
);
4057 else if( p_dr
->i_tag
== 0x05 )
4059 /* Registration Descriptor */
4060 if( p_dr
->i_length
!= 4 )
4062 msg_Warn( p_demux
, "invalid Registration Descriptor" );
4066 msg_Dbg( p_demux
, " * descriptor : registration %4.4s", p_dr
->p_data
);
4067 if( !memcmp( p_dr
->p_data
, "HDMV", 4 ) )
4076 msg_Dbg( p_demux
, " * descriptor : unknown (0x%x)", p_dr
->i_tag
);
4080 for( p_es
= p_pmt
->p_first_es
; p_es
!= NULL
; p_es
= p_es
->p_next
)
4082 ts_pid_t tmp_pid
, *old_pid
= 0, *pid
= &tmp_pid
;
4084 /* Find out if the PID was already declared */
4085 for( int i
= 0; i
< i_clean
; i
++ )
4087 if( pp_clean
[i
] == &p_sys
->pid
[p_es
->i_pid
] )
4089 old_pid
= pp_clean
[i
];
4093 ValidateDVBMeta( p_demux
, p_es
->i_pid
);
4095 if( !old_pid
&& p_sys
->pid
[p_es
->i_pid
].b_valid
)
4097 msg_Warn( p_demux
, "pmt error: pid=%d already defined",
4102 for( p_dr
= p_es
->p_first_descriptor
; p_dr
!= NULL
;
4103 p_dr
= p_dr
->p_next
)
4105 msg_Dbg( p_demux
, " * es pid=%d type=%d dr->i_tag=0x%x",
4106 p_es
->i_pid
, p_es
->i_type
, p_dr
->i_tag
);
4109 PIDInit( pid
, false, pmt
->psi
);
4110 PIDFillFormat( pid
, p_es
->i_type
);
4111 pid
->i_owner_number
= prg
->i_number
;
4112 pid
->i_pid
= p_es
->i_pid
;
4113 pid
->b_seen
= p_sys
->pid
[p_es
->i_pid
].b_seen
;
4115 if( p_es
->i_type
== 0x10 || p_es
->i_type
== 0x11 ||
4116 p_es
->i_type
== 0x12 || p_es
->i_type
== 0x0f )
4118 PMTSetupEsISO14496( p_demux
, pid
, prg
, p_es
);
4120 else if( p_es
->i_type
== 0x06 )
4122 PMTSetupEs0x06( p_demux
, pid
, p_es
);
4124 else if( p_es
->i_type
== 0xEA )
4126 PMTSetupEs0xEA( p_demux
, pid
, p_es
);
4128 else if( p_es
->i_type
== 0xd1 )
4130 PMTSetupEs0xD1( p_demux
, pid
, p_es
);
4132 else if( p_es
->i_type
== 0xa0 )
4134 PMTSetupEs0xA0( p_demux
, pid
, p_es
);
4138 PMTSetupEsHDMV( p_demux
, pid
, p_es
);
4140 else if( p_es
->i_type
>= 0x80 )
4142 PMTSetupEsRegistration( p_demux
, pid
, p_es
);
4145 if( pid
->es
->fmt
.i_cat
== AUDIO_ES
||
4146 ( pid
->es
->fmt
.i_cat
== SPU_ES
&&
4147 pid
->es
->fmt
.i_codec
!= VLC_CODEC_DVBS
&&
4148 pid
->es
->fmt
.i_codec
!= VLC_CODEC_TELETEXT
) )
4150 PMTParseEsIso639( p_demux
, pid
, p_es
);
4153 pid
->es
->fmt
.i_group
= p_pmt
->i_program_number
;
4154 for( int i
= 0; i
< pid
->i_extra_es
; i
++ )
4155 pid
->extra_es
[i
]->fmt
.i_group
= p_pmt
->i_program_number
;
4157 if( pid
->es
->fmt
.i_cat
== UNKNOWN_ES
)
4159 msg_Dbg( p_demux
, " * es pid=%d type=%d *unknown*",
4160 p_es
->i_pid
, p_es
->i_type
);
4162 else if( !p_sys
->b_udp_out
)
4164 msg_Dbg( p_demux
, " * es pid=%d type=%d fcc=%4.4s",
4165 p_es
->i_pid
, p_es
->i_type
, (char*)&pid
->es
->fmt
.i_codec
);
4167 if( p_sys
->b_es_id_pid
) pid
->es
->fmt
.i_id
= p_es
->i_pid
;
4169 /* Check if we can avoid restarting the ES */
4171 pid
->es
->fmt
.i_codec
== old_pid
->es
->fmt
.i_codec
&&
4172 pid
->es
->fmt
.i_extra
== old_pid
->es
->fmt
.i_extra
&&
4173 pid
->es
->fmt
.i_extra
== 0 &&
4174 pid
->i_extra_es
== old_pid
->i_extra_es
&&
4175 ( ( !pid
->es
->fmt
.psz_language
&&
4176 !old_pid
->es
->fmt
.psz_language
) ||
4177 ( pid
->es
->fmt
.psz_language
&&
4178 old_pid
->es
->fmt
.psz_language
&&
4179 !strcmp( pid
->es
->fmt
.psz_language
,
4180 old_pid
->es
->fmt
.psz_language
) ) ) )
4182 pid
->es
->id
= old_pid
->es
->id
;
4183 old_pid
->es
->id
= NULL
;
4184 for( int i
= 0; i
< pid
->i_extra_es
; i
++ )
4186 pid
->extra_es
[i
]->id
= old_pid
->extra_es
[i
]->id
;
4187 old_pid
->extra_es
[i
]->id
= NULL
;
4194 PIDClean( p_demux
, old_pid
);
4195 TAB_REMOVE( i_clean
, pp_clean
, old_pid
);
4199 pid
->es
->id
= es_out_Add( p_demux
->out
, &pid
->es
->fmt
);
4200 for( int i
= 0; i
< pid
->i_extra_es
; i
++ )
4202 pid
->extra_es
[i
]->id
=
4203 es_out_Add( p_demux
->out
, &pid
->extra_es
[i
]->fmt
);
4205 p_sys
->i_pmt_es
+= 1 + pid
->i_extra_es
;
4209 /* Add ES to the list */
4212 PIDClean( p_demux
, old_pid
);
4213 TAB_REMOVE( i_clean
, pp_clean
, old_pid
);
4215 p_sys
->pid
[p_es
->i_pid
] = *pid
;
4217 p_dr
= PMTEsFindDescriptor( p_es
, 0x09 );
4218 if( p_dr
&& p_dr
->i_length
>= 2 )
4220 uint16_t i_sysid
= (p_dr
->p_data
[0] << 8) | p_dr
->p_data
[1];
4221 msg_Dbg( p_demux
, " * descriptor : CA (0x9) SysID 0x%x",
4225 if( ProgramIsSelected( p_demux
, prg
->i_number
) &&
4226 ( pid
->es
->id
!= NULL
|| p_sys
->b_udp_out
) )
4228 /* Set demux filter */
4229 stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
4230 ACCESS_SET_PRIVATE_ID_STATE
, p_es
->i_pid
,
4235 /* Set CAM descrambling */
4236 if( !ProgramIsSelected( p_demux
, prg
->i_number
)
4237 || stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
4238 ACCESS_SET_PRIVATE_ID_CA
, p_pmt
) != VLC_SUCCESS
)
4239 dvbpsi_DeletePMT( p_pmt
);
4241 for( int i
= 0; i
< i_clean
; i
++ )
4243 if( ProgramIsSelected( p_demux
, prg
->i_number
) )
4245 stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
4246 ACCESS_SET_PRIVATE_ID_STATE
, pp_clean
[i
]->i_pid
,
4250 PIDClean( p_demux
, pp_clean
[i
] );
4256 static void PATCallBack( demux_t
*p_demux
, dvbpsi_pat_t
*p_pat
)
4258 demux_sys_t
*p_sys
= p_demux
->p_sys
;
4259 dvbpsi_pat_program_t
*p_program
;
4260 ts_pid_t
*pat
= &p_sys
->pid
[0];
4262 msg_Dbg( p_demux
, "PATCallBack called" );
4264 if( ( pat
->psi
->i_pat_version
!= -1 &&
4265 ( !p_pat
->b_current_next
||
4266 p_pat
->i_version
== pat
->psi
->i_pat_version
) ) ||
4269 dvbpsi_DeletePAT( p_pat
);
4273 msg_Dbg( p_demux
, "new PAT ts_id=%d version=%d current_next=%d",
4274 p_pat
->i_ts_id
, p_pat
->i_version
, p_pat
->b_current_next
);
4277 if( p_sys
->i_pmt
> 0 )
4280 ts_pid_t
**pmt_rm
= NULL
;
4282 /* Search pmt to be deleted */
4283 for( int i
= 0; i
< p_sys
->i_pmt
; i
++ )
4285 ts_pid_t
*pmt
= p_sys
->pmt
[i
];
4286 bool b_keep
= false;
4288 for( p_program
= p_pat
->p_first_program
; p_program
!= NULL
;
4289 p_program
= p_program
->p_next
)
4291 if( p_program
->i_pid
== pmt
->i_pid
)
4293 for( int i_prg
= 0; i_prg
< pmt
->psi
->i_prg
; i_prg
++ )
4295 if( p_program
->i_number
==
4296 pmt
->psi
->prg
[i_prg
]->i_number
)
4309 TAB_APPEND( i_pmt_rm
, pmt_rm
, pmt
);
4313 /* Delete all ES attached to thoses PMT */
4314 for( int i
= 2; i
< 8192; i
++ )
4316 ts_pid_t
*pid
= &p_sys
->pid
[i
];
4318 if( !pid
->b_valid
|| pid
->psi
)
4321 for( int j
= 0; j
< i_pmt_rm
&& pid
->b_valid
; j
++ )
4323 for( int i_prg
= 0; i_prg
< pid
->p_owner
->i_prg
; i_prg
++ )
4325 /* We only remove es that aren't defined by extra pmt */
4326 if( pid
->p_owner
->prg
[i_prg
]->i_pid_pmt
!= pmt_rm
[j
]->i_pid
)
4329 if( p_sys
->b_access_control
&& pid
->es
->id
)
4331 if( stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
4332 ACCESS_SET_PRIVATE_ID_STATE
, i
,
4334 p_sys
->b_access_control
= false;
4337 PIDClean( p_demux
, pid
);
4343 /* Delete PMT pid */
4344 for( int i
= 0; i
< i_pmt_rm
; i
++ )
4346 if( p_sys
->b_access_control
)
4348 if( stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
4349 ACCESS_SET_PRIVATE_ID_STATE
,
4350 pmt_rm
[i
]->i_pid
, false ) )
4351 p_sys
->b_access_control
= false;
4354 for( int i_prg
= 0; i_prg
< pmt_rm
[i
]->psi
->i_prg
; i_prg
++ )
4356 const int i_number
= pmt_rm
[i
]->psi
->prg
[i_prg
]->i_number
;
4357 es_out_Control( p_demux
->out
, ES_OUT_DEL_GROUP
, i_number
);
4360 PIDClean( p_demux
, &p_sys
->pid
[pmt_rm
[i
]->i_pid
] );
4361 TAB_REMOVE( p_sys
->i_pmt
, p_sys
->pmt
, pmt_rm
[i
] );
4367 /* now create programs */
4368 for( p_program
= p_pat
->p_first_program
; p_program
!= NULL
;
4369 p_program
= p_program
->p_next
)
4371 msg_Dbg( p_demux
, " * number=%d pid=%d", p_program
->i_number
,
4373 if( p_program
->i_number
!= 0 )
4375 ts_pid_t
*pmt
= &p_sys
->pid
[p_program
->i_pid
];
4378 ValidateDVBMeta( p_demux
, p_program
->i_pid
);
4383 for( i_prg
= 0; i_prg
< pmt
->psi
->i_prg
; i_prg
++ )
4385 if( pmt
->psi
->prg
[i_prg
]->i_number
== p_program
->i_number
)
4394 TAB_APPEND( p_sys
->i_pmt
, p_sys
->pmt
, pmt
);
4399 PIDInit( pmt
, true, pat
->psi
);
4400 pmt
->psi
->prg
[pmt
->psi
->i_prg
-1]->handle
=
4401 dvbpsi_AttachPMT( p_program
->i_number
,
4402 (dvbpsi_pmt_callback
)PMTCallBack
,
4404 pmt
->psi
->prg
[pmt
->psi
->i_prg
-1]->i_number
=
4405 p_program
->i_number
;
4406 pmt
->psi
->prg
[pmt
->psi
->i_prg
-1]->i_pid_pmt
=
4409 /* Now select PID at access level */
4410 if( p_sys
->b_access_control
)
4412 if( ProgramIsSelected( p_demux
, p_program
->i_number
) )
4414 if( p_sys
->i_current_program
== 0 )
4415 p_sys
->i_current_program
= p_program
->i_number
;
4417 if( stream_Control( p_demux
->s
, STREAM_CONTROL_ACCESS
,
4418 ACCESS_SET_PRIVATE_ID_STATE
,
4419 p_program
->i_pid
, true ) )
4420 p_sys
->b_access_control
= false;
4426 pat
->psi
->i_pat_version
= p_pat
->i_version
;
4428 dvbpsi_DeletePAT( p_pat
);