1 /*****************************************************************************
2 * ts.c: Transport Stream input module for VLC.
3 *****************************************************************************
4 * Copyright (C) 2004-2016 VLC authors and VideoLAN
5 * $Id: 3dbe5277569491bde5e9e3485934591ac5b91b56 $
6 *
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Jean-Paul Saman <jpsaman #_at_# m2x.nl>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
14 *
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 Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
24
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_access.h> /* DVB-specific things */
36 #include <vlc_demux.h>
37 #include <vlc_input.h>
38
39 #include "ts_pid.h"
40 #include "ts_streams.h"
41 #include "ts_streams_private.h"
42 #include "ts_psi.h"
43 #include "ts_si.h"
44 #include "ts_psip.h"
45
46 #include "ts_hotfixes.h"
47 #include "ts_sl.h"
48 #include "ts_metadata.h"
49 #include "sections.h"
50 #include "pes.h"
51 #include "timestamps.h"
52
53 #include "ts.h"
54
55 #include "../../codec/scte18.h"
56 #include "../opus.h"
57 #include "../../mux/mpeg/csa.h"
58
59 #ifdef HAVE_ARIBB24
60 #include <aribb24/aribb24.h>
61 #endif
62
63 #include <assert.h>
64
65 /*****************************************************************************
66 * Module descriptor
67 *****************************************************************************/
68 static int Open ( vlc_object_t * );
69 static void Close ( vlc_object_t * );
70
71 /* TODO
72 * - Rename "extra pmt" to "user pmt"
73 * - Update extra pmt description
74 * pmt_pid[:pmt_number][=pid_description[,pid_description]]
75 * where pid_description could take 3 forms:
76 * 1. pid:pcr (to force the pcr pid)
77 * 2. pid:stream_type
78 * 3. pid:type=fourcc where type=(video|audio|spu)
79 */
80 #define PMT_TEXT N_("Extra PMT")
81 #define PMT_LONGTEXT N_( \
82 "Allows a user to specify an extra pmt (pmt_pid=pid:stream_type[,...])." )
83
84 #define PID_TEXT N_("Set id of ES to PID")
85 #define PID_LONGTEXT N_("Set the internal ID of each elementary stream" \
86 " handled by VLC to the same value as the PID in" \
87 " the TS stream, instead of 1, 2, 3, etc. Useful to" \
88 " do \'#duplicate{..., select=\"es=<pid>\"}\'.")
89
90 #define CSA_TEXT N_("CSA Key")
91 #define CSA_LONGTEXT N_("CSA encryption key. This must be a " \
92 "16 char string (8 hexadecimal bytes).")
93
94 #define CSA2_TEXT N_("Second CSA Key")
95 #define CSA2_LONGTEXT N_("The even CSA encryption key. This must be a " \
96 "16 char string (8 hexadecimal bytes).")
97
98
99 #define CPKT_TEXT N_("Packet size in bytes to decrypt")
100 #define CPKT_LONGTEXT N_("Specify the size of the TS packet to decrypt. " \
101 "The decryption routines subtract the TS-header from the value before " \
102 "decrypting." )
103
104 #define SPLIT_ES_TEXT N_("Separate sub-streams")
105 #define SPLIT_ES_LONGTEXT N_( \
106 "Separate teletex/dvbs pages into independent ES. " \
107 "It can be useful to turn off this option when using stream output." )
108
109 #define SEEK_PERCENT_TEXT N_("Seek based on percent not time")
110 #define SEEK_PERCENT_LONGTEXT N_( \
111 "Seek and position based on a percent byte position, not a PCR generated " \
112 "time position. If seeking doesn't work property, turn on this option." )
113
114 #define CC_CHECK_TEXT "Check packets continuity counter"
115 #define CC_CHECK_LONGTEXT "Detect discontinuities and drop packet duplicates. " \
116 "(bluRay sources are known broken and have false positives). "
117
118 #define TS_PATFIX_TEXT "Try to generate PAT/PMT if missing"
119 #define TS_SKIP_GHOST_PROGRAM_TEXT "Only create ES on program sending data"
120 #define TS_OFFSETFIX_TEXT "Try to fix too early PCR (or late DTS)"
121
122 #define PCR_TEXT N_("Trust in-stream PCR")
123 #define PCR_LONGTEXT N_("Use the stream PCR as a reference.")
124
125 static const char *const ts_standards_list[] =
126 { "auto", "mpeg", "dvb", "arib", "atsc", "tdmb" };
127 static const char *const ts_standards_list_text[] =
128 { N_("Auto"), "MPEG", "DVB", "ARIB", "ATSC", "T-DMB" };
129
130 #define STANDARD_TEXT N_("Digital TV Standard")
131 #define STANDARD_LONGTEXT N_( "Selects mode for digital TV standard. " \
132 "This feature affects EPG information and subtitles." )
133
134 vlc_module_begin ()
135 set_description( N_("MPEG Transport Stream demuxer") )
136 set_shortname ( "MPEG-TS" )
137 set_category( CAT_INPUT )
138 set_subcategory( SUBCAT_INPUT_DEMUX )
139
140 add_string( "ts-standard", "auto", STANDARD_TEXT, STANDARD_LONGTEXT, true )
141 change_string_list( ts_standards_list, ts_standards_list_text )
142
143 add_string( "ts-extra-pmt", NULL, PMT_TEXT, PMT_LONGTEXT, true )
144 add_bool( "ts-trust-pcr", true, PCR_TEXT, PCR_LONGTEXT, true )
145 change_safe()
146 add_bool( "ts-es-id-pid", true, PID_TEXT, PID_LONGTEXT, true )
147 change_safe()
148 add_obsolete_string( "ts-out" ) /* since 2.2.0 */
149 add_obsolete_integer( "ts-out-mtu" ) /* since 2.2.0 */
150 add_string( "ts-csa-ck", NULL, CSA_TEXT, CSA_LONGTEXT, true )
151 change_safe()
152 add_string( "ts-csa2-ck", NULL, CSA2_TEXT, CSA2_LONGTEXT, true )
153 change_safe()
154 add_integer( "ts-csa-pkt", 188, CPKT_TEXT, CPKT_LONGTEXT, true )
155 change_safe()
156
157 add_bool( "ts-split-es", true, SPLIT_ES_TEXT, SPLIT_ES_LONGTEXT, false )
158 add_bool( "ts-seek-percent", false, SEEK_PERCENT_TEXT, SEEK_PERCENT_LONGTEXT, true )
159 add_bool( "ts-cc-check", true, CC_CHECK_TEXT, CC_CHECK_LONGTEXT, true )
160 add_bool( "ts-pmtfix-waitdata", true, TS_SKIP_GHOST_PROGRAM_TEXT, NULL, true )
161 add_bool( "ts-patfix", true, TS_PATFIX_TEXT, NULL, true )
162 add_bool( "ts-pcr-offsetfix", true, TS_OFFSETFIX_TEXT, NULL, true )
163
164 add_obsolete_bool( "ts-silent" );
165
166 set_capability( "demux", 10 )
167 set_callbacks( Open, Close )
168 add_shortcut( "ts" )
169 vlc_module_end ()
170
171 /*****************************************************************************
172 * Local prototypes
173 *****************************************************************************/
174 static int Demux ( demux_t *p_demux );
175 static int Control( demux_t *p_demux, int i_query, va_list args );
176
177 static int ChangeKeyCallback( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );
178
179 /* Helpers */
180 static bool PIDReferencedByProgram( const ts_pmt_t *, uint16_t );
181 void UpdatePESFilters( demux_t *p_demux, bool b_all );
182 static inline void FlushESBuffer( ts_stream_t *p_pes );
183 static void UpdatePIDScrambledState( demux_t *p_demux, ts_pid_t *p_pid, bool );
PIDGet(block_t * p)184 static inline int PIDGet( block_t *p )
185 {
186 return ( (p->p_buffer[1]&0x1f)<<8 )|p->p_buffer[2];
187 }
188 static mtime_t GetPCR( const block_t * );
189
190 static block_t * ProcessTSPacket( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, int * );
191 static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk, size_t );
192 static bool GatherSectionsData( demux_t *p_demux, ts_pid_t *, block_t *, size_t );
193 static void ProgramSetPCR( demux_t *p_demux, ts_pmt_t *p_prg, mtime_t i_pcr );
194
195 static block_t* ReadTSPacket( demux_t *p_demux );
196 static int SeekToTime( demux_t *p_demux, const ts_pmt_t *, int64_t time );
197 static void ReadyQueuesPostSeek( demux_t *p_demux );
198 static void PCRHandle( demux_t *p_demux, ts_pid_t *, mtime_t );
199 static void PCRFixHandle( demux_t *, ts_pmt_t *, block_t * );
200
201 #define TS_PACKET_SIZE_188 188
202 #define TS_PACKET_SIZE_192 192
203 #define TS_PACKET_SIZE_204 204
204 #define TS_PACKET_SIZE_MAX 204
205 #define TS_HEADER_SIZE 4
206
207 #define PROBE_CHUNK_COUNT 500
208 #define PROBE_MAX (PROBE_CHUNK_COUNT * 10)
209
DetectPacketSize(demux_t * p_demux,unsigned * pi_header_size,int i_offset)210 static int DetectPacketSize( demux_t *p_demux, unsigned *pi_header_size, int i_offset )
211 {
212 const uint8_t *p_peek;
213
214 if( vlc_stream_Peek( p_demux->s,
215 &p_peek, i_offset + TS_PACKET_SIZE_MAX ) < i_offset + TS_PACKET_SIZE_MAX )
216 return -1;
217
218 for( int i_sync = 0; i_sync < TS_PACKET_SIZE_MAX; i_sync++ )
219 {
220 if( p_peek[i_offset + i_sync] != 0x47 )
221 continue;
222
223 /* Check next 3 sync bytes */
224 int i_peek = i_offset + TS_PACKET_SIZE_MAX * 3 + i_sync + 1;
225 if( ( vlc_stream_Peek( p_demux->s, &p_peek, i_peek ) ) < i_peek )
226 {
227 msg_Dbg( p_demux, "cannot peek" );
228 return -1;
229 }
230 if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_188] == 0x47 &&
231 p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_188] == 0x47 &&
232 p_peek[i_offset + i_sync + 3 * TS_PACKET_SIZE_188] == 0x47 )
233 {
234 return TS_PACKET_SIZE_188;
235 }
236 else if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_192] == 0x47 &&
237 p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_192] == 0x47 &&
238 p_peek[i_offset + i_sync + 3 * TS_PACKET_SIZE_192] == 0x47 )
239 {
240 if( i_sync == 4 )
241 {
242 *pi_header_size = 4; /* BluRay TS packets have 4-byte header */
243 }
244 return TS_PACKET_SIZE_192;
245 }
246 else if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_204] == 0x47 &&
247 p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_204] == 0x47 &&
248 p_peek[i_offset + i_sync + 3 * TS_PACKET_SIZE_204] == 0x47 )
249 {
250 return TS_PACKET_SIZE_204;
251 }
252 }
253
254 if( p_demux->obj.force )
255 {
256 msg_Warn( p_demux, "this does not look like a TS stream, continuing" );
257 return TS_PACKET_SIZE_188;
258 }
259 msg_Dbg( p_demux, "TS module discarded (lost sync)" );
260 return -1;
261 }
262
263 #define TOPFIELD_HEADER_SIZE 3712
264
DetectPVRHeadersAndHeaderSize(demux_t * p_demux,unsigned * pi_header_size,vdr_info_t * p_vdr)265 static int DetectPVRHeadersAndHeaderSize( demux_t *p_demux, unsigned *pi_header_size, vdr_info_t *p_vdr )
266 {
267 const uint8_t *p_peek;
268 *pi_header_size = 0;
269 int i_packet_size = -1;
270
271 if( vlc_stream_Peek( p_demux->s,
272 &p_peek, TS_PACKET_SIZE_MAX ) < TS_PACKET_SIZE_MAX )
273 return -1;
274
275 if( memcmp( p_peek, "TFrc", 4 ) == 0 && p_peek[6] == 0 &&
276 vlc_stream_Peek( p_demux->s, &p_peek, TOPFIELD_HEADER_SIZE + TS_PACKET_SIZE_MAX )
277 == TOPFIELD_HEADER_SIZE + TS_PACKET_SIZE_MAX )
278 {
279 const int i_service = GetWBE(&p_peek[18]);
280 i_packet_size = DetectPacketSize( p_demux, pi_header_size, TOPFIELD_HEADER_SIZE );
281 if( i_packet_size != -1 )
282 {
283 msg_Dbg( p_demux, "this is a topfield file" );
284 #if 0
285 /* I used the TF5000PVR 2004 Firmware .doc header documentation,
286 * /doc/Structure%20of%20Recorded%20File%20in%20TF5000PVR%20(Feb%2021%202004).doc on streams.vo
287 * but after the filename the offsets seem to be incorrect. - DJ */
288 int i_duration, i_name;
289 char *psz_name = xmalloc(25);
290 char *psz_event_name;
291 char *psz_event_text = xmalloc(130);
292 char *psz_ext_text = xmalloc(1025);
293
294 // 2 bytes version Uimsbf (4,5)
295 // 2 bytes reserved (6,7)
296 // 2 bytes duration in minutes Uimsbf (8,9(
297 i_duration = (int) (p_peek[8] << 8) | p_peek[9];
298 msg_Dbg( p_demux, "Topfield recording length: +/- %d minutes", i_duration);
299 // 2 bytes service number in channel list (10, 11)
300 // 2 bytes service type Bslbf 0=TV 1=Radio Bslb (12, 13)
301 // 4 bytes of reserved + tuner info (14,15,16,17)
302 // 2 bytes of Service ID Bslbf (18,19)
303 // 2 bytes of PMT PID Uimsbf (20,21)
304 // 2 bytes of PCR PID Uimsbf (22,23)
305 // 2 bytes of Video PID Uimsbf (24,25)
306 // 2 bytes of Audio PID Uimsbf (26,27)
307 // 24 bytes filename Bslbf
308 memcpy( psz_name, &p_peek[28], 24 );
309 psz_name[24] = '\0';
310 msg_Dbg( p_demux, "recordingname=%s", psz_name );
311 // 1 byte of sat index Uimsbf (52)
312 // 3 bytes (1 bit of polarity Bslbf +23 bits reserved)
313 // 4 bytes of freq. Uimsbf (56,57,58,59)
314 // 2 bytes of symbol rate Uimsbf (60,61)
315 // 2 bytes of TS stream ID Uimsbf (62,63)
316 // 4 bytes reserved
317 // 2 bytes reserved
318 // 2 bytes duration Uimsbf (70,71)
319 //i_duration = (int) (p_peek[70] << 8) | p_peek[71];
320 //msg_Dbg( p_demux, "Topfield 2nd duration field: +/- %d minutes", i_duration);
321 // 4 bytes EventID Uimsbf (72-75)
322 // 8 bytes of Start and End time info (76-83)
323 // 1 byte reserved (84)
324 // 1 byte event name length Uimsbf (89)
325 i_name = (int)(p_peek[89]&~0x81);
326 msg_Dbg( p_demux, "event name length = %d", i_name);
327 psz_event_name = xmalloc( i_name+1 );
328 // 1 byte parental rating (90)
329 // 129 bytes of event text
330 memcpy( psz_event_name, &p_peek[91], i_name );
331 psz_event_name[i_name] = '\0';
332 memcpy( psz_event_text, &p_peek[91+i_name], 129-i_name );
333 psz_event_text[129-i_name] = '\0';
334 msg_Dbg( p_demux, "event name=%s", psz_event_name );
335 msg_Dbg( p_demux, "event text=%s", psz_event_text );
336 // 12 bytes reserved (220)
337 // 6 bytes reserved
338 // 2 bytes Event Text Length Uimsbf
339 // 4 bytes EventID Uimsbf
340 // FIXME We just have 613 bytes. not enough for this entire text
341 // 1024 bytes Extended Event Text Bslbf
342 memcpy( psz_ext_text, p_peek+372, 1024 );
343 psz_ext_text[1024] = '\0';
344 msg_Dbg( p_demux, "extended event text=%s", psz_ext_text );
345 // 52 bytes reserved Bslbf
346 #endif
347 p_vdr->i_service = i_service;
348
349 return i_packet_size;
350 //return TS_PACKET_SIZE_188;
351 }
352 }
353
354 return DetectPacketSize( p_demux, pi_header_size, 0 );
355 }
356
357 /*****************************************************************************
358 * Open
359 *****************************************************************************/
Open(vlc_object_t * p_this)360 static int Open( vlc_object_t *p_this )
361 {
362 demux_t *p_demux = (demux_t*)p_this;
363 demux_sys_t *p_sys;
364
365 int i_packet_size;
366 unsigned i_packet_header_size = 0;
367
368 ts_pid_t *patpid;
369 vdr_info_t vdr = {0};
370
371 /* Search first sync byte */
372 i_packet_size = DetectPVRHeadersAndHeaderSize( p_demux, &i_packet_header_size, &vdr );
373 if( i_packet_size < 0 )
374 return VLC_EGENERIC;
375
376 p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
377 if( !p_sys )
378 return VLC_ENOMEM;
379 memset( p_sys, 0, sizeof( demux_sys_t ) );
380 vlc_mutex_init( &p_sys->csa_lock );
381
382 p_demux->pf_demux = Demux;
383 p_demux->pf_control = Control;
384
385 /* Init p_sys field */
386 p_sys->b_end_preparse = false;
387 ARRAY_INIT( p_sys->programs );
388 p_sys->b_default_selection = false;
389 p_sys->i_network_time = 0;
390 p_sys->i_network_time_update = 0;
391
392 p_sys->vdr = vdr;
393
394 p_sys->arib.b25stream = NULL;
395 p_sys->stream = p_demux->s;
396
397 p_sys->b_broken_charset = false;
398
399 ts_pid_list_Init( &p_sys->pids );
400
401 p_sys->i_packet_size = i_packet_size;
402 p_sys->i_packet_header_size = i_packet_header_size;
403 p_sys->i_ts_read = 50;
404 p_sys->csa = NULL;
405 p_sys->b_start_record = false;
406
407 vlc_dictionary_init( &p_sys->attachments, 0 );
408
409 p_sys->patfix.i_first_dts = -1;
410 p_sys->patfix.i_timesourcepid = 0;
411 p_sys->patfix.status = var_CreateGetBool( p_demux, "ts-patfix" ) ? PAT_WAITING : PAT_FIXTRIED;
412
413 /* Init PAT handler */
414 patpid = GetPID(p_sys, 0);
415 if ( !PIDSetup( p_demux, TYPE_PAT, patpid, NULL ) )
416 {
417 vlc_mutex_destroy( &p_sys->csa_lock );
418 free( p_sys );
419 return VLC_ENOMEM;
420 }
421 if( !ts_psi_PAT_Attach( patpid, p_demux ) )
422 {
423 PIDRelease( p_demux, patpid );
424 vlc_mutex_destroy( &p_sys->csa_lock );
425 free( p_sys );
426 return VLC_EGENERIC;
427 }
428
429 p_sys->b_access_control = true;
430 p_sys->b_access_control = ( VLC_SUCCESS == SetPIDFilter( p_sys, patpid, true ) );
431
432 p_sys->i_pmt_es = 0;
433 p_sys->seltype = PROGRAM_AUTO_DEFAULT;
434
435 /* Read config */
436 p_sys->b_es_id_pid = var_CreateGetBool( p_demux, "ts-es-id-pid" );
437 p_sys->i_next_extraid = 1;
438
439 p_sys->b_trust_pcr = var_CreateGetBool( p_demux, "ts-trust-pcr" );
440 p_sys->b_check_pcr_offset = p_sys->b_trust_pcr && var_CreateGetBool(p_demux, "ts-pcr-offsetfix" );
441
442 /* We handle description of an extra PMT */
443 char* psz_string = var_CreateGetString( p_demux, "ts-extra-pmt" );
444 p_sys->b_user_pmt = false;
445 if( psz_string && *psz_string )
446 UserPmt( p_demux, psz_string );
447 free( psz_string );
448
449 psz_string = var_CreateGetStringCommand( p_demux, "ts-csa-ck" );
450 if( psz_string && *psz_string )
451 {
452 int i_res;
453 char* psz_csa2;
454
455 p_sys->csa = csa_New();
456
457 psz_csa2 = var_CreateGetStringCommand( p_demux, "ts-csa2-ck" );
458 i_res = csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, psz_string, true );
459 if( i_res == VLC_SUCCESS && psz_csa2 && *psz_csa2 )
460 {
461 if( csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, psz_csa2, false ) != VLC_SUCCESS )
462 {
463 csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, psz_string, false );
464 }
465 }
466 else if ( i_res == VLC_SUCCESS )
467 {
468 csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, psz_string, false );
469 }
470 else
471 {
472 csa_Delete( p_sys->csa );
473 p_sys->csa = NULL;
474 }
475
476 if( p_sys->csa )
477 {
478 var_AddCallback( p_demux, "ts-csa-ck", ChangeKeyCallback, (void *)1 );
479 var_AddCallback( p_demux, "ts-csa2-ck", ChangeKeyCallback, NULL );
480
481 int i_pkt = var_CreateGetInteger( p_demux, "ts-csa-pkt" );
482 if( i_pkt < 4 || i_pkt > 188 )
483 {
484 msg_Err( p_demux, "wrong packet size %d specified.", i_pkt );
485 msg_Warn( p_demux, "using default packet size of 188 bytes" );
486 p_sys->i_csa_pkt_size = 188;
487 }
488 else
489 p_sys->i_csa_pkt_size = i_pkt;
490 msg_Dbg( p_demux, "decrypting %d bytes of packet", p_sys->i_csa_pkt_size );
491 }
492 free( psz_csa2 );
493 }
494 free( psz_string );
495
496 p_sys->b_split_es = var_InheritBool( p_demux, "ts-split-es" );
497
498 p_sys->b_canseek = false;
499 p_sys->b_canfastseek = false;
500 p_sys->b_ignore_time_for_positions = var_InheritBool( p_demux, "ts-seek-percent" );
501 p_sys->b_cc_check = var_InheritBool( p_demux, "ts-cc-check" );
502
503 p_sys->standard = TS_STANDARD_AUTO;
504 char *psz_standard = var_InheritString( p_demux, "ts-standard" );
505 if( psz_standard )
506 {
507 for( unsigned i=0; i<ARRAY_SIZE(ts_standards_list); i++ )
508 {
509 if( !strcmp( psz_standard, ts_standards_list[i] ) )
510 {
511 TsChangeStandard( p_sys, TS_STANDARD_AUTO + i );
512 msg_Dbg( p_demux, "Standard set to %s", ts_standards_list_text[i] );
513 break;
514 }
515 }
516 free( psz_standard );
517 }
518
519 if( p_sys->standard == TS_STANDARD_AUTO &&
520 ( !strcmp( p_demux->psz_access, "atsc" ) ||
521 !strcmp( p_demux->psz_access, "usdigital" ) ) )
522 {
523 TsChangeStandard( p_sys, TS_STANDARD_ATSC );
524 }
525
526 vlc_stream_Control( p_sys->stream, STREAM_CAN_SEEK, &p_sys->b_canseek );
527 vlc_stream_Control( p_sys->stream, STREAM_CAN_FASTSEEK,
528 &p_sys->b_canfastseek );
529
530 if( !p_sys->b_access_control && var_CreateGetBool( p_demux, "ts-pmtfix-waitdata" ) )
531 p_sys->es_creation = DELAY_ES;
532 else
533 p_sys->es_creation = CREATE_ES;
534
535 /* Preparse time */
536 if( p_demux->b_preparsing && p_sys->b_canseek )
537 {
538 while( !p_sys->i_pmt_es && !p_sys->b_end_preparse )
539 if( Demux( p_demux ) != VLC_DEMUXER_SUCCESS )
540 break;
541 }
542
543 return VLC_SUCCESS;
544 }
545
546 /*****************************************************************************
547 * Close
548 *****************************************************************************/
FreeDictAttachment(void * p_value,void * p_obj)549 static void FreeDictAttachment( void *p_value, void *p_obj )
550 {
551 VLC_UNUSED(p_obj);
552 vlc_input_attachment_Delete( (input_attachment_t *) p_value );
553 }
554
Close(vlc_object_t * p_this)555 static void Close( vlc_object_t *p_this )
556 {
557 demux_t *p_demux = (demux_t*)p_this;
558 demux_sys_t *p_sys = p_demux->p_sys;
559
560 PIDRelease( p_demux, GetPID(p_sys, 0) );
561
562 vlc_mutex_lock( &p_sys->csa_lock );
563 if( p_sys->csa )
564 {
565 var_DelCallback( p_demux, "ts-csa-ck", ChangeKeyCallback, (void *)1 );
566 var_DelCallback( p_demux, "ts-csa2-ck", ChangeKeyCallback, NULL );
567 csa_Delete( p_sys->csa );
568 }
569 vlc_mutex_unlock( &p_sys->csa_lock );
570
571 ARRAY_RESET( p_sys->programs );
572
573 #ifdef HAVE_ARIBB24
574 if ( p_sys->arib.p_instance )
575 arib_instance_destroy( p_sys->arib.p_instance );
576 #endif
577
578 if ( p_sys->arib.b25stream )
579 {
580 p_sys->arib.b25stream->p_source = NULL; /* don't chain kill demuxer's source */
581 vlc_stream_Delete( p_sys->arib.b25stream );
582 }
583
584 vlc_mutex_destroy( &p_sys->csa_lock );
585
586 /* Release all non default pids */
587 ts_pid_list_Release( p_demux, &p_sys->pids );
588
589 /* Clear up attachments */
590 vlc_dictionary_clear( &p_sys->attachments, FreeDictAttachment, NULL );
591
592 free( p_sys );
593 }
594
595 /*****************************************************************************
596 * ChangeKeyCallback: called when changing the odd encryption key on the fly.
597 *****************************************************************************/
ChangeKeyCallback(vlc_object_t * p_this,char const * psz_cmd,vlc_value_t oldval,vlc_value_t newval,void * p_data)598 static int ChangeKeyCallback( vlc_object_t *p_this, char const *psz_cmd,
599 vlc_value_t oldval, vlc_value_t newval,
600 void *p_data )
601 {
602 VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
603 demux_t *p_demux = (demux_t*)p_this;
604 demux_sys_t *p_sys = p_demux->p_sys;
605 int i_tmp = (intptr_t)p_data;
606
607 vlc_mutex_lock( &p_sys->csa_lock );
608 if ( i_tmp )
609 i_tmp = csa_SetCW( p_this, p_sys->csa, newval.psz_string, true );
610 else
611 i_tmp = csa_SetCW( p_this, p_sys->csa, newval.psz_string, false );
612
613 vlc_mutex_unlock( &p_sys->csa_lock );
614 return i_tmp;
615 }
616
617 /*****************************************************************************
618 * Demux:
619 *****************************************************************************/
Demux(demux_t * p_demux)620 static int Demux( demux_t *p_demux )
621 {
622 demux_sys_t *p_sys = p_demux->p_sys;
623 bool b_wait_es = p_sys->i_pmt_es <= 0;
624
625 /* If we had no PAT within MIN_PAT_INTERVAL, create PAT/PMT from probed streams */
626 if( p_sys->i_pmt_es == 0 && !SEEN(GetPID(p_sys, 0)) && p_sys->patfix.status == PAT_MISSING )
627 {
628 MissingPATPMTFixup( p_demux );
629 p_sys->patfix.status = PAT_FIXTRIED;
630 GetPID(p_sys, 0)->u.p_pat->b_generated = true;
631 }
632
633 /* We read at most 100 TS packet or until a frame is completed */
634 for( unsigned i_pkt = 0; i_pkt < p_sys->i_ts_read; i_pkt++ )
635 {
636 bool b_frame = false;
637 int i_header = 0;
638 block_t *p_pkt;
639 if( !(p_pkt = ReadTSPacket( p_demux )) )
640 {
641 return VLC_DEMUXER_EOF;
642 }
643
644 if( p_sys->b_start_record )
645 {
646 /* Enable recording once synchronized */
647 vlc_stream_Control( p_sys->stream, STREAM_SET_RECORD_STATE, true,
648 "ts" );
649 p_sys->b_start_record = false;
650 }
651
652 /* Early reject truncated packets from hw devices */
653 if( unlikely(p_pkt->i_buffer < TS_PACKET_SIZE_188) )
654 {
655 block_Release( p_pkt );
656 continue;
657 }
658
659 /* Reject any fully uncorrected packet. Even PID can be incorrect */
660 if( p_pkt->p_buffer[1]&0x80 )
661 {
662 msg_Dbg( p_demux, "transport_error_indicator set (pid=%d)",
663 PIDGet( p_pkt ) );
664 block_Release( p_pkt );
665 continue;
666 }
667
668 /* Parse the TS packet */
669 ts_pid_t *p_pid = GetPID( p_sys, PIDGet( p_pkt ) );
670 if( !SEEN(p_pid) )
671 {
672 if( p_pid->type == TYPE_FREE )
673 msg_Dbg( p_demux, "pid[%d] unknown", p_pid->i_pid );
674 p_pid->i_flags |= FLAG_SEEN;
675 if( p_pid->i_pid == 0x01 )
676 p_sys->b_valid_scrambling = true;
677 }
678
679 /* Drop duplicates and invalid (DOES NOT drop corrupted) */
680 p_pkt = ProcessTSPacket( p_demux, p_pid, p_pkt, &i_header );
681 if( !p_pkt )
682 continue;
683
684 if( !SCRAMBLED(*p_pid) != !(p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) )
685 {
686 UpdatePIDScrambledState( p_demux, p_pid, p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED );
687 }
688
689 /* Adaptation field cannot be scrambled */
690 mtime_t i_pcr = GetPCR( p_pkt );
691 if( i_pcr > VLC_TS_INVALID )
692 PCRHandle( p_demux, p_pid, i_pcr );
693
694 /* Probe streams to build PAT/PMT after MIN_PAT_INTERVAL in case we don't see any PAT */
695 if( !SEEN( GetPID( p_sys, 0 ) ) &&
696 (p_pid->probed.i_fourcc == 0 || p_pid->i_pid == p_sys->patfix.i_timesourcepid) &&
697 (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* Payload start but not corrupt */
698 (p_pkt->p_buffer[3] & 0xD0) == 0x10 ) /* Has payload but is not encrypted */
699 {
700 ProbePES( p_demux, p_pid, p_pkt->p_buffer + TS_HEADER_SIZE,
701 p_pkt->i_buffer - TS_HEADER_SIZE, p_pkt->p_buffer[3] & 0x20 /* Adaptation field */);
702 }
703
704 switch( p_pid->type )
705 {
706 case TYPE_PAT:
707 case TYPE_PMT:
708 /* PAT and PMT are not allowed to be scrambled */
709 ts_psi_Packet_Push( p_pid, p_pkt->p_buffer );
710 block_Release( p_pkt );
711 break;
712
713 case TYPE_STREAM:
714 p_sys->b_end_preparse = true;
715
716 if( p_sys->es_creation == DELAY_ES ) /* No longer delay ES since that pid's program sends data */
717 {
718 msg_Dbg( p_demux, "Creating delayed ES" );
719 AddAndCreateES( p_demux, p_pid, true );
720 UpdatePESFilters( p_demux, p_demux->p_sys->seltype == PROGRAM_ALL );
721 }
722
723 /* Emulate HW filter */
724 if( !p_sys->b_access_control && !(p_pid->i_flags & FLAG_FILTERED) )
725 {
726 /* That packet is for an unselected ES, don't waste time/memory gathering its data */
727 block_Release( p_pkt );
728 continue;
729 }
730
731 if( p_pid->u.p_stream->transport == TS_TRANSPORT_PES )
732 {
733 b_frame = GatherPESData( p_demux, p_pid, p_pkt, i_header );
734 }
735 else if( p_pid->u.p_stream->transport == TS_TRANSPORT_SECTIONS )
736 {
737 b_frame = GatherSectionsData( p_demux, p_pid, p_pkt, i_header );
738 }
739 else // pid->u.p_pes->transport == TS_TRANSPORT_IGNORE
740 {
741 block_Release( p_pkt );
742 }
743
744 break;
745
746 case TYPE_SI:
747 if( (p_pkt->i_flags & (BLOCK_FLAG_SCRAMBLED|BLOCK_FLAG_CORRUPTED)) == 0 )
748 ts_si_Packet_Push( p_pid, p_pkt->p_buffer );
749 block_Release( p_pkt );
750 break;
751
752 case TYPE_PSIP:
753 if( (p_pkt->i_flags & (BLOCK_FLAG_SCRAMBLED|BLOCK_FLAG_CORRUPTED)) == 0 )
754 ts_psip_Packet_Push( p_pid, p_pkt->p_buffer );
755 block_Release( p_pkt );
756 break;
757
758 case TYPE_CAT:
759 default:
760 /* We have to handle PCR if present */
761 block_Release( p_pkt );
762 break;
763 }
764
765 if( b_frame || ( b_wait_es && p_sys->i_pmt_es > 0 ) )
766 break;
767 }
768
769 demux_UpdateTitleFromStream( p_demux );
770 return VLC_DEMUXER_SUCCESS;
771 }
772
773 /*****************************************************************************
774 * Control:
775 *****************************************************************************/
EITCurrentEventTime(const ts_pmt_t * p_pmt,demux_sys_t * p_sys,time_t * pi_time,time_t * pi_length)776 static int EITCurrentEventTime( const ts_pmt_t *p_pmt, demux_sys_t *p_sys,
777 time_t *pi_time, time_t *pi_length )
778 {
779 if( p_sys->i_network_time == 0 || !p_pmt || p_pmt->eit.i_event_length == 0 )
780 return VLC_EGENERIC;
781
782 if( p_pmt->eit.i_event_start <= p_sys->i_network_time &&
783 p_sys->i_network_time < p_pmt->eit.i_event_start + p_pmt->eit.i_event_length )
784 {
785 if( pi_length )
786 *pi_length = p_pmt->eit.i_event_length;
787 if( pi_time )
788 {
789 *pi_time = p_sys->i_network_time - p_pmt->eit.i_event_start;
790 *pi_time += time(NULL) - p_sys->i_network_time_update;
791 }
792 return VLC_SUCCESS;
793 }
794
795 return VLC_EGENERIC;
796 }
797
HasSelectedES(es_out_t * out,const ts_es_t * p_es,const ts_pmt_t * p_pmt,bool * pb_stream_selected)798 static inline void HasSelectedES( es_out_t *out, const ts_es_t *p_es,
799 const ts_pmt_t *p_pmt, bool *pb_stream_selected )
800 {
801 for( ; p_es && !*pb_stream_selected; p_es = p_es->p_next )
802 {
803 if( p_es->id )
804 es_out_Control( out, ES_OUT_GET_ES_STATE,
805 p_es->id, pb_stream_selected );
806 HasSelectedES( out, p_es->p_extraes, p_pmt, pb_stream_selected );
807 }
808 }
809
UpdatePESFilters(demux_t * p_demux,bool b_all)810 void UpdatePESFilters( demux_t *p_demux, bool b_all )
811 {
812 demux_sys_t *p_sys = p_demux->p_sys;
813 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
814
815 /* We need 3 pass to avoid loss on deselect/relesect with hw filters and
816 because pid could be shared and its state altered by another unselected pmt
817 First clear flag on every referenced pid
818 Then add flag if non on each selected pmt/pcr and active es
819 Then commit it at hardware level if any */
820
821 /* clear selection flag on every pmt referenced pid */
822 for( int i=0; i< p_pat->programs.i_size; i++ )
823 {
824 ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
825 ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
826
827 p_pmt_pid->i_flags &= ~FLAG_FILTERED;
828 for( int j=0; j< p_pmt->e_streams.i_size; j++ )
829 p_pmt->e_streams.p_elems[j]->i_flags &= ~FLAG_FILTERED;
830 GetPID(p_sys, p_pmt->i_pid_pcr)->i_flags &= ~FLAG_FILTERED;
831 }
832
833 /* set selection flag on selected pmt referenced pid with active es */
834 for( int i=0; i< p_pat->programs.i_size; i++ )
835 {
836 ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
837 ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
838
839 if( (p_sys->b_default_selection && !p_sys->b_access_control) || b_all )
840 p_pmt->b_selected = true;
841 else
842 p_pmt->b_selected = ProgramIsSelected( p_sys, p_pmt->i_number );
843
844 if( p_pmt->b_selected )
845 {
846 p_pmt_pid->i_flags |= FLAG_FILTERED;
847
848 for( int j=0; j<p_pmt->e_streams.i_size; j++ )
849 {
850 ts_pid_t *espid = p_pmt->e_streams.p_elems[j];
851 ts_stream_t *p_pes = espid->u.p_stream;
852
853 bool b_stream_selected = true;
854 if( !p_pes->b_always_receive && !b_all )
855 HasSelectedES( p_demux->out, p_pes->p_es, p_pmt, &b_stream_selected );
856
857 if( b_stream_selected )
858 {
859 msg_Dbg( p_demux, "enabling pid %d from program %d", espid->i_pid, p_pmt->i_number );
860 espid->i_flags |= FLAG_FILTERED;
861 }
862 }
863
864 /* Select pcr last in case it is handled by unselected ES */
865 if( p_pmt->i_pid_pcr > 0 )
866 {
867 GetPID(p_sys, p_pmt->i_pid_pcr)->i_flags |= FLAG_FILTERED;
868 msg_Dbg( p_demux, "enabling pcr pid %d from program %d", p_pmt->i_pid_pcr, p_pmt->i_number );
869 }
870 }
871 }
872
873 /* Commit HW changes based on flags */
874 for( int i=0; i< p_pat->programs.i_size; i++ )
875 {
876 ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
877 ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
878
879 UpdateHWFilter( p_sys, p_pmt_pid );
880 for( int j=0; j< p_pmt->e_streams.i_size; j++ )
881 {
882 ts_pid_t *espid = p_pmt->e_streams.p_elems[j];
883 UpdateHWFilter( p_sys, espid );
884 if( (espid->i_flags & FLAG_FILTERED) == 0 )
885 FlushESBuffer( espid->u.p_stream );
886 }
887 UpdateHWFilter( p_sys, GetPID(p_sys, p_pmt->i_pid_pcr) );
888 }
889 }
890
Control(demux_t * p_demux,int i_query,va_list args)891 static int Control( demux_t *p_demux, int i_query, va_list args )
892 {
893 demux_sys_t *p_sys = p_demux->p_sys;
894 double f, *pf;
895 bool b_bool, *pb_bool;
896 int64_t i64;
897 int64_t *pi64;
898 int i_int;
899 const ts_pmt_t *p_pmt = NULL;
900 const ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
901
902 for( int i=0; i<p_pat->programs.i_size && !p_pmt; i++ )
903 {
904 if( p_pat->programs.p_elems[i]->u.p_pmt->b_selected )
905 p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
906 }
907
908 switch( i_query )
909 {
910 case DEMUX_CAN_SEEK:
911 *va_arg( args, bool * ) = p_sys->b_canseek;
912 return VLC_SUCCESS;
913
914 case DEMUX_GET_POSITION:
915 pf = va_arg( args, double * );
916
917 /* Access control test is because EPG for recordings is not relevant */
918 if( p_sys->b_access_control )
919 {
920 time_t i_time, i_length;
921 if( !EITCurrentEventTime( p_pmt, p_sys, &i_time, &i_length ) && i_length > 0 )
922 {
923 *pf = (double)i_time/(double)i_length;
924 return VLC_SUCCESS;
925 }
926 }
927
928 if( !p_sys->b_ignore_time_for_positions &&
929 p_pmt &&
930 p_pmt->pcr.i_first > -1 && p_pmt->i_last_dts > VLC_TS_INVALID &&
931 p_pmt->pcr.i_current > -1 )
932 {
933 double i_length = TimeStampWrapAround( p_pmt->pcr.i_first,
934 p_pmt->i_last_dts ) - p_pmt->pcr.i_first;
935 i_length += p_pmt->pcr.i_pcroffset;
936 double i_pos = TimeStampWrapAround( p_pmt->pcr.i_first,
937 p_pmt->pcr.i_current ) - p_pmt->pcr.i_first;
938 if( i_length > 0 )
939 {
940 *pf = i_pos / i_length;
941 return VLC_SUCCESS;
942 }
943 }
944
945 if( (i64 = stream_Size( p_sys->stream) ) > 0 )
946 {
947 uint64_t offset = vlc_stream_Tell( p_sys->stream );
948 *pf = (double)offset / (double)i64;
949 return VLC_SUCCESS;
950 }
951 break;
952
953 case DEMUX_SET_POSITION:
954 f = va_arg( args, double );
955 b_bool = (bool) va_arg( args, int ); /* precise */
956
957 if(!p_sys->b_canseek)
958 break;
959
960 if( p_sys->b_access_control &&
961 !p_sys->b_ignore_time_for_positions && b_bool && p_pmt )
962 {
963 time_t i_time, i_length;
964 if( !EITCurrentEventTime( p_pmt, p_sys, &i_time, &i_length ) &&
965 i_length > 0 && !SeekToTime( p_demux, p_pmt, (int64_t)(TO_SCALE(i_length * CLOCK_FREQ) * f) ) )
966 {
967 ReadyQueuesPostSeek( p_demux );
968 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
969 (int64_t)(TO_SCALE(i_length * CLOCK_FREQ) * f) );
970 return VLC_SUCCESS;
971 }
972 }
973
974 if( !p_sys->b_ignore_time_for_positions && b_bool && p_pmt &&
975 p_pmt->pcr.i_first > -1 && p_pmt->i_last_dts > VLC_TS_INVALID &&
976 p_pmt->pcr.i_current > -1 )
977 {
978 int64_t i_length = TimeStampWrapAround( p_pmt->pcr.i_first,
979 p_pmt->i_last_dts ) - p_pmt->pcr.i_first;
980 i64 = p_pmt->pcr.i_first + (int64_t)(i_length * f);
981 if( i64 <= p_pmt->i_last_dts )
982 {
983 if( !SeekToTime( p_demux, p_pmt, i64 ) )
984 {
985 ReadyQueuesPostSeek( p_demux );
986 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, FROM_SCALE(i64) );
987 return VLC_SUCCESS;
988 }
989 }
990 }
991
992 i64 = stream_Size( p_sys->stream );
993 if( i64 > 0 &&
994 vlc_stream_Seek( p_sys->stream, (int64_t)(i64 * f) ) == VLC_SUCCESS )
995 {
996 ReadyQueuesPostSeek( p_demux );
997 return VLC_SUCCESS;
998 }
999 break;
1000
1001 case DEMUX_SET_TIME:
1002 i64 = va_arg( args, int64_t );
1003
1004 if( p_sys->b_canseek && p_pmt && p_pmt->pcr.i_first > -1 &&
1005 !SeekToTime( p_demux, p_pmt, p_pmt->pcr.i_first + TO_SCALE(i64) ) )
1006 {
1007 ReadyQueuesPostSeek( p_demux );
1008 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
1009 FROM_SCALE(p_pmt->pcr.i_first) + i64 - VLC_TS_0 );
1010 return VLC_SUCCESS;
1011 }
1012 break;
1013
1014 case DEMUX_GET_TIME:
1015 pi64 = va_arg( args, int64_t * );
1016
1017 if( p_sys->b_access_control )
1018 {
1019 time_t i_event_start;
1020 if( !EITCurrentEventTime( p_pmt, p_sys, &i_event_start, NULL ) )
1021 {
1022 *pi64 = i_event_start * CLOCK_FREQ;
1023 return VLC_SUCCESS;
1024 }
1025 }
1026
1027 if( p_pmt && p_pmt->pcr.i_current > -1 && p_pmt->pcr.i_first > -1 )
1028 {
1029 int64_t i_pcr = TimeStampWrapAround( p_pmt->pcr.i_first, p_pmt->pcr.i_current );
1030 *pi64 = FROM_SCALE(i_pcr - p_pmt->pcr.i_first);
1031 return VLC_SUCCESS;
1032 }
1033 break;
1034
1035 case DEMUX_GET_LENGTH:
1036 pi64 = va_arg( args, int64_t * );
1037
1038 if( p_sys->b_access_control )
1039 {
1040 time_t i_event_duration;
1041 if( !EITCurrentEventTime( p_pmt, p_sys, NULL, &i_event_duration ) )
1042 {
1043 *pi64 = i_event_duration * CLOCK_FREQ;
1044 return VLC_SUCCESS;
1045 }
1046 }
1047
1048 if( !p_sys->b_ignore_time_for_positions &&
1049 p_pmt &&
1050 ( p_pmt->pcr.i_first > -1 || p_pmt->pcr.i_first_dts > VLC_TS_INVALID ) &&
1051 p_pmt->i_last_dts > 0 )
1052 {
1053 int64_t i_start = (p_pmt->pcr.i_first > -1) ? p_pmt->pcr.i_first :
1054 TO_SCALE(p_pmt->pcr.i_first_dts);
1055 int64_t i_last = TimeStampWrapAround( p_pmt->pcr.i_first, p_pmt->i_last_dts );
1056 i_last += p_pmt->pcr.i_pcroffset;
1057 *pi64 = FROM_SCALE(i_last - i_start);
1058 return VLC_SUCCESS;
1059 }
1060 break;
1061
1062 case DEMUX_SET_GROUP:
1063 {
1064 vlc_list_t *p_list;
1065
1066 i_int = va_arg( args, int );
1067 p_list = va_arg( args, vlc_list_t * );
1068 msg_Dbg( p_demux, "DEMUX_SET_GROUP %d %p", i_int, (void *)p_list );
1069
1070 if( i_int != 0 ) /* If not default program */
1071 {
1072 /* Deselect/filter current ones */
1073 ARRAY_RESET( p_sys->programs );
1074
1075 if( i_int != -1 )
1076 {
1077 p_sys->seltype = PROGRAM_LIST;
1078 ARRAY_APPEND( p_sys->programs, i_int );
1079 UpdatePESFilters( p_demux, false );
1080 }
1081 else if( likely( p_list != NULL ) )
1082 {
1083 p_sys->seltype = PROGRAM_LIST;
1084 for( int i = 0; i < p_list->i_count; i++ )
1085 ARRAY_APPEND( p_sys->programs, p_list->p_values[i].i_int );
1086 UpdatePESFilters( p_demux, false );
1087 }
1088 else // All ES Mode
1089 {
1090 p_pat = GetPID(p_sys, 0)->u.p_pat;
1091 for( int i = 0; i < p_pat->programs.i_size; i++ )
1092 ARRAY_APPEND( p_sys->programs, p_pat->programs.p_elems[i]->i_pid );
1093 p_sys->seltype = PROGRAM_ALL;
1094 UpdatePESFilters( p_demux, true );
1095 }
1096
1097 p_sys->b_default_selection = false;
1098 }
1099 else if( !p_sys->b_default_selection )
1100 {
1101 ARRAY_RESET( p_sys->programs );
1102 p_sys->seltype = PROGRAM_AUTO_DEFAULT;
1103 }
1104
1105 return VLC_SUCCESS;
1106 }
1107
1108 case DEMUX_SET_ES:
1109 {
1110 i_int = va_arg( args, int );
1111 msg_Dbg( p_demux, "DEMUX_SET_ES %d", i_int );
1112
1113 if( p_demux->p_sys->seltype != PROGRAM_ALL ) /* Won't change anything */
1114 UpdatePESFilters( p_demux, false );
1115
1116 return VLC_SUCCESS;
1117 }
1118
1119 case DEMUX_GET_TITLE_INFO:
1120 {
1121 struct input_title_t ***v = va_arg( args, struct input_title_t*** );
1122 int *c = va_arg( args, int * );
1123
1124 *va_arg( args, int* ) = 0; /* Title offset */
1125 *va_arg( args, int* ) = 0; /* Chapter offset */
1126 return vlc_stream_Control( p_sys->stream, STREAM_GET_TITLE_INFO, v,
1127 c );
1128 }
1129
1130 case DEMUX_SET_TITLE:
1131 return vlc_stream_vaControl( p_sys->stream, STREAM_SET_TITLE, args );
1132
1133 case DEMUX_SET_SEEKPOINT:
1134 return vlc_stream_vaControl( p_sys->stream, STREAM_SET_SEEKPOINT,
1135 args );
1136
1137 case DEMUX_GET_META:
1138 return vlc_stream_vaControl( p_sys->stream, STREAM_GET_META, args );
1139
1140 case DEMUX_CAN_RECORD:
1141 pb_bool = va_arg( args, bool * );
1142 *pb_bool = true;
1143 return VLC_SUCCESS;
1144
1145 case DEMUX_SET_RECORD_STATE:
1146 b_bool = va_arg( args, int );
1147
1148 if( !b_bool )
1149 vlc_stream_Control( p_sys->stream, STREAM_SET_RECORD_STATE,
1150 false );
1151 p_sys->b_start_record = b_bool;
1152 return VLC_SUCCESS;
1153
1154 case DEMUX_GET_SIGNAL:
1155 return vlc_stream_vaControl( p_sys->stream, STREAM_GET_SIGNAL, args );
1156
1157 case DEMUX_GET_ATTACHMENTS:
1158 {
1159 input_attachment_t ***ppp_attach = va_arg( args, input_attachment_t *** );
1160 int *pi_int = va_arg( args, int * );
1161
1162 *pi_int = vlc_dictionary_keys_count( &p_sys->attachments );
1163 if( *pi_int <= 0 )
1164 return VLC_EGENERIC;
1165
1166 *ppp_attach = vlc_alloc( *pi_int, sizeof(input_attachment_t*) );
1167 if( !*ppp_attach )
1168 return VLC_EGENERIC;
1169
1170 *pi_int = 0;
1171 for( int i = 0; i < p_sys->attachments.i_size; i++ )
1172 {
1173 for( vlc_dictionary_entry_t *p_entry = p_sys->attachments.p_entries[i];
1174 p_entry; p_entry = p_entry->p_next )
1175 {
1176 msg_Err(p_demux, "GET ATTACHMENT %s", p_entry->psz_key);
1177 (*ppp_attach)[*pi_int] = vlc_input_attachment_Duplicate(
1178 (input_attachment_t *) p_entry->p_value );
1179 if( (*ppp_attach)[*pi_int] )
1180 (*pi_int)++;
1181 }
1182 }
1183
1184 return VLC_SUCCESS;
1185 }
1186
1187 default:
1188 break;
1189 }
1190
1191 return VLC_EGENERIC;
1192 }
1193
1194 /*****************************************************************************
1195 *
1196 *****************************************************************************/
read_opus_flag(uint8_t ** buf,size_t * len)1197 static int16_t read_opus_flag(uint8_t **buf, size_t *len)
1198 {
1199 if (*len < 2)
1200 return -1;
1201
1202 int16_t ret = ((*buf)[0] << 8) | (*buf)[1];
1203
1204 *len -= 2;
1205 *buf += 2;
1206
1207 if (ret & (3<<13))
1208 ret = -1;
1209
1210 return ret;
1211 }
1212
Opus_Parse(demux_t * demux,block_t * block)1213 static block_t *Opus_Parse(demux_t *demux, block_t *block)
1214 {
1215 block_t *p_chain = NULL;
1216 block_t **pp_chain_last = &p_chain;
1217
1218 uint8_t *buf = block->p_buffer;
1219 size_t len = block->i_buffer;
1220
1221 while (len > 3 && ((buf[0] << 3) | (buf[1] >> 5)) == 0x3ff) {
1222 int16_t start_trim = 0, end_trim = 0;
1223 int start_trim_flag = (buf[1] >> 4) & 1;
1224 int end_trim_flag = (buf[1] >> 3) & 1;
1225 int control_extension_flag = (buf[1] >> 2) & 1;
1226
1227 len -= 2;
1228 buf += 2;
1229
1230 unsigned au_size = 0;
1231 while (len--) {
1232 int c = *buf++;
1233 au_size += c;
1234 if (c != 0xff)
1235 break;
1236 }
1237
1238 if (start_trim_flag) {
1239 start_trim = read_opus_flag(&buf, &len);
1240 if (start_trim < 0) {
1241 msg_Err(demux, "Invalid start trimming flag");
1242 }
1243 }
1244 if (end_trim_flag) {
1245 end_trim = read_opus_flag(&buf, &len);
1246 if (end_trim < 0) {
1247 msg_Err(demux, "Invalid end trimming flag");
1248 }
1249 }
1250 if (control_extension_flag && len) {
1251 unsigned l = *buf++; len--;
1252 if (l > len) {
1253 msg_Err(demux, "Invalid control extension length %d > %zu", l, len);
1254 break;
1255 }
1256 buf += l;
1257 len -= l;
1258 }
1259
1260 if (!au_size || au_size > len) {
1261 msg_Err(demux, "Invalid Opus AU size %d (PES %zu)", au_size, len);
1262 break;
1263 }
1264
1265 block_t *au = block_Alloc(au_size);
1266 if (!au)
1267 break;
1268 memcpy(au->p_buffer, buf, au_size);
1269 block_CopyProperties(au, block);
1270 block_ChainLastAppend( &pp_chain_last, au );
1271
1272 au->i_nb_samples = opus_frame_duration(buf, au_size);
1273 if (end_trim && (uint16_t) end_trim <= au->i_nb_samples)
1274 au->i_length = end_trim; /* Blatant abuse of the i_length field. */
1275 else
1276 au->i_length = 0;
1277
1278 if (start_trim && start_trim < (au->i_nb_samples - au->i_length)) {
1279 au->i_nb_samples -= start_trim;
1280 if (au->i_nb_samples == 0)
1281 au->i_flags |= BLOCK_FLAG_PREROLL;
1282 }
1283
1284 buf += au_size;
1285 len -= au_size;
1286 }
1287
1288 block_Release(block);
1289 return p_chain;
1290 }
1291
J2K_Parse(demux_t * p_demux,block_t * p_block,bool b_interlaced)1292 static block_t *J2K_Parse( demux_t *p_demux, block_t *p_block, bool b_interlaced )
1293 {
1294 const uint8_t *p_buf = p_block->p_buffer;
1295
1296 if( p_block->i_buffer < ((b_interlaced) ? 48 : 38) )
1297 goto invalid;
1298
1299 if( memcmp( p_buf, "elsmfrat", 8 ) )
1300 goto invalid;
1301
1302 uint16_t i_den = GetWBE( &p_buf[8] );
1303 uint16_t i_num = GetWBE( &p_buf[10] );
1304 if( i_den == 0 )
1305 goto invalid;
1306 p_block->i_length = CLOCK_FREQ * i_den / i_num;
1307
1308 p_block->p_buffer += (b_interlaced) ? 48 : 38;
1309 p_block->i_buffer -= (b_interlaced) ? 48 : 38;
1310
1311 return p_block;
1312
1313 invalid:
1314 msg_Warn( p_demux, "invalid J2K header, dropping codestream" );
1315 block_Release( p_block );
1316 return NULL;
1317 }
1318
ConvertPESBlock(demux_t * p_demux,ts_es_t * p_es,size_t i_pes_size,uint8_t i_stream_id,block_t * p_block)1319 static block_t * ConvertPESBlock( demux_t *p_demux, ts_es_t *p_es,
1320 size_t i_pes_size, uint8_t i_stream_id,
1321 block_t *p_block )
1322 {
1323 if(!p_block)
1324 return NULL;
1325
1326 if( p_es->fmt.i_codec == VLC_CODEC_SUBT )
1327 {
1328 if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )
1329 {
1330 p_block->i_buffer = i_pes_size;
1331 }
1332 /* Append a \0 */
1333 p_block = block_Realloc( p_block, 0, p_block->i_buffer + 1 );
1334 if( p_block )
1335 p_block->p_buffer[p_block->i_buffer -1] = '\0';
1336 }
1337 else if( p_es->fmt.i_codec == VLC_CODEC_TELETEXT )
1338 {
1339 if( p_block->i_pts <= VLC_TS_INVALID )
1340 {
1341 /* Teletext may have missing PTS (ETSI EN 300 472 Annexe A)
1342 * In this case use the last PCR + 40ms */
1343 mtime_t i_pcr = p_es->p_program->pcr.i_current;
1344 if( i_pcr > VLC_TS_INVALID )
1345 p_block->i_pts = FROM_SCALE(i_pcr) + 40000;
1346 }
1347 }
1348 else if( p_es->fmt.i_codec == VLC_CODEC_ARIB_A ||
1349 p_es->fmt.i_codec == VLC_CODEC_ARIB_C )
1350 {
1351 if( p_block->i_pts <= VLC_TS_INVALID )
1352 {
1353 if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )
1354 {
1355 p_block->i_buffer = i_pes_size;
1356 }
1357 /* Append a \0 */
1358 p_block = block_Realloc( p_block, 0, p_block->i_buffer + 1 );
1359 if( p_block )
1360 p_block->p_buffer[p_block->i_buffer -1] = '\0';
1361 }
1362 }
1363 else if( p_es->fmt.i_codec == VLC_CODEC_OPUS)
1364 {
1365 p_block = Opus_Parse(p_demux, p_block);
1366 }
1367 else if( p_es->fmt.i_codec == VLC_CODEC_JPEG2000 )
1368 {
1369 if( unlikely(i_stream_id != 0xBD) )
1370 {
1371 block_Release( p_block );
1372 p_block = NULL;
1373 }
1374 else
1375 {
1376 p_block = J2K_Parse( p_demux, p_block, p_es->b_interlaced );
1377 }
1378 }
1379
1380 return p_block;
1381 }
1382
1383 /****************************************************************************
1384 * fanouts current block to all subdecoders / shared pid es
1385 ****************************************************************************/
SendDataChain(demux_t * p_demux,ts_es_t * p_es,block_t * p_chain)1386 static void SendDataChain( demux_t *p_demux, ts_es_t *p_es, block_t *p_chain )
1387 {
1388 while( p_chain )
1389 {
1390 block_t *p_block = p_chain;
1391 p_chain = p_block->p_next;
1392 p_block->p_next = NULL;
1393
1394 ts_es_t *p_es_send = p_es;
1395 if( p_es_send->i_next_block_flags )
1396 {
1397 p_block->i_flags |= p_es_send->i_next_block_flags;
1398 p_es_send->i_next_block_flags = 0;
1399 }
1400
1401 while( p_es_send )
1402 {
1403 if( p_es_send->p_program->b_selected )
1404 {
1405 /* Send a copy to each extra es */
1406 ts_es_t *p_extra_es = p_es_send->p_extraes;
1407 while( p_extra_es )
1408 {
1409 if( p_extra_es->id )
1410 {
1411 block_t *p_dup = block_Duplicate( p_block );
1412 if( p_dup )
1413 es_out_Send( p_demux->out, p_extra_es->id, p_dup );
1414 }
1415 p_extra_es = p_extra_es->p_next;
1416 }
1417
1418 if( p_es_send->p_next )
1419 {
1420 if( p_es_send->id )
1421 {
1422 block_t *p_dup = block_Duplicate( p_block );
1423 if( p_dup )
1424 es_out_Send( p_demux->out, p_es_send->id, p_dup );
1425 }
1426 }
1427 else
1428 {
1429 if( p_es_send->id )
1430 {
1431 es_out_Send( p_demux->out, p_es_send->id, p_block );
1432 p_block = NULL;
1433 }
1434 }
1435 }
1436 p_es_send = p_es_send->p_next;
1437 }
1438
1439 if( p_block )
1440 block_Release( p_block );
1441 }
1442 }
1443
1444 /****************************************************************************
1445 * gathering stuff
1446 ****************************************************************************/
ParsePESDataChain(demux_t * p_demux,ts_pid_t * pid,block_t * p_pes)1447 static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
1448 {
1449 uint8_t header[34];
1450 unsigned i_pes_size = 0;
1451 unsigned i_skip = 0;
1452 mtime_t i_dts = -1;
1453 mtime_t i_pts = -1;
1454 mtime_t i_length = 0;
1455 uint8_t i_stream_id;
1456 bool b_pes_scrambling = false;
1457 const es_mpeg4_descriptor_t *p_mpeg4desc = NULL;
1458
1459 assert(pid->type == TYPE_STREAM);
1460
1461 const int i_max = block_ChainExtract( p_pes, header, 34 );
1462 if ( i_max < 4 )
1463 {
1464 block_ChainRelease( p_pes );
1465 return;
1466 }
1467
1468 if( header[0] != 0 || header[1] != 0 || header[2] != 1 )
1469 {
1470 if ( !(p_pes->i_flags & BLOCK_FLAG_SCRAMBLED) )
1471 msg_Warn( p_demux, "invalid header [0x%02x:%02x:%02x:%02x] (pid: %d)",
1472 header[0], header[1],header[2],header[3], pid->i_pid );
1473 block_ChainRelease( p_pes );
1474 return;
1475 }
1476 else
1477 {
1478 /* Incorrect transport scrambling flag set by german boxes */
1479 p_pes->i_flags &= ~BLOCK_FLAG_SCRAMBLED;
1480 }
1481
1482 ts_es_t *p_es = pid->u.p_stream->p_es;
1483
1484 if( ParsePESHeader( VLC_OBJECT(p_demux), (uint8_t*)&header, i_max, &i_skip,
1485 &i_dts, &i_pts, &i_stream_id, &b_pes_scrambling ) == VLC_EGENERIC )
1486 {
1487 block_ChainRelease( p_pes );
1488 return;
1489 }
1490 else
1491 {
1492 if( i_pts != -1 && p_es->p_program )
1493 i_pts = TimeStampWrapAround( p_es->p_program->pcr.i_first, i_pts );
1494 if( i_dts != -1 && p_es->p_program )
1495 i_dts = TimeStampWrapAround( p_es->p_program->pcr.i_first, i_dts );
1496 if( b_pes_scrambling )
1497 p_pes->i_flags |= BLOCK_FLAG_SCRAMBLED;
1498 }
1499
1500 if( p_es->i_sl_es_id )
1501 p_mpeg4desc = GetMPEG4DescByEsId( p_es->p_program, p_es->i_sl_es_id );
1502
1503 if( p_es->fmt.i_codec == VLC_FOURCC( 'a', '5', '2', 'b' ) ||
1504 p_es->fmt.i_codec == VLC_FOURCC( 'd', 't', 's', 'b' ) )
1505 {
1506 i_skip += 4;
1507 }
1508 else if( p_es->fmt.i_codec == VLC_FOURCC( 'l', 'p', 'c', 'b' ) ||
1509 p_es->fmt.i_codec == VLC_FOURCC( 's', 'p', 'u', 'b' ) ||
1510 p_es->fmt.i_codec == VLC_FOURCC( 's', 'd', 'd', 'b' ) )
1511 {
1512 i_skip += 1;
1513 }
1514 else if( p_es->fmt.i_codec == VLC_CODEC_SUBT && p_mpeg4desc )
1515 {
1516 const decoder_config_descriptor_t *dcd = &p_mpeg4desc->dec_descr;
1517
1518 if( dcd->i_extra > 2 &&
1519 dcd->p_extra[0] == 0x10 &&
1520 ( dcd->p_extra[1]&0x10 ) )
1521 {
1522 /* display length */
1523 if( p_pes->i_buffer + 2 <= i_skip )
1524 i_length = GetWBE( &p_pes->p_buffer[i_skip] );
1525
1526 i_skip += 2;
1527 }
1528 if( p_pes->i_buffer + 2 <= i_skip )
1529 i_pes_size = GetWBE( &p_pes->p_buffer[i_skip] );
1530 /* */
1531 i_skip += 2;
1532 }
1533
1534 /* skip header */
1535 while( p_pes && i_skip > 0 )
1536 {
1537 if( p_pes->i_buffer <= i_skip )
1538 {
1539 block_t *p_next = p_pes->p_next;
1540
1541 i_skip -= p_pes->i_buffer;
1542 block_Release( p_pes );
1543 p_pes = p_next;
1544 }
1545 else
1546 {
1547 p_pes->i_buffer -= i_skip;
1548 p_pes->p_buffer += i_skip;
1549 break;
1550 }
1551 }
1552
1553 /* ISO/IEC 13818-1 2.7.5: if no pts and no dts, then dts == pts */
1554 if( i_pts >= 0 && i_dts < 0 )
1555 i_dts = i_pts;
1556
1557 if( p_pes )
1558 {
1559 ts_pmt_t *p_pmt = p_es->p_program;
1560 if( unlikely(!p_pmt) )
1561 {
1562 block_ChainRelease( p_pes );
1563 return;
1564 }
1565
1566 if( i_dts >= 0 )
1567 p_pes->i_dts = FROM_SCALE(i_dts);
1568
1569 if( i_pts >= 0 )
1570 p_pes->i_pts = FROM_SCALE(i_pts);
1571
1572 p_pes->i_length = FROM_SCALE_NZ(i_length);
1573
1574 /* Can become a chain on next call due to prepcr */
1575 block_t *p_chain = block_ChainGather( p_pes );
1576 while ( p_chain ) {
1577 block_t *p_block = p_chain;
1578 p_chain = p_chain->p_next;
1579 p_block->p_next = NULL;
1580
1581 if( !p_pmt->pcr.b_fix_done ) /* Not seen yet */
1582 PCRFixHandle( p_demux, p_pmt, p_block );
1583
1584 if( p_es->id && (p_pmt->pcr.i_current > -1 || p_pmt->pcr.b_disable) )
1585 {
1586 if( pid->u.p_stream->prepcr.p_head )
1587 {
1588 /* Rebuild current output chain, appending any prepcr outqueue */
1589 block_ChainLastAppend( &pid->u.p_stream->prepcr.pp_last, p_block );
1590 if( p_chain )
1591 block_ChainLastAppend( &pid->u.p_stream->prepcr.pp_last, p_chain );
1592 p_chain = pid->u.p_stream->prepcr.p_head;
1593 pid->u.p_stream->prepcr.p_head = NULL;
1594 pid->u.p_stream->prepcr.pp_last = &pid->u.p_stream->prepcr.p_head;
1595 /* Then now output all data */
1596 continue;
1597 }
1598
1599 if ( p_pmt->pcr.b_disable && p_block->i_dts > VLC_TS_INVALID &&
1600 ( p_pmt->i_pid_pcr == pid->i_pid || p_pmt->i_pid_pcr == 0x1FFF ) )
1601 {
1602 ProgramSetPCR( p_demux, p_pmt, TO_SCALE(p_block->i_dts) - 120000 );
1603 }
1604
1605 /* Compute PCR/DTS offset if any */
1606 if( p_pmt->pcr.i_pcroffset == -1 && p_block->i_dts > VLC_TS_INVALID &&
1607 p_pmt->pcr.i_current > VLC_TS_INVALID &&
1608 (p_es->fmt.i_cat == VIDEO_ES || p_es->fmt.i_cat == AUDIO_ES) )
1609 {
1610 int64_t i_dts27 = TO_SCALE(p_block->i_dts);
1611 i_dts27 = TimeStampWrapAround( p_pmt->pcr.i_first, i_dts27 );
1612 int64_t i_pcr = TimeStampWrapAround( p_pmt->pcr.i_first, p_pmt->pcr.i_current );
1613 if( i_dts27 < i_pcr )
1614 {
1615 p_pmt->pcr.i_pcroffset = i_pcr - i_dts27 + 80000;
1616 msg_Warn( p_demux, "Broken stream: pid %d sends packets with dts %"PRId64
1617 "us later than pcr, applying delay",
1618 pid->i_pid, FROM_SCALE_NZ(p_pmt->pcr.i_pcroffset) );
1619 }
1620 else p_pmt->pcr.i_pcroffset = 0;
1621 }
1622
1623 if( p_pmt->pcr.i_pcroffset != -1 )
1624 {
1625 if( p_block->i_dts > VLC_TS_INVALID )
1626 p_block->i_dts += FROM_SCALE_NZ(p_pmt->pcr.i_pcroffset);
1627 if( p_block->i_pts > VLC_TS_INVALID )
1628 p_block->i_pts += FROM_SCALE_NZ(p_pmt->pcr.i_pcroffset);
1629 }
1630
1631 /*** From here, block can become a chain again though conversion below ***/
1632
1633 if( pid->u.p_stream->p_proc )
1634 {
1635 if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
1636 ts_stream_processor_Reset( pid->u.p_stream->p_proc );
1637 p_block = ts_stream_processor_Push( pid->u.p_stream->p_proc, i_stream_id, p_block );
1638 }
1639 else
1640 /* Some codecs might need xform or AU splitting */
1641 {
1642 p_block = ConvertPESBlock( p_demux, p_es, i_pes_size, i_stream_id, p_block );
1643 }
1644
1645 SendDataChain( p_demux, p_es, p_block );
1646 }
1647 else
1648 {
1649 if( !p_pmt->pcr.b_fix_done ) /* Not seen yet */
1650 PCRFixHandle( p_demux, p_pmt, p_block );
1651
1652 block_ChainLastAppend( &pid->u.p_stream->prepcr.pp_last, p_block );
1653
1654 /* PCR Seen and no es->id, cleanup current and prepcr blocks */
1655 if( p_pmt->pcr.i_current > -1)
1656 {
1657 block_ChainRelease( pid->u.p_stream->prepcr.p_head );
1658 pid->u.p_stream->prepcr.p_head = NULL;
1659 pid->u.p_stream->prepcr.pp_last = &pid->u.p_stream->prepcr.p_head;
1660 }
1661 }
1662 }
1663 }
1664 else
1665 {
1666 msg_Warn( p_demux, "empty pes" );
1667 }
1668 }
1669
PushPESBlock(demux_t * p_demux,ts_pid_t * pid,block_t * p_pkt,bool b_unit_start)1670 static bool PushPESBlock( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, bool b_unit_start )
1671 {
1672 bool b_ret = false;
1673 ts_stream_t *p_pes = pid->u.p_stream;
1674
1675 if ( b_unit_start && p_pes->gather.p_data )
1676 {
1677 block_t *p_datachain = p_pes->gather.p_data;
1678 /* Flush the pes from pid */
1679 p_pes->gather.p_data = NULL;
1680 p_pes->gather.i_data_size = 0;
1681 p_pes->gather.i_gathered = 0;
1682 p_pes->gather.pp_last = &p_pes->gather.p_data;
1683 ParsePESDataChain( p_demux, pid, p_datachain );
1684 b_ret = true;
1685 }
1686
1687 if( p_pkt == NULL )
1688 return b_ret;
1689
1690 if( !b_unit_start && p_pes->gather.p_data == NULL )
1691 {
1692 /* msg_Dbg( p_demux, "broken packet" ); */
1693 block_Release( p_pkt );
1694 return b_ret;
1695 }
1696
1697 block_ChainLastAppend( &p_pes->gather.pp_last, p_pkt );
1698 p_pes->gather.i_gathered += p_pkt->i_buffer;
1699
1700 if( p_pes->gather.i_data_size > 0 &&
1701 p_pes->gather.i_gathered >= p_pes->gather.i_data_size )
1702 {
1703 /* re-enter in Flush above */
1704 assert(p_pes->gather.p_data);
1705 return PushPESBlock( p_demux, pid, NULL, true );
1706 }
1707
1708 return b_ret;
1709 }
1710
ReadTSPacket(demux_t * p_demux)1711 static block_t* ReadTSPacket( demux_t *p_demux )
1712 {
1713 demux_sys_t *p_sys = p_demux->p_sys;
1714
1715 block_t *p_pkt;
1716
1717 /* Get a new TS packet */
1718 if( !( p_pkt = vlc_stream_Block( p_sys->stream, p_sys->i_packet_size ) ) )
1719 {
1720 int64_t size = stream_Size( p_sys->stream );
1721 if( size >= 0 && (uint64_t)size == vlc_stream_Tell( p_sys->stream ) )
1722 msg_Dbg( p_demux, "EOF at %"PRIu64, vlc_stream_Tell( p_sys->stream ) );
1723 else
1724 msg_Dbg( p_demux, "Can't read TS packet at %"PRIu64, vlc_stream_Tell(p_sys->stream) );
1725 return NULL;
1726 }
1727
1728 if( p_pkt->i_buffer < TS_HEADER_SIZE + p_sys->i_packet_header_size )
1729 {
1730 block_Release( p_pkt );
1731 return NULL;
1732 }
1733
1734 /* Skip header (BluRay streams).
1735 * re-sync logic would do this (by adjusting packet start), but this would result in losing first and last ts packets.
1736 * First packet is usually PAT, and losing it means losing whole first GOP. This is fatal with still-image based menus.
1737 */
1738 p_pkt->p_buffer += p_sys->i_packet_header_size;
1739 p_pkt->i_buffer -= p_sys->i_packet_header_size;
1740
1741 /* Check sync byte and re-sync if needed */
1742 if( p_pkt->p_buffer[0] != 0x47 )
1743 {
1744 msg_Warn( p_demux, "lost synchro" );
1745 block_Release( p_pkt );
1746 for( ;; )
1747 {
1748 const uint8_t *p_peek;
1749 int i_peek = 0;
1750 unsigned i_skip = 0;
1751
1752 i_peek = vlc_stream_Peek( p_sys->stream, &p_peek,
1753 p_sys->i_packet_size * 10 );
1754 if( i_peek < 0 || (unsigned)i_peek < p_sys->i_packet_size + 1 )
1755 {
1756 msg_Dbg( p_demux, "eof ?" );
1757 return NULL;
1758 }
1759
1760 while( i_skip < i_peek - p_sys->i_packet_size )
1761 {
1762 if( p_peek[i_skip + p_sys->i_packet_header_size] == 0x47 &&
1763 p_peek[i_skip + p_sys->i_packet_header_size + p_sys->i_packet_size] == 0x47 )
1764 {
1765 break;
1766 }
1767 i_skip++;
1768 }
1769 msg_Dbg( p_demux, "skipping %d bytes of garbage", i_skip );
1770 if (vlc_stream_Read( p_sys->stream, NULL, i_skip ) != i_skip)
1771 return NULL;
1772
1773 if( i_skip < i_peek - p_sys->i_packet_size )
1774 {
1775 break;
1776 }
1777 }
1778 if( !( p_pkt = vlc_stream_Block( p_sys->stream, p_sys->i_packet_size ) ) )
1779 {
1780 msg_Dbg( p_demux, "eof ?" );
1781 return NULL;
1782 }
1783 }
1784 return p_pkt;
1785 }
1786
GetPCR(const block_t * p_pkt)1787 static mtime_t GetPCR( const block_t *p_pkt )
1788 {
1789 const uint8_t *p = p_pkt->p_buffer;
1790
1791 mtime_t i_pcr = -1;
1792
1793 if( likely(p_pkt->i_buffer > 11) &&
1794 ( p[3]&0x20 ) && /* adaptation */
1795 ( p[5]&0x10 ) &&
1796 ( p[4] >= 7 ) )
1797 {
1798 /* PCR is 33 bits */
1799 i_pcr = ( (mtime_t)p[6] << 25 ) |
1800 ( (mtime_t)p[7] << 17 ) |
1801 ( (mtime_t)p[8] << 9 ) |
1802 ( (mtime_t)p[9] << 1 ) |
1803 ( (mtime_t)p[10] >> 7 );
1804 }
1805 return i_pcr;
1806 }
1807
UpdateESScrambledState(es_out_t * out,const ts_es_t * p_es,bool b_scrambled)1808 static inline void UpdateESScrambledState( es_out_t *out, const ts_es_t *p_es, bool b_scrambled )
1809 {
1810 for( ; p_es; p_es = p_es->p_next )
1811 {
1812 if( p_es->id )
1813 es_out_Control( out, ES_OUT_SET_ES_SCRAMBLED_STATE,
1814 p_es->id, b_scrambled );
1815 UpdateESScrambledState( out, p_es->p_extraes, b_scrambled );
1816 }
1817 }
1818
UpdatePIDScrambledState(demux_t * p_demux,ts_pid_t * p_pid,bool b_scrambled)1819 static void UpdatePIDScrambledState( demux_t *p_demux, ts_pid_t *p_pid, bool b_scrambled )
1820 {
1821 if( !SCRAMBLED(*p_pid) == !b_scrambled )
1822 return;
1823
1824 msg_Warn( p_demux, "scrambled state changed on pid %d (%d->%d)",
1825 p_pid->i_pid, !!SCRAMBLED(*p_pid), b_scrambled );
1826
1827 if( b_scrambled )
1828 p_pid->i_flags |= FLAG_SCRAMBLED;
1829 else
1830 p_pid->i_flags &= ~FLAG_SCRAMBLED;
1831
1832 if( p_pid->type == TYPE_STREAM )
1833 UpdateESScrambledState( p_demux->out, p_pid->u.p_stream->p_es, b_scrambled );
1834 }
1835
FlushESBuffer(ts_stream_t * p_pes)1836 static inline void FlushESBuffer( ts_stream_t *p_pes )
1837 {
1838 if( p_pes->gather.p_data )
1839 {
1840 p_pes->gather.i_gathered = p_pes->gather.i_data_size = 0;
1841 block_ChainRelease( p_pes->gather.p_data );
1842 p_pes->gather.p_data = NULL;
1843 p_pes->gather.pp_last = &p_pes->gather.p_data;
1844 p_pes->gather.i_saved = 0;
1845 }
1846 if( p_pes->p_proc )
1847 ts_stream_processor_Reset( p_pes->p_proc );
1848 }
1849
ReadyQueuesPostSeek(demux_t * p_demux)1850 static void ReadyQueuesPostSeek( demux_t *p_demux )
1851 {
1852 demux_sys_t *p_sys = p_demux->p_sys;
1853
1854 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
1855 for( int i=0; i< p_pat->programs.i_size; i++ )
1856 {
1857 ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
1858 for( int j=0; j<p_pmt->e_streams.i_size; j++ )
1859 {
1860 ts_pid_t *pid = p_pmt->e_streams.p_elems[j];
1861 ts_stream_t *p_pes = pid->u.p_stream;
1862
1863 if( pid->type != TYPE_STREAM )
1864 continue;
1865
1866 for( ts_es_t *p_es = p_pes->p_es; p_es; p_es = p_es->p_next )
1867 p_es->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
1868
1869 pid->i_cc = 0xff;
1870
1871 if( pid->u.p_stream->prepcr.p_head )
1872 {
1873 block_ChainRelease( pid->u.p_stream->prepcr.p_head );
1874 pid->u.p_stream->prepcr.p_head = NULL;
1875 pid->u.p_stream->prepcr.pp_last = &pid->u.p_stream->prepcr.p_head;
1876 }
1877
1878 ts_sections_processor_Reset( pid->u.p_stream->p_sections_proc );
1879 ts_stream_processor_Reset( pid->u.p_stream->p_proc );
1880
1881 FlushESBuffer( pid->u.p_stream );
1882 }
1883 p_pmt->pcr.i_current = -1;
1884 }
1885 }
1886
SeekToTime(demux_t * p_demux,const ts_pmt_t * p_pmt,int64_t i_scaledtime)1887 static int SeekToTime( demux_t *p_demux, const ts_pmt_t *p_pmt, int64_t i_scaledtime )
1888 {
1889 demux_sys_t *p_sys = p_demux->p_sys;
1890
1891 /* Deal with common but worst binary search case */
1892 if( p_pmt->pcr.i_first == i_scaledtime && p_sys->b_canseek )
1893 return vlc_stream_Seek( p_sys->stream, 0 );
1894
1895 const int64_t i_stream_size = stream_Size( p_sys->stream );
1896 if( !p_sys->b_canfastseek || i_stream_size < p_sys->i_packet_size )
1897 return VLC_EGENERIC;
1898
1899 const uint64_t i_initial_pos = vlc_stream_Tell( p_sys->stream );
1900
1901 /* Find the time position by using binary search algorithm. */
1902 uint64_t i_head_pos = 0;
1903 uint64_t i_tail_pos = (uint64_t) i_stream_size - p_sys->i_packet_size;
1904 if( i_head_pos >= i_tail_pos )
1905 return VLC_EGENERIC;
1906
1907 bool b_found = false;
1908 while( (i_head_pos + p_sys->i_packet_size) <= i_tail_pos && !b_found )
1909 {
1910 /* Round i_pos to a multiple of p_sys->i_packet_size */
1911 uint64_t i_splitpos = i_head_pos + (i_tail_pos - i_head_pos) / 2;
1912 uint64_t i_div = i_splitpos % p_sys->i_packet_size;
1913 i_splitpos -= i_div;
1914
1915 if ( vlc_stream_Seek( p_sys->stream, i_splitpos ) != VLC_SUCCESS )
1916 break;
1917
1918 uint64_t i_pos = i_splitpos;
1919 while( i_pos < i_tail_pos )
1920 {
1921 int64_t i_pcr = -1;
1922 block_t *p_pkt = ReadTSPacket( p_demux );
1923 if( !p_pkt )
1924 {
1925 i_head_pos = i_tail_pos;
1926 break;
1927 }
1928 else
1929 i_pos = vlc_stream_Tell( p_sys->stream );
1930
1931 int i_pid = PIDGet( p_pkt );
1932 ts_pid_t *p_pid = GetPID(p_sys, i_pid);
1933 if( i_pid != 0x1FFF && p_pid->type == TYPE_STREAM &&
1934 ts_stream_Find_es( p_pid->u.p_stream, p_pmt ) &&
1935 (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* Payload start but not corrupt */
1936 (p_pkt->p_buffer[3] & 0xD0) == 0x10 /* Has payload but is not encrypted */
1937 )
1938 {
1939 unsigned i_skip = 4;
1940 if ( p_pkt->p_buffer[3] & 0x20 ) // adaptation field
1941 {
1942 if( p_pkt->i_buffer >= 4 + 2 + 5 )
1943 {
1944 if( p_pmt->i_pid_pcr == i_pid )
1945 i_pcr = GetPCR( p_pkt );
1946 i_skip += 1 + __MIN(p_pkt->p_buffer[4], 182);
1947 }
1948 }
1949
1950 if( i_pcr == -1 )
1951 {
1952 mtime_t i_dts = -1;
1953 mtime_t i_pts = -1;
1954 uint8_t i_stream_id;
1955 if ( VLC_SUCCESS == ParsePESHeader( VLC_OBJECT(p_demux), &p_pkt->p_buffer[i_skip],
1956 p_pkt->i_buffer - i_skip, &i_skip,
1957 &i_dts, &i_pts, &i_stream_id, NULL ) )
1958 {
1959 if( i_dts > -1 )
1960 i_pcr = i_dts;
1961 }
1962 }
1963 }
1964 block_Release( p_pkt );
1965
1966 if( i_pcr != -1 )
1967 {
1968 int64_t i_diff = i_scaledtime - TimeStampWrapAround( p_pmt->pcr.i_first, i_pcr );
1969 if ( i_diff < 0 )
1970 i_tail_pos = (i_splitpos >= p_sys->i_packet_size) ? i_splitpos - p_sys->i_packet_size : 0;
1971 else if( i_diff < TO_SCALE(VLC_TS_0 + CLOCK_FREQ / 2) ) // 500ms
1972 b_found = true;
1973 else
1974 i_head_pos = i_pos;
1975 break;
1976 }
1977 }
1978
1979 if ( !b_found && i_pos + p_sys->i_packet_size > i_tail_pos )
1980 i_tail_pos = (i_splitpos >= p_sys->i_packet_size) ? i_splitpos - p_sys->i_packet_size : 0;
1981 }
1982
1983 if( !b_found )
1984 {
1985 msg_Dbg( p_demux, "Seek():cannot find a time position." );
1986 vlc_stream_Seek( p_sys->stream, i_initial_pos );
1987 return VLC_EGENERIC;
1988 }
1989 return VLC_SUCCESS;
1990 }
1991
ProbeChunk(demux_t * p_demux,int i_program,bool b_end,int64_t * pi_pcr,bool * pb_found)1992 static int ProbeChunk( demux_t *p_demux, int i_program, bool b_end, int64_t *pi_pcr, bool *pb_found )
1993 {
1994 demux_sys_t *p_sys = p_demux->p_sys;
1995 int i_count = 0;
1996 block_t *p_pkt = NULL;
1997
1998 for( ;; )
1999 {
2000 *pi_pcr = -1;
2001
2002 if( i_count++ > PROBE_CHUNK_COUNT || !( p_pkt = ReadTSPacket( p_demux ) ) )
2003 {
2004 break;
2005 }
2006
2007 if( p_pkt->i_size < TS_PACKET_SIZE_188 &&
2008 ( p_pkt->p_buffer[1]&0x80 ) /* transport error */ )
2009 {
2010 block_Release( p_pkt );
2011 continue;
2012 }
2013
2014 const int i_pid = PIDGet( p_pkt );
2015 ts_pid_t *p_pid = GetPID(p_sys, i_pid);
2016
2017 p_pid->i_flags |= FLAG_SEEN;
2018
2019 if( i_pid != 0x1FFF && (p_pkt->p_buffer[1] & 0x80) == 0 ) /* not corrupt */
2020 {
2021 bool b_pcrresult = true;
2022 bool b_adaptfield = p_pkt->p_buffer[3] & 0x20;
2023
2024 if( b_adaptfield && p_pkt->i_buffer >= 4 + 2 + 5 )
2025 *pi_pcr = GetPCR( p_pkt );
2026
2027 if( *pi_pcr == -1 &&
2028 (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* payload start */
2029 (p_pkt->p_buffer[3] & 0xD0) == 0x10 && /* Has payload but is not encrypted */
2030 p_pid->type == TYPE_STREAM &&
2031 p_pid->u.p_stream->p_es->fmt.i_cat != UNKNOWN_ES
2032 )
2033 {
2034 b_pcrresult = false;
2035 mtime_t i_dts = -1;
2036 mtime_t i_pts = -1;
2037 uint8_t i_stream_id;
2038 unsigned i_skip = 4;
2039 if ( b_adaptfield ) // adaptation field
2040 i_skip += 1 + __MIN(p_pkt->p_buffer[4], 182);
2041
2042 if ( VLC_SUCCESS == ParsePESHeader( VLC_OBJECT(p_demux), &p_pkt->p_buffer[i_skip],
2043 p_pkt->i_buffer - i_skip, &i_skip,
2044 &i_dts, &i_pts, &i_stream_id, NULL ) )
2045 {
2046 if( i_dts != -1 )
2047 *pi_pcr = i_dts;
2048 else if( i_pts != -1 )
2049 *pi_pcr = i_pts;
2050 }
2051 }
2052
2053 if( *pi_pcr != -1 )
2054 {
2055 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2056 for( int i=0; i<p_pat->programs.i_size; i++ )
2057 {
2058 ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
2059 if( p_pmt->i_pid_pcr == p_pid->i_pid ||
2060 ( p_pmt->i_pid_pcr == 0x1FFF &&
2061 PIDReferencedByProgram( p_pmt, p_pid->i_pid ) )
2062 )
2063 {
2064 if( b_end )
2065 {
2066 p_pmt->i_last_dts = *pi_pcr;
2067 p_pmt->i_last_dts_byte = vlc_stream_Tell( p_sys->stream );
2068 }
2069 /* Start, only keep first */
2070 else if( b_pcrresult && p_pmt->pcr.i_first == -1 )
2071 {
2072 p_pmt->pcr.i_first = *pi_pcr;
2073 }
2074 else if( p_pmt->pcr.i_first_dts < VLC_TS_0 )
2075 {
2076 p_pmt->pcr.i_first_dts = FROM_SCALE(*pi_pcr);
2077 }
2078
2079 if( i_program == 0 || i_program == p_pmt->i_number )
2080 *pb_found = true;
2081 }
2082 }
2083 }
2084 }
2085
2086 block_Release( p_pkt );
2087 }
2088
2089 return i_count;
2090 }
2091
ProbeStart(demux_t * p_demux,int i_program)2092 int ProbeStart( demux_t *p_demux, int i_program )
2093 {
2094 demux_sys_t *p_sys = p_demux->p_sys;
2095 const uint64_t i_initial_pos = vlc_stream_Tell( p_sys->stream );
2096 int64_t i_stream_size = stream_Size( p_sys->stream );
2097
2098 int i_probe_count = 0;
2099 int64_t i_pos;
2100 mtime_t i_pcr = -1;
2101 bool b_found = false;
2102
2103 do
2104 {
2105 i_pos = p_sys->i_packet_size * i_probe_count;
2106 i_pos = __MIN( i_pos, i_stream_size );
2107
2108 if( vlc_stream_Seek( p_sys->stream, i_pos ) )
2109 return VLC_EGENERIC;
2110
2111 ProbeChunk( p_demux, i_program, false, &i_pcr, &b_found );
2112
2113 /* Go ahead one more chunk if end of file contained only stuffing packets */
2114 i_probe_count += PROBE_CHUNK_COUNT;
2115 } while( i_pos < i_stream_size && !b_found &&
2116 i_probe_count < PROBE_MAX );
2117
2118 if( vlc_stream_Seek( p_sys->stream, i_initial_pos ) )
2119 return VLC_EGENERIC;
2120
2121 return (b_found) ? VLC_SUCCESS : VLC_EGENERIC;
2122 }
2123
ProbeEnd(demux_t * p_demux,int i_program)2124 int ProbeEnd( demux_t *p_demux, int i_program )
2125 {
2126 demux_sys_t *p_sys = p_demux->p_sys;
2127 const uint64_t i_initial_pos = vlc_stream_Tell( p_sys->stream );
2128 int64_t i_stream_size = stream_Size( p_sys->stream );
2129
2130 int i_probe_count = PROBE_CHUNK_COUNT;
2131 int64_t i_pos;
2132 mtime_t i_pcr = -1;
2133 bool b_found = false;
2134
2135 do
2136 {
2137 i_pos = i_stream_size - (p_sys->i_packet_size * i_probe_count);
2138 i_pos = __MAX( i_pos, 0 );
2139
2140 if( vlc_stream_Seek( p_sys->stream, i_pos ) )
2141 return VLC_EGENERIC;
2142
2143 ProbeChunk( p_demux, i_program, true, &i_pcr, &b_found );
2144
2145 /* Go ahead one more chunk if end of file contained only stuffing packets */
2146 i_probe_count += PROBE_CHUNK_COUNT;
2147 } while( i_pos > 0 && !b_found &&
2148 i_probe_count < PROBE_MAX );
2149
2150 if( vlc_stream_Seek( p_sys->stream, i_initial_pos ) )
2151 return VLC_EGENERIC;
2152
2153 return (b_found) ? VLC_SUCCESS : VLC_EGENERIC;
2154 }
2155
ProgramSetPCR(demux_t * p_demux,ts_pmt_t * p_pmt,mtime_t i_pcr)2156 static void ProgramSetPCR( demux_t *p_demux, ts_pmt_t *p_pmt, mtime_t i_pcr )
2157 {
2158 demux_sys_t *p_sys = p_demux->p_sys;
2159
2160 /* Check if we have enqueued blocks waiting the/before the
2161 PCR barrier, and then adapt pcr so they have valid PCR when dequeuing */
2162 if( p_pmt->pcr.i_current == -1 && p_pmt->pcr.b_fix_done )
2163 {
2164 mtime_t i_mindts = -1;
2165
2166 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2167 for( int i=0; i< p_pat->programs.i_size; i++ )
2168 {
2169 ts_pmt_t *p_opmt = p_pat->programs.p_elems[i]->u.p_pmt;
2170 for( int j=0; j<p_opmt->e_streams.i_size; j++ )
2171 {
2172 ts_pid_t *p_pid = p_opmt->e_streams.p_elems[j];
2173 block_t *p_block = p_pid->u.p_stream->prepcr.p_head;
2174 while( p_block && p_block->i_dts == VLC_TS_INVALID )
2175 p_block = p_block->p_next;
2176
2177 if( p_block && ( i_mindts == -1 || p_block->i_dts < i_mindts ) )
2178 i_mindts = p_block->i_dts;
2179 }
2180 }
2181
2182 if( i_mindts > VLC_TS_INVALID )
2183 {
2184 msg_Dbg( p_demux, "Program %d PCR prequeue fixup %"PRId64"->%"PRId64,
2185 p_pmt->i_number, TO_SCALE(i_mindts), i_pcr );
2186 i_pcr = TO_SCALE(i_mindts);
2187 }
2188 }
2189
2190 p_pmt->pcr.i_current = i_pcr;
2191 if( p_pmt->pcr.i_first == -1 )
2192 {
2193 p_pmt->pcr.i_first = i_pcr; // now seen
2194 }
2195
2196 if ( p_sys->i_pmt_es )
2197 {
2198 es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR, p_pmt->i_number, FROM_SCALE(i_pcr) );
2199 /* growing files/named fifo handling */
2200 if( p_sys->b_access_control == false &&
2201 vlc_stream_Tell( p_sys->stream ) > p_pmt->i_last_dts_byte )
2202 {
2203 if( p_pmt->i_last_dts_byte == 0 ) /* first run */
2204 p_pmt->i_last_dts_byte = stream_Size( p_sys->stream );
2205 else
2206 {
2207 p_pmt->i_last_dts = i_pcr;
2208 p_pmt->i_last_dts_byte = vlc_stream_Tell( p_sys->stream );
2209 }
2210 }
2211 }
2212 }
2213
IsVideoEnd(ts_pid_t * p_pid)2214 static int IsVideoEnd( ts_pid_t *p_pid )
2215 {
2216 /* jump to near end of PES packet */
2217 block_t *p = p_pid->u.p_stream->gather.p_data;
2218 if( !p || !p->p_next )
2219 return 0;
2220 while( p->p_next->p_next )
2221 p = p->p_next;
2222 if( p->p_next->i_buffer > 4)
2223 p = p->p_next;
2224
2225 /* extract last bytes */
2226 uint8_t tail[ 188 ];
2227 const int i_tail = block_ChainExtract( p, tail, sizeof( tail ) );
2228 if( i_tail < 4 )
2229 return 0;
2230
2231 /* check for start code at end */
2232 return ( tail[ i_tail - 4 ] == 0 && tail[ i_tail - 3 ] == 0 && tail[ i_tail - 2 ] == 1 &&
2233 ( tail[ i_tail - 1 ] == 0xb7 || tail[ i_tail - 1 ] == 0x0a ) );
2234 }
2235
PCRCheckDTS(demux_t * p_demux,ts_pmt_t * p_pmt,mtime_t i_pcr)2236 static void PCRCheckDTS( demux_t *p_demux, ts_pmt_t *p_pmt, mtime_t i_pcr)
2237 {
2238 for( int i=0; i<p_pmt->e_streams.i_size; i++ )
2239 {
2240 ts_pid_t *p_pid = p_pmt->e_streams.p_elems[i];
2241
2242 if( p_pid->type != TYPE_STREAM || SCRAMBLED(*p_pid) )
2243 continue;
2244
2245 ts_stream_t *p_pes = p_pid->u.p_stream;
2246 ts_es_t *p_es = p_pes->p_es;
2247
2248 if( p_pes->gather.p_data == NULL )
2249 continue;
2250 if( p_pes->gather.i_data_size != 0 )
2251 continue;
2252
2253 /* check only MPEG2, H.264 and VC-1 */
2254 if( p_es->fmt.i_codec != VLC_CODEC_MPGV &&
2255 p_es->fmt.i_codec != VLC_CODEC_H264 &&
2256 p_es->fmt.i_codec != VLC_CODEC_VC1 )
2257 continue;
2258
2259 uint8_t header[34];
2260 const int i_max = block_ChainExtract( p_pes->gather.p_data, header, 34 );
2261
2262 if( i_max < 6 || header[0] != 0 || header[1] != 0 || header[2] != 1 )
2263 continue;
2264
2265 unsigned i_skip = 0;
2266 mtime_t i_dts = -1;
2267 mtime_t i_pts = -1;
2268 uint8_t i_stream_id;
2269
2270 if( ParsePESHeader( VLC_OBJECT(p_demux), (uint8_t*)&header, i_max, &i_skip,
2271 &i_dts, &i_pts, &i_stream_id, NULL ) == VLC_EGENERIC )
2272 continue;
2273
2274 if (p_pmt->pcr.i_pcroffset > 0) {
2275 if( i_dts > VLC_TS_INVALID )
2276 i_dts += p_pmt->pcr.i_pcroffset;
2277 if( i_pts > VLC_TS_INVALID )
2278 i_pts += p_pmt->pcr.i_pcroffset;
2279 }
2280
2281 if( i_dts > VLC_TS_INVALID )
2282 i_dts = TimeStampWrapAround( i_pcr, i_dts );
2283 if( i_pts > VLC_TS_INVALID )
2284 i_pts = TimeStampWrapAround( i_pcr, i_pts );
2285
2286 if(( i_dts > VLC_TS_INVALID && i_dts <= i_pcr ) ||
2287 ( i_pts > VLC_TS_INVALID && i_pts <= i_pcr ))
2288 {
2289 if( IsVideoEnd( p_pid ) )
2290 {
2291 msg_Warn( p_demux, "send queued data for pid %d: TS %"PRId64" <= PCR %"PRId64"\n",
2292 p_pid->i_pid, i_dts > VLC_TS_INVALID ? i_dts : i_pts, i_pcr);
2293 PushPESBlock( p_demux, p_pid, NULL, true ); /* Flush */
2294 }
2295 }
2296 }
2297 }
2298
PCRHandle(demux_t * p_demux,ts_pid_t * pid,mtime_t i_pcr)2299 static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, mtime_t i_pcr )
2300 {
2301 demux_sys_t *p_sys = p_demux->p_sys;
2302
2303 pid->probed.i_pcr_count++;
2304
2305 if( p_sys->i_pmt_es <= 0 )
2306 return;
2307
2308 if(unlikely(GetPID(p_sys, 0)->type != TYPE_PAT))
2309 return;
2310
2311 /* Search program and set the PCR */
2312 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2313 for( int i = 0; i < p_pat->programs.i_size; i++ )
2314 {
2315 ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
2316 if( p_pmt->pcr.b_disable )
2317 continue;
2318 mtime_t i_program_pcr = TimeStampWrapAround( p_pmt->pcr.i_first, i_pcr );
2319
2320 if( p_pmt->i_pid_pcr == 0x1FFF ) /* That program has no dedicated PCR pid ISO/IEC 13818-1 2.4.4.9 */
2321 {
2322 if( PIDReferencedByProgram( p_pmt, pid->i_pid ) ) /* PCR shall be on pid itself */
2323 {
2324 /* ? update PCR for the whole group program ? */
2325 ProgramSetPCR( p_demux, p_pmt, i_program_pcr );
2326 }
2327 }
2328 else /* set PCR provided by current pid to program(s) referencing it */
2329 {
2330 /* Can be dedicated PCR pid (no owned then) or another pid (owner == pmt) */
2331 if( p_pmt->i_pid_pcr == pid->i_pid ) /* If that program references current pid as PCR */
2332 {
2333 /* We've found a target group for update */
2334 PCRCheckDTS( p_demux, p_pmt, i_pcr );
2335 ProgramSetPCR( p_demux, p_pmt, i_program_pcr );
2336 }
2337 }
2338
2339 }
2340 }
2341
FindPCRCandidate(ts_pmt_t * p_pmt)2342 int FindPCRCandidate( ts_pmt_t *p_pmt )
2343 {
2344 ts_pid_t *p_cand = NULL;
2345 int i_previous = p_pmt->i_pid_pcr;
2346
2347 for( int i=0; i<p_pmt->e_streams.i_size; i++ )
2348 {
2349 ts_pid_t *p_pid = p_pmt->e_streams.p_elems[i];
2350 if( SEEN(p_pid) && p_pid->i_pid != i_previous )
2351 {
2352 if( p_pid->probed.i_pcr_count ) /* check PCR frequency first */
2353 {
2354 if( !p_cand || p_pid->probed.i_pcr_count > p_cand->probed.i_pcr_count )
2355 {
2356 p_cand = p_pid;
2357 continue;
2358 }
2359 }
2360
2361 if( p_pid->u.p_stream->p_es->fmt.i_cat == AUDIO_ES )
2362 {
2363 if( !p_cand )
2364 p_cand = p_pid;
2365 }
2366 else if ( p_pid->u.p_stream->p_es->fmt.i_cat == VIDEO_ES ) /* Otherwise prioritize video dts */
2367 {
2368 if( !p_cand || p_cand->u.p_stream->p_es->fmt.i_cat == AUDIO_ES )
2369 p_cand = p_pid;
2370 }
2371 }
2372 }
2373
2374 if( p_cand )
2375 return p_cand->i_pid;
2376 else
2377 return 0x1FFF;
2378 }
2379
2380 /* Tries to reselect a new PCR when none has been received */
PCRFixHandle(demux_t * p_demux,ts_pmt_t * p_pmt,block_t * p_block)2381 static void PCRFixHandle( demux_t *p_demux, ts_pmt_t *p_pmt, block_t *p_block )
2382 {
2383 demux_sys_t *p_sys = p_demux->p_sys;
2384
2385 /* disable PCR offset check */
2386 if( !p_sys->b_check_pcr_offset && p_pmt->pcr.i_pcroffset == -1 )
2387 p_pmt->pcr.i_pcroffset = 0;
2388
2389 if ( p_pmt->pcr.b_disable || p_pmt->pcr.b_fix_done )
2390 {
2391 return;
2392 }
2393 /* Record the first data packet timestamp in case there wont be any PCR */
2394 else if( !p_pmt->pcr.i_first_dts )
2395 {
2396 p_pmt->pcr.i_first_dts = p_block->i_dts;
2397 }
2398 else if( p_block->i_dts - p_pmt->pcr.i_first_dts > CLOCK_FREQ / 2 ) /* "PCR repeat rate shall not exceed 100ms" */
2399 {
2400 if( p_pmt->pcr.i_current < 0 &&
2401 GetPID( p_demux->p_sys, p_pmt->i_pid_pcr )->probed.i_pcr_count == 0 )
2402 {
2403 int i_cand = FindPCRCandidate( p_pmt );
2404 p_pmt->i_pid_pcr = i_cand;
2405 if ( GetPID( p_demux->p_sys, p_pmt->i_pid_pcr )->probed.i_pcr_count == 0 )
2406 p_pmt->pcr.b_disable = true;
2407 msg_Warn( p_demux, "No PCR received for program %d, set up workaround using pid %d",
2408 p_pmt->i_number, i_cand );
2409 UpdatePESFilters( p_demux, p_demux->p_sys->seltype == PROGRAM_ALL );
2410 }
2411 p_pmt->pcr.b_fix_done = true;
2412 }
2413 }
2414
ProcessTSPacket(demux_t * p_demux,ts_pid_t * pid,block_t * p_pkt,int * pi_skip)2415 static block_t * ProcessTSPacket( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, int *pi_skip )
2416 {
2417 const uint8_t *p = p_pkt->p_buffer;
2418 const bool b_adaptation = p[3]&0x20;
2419 const bool b_payload = p[3]&0x10;
2420 const bool b_scrambled = p[3]&0xc0;
2421 const int i_cc = p[3]&0x0f; /* continuity counter */
2422 bool b_discontinuity = false; /* discontinuity */
2423
2424 /* transport_scrambling_control is ignored */
2425 *pi_skip = 4;
2426
2427 #if 0
2428 msg_Dbg( p_demux, "pid=%d unit_start=%d adaptation=%d payload=%d "
2429 "cc=0x%x", pid->i_pid, b_unit_start, b_adaptation,
2430 b_payload, i_cc );
2431 #endif
2432
2433 /* Drop null packets */
2434 if( unlikely(pid->i_pid == 0x1FFF) )
2435 {
2436 block_Release( p_pkt );
2437 return NULL;
2438 }
2439
2440 /* For now, ignore additional error correction
2441 * TODO: handle Reed-Solomon 204,188 error correction */
2442 p_pkt->i_buffer = TS_PACKET_SIZE_188;
2443
2444 if( b_scrambled )
2445 {
2446 if( p_demux->p_sys->csa )
2447 {
2448 vlc_mutex_lock( &p_demux->p_sys->csa_lock );
2449 csa_Decrypt( p_demux->p_sys->csa, p_pkt->p_buffer, p_demux->p_sys->i_csa_pkt_size );
2450 vlc_mutex_unlock( &p_demux->p_sys->csa_lock );
2451 }
2452 else
2453 p_pkt->i_flags |= BLOCK_FLAG_SCRAMBLED;
2454 }
2455
2456 /* We don't have any adaptation_field, so payload starts
2457 * immediately after the 4 byte TS header */
2458 if( b_adaptation )
2459 {
2460 /* p[4] is adaptation_field_length minus one */
2461 *pi_skip += 1 + p[4];
2462 if( p[4] + 5 > 188 /* adaptation field only == 188 */ )
2463 {
2464 /* Broken is broken */
2465 block_Release( p_pkt );
2466 return NULL;
2467 }
2468 else if( p[4] > 0 )
2469 {
2470 /* discontinuity indicator found in stream */
2471 b_discontinuity = (p[5]&0x80) ? true : false;
2472 if( b_discontinuity )
2473 {
2474 msg_Warn( p_demux, "discontinuity indicator (pid=%d) ",
2475 pid->i_pid );
2476 /* ignore, that's not that simple 2.4.3.5 */
2477 //p_pkt->i_flags |= BLOCK_FLAG_DISCONTINUITY;
2478
2479 /* ... or don't ignore for our Bluray still frames and seek hacks */
2480 if(p[5] == 0x82 && !strncmp((const char *)&p[7], "VLC_DISCONTINU", 14))
2481 p_pkt->i_flags |= BLOCK_FLAG_DISCONTINUITY;
2482 }
2483 #if 0
2484 if( p[5]&0x40 )
2485 msg_Dbg( p_demux, "random access indicator (pid=%d) ", pid->i_pid );
2486 #endif
2487 }
2488 }
2489
2490 /* Test continuity counter */
2491 /* continuous when (one of this):
2492 * diff == 1
2493 * diff == 0 and payload == 0
2494 * diff == 0 and duplicate packet (playload != 0) <- should we
2495 * test the content ?
2496 */
2497 if( b_payload && p_demux->p_sys->b_cc_check )
2498 {
2499 const int i_diff = ( i_cc - pid->i_cc )&0x0f;
2500 if( i_diff == 1 )
2501 {
2502 pid->i_cc = ( pid->i_cc + 1 ) & 0xf;
2503 pid->i_dup = 0;
2504 }
2505 else
2506 {
2507 if( pid->i_cc == 0xff )
2508 {
2509 msg_Dbg( p_demux, "first packet for pid=%d cc=0x%x",
2510 pid->i_pid, i_cc );
2511 pid->i_cc = i_cc;
2512 }
2513 else if( i_diff == 0 && pid->i_dup == 0 &&
2514 !memcmp(pid->prevpktbytes, /* see comment below */
2515 &p_pkt->p_buffer[1], PREVPKTKEEPBYTES) )
2516 {
2517 /* Discard duplicated payload 2.4.3.3 */
2518 /* Added previous pkt bytes comparison for
2519 * stupid HLS dumps/joined segments which are
2520 * triggering erroneous duplicates instead of discontinuity.
2521 * That should not need CRC or full payload as it should be
2522 * restarting with PSI packets */
2523 pid->i_dup++;
2524 block_Release( p_pkt );
2525 return NULL;
2526 }
2527 else if( i_diff != 0 && !b_discontinuity )
2528 {
2529 msg_Warn( p_demux, "discontinuity received 0x%x instead of 0x%x (pid=%d)",
2530 i_cc, ( pid->i_cc + 1 )&0x0f, pid->i_pid );
2531
2532 pid->i_cc = i_cc;
2533 pid->i_dup = 0;
2534 p_pkt->i_flags |= BLOCK_FLAG_DISCONTINUITY;
2535 }
2536 else pid->i_cc = i_cc;
2537 }
2538 memcpy(pid->prevpktbytes, &p_pkt->p_buffer[1], PREVPKTKEEPBYTES);
2539 }
2540 else /* Ignore all 00 or 10 as in 2.4.3.3 CC counter must not be
2541 incremented in those cases, but there is humax inserting
2542 empty/10 packets always set with cc = 0 between 2 payload pkts
2543 see stream_main_pcr_1280x720p50_5mbps.ts */
2544 {
2545 if( b_discontinuity )
2546 pid->i_cc = i_cc;
2547 }
2548
2549 if( unlikely(!(b_payload || b_adaptation)) ) /* Invalid, ignore */
2550 {
2551 block_Release( p_pkt );
2552 return NULL;
2553 }
2554
2555 return p_pkt;
2556 }
2557
2558 /* Avoids largest memcpy */
block_Split(block_t ** pp_block,block_t ** pp_remain,size_t i_offset)2559 static bool block_Split( block_t **pp_block, block_t **pp_remain, size_t i_offset )
2560 {
2561 block_t *p_block = *pp_block;
2562 block_t *p_split = NULL;
2563 *pp_remain = NULL;
2564
2565 size_t i_tocopy = p_block->i_buffer - i_offset;
2566 if( i_tocopy > i_offset ) /* make new block for head */
2567 {
2568 if( i_offset > 0 )
2569 {
2570 p_split = block_Alloc( i_offset );
2571 if( p_split == NULL )
2572 return false;
2573 memcpy( p_split->p_buffer, p_block->p_buffer, i_offset );
2574 p_block->p_buffer += i_offset;
2575 p_block->i_buffer -= i_offset;
2576 }
2577 *pp_remain = p_block;
2578 *pp_block = p_split;
2579 }
2580 else /* other gets the tail of our split */
2581 {
2582 if( i_tocopy > 0 )
2583 {
2584 p_split = block_Alloc( i_tocopy );
2585 if( p_split == NULL )
2586 return false;
2587 memcpy( p_split->p_buffer, &p_block->p_buffer[i_offset], i_tocopy );
2588 p_block->i_buffer -= i_tocopy;
2589 }
2590 *pp_remain = p_split;
2591 }
2592 return true;
2593 }
2594
FindNextPESHeader(uint8_t * p_buf,size_t i_buffer)2595 static uint8_t *FindNextPESHeader( uint8_t *p_buf, size_t i_buffer )
2596 {
2597 const uint8_t *p_end = &p_buf[i_buffer];
2598 unsigned i_bitflow = 0;
2599 for( ; p_buf != p_end; p_buf++ )
2600 {
2601 i_bitflow <<= 1;
2602 if( !*p_buf )
2603 {
2604 i_bitflow |= 1;
2605 }
2606 else if( *p_buf == 0x01 && (i_bitflow & 0x06) == 0x06 ) /* >= two zero prefixed 1 */
2607 {
2608 return p_buf - 2;
2609 }
2610 }
2611 return NULL;
2612 }
2613
2614 static const uint8_t pes_sync[] = { 0, 0, 1 };
2615
MayHaveStartCodeOnEnd(const uint8_t * p_buf,size_t i_buf)2616 static bool MayHaveStartCodeOnEnd( const uint8_t *p_buf, size_t i_buf )
2617 {
2618 assert(i_buf > 2);
2619 return !( *(--p_buf) > 1 || *(--p_buf) > 0 || *(--p_buf) > 0 );
2620 }
2621
GatherPESData(demux_t * p_demux,ts_pid_t * pid,block_t * p_pkt,size_t i_skip)2622 static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size_t i_skip )
2623 {
2624 const bool b_unit_start = p_pkt->p_buffer[1]&0x40;
2625 bool b_ret = false;
2626 ts_stream_t *p_pes = pid->u.p_stream;
2627
2628 /* We have to gather it */
2629 p_pkt->p_buffer += i_skip;
2630 p_pkt->i_buffer -= i_skip;
2631
2632 bool b_single_payload = b_unit_start; /* Single payload in case of unit start */
2633 bool b_aligned_ts_payload = true;
2634
2635 if( unlikely(p_pes->b_broken_PUSI_conformance) )
2636 {
2637 /* Stream does not conform to payload_unit_start flag
2638 * applied to PES packets (AdTech private_stream_1) */
2639 b_aligned_ts_payload = false;
2640 b_single_payload = false;
2641
2642 }
2643
2644 /* We'll cannot parse any pes data */
2645 if( (p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) && p_demux->p_sys->b_valid_scrambling )
2646 {
2647 block_Release( p_pkt );
2648 return PushPESBlock( p_demux, pid, NULL, true );
2649 }
2650
2651 /* Data discontinuity, we need to drop or output currently
2652 * gathered data as it can't match the target size or can
2653 * have dropped next sync code */
2654 if( p_pkt->i_flags & BLOCK_FLAG_DISCONTINUITY )
2655 {
2656 p_pes->gather.i_saved = 0;
2657 /* Flush/output current */
2658 b_ret |= PushPESBlock( p_demux, pid, NULL, true );
2659 /* Propagate to output block to notify packetizers/decoders */
2660 if( p_pes->p_es )
2661 p_pes->p_es->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
2662 }
2663
2664 if ( unlikely(p_pes->gather.i_saved > 0) )
2665 {
2666 /* Saved from previous packet end */
2667 assert(p_pes->gather.i_saved < 6);
2668 if( !b_aligned_ts_payload )
2669 {
2670 p_pkt = block_Realloc( p_pkt, p_pes->gather.i_saved, p_pkt->i_buffer );
2671 if( p_pkt )
2672 memcpy( p_pkt->p_buffer, p_pes->gather.saved, p_pes->gather.i_saved );
2673 }
2674 p_pes->gather.i_saved = 0;
2675 }
2676
2677 for( bool b_first_sync_done = false; p_pkt; )
2678 {
2679 assert( p_pes->gather.i_saved == 0 );
2680
2681 if( p_pes->gather.p_data == NULL && !b_first_sync_done && p_pkt->i_buffer >= 6 )
2682 {
2683 if( likely(b_aligned_ts_payload) )
2684 {
2685 if( memcmp( p_pkt->p_buffer, pes_sync, 3 ) )
2686 {
2687 block_Release( p_pkt );
2688 return b_ret;
2689 }
2690 }
2691 else
2692 {
2693 /* Need to find sync code */
2694 uint8_t *p_buf = FindNextPESHeader( p_pkt->p_buffer, p_pkt->i_buffer - 3 );
2695 if( p_buf == NULL )
2696 {
2697 /* no first sync code */
2698 if( MayHaveStartCodeOnEnd( p_pkt->p_buffer, p_pkt->i_buffer ) )
2699 {
2700 /* Drop everything except last bytes for next packet */
2701 p_pkt->p_buffer += p_pkt->i_buffer - 3;
2702 p_pes->gather.i_saved = p_pkt->i_buffer = 3;
2703 memcpy(p_pes->gather.saved, p_pkt->p_buffer, p_pkt->i_buffer);
2704 }
2705 block_Release( p_pkt );
2706 return b_ret;
2707 }
2708 p_pkt->i_buffer -= p_buf - p_pkt->p_buffer;
2709 p_pkt->p_buffer = p_buf;
2710 }
2711 /* now points to PES header */
2712 p_pes->gather.i_data_size = GetWBE(&p_pkt->p_buffer[4]);
2713 if( p_pes->gather.i_data_size > 0 )
2714 p_pes->gather.i_data_size += 6;
2715 b_first_sync_done = true; /* Because if size is 0, we woud not look for second sync */
2716 }
2717 else
2718 {
2719 assert( p_pes->gather.i_data_size > p_pes->gather.i_gathered ||
2720 p_pes->gather.i_data_size == 0 );
2721
2722 /* If we started reading a fixed size */
2723 if( p_pes->gather.i_data_size > p_pes->gather.i_gathered )
2724 {
2725 const size_t i_remain = p_pes->gather.i_data_size - p_pes->gather.i_gathered;
2726 /* Append whole block */
2727 if( likely(p_pkt->i_buffer <= i_remain || b_single_payload) )
2728 {
2729 b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL );
2730 p_pkt = NULL;
2731 }
2732 else /* p_pkt->i_buffer > i_remain */
2733 {
2734 block_t *p_split;
2735 if( !block_Split( &p_pkt, &p_split, i_remain ) )
2736 {
2737 block_Release( p_pkt );
2738 return false;
2739 }
2740 b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL );
2741 p_pkt = p_split;
2742 b_first_sync_done = false;
2743 }
2744 }
2745 else /* if( p_pes->gather.i_data_size == 0 ) // see next packet */
2746 {
2747 /* Append or finish current/start new PES depending on unit_start */
2748 b_ret |= PushPESBlock( p_demux, pid, p_pkt, b_unit_start );
2749 p_pkt = NULL;
2750 }
2751 }
2752
2753 if( unlikely(p_pkt && p_pkt->i_buffer < 6) )
2754 {
2755 /* save and prepend to next packet */
2756 assert(!b_single_payload);
2757 assert(p_pes->gather.i_saved == 0);
2758 p_pes->gather.i_saved = p_pkt->i_buffer;
2759 memcpy(p_pes->gather.saved, p_pkt->p_buffer, p_pkt->i_buffer);
2760 block_Release( p_pkt );
2761 p_pkt = NULL;
2762 }
2763 }
2764
2765 return b_ret;
2766 }
2767
GatherSectionsData(demux_t * p_demux,ts_pid_t * p_pid,block_t * p_pkt,size_t i_skip)2768 static bool GatherSectionsData( demux_t *p_demux, ts_pid_t *p_pid, block_t *p_pkt, size_t i_skip )
2769 {
2770 VLC_UNUSED(i_skip); VLC_UNUSED(p_demux);
2771 bool b_ret = false;
2772
2773 if( p_pkt->i_flags & BLOCK_FLAG_DISCONTINUITY )
2774 {
2775 ts_sections_processor_Reset( p_pid->u.p_stream->p_sections_proc );
2776 }
2777
2778 if( (p_pkt->i_flags & (BLOCK_FLAG_SCRAMBLED | BLOCK_FLAG_CORRUPTED)) == 0 )
2779 {
2780 ts_sections_processor_Push( p_pid->u.p_stream->p_sections_proc, p_pkt->p_buffer );
2781 b_ret = true;
2782 }
2783
2784 block_Release( p_pkt );
2785
2786 return b_ret;
2787 }
2788
TsChangeStandard(demux_sys_t * p_sys,ts_standards_e v)2789 void TsChangeStandard( demux_sys_t *p_sys, ts_standards_e v )
2790 {
2791 if( p_sys->standard != TS_STANDARD_AUTO &&
2792 p_sys->standard != v )
2793 return; /* TODO */
2794 p_sys->standard = v;
2795 }
2796
ProgramIsSelected(demux_sys_t * p_sys,uint16_t i_pgrm)2797 bool ProgramIsSelected( demux_sys_t *p_sys, uint16_t i_pgrm )
2798 {
2799 if( p_sys->seltype == PROGRAM_ALL )
2800 return true;
2801
2802 for(int i=0; i<p_sys->programs.i_size; i++)
2803 if( p_sys->programs.p_elems[i] == i_pgrm )
2804 return true;
2805
2806 return false;
2807 }
2808
PIDReferencedByProgram(const ts_pmt_t * p_pmt,uint16_t i_pid)2809 static bool PIDReferencedByProgram( const ts_pmt_t *p_pmt, uint16_t i_pid )
2810 {
2811 for(int i=0; i<p_pmt->e_streams.i_size; i++)
2812 if( p_pmt->e_streams.p_elems[i]->i_pid == i_pid )
2813 return true;
2814
2815 return false;
2816 }
2817
DoCreateES(demux_t * p_demux,ts_es_t * p_es,const ts_es_t * p_parent_es)2818 static void DoCreateES( demux_t *p_demux, ts_es_t *p_es, const ts_es_t *p_parent_es )
2819 {
2820 demux_sys_t *p_sys = p_demux->p_sys;
2821
2822 for( ; p_es ; p_es = p_es->p_next )
2823 {
2824 if( !p_es->id )
2825 {
2826 if( !p_es->fmt.i_group )
2827 p_es->fmt.i_group = p_es->p_program->i_number;
2828 p_es->id = es_out_Add( p_demux->out, &p_es->fmt );
2829 if( p_parent_es ) /* Set Extra ES group and original ID */
2830 {
2831 if ( p_sys->b_es_id_pid ) /* pid is 13 bits */
2832 p_es->fmt.i_id = (p_sys->i_next_extraid++ << 13) | p_parent_es->fmt.i_id;
2833 p_es->fmt.i_group = p_parent_es->fmt.i_group;
2834 }
2835 p_sys->i_pmt_es++;
2836 }
2837 DoCreateES( p_demux, p_es->p_extraes, p_es );
2838 }
2839 }
2840
AddAndCreateES(demux_t * p_demux,ts_pid_t * pid,bool b_create_delayed)2841 void AddAndCreateES( demux_t *p_demux, ts_pid_t *pid, bool b_create_delayed )
2842 {
2843 demux_sys_t *p_sys = p_demux->p_sys;
2844
2845 if( b_create_delayed )
2846 p_sys->es_creation = CREATE_ES;
2847
2848 if( pid && p_sys->es_creation == CREATE_ES )
2849 {
2850 DoCreateES( p_demux, pid->u.p_stream->p_es, NULL );
2851
2852 /* Update the default program == first created ES group */
2853 if( p_sys->b_default_selection && p_sys->programs.i_size > 0)
2854 {
2855 p_sys->b_default_selection = false;
2856 const int i_first_program = pid->u.p_stream->p_es->p_program->i_number;
2857 if( p_sys->programs.p_elems[0] != i_first_program )
2858 p_sys->programs.p_elems[0] = i_first_program;
2859 msg_Dbg( p_demux, "Default program is %d", i_first_program );
2860 }
2861 }
2862
2863 if( b_create_delayed )
2864 {
2865 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2866 for( int i=0; i< p_pat->programs.i_size; i++ )
2867 {
2868 ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
2869 for( int j=0; j<p_pmt->e_streams.i_size; j++ )
2870 DoCreateES( p_demux, p_pmt->e_streams.p_elems[j]->u.p_stream->p_es, NULL );
2871 }
2872 }
2873 }
2874