Coverage Report

Created: 2026-08-31 08:22

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
170
vlc_module_begin ()
140
85
    set_description( N_("MPEG Transport Stream demuxer") )
141
85
    set_shortname ( "MPEG-TS" )
142
85
    set_subcategory( SUBCAT_INPUT_DEMUX )
143
144
85
    add_string( "ts-standard", "auto", STANDARD_TEXT, STANDARD_LONGTEXT )
145
85
        change_string_list( ts_standards_list, ts_standards_list_text )
146
147
85
    add_string( "ts-extra-pmt", NULL, PMT_TEXT, PMT_LONGTEXT )
148
85
    add_bool( "ts-trust-pcr", true, PCR_TEXT, PCR_LONGTEXT )
149
85
        change_safe()
150
85
    add_bool( "ts-es-id-pid", true, PID_TEXT, PID_LONGTEXT )
151
85
        change_safe()
152
85
    add_string( "ts-csa-ck", NULL, CSA_TEXT, CSA_LONGTEXT )
153
85
        change_safe()
154
85
    add_string( "ts-csa2-ck", NULL, CSA2_TEXT, CSA2_LONGTEXT )
155
85
        change_safe()
156
85
    add_integer( "ts-csa-pkt", 188, CPKT_TEXT, CPKT_LONGTEXT )
157
85
        change_safe()
158
159
85
    add_bool( "ts-split-es", true, SPLIT_ES_TEXT, SPLIT_ES_LONGTEXT )
160
85
    add_bool( "ts-seek-percent", false, SEEK_PERCENT_TEXT, SEEK_PERCENT_LONGTEXT )
161
85
    add_bool( "ts-cc-check", true, CC_CHECK_TEXT, CC_CHECK_LONGTEXT )
162
85
    add_bool( "ts-pmtfix-waitdata", true, TS_SKIP_GHOST_PROGRAM_TEXT, NULL )
163
85
    add_bool( "ts-patfix", true, TS_PATFIX_TEXT, NULL )
164
85
    add_bool( "ts-pcr-offsetfix", true, TS_OFFSETFIX_TEXT, NULL )
165
85
    add_integer_with_range( "ts-generated-pcr-offset", 120, 0, 500,
166
85
                            TS_GENERATED_PCR_OFFSET_TEXT, NULL )
167
168
85
    set_capability( "demux", 10 )
169
170
    set_callbacks( Open, Close )
170
85
    add_shortcut( "ts" )
171
85
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.58M
#define PROBE_CHUNK_COUNT 500
199
546
#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.5k
{
203
16.5k
    const uint8_t *p_peek;
204
205
16.5k
    if( vlc_stream_Peek( p_demux->s,
206
16.5k
                     &p_peek, i_offset + TS_PACKET_SIZE_MAX ) < i_offset + TS_PACKET_SIZE_MAX )
207
8
        return -1;
208
209
3.24M
    for( int i_sync = 0; i_sync < TS_PACKET_SIZE_MAX; i_sync++ )
210
3.22M
    {
211
3.22M
        if( p_peek[i_offset + i_sync] != 0x47 )
212
3.15M
            continue;
213
214
        /* Check next 3 sync bytes */
215
70.4k
        int i_peek = i_offset + TS_PACKET_SIZE_MAX * 3 + i_sync + 1;
216
70.4k
        if( ( vlc_stream_Peek( p_demux->s, &p_peek, i_peek ) ) < i_peek )
217
107
            return -1;
218
219
70.2k
        if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_188] == 0x47 &&
220
10.0k
            p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_188] == 0x47 &&
221
5.78k
            p_peek[i_offset + i_sync + 3 * TS_PACKET_SIZE_188] == 0x47 )
222
817
        {
223
817
            return TS_PACKET_SIZE_188;
224
817
        }
225
69.4k
        else if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_192] == 0x47 &&
226
2.30k
                 p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_192] == 0x47 &&
227
627
                 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
69.4k
        else if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_204] == 0x47 &&
236
2.99k
                 p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_204] == 0x47 &&
237
601
                 p_peek[i_offset + i_sync + 3 * TS_PACKET_SIZE_204] == 0x47 )
238
10
        {
239
10
            return TS_PACKET_SIZE_204;
240
10
        }
241
70.2k
    }
242
243
15.5k
    if( p_demux->obj.force )
244
15.5k
    {
245
15.5k
        msg_Warn( p_demux, "this does not look like a TS stream, continuing" );
246
15.5k
        return TS_PACKET_SIZE_188;
247
15.5k
    }
248
10
    msg_Dbg( p_demux, "TS module discarded (lost sync)" );
249
10
    return -1;
250
15.5k
}
251
252
613
#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.5k
{
256
16.5k
    const uint8_t *p_peek;
257
16.5k
    *pi_header_size = 0;
258
16.5k
    int i_packet_size = -1;
259
16.5k
    int i_offset = 0;
260
261
16.5k
    if( vlc_stream_Peek( p_demux->s,
262
16.5k
                     &p_peek, TS_PACKET_SIZE_MAX ) < TS_PACKET_SIZE_MAX )
263
23
        return -1;
264
265
16.5k
    if( memcmp( p_peek, "TFrc", 4 ) == 0 && p_peek[6] == 0 &&
266
266
        vlc_stream_Peek( p_demux->s, &p_peek, TOPFIELD_HEADER_SIZE + TS_PACKET_SIZE_MAX )
267
266
            == TOPFIELD_HEADER_SIZE + TS_PACKET_SIZE_MAX )
268
81
    {
269
81
        const int i_service = GetWBE(&p_peek[18]);
270
81
        i_packet_size = DetectPacketSize( p_demux, pi_header_size, TOPFIELD_HEADER_SIZE );
271
81
        if( i_packet_size != -1 )
272
72
        {
273
72
            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
72
            p_vdr->i_service = i_service;
338
339
72
            return i_packet_size;
340
            //return TS_PACKET_SIZE_188;
341
72
        }
342
81
    }
343
16.4k
    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.4k
    return DetectPacketSize( p_demux, pi_header_size, i_offset );
350
16.5k
}
351
352
/*****************************************************************************
353
 * Open
354
 *****************************************************************************/
