Coverage Report

Created: 2026-05-16 07:42

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
134
vlc_module_begin ()
140
67
    set_description( N_("MPEG Transport Stream demuxer") )
141
67
    set_shortname ( "MPEG-TS" )
142
67
    set_subcategory( SUBCAT_INPUT_DEMUX )
143
144
67
    add_string( "ts-standard", "auto", STANDARD_TEXT, STANDARD_LONGTEXT )
145
67
        change_string_list( ts_standards_list, ts_standards_list_text )
146
147
67
    add_string( "ts-extra-pmt", NULL, PMT_TEXT, PMT_LONGTEXT )
148
67
    add_bool( "ts-trust-pcr", true, PCR_TEXT, PCR_LONGTEXT )
149
67
        change_safe()
150
67
    add_bool( "ts-es-id-pid", true, PID_TEXT, PID_LONGTEXT )
151
67
        change_safe()
152
67
    add_string( "ts-csa-ck", NULL, CSA_TEXT, CSA_LONGTEXT )
153
67
        change_safe()
154
67
    add_string( "ts-csa2-ck", NULL, CSA2_TEXT, CSA2_LONGTEXT )
155
67
        change_safe()
156
67
    add_integer( "ts-csa-pkt", 188, CPKT_TEXT, CPKT_LONGTEXT )
157
67
        change_safe()
158
159
67
    add_bool( "ts-split-es", true, SPLIT_ES_TEXT, SPLIT_ES_LONGTEXT )
160
67
    add_bool( "ts-seek-percent", false, SEEK_PERCENT_TEXT, SEEK_PERCENT_LONGTEXT )
161
67
    add_bool( "ts-cc-check", true, CC_CHECK_TEXT, CC_CHECK_LONGTEXT )
162
67
    add_bool( "ts-pmtfix-waitdata", true, TS_SKIP_GHOST_PROGRAM_TEXT, NULL )
163
67
    add_bool( "ts-patfix", true, TS_PATFIX_TEXT, NULL )
164
67
    add_bool( "ts-pcr-offsetfix", true, TS_OFFSETFIX_TEXT, NULL )
165
67
    add_integer_with_range( "ts-generated-pcr-offset", 120, 0, 500,
166
67
                            TS_GENERATED_PCR_OFFSET_TEXT, NULL )
167
168
67
    set_capability( "demux", 10 )
169
134
    set_callbacks( Open, Close )
170
67
    add_shortcut( "ts" )
171
67
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
5.39M
#define PROBE_CHUNK_COUNT 500
199
569
#define PROBE_MAX         (PROBE_CHUNK_COUNT * 10)
200
201
static int DetectPacketSize( demux_t *p_demux, unsigned *pi_header_size, int i_offset )
202
5.03k
{
203
5.03k
    const uint8_t *p_peek;
204
205
5.03k
    if( vlc_stream_Peek( p_demux->s,
206
5.03k
                     &p_peek, i_offset + TS_PACKET_SIZE_MAX ) < i_offset + TS_PACKET_SIZE_MAX )
207
0
        return -1;
208
209
1.01M
    for( int i_sync = 0; i_sync < TS_PACKET_SIZE_MAX; i_sync++ )
210
1.01M
    {
211
1.01M
        if( p_peek[i_offset + i_sync] != 0x47 )
212
998k
            continue;
213
214
        /* Check next 3 sync bytes */
215
14.1k
        int i_peek = i_offset + TS_PACKET_SIZE_MAX * 3 + i_sync + 1;
216
14.1k
        if( ( vlc_stream_Peek( p_demux->s, &p_peek, i_peek ) ) < i_peek )
217
0
            return -1;
218
219
14.1k
        if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_188] == 0x47 &&
220
2.11k
            p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_188] == 0x47 &&
221
823
            p_peek[i_offset + i_sync + 3 * TS_PACKET_SIZE_188] == 0x47 )
222
129
        {
223
129
            return TS_PACKET_SIZE_188;
224
129
        }
225
14.0k
        else if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_192] == 0x47 &&
226
858
                 p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_192] == 0x47 &&
227
197
                 p_peek[i_offset + i_sync + 3 * TS_PACKET_SIZE_192] == 0x47 )
228
5
        {
229
5
            if( i_sync == 4 )
230
0
            {
231
0
                *pi_header_size = 4; /* BluRay TS packets have 4-byte header */
232
0
            }
233
5
            return TS_PACKET_SIZE_192;
234
5
        }
235
13.9k
        else if( p_peek[i_offset + i_sync + 1 * TS_PACKET_SIZE_204] == 0x47 &&
236
759
                 p_peek[i_offset + i_sync + 2 * TS_PACKET_SIZE_204] == 0x47 &&
237
186
                 p_peek[i_offset + i_sync + 3 * TS_PACKET_SIZE_204] == 0x47 )
238
10
        {
239
10
            return TS_PACKET_SIZE_204;
240
10
        }
241
14.1k
    }
242
243
4.88k
    if( p_demux->obj.force )
244
3.92k
    {
245
3.92k
        msg_Warn( p_demux, "this does not look like a TS stream, continuing" );
246
3.92k
        return TS_PACKET_SIZE_188;
247
3.92k
    }
248
962
    msg_Dbg( p_demux, "TS module discarded (lost sync)" );
249
962
    return -1;
250
4.88k
}
251
252
111
#define TOPFIELD_HEADER_SIZE 3712
253
254
static int DetectPVRHeadersAndHeaderSize( demux_t *p_demux, unsigned *pi_header_size, vdr_info_t *p_vdr )
255
5.03k
{
256
5.03k
    const uint8_t *p_peek;
257
5.03k
    *pi_header_size = 0;
258
5.03k
    int i_packet_size = -1;
259
5.03k
    int i_offset = 0;
260
261
5.03k
    if( vlc_stream_Peek( p_demux->s,
262
5.03k
                     &p_peek, TS_PACKET_SIZE_MAX ) < TS_PACKET_SIZE_MAX )
263
0
        return -1;
264
265
5.03k
    if( memcmp( p_peek, "TFrc", 4 ) == 0 && p_peek[6] == 0 &&
266
37
        vlc_stream_Peek( p_demux->s, &p_peek, TOPFIELD_HEADER_SIZE + TS_PACKET_SIZE_MAX )
267
37
            == TOPFIELD_HEADER_SIZE + TS_PACKET_SIZE_MAX )
268
37
    {
269
37
        const int i_service = GetWBE(&p_peek[18]);
270
37
        i_packet_size = DetectPacketSize( p_demux, pi_header_size, TOPFIELD_HEADER_SIZE );
271
37
        if( i_packet_size != -1 )
272
36
        {
273
36
            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
36
            p_vdr->i_service = i_service;
338
339
36
            return i_packet_size;
340
            //return TS_PACKET_SIZE_188;
341
36
        }
342
37
    }
343
4.99k
    else if( !memcmp( p_peek, "\x47\xff\xffPRIV", 7 ) ) /* Denver */
344
0
    {
345
        /* Bogus TS packets with private payload interleaved in stream */
346
0
        i_offset = TS_PACKET_SIZE_188 * 11;
347
0
    }
348
349
4.99k
    return DetectPacketSize( p_demux, pi_header_size, i_offset );
350
5.03k
}
351
352
/*****************************************************************************
353
 * Open
354
 *****************************************************************************/
