Coverage Report

Created: 2026-08-14 07:16

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