355
static int Open( vlc_object_t *p_this )
356
16.5k
{
357
16.5k
    demux_t     *p_demux = (demux_t*)p_this;
358
16.5k
    demux_sys_t *p_sys;
359
360
16.5k
    int          i_packet_size;
361
16.5k
    unsigned     i_packet_header_size = 0;
362
363
16.5k
    ts_pid_t    *patpid;
364
16.5k
    vdr_info_t   vdr = {0};
365
366
    /* Search first sync byte */
367
16.5k
    i_packet_size = DetectPVRHeadersAndHeaderSize( p_demux, &i_packet_header_size, &vdr );
368
16.5k
    if( i_packet_size < 0 )
369
139
        return VLC_EGENERIC;
370
371
16.4k
    p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
372
16.4k
    if( !p_sys )
373
0
        return VLC_ENOMEM;
374
16.4k
    memset( p_sys, 0, sizeof( demux_sys_t ) );
375
16.4k
    vlc_mutex_init( &p_sys->csa_lock );
376
377
16.4k
    p_demux->pf_demux = Demux;
378
16.4k
    p_demux->pf_control = Control;
379
380
    /* Init p_sys field */
381
16.4k
    p_sys->b_end_preparse = false;
382
16.4k
    ARRAY_INIT( p_sys->programs );
383
16.4k
    p_sys->b_default_selection = false;
384
16.4k
    p_sys->i_network_time = 0;
385
16.4k
    p_sys->i_network_time_update = 0;
386
387
16.4k
    p_sys->vdr = vdr;
388
389
16.4k
    p_sys->stream = p_demux->s;
390
391
16.4k
    p_sys->b_broken_charset = false;
392
393
16.4k
    ts_pid_list_Init( &p_sys->pids );
394
395
16.4k
    p_sys->i_packet_size = i_packet_size;
396
16.4k
    p_sys->i_packet_header_size = i_packet_header_size;
397
16.4k
    p_sys->i_ts_read = 50;
398
16.4k
    p_sys->csa = NULL;
399
16.4k
    p_sys->b_start_record = false;
400
16.4k
    p_sys->record_dir_path = NULL;
401
402
16.4k
    vlc_dictionary_init( &p_sys->attachments, 0 );
403
404
16.4k
    p_sys->patfix.i_first_dts = VLC_TICK_INVALID;
405
16.4k
    p_sys->patfix.i_timesourcepid = 0;
406
16.4k
    p_sys->patfix.b_pcrhasnopcrfield = false;
407
16.4k
    p_sys->patfix.status = var_CreateGetBool( p_demux, "ts-patfix" ) ? PAT_WAITING : PAT_FIXTRIED;
408
409
    /* Init PAT handler */
410
16.4k
    patpid = GetPID(p_sys, 0);
411
16.4k
    if ( !PIDSetup( p_demux, TYPE_PAT, patpid, NULL ) )
412
0
    {
413
0
        free( p_sys );
414
0
        return VLC_ENOMEM;
415
0
    }
416
16.4k
    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.4k
    p_sys->b_access_control = true;
425
16.4k
    p_sys->b_access_control = ( VLC_SUCCESS == SetPIDFilter( p_sys, patpid, true ) );
426
427
16.4k
    p_sys->i_pmt_es = 0;
428
16.4k
    p_sys->seltype = PROGRAM_AUTO_DEFAULT;
429
430
    /* Read config */
431
16.4k
    p_sys->b_es_id_pid = var_CreateGetBool( p_demux, "ts-es-id-pid" );
432
16.4k
    p_sys->i_next_extraid = 1;
433
434
16.4k
    p_sys->b_trust_pcr = var_CreateGetBool( p_demux, "ts-trust-pcr" );
435
16.4k
    p_sys->b_check_pcr_offset = p_sys->b_trust_pcr && var_CreateGetBool(p_demux, "ts-pcr-offsetfix" );
436
16.4k
    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.4k
    char* psz_string = var_CreateGetString( p_demux, "ts-extra-pmt" );
440
16.4k
    p_sys->b_user_pmt = false;
441
16.4k
    if( psz_string && *psz_string )
442
0
        UserPmt( p_demux, psz_string );
443
16.4k
    free( psz_string );
444
445
16.4k
    psz_string = var_CreateGetStringCommand( p_demux, "ts-csa-ck" );
446
16.4k
    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.4k
    free( psz_string );
497
498
16.4k
    p_sys->b_split_es = var_InheritBool( p_demux, "ts-split-es" );
499
500
16.4k
    p_sys->b_canseek = false;
501
16.4k
    p_sys->b_canfastseek = false;
502
16.4k
    p_sys->b_lowdelay = var_InheritBool( p_demux, "low-delay" );
503
16.4k
    p_sys->b_ignore_time_for_positions = var_InheritBool( p_demux, "ts-seek-percent" );
504
16.4k
    p_sys->b_cc_check = var_InheritBool( p_demux, "ts-cc-check" );
505
506
16.4k
    p_sys->standard = TS_STANDARD_AUTO;
507
16.4k
    char *psz_standard = var_InheritString( p_demux, "ts-standard" );
508
16.4k
    if( psz_standard )
509
16.4k
    {
510
16.4k
        for( unsigned i=0; i<ARRAY_SIZE(ts_standards_list); i++ )
511
16.4k
        {
512
16.4k
            if( !strcmp( psz_standard, ts_standards_list[i] ) )
513
16.4k
            {
514
16.4k
                TsChangeStandard( p_sys, TS_STANDARD_AUTO + i );
515
16.4k
                msg_Dbg( p_demux, "Standard set to %s", ts_standards_list_text[i] );
516
16.4k
                break;
517
16.4k
            }
518
16.4k
        }
519
16.4k
        free( psz_standard );
520
16.4k
    }
521
522
16.4k
    if( p_sys->standard == TS_STANDARD_AUTO &&
523
16.4k
       !strncasecmp( p_demux->psz_url, "atsc", 4 ) )
524
0
    {
525
0
        TsChangeStandard( p_sys, TS_STANDARD_ATSC );
526
0
    }
527
528
16.4k
    vlc_stream_Control( p_sys->stream, STREAM_CAN_SEEK, &p_sys->b_canseek );
529
16.4k
    vlc_stream_Control( p_sys->stream, STREAM_CAN_FASTSEEK,
530
16.4k
                        &p_sys->b_canfastseek );
531
532
16.4k
    if( !p_sys->b_access_control && var_CreateGetBool( p_demux, "ts-pmtfix-waitdata" ) )
533
16.4k
        p_sys->es_creation = DELAY_ES;
534
0
    else
535
0
        p_sys->es_creation = CREATE_ES;
536
537
    /* Preparse time */
538
16.4k
    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.4k
    return VLC_SUCCESS;
546
16.4k
}
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.4k
{
559
16.4k
    demux_t     *p_demux = (demux_t*)p_this;
560
16.4k
    demux_sys_t *p_sys = p_demux->p_sys;
561
562
16.4k
    PIDRelease( p_demux, GetPID(p_sys, 0) );
563
564
16.4k
    vlc_mutex_lock( &p_sys->csa_lock );
565
16.4k
    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.4k
    vlc_mutex_unlock( &p_sys->csa_lock );
572
573
16.4k
    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.4k
    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.4k
    ts_pid_list_Release( p_demux, &p_sys->pids );
588
589
    /* Clear up attachments */
590
16.4k
    vlc_dictionary_clear( &p_sys->attachments, FreeDictAttachment, NULL );
591
592
16.4k
    free( p_sys->record_dir_path );
593
16.4k
    free( p_sys );
594
16.4k
}
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.07M
{
623
1.07M
    demux_sys_t *p_sys = p_demux->p_sys;
624
1.07M
    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.07M
    if( p_sys->i_pmt_es == 0 && !SEEN(GetPID(p_sys, 0)) && p_sys->patfix.status == PAT_MISSING )
628
389
    {
629
389
        msg_Warn( p_demux, "Generating PAT as we still have not received one" );
630
389
        MissingPATPMTFixup( p_demux );
631
389
        GetPID(p_sys, 0)->u.p_pat->b_generated = true;
632
389
        p_sys->patfix.status = PAT_FIXTRIED;
633
389
    }
634
635
    /* We read at most 100 TS packet or until a frame is completed */
636
2.66M
    for( unsigned i_pkt = 0; i_pkt < p_sys->i_ts_read; i_pkt++ )
637
2.65M
    {
638
2.65M
        bool         b_frame = false;
639
2.65M
        int          i_header = 0;
640
2.65M
        block_t     *p_pkt;
641
2.65M
        if( !(p_pkt = ReadTSPacket( p_demux )) )
642
16.4k
        {
643
16.4k
            return VLC_DEMUXER_EOF;
644
16.4k
        }
645
646
2.64M
        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.64M
        if( unlikely(p_pkt->i_buffer < TS_PACKET_SIZE_188) )
656
2.95k
        {
657
2.95k
            block_Release( p_pkt );
658
2.95k
            continue;
659
2.95k
        }
660
661
        /* Reject any fully uncorrected packet. Even PID can be incorrect */
662
2.63M
        if( p_pkt->p_buffer[1]&0x80 )
663
37.1k
        {
664
37.1k
            msg_Dbg( p_demux, "transport_error_indicator set (pid=%d)",
665
37.1k
                     PIDGet( p_pkt ) );
666
37.1k
            block_Release( p_pkt );
667
37.1k
            continue;
668
37.1k
        }
669
670
        /* Parse the TS packet */
671
2.60M
        ts_pid_t *p_pid = GetPID( p_sys, PIDGet( p_pkt ) );
672
2.60M
        if( !SEEN(p_pid) )
673
49.4k
        {
674
49.4k
            if( p_pid->type == TYPE_FREE )
675
49.4k
                msg_Dbg( p_demux, "pid[%d] unknown", p_pid->i_pid );
676
49.4k
            p_pid->i_flags |= FLAG_SEEN;
677
49.4k
            if( p_pid->i_pid == 0x01 )
678
118
                p_sys->b_valid_scrambling = true;
679
49.4k
        }
680
681
        /* Drop duplicates and invalid (DOES NOT drop corrupted) */
682
2.60M
        p_pkt = ProcessTSPacket( p_demux, p_pid, p_pkt, &i_header );
683
2.60M
        if( !p_pkt )
684
343k
            continue;
685
686
2.25M
        if( !SCRAMBLED(*p_pid) != !(p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) &&
687
64.9k
            ( p_pkt->p_buffer[1] & 0x40 ) ) /* update on payload start */
688
46.4k
        {
689
46.4k
            UpdatePIDScrambledState( p_demux, p_pid, p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED );
690
46.4k
        }
691
692
        /* Adaptation field cannot be scrambled */
693
2.25M
        ts_90khz_t i_pcr = GetPCR( p_pkt );
694
2.25M
        if( i_pcr != TS_90KHZ_INVALID )
695
201k
            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.25M
        if( !SEEN( GetPID( p_sys, 0 ) ) &&
699
71.8k
            (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* Payload start but not corrupt */
700
51.9k
            (p_pkt->p_buffer[3] & 0xD0) == 0x10 )  /* Has payload but is not encrypted */
701
48.4k
        {
702
48.4k
            ProbePES( p_demux, p_pid, p_pkt );
703
48.4k
        }
704
705
2.25M
        switch( p_pid->type )
706
2.25M
        {
707
87.5k
        case TYPE_PAT:
708
215k
        case TYPE_PMT:
709
            /* PAT and PMT are not allowed to be scrambled */
710
215k
            ts_psi_Packet_Push( p_pid, p_pkt->p_buffer );
711
215k
            block_Release( p_pkt );
712
215k
            break;
713
714
1.71M
        case TYPE_STREAM:
715
1.71M
            p_sys->b_end_preparse = true;
716
717
1.71M
            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.71M
            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.70M
            if( p_pid->u.p_stream->transport == TS_TRANSPORT_PES )
733
1.45M
            {
734
1.45M
                b_frame = GatherPESData( p_demux, p_pid, p_pkt, i_header );
735
1.45M
            }
736
247k
            else if( p_pid->u.p_stream->transport == TS_TRANSPORT_SECTIONS )
737
247k
            {
738
247k
                b_frame = GatherSectionsData( p_demux, p_pid, p_pkt, i_header );
739
247k
            }
740
0
            else // pid->u.p_pes->transport == TS_TRANSPORT_IGNORE
741
0
            {
742
0
                block_Release( p_pkt );
743
0
            }
744
745
1.70M
            break;
746
747
15.8k
        case TYPE_SI:
748
15.8k
            if( (p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) == 0 )
749
15.7k
                ts_si_Packet_Push( p_pid, p_pkt->p_buffer );
750
15.8k
            block_Release( p_pkt );
751
15.8k
            break;
752
753
9.97k
        case TYPE_PSIP:
754
9.97k
            if( (p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) == 0 )
755
9.71k
                ts_psip_Packet_Push( p_pid, p_pkt->p_buffer );
756
9.97k
            block_Release( p_pkt );
757
9.97k
            break;
758
759
0
        case TYPE_CAT:
760
304k
        default:
761
            /* We have to handle PCR if present */
762
304k
            block_Release( p_pkt );
763
304k
            break;
764
2.25M
        }
765
766
2.25M
        if( b_frame || ( b_wait_es && p_sys->i_pmt_es > 0 ) )
767
1.05M
            break;
768
2.25M
    }
769
770
1.05M
    demux_UpdateTitleFromStream( p_demux );
771
1.05M
    return VLC_DEMUXER_SUCCESS;
772
1.07M
}
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.4k
{
802
22.4k
    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.4k
}
810
811
void UpdatePESFilters( demux_t *p_demux, bool b_all )
812
138k
{
813
138k
    demux_sys_t *p_sys = p_demux->p_sys;
814
138k
    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
281k
    for( int i=0; i< p_pat->programs.i_size; i++ )
824
143k
    {
825
143k
        ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
826
143k
        ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
827
828
143k
        p_pmt_pid->i_flags &= ~FLAG_FILTERED;
829
653k
        for( int j=0; j< p_pmt->e_streams.i_size; j++ )
830
509k
            p_pmt->e_streams.p_elems[j]->i_flags &= ~FLAG_FILTERED;
831
143k
        GetPID(p_sys, p_pmt->i_pid_pcr)->i_flags &= ~FLAG_FILTERED;
832
143k
    }
833
834
    /* set selection flag on selected pmt referenced pid with active es */
835
281k
    for( int i=0; i< p_pat->programs.i_size; i++ )
836
143k
    {
837
143k
        ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
838
143k
        ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
839
143k
        const bool b_prev_selection = p_pmt->b_selected;
840
841
143k
        if( (p_sys->b_default_selection && !p_sys->b_access_control) || b_all )
842
97.4k
             p_pmt->b_selected = true;
843
45.6k
        else
844
45.6k
             p_pmt->b_selected = ProgramIsSelected( p_sys, p_pmt->i_number );
845
846
        /* Notify CI for program selection changes */
847
143k
        if( b_prev_selection != p_pmt->b_selected )
848
15.8k
            SendCAPMTUpdate( p_demux, p_pmt );
849
850
143k
        if( p_pmt->b_selected )
851
139k
        {
852
139k
            p_pmt_pid->i_flags |= FLAG_FILTERED;
853
854
648k
            for( int j=0; j<p_pmt->e_streams.i_size; j++ )
855
509k
            {
856
509k
                ts_pid_t *espid = p_pmt->e_streams.p_elems[j];
857
509k
                ts_stream_t *p_pes = espid->u.p_stream;
858
859
509k
                bool b_stream_selected = true;
860
509k
                if( !p_pes->b_always_receive && !b_all )
861
22.4k
                    HasSelectedES( p_demux->out, p_pes->p_es, p_pmt, &b_stream_selected );
862
863
509k
                if( b_stream_selected )
864
509k
                {
865
509k
                    msg_Dbg( p_demux, "enabling pid %d from program %d", espid->i_pid, p_pmt->i_number );
866
509k
                    espid->i_flags |= FLAG_FILTERED;
867
509k
                }
868
509k
            }
869
870
            /* Select pcr last in case it is handled by unselected ES */
871
139k
            if( p_pmt->i_pid_pcr > 0 )
872
139k
            {
873
139k
                GetPID(p_sys, p_pmt->i_pid_pcr)->i_flags |= FLAG_FILTERED;
874
139k
                msg_Dbg( p_demux, "enabling pcr pid %d from program %d", p_pmt->i_pid_pcr, p_pmt->i_number );
875
139k
            }
876
139k
        }
877
143k
    }
878
879
    /* Commit HW changes based on flags */
880
281k
    for( int i=0; i< p_pat->programs.i_size; i++ )
881
143k
    {
882
143k
        ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
883
143k
        ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
884
885
143k
        UpdateHWFilter( p_sys, p_pmt_pid );
886
653k
        for( int j=0; j< p_pmt->e_streams.i_size; j++ )
887
509k
        {
888
509k
            ts_pid_t *espid = p_pmt->e_streams.p_elems[j];
889
509k
            UpdateHWFilter( p_sys, espid );
890
509k
            if( (espid->i_flags & FLAG_FILTERED) == 0 )
891
871
                FlushESBuffer( espid->u.p_stream );
892
509k
        }
893
143k
        UpdateHWFilter( p_sys, GetPID(p_sys, p_pmt->i_pid_pcr) );
894
143k
    }
895
138k
}
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
85.2k
{
1399
85.2k
    if(!p_block)
1400
0
        return NULL;
1401
1402
85.2k
    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
85.2k
    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
85.2k
    else if( p_es->fmt.i_codec == VLC_CODEC_ARIB_A ||
1433
85.2k
             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
85.2k
    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
85.2k
    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
85.2k
    return p_block;
1465
85.2k
}
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
748k
{
1472
748k
    demux_sys_t *p_sys = p_demux->p_sys;
1473
1474
1.47M
    while( p_chain )
1475
724k
    {
1476
724k
        block_t *p_block = p_chain;
1477
724k
        p_chain = p_block->p_next;
1478
724k
        p_block->p_next = NULL;
1479
1480
        /* clean up any private flag */
1481
724k
        p_block->i_flags &= ~BLOCK_FLAG_PRIVATE_MASK;
1482
1483
724k
        if( p_sys->b_lowdelay )
1484
0
            p_block->i_flags |= BLOCK_FLAG_AU_END;
1485
1486
724k
        ts_es_t *p_es_send = p_es;
1487
724k
        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.44M
        while( p_es_send )
1494
724k
        {
1495
724k
            if( p_es_send->p_program->b_selected )
1496
724k
            {
1497
                /* Send a copy to each extra es */
1498
724k
                ts_es_t *p_extra_es = p_es_send->p_extraes;
1499
724k
                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
724k
                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
724k
                else
1520
724k
                {
1521
724k
                    if( p_es_send->id )
1522
724k
                    {
1523
724k
                        es_out_Send( p_demux->out, p_es_send->id, p_block );
1524
724k
                        p_block = NULL;
1525
724k
                    }
1526
724k
                }
1527
724k
            }
1528
724k
            p_es_send = p_es_send->p_next;
1529
724k
        }
1530
1531
724k
        if( p_block )
1532
0
            block_Release( p_block );
1533
724k
    }
1534
748k
}
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
838k
{
1542
838k
    uint8_t header[34];
1543
838k
    unsigned i_pes_size = 0;
1544
838k
    unsigned i_skip = 0;
1545
838k
    ts_90khz_t i_length = 0;
1546
838k
    vlc_tick_t i_dts = VLC_TICK_INVALID;
1547
838k
    vlc_tick_t i_pts = VLC_TICK_INVALID;
1548
838k
    const es_mpeg4_descriptor_t *p_mpeg4desc = NULL;
1549
838k
    demux_sys_t *p_sys = p_demux->p_sys;
1550
1551
838k
    assert(pid->type == TYPE_STREAM);
1552
1553
838k
    const int i_max = block_ChainExtract( p_pes, header, 34 );
1554
838k
    if ( i_max < 4 )
1555
762
    {
1556
762
        block_ChainRelease( p_pes );
1557
762
        return;
1558
762
    }
1559
1560
837k
    if( header[0] != 0 || header[1] != 0 || header[2] != 1 )
1561
13.6k
    {
1562
13.6k
        if ( !(p_pes->i_flags & BLOCK_FLAG_SCRAMBLED) )
1563
13.6k
            msg_Warn( p_demux, "invalid header [0x%02x:%02x:%02x:%02x] (pid: %d)",
1564
13.6k
                        header[0], header[1],header[2],header[3], pid->i_pid );
1565
13.6k
        block_ChainRelease( p_pes );
1566
13.6k
        return;
1567
13.6k
    }
1568
824k
    else
1569
824k
    {
1570
        /* Incorrect transport scrambling flag set by german boxes */
1571
824k
        p_pes->i_flags &= ~BLOCK_FLAG_SCRAMBLED;
1572
824k
    }
1573
1574
824k
    ts_es_t *p_es = pid->u.p_stream->p_es;
1575
1576
824k
    ts_pes_header_t pesh;
1577
824k
    ts_pes_header_init( &pesh );
1578
1579
824k
    if( ParsePESHeader( p_demux->obj.logger, (uint8_t*)&header, i_max, &pesh ) == VLC_EGENERIC )
1580
9.09k
    {
1581
9.09k
        block_ChainRelease( p_pes );
1582
9.09k
        return;
1583
9.09k
    }
1584
814k
    else
1585
814k
    {
1586
814k
        if( pesh.i_pts != TS_90KHZ_INVALID && p_es->p_program )
1587
105k
            i_pts = TimeStampWrapAround( p_es->p_program->pcr.i_first, FROM_SCALE(pesh.i_pts) );
1588
814k
        if( pesh.i_dts != TS_90KHZ_INVALID && p_es->p_program )
1589
34.0k
            i_dts = TimeStampWrapAround( p_es->p_program->pcr.i_first, FROM_SCALE(pesh.i_dts) );
1590
814k
        if( pesh.b_scrambling )
1591
3.74k
            p_pes->i_flags |= BLOCK_FLAG_SCRAMBLED;
1592
814k
        i_skip = pesh.i_size;
1593
814k
    }
1594
1595
814k
    if( p_es->i_sl_es_id )
1596
727k
        p_mpeg4desc = GetMPEG4DescByEsId( p_es->p_program, p_es->i_sl_es_id );
1597
1598
814k
    if( p_es->fmt.i_codec == VLC_FOURCC( 'a', '5', '2', 'b' ) ||
1599
814k
        p_es->fmt.i_codec == VLC_FOURCC( 'd', 't', 's', 'b' ) )
1600
0
    {
1601
0
        i_skip += 4;
1602
0
    }
1603
814k
    else if( p_es->fmt.i_codec == VLC_FOURCC( 'l', 'p', 'c', 'b' ) ||
1604
814k
             p_es->fmt.i_codec == VLC_FOURCC( 's', 'p', 'u', 'b' ) ||
1605
814k
             p_es->fmt.i_codec == VLC_FOURCC( 's', 'd', 'd', 'b' ) )
1606
0
    {
1607
0
        i_skip += 1;
1608
0
    }
1609
814k
    else if( p_es->fmt.i_codec == VLC_CODEC_SUBT && p_mpeg4desc )
1610
10.0k
    {
1611
10.0k
        const decoder_config_descriptor_t *dcd = &p_mpeg4desc->dec_descr;
1612
1613
10.0k
        if( dcd->i_extra > 2 &&
1614
5.98k
            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.0k
        if( p_pes->i_buffer >= i_skip + 2 )
1624
9.75k
            i_pes_size = GetWBE( &p_pes->p_buffer[i_skip] );
1625
        /* */
1626
10.0k
        i_skip += 2;
1627
10.0k
    }
1628
1629
    /* skip header */
1630
819k
    while( p_pes && i_skip > 0 )
1631
815k
    {
1632
815k
        if( p_pes->i_buffer <= i_skip )
1633
4.86k
        {
1634
4.86k
            block_t *p_next = p_pes->p_next;
1635
1636
4.86k
            i_skip -= p_pes->i_buffer;
1637
4.86k
            block_Release( p_pes );
1638
4.86k
            p_pes = p_next;
1639
4.86k
        }
1640
811k
        else
1641
811k
        {
1642
811k
            p_pes->i_buffer -= i_skip;
1643
811k
            p_pes->p_buffer += i_skip;
1644
811k
            break;
1645
811k
        }
1646
815k
    }
1647
1648
    /* ISO/IEC 13818-1 2.7.5: if no pts and no dts, then dts == pts */
1649
814k
    if( i_pts != VLC_TICK_INVALID && i_dts == VLC_TICK_INVALID )
1650
89.2k
        i_dts = i_pts;
1651
1652
814k
    if( i_dts != VLC_TICK_INVALID )
1653
123k
        pid->u.p_stream->i_last_dts = i_dts;
1654
1655
814k
    if( p_pes )
1656
811k
    {
1657
811k
        ts_pmt_t *p_pmt = p_es->p_program;
1658
811k
        if( unlikely(!p_pmt) )
1659
0
        {
1660
0
            block_ChainRelease( p_pes );
1661
0
            return;
1662
0
        }
1663
1664
811k
        if( i_dts != VLC_TICK_INVALID )
1665
122k
            p_pes->i_dts = i_dts;
1666
1667
811k
        if( i_pts != VLC_TICK_INVALID )
1668
105k
            p_pes->i_pts = i_pts;
1669
1670
811k
        p_pes->i_length = FROM_SCALE_NZ(i_length);
1671
1672
        /* Can become a chain on next call due to prepcr */
1673
811k
        block_t *p_chain = block_ChainGather( p_pes );
1674
1.67M
        while ( p_chain ) {
1675
862k
            block_t *p_block = p_chain;
1676
862k
            p_chain = p_chain->p_next;
1677
862k
            p_block->p_next = NULL;
1678
1679
862k
            if( i_flags )
1680
287k
            {
1681
287k
                p_block->i_flags |= i_flags;
1682
287k
                i_flags = 0;
1683
287k
            }
1684
1685
862k
            if( !p_pmt->pcr.b_fix_done ) /* Not seen yet */
1686
355k
                PCRFixHandle( p_demux, p_pmt, p_block );
1687
1688
862k
            if( p_es->id && (p_pmt->pcr.i_current != VLC_TICK_INVALID || p_pmt->pcr.b_disable) )
1689
754k
            {
1690
754k
                if( pid->u.p_stream->prepcr.p_head )
1691
6.15k
                {
1692
                    /* Rebuild current output chain, appending any prepcr outqueue */
1693
6.15k
                    block_ChainLastAppend( &pid->u.p_stream->prepcr.pp_last, p_block );
1694
6.15k
                    if( p_chain )
1695
0
                        block_ChainLastAppend( &pid->u.p_stream->prepcr.pp_last, p_chain );
1696
6.15k
                    p_chain = pid->u.p_stream->prepcr.p_head;
1697
6.15k
                    pid->u.p_stream->prepcr.p_head = NULL;
1698
6.15k
                    pid->u.p_stream->prepcr.pp_last = &pid->u.p_stream->prepcr.p_head;
1699
                    /* Then now output all data */
1700
6.15k
                    continue;
1701
6.15k
                }
1702
1703
748k
                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
748k
                vlc_tick_t i_pcrref = (i_append_pcr != TS_90KHZ_INVALID) ? FROM_SCALE(i_append_pcr) : p_pmt->pcr.i_first;
1714
748k
                if( p_pmt->pcr.i_pcroffset == -1 && p_block->i_dts != VLC_TICK_INVALID &&
1715
9.15k
                    i_pcrref != VLC_TICK_INVALID &&
1716
8.20k
                    (p_es->fmt.i_cat == VIDEO_ES || p_es->fmt.i_cat == AUDIO_ES) )
1717
6.64k
                {
1718
6.64k
                    if( p_block->i_dts + FROM_SCALE_NZ(1) < i_pcrref )
1719
1.52k
                    {
1720
1.52k
                        p_pmt->pcr.i_pcroffset = i_pcrref - p_block->i_dts + VLC_TICK_FROM_MS(80);
1721
1.52k
                        msg_Warn( p_demux, "Broken stream: pid %d sends packets with dts %"PRId64
1722
1.52k
                                           "us later than pcr, applying delay",
1723
1.52k
                                  pid->i_pid, i_pcrref - p_block->i_dts );
1724
1.52k
                    }
1725
5.11k
                    else p_pmt->pcr.i_pcroffset = 0;
1726
6.64k
                }
1727
1728
748k
                if( p_pmt->pcr.i_pcroffset != -1 )
1729
547k
                {
1730
547k
                    if( p_block->i_dts != VLC_TICK_INVALID )
1731
113k
                        p_block->i_dts += p_pmt->pcr.i_pcroffset;
1732
547k
                    if( p_block->i_pts != VLC_TICK_INVALID )
1733
106k
                        p_block->i_pts += p_pmt->pcr.i_pcroffset;
1734
547k
                }
1735
1736
                /*** From here, block can become a chain again though conversion below ***/
1737
1738
748k
                if( pid->u.p_stream->p_proc )
1739
663k
                {
1740
663k
                    if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
1741
0
                        ts_stream_processor_Reset( pid->u.p_stream->p_proc );
1742
663k
                    p_block = ts_stream_processor_Push( pid->u.p_stream->p_proc, pesh.i_stream_id, p_block );
1743
663k
                }
1744
85.2k
                else
1745
                /* Some codecs might need xform or AU splitting */
1746
85.2k
                {
1747
85.2k
                    p_block = ConvertPESBlock( p_demux, p_es, i_pes_size, pesh.i_stream_id, p_block );
1748
85.2k
                }
1749
1750
748k
                SendDataChain( p_demux, p_es, p_block );
1751
748k
            }
1752
108k
            else
1753
108k
            {
1754
108k
                if( !p_pmt->pcr.b_fix_done ) /* Not seen yet */
1755
55.7k
                    PCRFixHandle( p_demux, p_pmt, p_block );
1756
1757
108k
                if( pid->u.p_stream->p_proc )
1758
97.9k
                {
1759
97.9k
                    if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
1760
0
                        ts_stream_processor_Reset( pid->u.p_stream->p_proc );
1761
97.9k
                    p_block = ts_stream_processor_Push( pid->u.p_stream->p_proc, pesh.i_stream_id, p_block );
1762
97.9k
                }
1763
1764
108k
                if( p_block )
1765
51.9k
                    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
108k
                if( p_pmt->pcr.i_current != VLC_TICK_INVALID )
1769
39.9k
                {
1770
39.9k
                    block_ChainRelease( pid->u.p_stream->prepcr.p_head );
1771
39.9k
                    pid->u.p_stream->prepcr.p_head = NULL;
1772
39.9k
                    pid->u.p_stream->prepcr.pp_last = &pid->u.p_stream->prepcr.p_head;
1773
39.9k
                }
1774
108k
            }
1775
862k
        }
1776
811k
    }
1777
3.83k
    else
1778
3.83k
    {
1779
3.83k
        msg_Warn( p_demux, "empty pes" );
1780
3.83k
    }
1781
814k
}
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
838k
{
1786
838k
    ParsePESDataChain( (demux_t *)p_obj, (ts_pid_t *) priv, p_data, i_flags, i_appendpcr );
1787
838k
}
1788
1789
static bool CheckAndResync( demux_t *p_demux )
1790
5.92M
{
1791
5.92M
    demux_sys_t *p_sys = p_demux->p_sys;
1792
1793
5.92M
    const uint8_t *p_peek;
1794
5.92M
    if( vlc_stream_Peek( p_sys->stream, &p_peek, 1 + p_sys->i_packet_header_size )
1795
5.92M
            != 1 + p_sys->i_packet_header_size )
1796
8.79k
        return true;
1797
1798
    /* Check sync byte and re-sync if needed */
1799
5.91M
    if( p_peek[p_sys->i_packet_header_size] == 0x47 )
1800
3.73M
        return true;
1801
1802
2.17M
    msg_Warn( p_demux, "lost synchro at %" PRIu64, vlc_stream_Tell( p_sys->stream ) );
1803
1804
2.17M
    for( ;; )
1805
2.24M
    {
1806
2.24M
        ssize_t i_peek = 0;
1807
2.24M
        unsigned i_skip = 0;
1808
1809
2.24M
        i_peek = vlc_stream_Peek( p_sys->stream, &p_peek,
1810
2.24M
                                  p_sys->i_packet_size * 10 );
1811
2.24M
        if( i_peek < 0 || (size_t)i_peek < p_sys->i_packet_size + 1 )
1812
37.6k
        {
1813
37.6k
            msg_Dbg( p_demux, "eof ?" );
1814
37.6k
            return false;
1815
37.6k
        }
1816
1817
684M
        while( i_skip < i_peek - p_sys->i_packet_size )
1818
684M
        {
1819
684M
            if( p_peek[i_skip + p_sys->i_packet_header_size] == 0x47 &&
1820
7.57M
                p_peek[i_skip + p_sys->i_packet_header_size + p_sys->i_packet_size] == 0x47 )
1821
2.13M
                break;
1822
681M
            i_skip++;
1823
681M
        }
1824
2.20M
        msg_Dbg( p_demux, "skipping %d bytes of garbage at %"PRIu64,
1825
2.20M
                 i_skip, vlc_stream_Tell( p_sys->stream ) );
1826
2.20M
        if (vlc_stream_Read( p_sys->stream, NULL, i_skip ) != i_skip)
1827
0
            return false;
1828
1829
2.20M
        if( i_skip < i_peek - p_sys->i_packet_size )
1830
2.13M
            break;
1831
2.20M
    }
1832
2.13M
    msg_Dbg( p_demux, "resynced at %" PRIu64, vlc_stream_Tell( p_sys->stream ) );
1833
1834
2.13M
    return true;
1835
2.17M
}
1836
1837
static block_t* ReadTSPacket( demux_t *p_demux )
1838
5.92M
{
1839
5.92M
    demux_sys_t *p_sys = p_demux->p_sys;
1840
1841
5.92M
    if( !CheckAndResync( p_demux) )
1842
37.6k
        return NULL;
1843
1844
5.88M
    block_t     *p_pkt;
1845
1846
    /* Get a new TS packet */
1847
5.88M
    if( !( p_pkt = vlc_stream_Block( p_sys->stream, p_sys->i_packet_size ) ) )
1848
8.79k
    {
1849
8.79k
        uint64_t size;
1850
8.79k
        if( vlc_stream_GetSize( p_sys->stream, &size ) == VLC_SUCCESS &&
1851
8.79k
            size == vlc_stream_Tell( p_sys->stream ) )
1852
8.79k
            msg_Dbg( p_demux, "EOF at %"PRIu64, size );
1853
0
        else
1854
8.79k
            msg_Dbg( p_demux, "Can't read TS packet at %"PRIu64, vlc_stream_Tell(p_sys->stream) );
1855
8.79k
        return NULL;
1856
8.79k
    }
1857
1858
5.87M
    if( p_pkt->i_buffer < TS_HEADER_SIZE + p_sys->i_packet_header_size )
1859
504
    {
1860
504
        block_Release( p_pkt );
1861
504
        return NULL;
1862
504
    }
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.87M
    p_pkt->p_buffer += p_sys->i_packet_header_size;
1869
5.87M
    p_pkt->i_buffer -= p_sys->i_packet_header_size;
1870
1871
5.87M
    return p_pkt;
1872
5.87M
}
1873
1874
static inline void UpdateESScrambledState( es_out_t *out, const ts_es_t *p_es, bool b_scrambled )
1875
26.4k
{
1876
39.6k
    for( ; p_es; p_es = p_es->p_next )
1877
13.2k
    {
1878
13.2k
        if( p_es->id )
1879
8.46k
            es_out_Control( out, ES_OUT_SET_ES_SCRAMBLED_STATE,
1880
8.46k
                            p_es->id, b_scrambled );
1881
13.2k
        UpdateESScrambledState( out, p_es->p_extraes, b_scrambled );
1882
13.2k
    }
1883
26.4k
}
1884
1885
static void UpdatePIDScrambledState( demux_t *p_demux, ts_pid_t *p_pid, bool b_scrambled )
1886
46.4k
{
1887
46.4k
    if( !SCRAMBLED(*p_pid) == !b_scrambled )
1888
0
        return;
1889
1890
    /* avoid flapping descrambled state on partial scrambling */
1891
46.4k
    if( b_scrambled )
1892
12.5k
    {
1893
12.5k
        p_pid->i_scramble_counter = 4;
1894
12.5k
    }
1895
33.9k
    else if( p_pid->i_scramble_counter != 0 )
1896
27.8k
    {
1897
27.8k
        p_pid->i_scramble_counter--;
1898
27.8k
        return;
1899
27.8k
    }
1900
1901
18.5k
    msg_Warn( p_demux, "scrambled state changed on pid %d (%d->%d)",
1902
18.5k
              p_pid->i_pid, !!SCRAMBLED(*p_pid), b_scrambled );
1903
1904
18.5k
    if( b_scrambled )
1905
12.5k
        p_pid->i_flags |= FLAG_SCRAMBLED;
1906
6.08k
    else
1907
6.08k
        p_pid->i_flags &= ~FLAG_SCRAMBLED;
1908
1909
18.5k
    if( p_pid->type == TYPE_STREAM )
1910
13.2k
        UpdateESScrambledState( p_demux->out, p_pid->u.p_stream->p_es, b_scrambled );
1911
18.5k
}
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.2k
{
2072
32.2k
    demux_sys_t *p_sys = p_demux->p_sys;
2073
32.2k
    int i_count = 0;
2074
32.2k
    block_t *p_pkt = NULL;
2075
2076
32.2k
    for( ;; )
2077
3.26M
    {
2078
3.26M
        ts_90khz_t i_pcr = TS_90KHZ_INVALID;
2079
2080
3.26M
        if( i_count++ > PROBE_CHUNK_COUNT || !( p_pkt = ReadTSPacket( p_demux ) ) )
2081
32.2k
        {
2082
32.2k
            break;
2083
32.2k
        }
2084
2085
3.23M
        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.23M
        const int i_pid = PIDGet( p_pkt );
2093
3.23M
        ts_pid_t *p_pid = GetPID(p_sys, i_pid);
2094
2095
3.23M
        p_pid->i_flags |= FLAG_SEEN;
2096
2097
3.23M
        if( i_pid != 0x1FFF && (p_pkt->p_buffer[1] & 0x80) == 0 ) /* not corrupt */
2098
2.97M
        {
2099
2.97M
            bool b_pcrresult = true;
2100
2.97M
            i_pcr = GetPCR( p_pkt );
2101
2102
            /* Designated PCR pid will be valid, don't repick (on the fly probing) */
2103
2.97M
            if( i_pcr != TS_90KHZ_INVALID && !p_pid->probed.i_pcr_count )
2104
12.6k
                p_pid->probed.i_pcr_count++;
2105
2106
2.97M
            if( i_pcr == TS_90KHZ_INVALID &&
2107
2.69M
                (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* payload start */
2108
1.80M
                (p_pkt->p_buffer[3] & 0xD0) == 0x10 && /* Has payload but is not encrypted */
2109
1.76M
                p_pid->type == TYPE_STREAM &&
2110
1.22M
                p_pid->u.p_stream->p_es->fmt.i_cat != UNKNOWN_ES
2111
2.97M
              )
2112
100k
            {
2113
100k
                b_pcrresult = false;
2114
100k
                unsigned i_skip = PKTHeaderAndAFSize( p_pkt );
2115
100k
                if (p_pkt->i_buffer > i_skip)
2116
100k
                {
2117
100k
                ts_pes_header_t pesh;
2118
100k
                ts_pes_header_init( &pesh );
2119
100k
                if ( VLC_SUCCESS == ParsePESHeader( NULL, &p_pkt->p_buffer[i_skip],
2120
100k
                                                    p_pkt->i_buffer - i_skip, &pesh ) )
2121
92.7k
                {
2122
92.7k
                    if( pesh.i_dts != TS_90KHZ_INVALID )
2123
5.49k
                        i_pcr = pesh.i_dts;
2124
87.2k
                    else if( pesh.i_pts != TS_90KHZ_INVALID )
2125
30.5k
                        i_pcr = pesh.i_pts;
2126
92.7k
                }
2127
100k
                }
2128
100k
            }
2129
2130
2.97M
            if( i_pcr != TS_90KHZ_INVALID )
2131
323k
            {
2132
323k
                ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2133
720k
                for( int i=0; i<p_pat->programs.i_size; i++ )
2134
396k
                {
2135
396k
                    ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
2136
396k
                    if( p_pmt->i_pid_pcr == p_pid->i_pid ||
2137
126k
                          ( p_pmt->i_pid_pcr == 0x1FFF &&
2138
70.6k
                            PIDReferencedByProgram( p_pmt, p_pid->i_pid ) )
2139
396k
                      )
2140
270k
                    {
2141
270k
                        if( b_end )
2142
122k
                        {
2143
122k
                            p_pmt->i_last_dts = FROM_SCALE(i_pcr);
2144
122k
                            p_pmt->i_last_dts_byte = vlc_stream_Tell( p_sys->stream );
2145
122k
                        }
2146
                        /* Start, only keep first */
2147
148k
                        else if( b_pcrresult && p_pmt->pcr.i_first == VLC_TICK_INVALID )
2148
11.5k
                        {
2149
11.5k
                            p_pmt->pcr.i_first = FROM_SCALE(i_pcr);
2150
11.5k
                        }
2151
136k
                        else if( p_pmt->pcr.i_first_dts == VLC_TICK_INVALID )
2152
8.75k
                        {
2153
8.75k
                            p_pmt->pcr.i_first_dts = FROM_SCALE(i_pcr);
2154
8.75k
                        }
2155
2156
270k
                        if( i_program == 0 || i_program == p_pmt->i_number )
2157
269k
                            *pb_found = true;
2158
270k
                    }
2159
396k
                }
2160
323k
            }
2161
2.97M
        }
2162
2163
3.23M
        block_Release( p_pkt );
2164
3.23M
    }
2165
2166
32.2k
    return i_count;
2167
32.2k
}
2168
2169
int ProbeStart( demux_t *p_demux, int i_program )
2170
15.8k
{
2171
15.8k
    demux_sys_t *p_sys = p_demux->p_sys;
2172
15.8k
    const uint64_t i_initial_pos = vlc_stream_Tell( p_sys->stream );
2173
15.8k
    uint64_t i_stream_size;
2174
15.8k
    if( vlc_stream_GetSize( p_sys->stream, &i_stream_size ) != VLC_SUCCESS )
2175
0
      return VLC_EGENERIC;
2176
2177
15.8k
    if( i_stream_size < p_sys->i_packet_size )
2178
0
      return VLC_EGENERIC;
2179
2180
15.8k
    unsigned i_probe_count = 0;
2181
15.8k
    uint64_t i_pos;
2182
15.8k
    bool b_found = false;
2183
2184
15.8k
    do
2185
16.3k
    {
2186
16.3k
        i_pos = p_sys->i_packet_size * i_probe_count;
2187
16.3k
        if( i_pos > i_stream_size - p_sys->i_packet_size )
2188
0
          break;
2189
2190
16.3k
        if( vlc_stream_Seek( p_sys->stream, i_pos ) )
2191
0
            return VLC_EGENERIC;
2192
2193
16.3k
        int i_count =  ProbeChunk( p_demux, i_program, false, &b_found );
2194
16.3k
        if( i_count < PROBE_CHUNK_COUNT )
2195
14.6k
            break;
2196
2197
        /* Go ahead one more chunk if end of file contained only stuffing packets */
2198
1.75k
        i_probe_count += i_count;
2199
1.75k
    } while( i_pos < i_stream_size && !b_found &&
2200
545
             i_probe_count < PROBE_MAX );
2201
2202
15.8k
    if( vlc_stream_Seek( p_sys->stream, i_initial_pos ) )
2203
0
        return VLC_EGENERIC;
2204
2205
15.8k
    return (b_found) ? VLC_SUCCESS : VLC_EGENERIC;
2206
15.8k
}
2207
2208
int ProbeEnd( demux_t *p_demux, int i_program )
2209
15.8k
{
2210
15.8k
    demux_sys_t *p_sys = p_demux->p_sys;
2211
15.8k
    const uint64_t i_initial_pos = vlc_stream_Tell( p_sys->stream );
2212
15.8k
    uint64_t i_stream_size;
2213
15.8k
    if( vlc_stream_GetSize( p_sys->stream, &i_stream_size ) != VLC_SUCCESS )
2214
0
      return VLC_EGENERIC;
2215
2216
15.8k
    unsigned i_probe_count = PROBE_CHUNK_COUNT;
2217
15.8k
    uint64_t i_pos;
2218
15.8k
    bool b_found = false;
2219
15.8k
    const uint64_t i_sync_align_offset = i_initial_pos % p_sys->i_packet_size;
2220
2221
15.8k
    do
2222
15.8k
    {
2223
15.8k
        i_pos = p_sys->i_packet_size * i_probe_count;
2224
15.8k
        if( i_stream_size > i_pos )
2225
2.23k
          i_pos = i_stream_size - i_pos;
2226
13.6k
        else
2227
13.6k
          i_pos = 0;
2228
2229
        /* Avoid resyncing, as the starting point should be packet aligned */
2230
15.8k
        if( i_pos % p_sys->i_packet_size != i_sync_align_offset )
2231
15.1k
            i_pos = i_pos - (i_pos % p_sys->i_packet_size) + i_sync_align_offset;
2232
2233
15.8k
        if( vlc_stream_Seek( p_sys->stream, i_pos ) )
2234
0
            return VLC_EGENERIC;
2235
2236
15.8k
        int i_count = ProbeChunk( p_demux, i_program, true, &b_found );
2237
15.8k
        if( i_count < PROBE_CHUNK_COUNT )
2238
15.8k
            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
15.8k
    if( vlc_stream_Seek( p_sys->stream, i_initial_pos ) )
2246
0
        return VLC_EGENERIC;
2247
2248
15.8k
    return (b_found) ? VLC_SUCCESS : VLC_EGENERIC;
2249
15.8k
}
2250
2251
static void ProgramSetPCR( demux_t *p_demux, ts_pmt_t *p_pmt, vlc_tick_t i_pcr )
2252
188k
{
2253
188k
    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
188k
    if( p_pmt->pcr.i_current == VLC_TICK_INVALID && p_pmt->pcr.b_fix_done )
2258
2.96k
    {
2259
2.96k
        vlc_tick_t i_mindts = VLC_TICK_INVALID;
2260
2261
2.96k
        ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2262
7.07k
        for( int i=0; i< p_pat->programs.i_size; i++ )
2263
4.11k
        {
2264
4.11k
            ts_pmt_t *p_opmt = p_pat->programs.p_elems[i]->u.p_pmt;
2265
16.3k
            for( int j=0; j<p_opmt->e_streams.i_size; j++ )
2266
12.2k
            {
2267
12.2k
                ts_pid_t *p_pid = p_opmt->e_streams.p_elems[j];
2268
12.2k
                block_t *p_block = p_pid->u.p_stream->prepcr.p_head;
2269
16.7k
                while( p_block && p_block->i_dts == VLC_TICK_INVALID )
2270
4.50k
                    p_block = p_block->p_next;
2271
2272
12.2k
                if( p_block && ( i_mindts == VLC_TICK_INVALID || p_block->i_dts < i_mindts ) )
2273
1.80k
                    i_mindts = p_block->i_dts;
2274
12.2k
            }
2275
4.11k
        }
2276
2277
2.96k
        if( i_mindts != VLC_TICK_INVALID )
2278
1.79k
        {
2279
1.79k
            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.63k
            else i_pcr = p_pmt->pcr.i_first;
2286
1.79k
        }
2287
2.96k
    }
2288
2289
188k
    p_pmt->pcr.i_current = i_pcr;
2290
2291
188k
    if( p_pmt->pcr.i_first == VLC_TICK_INVALID )
2292
1.13k
    {
2293
1.13k
        p_pmt->pcr.i_first = i_pcr; // now seen
2294
1.13k
    }
2295
2296
188k
    if ( p_sys->i_pmt_es )
2297
188k
    {
2298
188k
        es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR, p_pmt->i_number, i_pcr );
2299
        /* growing files/named fifo handling */
2300
188k
        if( p_sys->b_access_control == false &&
2301
188k
            vlc_stream_Tell( p_sys->stream ) > p_pmt->i_last_dts_byte )
2302
2.52k
        {
2303
2.52k
            if( p_pmt->i_last_dts_byte == 0 ) /* first run */
2304
1.12k
            {
2305
1.12k
                if( vlc_stream_GetSize( p_sys->stream, &p_pmt->i_last_dts_byte ) != VLC_SUCCESS )
2306
1.12k
                    msg_Dbg( p_demux, "Can't get stream size" );
2307
1.12k
            }
2308
1.40k
            else
2309
1.40k
            {
2310
1.40k
                p_pmt->i_last_dts = i_pcr;
2311
1.40k
                p_pmt->i_last_dts_byte = vlc_stream_Tell( p_sys->stream );
2312
1.40k
            }
2313
2.52k
        }
2314
188k
    }
2315
188k
}
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
173k
{
2341
790k
    for( int i=0; i<p_pmt->e_streams.i_size; i++ )
2342
616k
    {
2343
616k
        ts_pid_t *p_pid = p_pmt->e_streams.p_elems[i];
2344
2345
616k
        if( p_pid->type != TYPE_STREAM || SCRAMBLED(*p_pid) )
2346
40.1k
            continue;
2347
2348
576k
        ts_stream_t *p_pes = p_pid->u.p_stream;
2349
576k
        ts_es_t *p_es = p_pes->p_es;
2350
2351
576k
        if( p_pes->gather.p_data == NULL )
2352
488k
            continue;
2353
88.0k
        if( p_pes->gather.i_data_size != 0 )
2354
80.5k
            continue;
2355
2356
        /* check only MPEG2, H.264 and VC-1 */
2357
7.45k
        if( p_es->fmt.i_codec != VLC_CODEC_MPGV &&
2358
7.45k
            p_es->fmt.i_codec != VLC_CODEC_H264 &&
2359
1.64k
            p_es->fmt.i_codec != VLC_CODEC_VC1 )
2360
1.64k
            continue;
2361
2362
5.80k
        uint8_t header[34];
2363
5.80k
        const int i_max = block_ChainExtract( p_pes->gather.p_data, header, 34 );
2364
2365
5.80k
        ts_pes_header_t pesh;
2366
5.80k
        ts_pes_header_init( &pesh );
2367
2368
5.80k
        if( ParsePESHeader( NULL, (uint8_t*)&header, i_max, &pesh ) == VLC_EGENERIC )
2369
2.27k
            continue;
2370
2371
3.52k
        vlc_tick_t i_dts = VLC_TICK_INVALID;
2372
3.52k
        vlc_tick_t i_pts = VLC_TICK_INVALID;
2373
2374
3.52k
        if( pesh.i_dts != TS_90KHZ_INVALID )
2375
165
            i_dts = TimeStampWrapAround( i_pcr, FROM_SCALE(pesh.i_dts) );
2376
3.52k
        if( pesh.i_pts != TS_90KHZ_INVALID )
2377
2.06k
            i_pts = TimeStampWrapAround( i_pcr, FROM_SCALE(pesh.i_pts) );
2378
2379
3.52k
        if (p_pmt->pcr.i_pcroffset > 0) {
2380
535
            if( i_dts != VLC_TICK_INVALID )
2381
87
                i_dts += p_pmt->pcr.i_pcroffset;
2382
535
            if( i_pts != VLC_TICK_INVALID )
2383
234
                i_pts += p_pmt->pcr.i_pcroffset;
2384
535
        }
2385
2386
3.52k
        if(( i_dts != VLC_TICK_INVALID && i_dts <= i_pcr ) ||
2387
3.48k
           ( 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.52k
    }
2400
173k
}
2401
2402
static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, ts_90khz_t i_pcr )
2403
201k
{
2404
201k
    demux_sys_t   *p_sys = p_demux->p_sys;
2405
2406
201k
    pid->probed.i_pcr_count++;
2407
2408
201k
    if( p_sys->i_pmt_es <= 0 )
2409
13.2k
        return;
2410
2411
188k
    if(unlikely(GetPID(p_sys, 0)->type != TYPE_PAT))
2412
0
        return;
2413
2414
    /* Search program and set the PCR */
2415
188k
    ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2416
384k
    for( int i = 0; i < p_pat->programs.i_size; i++ )
2417
195k
    {
2418
195k
        ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
2419
195k
        if( p_pmt->pcr.b_disable )
2420
1.17k
            continue;
2421
2422
194k
        vlc_tick_t i_past_pcr = p_pmt->pcr.i_current;
2423
194k
        if( i_past_pcr == VLC_TICK_INVALID )
2424
20.5k
            i_past_pcr = p_pmt->pcr.i_first;
2425
2426
194k
        vlc_tick_t i_program_pcr = TimeStampWrapAround( i_past_pcr, FROM_SCALE(i_pcr) );
2427
2428
194k
        if( p_pmt->i_pid_pcr == 0x1FFF ) /* That program has no dedicated PCR pid ISO/IEC 13818-1 2.4.4.9 */
2429
6.87k
        {
2430
6.87k
            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.87k
        }
2436
187k
        else /* set PCR provided by current pid to program(s) referencing it */
2437
187k
        {
2438
            /* Can be dedicated PCR pid (no owned then) or another pid (owner == pmt) */
2439
187k
            if( p_pmt->i_pid_pcr == pid->i_pid ) /* If that program references current pid as PCR */
2440
173k
            {
2441
                /* We've found a target group for update */
2442
173k
                PCRCheckDTS( p_demux, p_pmt, FROM_SCALE(i_pcr) );
2443
173k
                ProgramSetPCR( p_demux, p_pmt, i_program_pcr );
2444
173k
            }
2445
187k
        }
2446
2447
194k
    }
2448
188k
}
2449
2450
int FindPCRCandidate( ts_pmt_t *p_pmt )
2451
1.12k
{
2452
1.12k
    ts_pid_t *p_cand = NULL;
2453
1.12k
    int i_previous = p_pmt->i_pid_pcr;
2454
2455
6.27k
    for( int i=0; i<p_pmt->e_streams.i_size; i++ )
2456
5.14k
    {
2457
5.14k
        ts_pid_t *p_pid = p_pmt->e_streams.p_elems[i];
2458
5.14k
        if( SEEN(p_pid) && p_pid->i_pid != i_previous )
2459
1.39k
        {
2460
1.39k
            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.36k
            if( p_pid->u.p_stream->p_es->fmt.i_cat == AUDIO_ES )
2470
304
            {
2471
304
                if( !p_cand )
2472
290
                    p_cand = p_pid;
2473
304
            }
2474
1.06k
            else if ( p_pid->u.p_stream->p_es->fmt.i_cat == VIDEO_ES ) /* Otherwise prioritize video dts */
2475
79
            {
2476
79
                if( !p_cand || p_cand->u.p_stream->p_es->fmt.i_cat == AUDIO_ES )
2477
78
                    p_cand = p_pid;
2478
79
            }
2479
1.36k
        }
2480
5.14k
    }
2481
2482
1.12k
    if( p_cand )
2483
388
        return p_cand->i_pid;
2484
739
    else
2485
739
        return 0x1FFF;
2486
1.12k
}
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
411k
{
2491
411k
    demux_sys_t *p_sys = p_demux->p_sys;
2492
2493
    /* disable PCR offset check */
2494
411k
    if( !p_sys->b_check_pcr_offset && p_pmt->pcr.i_pcroffset == -1 )
2495
0
        p_pmt->pcr.i_pcroffset = 0;
2496
2497
411k
    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
411k
    else if( p_pmt->pcr.i_first_dts == VLC_TICK_INVALID )
2503
39.8k
    {
2504
39.8k
        p_pmt->pcr.i_first_dts = p_block->i_dts;
2505
39.8k
    }
2506
371k
    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.89k
    {
2508
4.89k
        if( p_pmt->pcr.i_current == VLC_TICK_INVALID &&
2509
3.08k
            GetPID( p_sys, p_pmt->i_pid_pcr )->probed.i_pcr_count == 0 )
2510
1.12k
        {
2511
1.12k
            int i_cand = FindPCRCandidate( p_pmt );
2512
1.12k
            p_pmt->i_pid_pcr = i_cand;
2513
1.12k
            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.12k
            msg_Warn( p_demux, "No PCR received for program %d, set up workaround using pid %d",
2516
1.12k
                      p_pmt->i_number, i_cand );
2517
1.12k
            UpdatePESFilters( p_demux, p_sys->seltype == PROGRAM_ALL );
2518
1.12k
        }
2519
4.89k
        p_pmt->pcr.b_fix_done = true;
2520
4.89k
    }
2521
411k
}
2522
2523
static block_t * ProcessTSPacket( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, int *pi_skip )
2524
2.60M
{
2525
2.60M
    demux_sys_t *p_sys = p_demux->p_sys;
2526
2.60M
    const uint8_t *p = p_pkt->p_buffer;
2527
2.60M
    const bool b_adaptation = p[3]&0x20;
2528
2.60M
    const bool b_payload    = p[3]&0x10;
2529
2.60M
    const bool b_scrambled  = p[3]&0xc0;
2530
2.60M
    const int  i_cc         = p[3]&0x0f; /* continuity counter */
2531
2.60M
    bool       b_discontinuity = false;  /* discontinuity */
2532
2533
    /* transport_scrambling_control is ignored */
2534
2.60M
    *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.60M
    if( unlikely(pid->i_pid == 0x1FFF) )
2544
192k
    {
2545
192k
        block_Release( p_pkt );
2546
192k
        return NULL;
2547
192k
    }
2548
2549
    /* For now, ignore additional error correction
2550
     * TODO: handle Reed-Solomon 204,188 error correction */
2551
2.40M
    p_pkt->i_buffer = TS_PACKET_SIZE_188;
2552
2553
2.40M
    if( b_scrambled )
2554
85.9k
    {
2555
85.9k
        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
85.9k
        else
2562
85.9k
            p_pkt->i_flags |= BLOCK_FLAG_SCRAMBLED;
2563
85.9k
    }
2564
2565
    /* We don't have any adaptation_field, so payload starts
2566
     * immediately after the 4 byte TS header */
2567
2.40M
    if( b_adaptation )
2568
1.08M
    {
2569
        /* p[4] is adaptation_field_length minus one */
2570
1.08M
        *pi_skip += 1 + p[4];
2571
1.08M
        if( p[4] + 5 > 188 /* adaptation field only == 188 */ )
2572
10.8k
        {
2573
            /* Broken is broken */
2574
10.8k
            block_Release( p_pkt );
2575
10.8k
            return NULL;
2576
10.8k
        }
2577
1.07M
        else if( p[4] > 0 )
2578
1.06M
        {
2579
            /* discontinuity indicator found in stream */
2580
1.06M
            b_discontinuity = (p[5]&0x80) ? true : false;
2581
1.06M
            if( b_discontinuity )
2582
148k
            {
2583
148k
                msg_Warn( p_demux, "discontinuity indicator (pid=%d) ",
2584
148k
                            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
148k
                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
148k
            }
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.06M
        }
2597
1.08M
    }
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.39M
    if( b_payload && p_sys->b_cc_check )
2607
2.34M
    {
2608
2.34M
        const int i_diff = ( i_cc - pid->i_cc )&0x0f;
2609
2.34M
        if( i_diff == 1 )
2610
828k
        {
2611
828k
            pid->i_cc = ( pid->i_cc + 1 ) & 0xf;
2612
828k
            pid->i_dup = 0;
2613
828k
        }
2614
1.51M
        else
2615
1.51M
        {
2616
1.51M
            if( pid->i_cc == 0xff )
2617
121k
            {
2618
121k
                msg_Dbg( p_demux, "first packet for pid=%d cc=0x%x",
2619
121k
                         pid->i_pid, i_cc );
2620
121k
                pid->i_cc = i_cc;
2621
121k
            }
2622
1.39M
            else if( i_diff == 0 && pid->i_dup == 0 &&
2623
222k
                     !memcmp(pid->prevpktbytes, /* see comment below */
2624
222k
                             &p_pkt->p_buffer[1], PREVPKTKEEPBYTES)  )
2625
96.4k
            {
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
96.4k
                pid->i_dup++;
2633
96.4k
                block_Release( p_pkt );
2634
96.4k
                return NULL;
2635
96.4k
            }
2636
1.29M
            else if( i_diff != 0 && !b_discontinuity )
2637
625k
            {
2638
625k
                msg_Warn( p_demux, "discontinuity received 0x%x instead of 0x%x (pid=%d)",
2639
625k
                          i_cc, ( pid->i_cc + 1 )&0x0f, pid->i_pid );
2640
2641
625k
                pid->i_cc = i_cc;
2642
625k
                pid->i_dup = 0;
2643
625k
                p_pkt->i_flags |= BLOCK_FLAG_PRIVATE_PACKET_LOSS;
2644
625k
            }
2645
672k
            else pid->i_cc = i_cc;
2646
1.51M
        }
2647
2.24M
        memcpy(pid->prevpktbytes, &p_pkt->p_buffer[1], PREVPKTKEEPBYTES);
2648
2.24M
    }
2649
52.5k
    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
52.5k
    {
2654
52.5k
        if( b_discontinuity )
2655
3.31k
            pid->i_cc = i_cc;
2656
52.5k
    }
2657
2658
2.30M
    if( unlikely(!(b_payload || b_adaptation)) ) /* Invalid, ignore */
2659
43.0k
    {
2660
43.0k
        block_Release( p_pkt );
2661
43.0k
        return NULL;
2662
43.0k
    }
2663
2664
2.25M
    return p_pkt;
2665
2.30M
}
2666
2667
static bool GatherPESData( demux_t *p_demux, ts_pid_t *p_pid, block_t *p_pkt, size_t i_skip )
2668
1.45M
{
2669
1.45M
    demux_sys_t *p_sys = p_demux->p_sys;
2670
1.45M
    ts_pes_parse_callback cb = { .p_obj = VLC_OBJECT(p_demux),
2671
1.45M
                                 .priv = p_pid,
2672
1.45M
                                 .pf_parse = PESDataChainHandle };
2673
1.45M
    const bool b_unit_start = p_pkt->p_buffer[1]&0x40;
2674
2675
1.45M
    p_pkt->p_buffer += i_skip; /* point to PES */
2676
1.45M
    p_pkt->i_buffer -= i_skip;
2677
2678
1.45M
    const ts_es_t *p_es = p_pid->u.p_stream->p_es;
2679
1.45M
    ts_90khz_t i_append_pcr = ( p_es && p_es->p_program && p_es->p_program->pcr.i_current != VLC_TICK_INVALID )
2680
1.45M
                                  ? TO_SCALE(p_es->p_program->pcr.i_current)
2681
1.45M
                                  : TS_90KHZ_INVALID;
2682
2683
1.45M
    return ts_pes_Gather( &cb, p_pid->u.p_stream,
2684
1.45M
                          p_pkt, b_unit_start,
2685
1.45M
                          p_sys->b_valid_scrambling,
2686
1.45M
                          i_append_pcr );
2687
1.45M
}
2688
2689
static bool GatherSectionsData( demux_t *p_demux, ts_pid_t *p_pid, block_t *p_pkt, size_t i_skip )
2690
247k
{
2691
247k
    VLC_UNUSED(i_skip); VLC_UNUSED(p_demux);
2692
247k
    bool b_ret = false;
2693
2694
247k
    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
247k
    if( (p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) == 0 )
2700
239k
    {
2701
239k
        ts_sections_processor_Push( p_pid->u.p_stream->p_sections_proc, p_pkt->p_buffer );
2702
239k
        b_ret = true;
2703
239k
    }
2704
2705
247k
    block_Release( p_pkt );
2706
2707
247k
    return b_ret;
2708
247k
}
2709
2710
void TsChangeStandard( demux_sys_t *p_sys, ts_standards_e v )
2711
16.6k
{
2712
16.6k
    if( p_sys->standard != TS_STANDARD_AUTO &&
2713
0
        p_sys->standard != v )
2714
0
        return; /* TODO */
2715
16.6k
    p_sys->standard = v;
2716
16.6k
}
2717
2718
bool ProgramIsSelected( demux_sys_t *p_sys, uint16_t i_pgrm )
2719
89.8k
{
2720
89.8k
    if( p_sys->seltype == PROGRAM_ALL )
2721
0
        return true;
2722
2723
96.2k
    for(int i=0; i<p_sys->programs.i_size; i++)
2724
89.8k
        if( p_sys->programs.p_elems[i] == i_pgrm )
2725
83.4k
            return true;
2726
2727
6.41k
    return false;
2728
89.8k
}
2729
2730
static bool PIDReferencedByProgram( const ts_pmt_t *p_pmt, uint16_t i_pid )
2731
77.5k
{
2732
77.6k
    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.4k
    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.4k
{
2741
68.4k
    demux_sys_t *p_sys = p_demux->p_sys;
2742
2743
102k
    for( ; p_es ; p_es = p_es->p_next )
2744
34.2k
    {
2745
34.2k
        if( !p_es->id )
2746
34.2k
        {
2747
34.2k
            if( !p_es->fmt.i_group )
2748
0
                p_es->fmt.i_group = p_es->p_program->i_number;
2749
34.2k
            p_es->id = es_out_Add( p_demux->out, &p_es->fmt );
2750
34.2k
            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.2k
            p_sys->i_pmt_es++;
2757
34.2k
        }
2758
34.2k
        DoCreateES( p_demux, p_es->p_extraes, p_es );
2759
34.2k
    }
2760
68.4k
}
2761
2762
void AddAndCreateES( demux_t *p_demux, ts_pid_t *pid, bool b_create_delayed )
2763
34.2k
{
2764
34.2k
    demux_sys_t  *p_sys = p_demux->p_sys;
2765
2766
34.2k
    if( b_create_delayed )
2767
0
        p_sys->es_creation = CREATE_ES;
2768
2769
34.2k
    if( pid && p_sys->es_creation == CREATE_ES )
2770
34.2k
    {
2771
34.2k
        DoCreateES( p_demux, pid->u.p_stream->p_es, NULL );
2772
2773
        /* Update the default program == first created ES group */
2774
34.2k
        if( p_sys->b_default_selection && p_sys->programs.i_size > 0)
2775
4.08k
        {
2776
4.08k
            p_sys->b_default_selection = false;
2777
4.08k
            const int i_first_program = pid->u.p_stream->p_es->p_program->i_number;
2778
4.08k
            if( p_sys->programs.p_elems[0] != i_first_program )
2779
68
                p_sys->programs.p_elems[0] = i_first_program;
2780
4.08k
            msg_Dbg( p_demux, "Default program is %d", i_first_program );
2781
4.08k
        }
2782
34.2k
    }
2783
2784
34.2k
    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.2k
}