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