355
static int Open( vlc_object_t *p_this )
356
5.03k
{
357
5.03k
    demux_t     *p_demux = (demux_t*)p_this;
358
5.03k
    demux_sys_t *p_sys;
359
360
5.03k
    int          i_packet_size;
361
5.03k
    unsigned     i_packet_header_size = 0;
362
363
5.03k
    ts_pid_t    *patpid;
364
5.03k
    vdr_info_t   vdr = {0};
365
366
    /* Search first sync byte */
367
5.03k
    i_packet_size = DetectPVRHeadersAndHeaderSize( p_demux, &i_packet_header_size, &vdr );
368
5.03k
    if( i_packet_size < 0 )
369
961
        return VLC_EGENERIC;
370
371
4.07k
    p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
372
4.07k
    if( !p_sys )
373
0
        return VLC_ENOMEM;
374
4.07k
    memset( p_sys, 0, sizeof( demux_sys_t ) );
375
4.07k
    vlc_mutex_init( &p_sys->csa_lock );
376
377
4.07k
    p_demux->pf_demux = Demux;
378
4.07k
    p_demux->pf_control = Control;
379
380
    /* Init p_sys field */
381
4.07k
    p_sys->b_end_preparse = false;
382
4.07k
    ARRAY_INIT( p_sys->programs );
383
4.07k
    p_sys->b_default_selection = false;
384
4.07k
    p_sys->i_network_time = 0;
385
4.07k
    p_sys->i_network_time_update = 0;
386
387
4.07k
    p_sys->vdr = vdr;
388
389
4.07k
    p_sys->stream = p_demux->s;
390
391
4.07k
    p_sys->b_broken_charset = false;
392
393
4.07k
    ts_pid_list_Init( &p_sys->pids );
394
395
4.07k
    p_sys->i_packet_size = i_packet_size;
396
4.07k
    p_sys->i_packet_header_size = i_packet_header_size;
397
4.07k
    p_sys->i_ts_read = 50;
398
4.07k
    p_sys->csa = NULL;
399
4.07k
    p_sys->b_start_record = false;
400
4.07k
    p_sys->record_dir_path = NULL;
401
402
4.07k
    vlc_dictionary_init( &p_sys->attachments, 0 );
403
404
4.07k
    p_sys->patfix.i_first_dts = VLC_TICK_INVALID;
405
4.07k
    p_sys->patfix.i_timesourcepid = 0;
406
4.07k
    p_sys->patfix.b_pcrhasnopcrfield = false;
407
4.07k
    p_sys->patfix.status = var_CreateGetBool( p_demux, "ts-patfix" ) ? PAT_WAITING : PAT_FIXTRIED;
408
409
    /* Init PAT handler */
410
4.07k
    patpid = GetPID(p_sys, 0);
411
4.07k
    if ( !PIDSetup( p_demux, TYPE_PAT, patpid, NULL ) )
412
0
    {
413
0
        free( p_sys );
414
0
        return VLC_ENOMEM;
415
0
    }
416
4.07k
    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
4.07k
    p_sys->b_access_control = true;
425
4.07k
    p_sys->b_access_control = ( VLC_SUCCESS == SetPIDFilter( p_sys, patpid, true ) );
426
427
4.07k
    p_sys->i_pmt_es = 0;
428
4.07k
    p_sys->seltype = PROGRAM_AUTO_DEFAULT;
429
430
    /* Read config */
431
4.07k
    p_sys->b_es_id_pid = var_CreateGetBool( p_demux, "ts-es-id-pid" );
432
4.07k
    p_sys->i_next_extraid = 1;
433
434
4.07k
    p_sys->b_trust_pcr = var_CreateGetBool( p_demux, "ts-trust-pcr" );
435
4.07k
    p_sys->b_check_pcr_offset = p_sys->b_trust_pcr && var_CreateGetBool(p_demux, "ts-pcr-offsetfix" );
436
4.07k
    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
4.07k
    char* psz_string = var_CreateGetString( p_demux, "ts-extra-pmt" );
440
4.07k
    p_sys->b_user_pmt = false;
441
4.07k
    if( psz_string && *psz_string )
442
0
        UserPmt( p_demux, psz_string );
443
4.07k
    free( psz_string );
444
445
4.07k
    psz_string = var_CreateGetStringCommand( p_demux, "ts-csa-ck" );
446
4.07k
    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
4.07k
    free( psz_string );
497
498
4.07k
    p_sys->b_split_es = var_InheritBool( p_demux, "ts-split-es" );
499
500
4.07k
    p_sys->b_canseek = false;
501
4.07k
    p_sys->b_canfastseek = false;
502
4.07k
    p_sys->b_lowdelay = var_InheritBool( p_demux, "low-delay" );
503
4.07k
    p_sys->b_ignore_time_for_positions = var_InheritBool( p_demux, "ts-seek-percent" );
504
4.07k
    p_sys->b_cc_check = var_InheritBool( p_demux, "ts-cc-check" );
505
506
4.07k
    p_sys->standard = TS_STANDARD_AUTO;
507
4.07k
    char *psz_standard = var_InheritString( p_demux, "ts-standard" );
508
4.07k
    if( psz_standard )
509
4.07k
    {
510
4.07k
        for( unsigned i=0; i<ARRAY_SIZE(ts_standards_list); i++ )
511
4.07k
        {
512
4.07k
            if( !strcmp( psz_standard, ts_standards_list[i] ) )
513
4.07k
            {
514
4.07k
                TsChangeStandard( p_sys, TS_STANDARD_AUTO + i );
515
4.07k
                msg_Dbg( p_demux, "Standard set to %s", ts_standards_list_text[i] );
516
4.07k
                break;
517
4.07k
            }
518
4.07k
        }
519
4.07k
        free( psz_standard );
520
4.07k
    }
521
522
4.07k
    if( p_sys->standard == TS_STANDARD_AUTO &&
523
4.07k
       !strncasecmp( p_demux->psz_url, "atsc", 4 ) )
524
0
    {
525
0
        TsChangeStandard( p_sys, TS_STANDARD_ATSC );
526
0
    }
527
528
4.07k
    vlc_stream_Control( p_sys->stream, STREAM_CAN_SEEK, &p_sys->b_canseek );
529
4.07k
    vlc_stream_Control( p_sys->stream, STREAM_CAN_FASTSEEK,
530
4.07k
                        &p_sys->b_canfastseek );
531
532
4.07k
    if( !p_sys->b_access_control && var_CreateGetBool( p_demux, "ts-pmtfix-waitdata" ) )
533
4.07k
        p_sys->es_creation = DELAY_ES;
534
0
    else
535
0
        p_sys->es_creation = CREATE_ES;
536
537
    /* Preparse time */
538
4.07k
    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
4.07k
    return VLC_SUCCESS;
546
4.07k
}
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
4.07k
{
559
4.07k
    demux_t     *p_demux = (demux_t*)p_this;
560
4.07k
    demux_sys_t *p_sys = p_demux->p_sys;
561
562
4.07k
    PIDRelease( p_demux, GetPID(p_sys, 0) );
563
564
4.07k
    vlc_mutex_lock( &p_sys->csa_lock );
565
4.07k
    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
4.07k
    vlc_mutex_unlock( &p_sys->csa_lock );
572
573
4.07k
    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
4.07k
    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
4.07k
    ts_pid_list_Release( p_demux, &p_sys->pids );
588
589
    /* Clear up attachments */
590
4.07k
    vlc_dictionary_clear( &p_sys->attachments, FreeDictAttachment, NULL );
591
592
4.07k
    free( p_sys->record_dir_path );
593
4.07k
    free( p_sys );
594
4.07k
}
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
955k
{
623
955k
    demux_sys_t *p_sys = p_demux->p_sys;
624
955k
    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
955k
    if( p_sys->i_pmt_es == 0 && !SEEN(GetPID(p_sys, 0)) && p_sys->patfix.status == PAT_MISSING )
628
356
    {
629
356
        msg_Warn( p_demux, "Generating PAT as we still have not received one" );
630
356
        MissingPATPMTFixup( p_demux );
631
356
        GetPID(p_sys, 0)->u.p_pat->b_generated = true;
632
356
        p_sys->patfix.status = PAT_FIXTRIED;
633
356
    }
634
635
    /* We read at most 100 TS packet or until a frame is completed */
636
2.50M
    for( unsigned i_pkt = 0; i_pkt < p_sys->i_ts_read; i_pkt++ )
637
2.50M
    {
638
2.50M
        bool         b_frame = false;
639
2.50M
        int          i_header = 0;
640
2.50M
        block_t     *p_pkt;
641
2.50M
        if( !(p_pkt = ReadTSPacket( p_demux )) )
642
4.07k
        {
643
4.07k
            return VLC_DEMUXER_EOF;
644
4.07k
        }
645
646
2.49M
        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.49M
        if( unlikely(p_pkt->i_buffer < TS_PACKET_SIZE_188) )
656
768
        {
657
768
            block_Release( p_pkt );
658
768
            continue;
659
768
        }
660
661
        /* Reject any fully uncorrected packet. Even PID can be incorrect */
662
2.49M
        if( p_pkt->p_buffer[1]&0x80 )
663
43.4k
        {
664
43.4k
            msg_Dbg( p_demux, "transport_error_indicator set (pid=%d)",
665
43.4k
                     PIDGet( p_pkt ) );
666
43.4k
            block_Release( p_pkt );
667
43.4k
            continue;
668
43.4k
        }
669
670
        /* Parse the TS packet */
671
2.45M
        ts_pid_t *p_pid = GetPID( p_sys, PIDGet( p_pkt ) );
672
2.45M
        if( !SEEN(p_pid) )
673
19.6k
        {
674
19.6k
            if( p_pid->type == TYPE_FREE )
675
19.6k
                msg_Dbg( p_demux, "pid[%d] unknown", p_pid->i_pid );
676
19.6k
            p_pid->i_flags |= FLAG_SEEN;
677
19.6k
            if( p_pid->i_pid == 0x01 )
678
63
                p_sys->b_valid_scrambling = true;
679
19.6k
        }
680
681
        /* Drop duplicates and invalid (DOES NOT drop corrupted) */
682
2.45M
        p_pkt = ProcessTSPacket( p_demux, p_pid, p_pkt, &i_header );
683
2.45M
        if( !p_pkt )
684
332k
            continue;
685
686
2.12M
        if( !SCRAMBLED(*p_pid) != !(p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) &&
687
69.6k
            ( p_pkt->p_buffer[1] & 0x40 ) ) /* update on payload start */
688
51.4k
        {
689
51.4k
            UpdatePIDScrambledState( p_demux, p_pid, p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED );
690
51.4k
        }
691
692
        /* Adaptation field cannot be scrambled */
693
2.12M
        ts_90khz_t i_pcr = GetPCR( p_pkt );
694
2.12M
        if( i_pcr != TS_90KHZ_INVALID )
695
154k
            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.12M
        if( !SEEN( GetPID( p_sys, 0 ) ) &&
699
60.1k
            (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* Payload start but not corrupt */
700
39.8k
            (p_pkt->p_buffer[3] & 0xD0) == 0x10 )  /* Has payload but is not encrypted */
701
37.8k
        {
702
37.8k
            ProbePES( p_demux, p_pid, p_pkt );
703
37.8k
        }
704
705
2.12M
        switch( p_pid->type )
706
2.12M
        {
707
72.7k
        case TYPE_PAT:
708
175k
        case TYPE_PMT:
709
            /* PAT and PMT are not allowed to be scrambled */
710
175k
            ts_psi_Packet_Push( p_pid, p_pkt->p_buffer );
711
175k
            block_Release( p_pkt );
712
175k
            break;
713
714
1.61M
        case TYPE_STREAM:
715
1.61M
            p_sys->b_end_preparse = true;
716
717
1.61M
            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.61M
            if( !p_sys->b_access_control && !(p_pid->i_flags & FLAG_FILTERED) )
726
1.69k
            {
727
                /* That packet is for an unselected ES, don't waste time/memory gathering its data */
728
1.69k
                block_Release( p_pkt );
729
1.69k
                continue;
730
1.69k
            }
731
732
1.61M
            if( p_pid->u.p_stream->transport == TS_TRANSPORT_PES )
733
1.42M
            {
734
1.42M
                b_frame = GatherPESData( p_demux, p_pid, p_pkt, i_header );
735
1.42M
            }
736
188k
            else if( p_pid->u.p_stream->transport == TS_TRANSPORT_SECTIONS )
737
188k
            {
738
188k
                b_frame = GatherSectionsData( p_demux, p_pid, p_pkt, i_header );
739
188k
            }
740
0
            else // pid->u.p_pes->transport == TS_TRANSPORT_IGNORE
741
0
            {
742
0
                block_Release( p_pkt );
743
0
            }
744
745
1.61M
            break;
746
747
13.1k
        case TYPE_SI:
748
13.1k
            if( (p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) == 0 )
749
13.0k
                ts_si_Packet_Push( p_pid, p_pkt->p_buffer );
750
13.1k
            block_Release( p_pkt );
751
13.1k
            break;
752
753
370
        case TYPE_PSIP:
754
370
            if( (p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) == 0 )
755
84
                ts_psip_Packet_Push( p_pid, p_pkt->p_buffer );
756
370
            block_Release( p_pkt );
757
370
            break;
758
759
0
        case TYPE_CAT:
760
314k
        default:
761
            /* We have to handle PCR if present */
762
314k
            block_Release( p_pkt );
763
314k
            break;
764
2.12M
        }
765
766
2.12M
        if( b_frame || ( b_wait_es && p_sys->i_pmt_es > 0 ) )
767
948k
            break;
768
2.12M
    }
769
770
951k
    demux_UpdateTitleFromStream( p_demux );
771
951k
    return VLC_DEMUXER_SUCCESS;
772
955k
}
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
14.1k
{
802
14.1k
    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
14.1k
}
810
811
void UpdatePESFilters( demux_t *p_demux, bool b_all )
812
89.6k
{
813
89.6k
    demux_sys_t *p_sys = p_demux->p_sys;
814
89.6k
    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
182k
    for( int i=0; i< p_pat->programs.i_size; i++ )
824
93.0k
    {
825
93.0k
        ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
826
93.0k
        ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
827
828
93.0k
        p_pmt_pid->i_flags &= ~FLAG_FILTERED;
829
422k
        for( int j=0; j< p_pmt->e_streams.i_size; j++ )
830
329k
            p_pmt->e_streams.p_elems[j]->i_flags &= ~FLAG_FILTERED;
831
93.0k
        GetPID(p_sys, p_pmt->i_pid_pcr)->i_flags &= ~FLAG_FILTERED;
832
93.0k
    }
833
834
    /* set selection flag on selected pmt referenced pid with active es */
835
182k
    for( int i=0; i< p_pat->programs.i_size; i++ )
836
93.0k
    {
837
93.0k
        ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
838
93.0k
        ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
839
93.0k
        const bool b_prev_selection = p_pmt->b_selected;
840
841
93.0k
        if( (p_sys->b_default_selection && !p_sys->b_access_control) || b_all )
842
56.1k
             p_pmt->b_selected = true;
843
36.8k
        else
844
36.8k
             p_pmt->b_selected = ProgramIsSelected( p_sys, p_pmt->i_number );
845
846
        /* Notify CI for program selection changes */
847
93.0k
        if( b_prev_selection != p_pmt->b_selected )
848
4.11k
            SendCAPMTUpdate( p_demux, p_pmt );
849
850
93.0k
        if( p_pmt->b_selected )
851
90.5k
        {
852
90.5k
            p_pmt_pid->i_flags |= FLAG_FILTERED;
853
854
419k
            for( int j=0; j<p_pmt->e_streams.i_size; j++ )
855
328k
            {
856
328k
                ts_pid_t *espid = p_pmt->e_streams.p_elems[j];
857
328k
                ts_stream_t *p_pes = espid->u.p_stream;
858
859
328k
                bool b_stream_selected = true;
860
328k
                if( !p_pes->b_always_receive && !b_all )
861
14.1k
                    HasSelectedES( p_demux->out, p_pes->p_es, p_pmt, &b_stream_selected );
862
863
328k
                if( b_stream_selected )
864
328k
                {
865
328k
                    msg_Dbg( p_demux, "enabling pid %d from program %d", espid->i_pid, p_pmt->i_number );
866
328k
                    espid->i_flags |= FLAG_FILTERED;
867
328k
                }
868
328k
            }
869
870
            /* Select pcr last in case it is handled by unselected ES */
871
90.5k
            if( p_pmt->i_pid_pcr > 0 )
872
90.5k
            {
873
90.5k
                GetPID(p_sys, p_pmt->i_pid_pcr)->i_flags |= FLAG_FILTERED;
874
90.5k
                msg_Dbg( p_demux, "enabling pcr pid %d from program %d", p_pmt->i_pid_pcr, p_pmt->i_number );
875
90.5k
            }
876
90.5k
        }
877
93.0k
    }
878
879
    /* Commit HW changes based on flags */
880
182k
    for( int i=0; i< p_pat->programs.i_size; i++ )
881
93.0k
    {
882
93.0k
        ts_pid_t *p_pmt_pid = p_pat->programs.p_elems[i];
883
93.0k
        ts_pmt_t *p_pmt = p_pmt_pid->u.p_pmt;
884
885
93.0k
        UpdateHWFilter( p_sys, p_pmt_pid );
886
422k
        for( int j=0; j< p_pmt->e_streams.i_size; j++ )
887
329k
        {
888
329k
            ts_pid_t *espid = p_pmt->e_streams.p_elems[j];
889
329k
            UpdateHWFilter( p_sys, espid );
890
329k
            if( (espid->i_flags & FLAG_FILTERED) == 0 )
891
694
                FlushESBuffer( espid->u.p_stream );
892
329k
        }
893
93.0k
        UpdateHWFilter( p_sys, GetPID(p_sys, p_pmt->i_pid_pcr) );
894
93.0k
    }
895
89.6k
}
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
0
{
1370
0
    vlc_tick_t i_ts = p_pmt->pcr.i_current;
1371
0
    const ts_stream_t *p_cand = NULL;
1372
0
    for( int i=0; i< p_pmt->e_streams.i_size; i++ )
1373
0
    {
1374
0
        const ts_pid_t *p_pid = p_pmt->e_streams.p_elems[i];
1375
0
        if( (p_pid->i_flags & FLAG_FILTERED) && SEEN(p_pid) &&
1376
0
             p_pid->type == TYPE_STREAM &&
1377
0
             p_pid->u.p_stream->p_es &&
1378
0
             p_pid->u.p_stream->i_last_dts != VLC_TICK_INVALID )
1379
0
        {
1380
0
            const ts_es_t *p_es = p_pid->u.p_stream->p_es;
1381
0
            if( p_es->fmt.i_cat == VIDEO_ES || p_es->fmt.i_cat == AUDIO_ES )
1382
0
            {
1383
0
                if( !p_cand || (p_es->fmt.i_cat == VIDEO_ES &&
1384
0
                                p_cand->p_es->fmt.i_cat != VIDEO_ES) )
1385
0
                {
1386
0
                    p_cand = p_pid->u.p_stream;
1387
0
                    i_ts = p_cand->i_last_dts;
1388
0
                }
1389
0
            }
1390
0
        }
1391
0
    }
1392
0
    return i_ts;
1393
0
}
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
73.8k
{
1399
73.8k
    if(!p_block)
1400
0
        return NULL;
1401
1402
73.8k
    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
73.8k
    else if( p_es->fmt.i_codec == VLC_CODEC_TELETEXT )
1414
0
    {
1415
0
        const ts_pmt_t *p_pmt = p_es->p_program;
1416
0
        if( p_block->i_pts != VLC_TICK_INVALID &&
1417
0
            p_pmt->pcr.i_current != VLC_TICK_INVALID )
1418
0
        {
1419
            /* Teletext can have totally offset timestamps... RAI1, German */
1420
0
            if( p_pmt->pcr.i_current < p_block->i_pts || p_pmt->pcr.i_current - p_block->i_pts > CLOCK_FREQ )
1421
0
                p_block->i_dts = p_block->i_pts = VLC_TICK_INVALID;
1422
0
        }
1423
0
        if( p_block->i_pts == VLC_TICK_INVALID )
1424
0
        {
1425
            /* Teletext may have missing PTS (ETSI EN 300 472 Annexe A)
1426
             * In this case use the last PCR + 40ms */
1427
0
            vlc_tick_t i_ts = GetTimeForUntimed( p_es->p_program );
1428
0
            if( i_ts != VLC_TICK_INVALID )
1429
0
                p_block->i_dts = p_block->i_pts = i_ts + VLC_TICK_FROM_MS(40);
1430
0
        }
1431
0
    }
1432
73.8k
    else if( p_es->fmt.i_codec == VLC_CODEC_ARIB_A ||
1433
73.8k
             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
73.8k
    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
73.8k
    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
73.8k
    return p_block;
1465
73.8k
}
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
703k
{
1472
703k
    demux_sys_t *p_sys = p_demux->p_sys;
1473
1474
1.38M
    while( p_chain )
1475
677k
    {
1476
677k
        block_t *p_block = p_chain;
1477
677k
        p_chain = p_block->p_next;
1478
677k
        p_block->p_next = NULL;
1479
1480
        /* clean up any private flag */
1481
677k
        p_block->i_flags &= ~BLOCK_FLAG_PRIVATE_MASK;
1482
1483
677k
        if( p_sys->b_lowdelay )
1484
0
            p_block->i_flags |= BLOCK_FLAG_AU_END;
1485
1486
677k
        ts_es_t *p_es_send = p_es;
1487
677k
        if( p_es_send->i_next_block_flags )
1488
132
        {
1489
132
            p_block->i_flags |= p_es_send->i_next_block_flags;
1490
132
            p_es_send->i_next_block_flags = 0;
1491
132
        }
1492
1493
1.35M
        while( p_es_send )
1494
677k
        {
1495
677k
            if( p_es_send->p_program->b_selected )
1496
677k
            {
1497
                /* Send a copy to each extra es */
1498
677k
                ts_es_t *p_extra_es = p_es_send->p_extraes;
1499
677k
                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
677k
                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
677k
                else
1520
677k
                {
1521
677k
                    if( p_es_send->id )
1522
677k
                    {
1523
677k
                        es_out_Send( p_demux->out, p_es_send->id, p_block );
1524
677k
                        p_block = NULL;
1525
677k
                    }
1526
677k
                }
1527
677k
            }
1528
677k
            p_es_send = p_es_send->p_next;
1529
677k
        }
1530
1531
677k
        if( p_block )
1532
0
            block_Release( p_block );
1533
677k
    }
1534
703k
}
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
782k
{
1542
782k
    uint8_t header[34];
1543
782k
    unsigned i_pes_size = 0;
1544
782k
    unsigned i_skip = 0;
1545
782k
    ts_90khz_t i_length = 0;
1546
782k
    vlc_tick_t i_dts = VLC_TICK_INVALID;
1547
782k
    vlc_tick_t i_pts = VLC_TICK_INVALID;
1548
782k
    const es_mpeg4_descriptor_t *p_mpeg4desc = NULL;
1549
782k
    demux_sys_t *p_sys = p_demux->p_sys;
1550
1551
782k
    assert(pid->type == TYPE_STREAM);
1552
1553
782k
    const int i_max = block_ChainExtract( p_pes, header, 34 );
1554
782k
    if ( i_max < 4 )
1555
587
    {
1556
587
        block_ChainRelease( p_pes );
1557
587
        return;
1558
587
    }
1559
1560
781k
    if( header[0] != 0 || header[1] != 0 || header[2] != 1 )
1561
11.2k
    {
1562
11.2k
        if ( !(p_pes->i_flags & BLOCK_FLAG_SCRAMBLED) )
1563
11.2k
            msg_Warn( p_demux, "invalid header [0x%02x:%02x:%02x:%02x] (pid: %d)",
1564
11.2k
                        header[0], header[1],header[2],header[3], pid->i_pid );
1565
11.2k
        block_ChainRelease( p_pes );
1566
11.2k
        return;
1567
11.2k
    }
1568
770k
    else
1569
770k
    {
1570
        /* Incorrect transport scrambling flag set by german boxes */
1571
770k
        p_pes->i_flags &= ~BLOCK_FLAG_SCRAMBLED;
1572
770k
    }
1573
1574
770k
    ts_es_t *p_es = pid->u.p_stream->p_es;
1575
1576
770k
    ts_pes_header_t pesh;
1577
770k
    ts_pes_header_init( &pesh );
1578
1579
770k
    if( ParsePESHeader( p_demux->obj.logger, (uint8_t*)&header, i_max, &pesh ) == VLC_EGENERIC )
1580
9.98k
    {
1581
9.98k
        block_ChainRelease( p_pes );
1582
9.98k
        return;
1583
9.98k
    }
1584
760k
    else
1585
760k
    {
1586
760k
        if( pesh.i_pts != TS_90KHZ_INVALID && p_es->p_program )
1587
78.2k
            i_pts = TimeStampWrapAround( p_es->p_program->pcr.i_first, FROM_SCALE(pesh.i_pts) );
1588
760k
        if( pesh.i_dts != TS_90KHZ_INVALID && p_es->p_program )
1589
23.1k
            i_dts = TimeStampWrapAround( p_es->p_program->pcr.i_first, FROM_SCALE(pesh.i_dts) );
1590
760k
        if( pesh.b_scrambling )
1591
3.47k
            p_pes->i_flags |= BLOCK_FLAG_SCRAMBLED;
1592
760k
        i_skip = pesh.i_size;
1593
760k
    }
1594
1595
760k
    if( p_es->i_sl_es_id )
1596
684k
        p_mpeg4desc = GetMPEG4DescByEsId( p_es->p_program, p_es->i_sl_es_id );
1597
1598
760k
    if( p_es->fmt.i_codec == VLC_FOURCC( 'a', '5', '2', 'b' ) ||
1599
760k
        p_es->fmt.i_codec == VLC_FOURCC( 'd', 't', 's', 'b' ) )
1600
0
    {
1601
0
        i_skip += 4;
1602
0
    }
1603
760k
    else if( p_es->fmt.i_codec == VLC_FOURCC( 'l', 'p', 'c', 'b' ) ||
1604
760k
             p_es->fmt.i_codec == VLC_FOURCC( 's', 'p', 'u', 'b' ) ||
1605
760k
             p_es->fmt.i_codec == VLC_FOURCC( 's', 'd', 'd', 'b' ) )
1606
0
    {
1607
0
        i_skip += 1;
1608
0
    }
1609
760k
    else if( p_es->fmt.i_codec == VLC_CODEC_SUBT && p_mpeg4desc )
1610
11.9k
    {
1611
11.9k
        const decoder_config_descriptor_t *dcd = &p_mpeg4desc->dec_descr;
1612
1613
11.9k
        if( dcd->i_extra > 2 &&
1614
7.91k
            dcd->p_extra[0] == 0x10 &&
1615
431
            ( dcd->p_extra[1]&0x10 ) )
1616
200
        {
1617
            /* display length */
1618
200
            if( p_pes->i_buffer + 2 <= i_skip )
1619
0
                i_length = GetWBE( &p_pes->p_buffer[i_skip] );
1620
1621
200
            i_skip += 2;
1622
200
        }
1623
11.9k
        if( p_pes->i_buffer + 2 <= i_skip )
1624
35
            i_pes_size = GetWBE( &p_pes->p_buffer[i_skip] );
1625
        /* */
1626
11.9k
        i_skip += 2;
1627
11.9k
    }
1628
1629
    /* skip header */
1630
765k
    while( p_pes && i_skip > 0 )
1631
761k
    {
1632
761k
        if( p_pes->i_buffer <= i_skip )
1633
5.04k
        {
1634
5.04k
            block_t *p_next = p_pes->p_next;
1635
1636
5.04k
            i_skip -= p_pes->i_buffer;
1637
5.04k
            block_Release( p_pes );
1638
5.04k
            p_pes = p_next;
1639
5.04k
        }
1640
756k
        else
1641
756k
        {
1642
756k
            p_pes->i_buffer -= i_skip;
1643
756k
            p_pes->p_buffer += i_skip;
1644
756k
            break;
1645
756k
        }
1646
761k
    }
1647
1648
    /* ISO/IEC 13818-1 2.7.5: if no pts and no dts, then dts == pts */
1649
760k
    if( i_pts != VLC_TICK_INVALID && i_dts == VLC_TICK_INVALID )
1650
71.5k
        i_dts = i_pts;
1651
1652
760k
    if( i_dts != VLC_TICK_INVALID )
1653
94.6k
        pid->u.p_stream->i_last_dts = i_dts;
1654
1655
760k
    if( p_pes )
1656
756k
    {
1657
756k
        ts_pmt_t *p_pmt = p_es->p_program;
1658
756k
        if( unlikely(!p_pmt) )
1659
0
        {
1660
0
            block_ChainRelease( p_pes );
1661
0
            return;
1662
0
        }
1663
1664
756k
        if( i_dts != VLC_TICK_INVALID )
1665
94.0k
            p_pes->i_dts = i_dts;
1666
1667
756k
        if( i_pts != VLC_TICK_INVALID )
1668
78.2k
            p_pes->i_pts = i_pts;
1669
1670
756k
        p_pes->i_length = FROM_SCALE_NZ(i_length);
1671
1672
        /* Can become a chain on next call due to prepcr */
1673
756k
        block_t *p_chain = block_ChainGather( p_pes );
1674
1.55M
        while ( p_chain ) {
1675
795k
            block_t *p_block = p_chain;
1676
795k
            p_chain = p_chain->p_next;
1677
795k
            p_block->p_next = NULL;
1678
1679
795k
            if( i_flags )
1680
264k
            {
1681
264k
                p_block->i_flags |= i_flags;
1682
264k
                i_flags = 0;
1683
264k
            }
1684
1685
795k
            if( !p_pmt->pcr.b_fix_done ) /* Not seen yet */
1686
292k
                PCRFixHandle( p_demux, p_pmt, p_block );
1687
1688
795k
            if( p_es->id && (p_pmt->pcr.i_current != VLC_TICK_INVALID || p_pmt->pcr.b_disable) )
1689
707k
            {
1690
707k
                if( pid->u.p_stream->prepcr.p_head )
1691
3.05k
                {
1692
                    /* Rebuild current output chain, appending any prepcr outqueue */
1693
3.05k
                    block_ChainLastAppend( &pid->u.p_stream->prepcr.pp_last, p_block );
1694
3.05k
                    if( p_chain )
1695
0
                        block_ChainLastAppend( &pid->u.p_stream->prepcr.pp_last, p_chain );
1696
3.05k
                    p_chain = pid->u.p_stream->prepcr.p_head;
1697
3.05k
                    pid->u.p_stream->prepcr.p_head = NULL;
1698
3.05k
                    pid->u.p_stream->prepcr.pp_last = &pid->u.p_stream->prepcr.p_head;
1699
                    /* Then now output all data */
1700
3.05k
                    continue;
1701
3.05k
                }
1702
1703
703k
                if ( p_pmt->pcr.b_disable && p_block->i_dts != VLC_TICK_INVALID &&
1704
10.3k
                     ( p_pmt->i_pid_pcr == pid->i_pid || p_pmt->i_pid_pcr == 0x1FFF ) )
1705
9.00k
                {
1706
9.00k
                    vlc_tick_t i_pcr = p_block->i_dts;
1707
9.00k
                    if( i_pcr > VLC_TICK_0 + p_sys->i_generated_pcr_dpb_offset )
1708
8.83k
                        i_pcr -= p_sys->i_generated_pcr_dpb_offset;
1709
9.00k
                    ProgramSetPCR( p_demux, p_pmt, i_pcr );
1710
9.00k
                }
1711
1712
                /* Compute PCR/DTS offset if any */
1713
703k
                vlc_tick_t i_pcrref = (i_append_pcr != TS_90KHZ_INVALID) ? FROM_SCALE(i_append_pcr) : p_pmt->pcr.i_first;
1714
703k
                if( p_pmt->pcr.i_pcroffset == -1 && p_block->i_dts != VLC_TICK_INVALID &&
1715
4.79k
                    i_pcrref != VLC_TICK_INVALID &&
1716
3.67k
                    (p_es->fmt.i_cat == VIDEO_ES || p_es->fmt.i_cat == AUDIO_ES) )
1717
3.03k
                {
1718
3.03k
                    if( p_block->i_dts + FROM_SCALE_NZ(1) < i_pcrref )
1719
868
                    {
1720
868
                        p_pmt->pcr.i_pcroffset = i_pcrref - p_block->i_dts + VLC_TICK_FROM_MS(80);
1721
868
                        msg_Warn( p_demux, "Broken stream: pid %d sends packets with dts %"PRId64
1722
868
                                           "us later than pcr, applying delay",
1723
868
                                  pid->i_pid, i_pcrref - p_block->i_dts );
1724
868
                    }
1725
2.16k
                    else p_pmt->pcr.i_pcroffset = 0;
1726
3.03k
                }
1727
1728
703k
                if( p_pmt->pcr.i_pcroffset != -1 )
1729
559k
                {
1730
559k
                    if( p_block->i_dts != VLC_TICK_INVALID )
1731
87.4k
                        p_block->i_dts += p_pmt->pcr.i_pcroffset;
1732
559k
                    if( p_block->i_pts != VLC_TICK_INVALID )
1733
83.1k
                        p_block->i_pts += p_pmt->pcr.i_pcroffset;
1734
559k
                }
1735
1736
                /*** From here, block can become a chain again though conversion below ***/
1737
1738
703k
                if( pid->u.p_stream->p_proc )
1739
630k
                {
1740
630k
                    if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
1741
0
                        ts_stream_processor_Reset( pid->u.p_stream->p_proc );
1742
630k
                    p_block = ts_stream_processor_Push( pid->u.p_stream->p_proc, pesh.i_stream_id, p_block );
1743
630k
                }
1744
73.8k
                else
1745
                /* Some codecs might need xform or AU splitting */
1746
73.8k
                {
1747
73.8k
                    p_block = ConvertPESBlock( p_demux, p_es, i_pes_size, pesh.i_stream_id, p_block );
1748
73.8k
                }
1749
1750
703k
                SendDataChain( p_demux, p_es, p_block );
1751
703k
            }
1752
88.1k
            else
1753
88.1k
            {
1754
88.1k
                if( !p_pmt->pcr.b_fix_done ) /* Not seen yet */
1755
44.7k
                    PCRFixHandle( p_demux, p_pmt, p_block );
1756
1757
88.1k
                if( pid->u.p_stream->p_proc )
1758
77.7k
                {
1759
77.7k
                    if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
1760
0
                        ts_stream_processor_Reset( pid->u.p_stream->p_proc );
1761
77.7k
                    p_block = ts_stream_processor_Push( pid->u.p_stream->p_proc, pesh.i_stream_id, p_block );
1762
77.7k
                }
1763
1764
88.1k
                if( p_block )
1765
40.8k
                    block_ChainLastAppend( &pid->u.p_stream->prepcr.pp_last, p_block );
1766
1767
                /* PCR Seen and no es->id, cleanup current and prepcr blocks */
1768
88.1k
                if( p_pmt->pcr.i_current != VLC_TICK_INVALID )
1769
32.8k
                {
1770
32.8k
                    block_ChainRelease( pid->u.p_stream->prepcr.p_head );
1771
32.8k
                    pid->u.p_stream->prepcr.p_head = NULL;
1772
32.8k
                    pid->u.p_stream->prepcr.pp_last = &pid->u.p_stream->prepcr.p_head;
1773
32.8k
                }
1774
88.1k
            }
1775
795k
        }
1776
756k
    }
1777
4.31k
    else
1778
4.31k
    {
1779
4.31k
        msg_Warn( p_demux, "empty pes" );
1780
4.31k
    }
1781
760k
}
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
782k
{
1786
782k
    ParsePESDataChain( (demux_t *)p_obj, (ts_pid_t *) priv, p_data, i_flags, i_appendpcr );
1787
782k
}
1788
1789
static bool CheckAndResync( demux_t *p_demux )
1790
5.19M
{
1791
5.19M
    demux_sys_t *p_sys = p_demux->p_sys;
1792
1793
5.19M
    const uint8_t *p_peek;
1794
5.19M
    if( vlc_stream_Peek( p_sys->stream, &p_peek, 1 + p_sys->i_packet_header_size )
1795
5.19M
            != 1 + p_sys->i_packet_header_size )
1796
2.09k
        return true;
1797
1798
    /* Check sync byte and re-sync if needed */
1799
5.18M
    if( p_peek[p_sys->i_packet_header_size] == 0x47 )
1800
3.39M
        return true;
1801
1802
1.79M
    msg_Warn( p_demux, "lost synchro at %" PRIu64, vlc_stream_Tell( p_sys->stream ) );
1803
1804
1.79M
    for( ;; )
1805
1.85M
    {
1806
1.85M
        ssize_t i_peek = 0;
1807
1.85M
        unsigned i_skip = 0;
1808
1809
1.85M
        i_peek = vlc_stream_Peek( p_sys->stream, &p_peek,
1810
1.85M
                                  p_sys->i_packet_size * 10 );
1811
1.85M
        if( i_peek < 0 || (size_t)i_peek < p_sys->i_packet_size + 1 )
1812
8.79k
        {
1813
8.79k
            msg_Dbg( p_demux, "eof ?" );
1814
8.79k
            return false;
1815
8.79k
        }
1816
1817
581M
        while( i_skip < i_peek - p_sys->i_packet_size )
1818
581M
        {
1819
581M
            if( p_peek[i_skip + p_sys->i_packet_header_size] == 0x47 &&
1820
5.99M
                p_peek[i_skip + p_sys->i_packet_header_size + p_sys->i_packet_size] == 0x47 )
1821
1.78M
                break;
1822
580M
            i_skip++;
1823
580M
        }
1824
1.84M
        msg_Dbg( p_demux, "skipping %d bytes of garbage at %"PRIu64,
1825
1.84M
                 i_skip, vlc_stream_Tell( p_sys->stream ) );
1826
1.84M
        if (vlc_stream_Read( p_sys->stream, NULL, i_skip ) != i_skip)
1827
0
            return false;
1828
1829
1.84M
        if( i_skip < i_peek - p_sys->i_packet_size )
1830
1.78M
            break;
1831
1.84M
    }
1832
1.78M
    msg_Dbg( p_demux, "resynced at %" PRIu64, vlc_stream_Tell( p_sys->stream ) );
1833
1834
1.78M
    return true;
1835
1.79M
}
1836
1837
static block_t* ReadTSPacket( demux_t *p_demux )
1838
5.19M
{
1839
5.19M
    demux_sys_t *p_sys = p_demux->p_sys;
1840
1841
5.19M
    if( !CheckAndResync( p_demux) )
1842
8.79k
        return NULL;
1843
1844
5.18M
    block_t     *p_pkt;
1845
1846
    /* Get a new TS packet */
1847
5.18M
    if( !( p_pkt = vlc_stream_Block( p_sys->stream, p_sys->i_packet_size ) ) )
1848
2.09k
    {
1849
2.09k
        uint64_t size;
1850
2.09k
        if( vlc_stream_GetSize( p_sys->stream, &size ) == VLC_SUCCESS &&
1851
2.09k
            size == vlc_stream_Tell( p_sys->stream ) )
1852
2.09k
            msg_Dbg( p_demux, "EOF at %"PRIu64, size );
1853
0
        else
1854
2.09k
            msg_Dbg( p_demux, "Can't read TS packet at %"PRIu64, vlc_stream_Tell(p_sys->stream) );
1855
2.09k
        return NULL;
1856
2.09k
    }
1857
1858
5.18M
    if( p_pkt->i_buffer < TS_HEADER_SIZE + p_sys->i_packet_header_size )
1859
32
    {
1860
32
        block_Release( p_pkt );
1861
32
        return NULL;
1862
32
    }
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.18M
    p_pkt->p_buffer += p_sys->i_packet_header_size;
1869
5.18M
    p_pkt->i_buffer -= p_sys->i_packet_header_size;
1870
1871
5.18M
    return p_pkt;
1872
5.18M
}
1873
1874
static inline void UpdateESScrambledState( es_out_t *out, const ts_es_t *p_es, bool b_scrambled )
1875
29.6k
{
1876
44.4k
    for( ; p_es; p_es = p_es->p_next )
1877
14.8k
    {
1878
14.8k
        if( p_es->id )
1879
10.1k
            es_out_Control( out, ES_OUT_SET_ES_SCRAMBLED_STATE,
1880
10.1k
                            p_es->id, b_scrambled );
1881
14.8k
        UpdateESScrambledState( out, p_es->p_extraes, b_scrambled );
1882
14.8k
    }
1883
29.6k
}
1884
1885
static void UpdatePIDScrambledState( demux_t *p_demux, ts_pid_t *p_pid, bool b_scrambled )
1886
51.4k
{
1887
51.4k
    if( !SCRAMBLED(*p_pid) == !b_scrambled )
1888
0
        return;
1889
1890
    /* avoid flapping descrambled state on partial scrambling */
1891
51.4k
    if( b_scrambled )
1892
12.5k
    {
1893
12.5k
        p_pid->i_scramble_counter = 4;
1894
12.5k
    }
1895
38.8k
    else if( p_pid->i_scramble_counter != 0 )
1896
31.6k
    {
1897
31.6k
        p_pid->i_scramble_counter--;
1898
31.6k
        return;
1899
31.6k
    }
1900
1901
19.7k
    msg_Warn( p_demux, "scrambled state changed on pid %d (%d->%d)",
1902
19.7k
              p_pid->i_pid, !!SCRAMBLED(*p_pid), b_scrambled );
1903
1904
19.7k
    if( b_scrambled )
1905
12.5k
        p_pid->i_flags |= FLAG_SCRAMBLED;
1906
7.19k
    else
1907
7.19k
        p_pid->i_flags &= ~FLAG_SCRAMBLED;
1908
1909
19.7k
    if( p_pid->type == TYPE_STREAM )
1910
14.8k
        UpdateESScrambledState( p_demux->out, p_pid->u.p_stream->p_es, b_scrambled );
1911
19.7k
}
1912
1913
static inline void FlushESBuffer( ts_stream_t *p_pes )
1914
694
{
1915
694
    if( p_pes->gather.p_data )
1916
10
    {
1917
10
        p_pes->gather.i_gathered = p_pes->gather.i_data_size = 0;
1918
10
        block_ChainRelease( p_pes->gather.p_data );
1919
10
        p_pes->gather.p_data = NULL;
1920
10
        p_pes->gather.pp_last = &p_pes->gather.p_data;
1921
10
        p_pes->gather.i_saved = 0;
1922
10
        p_pes->gather.i_block_flags = 0;
1923
10
    }
1924
694
    if( p_pes->p_proc )
1925
106
        ts_stream_processor_Reset( p_pes->p_proc );
1926
694
}
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
8.78k
{
2072
8.78k
    demux_sys_t *p_sys = p_demux->p_sys;
2073
8.78k
    int i_count = 0;
2074
8.78k
    block_t *p_pkt = NULL;
2075
2076
8.78k
    for( ;; )
2077
2.69M
    {
2078
2.69M
        ts_90khz_t i_pcr = TS_90KHZ_INVALID;
2079
2080
2.69M
        if( i_count++ > PROBE_CHUNK_COUNT || !( p_pkt = ReadTSPacket( p_demux ) ) )
2081
8.78k
        {
2082
8.78k
            break;
2083
8.78k
        }
2084
2085
2.68M
        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
2.68M
        const int i_pid = PIDGet( p_pkt );
2093
2.68M
        ts_pid_t *p_pid = GetPID(p_sys, i_pid);
2094
2095
2.68M
        p_pid->i_flags |= FLAG_SEEN;
2096
2097
2.68M
        if( i_pid != 0x1FFF && (p_pkt->p_buffer[1] & 0x80) == 0 ) /* not corrupt */
2098
2.46M
        {
2099
2.46M
            bool b_pcrresult = true;
2100
2.46M
            i_pcr = GetPCR( p_pkt );
2101
2102
            /* Designated PCR pid will be valid, don't repick (on the fly probing) */
2103
2.46M
            if( i_pcr != TS_90KHZ_INVALID && !p_pid->probed.i_pcr_count )
2104
4.18k
                p_pid->probed.i_pcr_count++;
2105
2106
2.46M
            if( i_pcr == TS_90KHZ_INVALID &&
2107
2.28M
                (p_pkt->p_buffer[1] & 0xC0) == 0x40 && /* payload start */
2108
1.41M
                (p_pkt->p_buffer[3] & 0xD0) == 0x10 && /* Has payload but is not encrypted */
2109
1.37M
                p_pid->type == TYPE_STREAM &&
2110
981k
                p_pid->u.p_stream->p_es->fmt.i_cat != UNKNOWN_ES
2111
2.46M
              )
2112
83.4k
            {
2113
83.4k
                b_pcrresult = false;
2114
83.4k
                unsigned i_skip = PKTHeaderAndAFSize( p_pkt );
2115
83.4k
                if (p_pkt->i_buffer > i_skip)
2116
83.4k
                {
2117
83.4k
                ts_pes_header_t pesh;
2118
83.4k
                ts_pes_header_init( &pesh );
2119
83.4k
                if ( VLC_SUCCESS == ParsePESHeader( NULL, &p_pkt->p_buffer[i_skip],
2120
83.4k
                                                    p_pkt->i_buffer - i_skip, &pesh ) )
2121
78.7k
                {
2122
78.7k
                    if( pesh.i_dts != TS_90KHZ_INVALID )
2123
4.58k
                        i_pcr = pesh.i_dts;
2124
74.1k
                    else if( pesh.i_pts != TS_90KHZ_INVALID )
2125
25.2k
                        i_pcr = pesh.i_pts;
2126
78.7k
                }
2127
83.4k
                }
2128
83.4k
            }
2129
2130
2.46M
            if( i_pcr != TS_90KHZ_INVALID )
2131
209k
            {
2132
209k
                ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2133
490k
                for( int i=0; i<p_pat->programs.i_size; i++ )
2134
281k
                {
2135
281k
                    ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
2136
281k
                    if( p_pmt->i_pid_pcr == p_pid->i_pid ||
2137
109k
                          ( p_pmt->i_pid_pcr == 0x1FFF &&
2138
70.5k
                            PIDReferencedByProgram( p_pmt, p_pid->i_pid ) )
2139
281k
                      )
2140
171k
                    {
2141
171k
                        if( b_end )
2142
74.3k
                        {
2143
74.3k
                            p_pmt->i_last_dts = FROM_SCALE(i_pcr);
2144
74.3k
                            p_pmt->i_last_dts_byte = vlc_stream_Tell( p_sys->stream );
2145
74.3k
                        }
2146
                        /* Start, only keep first */
2147
97.5k
                        else if( b_pcrresult && p_pmt->pcr.i_first == VLC_TICK_INVALID )
2148
3.58k
                        {
2149
3.58k
                            p_pmt->pcr.i_first = FROM_SCALE(i_pcr);
2150
3.58k
                        }
2151
93.9k
                        else if( p_pmt->pcr.i_first_dts == VLC_TICK_INVALID )
2152
3.49k
                        {
2153
3.49k
                            p_pmt->pcr.i_first_dts = FROM_SCALE(i_pcr);
2154
3.49k
                        }
2155
2156
171k
                        if( i_program == 0 || i_program == p_pmt->i_number )
2157
171k
                            *pb_found = true;
2158
171k
                    }
2159
281k
                }
2160
209k
            }
2161
2.46M
        }
2162
2163
2.68M
        block_Release( p_pkt );
2164
2.68M
    }
2165
2166
8.78k
    return i_count;
2167
8.78k
}
2168
2169
int ProbeStart( demux_t *p_demux, int i_program )
2170
4.11k
{
2171
4.11k
    demux_sys_t *p_sys = p_demux->p_sys;
2172
4.11k
    const uint64_t i_initial_pos = vlc_stream_Tell( p_sys->stream );
2173
4.11k
    uint64_t i_stream_size;
2174
4.11k
    if( vlc_stream_GetSize( p_sys->stream, &i_stream_size ) != VLC_SUCCESS )
2175
0
      return VLC_EGENERIC;
2176
2177
4.11k
    if( i_stream_size < p_sys->i_packet_size )
2178
0
      return VLC_EGENERIC;
2179
2180
4.11k
    unsigned i_probe_count = 0;
2181
4.11k
    uint64_t i_pos;
2182
4.11k
    bool b_found = false;
2183
2184
4.11k
    do
2185
4.67k
    {
2186
4.67k
        i_pos = p_sys->i_packet_size * i_probe_count;
2187
4.67k
        if( i_pos > i_stream_size - p_sys->i_packet_size )
2188
0
          break;
2189
2190
4.67k
        if( vlc_stream_Seek( p_sys->stream, i_pos ) )
2191
0
            return VLC_EGENERIC;
2192
2193
4.67k
        int i_count =  ProbeChunk( p_demux, i_program, false, &b_found );
2194
4.67k
        if( i_count < PROBE_CHUNK_COUNT )
2195
2.73k
            break;
2196
2197
        /* Go ahead one more chunk if end of file contained only stuffing packets */
2198
1.94k
        i_probe_count += i_count;
2199
1.94k
    } while( i_pos < i_stream_size && !b_found &&
2200
568
             i_probe_count < PROBE_MAX );
2201
2202
4.11k
    if( vlc_stream_Seek( p_sys->stream, i_initial_pos ) )
2203
0
        return VLC_EGENERIC;
2204
2205
4.11k
    return (b_found) ? VLC_SUCCESS : VLC_EGENERIC;
2206
4.11k
}
2207
2208
int ProbeEnd( demux_t *p_demux, int i_program )
2209
4.11k
{
2210
4.11k
    demux_sys_t *p_sys = p_demux->p_sys;
2211
4.11k
    const uint64_t i_initial_pos = vlc_stream_Tell( p_sys->stream );
2212
4.11k
    uint64_t i_stream_size;
2213
4.11k
    if( vlc_stream_GetSize( p_sys->stream, &i_stream_size ) != VLC_SUCCESS )
2214
0
      return VLC_EGENERIC;
2215
2216
4.11k
    unsigned i_probe_count = PROBE_CHUNK_COUNT;
2217
4.11k
    uint64_t i_pos;
2218
4.11k
    bool b_found = false;
2219
4.11k
    const uint64_t i_sync_align_offset = i_initial_pos % p_sys->i_packet_size;
2220
2221
4.11k
    do
2222
4.11k
    {
2223
4.11k
        i_pos = p_sys->i_packet_size * i_probe_count;
2224
4.11k
        if( i_stream_size > i_pos )
2225
2.29k
          i_pos = i_stream_size - i_pos;
2226
1.81k
        else
2227
1.81k
          i_pos = 0;
2228
2229
        /* Avoid resyncing, as the starting point should be packet aligned */
2230
4.11k
        if( i_pos % p_sys->i_packet_size != i_sync_align_offset )
2231
4.10k
            i_pos = i_pos - (i_pos % p_sys->i_packet_size) + i_sync_align_offset;
2232
2233
4.11k
        if( vlc_stream_Seek( p_sys->stream, i_pos ) )
2234
0
            return VLC_EGENERIC;
2235
2236
4.11k
        int i_count = ProbeChunk( p_demux, i_program, true, &b_found );
2237
4.11k
        if( i_count < PROBE_CHUNK_COUNT )
2238
4.10k
            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
4.11k
    if( vlc_stream_Seek( p_sys->stream, i_initial_pos ) )
2246
0
        return VLC_EGENERIC;
2247
2248
4.11k
    return (b_found) ? VLC_SUCCESS : VLC_EGENERIC;
2249
4.11k
}
2250
2251
static void ProgramSetPCR( demux_t *p_demux, ts_pmt_t *p_pmt, vlc_tick_t i_pcr )
2252
139k
{
2253
139k
    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
139k
    if( p_pmt->pcr.i_current == VLC_TICK_INVALID && p_pmt->pcr.b_fix_done )
2258
1.20k
    {
2259
1.20k
        vlc_tick_t i_mindts = VLC_TICK_INVALID;
2260
2261
1.20k
        ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2262
3.30k
        for( int i=0; i< p_pat->programs.i_size; i++ )
2263
2.10k
        {
2264
2.10k
            ts_pmt_t *p_opmt = p_pat->programs.p_elems[i]->u.p_pmt;
2265
7.35k
            for( int j=0; j<p_opmt->e_streams.i_size; j++ )
2266
5.25k
            {
2267
5.25k
                ts_pid_t *p_pid = p_opmt->e_streams.p_elems[j];
2268
5.25k
                block_t *p_block = p_pid->u.p_stream->prepcr.p_head;
2269
9.22k
                while( p_block && p_block->i_dts == VLC_TICK_INVALID )
2270
3.97k
                    p_block = p_block->p_next;
2271
2272
5.25k
                if( p_block && ( i_mindts == VLC_TICK_INVALID || p_block->i_dts < i_mindts ) )
2273
816
                    i_mindts = p_block->i_dts;
2274
5.25k
            }
2275
2.10k
        }
2276
2277
1.20k
        if( i_mindts != VLC_TICK_INVALID )
2278
806
        {
2279
806
            if( i_pcr > p_pmt->pcr.i_first ) /* don't bork the natural pcr offset */
2280
111
            {
2281
111
                msg_Dbg( p_demux, "Program %d PCR prequeue fixup %"PRId64"->%"PRId64,
2282
111
                         p_pmt->i_number, TO_SCALE(i_mindts), i_pcr );
2283
111
                i_pcr = i_mindts;
2284
111
            }
2285
695
            else i_pcr = p_pmt->pcr.i_first;
2286
806
        }
2287
1.20k
    }
2288
2289
139k
    p_pmt->pcr.i_current = i_pcr;
2290
2291
139k
    if( p_pmt->pcr.i_first == VLC_TICK_INVALID )
2292
357
    {
2293
357
        p_pmt->pcr.i_first = i_pcr; // now seen
2294
357
    }
2295
2296
139k
    if ( p_sys->i_pmt_es )
2297
139k
    {
2298
139k
        es_out_Control( p_demux->out, ES_OUT_SET_GROUP_PCR, p_pmt->i_number, i_pcr );
2299
        /* growing files/named fifo handling */
2300
139k
        if( p_sys->b_access_control == false &&
2301
139k
            vlc_stream_Tell( p_sys->stream ) > p_pmt->i_last_dts_byte )
2302
1.13k
        {
2303
1.13k
            if( p_pmt->i_last_dts_byte == 0 ) /* first run */
2304
372
            {
2305
372
                if( vlc_stream_GetSize( p_sys->stream, &p_pmt->i_last_dts_byte ) != VLC_SUCCESS )
2306
372
                    msg_Dbg( p_demux, "Can't get stream size" );
2307
372
            }
2308
758
            else
2309
758
            {
2310
758
                p_pmt->i_last_dts = i_pcr;
2311
758
                p_pmt->i_last_dts_byte = vlc_stream_Tell( p_sys->stream );
2312
758
            }
2313
1.13k
        }
2314
139k
    }
2315
139k
}
2316
2317
static int IsVideoEnd( ts_pid_t *p_pid )
2318
134
{
2319
    /* jump to near end of PES packet */
2320
134
    block_t *p = p_pid->u.p_stream->gather.p_data;
2321
134
    if( !p || !p->p_next )
2322
34
        return 0;
2323
687
    while( p->p_next->p_next )
2324
587
        p = p->p_next;
2325
100
    if( p->p_next->i_buffer > 4)
2326
100
        p = p->p_next;
2327
2328
    /* extract last bytes */
2329
100
    uint8_t tail[ 188 ];
2330
100
    const int i_tail = block_ChainExtract( p, tail, sizeof( tail ) );
2331
100
    if( i_tail < 4 )
2332
0
        return 0;
2333
2334
    /* check for start code at end */
2335
100
    return ( tail[ i_tail - 4 ] == 0 && tail[ i_tail - 3 ] == 0 && tail[ i_tail - 2 ] == 1 &&
2336
1
             ( tail[ i_tail - 1 ] == 0xb7 ||  tail[ i_tail - 1 ] == 0x0a ) );
2337
100
}
2338
2339
static void PCRCheckDTS( demux_t *p_demux, ts_pmt_t *p_pmt, vlc_tick_t i_pcr)
2340
130k
{
2341
610k
    for( int i=0; i<p_pmt->e_streams.i_size; i++ )
2342
480k
    {
2343
480k
        ts_pid_t *p_pid = p_pmt->e_streams.p_elems[i];
2344
2345
480k
        if( p_pid->type != TYPE_STREAM || SCRAMBLED(*p_pid) )
2346
57.1k
            continue;
2347
2348
423k
        ts_stream_t *p_pes = p_pid->u.p_stream;
2349
423k
        ts_es_t *p_es = p_pes->p_es;
2350
2351
423k
        if( p_pes->gather.p_data == NULL )
2352
344k
            continue;
2353
79.4k
        if( p_pes->gather.i_data_size != 0 )
2354
75.1k
            continue;
2355
2356
        /* check only MPEG2, H.264 and VC-1 */
2357
4.30k
        if( p_es->fmt.i_codec != VLC_CODEC_MPGV &&
2358
4.30k
            p_es->fmt.i_codec != VLC_CODEC_H264 &&
2359
1.35k
            p_es->fmt.i_codec != VLC_CODEC_VC1 )
2360
1.35k
            continue;
2361
2362
2.95k
        uint8_t header[34];
2363
2.95k
        const int i_max = block_ChainExtract( p_pes->gather.p_data, header, 34 );
2364
2365
2.95k
        ts_pes_header_t pesh;
2366
2.95k
        ts_pes_header_init( &pesh );
2367
2368
2.95k
        if( ParsePESHeader( NULL, (uint8_t*)&header, i_max, &pesh ) == VLC_EGENERIC )
2369
1.97k
            continue;
2370
2371
972
        vlc_tick_t i_dts = VLC_TICK_INVALID;
2372
972
        vlc_tick_t i_pts = VLC_TICK_INVALID;
2373
2374
972
        if( pesh.i_dts != TS_90KHZ_INVALID )
2375
104
            i_dts = TimeStampWrapAround( i_pcr, FROM_SCALE(pesh.i_dts) );
2376
972
        if( pesh.i_pts != TS_90KHZ_INVALID )
2377
589
            i_pts = TimeStampWrapAround( i_pcr, FROM_SCALE(pesh.i_pts) );
2378
2379
972
        if (p_pmt->pcr.i_pcroffset > 0) {
2380
158
            if( i_dts != VLC_TICK_INVALID )
2381
41
                i_dts += p_pmt->pcr.i_pcroffset;
2382
158
            if( i_pts != VLC_TICK_INVALID )
2383
64
                i_pts += p_pmt->pcr.i_pcroffset;
2384
158
        }
2385
2386
972
        if(( i_dts != VLC_TICK_INVALID && i_dts <= i_pcr ) ||
2387
924
           ( i_pts != VLC_TICK_INVALID && i_pts <= i_pcr ))
2388
134
        {
2389
134
            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
134
        }
2399
972
    }
2400
130k
}
2401
2402
static void PCRHandle( demux_t *p_demux, ts_pid_t *pid, ts_90khz_t i_pcr )
2403
154k
{
2404
154k
    demux_sys_t   *p_sys = p_demux->p_sys;
2405
2406
154k
    pid->probed.i_pcr_count++;
2407
2408
154k
    if( p_sys->i_pmt_es <= 0 )
2409
9.97k
        return;
2410
2411
144k
    if(unlikely(GetPID(p_sys, 0)->type != TYPE_PAT))
2412
0
        return;
2413
2414
    /* Search program and set the PCR */
2415
144k
    ts_pat_t *p_pat = GetPID(p_sys, 0)->u.p_pat;
2416
298k
    for( int i = 0; i < p_pat->programs.i_size; i++ )
2417
154k
    {
2418
154k
        ts_pmt_t *p_pmt = p_pat->programs.p_elems[i]->u.p_pmt;
2419
154k
        if( p_pmt->pcr.b_disable )
2420
1.05k
            continue;
2421
2422
153k
        vlc_tick_t i_past_pcr = p_pmt->pcr.i_current;
2423
153k
        if( i_past_pcr == VLC_TICK_INVALID )
2424
15.9k
            i_past_pcr = p_pmt->pcr.i_first;
2425
2426
153k
        vlc_tick_t i_program_pcr = TimeStampWrapAround( i_past_pcr, FROM_SCALE(i_pcr) );
2427
2428
153k
        if( p_pmt->i_pid_pcr == 0x1FFF ) /* That program has no dedicated PCR pid ISO/IEC 13818-1 2.4.4.9 */
2429
9.74k
        {
2430
9.74k
            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
9.74k
        }
2436
143k
        else /* set PCR provided by current pid to program(s) referencing it */
2437
143k
        {
2438
            /* Can be dedicated PCR pid (no owned then) or another pid (owner == pmt) */
2439
143k
            if( p_pmt->i_pid_pcr == pid->i_pid ) /* If that program references current pid as PCR */
2440
130k
            {
2441
                /* We've found a target group for update */
2442
130k
                PCRCheckDTS( p_demux, p_pmt, FROM_SCALE(i_pcr) );
2443
130k
                ProgramSetPCR( p_demux, p_pmt, i_program_pcr );
2444
130k
            }
2445
143k
        }
2446
2447
153k
    }
2448
144k
}
2449
2450
int FindPCRCandidate( ts_pmt_t *p_pmt )
2451
332
{
2452
332
    ts_pid_t *p_cand = NULL;
2453
332
    int i_previous = p_pmt->i_pid_pcr;
2454
2455
2.23k
    for( int i=0; i<p_pmt->e_streams.i_size; i++ )
2456
1.90k
    {
2457
1.90k
        ts_pid_t *p_pid = p_pmt->e_streams.p_elems[i];
2458
1.90k
        if( SEEN(p_pid) && p_pid->i_pid != i_previous )
2459
451
        {
2460
451
            if( p_pid->probed.i_pcr_count ) /* check PCR frequency first */
2461
22
            {
2462
22
                if( !p_cand || p_pid->probed.i_pcr_count > p_cand->probed.i_pcr_count )
2463
18
                {
2464
18
                    p_cand = p_pid;
2465
18
                    continue;
2466
18
                }
2467
22
            }
2468
2469
433
            if( p_pid->u.p_stream->p_es->fmt.i_cat == AUDIO_ES )
2470
234
            {
2471
234
                if( !p_cand )
2472
223
                    p_cand = p_pid;
2473
234
            }
2474
199
            else if ( p_pid->u.p_stream->p_es->fmt.i_cat == VIDEO_ES ) /* Otherwise prioritize video dts */
2475
41
            {
2476
41
                if( !p_cand || p_cand->u.p_stream->p_es->fmt.i_cat == AUDIO_ES )
2477
41
                    p_cand = p_pid;
2478
41
            }
2479
433
        }
2480
1.90k
    }
2481
2482
332
    if( p_cand )
2483
273
        return p_cand->i_pid;
2484
59
    else
2485
59
        return 0x1FFF;
2486
332
}
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
336k
{
2491
336k
    demux_sys_t *p_sys = p_demux->p_sys;
2492
2493
    /* disable PCR offset check */
2494
336k
    if( !p_sys->b_check_pcr_offset && p_pmt->pcr.i_pcroffset == -1 )
2495
0
        p_pmt->pcr.i_pcroffset = 0;
2496
2497
336k
    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
336k
    else if( p_pmt->pcr.i_first_dts == VLC_TICK_INVALID )
2503
17.4k
    {
2504
17.4k
        p_pmt->pcr.i_first_dts = p_block->i_dts;
2505
17.4k
    }
2506
319k
    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
2.42k
    {
2508
2.42k
        if( p_pmt->pcr.i_current == VLC_TICK_INVALID &&
2509
1.23k
            GetPID( p_sys, p_pmt->i_pid_pcr )->probed.i_pcr_count == 0 )
2510
332
        {
2511
332
            int i_cand = FindPCRCandidate( p_pmt );
2512
332
            p_pmt->i_pid_pcr = i_cand;
2513
332
            if ( GetPID( p_sys, p_pmt->i_pid_pcr )->probed.i_pcr_count == 0 ) /* does not have PCR field */
2514
320
                p_pmt->pcr.b_disable = true;
2515
332
            msg_Warn( p_demux, "No PCR received for program %d, set up workaround using pid %d",
2516
332
                      p_pmt->i_number, i_cand );
2517
332
            UpdatePESFilters( p_demux, p_sys->seltype == PROGRAM_ALL );
2518
332
        }
2519
2.42k
        p_pmt->pcr.b_fix_done = true;
2520
2.42k
    }
2521
336k
}
2522
2523
static block_t * ProcessTSPacket( demux_t *p_demux, ts_pid_t *pid, block_t *p_pkt, int *pi_skip )
2524
2.45M
{
2525
2.45M
    demux_sys_t *p_sys = p_demux->p_sys;
2526
2.45M
    const uint8_t *p = p_pkt->p_buffer;
2527
2.45M
    const bool b_adaptation = p[3]&0x20;
2528
2.45M
    const bool b_payload    = p[3]&0x10;
2529
2.45M
    const bool b_scrambled  = p[3]&0xc0;
2530
2.45M
    const int  i_cc         = p[3]&0x0f; /* continuity counter */
2531
2.45M
    bool       b_discontinuity = false;  /* discontinuity */
2532
2533
    /* transport_scrambling_control is ignored */
2534
2.45M
    *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.45M
    if( unlikely(pid->i_pid == 0x1FFF) )
2544
183k
    {
2545
183k
        block_Release( p_pkt );
2546
183k
        return NULL;
2547
183k
    }
2548
2549
    /* For now, ignore additional error correction
2550
     * TODO: handle Reed-Solomon 204,188 error correction */
2551
2.27M
    p_pkt->i_buffer = TS_PACKET_SIZE_188;
2552
2553
2.27M
    if( b_scrambled )
2554
99.9k
    {
2555
99.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
99.9k
        else
2562
99.9k
            p_pkt->i_flags |= BLOCK_FLAG_SCRAMBLED;
2563
99.9k
    }
2564
2565
    /* We don't have any adaptation_field, so payload starts
2566
     * immediately after the 4 byte TS header */
2567
2.27M
    if( b_adaptation )
2568
1.01M
    {
2569
        /* p[4] is adaptation_field_length minus one */
2570
1.01M
        *pi_skip += 1 + p[4];
2571
1.01M
        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.00M
        else if( p[4] > 0 )
2578
999k
        {
2579
            /* discontinuity indicator found in stream */
2580
999k
            b_discontinuity = (p[5]&0x80) ? true : false;
2581
999k
            if( b_discontinuity )
2582
115k
            {
2583
115k
                msg_Warn( p_demux, "discontinuity indicator (pid=%d) ",
2584
115k
                            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
115k
                if(p[5] == 0x82 && !strncmp((const char *)&p[7], "VLC_DISCONTINU", 14))
2590
1.46k
                    p_pkt->i_flags |= BLOCK_FLAG_PRIVATE_SOURCE_RANDOM_ACCESS;
2591
115k
            }
2592
#if 0
2593
            if( p[5]&0x40 )
2594
                msg_Dbg( p_demux, "random access indicator (pid=%d) ", pid->i_pid );
2595
#endif
2596
999k
        }
2597
1.01M
    }
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.25M
    if( b_payload && p_sys->b_cc_check )
2607
2.19M
    {
2608
2.19M
        const int i_diff = ( i_cc - pid->i_cc )&0x0f;
2609
2.19M
        if( i_diff == 1 )
2610
862k
        {
2611
862k
            pid->i_cc = ( pid->i_cc + 1 ) & 0xf;
2612
862k
            pid->i_dup = 0;
2613
862k
        }
2614
1.33M
        else
2615
1.33M
        {
2616
1.33M
            if( pid->i_cc == 0xff )
2617
65.2k
            {
2618
65.2k
                msg_Dbg( p_demux, "first packet for pid=%d cc=0x%x",
2619
65.2k
                         pid->i_pid, i_cc );
2620
65.2k
                pid->i_cc = i_cc;
2621
65.2k
            }
2622
1.27M
            else if( i_diff == 0 && pid->i_dup == 0 &&
2623
164k
                     !memcmp(pid->prevpktbytes, /* see comment below */
2624
164k
                             &p_pkt->p_buffer[1], PREVPKTKEEPBYTES)  )
2625
85.1k
            {
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
85.1k
                pid->i_dup++;
2633
85.1k
                block_Release( p_pkt );
2634
85.1k
                return NULL;
2635
85.1k
            }
2636
1.18M
            else if( i_diff != 0 && !b_discontinuity )
2637
634k
            {
2638
634k
                msg_Warn( p_demux, "discontinuity received 0x%x instead of 0x%x (pid=%d)",
2639
634k
                          i_cc, ( pid->i_cc + 1 )&0x0f, pid->i_pid );
2640
2641
634k
                pid->i_cc = i_cc;
2642
634k
                pid->i_dup = 0;
2643
634k
                p_pkt->i_flags |= BLOCK_FLAG_PRIVATE_PACKET_LOSS;
2644
634k
            }
2645
552k
            else pid->i_cc = i_cc;
2646
1.33M
        }
2647
2.11M
        memcpy(pid->prevpktbytes, &p_pkt->p_buffer[1], PREVPKTKEEPBYTES);
2648
2.11M
    }
2649
59.8k
    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
59.8k
    {
2654
59.8k
        if( b_discontinuity )
2655
2.53k
            pid->i_cc = i_cc;
2656
59.8k
    }
2657
2658
2.17M
    if( unlikely(!(b_payload || b_adaptation)) ) /* Invalid, ignore */
2659
52.6k
    {
2660
52.6k
        block_Release( p_pkt );
2661
52.6k
        return NULL;
2662
52.6k
    }
2663
2664
2.12M
    return p_pkt;
2665
2.17M
}
2666
2667
static bool GatherPESData( demux_t *p_demux, ts_pid_t *p_pid, block_t *p_pkt, size_t i_skip )
2668
1.42M
{
2669
1.42M
    demux_sys_t *p_sys = p_demux->p_sys;
2670
1.42M
    ts_pes_parse_callback cb = { .p_obj = VLC_OBJECT(p_demux),
2671
1.42M
                                 .priv = p_pid,
2672
1.42M
                                 .pf_parse = PESDataChainHandle };
2673
1.42M
    const bool b_unit_start = p_pkt->p_buffer[1]&0x40;
2674
2675
1.42M
    p_pkt->p_buffer += i_skip; /* point to PES */
2676
1.42M
    p_pkt->i_buffer -= i_skip;
2677
2678
1.42M
    const ts_es_t *p_es = p_pid->u.p_stream->p_es;
2679
1.42M
    ts_90khz_t i_append_pcr = ( p_es && p_es->p_program && p_es->p_program->pcr.i_current != VLC_TICK_INVALID )
2680
1.42M
                                  ? TO_SCALE(p_es->p_program->pcr.i_current)
2681
1.42M
                                  : TS_90KHZ_INVALID;
2682
2683
1.42M
    return ts_pes_Gather( &cb, p_pid->u.p_stream,
2684
1.42M
                          p_pkt, b_unit_start,
2685
1.42M
                          p_sys->b_valid_scrambling,
2686
1.42M
                          i_append_pcr );
2687
1.42M
}
2688
2689
static bool GatherSectionsData( demux_t *p_demux, ts_pid_t *p_pid, block_t *p_pkt, size_t i_skip )
2690
188k
{
2691
188k
    VLC_UNUSED(i_skip); VLC_UNUSED(p_demux);
2692
188k
    bool b_ret = false;
2693
2694
188k
    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
188k
    if( (p_pkt->i_flags & BLOCK_FLAG_SCRAMBLED) == 0 )
2700
180k
    {
2701
180k
        ts_sections_processor_Push( p_pid->u.p_stream->p_sections_proc, p_pkt->p_buffer );
2702
180k
        b_ret = true;
2703
180k
    }
2704
2705
188k
    block_Release( p_pkt );
2706
2707
188k
    return b_ret;
2708
188k
}
2709
2710
void TsChangeStandard( demux_sys_t *p_sys, ts_standards_e v )
2711
4.12k
{
2712
4.12k
    if( p_sys->standard != TS_STANDARD_AUTO &&
2713
0
        p_sys->standard != v )
2714
0
        return; /* TODO */
2715
4.12k
    p_sys->standard = v;
2716
4.12k
}
2717
2718
bool ProgramIsSelected( demux_sys_t *p_sys, uint16_t i_pgrm )
2719
61.9k
{
2720
61.9k
    if( p_sys->seltype == PROGRAM_ALL )
2721
0
        return true;
2722
2723
65.6k
    for(int i=0; i<p_sys->programs.i_size; i++)
2724
61.9k
        if( p_sys->programs.p_elems[i] == i_pgrm )
2725
58.2k
            return true;
2726
2727
3.70k
    return false;
2728
61.9k
}
2729
2730
static bool PIDReferencedByProgram( const ts_pmt_t *p_pmt, uint16_t i_pid )
2731
80.3k
{
2732
80.3k
    for(int i=0; i<p_pmt->e_streams.i_size; i++)
2733
0
        if( p_pmt->e_streams.p_elems[i]->i_pid == i_pid )
2734
0
            return true;
2735
2736
80.3k
    return false;
2737
80.3k
}
2738
2739
static void DoCreateES( demux_t *p_demux, ts_es_t *p_es, const ts_es_t *p_parent_es )
2740
48.2k
{
2741
48.2k
    demux_sys_t *p_sys = p_demux->p_sys;
2742
2743
72.4k
    for( ; p_es ; p_es = p_es->p_next )
2744
24.1k
    {
2745
24.1k
        if( !p_es->id )
2746
24.1k
        {
2747
24.1k
            if( !p_es->fmt.i_group )
2748
0
                p_es->fmt.i_group = p_es->p_program->i_number;
2749
24.1k
            p_es->id = es_out_Add( p_demux->out, &p_es->fmt );
2750
24.1k
            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
24.1k
            p_sys->i_pmt_es++;
2757
24.1k
        }
2758
24.1k
        DoCreateES( p_demux, p_es->p_extraes, p_es );
2759
24.1k
    }
2760
48.2k
}
2761
2762
void AddAndCreateES( demux_t *p_demux, ts_pid_t *pid, bool b_create_delayed )
2763
24.1k
{
2764
24.1k
    demux_sys_t  *p_sys = p_demux->p_sys;
2765
2766
24.1k
    if( b_create_delayed )
2767
0
        p_sys->es_creation = CREATE_ES;
2768
2769
24.1k
    if( pid && p_sys->es_creation == CREATE_ES )
2770
24.1k
    {
2771
24.1k
        DoCreateES( p_demux, pid->u.p_stream->p_es, NULL );
2772
2773
        /* Update the default program == first created ES group */
2774
24.1k
        if( p_sys->b_default_selection && p_sys->programs.i_size > 0)
2775
1.31k
        {
2776
1.31k
            p_sys->b_default_selection = false;
2777
1.31k
            const int i_first_program = pid->u.p_stream->p_es->p_program->i_number;
2778
1.31k
            if( p_sys->programs.p_elems[0] != i_first_program )
2779
16
                p_sys->programs.p_elems[0] = i_first_program;
2780
1.31k
            msg_Dbg( p_demux, "Default program is %d", i_first_program );
2781
1.31k
        }
2782
24.1k
    }
2783
2784
24.1k
    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
24.1k
}