demux: provide full URL instead of access name (refs #18504)
[vlc.git] / modules / demux / mpeg / ts.c
blob282fc20738278f74c30ce88248e22f6464ffc71c
1 /*****************************************************************************
2 * ts.c: Transport Stream input module for VLC.
3 *****************************************************************************
4 * Copyright (C) 2004-2016 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Jean-Paul Saman <jpsaman #_at_# m2x.nl>
10 * This program is free software; you can redistribute it and/or modify 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.
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.
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 *****************************************************************************/
25 /*****************************************************************************
26 * Preamble
27 *****************************************************************************/
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
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>
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"
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"
53 #include "ts.h"
55 #include "../../codec/scte18.h"
56 #include "../opus.h"
57 #include "../../mux/mpeg/csa.h"
59 #ifdef HAVE_ARIBB24
60 #include <aribb24/aribb24.h>
61 #endif
63 #include <assert.h>
65 /*****************************************************************************
66 * Module descriptor
67 *****************************************************************************/
68 static int Open ( vlc_object_t * );
69 static void Close ( vlc_object_t * );
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)
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[,...])." )
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>\"}\'.")
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).")
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).")
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." )
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." )
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." )
114 #define PCR_TEXT N_("Trust in-stream PCR")
115 #define PCR_LONGTEXT N_("Use the stream PCR as a reference.")
117 static const char *const ts_standards_list[] =
118 { "auto", "mpeg", "dvb", "arib", "atsc", "tdmb" };
119 static const char *const ts_standards_list_text[] =
120 { N_("Auto"), "MPEG", "DVB", "ARIB", "ATSC", "T-DMB" };
122 #define STANDARD_TEXT N_("Digital TV Standard")
123 #define STANDARD_LONGTEXT N_( "Selects mode for digital TV standard. " \
124 "This feature affects EPG information and subtitles." )
126 vlc_module_begin ()
127 set_description( N_("MPEG Transport Stream demuxer") )
128 set_shortname ( "MPEG-TS" )
129 set_category( CAT_INPUT )
130 set_subcategory( SUBCAT_INPUT_DEMUX )
132 add_string( "ts-standard", "auto", STANDARD_TEXT, STANDARD_LONGTEXT, true )
133 change_string_list( ts_standards_list, ts_standards_list_text )
135 add_string( "ts-extra-pmt", NULL, PMT_TEXT, PMT_LONGTEXT, true )
136 add_bool( "ts-trust-pcr", true, PCR_TEXT, PCR_LONGTEXT, true )
137 change_safe()
138 add_bool( "ts-es-id-pid", true, PID_TEXT, PID_LONGTEXT, true )
139 change_safe()
140 add_obsolete_string( "ts-out" ) /* since 2.2.0 */
141 add_obsolete_integer( "ts-out-mtu" ) /* since 2.2.0 */
142 add_string( "ts-csa-ck", NULL, CSA_TEXT, CSA_LONGTEXT, true )
143 change_safe()
144 add_string( "ts-csa2-ck", NULL, CSA2_TEXT, CSA2_LONGTEXT, true )
145 change_safe()
146 add_integer( "ts-csa-pkt", 188, CPKT_TEXT, CPKT_LONGTEXT, true )
147 change_safe()
149 add_bool( "ts-split-es", true, SPLIT_ES_TEXT, SPLIT_ES_LONGTEXT, false )
150 add_bool( "ts-seek-percent", false, SEEK_PERCENT_TEXT, SEEK_PERCENT_LONGTEXT, true )
152 add_obsolete_bool( "ts-silent" );
154 set_capability( "demux", 10 )
155 set_callbacks( Open, Close )
156 add_shortcut( "ts" )
157 vlc_module_end ()
159 /*****************************************************************************
160 * Local prototypes
161 *****************************************************************************/
162 static int Demux ( demux_t *p_demux );
163 static int Control( demux_t *p_demux, int i_query, va_list args );
165 static int ChangeKeyCallback( vlc_object_t *, char const *, vlc_value_t, vlc_value_t, void * );
167 /* Helpers */
168 static bool PIDReferencedByProgram( const ts_pmt_t *, uint16_t );
169 void UpdatePESFilters( demux_t *p_demux, bool b_all );
170 static inline void FlushESBuffer( ts_stream_t *p_pes );
171 static void UpdatePIDScrambledState( demux_t *p_demux, ts_pid_t *p_pid, bool );
172 static inline int PIDGet( block_t *p )
174 return ( (p->p_buffer[1]&0x1f)<<8 )|p->p_buffer[2];
176 static mtime_t GetPCR( const block_t * );
178 static block_t * ProcessTSPacket( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, int * );
179 static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_bk, size_t );
180 static bool GatherSectionsData( demux_t *p_demux, ts_pid_t *, block_t *, size_t );
181 static void ProgramSetPCR( demux_t *p_demux, ts_pmt_t *p_prg, mtime_t i_pcr );
183 static block_t* ReadTSPacket( demux_t *p_demux );
184 static int SeekToTime( demux_t *p_demux, const ts_pmt_t *, int64_t time );
185 static void ReadyQueuesPostSeek( demux_t *p_demux );
186 static void PCRHandle( demux_t *p_demux, ts_pid_t *, mtime_t );
187 static void PCRFixHandle( demux_t *, ts_pmt_t *, block_t * );
189 #define TS_PACKET_SIZE_188 188
190 #define TS_PACKET_SIZE_192 192
191 #define TS_PACKET_SIZE_204 204
192 #define TS_PACKET_SIZE_MAX 204
193 #define TS_HEADER_SIZE 4
195 static int DetectPacketSize( demux_t *p_demux, unsigned *pi_header_size, int i_offset )
197 const uint8_t *p_peek;
199 if( vlc_stream_Peek( p_demux->s,
200 &p_peek, i_offset + TS_PACKET_SIZE_MAX ) < i_offset + TS_PACKET_SIZE_MAX )
201 return -1;
203 for( int i_sync = 0; i_sync < TS_PACKET_SIZE_MAX; i_sync++ )
205 if( p_peek[i_offset + i_sync] != 0x47 )
206 continue;
208 /* Check next 3 sync bytes */
209 int i_peek = i_offset + TS_PACKET_SIZE_MAX * 3 + i_sync + 1;
210 if( ( vlc_stream_Peek( p_demux->s, &p_peek, i_peek ) ) < i_peek )
212 msg_Dbg( p_demux, "cannot peek" );
213 return -1;
215 if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_188] == 0x47 &&
216 p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_188] == 0x47 &&
217 p_peek[i_offset + i_sync + 3 * TS_PACKET_SIZE_188] == 0x47 )
219 return TS_PACKET_SIZE_188;
221 else if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_192] == 0x47 &&
222 p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_192] == 0x47 &&
223 p_peek[i_offset + i_sync + 3 * TS_PACKET_SIZE_192] == 0x47 )
225 if( i_sync == 4 )
227 *pi_header_size = 4; /* BluRay TS packets have 4-byte header */
229 return TS_PACKET_SIZE_192;
231 else if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_204] == 0x47 &&
232 p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_204] == 0x47 &&
233 p_peek[i_offset + i_sync + 3 * TS_PACKET_SIZE_204] == 0x47 )
235 return TS_PACKET_SIZE_204;
239 if( p_demux->obj.force )
241 msg_Warn( p_demux, "this does not look like a TS stream, continuing" );
242 return TS_PACKET_SIZE_188;
244 msg_Dbg( p_demux, "TS module discarded (lost sync)" );
245 return -1;
248 #define TOPFIELD_HEADER_SIZE 3712
250 static int DetectPVRHeadersAndHeaderSize( demux_t *p_demux, unsigned *pi_header_size, vdr_info_t *p_vdr )
252 const uint8_t *p_peek;
253 *pi_header_size = 0;
254 int i_packet_size = -1;
256 if( vlc_stream_Peek( p_demux->s,
257 &p_peek, TS_PACKET_SIZE_MAX ) < TS_PACKET_SIZE_MAX )
258 return -1;
260 if( memcmp( p_peek, "TFrc", 4 ) == 0 &&
261 p_peek[6] == 0 && ((GetDWBE(&p_peek[53]) & 0x7FFFFF00U) == 0x00) &&
262 vlc_stream_Peek( p_demux->s, &p_peek, TOPFIELD_HEADER_SIZE + TS_PACKET_SIZE_MAX )
263 == TOPFIELD_HEADER_SIZE + TS_PACKET_SIZE_MAX )
265 const int i_service = GetWBE(&p_peek[18]);
266 i_packet_size = DetectPacketSize( p_demux, pi_header_size, TOPFIELD_HEADER_SIZE );
267 if( i_packet_size != -1 )
269 msg_Dbg( p_demux, "this is a topfield file" );
270 #if 0
271 /* I used the TF5000PVR 2004 Firmware .doc header documentation,
272 * http://www.i-topfield.com/data/product/firmware/Structure%20of%20Recorded%20File%20in%20TF5000PVR%20(Feb%2021%202004).doc
273 * but after the filename the offsets seem to be incorrect. - DJ */
274 int i_duration, i_name;
275 char *psz_name = xmalloc(25);
276 char *psz_event_name;
277 char *psz_event_text = xmalloc(130);
278 char *psz_ext_text = xmalloc(1025);
280 // 2 bytes version Uimsbf (4,5)
281 // 2 bytes reserved (6,7)
282 // 2 bytes duration in minutes Uimsbf (8,9(
283 i_duration = (int) (p_peek[8] << 8) | p_peek[9];
284 msg_Dbg( p_demux, "Topfield recording length: +/- %d minutes", i_duration);
285 // 2 bytes service number in channel list (10, 11)
286 // 2 bytes service type Bslbf 0=TV 1=Radio Bslb (12, 13)
287 // 4 bytes of reserved + tuner info (14,15,16,17)
288 // 2 bytes of Service ID Bslbf (18,19)
289 // 2 bytes of PMT PID Uimsbf (20,21)
290 // 2 bytes of PCR PID Uimsbf (22,23)
291 // 2 bytes of Video PID Uimsbf (24,25)
292 // 2 bytes of Audio PID Uimsbf (26,27)
293 // 24 bytes filename Bslbf
294 memcpy( psz_name, &p_peek[28], 24 );
295 psz_name[24] = '\0';
296 msg_Dbg( p_demux, "recordingname=%s", psz_name );
297 // 1 byte of sat index Uimsbf (52)
298 // 3 bytes (1 bit of polarity Bslbf +23 bits reserved)
299 // 4 bytes of freq. Uimsbf (56,57,58,59)
300 // 2 bytes of symbol rate Uimsbf (60,61)
301 // 2 bytes of TS stream ID Uimsbf (62,63)
302 // 4 bytes reserved
303 // 2 bytes reserved
304 // 2 bytes duration Uimsbf (70,71)
305 //i_duration = (int) (p_peek[70] << 8) | p_peek[71];
306 //msg_Dbg( p_demux, "Topfield 2nd duration field: +/- %d minutes", i_duration);
307 // 4 bytes EventID Uimsbf (72-75)
308 // 8 bytes of Start and End time info (76-83)
309 // 1 byte reserved (84)
310 // 1 byte event name length Uimsbf (89)
311 i_name = (int)(p_peek[89]&~0x81);
312 msg_Dbg( p_demux, "event name length = %d", i_name);
313 psz_event_name = xmalloc( i_name+1 );
314 // 1 byte parental rating (90)
315 // 129 bytes of event text
316 memcpy( psz_event_name, &p_peek[91], i_name );
317 psz_event_name[i_name] = '\0';
318 memcpy( psz_event_text, &p_peek[91+i_name], 129-i_name );
319 psz_event_text[129-i_name] = '\0';
320 msg_Dbg( p_demux, "event name=%s", psz_event_name );
321 msg_Dbg( p_demux, "event text=%s", psz_event_text );
322 // 12 bytes reserved (220)
323 // 6 bytes reserved
324 // 2 bytes Event Text Length Uimsbf
325 // 4 bytes EventID Uimsbf
326 // FIXME We just have 613 bytes. not enough for this entire text
327 // 1024 bytes Extended Event Text Bslbf
328 memcpy( psz_ext_text, p_peek+372, 1024 );
329 psz_ext_text[1024] = '\0';
330 msg_Dbg( p_demux, "extended event text=%s", psz_ext_text );
331 // 52 bytes reserved Bslbf
332 #endif
333 p_vdr->i_service = i_service;
335 return i_packet_size;
336 //return TS_PACKET_SIZE_188;
340 return DetectPacketSize( p_demux, pi_header_size, 0 );
343 /*****************************************************************************
344 * Open
345 *****************************************************************************/
346 static int Open( vlc_object_t *p_this )
348 demux_t *p_demux = (demux_t*)p_this;
349 demux_sys_t *p_sys;
351 int i_packet_size;
352 unsigned i_packet_header_size = 0;
354 ts_pid_t *patpid;
355 vdr_info_t vdr = {0};
357 /* Search first sync byte */
358 i_packet_size = DetectPVRHeadersAndHeaderSize( p_demux, &i_packet_header_size, &vdr );
359 if( i_packet_size < 0 )
360 return VLC_EGENERIC;
362 p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
363 if( !p_sys )
364 return VLC_ENOMEM;
365 memset( p_sys, 0, sizeof( demux_sys_t ) );
366 vlc_mutex_init( &p_sys->csa_lock );
368 p_demux->pf_demux = Demux;
369 p_demux->pf_control = Control;
371 /* Init p_sys field */
372 p_sys->b_end_preparse = false;
373 ARRAY_INIT( p_sys->programs );
374 p_sys->b_default_selection = false;
375 p_sys->i_network_time = 0;
376 p_sys->i_network_time_update = 0;
378 p_sys->vdr = vdr;
380 p_sys->arib.b25stream = NULL;
381 p_sys->stream = p_demux->s;
383 p_sys->b_broken_charset = false;
385 ts_pid_list_Init( &p_sys->pids );
387 p_sys->i_packet_size = i_packet_size;
388 p_sys->i_packet_header_size = i_packet_header_size;
389 p_sys->i_ts_read = 50;
390 p_sys->csa = NULL;
391 p_sys->b_start_record = false;
393 vlc_dictionary_init( &p_sys->attachments, 0 );
395 p_sys->patfix.i_first_dts = -1;
396 p_sys->patfix.i_timesourcepid = 0;
397 p_sys->patfix.status = PAT_WAITING;
399 /* Init PAT handler */
400 patpid = GetPID(p_sys, 0);
401 if ( !PIDSetup( p_demux, TYPE_PAT, patpid, NULL ) )
403 vlc_mutex_destroy( &p_sys->csa_lock );
404 free( p_sys );
405 return VLC_ENOMEM;
407 if( !ts_psi_PAT_Attach( patpid, p_demux ) )
409 PIDRelease( p_demux, patpid );
410 vlc_mutex_destroy( &p_sys->csa_lock );
411 free( p_sys );
412 return VLC_EGENERIC;
415 p_sys->b_access_control = true;
416 p_sys->b_access_control = ( VLC_SUCCESS == SetPIDFilter( p_sys, patpid, true ) );
418 p_sys->i_pmt_es = 0;
419 p_sys->seltype = PROGRAM_AUTO_DEFAULT;
421 /* Read config */
422 p_sys->b_es_id_pid = var_CreateGetBool( p_demux, "ts-es-id-pid" );
423 p_sys->i_next_extraid = 1;
425 p_sys->b_trust_pcr = var_CreateGetBool( p_demux, "ts-trust-pcr" );
427 /* We handle description of an extra PMT */
428 char* psz_string = var_CreateGetString( p_demux, "ts-extra-pmt" );
429 p_sys->b_user_pmt = false;
430 if( psz_string && *psz_string )
431 UserPmt( p_demux, psz_string );
432 free( psz_string );
434 psz_string = var_CreateGetStringCommand( p_demux, "ts-csa-ck" );
435 if( psz_string && *psz_string )
437 int i_res;
438 char* psz_csa2;
440 p_sys->csa = csa_New();
442 psz_csa2 = var_CreateGetStringCommand( p_demux, "ts-csa2-ck" );
443 i_res = csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, psz_string, true );
444 if( i_res == VLC_SUCCESS && psz_csa2 && *psz_csa2 )
446 if( csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, psz_csa2, false ) != VLC_SUCCESS )
448 csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, psz_string, false );
451 else if ( i_res == VLC_SUCCESS )
453 csa_SetCW( (vlc_object_t*)p_demux, p_sys->csa, psz_string, false );
455 else
457 csa_Delete( p_sys->csa );
458 p_sys->csa = NULL;
461 if( p_sys->csa )
463 var_AddCallback( p_demux, "ts-csa-ck", ChangeKeyCallback, (void *)1 );
464 var_AddCallback( p_demux, "ts-csa2-ck", ChangeKeyCallback, NULL );
466 int i_pkt = var_CreateGetInteger( p_demux, "ts-csa-pkt" );
467 if( i_pkt < 4 || i_pkt > 188 )
469 msg_Err( p_demux, "wrong packet size %d specified.", i_pkt );
470 msg_Warn( p_demux, "using default packet size of 188 bytes" );
471 p_sys->i_csa_pkt_size = 188;
473 else
474 p_sys->i_csa_pkt_size = i_pkt;
475 msg_Dbg( p_demux, "decrypting %d bytes of packet", p_sys->i_csa_pkt_size );
477 free( psz_csa2 );
479 free( psz_string );
481 p_sys->b_split_es = var_InheritBool( p_demux, "ts-split-es" );
483 p_sys->b_canseek = false;
484 p_sys->b_canfastseek = false;
485 p_sys->b_ignore_time_for_positions = var_InheritBool( p_demux, "ts-seek-percent" );
487 p_sys->standard = TS_STANDARD_AUTO;
488 char *psz_standard = var_InheritString( p_demux, "ts-standard" );
489 if( psz_standard )
491 for( unsigned i=0; i<ARRAY_SIZE(ts_standards_list); i++ )
493 if( !strcmp( psz_standard, ts_standards_list[i] ) )
495 TsChangeStandard( p_sys, TS_STANDARD_AUTO + i );
496 msg_Dbg( p_demux, "Standard set to %s", ts_standards_list_text[i] );
497 break;
500 free( psz_standard );
503 if( p_sys->standard == TS_STANDARD_AUTO &&
504 ( !strncasecmp( p_demux->psz_url, "atsc", 4 ) ||
505 !strncasecmp( p_demux->psz_url, "usdigital", 9 ) ) )
507 TsChangeStandard( p_sys, TS_STANDARD_ATSC );
510 vlc_stream_Control( p_sys->stream, STREAM_CAN_SEEK, &p_sys->b_canseek );
511 vlc_stream_Control( p_sys->stream, STREAM_CAN_FASTSEEK,
512 &p_sys->b_canfastseek );
514 /* Preparse time */
515 if( p_sys->b_canseek )
517 p_sys->es_creation = NO_ES;
518 while( !p_sys->i_pmt_es && !p_sys->b_end_preparse )
519 if( Demux( p_demux ) != VLC_DEMUXER_SUCCESS )
520 break;
521 p_sys->es_creation = DELAY_ES;
523 else
524 p_sys->es_creation = ( p_sys->b_access_control ? CREATE_ES : DELAY_ES );
526 return VLC_SUCCESS;
529 /*****************************************************************************
530 * Close
531 *****************************************************************************/
532 static void FreeDictAttachment( void *p_value, void *p_obj )
534 VLC_UNUSED(p_obj);
535 vlc_input_attachment_Delete( (input_attachment_t *) p_value );
538 static void Close( vlc_object_t *p_this )
540 demux_t *p_demux = (demux_t*)p_this;
541 demux_sys_t *p_sys = p_demux->p_sys;
543 PIDRelease( p_demux, GetPID(p_sys, 0) );
545 vlc_mutex_lock( &p_sys->csa_lock );
546 if( p_sys->csa )
548 var_DelCallback( p_demux, "ts-csa-ck", ChangeKeyCallback, (void *)1 );
549 var_DelCallback( p_demux, "ts-csa2-ck", ChangeKeyCallback, NULL );
550 csa_Delete( p_sys->csa );
552 vlc_mutex_unlock( &p_sys->csa_lock );
554 ARRAY_RESET( p_sys->programs );
556 #ifdef HAVE_ARIBB24
557 if ( p_sys->arib.p_instance )
558 arib_instance_destroy( p_sys->arib.p_instance );
559 #endif
561 if ( p_sys->arib.b25stream )
563 p_sys->arib.b25stream->p_source = NULL; /* don't chain kill demuxer's source */
564 vlc_stream_Delete( p_sys->arib.b25stream );
567 vlc_mutex_destroy( &p_sys->csa_lock );
569 /* Release all non default pids */
570 ts_pid_list_Release( p_demux, &p_sys->pids );
572 /* Clear up attachments */
573 vlc_dictionary_clear( &p_sys->attachments, FreeDictAttachment, NULL );
575 free( p_sys );
578 /*****************************************************************************
579 * ChangeKeyCallback: called when changing the odd encryption key on the fly.
580 *****************************************************************************/
581 static int ChangeKeyCallback( vlc_object_t *p_this, char const *psz_cmd,
582 vlc_value_t oldval, vlc_value_t newval,
583 void *p_data )
585 VLC_UNUSED(psz_cmd); VLC_UNUSED(oldval);
586 demux_t *p_demux = (demux_t*)p_this;
587 demux_sys_t *p_sys = p_demux->p_sys;
588 int i_tmp = (intptr_t)p_data;
590 vlc_mutex_lock( &p_sys->csa_lock );
591 if ( i_tmp )
592 i_tmp = csa_SetCW( p_this, p_sys->csa, newval.psz_string, true );
593 else
594 i_tmp = csa_SetCW( p_this, p_sys->csa, newval.psz_string, false );
596 vlc_mutex_unlock( &p_sys->csa_lock );
597 return i_tmp;
600 /*****************************************************************************
601 * Demux:
602 *****************************************************************************/
603 static int Demux( demux_t *p_demux )
605 demux_sys_t *p_sys = p_demux->p_sys;
606 bool b_wait_es = p_sys->i_pmt_es <= 0;
608 /* If we had no PAT within MIN_PAT_INTERVAL, create PAT/PMT from probed streams */
609 if( p_sys->i_pmt_es == 0 && !SEEN(GetPID(p_sys, 0)) && p_sys->patfix.status == PAT_MISSING )
611 MissingPATPMTFixup( p_demux );
612 p_sys->patfix.status = PAT_FIXTRIED;
613 GetPID(p_sys, 0)->u.p_pat->b_generated = true;
616 /* We read at most 100 TS packet or until a frame is completed */
617 for( unsigned i_pkt = 0; i_pkt < p_sys->i_ts_read; i_pkt++ )
619 bool b_frame = false;
620 int i_header = 0;
621 block_t *p_pkt;
622 if( !(p_pkt = ReadTSPacket( p_demux )) )
624 return VLC_DEMUXER_EOF;
627 if( p_sys->b_start_record )
629 /* Enable recording once synchronized */
630 vlc_stream_Control( p_sys->stream, STREAM_SET_RECORD_STATE, true,
631 "ts" );
632 p_sys->b_start_record = false;
635 /* Early reject truncated packets from hw devices */
636 if( unlikely(p_pkt->i_buffer < TS_PACKET_SIZE_188) )
638 block_Release( p_pkt );
639 continue;
642 /* Reject any fully uncorrected packet. Even PID can be incorrect */
643 if( p_pkt->p_buffer[1]&0x80 )
645 msg_Dbg( p_demux, "transport_error_indicator set (pid=%d)",
646 PIDGet( p_pkt ) );
647 block_Release( p_pkt );
648 continue;
651 /* Parse the TS packet */
652 ts_pid_t *p_pid = GetPID( p_sys, PIDGet( p_pkt ) );
653 if( !SEEN(p_pid) )
655 if( p_pid->type == TYPE_FREE )
656 msg_Dbg( p_demux, "pid[%d] unknown", p_pid->i_pid );
657 p_pid->i_flags |= FLAG_SEEN;
658 if( p_pid->i_pid == 0x01 )
659 p_sys->b_valid_scrambling = true;
662 /* Drop duplicates and invalid (DOES NOT drop corrupted) */
663 p_pkt = ProcessTSPacket( p_demux, p_pid, p_pkt, &i_header );
664 if( !p_pkt )
665 continue;
667 if( !SCRAMBLED(*p_pid) != !(p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) )
669 UpdatePIDScrambledState( p_demux, p_pid, p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED );
672 /* Adaptation field cannot be scrambled */
673 mtime_t i_pcr = GetPCR( p_pkt );
674 if( i_pcr > VLC_TS_INVALID )
675 PCRHandle( p_demux, p_pid, i_pcr );
677 /* Probe streams to build PAT/PMT after MIN_PAT_INTERVAL in case we don't see any PAT */
678 if( !SEEN( GetPID( p_sys, 0 ) ) &&
679 (p_pid->probed.i_fourcc == 0 || p_pid->i_pid == p_sys->patfix.i_timesourcepid) &&
680 (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* Payload start but not corrupt */
681 (p_pkt->p_buffer[3] & 0xD0) == 0x10 ) /* Has payload but is not encrypted */
683 ProbePES( p_demux, p_pid, p_pkt->p_buffer + TS_HEADER_SIZE,
684 p_pkt->i_buffer - TS_HEADER_SIZE, p_pkt->p_buffer[3] & 0x20 /* Adaptation field */);
687 switch( p_pid->type )
689 case TYPE_PAT:
690 case TYPE_PMT:
691 /* PAT and PMT are not allowed to be scrambled */
692 ts_psi_Packet_Push( p_pid, p_pkt->p_buffer );
693 block_Release( p_pkt );
694 break;
696 case TYPE_STREAM:
697 p_sys->b_end_preparse = true;
699 if( p_sys->es_creation == DELAY_ES ) /* No longer delay ES since that pid's program sends data */
701 msg_Dbg( p_demux, "Creating delayed ES" );
702 AddAndCreateES( p_demux, p_pid, true );
703 UpdatePESFilters( p_demux, p_demux->p_sys->seltype == PROGRAM_ALL );
706 /* Emulate HW filter */
707 if( !p_sys->b_access_control && !(p_pid->i_flags & FLAG_FILTERED) )
709 /* That packet is for an unselected ES, don't waste time/memory gathering its data */
710 block_Release( p_pkt );
711 continue;
714 if( p_pid->u.p_stream->transport == TS_TRANSPORT_PES )
716 b_frame = GatherPESData( p_demux, p_pid, p_pkt, i_header );
718 else if( p_pid->u.p_stream->transport == TS_TRANSPORT_SECTIONS )
720 b_frame = GatherSectionsData( p_demux, p_pid, p_pkt, i_header );
722 else // pid->u.p_pes->transport == TS_TRANSPORT_IGNORE
724 block_Release( p_pkt );
727 break;
729 case TYPE_SI:
730 if( (p_pkt->i_flags & (BLOCK_FLAG_SCRAMBLED|BLOCK_FLAG_CORRUPTED)) == 0 )
731 ts_si_Packet_Push( p_pid, p_pkt->p_buffer );
732 block_Release( p_pkt );
733 break;
735 case TYPE_PSIP:
736 if( (p_pkt->i_flags & (BLOCK_FLAG_SCRAMBLED|BLOCK_FLAG_CORRUPTED)) == 0 )
737 ts_psip_Packet_Push( p_pid, p_pkt->p_buffer );
738 block_Release( p_pkt );
739 break;
741 case TYPE_CAT:
742 default:
743 /* We have to handle PCR if present */
744 block_Release( p_pkt );
745 break;
748 if( b_frame || ( b_wait_es && p_sys->i_pmt_es > 0 ) )
749 break;
752 demux_UpdateTitleFromStream( p_demux );
753 return VLC_DEMUXER_SUCCESS;
756 /*****************************************************************************
757 * Control:
758 *****************************************************************************/
759 static int EITCurrentEventTime( const ts_pmt_t *p_pmt, demux_sys_t *p_sys,
760 time_t *pi_time, time_t *pi_length )
762 if( p_sys->i_network_time == 0 || !p_pmt || p_pmt->eit.i_event_length == 0 )
763 return VLC_EGENERIC;
765 if( p_pmt->eit.i_event_start <= p_sys->i_network_time &&
766 p_sys->i_network_time < p_pmt->eit.i_event_start + p_pmt->eit.i_event_length )
768 if( pi_length )
769 *pi_length = p_pmt->eit.i_event_length;
770 if( pi_time )
772 *pi_time = p_sys->i_network_time - p_pmt->eit.i_event_start;
773 *pi_time += time(NULL) - p_sys->i_network_time_update;
775 return VLC_SUCCESS;
778 return VLC_EGENERIC;
781 static inline void HasSelectedES( es_out_t *out, const ts_es_t *p_es,
782 const ts_pmt_t *p_pmt, bool *pb_stream_selected )
784 for( ; p_es && !*pb_stream_selected; p_es = p_es->p_next )
786 if( p_es->id )
787 es_out_Control( out, ES_OUT_GET_ES_STATE,
788 p_es->id, pb_stream_selected );
789 HasSelectedES( out, p_es->p_extraes, p_pmt, pb_stream_selected );
793 void UpdatePESFilters( demux_t *p_demux, bool b_all )
795 demux_sys_t *p_sys = p_demux->p_sys;
796 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
798 /* We need 3 pass to avoid loss on deselect/relesect with hw filters and
799 because pid could be shared and its state altered by another unselected pmt
800 First clear flag on every referenced pid
801 Then add flag if non on each selected pmt/pcr and active es
802 Then commit it at hardware level if any */
804 /* clear selection flag on every pmt referenced pid */
805 for( int i=0; i< p_pat->programs.i_size; i++ )
807 ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
808 ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
810 p_pmt_pid->i_flags &= ~FLAG_FILTERED;
811 for( int j=0; j< p_pmt->e_streams.i_size; j++ )
812 p_pmt->e_streams.p_elems[j]->i_flags &= ~FLAG_FILTERED;
813 GetPID(p_sys, p_pmt->i_pid_pcr)->i_flags &= ~FLAG_FILTERED;
816 /* set selection flag on selected pmt referenced pid with active es */
817 for( int i=0; i< p_pat->programs.i_size; i++ )
819 ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
820 ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
822 if( (p_sys->b_default_selection && !p_sys->b_access_control) || b_all )
823 p_pmt->b_selected = true;
824 else
825 p_pmt->b_selected = ProgramIsSelected( p_sys, p_pmt->i_number );
827 if( p_pmt->b_selected )
829 p_pmt_pid->i_flags |= FLAG_FILTERED;
831 for( int j=0; j<p_pmt->e_streams.i_size; j++ )
833 ts_pid_t *espid = p_pmt->e_streams.p_elems[j];
834 ts_stream_t *p_pes = espid->u.p_stream;
836 bool b_stream_selected = true;
837 if( !p_pes->b_always_receive && !b_all )
838 HasSelectedES( p_demux->out, p_pes->p_es, p_pmt, &b_stream_selected );
840 if( b_stream_selected )
842 msg_Dbg( p_demux, "enabling pid %d from program %d", espid->i_pid, p_pmt->i_number );
843 espid->i_flags |= FLAG_FILTERED;
847 /* Select pcr last in case it is handled by unselected ES */
848 if( p_pmt->i_pid_pcr > 0 )
850 GetPID(p_sys, p_pmt->i_pid_pcr)->i_flags |= FLAG_FILTERED;
851 msg_Dbg( p_demux, "enabling pcr pid %d from program %d", p_pmt->i_pid_pcr, p_pmt->i_number );
856 /* Commit HW changes based on flags */
857 for( int i=0; i< p_pat->programs.i_size; i++ )
859 ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
860 ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
862 UpdateHWFilter( p_sys, p_pmt_pid );
863 for( int j=0; j< p_pmt->e_streams.i_size; j++ )
865 ts_pid_t *espid = p_pmt->e_streams.p_elems[j];
866 UpdateHWFilter( p_sys, espid );
867 if( (espid->i_flags & FLAG_FILTERED) == 0 )
868 FlushESBuffer( espid->u.p_stream );
870 UpdateHWFilter( p_sys, GetPID(p_sys, p_pmt->i_pid_pcr) );
874 static int Control( demux_t *p_demux, int i_query, va_list args )
876 demux_sys_t *p_sys = p_demux->p_sys;
877 double f, *pf;
878 bool b_bool, *pb_bool;
879 int64_t i64;
880 int64_t *pi64;
881 int i_int;
882 const ts_pmt_t *p_pmt = NULL;
883 const ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
885 for( int i=0; i<p_pat->programs.i_size && !p_pmt; i++ )
887 if( p_pat->programs.p_elems[i]->u.p_pmt->b_selected )
888 p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
891 switch( i_query )
893 case DEMUX_CAN_SEEK:
894 *va_arg( args, bool * ) = p_sys->b_canseek;
895 return VLC_SUCCESS;
897 case DEMUX_GET_POSITION:
898 pf = va_arg( args, double * );
900 /* Access control test is because EPG for recordings is not relevant */
901 if( p_sys->b_access_control )
903 time_t i_time, i_length;
904 if( !EITCurrentEventTime( p_pmt, p_sys, &i_time, &i_length ) && i_length > 0 )
906 *pf = (double)i_time/(double)i_length;
907 return VLC_SUCCESS;
911 if( !p_sys->b_ignore_time_for_positions &&
912 p_pmt &&
913 p_pmt->pcr.i_first > -1 && p_pmt->i_last_dts > VLC_TS_INVALID &&
914 p_pmt->pcr.i_current > -1 )
916 double i_length = TimeStampWrapAround( p_pmt->pcr.i_first,
917 p_pmt->i_last_dts ) - p_pmt->pcr.i_first;
918 i_length += p_pmt->pcr.i_pcroffset;
919 double i_pos = TimeStampWrapAround( p_pmt->pcr.i_first,
920 p_pmt->pcr.i_current ) - p_pmt->pcr.i_first;
921 if( i_length > 0 )
923 *pf = i_pos / i_length;
924 return VLC_SUCCESS;
928 if( (i64 = stream_Size( p_sys->stream) ) > 0 )
930 uint64_t offset = vlc_stream_Tell( p_sys->stream );
931 *pf = (double)offset / (double)i64;
932 return VLC_SUCCESS;
934 break;
936 case DEMUX_SET_POSITION:
937 f = va_arg( args, double );
938 b_bool = (bool) va_arg( args, int ); /* precise */
940 if(!p_sys->b_canseek)
941 break;
943 if( p_sys->b_access_control &&
944 !p_sys->b_ignore_time_for_positions && b_bool && p_pmt )
946 time_t i_time, i_length;
947 if( !EITCurrentEventTime( p_pmt, p_sys, &i_time, &i_length ) &&
948 i_length > 0 && !SeekToTime( p_demux, p_pmt, (int64_t)(TO_SCALE(i_length * CLOCK_FREQ) * f) ) )
950 ReadyQueuesPostSeek( p_demux );
951 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
952 (int64_t)(TO_SCALE(i_length * CLOCK_FREQ) * f) );
953 return VLC_SUCCESS;
957 if( !p_sys->b_ignore_time_for_positions && b_bool && p_pmt &&
958 p_pmt->pcr.i_first > -1 && p_pmt->i_last_dts > VLC_TS_INVALID &&
959 p_pmt->pcr.i_current > -1 )
961 int64_t i_length = TimeStampWrapAround( p_pmt->pcr.i_first,
962 p_pmt->i_last_dts ) - p_pmt->pcr.i_first;
963 i64 = p_pmt->pcr.i_first + (int64_t)(i_length * f);
964 if( i64 <= p_pmt->i_last_dts )
966 if( !SeekToTime( p_demux, p_pmt, i64 ) )
968 ReadyQueuesPostSeek( p_demux );
969 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME, FROM_SCALE(i64) );
970 return VLC_SUCCESS;
975 i64 = stream_Size( p_sys->stream );
976 if( i64 > 0 &&
977 vlc_stream_Seek( p_sys->stream, (int64_t)(i64 * f) ) == VLC_SUCCESS )
979 ReadyQueuesPostSeek( p_demux );
980 return VLC_SUCCESS;
982 break;
984 case DEMUX_SET_TIME:
985 i64 = va_arg( args, int64_t );
987 if( p_sys->b_canseek && p_pmt && p_pmt->pcr.i_first > -1 &&
988 !SeekToTime( p_demux, p_pmt, p_pmt->pcr.i_first + TO_SCALE(i64) ) )
990 ReadyQueuesPostSeek( p_demux );
991 es_out_Control( p_demux->out, ES_OUT_SET_NEXT_DISPLAY_TIME,
992 FROM_SCALE(p_pmt->pcr.i_first) + i64 - VLC_TS_0 );
993 return VLC_SUCCESS;
995 break;
997 case DEMUX_GET_TIME:
998 pi64 = va_arg( args, int64_t * );
1000 if( p_sys->b_access_control )
1002 time_t i_event_start;
1003 if( !EITCurrentEventTime( p_pmt, p_sys, &i_event_start, NULL ) )
1005 *pi64 = i_event_start * CLOCK_FREQ;
1006 return VLC_SUCCESS;
1010 if( p_pmt && p_pmt->pcr.i_current > -1 && p_pmt->pcr.i_first > -1 )
1012 int64_t i_pcr = TimeStampWrapAround( p_pmt->pcr.i_first, p_pmt->pcr.i_current );
1013 *pi64 = FROM_SCALE(i_pcr - p_pmt->pcr.i_first);
1014 return VLC_SUCCESS;
1016 break;
1018 case DEMUX_GET_LENGTH:
1019 pi64 = va_arg( args, int64_t * );
1021 if( p_sys->b_access_control )
1023 time_t i_event_duration;
1024 if( !EITCurrentEventTime( p_pmt, p_sys, NULL, &i_event_duration ) )
1026 *pi64 = i_event_duration * CLOCK_FREQ;
1027 return VLC_SUCCESS;
1031 if( !p_sys->b_ignore_time_for_positions &&
1032 p_pmt &&
1033 ( p_pmt->pcr.i_first > -1 || p_pmt->pcr.i_first_dts > VLC_TS_INVALID ) &&
1034 p_pmt->i_last_dts > 0 )
1036 int64_t i_start = (p_pmt->pcr.i_first > -1) ? p_pmt->pcr.i_first :
1037 TO_SCALE(p_pmt->pcr.i_first_dts);
1038 int64_t i_last = TimeStampWrapAround( p_pmt->pcr.i_first, p_pmt->i_last_dts );
1039 i_last += p_pmt->pcr.i_pcroffset;
1040 *pi64 = FROM_SCALE(i_last - i_start);
1041 return VLC_SUCCESS;
1043 break;
1045 case DEMUX_SET_GROUP:
1047 vlc_list_t *p_list;
1049 i_int = va_arg( args, int );
1050 p_list = va_arg( args, vlc_list_t * );
1051 msg_Dbg( p_demux, "DEMUX_SET_GROUP %d %p", i_int, (void *)p_list );
1053 if( i_int != 0 ) /* If not default program */
1055 /* Deselect/filter current ones */
1056 ARRAY_RESET( p_sys->programs );
1058 if( i_int != -1 )
1060 p_sys->seltype = PROGRAM_LIST;
1061 ARRAY_APPEND( p_sys->programs, i_int );
1062 UpdatePESFilters( p_demux, false );
1064 else if( likely( p_list != NULL ) )
1066 p_sys->seltype = PROGRAM_LIST;
1067 for( int i = 0; i < p_list->i_count; i++ )
1068 ARRAY_APPEND( p_sys->programs, p_list->p_values[i].i_int );
1069 UpdatePESFilters( p_demux, false );
1071 else // All ES Mode
1073 p_pat = GetPID(p_sys, 0)->u.p_pat;
1074 for( int i = 0; i < p_pat->programs.i_size; i++ )
1075 ARRAY_APPEND( p_sys->programs, p_pat->programs.p_elems[i]->i_pid );
1076 p_sys->seltype = PROGRAM_ALL;
1077 UpdatePESFilters( p_demux, true );
1080 p_sys->b_default_selection = false;
1082 else
1084 ARRAY_RESET( p_sys->programs );
1085 p_sys->seltype = PROGRAM_AUTO_DEFAULT;
1088 return VLC_SUCCESS;
1091 case DEMUX_SET_ES:
1093 i_int = va_arg( args, int );
1094 msg_Dbg( p_demux, "DEMUX_SET_ES %d", i_int );
1096 if( p_demux->p_sys->seltype != PROGRAM_ALL ) /* Won't change anything */
1097 UpdatePESFilters( p_demux, false );
1099 return VLC_SUCCESS;
1102 case DEMUX_GET_TITLE_INFO:
1104 struct input_title_t ***v = va_arg( args, struct input_title_t*** );
1105 int *c = va_arg( args, int * );
1107 *va_arg( args, int* ) = 0; /* Title offset */
1108 *va_arg( args, int* ) = 0; /* Chapter offset */
1109 return vlc_stream_Control( p_sys->stream, STREAM_GET_TITLE_INFO, v,
1110 c );
1113 case DEMUX_SET_TITLE:
1114 return vlc_stream_vaControl( p_sys->stream, STREAM_SET_TITLE, args );
1116 case DEMUX_SET_SEEKPOINT:
1117 return vlc_stream_vaControl( p_sys->stream, STREAM_SET_SEEKPOINT,
1118 args );
1120 case DEMUX_GET_META:
1121 return vlc_stream_vaControl( p_sys->stream, STREAM_GET_META, args );
1123 case DEMUX_CAN_RECORD:
1124 pb_bool = va_arg( args, bool * );
1125 *pb_bool = true;
1126 return VLC_SUCCESS;
1128 case DEMUX_SET_RECORD_STATE:
1129 b_bool = va_arg( args, int );
1131 if( !b_bool )
1132 vlc_stream_Control( p_sys->stream, STREAM_SET_RECORD_STATE,
1133 false );
1134 p_sys->b_start_record = b_bool;
1135 return VLC_SUCCESS;
1137 case DEMUX_GET_SIGNAL:
1138 return vlc_stream_vaControl( p_sys->stream, STREAM_GET_SIGNAL, args );
1140 case DEMUX_GET_ATTACHMENTS:
1142 input_attachment_t ***ppp_attach = va_arg( args, input_attachment_t *** );
1143 int *pi_int = va_arg( args, int * );
1145 *pi_int = vlc_dictionary_keys_count( &p_sys->attachments );
1146 if( *pi_int <= 0 )
1147 return VLC_EGENERIC;
1149 *ppp_attach = vlc_alloc( *pi_int, sizeof(input_attachment_t*) );
1150 if( !*ppp_attach )
1151 return VLC_EGENERIC;
1153 *pi_int = 0;
1154 for( int i = 0; i < p_sys->attachments.i_size; i++ )
1156 for( vlc_dictionary_entry_t *p_entry = p_sys->attachments.p_entries[i];
1157 p_entry; p_entry = p_entry->p_next )
1159 msg_Err(p_demux, "GET ATTACHMENT %s", p_entry->psz_key);
1160 (*ppp_attach)[*pi_int] = vlc_input_attachment_Duplicate(
1161 (input_attachment_t *) p_entry->p_value );
1162 if( (*ppp_attach)[*pi_int] )
1163 (*pi_int)++;
1167 return VLC_SUCCESS;
1170 default:
1171 break;
1174 return VLC_EGENERIC;
1177 /*****************************************************************************
1179 *****************************************************************************/
1180 static int16_t read_opus_flag(uint8_t **buf, size_t *len)
1182 if (*len < 2)
1183 return -1;
1185 int16_t ret = ((*buf)[0] << 8) | (*buf)[1];
1187 *len -= 2;
1188 *buf += 2;
1190 if (ret & (3<<13))
1191 ret = -1;
1193 return ret;
1196 static block_t *Opus_Parse(demux_t *demux, block_t *block)
1198 block_t *p_chain = NULL;
1199 block_t **pp_chain_last = &p_chain;
1201 uint8_t *buf = block->p_buffer;
1202 size_t len = block->i_buffer;
1204 while (len > 3 && ((buf[0] << 3) | (buf[1] >> 5)) == 0x3ff) {
1205 int16_t start_trim = 0, end_trim = 0;
1206 int start_trim_flag = (buf[1] >> 4) & 1;
1207 int end_trim_flag = (buf[1] >> 3) & 1;
1208 int control_extension_flag = (buf[1] >> 2) & 1;
1210 len -= 2;
1211 buf += 2;
1213 unsigned au_size = 0;
1214 while (len--) {
1215 int c = *buf++;
1216 au_size += c;
1217 if (c != 0xff)
1218 break;
1221 if (start_trim_flag) {
1222 start_trim = read_opus_flag(&buf, &len);
1223 if (start_trim < 0) {
1224 msg_Err(demux, "Invalid start trimming flag");
1227 if (end_trim_flag) {
1228 end_trim = read_opus_flag(&buf, &len);
1229 if (end_trim < 0) {
1230 msg_Err(demux, "Invalid end trimming flag");
1233 if (control_extension_flag && len) {
1234 unsigned l = *buf++; len--;
1235 if (l > len) {
1236 msg_Err(demux, "Invalid control extension length %d > %zu", l, len);
1237 break;
1239 buf += l;
1240 len -= l;
1243 if (!au_size || au_size > len) {
1244 msg_Err(demux, "Invalid Opus AU size %d (PES %zu)", au_size, len);
1245 break;
1248 block_t *au = block_Alloc(au_size);
1249 if (!au)
1250 break;
1251 memcpy(au->p_buffer, buf, au_size);
1252 block_CopyProperties(au, block);
1253 block_ChainLastAppend( &pp_chain_last, au );
1255 au->i_nb_samples = opus_frame_duration(buf, au_size);
1256 if (end_trim && (uint16_t) end_trim <= au->i_nb_samples)
1257 au->i_length = end_trim; /* Blatant abuse of the i_length field. */
1258 else
1259 au->i_length = 0;
1261 if (start_trim && start_trim < (au->i_nb_samples - au->i_length)) {
1262 au->i_nb_samples -= start_trim;
1263 if (au->i_nb_samples == 0)
1264 au->i_flags |= BLOCK_FLAG_PREROLL;
1267 buf += au_size;
1268 len -= au_size;
1271 block_Release(block);
1272 return p_chain;
1275 static block_t *J2K_Parse( demux_t *p_demux, block_t *p_block, bool b_interlaced )
1277 const uint8_t *p_buf = p_block->p_buffer;
1279 if( p_block->i_buffer < ((b_interlaced) ? 48 : 38) )
1280 goto invalid;
1282 if( memcmp( p_buf, "elsmfrat", 8 ) )
1283 goto invalid;
1285 uint16_t i_den = GetWBE( &p_buf[8] );
1286 uint16_t i_num = GetWBE( &p_buf[10] );
1287 if( i_den == 0 )
1288 goto invalid;
1289 p_block->i_length = CLOCK_FREQ * i_den / i_num;
1291 p_block->p_buffer += (b_interlaced) ? 48 : 38;
1292 p_block->i_buffer -= (b_interlaced) ? 48 : 38;
1294 return p_block;
1296 invalid:
1297 msg_Warn( p_demux, "invalid J2K header, dropping codestream" );
1298 block_Release( p_block );
1299 return NULL;
1302 static block_t * ConvertPESBlock( demux_t *p_demux, ts_es_t *p_es,
1303 size_t i_pes_size, uint8_t i_stream_id,
1304 block_t *p_block )
1306 if(!p_block)
1307 return NULL;
1309 if( p_es->fmt.i_codec == VLC_CODEC_SUBT )
1311 if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )
1313 p_block->i_buffer = i_pes_size;
1315 /* Append a \0 */
1316 p_block = block_Realloc( p_block, 0, p_block->i_buffer + 1 );
1317 if( p_block )
1318 p_block->p_buffer[p_block->i_buffer -1] = '\0';
1320 else if( p_es->fmt.i_codec == VLC_CODEC_TELETEXT )
1322 if( p_block->i_pts <= VLC_TS_INVALID )
1324 /* Teletext may have missing PTS (ETSI EN 300 472 Annexe A)
1325 * In this case use the last PCR + 40ms */
1326 mtime_t i_pcr = p_es->p_program->pcr.i_current;
1327 if( i_pcr > VLC_TS_INVALID )
1328 p_block->i_pts = FROM_SCALE(i_pcr) + 40000;
1331 else if( p_es->fmt.i_codec == VLC_CODEC_ARIB_A ||
1332 p_es->fmt.i_codec == VLC_CODEC_ARIB_C )
1334 if( p_block->i_pts <= VLC_TS_INVALID )
1336 if( i_pes_size > 0 && p_block->i_buffer > i_pes_size )
1338 p_block->i_buffer = i_pes_size;
1340 /* Append a \0 */
1341 p_block = block_Realloc( p_block, 0, p_block->i_buffer + 1 );
1342 if( p_block )
1343 p_block->p_buffer[p_block->i_buffer -1] = '\0';
1346 else if( p_es->fmt.i_codec == VLC_CODEC_OPUS)
1348 p_block = Opus_Parse(p_demux, p_block);
1350 else if( p_es->fmt.i_codec == VLC_CODEC_JPEG2000 )
1352 if( unlikely(i_stream_id != 0xBD) )
1354 block_Release( p_block );
1355 p_block = NULL;
1357 else
1359 p_block = J2K_Parse( p_demux, p_block, p_es->b_interlaced );
1363 return p_block;
1366 /****************************************************************************
1367 * fanouts current block to all subdecoders / shared pid es
1368 ****************************************************************************/
1369 static void SendDataChain( demux_t *p_demux, ts_es_t *p_es, block_t *p_chain )
1371 while( p_chain )
1373 block_t *p_block = p_chain;
1374 p_chain = p_block->p_next;
1375 p_block->p_next = NULL;
1377 ts_es_t *p_es_send = p_es;
1378 if( p_es_send->i_next_block_flags )
1380 p_block->i_flags |= p_es_send->i_next_block_flags;
1381 p_es_send->i_next_block_flags = 0;
1384 while( p_es_send )
1386 if( p_es_send->p_program->b_selected )
1388 /* Send a copy to each extra es */
1389 ts_es_t *p_extra_es = p_es_send->p_extraes;
1390 while( p_extra_es )
1392 if( p_extra_es->id )
1394 block_t *p_dup = block_Duplicate( p_block );
1395 if( p_dup )
1396 es_out_Send( p_demux->out, p_extra_es->id, p_dup );
1398 p_extra_es = p_extra_es->p_next;
1401 if( p_es_send->p_next )
1403 if( p_es_send->id )
1405 block_t *p_dup = block_Duplicate( p_block );
1406 if( p_dup )
1407 es_out_Send( p_demux->out, p_es_send->id, p_dup );
1410 else
1412 if( p_es_send->id )
1414 es_out_Send( p_demux->out, p_es_send->id, p_block );
1415 p_block = NULL;
1419 p_es_send = p_es_send->p_next;
1422 if( p_block )
1423 block_Release( p_block );
1427 /****************************************************************************
1428 * gathering stuff
1429 ****************************************************************************/
1430 static void ParsePESDataChain( demux_t *p_demux, ts_pid_t *pid, block_t *p_pes )
1432 uint8_t header[34];
1433 unsigned i_pes_size = 0;
1434 unsigned i_skip = 0;
1435 mtime_t i_dts = -1;
1436 mtime_t i_pts = -1;
1437 mtime_t i_length = 0;
1438 uint8_t i_stream_id;
1439 bool b_pes_scrambling = false;
1440 const es_mpeg4_descriptor_t *p_mpeg4desc = NULL;
1442 assert(pid->type == TYPE_STREAM);
1444 const int i_max = block_ChainExtract( p_pes, header, 34 );
1445 if ( i_max < 4 )
1447 block_ChainRelease( p_pes );
1448 return;
1451 if( header[0] != 0 || header[1] != 0 || header[2] != 1 )
1453 if ( !(p_pes->i_flags & BLOCK_FLAG_SCRAMBLED) )
1454 msg_Warn( p_demux, "invalid header [0x%02x:%02x:%02x:%02x] (pid: %d)",
1455 header[0], header[1],header[2],header[3], pid->i_pid );
1456 block_ChainRelease( p_pes );
1457 return;
1459 else
1461 /* Incorrect transport scrambling flag set by german boxes */
1462 p_pes->i_flags &= ~BLOCK_FLAG_SCRAMBLED;
1465 ts_es_t *p_es = pid->u.p_stream->p_es;
1467 if( ParsePESHeader( VLC_OBJECT(p_demux), (uint8_t*)&header, i_max, &i_skip,
1468 &i_dts, &i_pts, &i_stream_id, &b_pes_scrambling ) == VLC_EGENERIC )
1470 block_ChainRelease( p_pes );
1471 return;
1473 else
1475 if( i_pts != -1 && p_es->p_program )
1476 i_pts = TimeStampWrapAround( p_es->p_program->pcr.i_first, i_pts );
1477 if( i_dts != -1 && p_es->p_program )
1478 i_dts = TimeStampWrapAround( p_es->p_program->pcr.i_first, i_dts );
1479 if( b_pes_scrambling )
1480 p_pes->i_flags |= BLOCK_FLAG_SCRAMBLED;
1483 if( p_es->i_sl_es_id )
1484 p_mpeg4desc = GetMPEG4DescByEsId( p_es->p_program, p_es->i_sl_es_id );
1486 if( p_es->fmt.i_codec == VLC_FOURCC( 'a', '5', '2', 'b' ) ||
1487 p_es->fmt.i_codec == VLC_FOURCC( 'd', 't', 's', 'b' ) )
1489 i_skip += 4;
1491 else if( p_es->fmt.i_codec == VLC_FOURCC( 'l', 'p', 'c', 'b' ) ||
1492 p_es->fmt.i_codec == VLC_FOURCC( 's', 'p', 'u', 'b' ) ||
1493 p_es->fmt.i_codec == VLC_FOURCC( 's', 'd', 'd', 'b' ) )
1495 i_skip += 1;
1497 else if( p_es->fmt.i_codec == VLC_CODEC_SUBT && p_mpeg4desc )
1499 const decoder_config_descriptor_t *dcd = &p_mpeg4desc->dec_descr;
1501 if( dcd->i_extra > 2 &&
1502 dcd->p_extra[0] == 0x10 &&
1503 ( dcd->p_extra[1]&0x10 ) )
1505 /* display length */
1506 if( p_pes->i_buffer + 2 <= i_skip )
1507 i_length = GetWBE( &p_pes->p_buffer[i_skip] );
1509 i_skip += 2;
1511 if( p_pes->i_buffer + 2 <= i_skip )
1512 i_pes_size = GetWBE( &p_pes->p_buffer[i_skip] );
1513 /* */
1514 i_skip += 2;
1517 /* skip header */
1518 while( p_pes && i_skip > 0 )
1520 if( p_pes->i_buffer <= i_skip )
1522 block_t *p_next = p_pes->p_next;
1524 i_skip -= p_pes->i_buffer;
1525 block_Release( p_pes );
1526 p_pes = p_next;
1528 else
1530 p_pes->i_buffer -= i_skip;
1531 p_pes->p_buffer += i_skip;
1532 break;
1536 /* ISO/IEC 13818-1 2.7.5: if no pts and no dts, then dts == pts */
1537 if( i_pts >= 0 && i_dts < 0 )
1538 i_dts = i_pts;
1540 if( p_pes )
1542 ts_pmt_t *p_pmt = p_es->p_program;
1543 if( unlikely(!p_pmt) )
1545 block_ChainRelease( p_pes );
1546 return;
1549 if( i_dts >= 0 )
1550 p_pes->i_dts = FROM_SCALE(i_dts);
1552 if( i_pts >= 0 )
1553 p_pes->i_pts = FROM_SCALE(i_pts);
1555 p_pes->i_length = FROM_SCALE_NZ(i_length);
1557 /* Can become a chain on next call due to prepcr */
1558 block_t *p_chain = block_ChainGather( p_pes );
1559 while ( p_chain ) {
1560 block_t *p_block = p_chain;
1561 p_chain = p_chain->p_next;
1562 p_block->p_next = NULL;
1564 if( !p_pmt->pcr.b_fix_done ) /* Not seen yet */
1565 PCRFixHandle( p_demux, p_pmt, p_block );
1567 if( p_es->id && (p_pmt->pcr.i_current > -1 || p_pmt->pcr.b_disable) )
1569 if( pid->u.p_stream->prepcr.p_head )
1571 /* Rebuild current output chain, appending any prepcr outqueue */
1572 block_ChainLastAppend( &pid->u.p_stream->prepcr.pp_last, p_block );
1573 if( p_chain )
1574 block_ChainLastAppend( &pid->u.p_stream->prepcr.pp_last, p_chain );
1575 p_chain = pid->u.p_stream->prepcr.p_head;
1576 pid->u.p_stream->prepcr.p_head = NULL;
1577 pid->u.p_stream->prepcr.pp_last = &pid->u.p_stream->prepcr.p_head;
1578 /* Then now output all data */
1579 continue;
1582 if ( p_pmt->pcr.b_disable && p_block->i_dts > VLC_TS_INVALID &&
1583 ( p_pmt->i_pid_pcr == pid->i_pid || p_pmt->i_pid_pcr == 0x1FFF ) )
1585 ProgramSetPCR( p_demux, p_pmt, TO_SCALE(p_block->i_dts) - 120000 );
1588 /* Compute PCR/DTS offset if any */
1589 if( p_pmt->pcr.i_pcroffset == -1 && p_block->i_dts > VLC_TS_INVALID &&
1590 p_pmt->pcr.i_current > VLC_TS_INVALID &&
1591 (p_es->fmt.i_cat == VIDEO_ES || p_es->fmt.i_cat == AUDIO_ES) )
1593 int64_t i_dts27 = TO_SCALE(p_block->i_dts);
1594 i_dts27 = TimeStampWrapAround( p_pmt->pcr.i_first, i_dts27 );
1595 int64_t i_pcr = TimeStampWrapAround( p_pmt->pcr.i_first, p_pmt->pcr.i_current );
1596 if( i_dts27 < i_pcr )
1598 p_pmt->pcr.i_pcroffset = i_pcr - i_dts27 + 80000;
1599 msg_Warn( p_demux, "Broken stream: pid %d sends packets with dts %"PRId64
1600 "us later than pcr, applying delay",
1601 pid->i_pid, FROM_SCALE_NZ(p_pmt->pcr.i_pcroffset) );
1603 else p_pmt->pcr.i_pcroffset = 0;
1606 if( p_pmt->pcr.i_pcroffset != -1 )
1608 if( p_block->i_dts > VLC_TS_INVALID )
1609 p_block->i_dts += FROM_SCALE_NZ(p_pmt->pcr.i_pcroffset);
1610 if( p_block->i_pts > VLC_TS_INVALID )
1611 p_block->i_pts += FROM_SCALE_NZ(p_pmt->pcr.i_pcroffset);
1614 /*** From here, block can become a chain again though conversion below ***/
1616 if( pid->u.p_stream->p_proc )
1618 if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
1619 ts_stream_processor_Reset( pid->u.p_stream->p_proc );
1620 p_block = ts_stream_processor_Push( pid->u.p_stream->p_proc, i_stream_id, p_block );
1622 else
1623 /* Some codecs might need xform or AU splitting */
1625 p_block = ConvertPESBlock( p_demux, p_es, i_pes_size, i_stream_id, p_block );
1628 SendDataChain( p_demux, p_es, p_block );
1630 else
1632 if( !p_pmt->pcr.b_fix_done ) /* Not seen yet */
1633 PCRFixHandle( p_demux, p_pmt, p_block );
1635 block_ChainLastAppend( &pid->u.p_stream->prepcr.pp_last, p_block );
1637 /* PCR Seen and no es->id, cleanup current and prepcr blocks */
1638 if( p_pmt->pcr.i_current > -1)
1640 block_ChainRelease( pid->u.p_stream->prepcr.p_head );
1641 pid->u.p_stream->prepcr.p_head = NULL;
1642 pid->u.p_stream->prepcr.pp_last = &pid->u.p_stream->prepcr.p_head;
1647 else
1649 msg_Warn( p_demux, "empty pes" );
1653 static bool PushPESBlock( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, bool b_unit_start )
1655 bool b_ret = false;
1656 ts_stream_t *p_pes = pid->u.p_stream;
1658 if ( b_unit_start && p_pes->gather.p_data )
1660 block_t *p_datachain = p_pes->gather.p_data;
1661 /* Flush the pes from pid */
1662 p_pes->gather.p_data = NULL;
1663 p_pes->gather.i_data_size = 0;
1664 p_pes->gather.i_gathered = 0;
1665 p_pes->gather.pp_last = &p_pes->gather.p_data;
1666 ParsePESDataChain( p_demux, pid, p_datachain );
1667 b_ret = true;
1670 if( p_pkt == NULL )
1671 return b_ret;
1673 if( !b_unit_start && p_pes->gather.p_data == NULL )
1675 /* msg_Dbg( p_demux, "broken packet" ); */
1676 block_Release( p_pkt );
1677 return b_ret;
1680 block_ChainLastAppend( &p_pes->gather.pp_last, p_pkt );
1681 p_pes->gather.i_gathered += p_pkt->i_buffer;
1683 if( p_pes->gather.i_data_size > 0 &&
1684 p_pes->gather.i_gathered >= p_pes->gather.i_data_size )
1686 /* re-enter in Flush above */
1687 assert(p_pes->gather.p_data);
1688 return PushPESBlock( p_demux, pid, NULL, true );
1691 return b_ret;
1694 static block_t* ReadTSPacket( demux_t *p_demux )
1696 demux_sys_t *p_sys = p_demux->p_sys;
1698 block_t *p_pkt;
1700 /* Get a new TS packet */
1701 if( !( p_pkt = vlc_stream_Block( p_sys->stream, p_sys->i_packet_size ) ) )
1703 int64_t size = stream_Size( p_sys->stream );
1704 if( size >= 0 && (uint64_t)size == vlc_stream_Tell( p_sys->stream ) )
1705 msg_Dbg( p_demux, "EOF at %"PRIu64, vlc_stream_Tell( p_sys->stream ) );
1706 else
1707 msg_Dbg( p_demux, "Can't read TS packet at %"PRIu64, vlc_stream_Tell(p_sys->stream) );
1708 return NULL;
1711 if( p_pkt->i_buffer < TS_HEADER_SIZE + p_sys->i_packet_header_size )
1713 block_Release( p_pkt );
1714 return NULL;
1717 /* Skip header (BluRay streams).
1718 * re-sync logic would do this (by adjusting packet start), but this would result in losing first and last ts packets.
1719 * First packet is usually PAT, and losing it means losing whole first GOP. This is fatal with still-image based menus.
1721 p_pkt->p_buffer += p_sys->i_packet_header_size;
1722 p_pkt->i_buffer -= p_sys->i_packet_header_size;
1724 /* Check sync byte and re-sync if needed */
1725 if( p_pkt->p_buffer[0] != 0x47 )
1727 msg_Warn( p_demux, "lost synchro" );
1728 block_Release( p_pkt );
1729 for( ;; )
1731 const uint8_t *p_peek;
1732 int i_peek = 0;
1733 unsigned i_skip = 0;
1735 i_peek = vlc_stream_Peek( p_sys->stream, &p_peek,
1736 p_sys->i_packet_size * 10 );
1737 if( i_peek < 0 || (unsigned)i_peek < p_sys->i_packet_size + 1 )
1739 msg_Dbg( p_demux, "eof ?" );
1740 return NULL;
1743 while( i_skip < i_peek - p_sys->i_packet_size )
1745 if( p_peek[i_skip + p_sys->i_packet_header_size] == 0x47 &&
1746 p_peek[i_skip + p_sys->i_packet_header_size + p_sys->i_packet_size] == 0x47 )
1748 break;
1750 i_skip++;
1752 msg_Dbg( p_demux, "skipping %d bytes of garbage", i_skip );
1753 if (vlc_stream_Read( p_sys->stream, NULL, i_skip ) != i_skip)
1754 return NULL;
1756 if( i_skip < i_peek - p_sys->i_packet_size )
1758 break;
1761 if( !( p_pkt = vlc_stream_Block( p_sys->stream, p_sys->i_packet_size ) ) )
1763 msg_Dbg( p_demux, "eof ?" );
1764 return NULL;
1767 return p_pkt;
1770 static mtime_t GetPCR( const block_t *p_pkt )
1772 const uint8_t *p = p_pkt->p_buffer;
1774 mtime_t i_pcr = -1;
1776 if( likely(p_pkt->i_buffer > 11) &&
1777 ( p[3]&0x20 ) && /* adaptation */
1778 ( p[5]&0x10 ) &&
1779 ( p[4] >= 7 ) )
1781 /* PCR is 33 bits */
1782 i_pcr = ( (mtime_t)p[6] << 25 ) |
1783 ( (mtime_t)p[7] << 17 ) |
1784 ( (mtime_t)p[8] << 9 ) |
1785 ( (mtime_t)p[9] << 1 ) |
1786 ( (mtime_t)p[10] >> 7 );
1788 return i_pcr;
1791 static inline void UpdateESScrambledState( es_out_t *out, const ts_es_t *p_es, bool b_scrambled )
1793 for( ; p_es; p_es = p_es->p_next )
1795 if( p_es->id )
1796 es_out_Control( out, ES_OUT_SET_ES_SCRAMBLED_STATE,
1797 p_es->id, b_scrambled );
1798 UpdateESScrambledState( out, p_es->p_extraes, b_scrambled );
1802 static void UpdatePIDScrambledState( demux_t *p_demux, ts_pid_t *p_pid, bool b_scrambled )
1804 if( !SCRAMBLED(*p_pid) == !b_scrambled )
1805 return;
1807 msg_Warn( p_demux, "scrambled state changed on pid %d (%d->%d)",
1808 p_pid->i_pid, !!SCRAMBLED(*p_pid), b_scrambled );
1810 if( b_scrambled )
1811 p_pid->i_flags |= FLAG_SCRAMBLED;
1812 else
1813 p_pid->i_flags &= ~FLAG_SCRAMBLED;
1815 if( p_pid->type == TYPE_STREAM )
1816 UpdateESScrambledState( p_demux->out, p_pid->u.p_stream->p_es, b_scrambled );
1819 static inline void FlushESBuffer( ts_stream_t *p_pes )
1821 if( p_pes->gather.p_data )
1823 p_pes->gather.i_gathered = p_pes->gather.i_data_size = 0;
1824 block_ChainRelease( p_pes->gather.p_data );
1825 p_pes->gather.p_data = NULL;
1826 p_pes->gather.pp_last = &p_pes->gather.p_data;
1827 p_pes->gather.i_saved = 0;
1829 if( p_pes->p_proc )
1830 ts_stream_processor_Reset( p_pes->p_proc );
1833 static void ReadyQueuesPostSeek( demux_t *p_demux )
1835 demux_sys_t *p_sys = p_demux->p_sys;
1837 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
1838 for( int i=0; i< p_pat->programs.i_size; i++ )
1840 ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
1841 for( int j=0; j<p_pmt->e_streams.i_size; j++ )
1843 ts_pid_t *pid = p_pmt->e_streams.p_elems[j];
1844 ts_stream_t *p_pes = pid->u.p_stream;
1846 if( pid->type != TYPE_STREAM )
1847 continue;
1849 for( ts_es_t *p_es = p_pes->p_es; p_es; p_es = p_es->p_next )
1850 p_es->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
1852 pid->i_cc = 0xff;
1854 if( pid->u.p_stream->prepcr.p_head )
1856 block_ChainRelease( pid->u.p_stream->prepcr.p_head );
1857 pid->u.p_stream->prepcr.p_head = NULL;
1858 pid->u.p_stream->prepcr.pp_last = &pid->u.p_stream->prepcr.p_head;
1861 ts_sections_processor_Reset( pid->u.p_stream->p_sections_proc );
1862 ts_stream_processor_Reset( pid->u.p_stream->p_proc );
1864 FlushESBuffer( pid->u.p_stream );
1866 p_pmt->pcr.i_current = -1;
1870 static int SeekToTime( demux_t *p_demux, const ts_pmt_t *p_pmt, int64_t i_scaledtime )
1872 demux_sys_t *p_sys = p_demux->p_sys;
1874 /* Deal with common but worst binary search case */
1875 if( p_pmt->pcr.i_first == i_scaledtime && p_sys->b_canseek )
1876 return vlc_stream_Seek( p_sys->stream, 0 );
1878 const int64_t i_stream_size = stream_Size( p_sys->stream );
1879 if( !p_sys->b_canfastseek || i_stream_size < p_sys->i_packet_size )
1880 return VLC_EGENERIC;
1882 const uint64_t i_initial_pos = vlc_stream_Tell( p_sys->stream );
1884 /* Find the time position by using binary search algorithm. */
1885 uint64_t i_head_pos = 0;
1886 uint64_t i_tail_pos = (uint64_t) i_stream_size - p_sys->i_packet_size;
1887 if( i_head_pos >= i_tail_pos )
1888 return VLC_EGENERIC;
1890 bool b_found = false;
1891 while( (i_head_pos + p_sys->i_packet_size) <= i_tail_pos && !b_found )
1893 /* Round i_pos to a multiple of p_sys->i_packet_size */
1894 uint64_t i_splitpos = i_head_pos + (i_tail_pos - i_head_pos) / 2;
1895 uint64_t i_div = i_splitpos % p_sys->i_packet_size;
1896 i_splitpos -= i_div;
1898 if ( vlc_stream_Seek( p_sys->stream, i_splitpos ) != VLC_SUCCESS )
1899 break;
1901 uint64_t i_pos = i_splitpos;
1902 while( i_pos < i_tail_pos )
1904 int64_t i_pcr = -1;
1905 block_t *p_pkt = ReadTSPacket( p_demux );
1906 if( !p_pkt )
1908 i_head_pos = i_tail_pos;
1909 break;
1911 else
1912 i_pos = vlc_stream_Tell( p_sys->stream );
1914 int i_pid = PIDGet( p_pkt );
1915 ts_pid_t *p_pid = GetPID(p_sys, i_pid);
1916 if( i_pid != 0x1FFF && p_pid->type == TYPE_STREAM &&
1917 ts_stream_Find_es( p_pid->u.p_stream, p_pmt ) &&
1918 (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* Payload start but not corrupt */
1919 (p_pkt->p_buffer[3] & 0xD0) == 0x10 /* Has payload but is not encrypted */
1922 unsigned i_skip = 4;
1923 if ( p_pkt->p_buffer[3] & 0x20 ) // adaptation field
1925 if( p_pkt->i_buffer >= 4 + 2 + 5 )
1927 if( p_pmt->i_pid_pcr == i_pid )
1928 i_pcr = GetPCR( p_pkt );
1929 i_skip += 1 + __MIN(p_pkt->p_buffer[4], 182);
1933 if( i_pcr == -1 )
1935 mtime_t i_dts = -1;
1936 mtime_t i_pts = -1;
1937 uint8_t i_stream_id;
1938 if ( VLC_SUCCESS == ParsePESHeader( VLC_OBJECT(p_demux), &p_pkt->p_buffer[i_skip],
1939 p_pkt->i_buffer - i_skip, &i_skip,
1940 &i_dts, &i_pts, &i_stream_id, NULL ) )
1942 if( i_dts > -1 )
1943 i_pcr = i_dts;
1947 block_Release( p_pkt );
1949 if( i_pcr != -1 )
1951 int64_t i_diff = i_scaledtime - TimeStampWrapAround( p_pmt->pcr.i_first, i_pcr );
1952 if ( i_diff < 0 )
1953 i_tail_pos = (i_splitpos >= p_sys->i_packet_size) ? i_splitpos - p_sys->i_packet_size : 0;
1954 else if( i_diff < TO_SCALE(VLC_TS_0 + CLOCK_FREQ / 2) ) // 500ms
1955 b_found = true;
1956 else
1957 i_head_pos = i_pos;
1958 break;
1962 if ( !b_found && i_pos + p_sys->i_packet_size > i_tail_pos )
1963 i_tail_pos = (i_splitpos >= p_sys->i_packet_size) ? i_splitpos - p_sys->i_packet_size : 0;
1966 if( !b_found )
1968 msg_Dbg( p_demux, "Seek():cannot find a time position." );
1969 vlc_stream_Seek( p_sys->stream, i_initial_pos );
1970 return VLC_EGENERIC;
1972 return VLC_SUCCESS;
1975 #define PROBE_CHUNK_COUNT 250
1977 static int ProbeChunk( demux_t *p_demux, int i_program, bool b_end, int64_t *pi_pcr, bool *pb_found )
1979 demux_sys_t *p_sys = p_demux->p_sys;
1980 int i_count = 0;
1981 block_t *p_pkt = NULL;
1983 for( ;; )
1985 *pi_pcr = -1;
1987 if( i_count++ > PROBE_CHUNK_COUNT || !( p_pkt = ReadTSPacket( p_demux ) ) )
1989 break;
1992 if( p_pkt->i_size < TS_PACKET_SIZE_188 &&
1993 ( p_pkt->p_buffer[1]&0x80 ) /* transport error */ )
1995 block_Release( p_pkt );
1996 continue;
1999 const int i_pid = PIDGet( p_pkt );
2000 ts_pid_t *p_pid = GetPID(p_sys, i_pid);
2002 p_pid->i_flags |= FLAG_SEEN;
2004 if( i_pid != 0x1FFF && (p_pkt->p_buffer[1] & 0x80) == 0 ) /* not corrupt */
2006 bool b_pcrresult = true;
2007 bool b_adaptfield = p_pkt->p_buffer[3] & 0x20;
2009 if( b_adaptfield && p_pkt->i_buffer >= 4 + 2 + 5 )
2010 *pi_pcr = GetPCR( p_pkt );
2012 if( *pi_pcr == -1 &&
2013 (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* payload start */
2014 (p_pkt->p_buffer[3] & 0xD0) == 0x10 && /* Has payload but is not encrypted */
2015 p_pid->type == TYPE_STREAM &&
2016 p_pid->u.p_stream->p_es->fmt.i_cat != UNKNOWN_ES
2019 b_pcrresult = false;
2020 mtime_t i_dts = -1;
2021 mtime_t i_pts = -1;
2022 uint8_t i_stream_id;
2023 unsigned i_skip = 4;
2024 if ( b_adaptfield ) // adaptation field
2025 i_skip += 1 + __MIN(p_pkt->p_buffer[4], 182);
2027 if ( VLC_SUCCESS == ParsePESHeader( VLC_OBJECT(p_demux), &p_pkt->p_buffer[i_skip],
2028 p_pkt->i_buffer - i_skip, &i_skip,
2029 &i_dts, &i_pts, &i_stream_id, NULL ) )
2031 if( i_dts != -1 )
2032 *pi_pcr = i_dts;
2033 else if( i_pts != -1 )
2034 *pi_pcr = i_pts;
2038 if( *pi_pcr != -1 )
2040 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2041 for( int i=0; i<p_pat->programs.i_size; i++ )
2043 ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
2044 if( p_pmt->i_pid_pcr == p_pid->i_pid ||
2045 ( p_pmt->i_pid_pcr == 0x1FFF &&
2046 PIDReferencedByProgram( p_pmt, p_pid->i_pid ) )
2049 if( b_end )
2051 p_pmt->i_last_dts = *pi_pcr;
2052 p_pmt->i_last_dts_byte = vlc_stream_Tell( p_sys->stream );
2054 /* Start, only keep first */
2055 else if( b_pcrresult && p_pmt->pcr.i_first == -1 )
2057 p_pmt->pcr.i_first = *pi_pcr;
2059 else if( p_pmt->pcr.i_first_dts < VLC_TS_0 )
2061 p_pmt->pcr.i_first_dts = FROM_SCALE(*pi_pcr);
2064 if( i_program == 0 || i_program == p_pmt->i_number )
2065 *pb_found = true;
2071 block_Release( p_pkt );
2074 return i_count;
2077 int ProbeStart( demux_t *p_demux, int i_program )
2079 demux_sys_t *p_sys = p_demux->p_sys;
2080 const uint64_t i_initial_pos = vlc_stream_Tell( p_sys->stream );
2081 int64_t i_stream_size = stream_Size( p_sys->stream );
2083 int i_probe_count = 0;
2084 int64_t i_pos;
2085 mtime_t i_pcr = -1;
2086 bool b_found = false;
2090 i_pos = p_sys->i_packet_size * i_probe_count;
2091 i_pos = __MIN( i_pos, i_stream_size );
2093 if( vlc_stream_Seek( p_sys->stream, i_pos ) )
2094 return VLC_EGENERIC;
2096 ProbeChunk( p_demux, i_program, false, &i_pcr, &b_found );
2098 /* Go ahead one more chunk if end of file contained only stuffing packets */
2099 i_probe_count += PROBE_CHUNK_COUNT;
2100 } while( i_pos > 0 && (i_pcr == -1 || !b_found) && i_probe_count < (2 * PROBE_CHUNK_COUNT) );
2102 if( vlc_stream_Seek( p_sys->stream, i_initial_pos ) )
2103 return VLC_EGENERIC;
2105 return (b_found) ? VLC_SUCCESS : VLC_EGENERIC;
2108 int ProbeEnd( demux_t *p_demux, int i_program )
2110 demux_sys_t *p_sys = p_demux->p_sys;
2111 const uint64_t i_initial_pos = vlc_stream_Tell( p_sys->stream );
2112 int64_t i_stream_size = stream_Size( p_sys->stream );
2114 int i_probe_count = PROBE_CHUNK_COUNT;
2115 int64_t i_pos;
2116 mtime_t i_pcr = -1;
2117 bool b_found = false;
2121 i_pos = i_stream_size - (p_sys->i_packet_size * i_probe_count);
2122 i_pos = __MAX( i_pos, 0 );
2124 if( vlc_stream_Seek( p_sys->stream, i_pos ) )
2125 return VLC_EGENERIC;
2127 ProbeChunk( p_demux, i_program, true, &i_pcr, &b_found );
2129 /* Go ahead one more chunk if end of file contained only stuffing packets */
2130 i_probe_count += PROBE_CHUNK_COUNT;
2131 } while( i_pos > 0 && (i_pcr == -1 || !b_found) && i_probe_count < (6 * PROBE_CHUNK_COUNT) );
2133 if( vlc_stream_Seek( p_sys->stream, i_initial_pos ) )
2134 return VLC_EGENERIC;
2136 return (b_found) ? VLC_SUCCESS : VLC_EGENERIC;
2139 static void ProgramSetPCR( demux_t *p_demux, ts_pmt_t *p_pmt, mtime_t i_pcr )
2141 demux_sys_t *p_sys = p_demux->p_sys;
2143 /* Check if we have enqueued blocks waiting the/before the
2144 PCR barrier, and then adapt pcr so they have valid PCR when dequeuing */
2145 if( p_pmt->pcr.i_current == -1 && p_pmt->pcr.b_fix_done )
2147 mtime_t i_mindts = -1;
2149 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2150 for( int i=0; i< p_pat->programs.i_size; i++ )
2152 ts_pmt_t *p_opmt = p_pat->programs.p_elems[i]->u.p_pmt;
2153 for( int j=0; j<p_opmt->e_streams.i_size; j++ )
2155 ts_pid_t *p_pid = p_opmt->e_streams.p_elems[j];
2156 block_t *p_block = p_pid->u.p_stream->prepcr.p_head;
2157 while( p_block && p_block->i_dts == VLC_TS_INVALID )
2158 p_block = p_block->p_next;
2160 if( p_block && ( i_mindts == -1 || p_block->i_dts < i_mindts ) )
2161 i_mindts = p_block->i_dts;
2165 if( i_mindts > VLC_TS_INVALID )
2167 msg_Dbg( p_demux, "Program %d PCR prequeue fixup %"PRId64"->%"PRId64,
2168 p_pmt->i_number, TO_SCALE(i_mindts), i_pcr );
2169 i_pcr = TO_SCALE(i_mindts);
2173 p_pmt->pcr.i_current = i_pcr;
2174 if( p_pmt->pcr.i_first == -1 )
2176 p_pmt->pcr.i_first = i_pcr; // now seen
2179 if ( p_sys->i_pmt_es )
2181 es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR, p_pmt->i_number, FROM_SCALE(i_pcr) );
2182 /* growing files/named fifo handling */
2183 if( p_sys->b_access_control == false &&
2184 vlc_stream_Tell( p_sys->stream ) > p_pmt->i_last_dts_byte )
2186 p_pmt->i_last_dts = i_pcr;
2187 p_pmt->i_last_dts_byte = vlc_stream_Tell( p_sys->stream );
2192 static int IsVideoEnd( ts_pid_t *p_pid )
2194 /* jump to near end of PES packet */
2195 block_t *p = p_pid->u.p_stream->gather.p_data;
2196 if( !p || !p->p_next )
2197 return 0;
2198 while( p->p_next->p_next )
2199 p = p->p_next;
2200 if( p->p_next->i_buffer > 4)
2201 p = p->p_next;
2203 /* extract last bytes */
2204 uint8_t tail[ 188 ];
2205 const int i_tail = block_ChainExtract( p, tail, sizeof( tail ) );
2206 if( i_tail < 4 )
2207 return 0;
2209 /* check for start code at end */
2210 return ( tail[ i_tail - 4 ] == 0 && tail[ i_tail - 3 ] == 0 && tail[ i_tail - 2 ] == 1 &&
2211 ( tail[ i_tail - 1 ] == 0xb7 || tail[ i_tail - 1 ] == 0x0a ) );
2214 static void PCRCheckDTS( demux_t *p_demux, ts_pmt_t *p_pmt, mtime_t i_pcr)
2216 for( int i=0; i<p_pmt->e_streams.i_size; i++ )
2218 ts_pid_t *p_pid = p_pmt->e_streams.p_elems[i];
2220 if( p_pid->type != TYPE_STREAM || SCRAMBLED(*p_pid) )
2221 continue;
2223 ts_stream_t *p_pes = p_pid->u.p_stream;
2224 ts_es_t *p_es = p_pes->p_es;
2226 if( p_pes->gather.p_data == NULL )
2227 continue;
2228 if( p_pes->gather.i_data_size != 0 )
2229 continue;
2231 /* check only MPEG2, H.264 and VC-1 */
2232 if( p_es->fmt.i_codec != VLC_CODEC_MPGV &&
2233 p_es->fmt.i_codec != VLC_CODEC_H264 &&
2234 p_es->fmt.i_codec != VLC_CODEC_VC1 )
2235 continue;
2237 uint8_t header[34];
2238 const int i_max = block_ChainExtract( p_pes->gather.p_data, header, 34 );
2240 if( i_max < 6 || header[0] != 0 || header[1] != 0 || header[2] != 1 )
2241 continue;
2243 unsigned i_skip = 0;
2244 mtime_t i_dts = -1;
2245 mtime_t i_pts = -1;
2246 uint8_t i_stream_id;
2248 if( ParsePESHeader( VLC_OBJECT(p_demux), (uint8_t*)&header, i_max, &i_skip,
2249 &i_dts, &i_pts, &i_stream_id, NULL ) == VLC_EGENERIC )
2250 continue;
2252 if (p_pmt->pcr.i_pcroffset > 0) {
2253 if( i_dts > VLC_TS_INVALID )
2254 i_dts += p_pmt->pcr.i_pcroffset;
2255 if( i_pts > VLC_TS_INVALID )
2256 i_pts += p_pmt->pcr.i_pcroffset;
2259 if( i_dts > VLC_TS_INVALID )
2260 i_dts = TimeStampWrapAround( i_pcr, i_dts );
2261 if( i_pts > VLC_TS_INVALID )
2262 i_pts = TimeStampWrapAround( i_pcr, i_pts );
2264 if(( i_dts > VLC_TS_INVALID && i_dts <= i_pcr ) ||
2265 ( i_pts > VLC_TS_INVALID && i_pts <= i_pcr ))
2267 if( IsVideoEnd( p_pid ) )
2269 msg_Warn( p_demux, "send queued data for pid %d: TS %"PRId64" <= PCR %"PRId64"\n",
2270 p_pid->i_pid, i_dts > VLC_TS_INVALID ? i_dts : i_pts, i_pcr);
2271 PushPESBlock( p_demux, p_pid, NULL, true ); /* Flush */
2277 static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, mtime_t i_pcr )
2279 demux_sys_t *p_sys = p_demux->p_sys;
2281 pid->probed.i_pcr_count++;
2283 if( p_sys->i_pmt_es <= 0 )
2284 return;
2286 if(unlikely(GetPID(p_sys, 0)->type != TYPE_PAT))
2287 return;
2289 /* Search program and set the PCR */
2290 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2291 for( int i = 0; i < p_pat->programs.i_size; i++ )
2293 ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
2294 if( p_pmt->pcr.b_disable )
2295 continue;
2296 mtime_t i_program_pcr = TimeStampWrapAround( p_pmt->pcr.i_first, i_pcr );
2298 if( p_pmt->i_pid_pcr == 0x1FFF ) /* That program has no dedicated PCR pid ISO/IEC 13818-1 2.4.4.9 */
2300 if( PIDReferencedByProgram( p_pmt, pid->i_pid ) ) /* PCR shall be on pid itself */
2302 /* ? update PCR for the whole group program ? */
2303 ProgramSetPCR( p_demux, p_pmt, i_program_pcr );
2306 else /* set PCR provided by current pid to program(s) referencing it */
2308 /* Can be dedicated PCR pid (no owned then) or another pid (owner == pmt) */
2309 if( p_pmt->i_pid_pcr == pid->i_pid ) /* If that program references current pid as PCR */
2311 /* We've found a target group for update */
2312 PCRCheckDTS( p_demux, p_pmt, i_pcr );
2313 ProgramSetPCR( p_demux, p_pmt, i_program_pcr );
2320 int FindPCRCandidate( ts_pmt_t *p_pmt )
2322 ts_pid_t *p_cand = NULL;
2323 int i_previous = p_pmt->i_pid_pcr;
2325 for( int i=0; i<p_pmt->e_streams.i_size; i++ )
2327 ts_pid_t *p_pid = p_pmt->e_streams.p_elems[i];
2328 if( SEEN(p_pid) && p_pid->i_pid != i_previous )
2330 if( p_pid->probed.i_pcr_count ) /* check PCR frequency first */
2332 if( !p_cand || p_pid->probed.i_pcr_count > p_cand->probed.i_pcr_count )
2334 p_cand = p_pid;
2335 continue;
2339 if( p_pid->u.p_stream->p_es->fmt.i_cat == AUDIO_ES )
2341 if( !p_cand )
2342 p_cand = p_pid;
2344 else if ( p_pid->u.p_stream->p_es->fmt.i_cat == VIDEO_ES ) /* Otherwise prioritize video dts */
2346 if( !p_cand || p_cand->u.p_stream->p_es->fmt.i_cat == AUDIO_ES )
2347 p_cand = p_pid;
2352 if( p_cand )
2353 return p_cand->i_pid;
2354 else
2355 return 0x1FFF;
2358 /* Tries to reselect a new PCR when none has been received */
2359 static void PCRFixHandle( demux_t *p_demux, ts_pmt_t *p_pmt, block_t *p_block )
2361 if ( p_pmt->pcr.b_disable || p_pmt->pcr.b_fix_done )
2363 return;
2365 /* Record the first data packet timestamp in case there wont be any PCR */
2366 else if( !p_pmt->pcr.i_first_dts )
2368 p_pmt->pcr.i_first_dts = p_block->i_dts;
2370 else if( p_block->i_dts - p_pmt->pcr.i_first_dts > CLOCK_FREQ / 2 ) /* "PCR repeat rate shall not exceed 100ms" */
2372 if( p_pmt->pcr.i_current < 0 &&
2373 GetPID( p_demux->p_sys, p_pmt->i_pid_pcr )->probed.i_pcr_count == 0 )
2375 int i_cand = FindPCRCandidate( p_pmt );
2376 p_pmt->i_pid_pcr = i_cand;
2377 if ( GetPID( p_demux->p_sys, p_pmt->i_pid_pcr )->probed.i_pcr_count == 0 )
2378 p_pmt->pcr.b_disable = true;
2379 msg_Warn( p_demux, "No PCR received for program %d, set up workaround using pid %d",
2380 p_pmt->i_number, i_cand );
2381 UpdatePESFilters( p_demux, p_demux->p_sys->seltype == PROGRAM_ALL );
2383 p_pmt->pcr.b_fix_done = true;
2387 static block_t * ProcessTSPacket( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, int *pi_skip )
2389 const uint8_t *p = p_pkt->p_buffer;
2390 const bool b_adaptation = p[3]&0x20;
2391 const bool b_payload = p[3]&0x10;
2392 const bool b_scrambled = p[3]&0xc0;
2393 const int i_cc = p[3]&0x0f; /* continuity counter */
2394 bool b_discontinuity = false; /* discontinuity */
2396 /* transport_scrambling_control is ignored */
2397 *pi_skip = 4;
2399 #if 0
2400 msg_Dbg( p_demux, "pid=%d unit_start=%d adaptation=%d payload=%d "
2401 "cc=0x%x", pid->i_pid, b_unit_start, b_adaptation,
2402 b_payload, i_cc );
2403 #endif
2405 /* Drop null packets */
2406 if( unlikely(pid->i_pid == 0x1FFF) )
2408 block_Release( p_pkt );
2409 return NULL;
2412 /* For now, ignore additional error correction
2413 * TODO: handle Reed-Solomon 204,188 error correction */
2414 p_pkt->i_buffer = TS_PACKET_SIZE_188;
2416 if( b_scrambled )
2418 if( p_demux->p_sys->csa )
2420 vlc_mutex_lock( &p_demux->p_sys->csa_lock );
2421 csa_Decrypt( p_demux->p_sys->csa, p_pkt->p_buffer, p_demux->p_sys->i_csa_pkt_size );
2422 vlc_mutex_unlock( &p_demux->p_sys->csa_lock );
2424 else
2425 p_pkt->i_flags |= BLOCK_FLAG_SCRAMBLED;
2428 /* We don't have any adaptation_field, so payload starts
2429 * immediately after the 4 byte TS header */
2430 if( b_adaptation )
2432 /* p[4] is adaptation_field_length minus one */
2433 *pi_skip += 1 + p[4];
2434 if( p[4] + 5 > 188 /* adaptation field only == 188 */ )
2436 /* Broken is broken */
2437 block_Release( p_pkt );
2438 return NULL;
2440 else if( p[4] > 0 )
2442 /* discontinuity indicator found in stream */
2443 b_discontinuity = (p[5]&0x80) ? true : false;
2444 if( b_discontinuity )
2446 msg_Warn( p_demux, "discontinuity indicator (pid=%d) ",
2447 pid->i_pid );
2448 p_pkt->i_flags |= BLOCK_FLAG_DISCONTINUITY;
2450 #if 0
2451 if( p[5]&0x40 )
2452 msg_Dbg( p_demux, "random access indicator (pid=%d) ", pid->i_pid );
2453 #endif
2457 /* Test continuity counter */
2458 /* continuous when (one of this):
2459 * diff == 1
2460 * diff == 0 and payload == 0
2461 * diff == 0 and duplicate packet (playload != 0) <- should we
2462 * test the content ?
2464 if( b_payload )
2466 const int i_diff = ( i_cc - pid->i_cc )&0x0f;
2467 if( i_diff == 1 )
2469 pid->i_cc = ( pid->i_cc + 1 ) & 0xf;
2470 pid->i_dup = 0;
2472 else
2474 if( pid->i_cc == 0xff )
2476 msg_Dbg( p_demux, "first packet for pid=%d cc=0x%x",
2477 pid->i_pid, i_cc );
2478 pid->i_cc = i_cc;
2480 else if( i_diff == 0 && pid->i_dup == 0 )
2482 /* Discard duplicated payload 2.4.3.3 */
2483 pid->i_dup++;
2484 block_Release( p_pkt );
2485 return NULL;
2487 else if( i_diff != 0 && !b_discontinuity )
2489 msg_Warn( p_demux, "discontinuity received 0x%x instead of 0x%x (pid=%d)",
2490 i_cc, ( pid->i_cc + 1 )&0x0f, pid->i_pid );
2492 pid->i_cc = i_cc;
2493 pid->i_dup = 0;
2494 p_pkt->i_flags |= BLOCK_FLAG_DISCONTINUITY;
2496 else pid->i_cc = i_cc;
2499 else /* Ignore all 00 or 10 as in 2.4.3.3 CC counter must not be
2500 incremented in those cases, but there is humax inserting
2501 empty/10 packets always set with cc = 0 between 2 payload pkts
2502 see stream_main_pcr_1280x720p50_5mbps.ts */
2504 if( b_discontinuity )
2505 pid->i_cc = i_cc;
2508 if( unlikely(!(b_payload || b_adaptation)) ) /* Invalid, ignore */
2510 block_Release( p_pkt );
2511 return NULL;
2514 return p_pkt;
2517 /* Avoids largest memcpy */
2518 static bool block_Split( block_t **pp_block, block_t **pp_remain, size_t i_offset )
2520 block_t *p_block = *pp_block;
2521 block_t *p_split = NULL;
2522 *pp_remain = NULL;
2524 size_t i_tocopy = p_block->i_buffer - i_offset;
2525 if( i_tocopy > i_offset ) /* make new block for head */
2527 if( i_offset > 0 )
2529 p_split = block_Alloc( i_offset );
2530 if( p_split == NULL )
2531 return false;
2532 memcpy( p_split->p_buffer, p_block->p_buffer, i_offset );
2533 p_block->p_buffer += i_offset;
2534 p_block->i_buffer -= i_offset;
2536 *pp_remain = p_block;
2537 *pp_block = p_split;
2539 else /* other gets the tail of our split */
2541 if( i_tocopy > 0 )
2543 p_split = block_Alloc( i_tocopy );
2544 if( p_split == NULL )
2545 return false;
2546 memcpy( p_split->p_buffer, &p_block->p_buffer[i_offset], i_tocopy );
2547 p_block->i_buffer -= i_tocopy;
2549 *pp_remain = p_split;
2551 return true;
2554 static uint8_t *FindNextPESHeader( uint8_t *p_buf, size_t i_buffer )
2556 const uint8_t *p_end = &p_buf[i_buffer];
2557 unsigned i_bitflow = 0;
2558 for( ; p_buf != p_end; p_buf++ )
2560 i_bitflow <<= 1;
2561 if( !*p_buf )
2563 i_bitflow |= 1;
2565 else if( *p_buf == 0x01 && (i_bitflow & 0x06) == 0x06 ) /* >= two zero prefixed 1 */
2567 return p_buf - 2;
2570 return NULL;
2573 static const uint8_t pes_sync[] = { 0, 0, 1 };
2575 static bool MayHaveStartCodeOnEnd( const uint8_t *p_buf, size_t i_buf )
2577 assert(i_buf > 2);
2578 return !( *(--p_buf) > 1 || *(--p_buf) > 0 || *(--p_buf) > 0 );
2581 static bool GatherPESData( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, size_t i_skip )
2583 const bool b_unit_start = p_pkt->p_buffer[1]&0x40;
2584 bool b_ret = false;
2585 ts_stream_t *p_pes = pid->u.p_stream;
2587 /* We have to gather it */
2588 p_pkt->p_buffer += i_skip;
2589 p_pkt->i_buffer -= i_skip;
2591 bool b_single_payload = b_unit_start; /* Single payload in case of unit start */
2592 bool b_aligned_ts_payload = true;
2594 if( unlikely(p_pes->b_broken_PUSI_conformance) )
2596 /* Stream does not conform to payload_unit_start flag
2597 * applied to PES packets (AdTech private_stream_1) */
2598 b_aligned_ts_payload = false;
2599 b_single_payload = false;
2603 /* We'll cannot parse any pes data */
2604 if( (p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) && p_demux->p_sys->b_valid_scrambling )
2606 block_Release( p_pkt );
2607 return PushPESBlock( p_demux, pid, NULL, true );
2610 /* Data discontinuity, we need to drop or output currently
2611 * gathered data as it can't match the target size or can
2612 * have dropped next sync code */
2613 if( p_pkt->i_flags & BLOCK_FLAG_DISCONTINUITY )
2615 p_pes->gather.i_saved = 0;
2616 /* Flush/output current */
2617 b_ret |= PushPESBlock( p_demux, pid, NULL, true );
2618 /* Propagate to output block to notify packetizers/decoders */
2619 if( p_pes->p_es )
2620 p_pes->p_es->i_next_block_flags |= BLOCK_FLAG_DISCONTINUITY;
2623 if ( unlikely(p_pes->gather.i_saved > 0) )
2625 /* Saved from previous packet end */
2626 assert(p_pes->gather.i_saved < 6);
2627 if( !b_aligned_ts_payload )
2629 p_pkt = block_Realloc( p_pkt, p_pes->gather.i_saved, p_pkt->i_buffer );
2630 if( p_pkt )
2631 memcpy( p_pkt->p_buffer, p_pes->gather.saved, p_pes->gather.i_saved );
2633 p_pes->gather.i_saved = 0;
2636 for( bool b_first_sync_done = false; p_pkt; )
2638 assert( p_pes->gather.i_saved == 0 );
2640 if( p_pes->gather.p_data == NULL && !b_first_sync_done && p_pkt->i_buffer >= 6 )
2642 if( likely(b_aligned_ts_payload) )
2644 if( memcmp( p_pkt->p_buffer, pes_sync, 3 ) )
2646 block_Release( p_pkt );
2647 return b_ret;
2650 else
2652 /* Need to find sync code */
2653 uint8_t *p_buf = FindNextPESHeader( p_pkt->p_buffer, p_pkt->i_buffer - 3 );
2654 if( p_buf == NULL )
2656 /* no first sync code */
2657 if( MayHaveStartCodeOnEnd( p_pkt->p_buffer, p_pkt->i_buffer ) )
2659 /* Drop everything except last bytes for next packet */
2660 p_pkt->p_buffer += p_pkt->i_buffer - 3;
2661 p_pes->gather.i_saved = p_pkt->i_buffer = 3;
2662 memcpy(p_pes->gather.saved, p_pkt->p_buffer, p_pkt->i_buffer);
2664 block_Release( p_pkt );
2665 return b_ret;
2667 p_pkt->i_buffer -= p_buf - p_pkt->p_buffer;
2668 p_pkt->p_buffer = p_buf;
2670 /* now points to PES header */
2671 p_pes->gather.i_data_size = GetWBE(&p_pkt->p_buffer[4]);
2672 if( p_pes->gather.i_data_size > 0 )
2673 p_pes->gather.i_data_size += 6;
2674 b_first_sync_done = true; /* Because if size is 0, we woud not look for second sync */
2676 else
2678 assert( p_pes->gather.i_data_size > p_pes->gather.i_gathered ||
2679 p_pes->gather.i_data_size == 0 );
2681 /* If we started reading a fixed size */
2682 if( p_pes->gather.i_data_size > p_pes->gather.i_gathered )
2684 const size_t i_remain = p_pes->gather.i_data_size - p_pes->gather.i_gathered;
2685 /* Append whole block */
2686 if( likely(p_pkt->i_buffer <= i_remain || b_single_payload) )
2688 b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL );
2689 p_pkt = NULL;
2691 else /* p_pkt->i_buffer > i_remain */
2693 block_t *p_split;
2694 if( !block_Split( &p_pkt, &p_split, i_remain ) )
2696 block_Release( p_pkt );
2697 return false;
2699 b_ret |= PushPESBlock( p_demux, pid, p_pkt, p_pes->gather.p_data == NULL );
2700 p_pkt = p_split;
2701 b_first_sync_done = false;
2704 else /* if( p_pes->gather.i_data_size == 0 ) // see next packet */
2706 /* Append or finish current/start new PES depending on unit_start */
2707 b_ret |= PushPESBlock( p_demux, pid, p_pkt, b_unit_start );
2708 p_pkt = NULL;
2712 if( unlikely(p_pkt && p_pkt->i_buffer < 6) )
2714 /* save and prepend to next packet */
2715 assert(!b_single_payload);
2716 assert(p_pes->gather.i_saved == 0);
2717 p_pes->gather.i_saved = p_pkt->i_buffer;
2718 memcpy(p_pes->gather.saved, p_pkt->p_buffer, p_pkt->i_buffer);
2719 block_Release( p_pkt );
2720 p_pkt = NULL;
2724 return b_ret;
2727 static bool GatherSectionsData( demux_t *p_demux, ts_pid_t *p_pid, block_t *p_pkt, size_t i_skip )
2729 VLC_UNUSED(i_skip); VLC_UNUSED(p_demux);
2730 bool b_ret = false;
2732 if( p_pkt->i_flags & BLOCK_FLAG_DISCONTINUITY )
2734 ts_sections_processor_Reset( p_pid->u.p_stream->p_sections_proc );
2737 if( (p_pkt->i_flags & (BLOCK_FLAG_SCRAMBLED | BLOCK_FLAG_CORRUPTED)) == 0 )
2739 ts_sections_processor_Push( p_pid->u.p_stream->p_sections_proc, p_pkt->p_buffer );
2740 b_ret = true;
2743 block_Release( p_pkt );
2745 return b_ret;
2748 void TsChangeStandard( demux_sys_t *p_sys, ts_standards_e v )
2750 if( p_sys->standard != TS_STANDARD_AUTO &&
2751 p_sys->standard != v )
2752 return; /* TODO */
2753 p_sys->standard = v;
2756 bool ProgramIsSelected( demux_sys_t *p_sys, uint16_t i_pgrm )
2758 if( p_sys->seltype == PROGRAM_ALL )
2759 return true;
2761 for(int i=0; i<p_sys->programs.i_size; i++)
2762 if( p_sys->programs.p_elems[i] == i_pgrm )
2763 return true;
2765 return false;
2768 static bool PIDReferencedByProgram( const ts_pmt_t *p_pmt, uint16_t i_pid )
2770 for(int i=0; i<p_pmt->e_streams.i_size; i++)
2771 if( p_pmt->e_streams.p_elems[i]->i_pid == i_pid )
2772 return true;
2774 return false;
2777 static void DoCreateES( demux_t *p_demux, ts_es_t *p_es, const ts_es_t *p_parent_es )
2779 demux_sys_t *p_sys = p_demux->p_sys;
2781 for( ; p_es ; p_es = p_es->p_next )
2783 if( !p_es->id )
2785 if( !p_es->fmt.i_group )
2786 p_es->fmt.i_group = p_es->p_program->i_number;
2787 p_es->id = es_out_Add( p_demux->out, &p_es->fmt );
2788 if( p_parent_es ) /* Set Extra ES group and original ID */
2790 if ( p_sys->b_es_id_pid ) /* pid is 13 bits */
2791 p_es->fmt.i_id = (p_sys->i_next_extraid++ << 13) | p_parent_es->fmt.i_id;
2792 p_es->fmt.i_group = p_parent_es->fmt.i_group;
2794 p_sys->i_pmt_es++;
2796 DoCreateES( p_demux, p_es->p_extraes, p_es );
2800 void AddAndCreateES( demux_t *p_demux, ts_pid_t *pid, bool b_create_delayed )
2802 demux_sys_t *p_sys = p_demux->p_sys;
2804 if( b_create_delayed )
2805 p_sys->es_creation = CREATE_ES;
2807 if( pid && p_sys->es_creation == CREATE_ES )
2809 DoCreateES( p_demux, pid->u.p_stream->p_es, NULL );
2811 /* Update the default program == first created ES group */
2812 if( p_sys->b_default_selection && p_sys->programs.i_size > 0)
2814 p_sys->b_default_selection = false;
2815 const int i_first_program = pid->u.p_stream->p_es->p_program->i_number;
2816 if( p_sys->programs.p_elems[0] != i_first_program )
2817 p_sys->programs.p_elems[0] = i_first_program;
2818 msg_Dbg( p_demux, "Default program is %d", i_first_program );
2822 if( b_create_delayed )
2824 ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2825 for( int i=0; i< p_pat->programs.i_size; i++ )
2827 ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
2828 for( int j=0; j<p_pmt->e_streams.i_size; j++ )
2829 DoCreateES( p_demux, p_pmt->e_streams.p_elems[j]->u.p_stream->p_es, NULL );