Coverage Report

Created: 2026-09-03 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/demux/mpeg/es.c
Line
Count
Source
1
/*****************************************************************************
2
 * es.c : Generic audio ES input module for vlc
3
 *****************************************************************************
4
 * Copyright (C) 2001-2008 VLC authors and VideoLAN
5
 *               2022 VideoLabs
6
 *
7
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8
 *          Gildas Bazin <gbazin@videolan.org>
9
 *
10
 * This program is free software; you can redistribute it and/or modify it
11
 * under the terms of the GNU Lesser General Public License as published by
12
 * the Free Software Foundation; either version 2.1 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public License
21
 * along with this program; if not, write to the Free Software Foundation,
22
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23
 *****************************************************************************/
24
25
/*****************************************************************************
26
 * Preamble
27
 *****************************************************************************/
28
29
#ifdef HAVE_CONFIG_H
30
# include "config.h"
31
#endif
32
33
#include <math.h>
34
35
#include <vlc_common.h>
36
#include <vlc_arrays.h>
37
#include <vlc_plugin.h>
38
#include <vlc_demux.h>
39
#include <vlc_codec.h>
40
#include <vlc_codecs.h>
41
#include <vlc_input.h>
42
#include <vlc_replay_gain.h>
43
44
#include "../../packetizer/a52.h"
45
#include "../../packetizer/dts_header.h"
46
#include "../../packetizer/mpegaudio.h"
47
#include "../../meta_engine/ID3Tag.h"
48
#include "../../meta_engine/ID3Text.h"
49
#include "../../meta_engine/ID3Meta.h"
50
51
/*****************************************************************************
52
 * Module descriptor
53
 *****************************************************************************/
54
static int  OpenAudio( vlc_object_t * );
55
static int  OpenVideo( vlc_object_t * );
56
static void Close    ( vlc_object_t * );
57
58
#define FPS_TEXT N_("Frames per Second")
59
#define FPS_LONGTEXT N_("This is the frame rate used as a fallback when " \
60
    "playing MPEG video elementary streams.")
61
62
174
vlc_module_begin ()
63
87
    set_subcategory( SUBCAT_INPUT_DEMUX )
64
87
    set_description( N_("MPEG-I/II/4 / A52 / DTS / MLP audio" ) )
65
87
    set_shortname( N_("Audio ES") )
66
87
    set_capability( "demux", 155 )
67
174
    set_callbacks( OpenAudio, Close )
68
69
87
    add_shortcut( "mpga", "mp3",
70
87
                  "m4a", "mp4a", "aac",
71
87
                  "ac3", "a52",
72
87
                  "eac3",
73
87
                  "dts",
74
87
                  "mlp", "thd" )
75
76
87
    add_submodule()
77
87
    set_description( N_("MPEG-4 video" ) )
78
87
    set_capability( "demux", 7 )
79
174
    set_callbacks( OpenVideo, Close )
80
87
    add_float( "es-fps", 25, FPS_TEXT, FPS_LONGTEXT )
81
82
87
    add_shortcut( "m4v" )
83
87
    add_shortcut( "mp4v" )
84
87
vlc_module_end ()
85
86
/*****************************************************************************
87
 * Local prototypes
88
 *****************************************************************************/
89
static int Demux  ( demux_t * );
90
static int Control( demux_t *, int, va_list );
91
92
2.08M
#define WAV_PROBE_SIZE (512*1024)
93
585
#define BASE_PROBE_SIZE (8000)
94
7.75k
#define WAV_EXTRA_PROBE_SIZE (44000/2*2*2)
95
96
typedef struct
97
{
98
    vlc_fourcc_t i_codec;
99
    bool       b_use_word;
100
    const char *psz_name;
101
    int  (*pf_probe)( demux_t *p_demux, uint64_t *pi_offset );
102
    int  (*pf_init)( demux_t *p_demux );
103
} codec_t;
104
105
typedef struct
106
{
107
    vlc_tick_t i_time;
108
    uint64_t i_pos;
109
    bs_t br;
110
} sync_table_ctx_t;
111
112
typedef struct
113
{
114
    uint16_t i_frames_btw_refs;
115
    uint32_t i_bytes_btw_refs;
116
    uint32_t i_ms_btw_refs;
117
    uint8_t i_bits_per_bytes_dev;
118
    uint8_t i_bits_per_ms_dev;
119
    uint8_t *p_bits;
120
    size_t i_bits;
121
    sync_table_ctx_t current;
122
} sync_table_t;
123
124
typedef struct
125
{
126
    uint32_t i_offset;
127
    seekpoint_t *p_seekpoint;
128
} chap_entry_t;
129
130
typedef struct
131
{
132
    vlc_tick_t i_start;
133
    char *psz_text;
134
} sylt_entry_t;
135
136
typedef struct
137
{
138
    char *psz_language;
139
    size_t i_count;
140
    size_t i_current; /* index of next lyric to send as SPU */
141
    sylt_entry_t *p_entry;
142
    es_out_id_t *p_es;
143
} sylt_track_t;
144
145
/* Mpga specific */
146
430
#define XING_FIELD_STREAMFRAMES    (1 << 0)
147
430
#define XING_FIELD_STREAMBYTES     (1 << 1)
148
430
#define XING_FIELD_TOC             (1 << 2)
149
430
#define XING_FIELD_QUALITY         (1 << 3)
150
12.0k
#define XING_MIN_TAG_SIZE           42
151
298
#define XING_TOC_COUNTBYTES         100
152
#define XING_MAX_TAG_SIZE          (XING_MIN_TAG_SIZE + 4 + 4 + XING_TOC_COUNTBYTES + 4 + 2)
153
#define XING_SUB_ETE_NOK_OTAE       XING_MIN_TAG_SIZE
154
155
struct xing_info_s
156
{
157
    uint32_t i_frames;
158
    uint32_t i_bytes;
159
    uint32_t i_quality;
160
    vlc_fourcc_t infotag;
161
    vlc_fourcc_t encoder;
162
    uint8_t  rgi_toc[XING_TOC_COUNTBYTES];
163
    float f_peak_signal;
164
    float f_radio_replay_gain;
165
    float f_audiophile_replay_gain;
166
    enum
167
    {
168
        XING_MODE_UNKNOWN   = 0,
169
        XING_MODE_CBR       = 1,
170
        XING_MODE_ABR       = 2,
171
        XING_MODE_VBR1      = 3,
172
        XING_MODE_VBR2      = 4,
173
        XING_MODE_VBR3      = 5,
174
        XING_MODE_VBR4      = 6,
175
        XING_MODE_CBR_2PASS = 8,
176
        XING_MODE_ABR_2PASS = 9,
177
    } brmode;
178
    enum
179
    {
180
        XING_AUDIOMODE_UNKNOWN    = 0,
181
        XING_AUDIOMODE_DPL        = 1,
182
        XING_AUDIOMODE_DPL2       = 2,
183
        XING_AUDIOMODE_AMBISONICS = 3,
184
    } audiomode;
185
    uint8_t  bitrate_avg;
186
    uint16_t i_delay_samples;
187
    uint16_t i_padding_samples;
188
    uint32_t i_music_length;
189
};
190
191
static int ParseXing( const uint8_t *p_buf, size_t i_buf, struct xing_info_s *xing )
192
11.6k
{
193
11.6k
    if( i_buf < XING_MIN_TAG_SIZE )
194
2.47k
        return VLC_EGENERIC;
195
196
9.15k
    vlc_fourcc_t infotag = VLC_FOURCC(p_buf[0], p_buf[1], p_buf[2], p_buf[3]);
197
198
    /* L3Enc VBR info */
199
9.15k
    if( infotag == VLC_FOURCC('V','B','R','I') )
200
134
    {
201
134
        if( GetWBE( &p_buf[4] ) != 0x0001 )
202
11
            return VLC_EGENERIC;
203
123
        xing->i_bytes = GetDWBE( &p_buf[10] );
204
123
        xing->i_frames = GetDWBE( &p_buf[14] );
205
123
        xing->infotag = infotag;
206
123
        return VLC_SUCCESS;
207
134
    }
208
    /* Xing VBR/CBR tags */
209
9.02k
    else if( infotag != VLC_FOURCC('X','i','n','g') &&
210
8.79k
             infotag != VLC_FOURCC('I','n','f','o') )
211
8.58k
    {
212
8.58k
        return VLC_EGENERIC;
213
8.58k
    }
214
215
432
    xing->infotag = infotag;
216
217
432
    const uint32_t i_flags = GetDWBE( &p_buf[4] );
218
    /* compute our variable struct size for early checks */
219
432
    const unsigned varsz[4] = { ((i_flags & 0x01) ? 4 : 0),
220
432
                                ((i_flags & 0x02) ? 4 : 0),
221
432
                                ((i_flags & 0x04) ? XING_TOC_COUNTBYTES : 0),
222
432
                                ((i_flags & 0x08) ? 4 : 0) };
223
432
    const unsigned i_varallsz = varsz[0] + varsz[1] + varsz[2] + varsz[3];
224
432
    const unsigned i_tag_total = XING_MIN_TAG_SIZE + i_varallsz;
225
226
432
    if( i_buf < i_tag_total )
227
2
        return VLC_EGENERIC;
228
229
430
    if( i_flags & XING_FIELD_STREAMFRAMES )
230
321
        xing->i_frames = GetDWBE( &p_buf[8] );
231
430
    if( i_flags & XING_FIELD_STREAMBYTES )
232
376
        xing->i_bytes = GetDWBE( &p_buf[8 + varsz[0]] );
233
430
    if( i_flags & XING_FIELD_TOC )
234
148
        memcpy( xing->rgi_toc, &p_buf[8 + varsz[0] + varsz[1]], XING_TOC_COUNTBYTES );
235
430
    if( i_flags & XING_FIELD_QUALITY )
236
285
        xing->i_quality = GetDWBE( &p_buf[8 + varsz[0] + varsz[1] + varsz[2]] );
237
238
    /* pointer past optional members */
239
430
    const uint8_t *p_fixed = &p_buf[8 + i_varallsz];
240
241
    /* Original Xing encoder header stops here */
242
243
430
    xing->encoder = VLC_FOURCC(p_fixed[0], p_fixed[1], p_fixed[2], p_fixed[3]); /* char version[9] start */
244
245
430
    if( xing->encoder != VLC_FOURCC('L','A','M','E') &&
246
427
        xing->encoder != VLC_FOURCC('L','a','v','c') &&
247
420
        xing->encoder != VLC_FOURCC('L','a','v','f') )
248
400
        return VLC_SUCCESS;
249
250
30
    xing->brmode  = p_fixed[9] & 0x0f; /* version upper / mode lower */
251
30
    uint32_t peak_signal  = GetDWBE( &p_fixed[11] );
252
30
    xing->f_peak_signal = peak_signal / 8388608.0; /* pow(2, 23) */
253
30
    uint16_t gain = GetWBE( &p_fixed[15] );
254
30
    xing->f_radio_replay_gain = (gain & 0x1FF) / /* 9bits val stored x10 */
255
30
                                ((gain & 0x200) ? -10.0 : 10.0); /* -sign bit on bit 6 */
256
30
    gain = GetWBE( &p_fixed[17] );
257
30
    xing->f_radio_replay_gain = (gain & 0x1FF) / /* 9bits val stored x10 */
258
30
                                ((gain & 0x200) ? -10.0 : 10.0); /* -sign bit on bit 6 */
259
    /* flags @19 */
260
30
    xing->bitrate_avg = (p_fixed[20] != 0xFF) ? p_fixed[20] : 0; /* clipped to 255, so it's unknown from there */
261
30
    xing->i_delay_samples = (p_fixed[21] << 4) | (p_fixed[22] >> 4); /* upper 12bits */
262
30
    xing->i_padding_samples = ((p_fixed[22] & 0x0F) << 8) | p_fixed[23]; /* lower 12bits */
263
30
    xing->audiomode = (p_fixed[26] >> 3) & 0x07; /* over 16bits, 2b unused / 3b mode / 11b preset */
264
30
    xing->i_music_length  = GetDWBE( &p_fixed[28] );
265
266
30
    return VLC_SUCCESS;
267
430
}
268
269
static int MpgaGetCBRSeekpoint( const struct mpga_frameheader_s *mpgah,
270
                                const struct xing_info_s *xing,
271
                                uint64_t i_seekablesize,
272
                                double f_pos, vlc_tick_t *pi_time, uint64_t *pi_offset )
273
0
{
274
0
    if( xing->infotag != 0 &&
275
0
        xing->infotag != VLC_FOURCC('I','n','f','o') &&
276
0
        xing->brmode != XING_MODE_CBR &&
277
0
        xing->brmode != XING_MODE_CBR_2PASS )
278
0
        return -1;
279
280
0
    if( !mpgah->i_sample_rate || !mpgah->i_samples_per_frame || !mpgah->i_frame_size )
281
0
        return -1;
282
283
0
    uint32_t i_total_frames = xing->i_frames ? xing->i_frames
284
0
                                             : i_seekablesize / mpgah->i_frame_size;
285
286
    /* xing must be optional here */
287
0
    uint32_t i_frame = i_total_frames * f_pos;
288
0
    *pi_offset = i_frame * mpgah->i_frame_size;
289
0
    *pi_time = vlc_tick_from_samples( i_frame * mpgah->i_samples_per_frame,
290
0
                                      mpgah->i_sample_rate ) + VLC_TICK_0;
291
292
0
    return 0;
293
0
}
294
295
static int SeekByPosUsingXingTOC( const struct mpga_frameheader_s *mpgah,
296
                                  const struct xing_info_s *xing,double pos,
297
                                  vlc_tick_t *pi_time, uint64_t *pi_offset )
298
0
{
299
0
    if( !xing->rgi_toc[XING_TOC_COUNTBYTES - 1] ||
300
0
        !mpgah->i_sample_rate || !mpgah->i_samples_per_frame )
301
0
        return -1;
302
303
0
    unsigned syncentry = pos * XING_TOC_COUNTBYTES;
304
0
    syncentry = VLC_CLIP(syncentry, 0, XING_TOC_COUNTBYTES - 1);
305
0
    unsigned syncframe = syncentry * xing->i_frames / XING_TOC_COUNTBYTES;
306
307
0
    *pi_time = vlc_tick_from_samples( syncframe * mpgah->i_samples_per_frame,
308
0
                                      mpgah->i_sample_rate ) + VLC_TICK_0;
309
0
    *pi_offset = xing->rgi_toc[syncentry] * xing->i_bytes / 256;
310
311
0
    return 0;
312
0
}
313
314
static int SeekByTimeUsingXingTOC( const struct mpga_frameheader_s *mpgah,
315
                                   const struct xing_info_s *xing,
316
                                   vlc_tick_t *pi_time, uint64_t *pi_offset )
317
0
{
318
0
    if( !mpgah->i_sample_rate || !mpgah->i_samples_per_frame || !xing->i_frames ||
319
0
        *pi_time < VLC_TICK_0 )
320
0
        return -1;
321
322
0
    uint32_t sample = samples_from_vlc_tick( *pi_time - VLC_TICK_0, mpgah->i_sample_rate );
323
0
    uint64_t totalsamples = mpgah->i_samples_per_frame * (uint64_t) xing->i_frames;
324
325
0
    return SeekByPosUsingXingTOC( mpgah, xing, (double)sample / totalsamples,
326
0
                                  pi_time, pi_offset );
327
0
}
328
329
static int MpgaSeek( const struct mpga_frameheader_s *mpgah,
330
                     const struct xing_info_s *xing,
331
                     uint64_t i_seekablesize, double f_pos,
332
                     vlc_tick_t *pi_time, uint64_t *pi_offset )
333
0
{
334
0
    if( f_pos >= 0 ) /* Set Pos */
335
0
    {
336
0
        if( !MpgaGetCBRSeekpoint( mpgah, xing, i_seekablesize,
337
0
                                  f_pos, pi_time, pi_offset ) )
338
0
        {
339
0
             return 0;
340
0
        }
341
0
    }
342
343
0
    if( *pi_time != VLC_TICK_INVALID &&
344
0
        !SeekByTimeUsingXingTOC( mpgah, xing, pi_time, pi_offset ) )
345
0
        return 0;
346
347
0
    return SeekByPosUsingXingTOC( mpgah, xing, f_pos, pi_time, pi_offset );
348
0
}
349
350
typedef struct
351
{
352
    codec_t codec;
353
    vlc_fourcc_t i_original;
354
355
    es_out_id_t *p_es;
356
357
    bool  b_start;
358
    decoder_t   *p_packetizer;
359
    block_t     *p_packetized_data;
360
361
    vlc_tick_t  i_pts;
362
    vlc_tick_t  i_time_offset;
363
    uint64_t    i_bytes;
364
365
    bool        b_big_endian;
366
    bool        b_estimate_bitrate;
367
    unsigned    i_bitrate;  /* extracted from Xing header */
368
    vlc_tick_t  i_duration;
369
370
    bool b_initial_sync_failed;
371
372
    unsigned i_packet_size;
373
374
    uint64_t i_stream_offset;
375
    unsigned i_demux_flags;
376
377
    float   f_fps;
378
379
    /* Mpga specific */
380
    struct mpga_frameheader_s mpgah;
381
    struct xing_info_s xing;
382
383
    audio_replay_gain_t audio_replay_gain;
384
385
    sync_table_t mllt;
386
    struct
387
    {
388
        size_t i_count;
389
        size_t i_current;
390
        chap_entry_t *p_entry;
391
    } chapters;
392
393
    /* Synchronized lyrics from ID3v2 SYLT, one track per language */
394
    struct
395
    {
396
        size_t i_count;
397
        sylt_track_t *p_track;
398
        bool b_meta_sent; /* true once sylt-data extra meta has been emitted */
399
    } sylt;
400
401
    vlc_meta_t *p_meta;
402
} demux_sys_t;
403
404
static int MpgaProbe( demux_t *p_demux, uint64_t *pi_offset );
405
static int MpgaInit( demux_t *p_demux );
406
407
static int AacProbe( demux_t *p_demux, uint64_t *pi_offset );
408
static int AacInit( demux_t *p_demux );
409
410
static int EA52Probe( demux_t *p_demux, uint64_t *pi_offset );
411
static int A52Probe( demux_t *p_demux, uint64_t *pi_offset );
412
static int A52Init( demux_t *p_demux );
413
414
static int DtsProbe( demux_t *p_demux, uint64_t *pi_offset );
415
static int DtsInit( demux_t *p_demux );
416
417
static int MlpProbe( demux_t *p_demux, uint64_t *pi_offset );
418
static int ThdProbe( demux_t *p_demux, uint64_t *pi_offset );
419
static int MlpInit( demux_t *p_demux );
420
421
static bool Parse( demux_t *p_demux, block_t **pp_output );
422
static int SeekByMlltTable( sync_table_t *, vlc_tick_t *, uint64_t * );
423
424
static const codec_t p_codecs[] = {
425
    { VLC_CODEC_MP4A, false, "mp4 audio",  AacProbe,  AacInit },
426
    { VLC_CODEC_MPGA, false, "mpeg audio", MpgaProbe, MpgaInit },
427
    { VLC_CODEC_A52, true,  "a52 audio",  A52Probe,  A52Init },
428
    { VLC_CODEC_EAC3, true,  "eac3 audio", EA52Probe, A52Init },
429
    { VLC_CODEC_DTS, false, "dts audio",  DtsProbe,  DtsInit },
430
    { VLC_CODEC_MLP, false, "mlp audio",  MlpProbe,  MlpInit },
431
    { VLC_CODEC_TRUEHD, false, "TrueHD audio",  ThdProbe,  MlpInit },
432
433
    { 0, false, NULL, NULL, NULL }
434
};
435
436
static int VideoInit( demux_t *p_demux );
437
438
static const codec_t codec_m4v = {
439
    VLC_CODEC_MP4V, false, "mp4 video", NULL,  VideoInit
440
};
441
442
/*****************************************************************************
443
 * OpenCommon: initializes demux structures
444
 *****************************************************************************/
445
static int OpenCommon( demux_t *p_demux,
446
                       int i_cat, const codec_t *p_codec, uint64_t i_bs_offset )
447
16.1k
{
448
16.1k
    demux_sys_t *p_sys;
449
450
16.1k
    es_format_t fmt;
451
452
16.1k
    DEMUX_INIT_COMMON(); p_sys = p_demux->p_sys;
453
16.1k
    memset( p_sys, 0, sizeof( demux_sys_t ) );
454
16.1k
    p_sys->codec = *p_codec;
455
16.1k
    p_sys->p_es = NULL;
456
16.1k
    p_sys->b_start = true;
457
16.1k
    p_sys->i_stream_offset = i_bs_offset;
458
16.1k
    p_sys->b_estimate_bitrate = true;
459
16.1k
    p_sys->i_bitrate = 0;
460
16.1k
    p_sys->i_duration = 0;
461
16.1k
    p_sys->b_big_endian = false;
462
16.1k
    p_sys->f_fps = var_InheritFloat( p_demux, "es-fps" );
463
16.1k
    p_sys->p_packetized_data = NULL;
464
16.1k
    p_sys->chapters.i_current = 0;
465
16.1k
    p_sys->xing.f_peak_signal = NAN;
466
16.1k
    p_sys->xing.f_radio_replay_gain = NAN;
467
16.1k
    p_sys->xing.f_audiophile_replay_gain = NAN;
468
16.1k
    TAB_INIT(p_sys->chapters.i_count, p_sys->chapters.p_entry);
469
16.1k
    TAB_INIT(p_sys->sylt.i_count, p_sys->sylt.p_track);
470
471
16.1k
    if( vlc_stream_Seek( p_demux->s, p_sys->i_stream_offset ) )
472
0
    {
473
0
        free( p_sys );
474
0
        return VLC_EGENERIC;
475
0
    }
476
477
16.1k
    if( p_sys->codec.pf_init( p_demux ) )
478
0
    {
479
0
        free( p_sys );
480
0
        return VLC_EGENERIC;
481
0
    }
482
483
16.1k
    if( vlc_stream_Seek( p_demux->s, p_sys->i_stream_offset ) )
484
0
    {
485
0
        free( p_sys );
486
0
        return VLC_EGENERIC;
487
0
    }
488
489
16.1k
    msg_Dbg( p_demux, "detected format %4.4s", (const char*)&p_sys->codec.i_codec );
490
491
    /* Load the audio packetizer */
492
16.1k
    es_format_Init( &fmt, i_cat, p_sys->codec.i_codec );
493
16.1k
    fmt.i_original_fourcc = p_sys->i_original;
494
16.1k
    p_sys->p_packetizer = demux_PacketizerNew( VLC_OBJECT(p_demux), &fmt, p_sys->codec.psz_name );
495
16.1k
    if( !p_sys->p_packetizer )
496
0
    {
497
0
        free( p_sys );
498
0
        return VLC_EGENERIC;
499
0
    }
500
501
16.1k
    es_format_t *p_fmt = &p_sys->p_packetizer->fmt_out;
502
16.1k
    replay_gain_Merge( &p_fmt->audio_replay_gain, &p_sys->audio_replay_gain );
503
504
    /* Register one SPU ES per SYLT language track */
505
16.1k
    for( size_t i = 0; i < p_sys->sylt.i_count; i++ )
506
0
    {
507
0
        sylt_track_t *p_tk = &p_sys->sylt.p_track[i];
508
0
        es_format_t spu_fmt;
509
0
        es_format_Init( &spu_fmt, SPU_ES, VLC_CODEC_SUBT );
510
0
        spu_fmt.psz_description = strdup( _("Lyrics") );
511
0
        spu_fmt.psz_language = p_tk->psz_language
512
0
                             ? strdup( p_tk->psz_language ) : NULL;
513
0
        p_tk->p_es = es_out_Add( p_demux->out, &spu_fmt );
514
0
        es_format_Clean( &spu_fmt );
515
0
        msg_Dbg( p_demux, "registered %zu synchronized lyrics entries (lang: %s)",
516
0
                 p_tk->i_count,
517
0
                 p_tk->psz_language ? p_tk->psz_language : "und" );
518
0
    }
519
520
16.1k
    for( ;; )
521
108k
    {
522
108k
        if( Parse( p_demux, &p_sys->p_packetized_data ) )
523
4.48k
            break;
524
104k
        if( p_sys->p_packetized_data )
525
11.6k
            break;
526
104k
    }
527
528
16.1k
    return VLC_SUCCESS;
529
16.1k
}
530
static int OpenAudio( vlc_object_t *p_this )
531
16.2k
{
532
16.2k
    demux_t *p_demux = (demux_t*)p_this;
533
40.3k
    for( int i = 0; p_codecs[i].i_codec != 0; i++ )
534
40.2k
    {
535
40.2k
        uint64_t i_offset;
536
40.2k
        if( !p_codecs[i].pf_probe( p_demux, &i_offset ) )
537
16.1k
            return OpenCommon( p_demux, AUDIO_ES, &p_codecs[i], i_offset );
538
40.2k
    }
539
116
    return VLC_EGENERIC;
540
16.2k
}
541
static int OpenVideo( vlc_object_t *p_this )
542
6
{
543
6
    demux_t *p_demux = (demux_t*)p_this;
544
545
    /* Only m4v is supported for the moment */
546
6
    bool b_m4v_ext    = demux_IsPathExtension( p_demux, ".m4v" );
547
6
    bool b_re4_ext    = !b_m4v_ext && demux_IsPathExtension( p_demux, ".re4" );
548
6
    bool b_m4v_forced = demux_IsForced( p_demux, "m4v" ) ||
549
6
                        demux_IsForced( p_demux, "mp4v" );
550
551
6
    if( !b_m4v_ext && !b_m4v_forced && !b_re4_ext )
552
6
        return VLC_EGENERIC;
553
554
0
    ssize_t i_off = b_re4_ext ? 220 : 0;
555
0
    const uint8_t *p_peek;
556
0
    if( vlc_stream_Peek( p_demux->s, &p_peek, i_off + 4 ) < i_off + 4 )
557
0
        return VLC_EGENERIC;
558
0
    if( p_peek[i_off + 0] != 0x00 || p_peek[i_off + 1] != 0x00 || p_peek[i_off + 2] != 0x01 )
559
0
    {
560
0
        if( !b_m4v_forced)
561
0
            return VLC_EGENERIC;
562
0
        msg_Warn( p_demux,
563
0
                  "this doesn't look like an MPEG ES stream, continuing anyway" );
564
0
    }
565
0
    return OpenCommon( p_demux, VIDEO_ES, &codec_m4v, i_off );
566
0
}
567
568
static void IncreaseChapter( demux_t *p_demux, vlc_tick_t i_time )
569
555k
{
570
555k
    demux_sys_t *p_sys = p_demux->p_sys;
571
555k
    while( p_sys->chapters.i_current + 1 < p_sys->chapters.i_count )
572
0
    {
573
0
        const chap_entry_t *p = &p_sys->chapters.p_entry[p_sys->chapters.i_current + 1];
574
0
        if( (p->i_offset != UINT32_MAX && vlc_stream_Tell( p_demux->s ) < p->i_offset) ||
575
0
            (i_time == VLC_TICK_INVALID || p->p_seekpoint->i_time_offset + VLC_TICK_0 > i_time) )
576
0
            break;
577
0
        ++p_sys->chapters.i_current;
578
0
        p_sys->i_demux_flags |= INPUT_UPDATE_SEEKPOINT;
579
0
    }
580
555k
}
581
582
/* Export all SYLT tracks as input item extra meta for the Qt display layer.
583
 * Called once on the first Demux invocation (deferred from Open) so that
584
 * the in-band metadata pass (InputSourceMeta / TagLib) has already run and
585
 * set title/artist/album before we call es_out_SetMeta, which sets the
586
 * ITEM_PREPARSED flag and would otherwise prevent those passes from running.
587
 *
588
 * Encoding: entries are packed as "ms\x1Ftext\x1E" (ASCII Unit Separator 0x1F
589
 * between timestamp and text; ASCII Record Separator 0x1E after each entry).
590
 * "sylt-data" carries the first (default) track for backward compatibility;
591
 * "sylt-data:xxx" carries each language for future language-aware UI. */
592
static void SyltEmitMeta( demux_t *p_demux )
593
0
{
594
0
    demux_sys_t *p_sys = p_demux->p_sys;
595
596
0
    for( size_t tk = 0; tk < p_sys->sylt.i_count; tk++ )
597
0
    {
598
0
        const sylt_track_t *p_tk = &p_sys->sylt.p_track[tk];
599
600
        /* 20 bytes for PRId64 decimal digits + 2 ASCII separator bytes per entry */
601
0
        size_t i_total = 1; /* null terminator */
602
0
        for( size_t i = 0; i < p_tk->i_count; i++ )
603
0
            i_total += 22 + strlen( p_tk->p_entry[i].psz_text );
604
605
0
        char *psz_data = malloc( i_total );
606
0
        if( !psz_data )
607
0
            continue;
608
609
0
        char *p = psz_data;
610
0
        *p = '\0';
611
0
        for( size_t i = 0; i < p_tk->i_count; i++ )
612
0
            p += sprintf( p, "%" PRId64 "\x1F%s\x1E",
613
0
                          MS_FROM_VLC_TICK( p_tk->p_entry[i].i_start ),
614
0
                          p_tk->p_entry[i].psz_text );
615
616
0
        vlc_meta_t *p_meta = vlc_meta_New();
617
0
        if( p_meta )
618
0
        {
619
0
            char psz_key[32];
620
0
            snprintf( psz_key, sizeof(psz_key), "sylt-data:%s",
621
0
                      p_tk->psz_language ? p_tk->psz_language : "und" );
622
0
            vlc_meta_SetExtra( p_meta, psz_key, psz_data );
623
0
            if( tk == 0 ) /* default key for single-language backward compat */
624
0
                vlc_meta_SetExtra( p_meta, "sylt-data", psz_data );
625
0
            es_out_SetMeta( p_demux->out, p_meta );
626
0
            vlc_meta_Delete( p_meta );
627
0
        }
628
0
        free( psz_data );
629
0
    }
630
0
    p_sys->sylt.b_meta_sent = true;
631
0
}
632
633
/*****************************************************************************
634
 * Demux: reads and demuxes data packets
635
 *****************************************************************************
636
 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
637
 *****************************************************************************/
638
static int Demux( demux_t *p_demux )
639
555k
{
640
555k
    int ret = 1;
641
555k
    demux_sys_t *p_sys = p_demux->p_sys;
642
643
    /* Emit sylt-data meta on the first Demux call, after InputSourceMeta has
644
     * already run and set title/artist/album. Doing this in Open would set the
645
     * ITEM_PREPARSED flag prematurely and prevent those metadata passes. */
646
555k
    if( unlikely( !p_sys->sylt.b_meta_sent ) && p_sys->sylt.i_count > 0 )
647
0
        SyltEmitMeta( p_demux );
648
649
555k
    block_t *p_block_out = p_sys->p_packetized_data;
650
555k
    if( p_block_out )
651
14.3k
        p_sys->p_packetized_data = NULL;
652
541k
    else
653
541k
        ret = Parse( p_demux, &p_block_out ) ? 0 : 1;
654
655
    /* Update chapter if any */
656
555k
    IncreaseChapter( p_demux,
657
555k
                     p_block_out ? p_sys->i_time_offset + p_block_out->i_dts
658
555k
                                 : VLC_TICK_INVALID );
659
660
6.84M
    while( p_block_out )
661
6.28M
    {
662
6.28M
        block_t *p_next = p_block_out->p_next;
663
664
        /* Correct timestamp */
665
6.28M
        if( p_sys->p_packetizer->fmt_out.i_cat == VIDEO_ES )
666
0
        {
667
0
            if( p_block_out->i_pts == VLC_TICK_INVALID &&
668
0
                p_block_out->i_dts == VLC_TICK_INVALID )
669
0
                p_block_out->i_dts = VLC_TICK_0 + p_sys->i_pts + VLC_TICK_FROM_SEC(1) / p_sys->f_fps;
670
0
            if( p_block_out->i_dts != VLC_TICK_INVALID )
671
0
                p_sys->i_pts = p_block_out->i_dts - VLC_TICK_0;
672
0
        }
673
6.28M
        else
674
6.28M
        {
675
6.28M
            p_sys->i_pts = p_block_out->i_pts - VLC_TICK_0;
676
6.28M
        }
677
678
6.28M
        if( p_block_out->i_pts != VLC_TICK_INVALID )
679
6.27M
        {
680
6.27M
            p_block_out->i_pts += p_sys->i_time_offset;
681
6.27M
        }
682
6.28M
        if( p_block_out->i_dts != VLC_TICK_INVALID )
683
6.27M
        {
684
6.27M
            p_block_out->i_dts += p_sys->i_time_offset;
685
6.27M
            es_out_SetPCR( p_demux->out, p_block_out->i_dts );
686
6.27M
        }
687
688
        /* Send synchronized lyrics as subtitle blocks */
689
6.28M
        if( p_sys->sylt.i_count > 0 && p_block_out->i_dts != VLC_TICK_INVALID )
690
0
        {
691
0
            vlc_tick_t i_audio_time = p_block_out->i_dts; /* already offset-adjusted above */
692
0
            for( size_t tk = 0; tk < p_sys->sylt.i_count; tk++ )
693
0
            {
694
0
                sylt_track_t *p_tk = &p_sys->sylt.p_track[tk];
695
0
                if( !p_tk->p_es )
696
0
                    continue;
697
0
                while( p_tk->i_current < p_tk->i_count )
698
0
                {
699
0
                    const sylt_entry_t *e = &p_tk->p_entry[p_tk->i_current];
700
0
                    if( VLC_TICK_0 + e->i_start > i_audio_time )
701
0
                        break;
702
703
0
                    size_t i_len = strlen( e->psz_text );
704
0
                    block_t *p_spu = block_Alloc( i_len + 1 );
705
0
                    if( p_spu )
706
0
                    {
707
0
                        memcpy( p_spu->p_buffer, e->psz_text, i_len + 1 );
708
0
                        p_spu->i_dts =
709
0
                        p_spu->i_pts = VLC_TICK_0 + e->i_start;
710
0
                        if( p_tk->i_current + 1 < p_tk->i_count )
711
0
                            p_spu->i_length = p_tk->p_entry[p_tk->i_current + 1].i_start
712
0
                                            - e->i_start;
713
0
                        else
714
0
                            p_spu->i_length = VLC_TICK_FROM_SEC( 5 );
715
0
                        es_out_Send( p_demux->out, p_tk->p_es, p_spu );
716
0
                    }
717
0
                    p_tk->i_current++;
718
0
                }
719
0
            }
720
0
        }
721
        /* Re-estimate bitrate */
722
6.28M
        if( p_sys->b_estimate_bitrate && p_sys->i_pts > VLC_TICK_FROM_MS(500) )
723
5.97M
            p_sys->i_bitrate = 8 * CLOCK_FREQ * p_sys->i_bytes
724
5.97M
                                   / (p_sys->i_pts - 1);
725
6.28M
        p_sys->i_bytes += p_block_out->i_buffer;
726
727
728
6.28M
        p_block_out->p_next = NULL;
729
6.28M
        if( likely(p_sys->p_es) )
730
6.28M
            es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
731
0
        else
732
0
            block_Release( p_block_out );
733
734
6.28M
        p_block_out = p_next;
735
6.28M
    }
736
555k
    return ret;
737
555k
}
738
739
/*****************************************************************************
740
 * Close: frees unused data
741
 *****************************************************************************/
742
static void Close( vlc_object_t * p_this )
743
16.1k
{
744
16.1k
    demux_t     *p_demux = (demux_t*)p_this;
745
16.1k
    demux_sys_t *p_sys = p_demux->p_sys;
746
747
16.1k
    if( p_sys->p_packetized_data )
748
0
        block_ChainRelease( p_sys->p_packetized_data );
749
16.1k
    for( size_t i=0; i< p_sys->chapters.i_count; i++ )
750
0
        vlc_seekpoint_Delete( p_sys->chapters.p_entry[i].p_seekpoint );
751
16.1k
    TAB_CLEAN( p_sys->chapters.i_count, p_sys->chapters.p_entry );
752
16.1k
    for( size_t i = 0; i < p_sys->sylt.i_count; i++ )
753
0
    {
754
0
        sylt_track_t *p_tk = &p_sys->sylt.p_track[i];
755
0
        for( size_t j = 0; j < p_tk->i_count; j++ )
756
0
            free( p_tk->p_entry[j].psz_text );
757
0
        TAB_CLEAN( p_tk->i_count, p_tk->p_entry );
758
0
        free( p_tk->psz_language );
759
0
    }
760
16.1k
    TAB_CLEAN( p_sys->sylt.i_count, p_sys->sylt.p_track );
761
16.1k
    if( p_sys->mllt.p_bits )
762
0
        free( p_sys->mllt.p_bits );
763
16.1k
    if( p_sys->p_meta )
764
0
        vlc_meta_Delete( p_sys->p_meta );
765
16.1k
    demux_PacketizerDestroy( p_sys->p_packetizer );
766
16.1k
    free( p_sys );
767
16.1k
}
768
769
/*****************************************************************************
770
 * Time seek:
771
 *****************************************************************************/
772
static void PostSeekCleanup( demux_sys_t *p_sys, vlc_tick_t i_time )
773
0
{
774
    /* Fix time_offset */
775
0
    if( i_time >= 0 )
776
0
        p_sys->i_time_offset = i_time - p_sys->i_pts;
777
    /* And reset buffered data */
778
0
    if( p_sys->p_packetized_data )
779
0
        block_ChainRelease( p_sys->p_packetized_data );
780
0
    p_sys->p_packetized_data = NULL;
781
    /* Reset chapter if any */
782
0
    p_sys->chapters.i_current = 0;
783
0
    p_sys->i_demux_flags |= INPUT_UPDATE_SEEKPOINT;
784
    /* Reset synchronized lyrics position */
785
0
    for( size_t tk = 0; tk < p_sys->sylt.i_count; tk++ )
786
0
    {
787
0
        sylt_track_t *p_tk = &p_sys->sylt.p_track[tk];
788
0
        p_tk->i_current = 0;
789
0
        if( i_time >= 0 )
790
0
        {
791
0
            for( size_t i = 0; i < p_tk->i_count; i++ )
792
0
            {
793
0
                if( VLC_TICK_0 + p_tk->p_entry[i].i_start > i_time )
794
0
                    break;
795
0
                p_tk->i_current = i;
796
0
            }
797
0
        }
798
0
    }
799
0
}
800
801
static int MovetoTimePos( demux_t *p_demux, vlc_tick_t i_time, uint64_t i_pos )
802
0
{
803
0
    demux_sys_t *p_sys  = p_demux->p_sys;
804
0
    int i_ret = vlc_stream_Seek( p_demux->s, p_sys->i_stream_offset + i_pos );
805
0
    if( i_ret != VLC_SUCCESS )
806
0
        return i_ret;
807
0
    PostSeekCleanup( p_sys, i_time );
808
0
    return VLC_SUCCESS;
809
0
}
810
811
/*****************************************************************************
812
 * Control:
813
 *****************************************************************************/
814
static int Control( demux_t *p_demux, int i_query, va_list args )
815
0
{
816
0
    demux_sys_t *p_sys  = p_demux->p_sys;
817
0
    bool *pb_bool;
818
819
0
    switch( i_query )
820
0
    {
821
0
        case DEMUX_HAS_UNSUPPORTED_META:
822
0
            pb_bool = va_arg( args, bool * );
823
0
            *pb_bool = true;
824
0
            return VLC_SUCCESS;
825
826
0
        case DEMUX_GET_META:
827
0
            if( p_sys->p_meta == NULL )
828
0
                return VLC_EGENERIC;
829
0
            vlc_meta_Merge( va_arg( args, vlc_meta_t * ), p_sys->p_meta );
830
0
            return VLC_SUCCESS;
831
832
0
        case DEMUX_GET_TIME:
833
0
            *va_arg( args, vlc_tick_t * ) = p_sys->i_pts + p_sys->i_time_offset;
834
0
            return VLC_SUCCESS;
835
836
0
        case DEMUX_GET_LENGTH:
837
0
        {
838
0
            if( p_sys->i_duration > 0 )
839
0
            {
840
0
                *va_arg( args, vlc_tick_t * ) = p_sys->i_duration;
841
0
                return VLC_SUCCESS;
842
0
            }
843
            /* compute length from bitrate */
844
0
            va_list ap;
845
0
            int i_ret;
846
847
0
            va_copy ( ap, args );
848
0
            i_ret = demux_vaControlHelper( p_demux->s, p_sys->i_stream_offset,
849
0
                                    -1, p_sys->i_bitrate, 1, i_query, ap );
850
0
            va_end( ap );
851
852
            /* No bitrate, we can't have it precisely, but we can compute
853
             * a raw approximation with time/position */
854
0
            if( i_ret && !p_sys->i_bitrate )
855
0
            {
856
0
                uint64_t i_stream_size;
857
0
                if( vlc_stream_GetSize( p_demux->s, &i_stream_size ) != VLC_SUCCESS )
858
0
                    return VLC_EGENERIC;
859
860
0
                uint64_t i_pos = vlc_stream_Tell( p_demux->s );
861
0
                float f_pos = (double)i_pos / (double)i_stream_size;
862
                /* The first few seconds are guaranteed to be very whacky,
863
                 * don't bother trying ... Too bad */
864
0
                if( f_pos < 0.01f ||
865
0
                    (p_sys->i_pts + p_sys->i_time_offset) < VLC_TICK_FROM_SEC(8) )
866
0
                {
867
0
                    return VLC_EGENERIC;
868
0
                }
869
870
0
                *va_arg( args, vlc_tick_t * ) =
871
0
                    (p_sys->i_pts + p_sys->i_time_offset) / f_pos;
872
0
                return VLC_SUCCESS;
873
0
            }
874
0
            return i_ret;
875
0
        }
876
877
0
        case DEMUX_SET_TIME:
878
0
        case DEMUX_SET_POSITION:
879
0
        {
880
0
            vlc_tick_t i_time;
881
0
            double f_pos;
882
0
            uint64_t i_offset;
883
884
0
            va_list ap;
885
0
            va_copy ( ap, args ); /* don't break args for helper fallback */
886
0
            if( i_query == DEMUX_SET_TIME )
887
0
            {
888
0
                i_time = va_arg(ap, vlc_tick_t);
889
0
                f_pos = p_sys->i_duration ? i_time / (double) p_sys->i_duration : -1.0;
890
0
                if( f_pos > 1.0 )
891
0
                    f_pos = 1.0;
892
0
            }
893
0
            else
894
0
            {
895
0
                f_pos = va_arg(ap, double);
896
0
                i_time = p_sys->i_duration ? p_sys->i_duration * f_pos : VLC_TICK_INVALID;
897
0
            }
898
0
            va_end( ap );
899
900
            /* Try to use ID3 table */
901
0
            if( !SeekByMlltTable( &p_sys->mllt, &i_time, &i_offset ) )
902
0
                return MovetoTimePos( p_demux, i_time, i_offset );
903
904
0
            if( p_sys->codec.i_codec == VLC_CODEC_MPGA )
905
0
            {
906
0
                uint64_t streamsize;
907
0
                if( !vlc_stream_GetSize( p_demux->s, &streamsize ) &&
908
0
                    streamsize > p_sys->i_stream_offset )
909
0
                    streamsize -= p_sys->i_stream_offset;
910
0
                else
911
0
                    streamsize = 0;
912
913
0
                if( !MpgaSeek( &p_sys->mpgah, &p_sys->xing,
914
0
                           streamsize, f_pos, &i_time, &i_offset ) )
915
0
                {
916
0
                    return MovetoTimePos( p_demux, i_time, i_offset );
917
0
                }
918
0
            }
919
920
            /* fallback on bitrate / file position seeking */
921
0
            i_time = VLC_TICK_INVALID;
922
0
            int ret = demux_vaControlHelper( p_demux->s, p_sys->i_stream_offset, -1,
923
0
                                             p_sys->i_bitrate, 1, i_query, args );
924
0
            if( ret != VLC_SUCCESS )
925
0
                return ret; /* not much we can do */
926
927
0
            if( p_sys->i_bitrate > 0 )
928
0
            {
929
0
                i_offset = vlc_stream_Tell( p_demux->s ); /* new pos */
930
0
                i_time = VLC_TICK_0;
931
0
                if( likely(i_offset > p_sys->i_stream_offset) )
932
0
                {
933
0
                    i_offset -= p_sys->i_stream_offset;
934
0
                    i_time += vlc_tick_from_samples( i_offset * 8, p_sys->i_bitrate );
935
0
                }
936
0
            }
937
0
            PostSeekCleanup( p_sys, i_time );
938
939
            /* FIXME TODO: implement a high precision seek (with mp3 parsing)
940
             * needed for multi-input */
941
0
            return VLC_SUCCESS;
942
0
        }
943
944
0
        case DEMUX_GET_TITLE_INFO:
945
0
        {
946
0
            if( p_sys->chapters.i_count == 0 )
947
0
                return VLC_EGENERIC;
948
0
            input_title_t **pp_title = malloc( sizeof(*pp_title) );
949
0
            if( !pp_title )
950
0
                return VLC_EGENERIC;
951
0
            *pp_title = vlc_input_title_New();
952
0
            if( !*pp_title )
953
0
            {
954
0
                free( pp_title );
955
0
                return VLC_EGENERIC;
956
0
            }
957
0
            (*pp_title)->seekpoint = vlc_alloc( p_sys->chapters.i_count, sizeof(seekpoint_t *) );
958
0
            if( !(*pp_title)->seekpoint )
959
0
            {
960
0
                free( *pp_title );
961
0
                free( pp_title );
962
0
                return VLC_EGENERIC;
963
0
            }
964
0
            for( size_t i=0; i<p_sys->chapters.i_count; i++ )
965
0
            {
966
0
                seekpoint_t *s = vlc_seekpoint_Duplicate( p_sys->chapters.p_entry[i].p_seekpoint );
967
0
                if( s )
968
0
                    (*pp_title)->seekpoint[(*pp_title)->i_seekpoint++] = s;
969
0
            }
970
0
            *(va_arg( args, input_title_t *** )) = pp_title;
971
0
            *(va_arg( args, int* )) = 1;
972
0
            *(va_arg( args, int* )) = 0;
973
0
            *(va_arg( args, int* )) = 0;
974
0
            return VLC_SUCCESS;
975
0
        }
976
0
        break;
977
978
0
        case DEMUX_GET_TITLE:
979
0
            if( p_sys->chapters.i_count == 0 )
980
0
                return VLC_EGENERIC;
981
0
            *(va_arg( args, int* )) = 0;
982
0
            return VLC_SUCCESS;
983
984
0
        case DEMUX_GET_SEEKPOINT:
985
0
            if( p_sys->chapters.i_count == 0 )
986
0
                return VLC_EGENERIC;
987
0
            *(va_arg( args, int* )) = p_sys->chapters.i_current;
988
0
            return VLC_SUCCESS;
989
990
0
        case DEMUX_SET_TITLE:
991
0
            return va_arg( args, int) == 0 ? VLC_SUCCESS : VLC_EGENERIC;
992
993
0
        case DEMUX_SET_SEEKPOINT:
994
0
        {
995
0
            int i = va_arg( args, int );
996
0
            if( (size_t)i>=p_sys->chapters.i_count )
997
0
                return VLC_EGENERIC;
998
0
            const chap_entry_t *p = &p_sys->chapters.p_entry[i];
999
0
            if( p_sys->chapters.p_entry[i].i_offset == UINT32_MAX )
1000
0
                return demux_Control( p_demux, DEMUX_SET_TIME, p->p_seekpoint->i_time_offset );
1001
0
            int i_ret= MovetoTimePos( p_demux, p->p_seekpoint->i_time_offset, p->i_offset );
1002
0
            if( i_ret == VLC_SUCCESS )
1003
0
                p_sys->chapters.i_current = i;
1004
0
            return i_ret;
1005
0
        }
1006
1007
0
        case DEMUX_TEST_AND_CLEAR_FLAGS:
1008
0
        {
1009
0
            unsigned *restrict flags = va_arg( args, unsigned * );
1010
0
            *flags &= p_sys->i_demux_flags;
1011
0
            p_sys->i_demux_flags &= ~*flags;
1012
0
            return VLC_SUCCESS;
1013
0
        }
1014
0
    }
1015
1016
0
    return demux_vaControlHelper( p_demux->s, p_sys->i_stream_offset, -1,
1017
0
                                  p_sys->i_bitrate, 1, i_query, args );
1018
0
}
1019
1020
/*****************************************************************************
1021
 * Makes a link list of buffer of parsed data
1022
 * Returns true if EOF
1023
 *****************************************************************************/
1024
static bool Parse( demux_t *p_demux, block_t **pp_output )
1025
650k
{
1026
650k
    demux_sys_t *p_sys = p_demux->p_sys;
1027
650k
    block_t *p_block_in, *p_block_out;
1028
1029
650k
    *pp_output = NULL;
1030
1031
650k
    if( p_sys->codec.b_use_word )
1032
117k
    {
1033
        /* Make sure we are word aligned */
1034
117k
        int64_t i_pos = vlc_stream_Tell( p_demux->s );
1035
117k
        if( (i_pos & 1) && vlc_stream_Read( p_demux->s, NULL, 1 ) != 1 )
1036
1.57k
            return true;
1037
117k
    }
1038
1039
648k
    p_block_in = vlc_stream_Block( p_demux->s, p_sys->i_packet_size );
1040
648k
    bool b_eof = p_block_in == NULL;
1041
1042
648k
    if( p_block_in )
1043
629k
    {
1044
629k
        if( p_sys->codec.b_use_word && !p_sys->b_big_endian && p_block_in->i_buffer > 0 )
1045
33.8k
        {
1046
            /* Convert to big endian */
1047
33.8k
            block_t *old = p_block_in;
1048
33.8k
            p_block_in = block_Alloc( p_block_in->i_buffer );
1049
33.8k
            if( p_block_in )
1050
33.8k
            {
1051
33.8k
                block_CopyProperties( p_block_in, old );
1052
33.8k
                swab( old->p_buffer, p_block_in->p_buffer, old->i_buffer );
1053
33.8k
            }
1054
33.8k
            block_Release( old );
1055
33.8k
        }
1056
1057
629k
        if( p_block_in )
1058
629k
        {
1059
629k
            p_block_in->i_pts =
1060
629k
            p_block_in->i_dts = (p_sys->b_start || p_sys->b_initial_sync_failed) ?
1061
629k
                                 VLC_TICK_0 : VLC_TICK_INVALID;
1062
629k
        }
1063
629k
    }
1064
648k
    p_sys->b_initial_sync_failed = p_sys->b_start; /* Only try to resync once */
1065
1066
648k
    decoder_t *p_packetizer = p_sys->p_packetizer;
1067
6.93M
    while( ( p_block_out = p_packetizer->pf_packetize( p_packetizer, p_block_in ? &p_block_in : NULL ) ) )
1068
6.28M
    {
1069
6.28M
        p_sys->b_initial_sync_failed = false;
1070
12.5M
        while( p_block_out )
1071
6.28M
        {
1072
6.28M
            if( !p_sys->p_es )
1073
14.3k
            {
1074
14.3k
                es_format_t fmt;
1075
14.3k
                es_format_Init( &fmt, p_packetizer->fmt_out.i_cat, p_packetizer->fmt_out.i_codec );
1076
14.3k
                es_format_Copy( &fmt, &p_packetizer->fmt_out );
1077
1078
14.3k
                switch( p_sys->xing.audiomode )
1079
14.3k
                {
1080
2
                    case XING_AUDIOMODE_AMBISONICS:
1081
2
                        fmt.audio.channel_type = AUDIO_CHANNEL_TYPE_AMBISONICS;
1082
2
                        break;
1083
14.3k
                    default:
1084
14.3k
                        break;
1085
14.3k
                }
1086
1087
14.3k
                fmt.b_packetized = true;
1088
14.3k
                fmt.i_id = 0;
1089
14.3k
                p_sys->p_es = es_out_Add( p_demux->out, &fmt );
1090
1091
                /* Use the bitrate as initual value */
1092
14.3k
                if( p_sys->b_estimate_bitrate )
1093
14.0k
                    p_sys->i_bitrate = fmt.i_bitrate;
1094
1095
14.3k
                es_format_Clean( &fmt );
1096
14.3k
            }
1097
1098
6.28M
            block_t *p_next = p_block_out->p_next;
1099
6.28M
            p_block_out->p_next = NULL;
1100
1101
6.28M
            block_ChainLastAppend( &pp_output, p_block_out );
1102
1103
6.28M
            p_block_out = p_next;
1104
6.28M
        }
1105
6.28M
    }
1106
1107
648k
    if( p_sys->b_initial_sync_failed )
1108
648k
        msg_Dbg( p_demux, "did not sync on first block" );
1109
648k
    p_sys->b_start = false;
1110
1111
648k
    return b_eof;
1112
648k
}
1113
1114
/* Check to apply to WAVE fmt header */
1115
static int GenericFormatCheck( int i_format, const uint8_t *p_head )
1116
1.74k
{
1117
1.74k
    if ( i_format == WAVE_FORMAT_PCM )
1118
1.08k
    {
1119
1.08k
        if( GetWLE( p_head /* nChannels */ ) != 2 )
1120
346
            return VLC_EGENERIC;
1121
734
        if( GetDWLE( p_head + 2 /* nSamplesPerSec */ ) != 44100 )
1122
155
            return VLC_EGENERIC;
1123
734
    }
1124
1.24k
    return VLC_SUCCESS;
1125
1.74k
}
1126
1127
/*****************************************************************************
1128
 * Wav header skipper
1129
 *****************************************************************************/
1130
static int WavSkipHeader( demux_t *p_demux, uint64_t *pi_skip,
1131
                          const uint16_t rgi_twocc[],
1132
                          int (*pf_format_check)( int, const uint8_t * ) )
1133
23.9k
{
1134
23.9k
    const uint8_t *p_peek;
1135
23.9k
    size_t i_peek = 0;
1136
23.9k
    uint32_t i_len;
1137
1138
    /* */
1139
23.9k
    *pi_skip = 0;
1140
1141
    /* Check if we are dealing with a WAV file */
1142
23.9k
    if( vlc_stream_Peek( p_demux->s, &p_peek, 12+8 ) != 12 + 8 )
1143
1.55k
        return VLC_SUCCESS;
1144
1145
22.4k
    if( memcmp( p_peek, "RIFF", 4 ) || memcmp( &p_peek[8], "WAVE", 4 ) )
1146
18.5k
        return VLC_SUCCESS;
1147
1148
    /* Find the wave format header */
1149
3.83k
    i_peek = 12 + 8;
1150
377k
    while( memcmp( p_peek + i_peek - 8, "fmt ", 4 ) )
1151
374k
    {
1152
374k
        i_len = GetDWLE( p_peek + i_peek - 4 );
1153
374k
        if( i_len > WAV_PROBE_SIZE || i_peek + i_len > WAV_PROBE_SIZE )
1154
202
            return VLC_EGENERIC;
1155
1156
374k
        i_peek += i_len + 8;
1157
374k
        if( vlc_stream_Peek( p_demux->s, &p_peek, i_peek ) != (ssize_t) i_peek )
1158
297
            return VLC_EGENERIC;
1159
374k
    }
1160
1161
    /* Sanity check the wave format header */
1162
3.33k
    i_len = GetDWLE( p_peek + i_peek - 4 );
1163
3.33k
    if( i_len > WAV_PROBE_SIZE )
1164
96
        return VLC_EGENERIC;
1165
1166
3.23k
    i_peek += i_len + 8;
1167
3.23k
    if( vlc_stream_Peek( p_demux->s, &p_peek, i_peek ) != (ssize_t) i_peek )
1168
184
        return VLC_EGENERIC;
1169
3.05k
    const uint16_t i_twocc = GetWLE( p_peek + i_peek - i_len - 8 /* wFormatTag */ );
1170
3.05k
    int i_format_idx;
1171
5.55k
    for( i_format_idx = 0; rgi_twocc[i_format_idx] != WAVE_FORMAT_UNKNOWN; i_format_idx++ )
1172
4.64k
    {
1173
4.64k
        if( i_twocc == rgi_twocc[i_format_idx] )
1174
2.13k
            break;
1175
4.64k
    }
1176
3.05k
    if( rgi_twocc[i_format_idx] == WAVE_FORMAT_UNKNOWN )
1177
915
        return VLC_EGENERIC;
1178
1179
2.13k
    if( pf_format_check &&
1180
1.74k
        pf_format_check( i_twocc, p_peek + i_peek - i_len - 6 ) != VLC_SUCCESS )
1181
501
            return VLC_EGENERIC;
1182
1183
    /* Skip the wave header */
1184
321k
    while( memcmp( p_peek + i_peek - 8, "data", 4 ) )
1185
320k
    {
1186
320k
        i_len = GetDWLE( p_peek + i_peek - 4 );
1187
320k
        if( i_len > WAV_PROBE_SIZE || i_peek + i_len > WAV_PROBE_SIZE )
1188
63
            return VLC_EGENERIC;
1189
1190
319k
        i_peek += i_len + 8;
1191
319k
        if( vlc_stream_Peek( p_demux->s, &p_peek, i_peek ) != (ssize_t) i_peek )
1192
69
            return VLC_EGENERIC;
1193
319k
    }
1194
1.50k
    *pi_skip = i_peek;
1195
1.50k
    return VLC_SUCCESS;
1196
1.63k
}
1197
1198
static int GenericProbe( demux_t *p_demux, uint64_t *pi_offset,
1199
                         const char * ppsz_name[],
1200
                         int (*pf_check)( const uint8_t *, unsigned * ),
1201
                         unsigned i_check_size,
1202
                         unsigned i_base_probing,
1203
                         unsigned i_wav_extra_probing,
1204
                         bool b_use_word,
1205
                         const uint16_t pi_twocc[],
1206
                         int (*pf_format_check)( int, const uint8_t * ) )
1207
7.75k
{
1208
7.75k
    bool   b_forced_demux;
1209
1210
7.75k
    uint64_t i_offset;
1211
7.75k
    const uint8_t *p_peek;
1212
7.75k
    uint64_t i_skip;
1213
1214
7.75k
    b_forced_demux = false;
1215
19.4k
    for( size_t i = 0; ppsz_name[i] != NULL; i++ )
1216
11.6k
    {
1217
11.6k
        b_forced_demux |= demux_IsForced( p_demux, ppsz_name[i] );
1218
11.6k
    }
1219
1220
7.75k
    i_offset = vlc_stream_Tell( p_demux->s );
1221
1222
7.75k
    if( WavSkipHeader( p_demux, &i_skip, pi_twocc, pf_format_check ) )
1223
1.18k
    {
1224
1.18k
        if( !b_forced_demux )
1225
756
            return VLC_EGENERIC;
1226
1.18k
    }
1227
7.00k
    const bool b_wav = i_skip > 0;
1228
1229
    /* peek the beginning
1230
     * It is common that wav files have some sort of garbage at the beginning
1231
     * We will accept probing 0.5s of data in this case.
1232
     */
1233
7.00k
    const size_t i_probe = i_skip + i_check_size + i_base_probing + ( b_wav ? i_wav_extra_probing : 0);
1234
7.00k
    const ssize_t i_peek = vlc_stream_Peek( p_demux->s, &p_peek, i_probe );
1235
1236
7.00k
    if( i_peek < 0 || (size_t)i_peek < i_skip + i_check_size )
1237
449
        return VLC_EGENERIC;
1238
1239
6.55k
    for( ;; )
1240
17.2M
    {
1241
        /* i_peek > 0 so we can cast into size_t. */
1242
17.2M
        if( i_skip + i_check_size > (size_t)i_peek )
1243
1.64k
        {
1244
1.64k
            if( !b_forced_demux )
1245
802
                return VLC_EGENERIC;
1246
839
            break;
1247
1.64k
        }
1248
17.2M
        unsigned i_samples = 0;
1249
17.2M
        int i_size = pf_check( &p_peek[i_skip], &i_samples );
1250
17.2M
        if( i_size >= 0 )
1251
24.9k
        {
1252
24.9k
            if( i_size == 0 || /* 0 sized frame ?? */
1253
24.8k
                i_skip == 0 /* exact match from start, we're not WAVE either, so skip multiple checks (would break if padding) */ )
1254
2.13k
                break;
1255
1256
            /* If we have the frame size, check the next frame for
1257
             * extra robustness
1258
             * The second test is because some .wav have paddings
1259
             */
1260
24.9k
            bool b_ok = false;
1261
60.7k
            for( int t = 0; t < 1 + !!b_wav; t++ )
1262
40.4k
            {
1263
40.4k
                if( t == 1 )
1264
17.6k
                {
1265
17.6k
                    if(!i_samples)
1266
1.78k
                        break;
1267
15.8k
                    i_size = i_samples * 2 * 2;
1268
15.8k
                }
1269
1270
38.6k
                if( i_skip + i_check_size + i_size <= (size_t)i_peek )
1271
30.4k
                {
1272
30.4k
                    b_ok = pf_check( &p_peek[i_skip+i_size], NULL ) >= 0;
1273
30.4k
                    if( b_ok )
1274
820
                        break;
1275
30.4k
                }
1276
38.6k
            }
1277
22.8k
            if( b_ok )
1278
820
                break;
1279
22.8k
        }
1280
17.2M
        if( b_use_word )
1281
8.48M
            i_skip += ((i_offset + i_skip) % 2 == 0) ? 2 : 1;
1282
8.73M
        else
1283
8.73M
            i_skip++;
1284
17.2M
        if( !b_wav && !b_forced_demux )
1285
1.96k
            return VLC_EGENERIC;
1286
17.2M
    }
1287
1288
3.78k
    *pi_offset = i_offset + i_skip;
1289
3.78k
    return VLC_SUCCESS;
1290
6.55k
}
1291
1292
/*****************************************************************************
1293
 * Mpeg I/II Audio
1294
 *****************************************************************************/
1295
static int MpgaCheckSync( const uint8_t *p_peek )
1296
311k
{
1297
311k
    uint32_t h = GetDWBE( p_peek );
1298
1299
311k
    if( ((( h >> 21 )&0x07FF) != 0x07FF )   /* header sync */
1300
48.9k
        || (((h >> 19)&0x03) == 1 )         /* valid version ID ? */
1301
48.8k
        || (((h >> 17)&0x03) == 0 )         /* valid layer ?*/
1302
46.9k
        || (((h >> 12)&0x0F) == 0x0F )      /* valid bitrate ?*/
1303
28.2k
        || (((h >> 10) & 0x03) == 0x03 )    /* valid sampling freq ? */
1304
24.1k
        || ((h & 0x03) == 0x02 ))           /* valid emphasis ? */
1305
287k
    {
1306
287k
        return false;
1307
287k
    }
1308
24.0k
    return true;
1309
311k
}
1310
1311
11.7k
#define MPGA_VERSION( h )   ( 1 - (((h)>>19)&0x01) )
1312
11.7k
#define MPGA_MODE(h)        (((h)>> 6)&0x03)
1313
1314
static int MpgaProbe( demux_t *p_demux, uint64_t *pi_offset )
1315
16.2k
{
1316
16.2k
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_MPEG, WAVE_FORMAT_MPEGLAYER3, WAVE_FORMAT_UNKNOWN };
1317
16.2k
    bool   b_forced;
1318
16.2k
    bool   b_forced_demux;
1319
16.2k
    uint64_t i_offset;
1320
1321
16.2k
    const uint8_t *p_peek;
1322
16.2k
    uint64_t i_skip;
1323
16.2k
    ssize_t i_peek;
1324
1325
16.2k
    b_forced = demux_IsPathExtension( p_demux, ".mp3" );
1326
16.2k
    b_forced_demux = demux_IsForced( p_demux, "mp3" ) ||
1327
14.4k
                     demux_IsForced( p_demux, "mpga" );
1328
1329
16.2k
    i_offset = vlc_stream_Tell( p_demux->s );
1330
1331
16.2k
    if( WavSkipHeader( p_demux, &i_skip, rgi_twocc, NULL ) )
1332
1.14k
    {
1333
1.14k
        if( !b_forced_demux )
1334
580
            return VLC_EGENERIC;
1335
1336
560
        return VLC_EGENERIC;
1337
1.14k
    }
1338
1339
15.0k
    i_peek = vlc_stream_Peek( p_demux->s, &p_peek, i_skip + 4 );
1340
15.0k
    if( i_peek <= 0 || (uint64_t) i_peek < i_skip + 4 )
1341
9
        return VLC_EGENERIC;
1342
1343
15.0k
    if( !MpgaCheckSync( &p_peek[i_skip] ) )
1344
3.53k
    {
1345
3.53k
        bool b_ok = false;
1346
1347
3.53k
        if( !b_forced_demux && !b_forced )
1348
2.75k
            return VLC_EGENERIC;
1349
1350
774
        i_peek = vlc_stream_Peek( p_demux->s, &p_peek, i_skip + 8096 );
1351
284k
        while( i_peek > 0 && i_skip + 4 < (uint64_t) i_peek )
1352
284k
        {
1353
284k
            if( MpgaCheckSync( &p_peek[i_skip] ) )
1354
744
            {
1355
744
                b_ok = true;
1356
744
                break;
1357
744
            }
1358
283k
            i_skip++;
1359
283k
        }
1360
774
        if( !b_ok && !b_forced_demux )
1361
0
            return VLC_EGENERIC;
1362
774
    }
1363
12.3k
    *pi_offset = i_offset + i_skip;
1364
12.3k
    return VLC_SUCCESS;
1365
15.0k
}
1366
1367
static int SeekByMlltTable( sync_table_t *mllt, vlc_tick_t *pi_time, uint64_t *pi_offset )
1368
0
{
1369
0
    if( !mllt->p_bits )
1370
0
        return -1;
1371
1372
0
    sync_table_ctx_t *p_cur = &mllt->current;
1373
1374
    /* reset or init context */
1375
0
    if( *pi_time < p_cur->i_time || !p_cur->br.p )
1376
0
    {
1377
0
        p_cur->i_time = 0;
1378
0
        p_cur->i_pos = 0;
1379
0
        bs_init(&p_cur->br, mllt->p_bits, mllt->i_bits);
1380
0
    }
1381
1382
0
    while(!bs_eof(&p_cur->br))
1383
0
    {
1384
0
        const uint32_t i_bytesdev = bs_read(&p_cur->br, mllt->i_bits_per_bytes_dev);
1385
0
        const uint32_t i_msdev = bs_read(&p_cur->br, mllt->i_bits_per_ms_dev);
1386
0
        if(bs_error(&p_cur->br))
1387
0
            break;
1388
0
        const vlc_tick_t i_deltatime = VLC_TICK_FROM_MS(mllt->i_ms_btw_refs + i_msdev);
1389
0
        if( p_cur->i_time + i_deltatime > *pi_time )
1390
0
            break;
1391
0
        p_cur->i_time += i_deltatime;
1392
0
        p_cur->i_pos += mllt->i_bytes_btw_refs + i_bytesdev;
1393
0
    }
1394
0
    *pi_time = p_cur->i_time;
1395
0
    *pi_offset = p_cur->i_pos;
1396
1397
0
    return 0;
1398
0
}
1399
1400
static int ID3TAG_Parse_Handler( uint32_t i_tag, const uint8_t *p_payload, size_t i_payload, void *p_priv )
1401
0
{
1402
0
    demux_t *p_demux = (demux_t *) p_priv;
1403
0
    demux_sys_t *p_sys = p_demux->p_sys;
1404
1405
0
    if( p_sys->p_meta == NULL )
1406
0
        p_sys->p_meta = vlc_meta_New();
1407
0
    if( p_sys->p_meta != NULL )
1408
0
    {
1409
0
        ID3HandleTag( p_payload, i_payload, i_tag, p_sys->p_meta, NULL );
1410
0
        if( i_tag == VLC_FOURCC('T', 'X', 'X', 'X') )
1411
0
            vlc_replay_gain_CopyFromMeta( &p_sys->audio_replay_gain, p_sys->p_meta );
1412
0
    }
1413
1414
0
    if( i_tag == VLC_FOURCC('M', 'L', 'L', 'T') )
1415
0
    {
1416
0
        if( i_payload > 20 )
1417
0
        {
1418
0
            p_sys->mllt.i_frames_btw_refs = GetWBE(p_payload);
1419
0
            p_sys->mllt.i_bytes_btw_refs = GetDWBE(&p_payload[1]) & 0x00FFFFFF;
1420
0
            p_sys->mllt.i_ms_btw_refs = GetDWBE(&p_payload[4]) & 0x00FFFFFF;
1421
0
            if( !p_sys->mllt.i_frames_btw_refs || !p_sys->mllt.i_bytes_btw_refs ||
1422
0
                    !p_sys->mllt.i_ms_btw_refs ||
1423
0
                    p_payload[8] > 31 || p_payload[9] > 31 || /* bits length sanity check */
1424
0
                    ((p_payload[8] + p_payload[9]) % 4) || p_payload[8] + p_payload[9] < 4 )
1425
0
                return VLC_EGENERIC;
1426
0
            p_sys->mllt.i_bits_per_bytes_dev = p_payload[8];
1427
0
            p_sys->mllt.i_bits_per_ms_dev = p_payload[9];
1428
0
            p_sys->mllt.p_bits = malloc(i_payload - 10);
1429
0
            if( likely(p_sys->mllt.p_bits) )
1430
0
            {
1431
0
                p_sys->mllt.i_bits = i_payload - 10;
1432
0
                memcpy(p_sys->mllt.p_bits, &p_payload[10], p_sys->mllt.i_bits);
1433
0
                msg_Dbg(p_demux, "read MLLT sync table with %zu entries",
1434
0
                        (p_sys->mllt.i_bits * 8) / (p_sys->mllt.i_bits_per_bytes_dev + p_sys->mllt.i_bits_per_ms_dev) );
1435
0
            }
1436
0
        }
1437
0
        return VLC_SUCCESS;
1438
0
    }
1439
0
    else if ( i_tag == VLC_FOURCC('C', 'H', 'A', 'P') && i_payload >= 17 )
1440
0
    {
1441
0
        char *psz_title = strndup( (const char *)p_payload, i_payload - 16 );
1442
0
        size_t i_offset = psz_title ? strlen( psz_title ) : 0;
1443
0
        if( p_payload[i_offset] != 0 )
1444
0
        {
1445
0
            free( psz_title );
1446
0
            return VLC_SUCCESS;
1447
0
        }
1448
0
        chap_entry_t e;
1449
0
        e.p_seekpoint = vlc_seekpoint_New();
1450
0
        if( e.p_seekpoint )
1451
0
        {
1452
0
            e.p_seekpoint->psz_name = psz_title;
1453
0
            e.p_seekpoint->i_time_offset = VLC_TICK_FROM_MS(GetDWBE(&p_payload[1 + i_offset]));
1454
0
            e.i_offset = GetDWBE(&p_payload[1 + i_offset + 8]);
1455
0
            p_payload += i_offset + 1 + 16;
1456
0
            i_payload -= i_offset + 1 + 16;
1457
0
            if( 12 < i_payload && !memcmp("TIT2", p_payload, 4) )
1458
0
            {
1459
0
                psz_title = NULL; /* optional alloc */
1460
0
                const char *psz = ID3TextConvert(&p_payload[10], i_payload-12, &psz_title);
1461
0
                if( psz ) /* replace with TIT2 */
1462
0
                {
1463
0
                    free( e.p_seekpoint->psz_name );
1464
0
                    e.p_seekpoint->psz_name = (psz_title) ? psz_title : strdup( psz );
1465
0
                }
1466
0
            }
1467
0
            TAB_APPEND(p_sys->chapters.i_count, p_sys->chapters.p_entry, e);
1468
0
        } else free( psz_title );
1469
0
    }
1470
0
    else if( i_tag == VLC_FOURCC('S', 'Y', 'L', 'T') )
1471
0
    {
1472
        /* SYLT frame: encoding(1) + language(3) + timestamp_fmt(1) + content_type(1) + descriptor(null-term) + events */
1473
0
        if( i_payload < 6 )
1474
0
            return VLC_SUCCESS;
1475
1476
0
        const uint8_t i_encoding = p_payload[0];
1477
0
        const uint8_t i_timestamp_fmt = p_payload[4];
1478
0
        if( i_timestamp_fmt != 0x02 ) /* only millisecond timestamps are supported */
1479
0
        {
1480
0
            msg_Warn( p_demux, "SYLT: unsupported timestamp format %u, skipping",
1481
0
                      (unsigned) i_timestamp_fmt );
1482
0
            return VLC_SUCCESS;
1483
0
        }
1484
1485
        /* Parse language (3-byte ISO 639-2 code, may not be null-terminated) */
1486
0
        char psz_language[4];
1487
0
        memcpy( psz_language, p_payload + 1, 3 );
1488
0
        psz_language[3] = '\0';
1489
1490
        /* Find or create a track entry for this language */
1491
0
        sylt_track_t *p_tk = NULL;
1492
0
        for( size_t i = 0; i < p_sys->sylt.i_count; i++ )
1493
0
        {
1494
0
            if( strcmp( p_sys->sylt.p_track[i].psz_language
1495
0
                            ? p_sys->sylt.p_track[i].psz_language : "",
1496
0
                        psz_language ) == 0 )
1497
0
            {
1498
0
                p_tk = &p_sys->sylt.p_track[i];
1499
0
                break;
1500
0
            }
1501
0
        }
1502
0
        if( !p_tk )
1503
0
        {
1504
0
            sylt_track_t new_tk;
1505
0
            new_tk.psz_language = strdup( psz_language );
1506
0
            new_tk.i_count   = 0;
1507
0
            new_tk.i_current = 0;
1508
0
            new_tk.p_entry   = NULL;
1509
0
            new_tk.p_es      = NULL;
1510
0
            TAB_APPEND( p_sys->sylt.i_count, p_sys->sylt.p_track, new_tk );
1511
0
            p_tk = &p_sys->sylt.p_track[p_sys->sylt.i_count - 1];
1512
0
        }
1513
1514
        /* skip fixed header: language(3) + timestamp_fmt(1) + content_type(1) = 5 bytes after encoding */
1515
0
        const uint8_t *p = p_payload + 6;
1516
0
        size_t i_remaining = i_payload - 6;
1517
1518
0
        bool b_utf16 = (i_encoding == 0x01 || i_encoding == 0x02);
1519
1520
        /* Skip content descriptor (null-terminated string) */
1521
0
        if( b_utf16 ) /* UTF-16 */
1522
0
        {
1523
0
            while( i_remaining >= 2 && (p[0] != 0 || p[1] != 0) )
1524
0
            {
1525
0
                p += 2;
1526
0
                i_remaining -= 2;
1527
0
            }
1528
0
            if( i_remaining < 2 )
1529
0
                return VLC_SUCCESS;
1530
0
            p += 2;
1531
0
            i_remaining -= 2;
1532
0
        }
1533
0
        else /* ISO-8859-1 or UTF-8 */
1534
0
        {
1535
0
            while( i_remaining > 0 && *p != 0 )
1536
0
            {
1537
0
                p++;
1538
0
                i_remaining--;
1539
0
            }
1540
0
            if( i_remaining == 0 )
1541
0
                return VLC_SUCCESS;
1542
0
            p++;
1543
0
            i_remaining--;
1544
0
        }
1545
1546
        /* Parse repeated [text (null-terminated)] [timestamp (4 bytes BE ms)] */
1547
0
        while( i_remaining > 4 )
1548
0
        {
1549
0
            const uint8_t *p_text_start = p;
1550
0
            size_t i_text_len = 0;
1551
1552
0
            if( b_utf16 ) /* UTF-16 */
1553
0
            {
1554
0
                while( i_remaining - i_text_len >= 2 + 4 &&
1555
0
                       (p_text_start[i_text_len] != 0 || p_text_start[i_text_len + 1] != 0) )
1556
0
                    i_text_len += 2;
1557
1558
0
                if( i_remaining - i_text_len < 2 + 4 )
1559
0
                    break;
1560
0
                i_text_len += 2; /* include null terminator */
1561
0
            }
1562
0
            else /* ISO-8859-1 or UTF-8 */
1563
0
            {
1564
0
                while( i_text_len < i_remaining - 4 && p_text_start[i_text_len] != 0 )
1565
0
                    i_text_len++;
1566
1567
0
                if( i_text_len >= i_remaining - 4 )
1568
0
                    break;
1569
0
                i_text_len++; /* include null terminator */
1570
0
            }
1571
1572
            /* Convert text to UTF-8 */
1573
0
            char *psz_allocated = NULL;
1574
0
            size_t i_null_size = b_utf16 ? 2 : 1;
1575
0
            const char *psz_text = ID3TextConv( p_text_start, i_text_len - i_null_size,
1576
0
                                                i_encoding, &psz_allocated );
1577
1578
0
            p += i_text_len;
1579
0
            i_remaining -= i_text_len;
1580
1581
0
            uint32_t i_timestamp_ms = GetDWBE( p );
1582
0
            p += 4;
1583
0
            i_remaining -= 4;
1584
1585
0
            if( psz_text && *psz_text )
1586
0
            {
1587
0
                sylt_entry_t entry;
1588
0
                entry.i_start = VLC_TICK_FROM_MS( i_timestamp_ms );
1589
0
                entry.psz_text = psz_allocated ? psz_allocated : strdup( psz_text );
1590
0
                if( entry.psz_text )
1591
0
                    TAB_APPEND( p_tk->i_count, p_tk->p_entry, entry );
1592
0
                else
1593
0
                    free( psz_allocated );
1594
0
            }
1595
0
            else
1596
0
            {
1597
0
                free( psz_allocated );
1598
0
            }
1599
0
        }
1600
0
    }
1601
0
    else if( i_tag == VLC_FOURCC('U', 'S', 'L', 'T') )
1602
0
    {
1603
        /* USLT frame: encoding(1) + language(3) + content descriptor + lyrics/text */
1604
0
        if( i_payload < 4 )
1605
0
            return VLC_SUCCESS;
1606
1607
0
        const uint8_t i_encoding = p_payload[0];
1608
0
        char psz_language[4];
1609
0
        memcpy( psz_language, p_payload + 1, 3 );
1610
0
        psz_language[3] = '\0';
1611
1612
0
        const uint8_t *p = p_payload + 4;
1613
0
        size_t i_remaining = i_payload - 4;
1614
1615
0
        bool b_utf16 = (i_encoding == 0x01 || i_encoding == 0x02);
1616
1617
0
        if( b_utf16 )
1618
0
        {
1619
0
            while( i_remaining >= 2 && (p[0] != 0 || p[1] != 0) )
1620
0
            {
1621
0
                p += 2;
1622
0
                i_remaining -= 2;
1623
0
            }
1624
0
            if( i_remaining < 2 )
1625
0
                return VLC_SUCCESS;
1626
0
            p += 2;
1627
0
            i_remaining -= 2;
1628
0
        }
1629
0
        else
1630
0
        {
1631
0
            while( i_remaining > 0 && *p != 0 )
1632
0
            {
1633
0
                p++;
1634
0
                i_remaining--;
1635
0
            }
1636
0
            if( i_remaining == 0 )
1637
0
                return VLC_SUCCESS;
1638
0
            p++;
1639
0
            i_remaining--;
1640
0
        }
1641
1642
0
        char *psz_allocated = NULL;
1643
0
        const char *psz_text = ID3TextConv( p, i_remaining, i_encoding, &psz_allocated );
1644
0
        if( psz_text && *psz_text )
1645
0
        {
1646
0
            if( p_sys->p_meta == NULL )
1647
0
                p_sys->p_meta = vlc_meta_New();
1648
0
            if( p_sys->p_meta != NULL )
1649
0
            {
1650
0
                char psz_key[32];
1651
0
                snprintf( psz_key, sizeof(psz_key), "Lyrics:%s", psz_language );
1652
0
                vlc_meta_SetExtra( p_sys->p_meta, psz_key, psz_text );
1653
1654
                /* Provide a synthetic uslt-data entry at t=0 so the Qt lyrics
1655
                 * panel can display USLT text using the same timed-lyrics path. */
1656
0
                char *psz_sylt;
1657
0
                if( asprintf( &psz_sylt, "0\x1F%s\x1E", psz_text ) >= 0 )
1658
0
                {
1659
0
                    vlc_meta_SetExtra( p_sys->p_meta, "uslt-data", psz_sylt );
1660
0
                    free( psz_sylt );
1661
0
                }
1662
0
            }
1663
0
        }
1664
0
        free( psz_allocated );
1665
0
    }
1666
1667
0
    return VLC_SUCCESS;
1668
0
}
1669
1670
static int ID3Parse( demux_t *p_demux,
1671
                     int (*pf_callback)(uint32_t, const uint8_t *, size_t, void *) )
1672
12.3k
{
1673
12.3k
    const block_t *p_tags = NULL;
1674
1675
12.3k
    if( vlc_stream_Control( p_demux->s, STREAM_GET_TAGS, &p_tags ) != VLC_SUCCESS )
1676
12.3k
        return VLC_EGENERIC;
1677
1678
0
    for( ; p_tags; p_tags = p_tags->p_next )
1679
0
        ID3TAG_Parse( p_tags->p_buffer, p_tags->i_buffer, pf_callback, (void *) p_demux );
1680
1681
0
    return VLC_SUCCESS;
1682
12.3k
}
1683
1684
static int MpgaInit( demux_t *p_demux )
1685
12.3k
{
1686
12.3k
    demux_sys_t *p_sys = p_demux->p_sys;
1687
1688
12.3k
    const uint8_t *p_peek;
1689
12.3k
    int i_peek;
1690
1691
    /* */
1692
12.3k
    p_sys->i_packet_size = 1024;
1693
1694
12.3k
    ID3Parse( p_demux, ID3TAG_Parse_Handler );
1695
1696
    /* Load a potential xing header */
1697
12.3k
    i_peek = vlc_stream_Peek( p_demux->s, &p_peek, 4 + 1024 );
1698
12.3k
    if( i_peek < 4 + 21 )
1699
568
        return VLC_SUCCESS;
1700
1701
11.7k
    const uint32_t header = GetDWBE( p_peek );
1702
11.7k
    if( !MpgaCheckSync( p_peek ) || mpga_decode_frameheader( header, &p_sys->mpgah ) )
1703
25
        return VLC_SUCCESS;
1704
1705
11.7k
    if( p_sys->mpgah.i_layer == 3 )
1706
5.13k
        p_sys->codec.i_codec = VLC_CODEC_MP3;
1707
1708
    /* Xing header */
1709
11.7k
    int i_skip;
1710
1711
11.7k
    if( MPGA_VERSION( header ) == 0 )
1712
6.32k
        i_skip = MPGA_MODE( header ) != 3 ? 36 : 21;
1713
5.40k
    else
1714
5.40k
        i_skip = MPGA_MODE( header ) != 3 ? 21 : 13;
1715
1716
11.7k
    if( i_skip >= i_peek )
1717
97
        return VLC_SUCCESS;
1718
1719
11.6k
    struct xing_info_s *xing = &p_sys->xing;
1720
11.6k
    if( ParseXing( &p_peek[i_skip], i_peek - i_skip, xing ) == VLC_SUCCESS )
1721
553
    {
1722
553
        const uint64_t i_total_samples = xing->i_frames * (uint64_t) p_sys->mpgah.i_samples_per_frame;
1723
553
        const uint64_t i_dropped_samples = xing->i_delay_samples + xing->i_padding_samples;
1724
1725
553
        if( p_sys->mpgah.i_sample_rate && i_dropped_samples < i_total_samples )
1726
440
        {
1727
440
            uint64_t i_stream_size;
1728
            /* We only set duration if we can't check (then compute it using bitrate/size)
1729
               or if we verified the file isn't truncated */
1730
440
            if( xing->i_bytes == 0 ||
1731
416
                vlc_stream_GetSize( p_demux->s, &i_stream_size ) ||
1732
416
               (i_stream_size >= xing->i_bytes &&
1733
89
                i_stream_size <= xing->i_bytes + p_sys->mpgah.i_frame_size) )
1734
29
            {
1735
29
                p_sys->i_duration = vlc_tick_from_samples( i_total_samples - i_dropped_samples,
1736
29
                                                           p_sys->mpgah.i_sample_rate );
1737
29
            }
1738
440
        }
1739
1740
553
        unsigned i_bitrate = 0;
1741
553
        if( xing->brmode == XING_MODE_ABR || xing->brmode == XING_MODE_ABR_2PASS )
1742
12
            i_bitrate = xing->bitrate_avg * 1000;
1743
1744
553
        if( !i_bitrate && p_sys->mpgah.i_sample_rate &&
1745
546
            xing->i_bytes > p_sys->mpgah.i_frame_size )
1746
459
        {
1747
459
            unsigned d = vlc_tick_from_samples( i_total_samples, p_sys->mpgah.i_sample_rate );
1748
459
            if( d )
1749
387
                i_bitrate = (xing->i_bytes - p_sys->mpgah.i_frame_size) * 8 * CLOCK_FREQ / d;
1750
459
        }
1751
1752
553
        if( i_bitrate )
1753
368
        {
1754
368
            p_sys->i_bitrate = i_bitrate;
1755
368
            p_sys->b_estimate_bitrate = false;
1756
368
        }
1757
1758
553
        if( isfinite(xing->f_radio_replay_gain) )
1759
30
        {
1760
30
            p_sys->audio_replay_gain.pb_gain[AUDIO_REPLAY_GAIN_TRACK] = true;
1761
30
            p_sys->audio_replay_gain.pf_gain[AUDIO_REPLAY_GAIN_TRACK] = xing->f_radio_replay_gain;
1762
30
        }
1763
1764
553
        if( isfinite(xing->f_peak_signal) )
1765
30
        {
1766
30
            p_sys->audio_replay_gain.pb_peak[AUDIO_REPLAY_GAIN_TRACK] = true;
1767
30
            p_sys->audio_replay_gain.pf_peak[AUDIO_REPLAY_GAIN_TRACK] = xing->f_peak_signal;
1768
30
        }
1769
1770
553
        if( isfinite(xing->f_audiophile_replay_gain) )
1771
0
        {
1772
0
            p_sys->audio_replay_gain.pb_gain[AUDIO_REPLAY_GAIN_ALBUM] = true;
1773
0
            p_sys->audio_replay_gain.pf_gain[AUDIO_REPLAY_GAIN_ALBUM] = xing->f_audiophile_replay_gain;
1774
0
        }
1775
1776
553
        msg_Dbg( p_demux, "Using '%4.4s' infotag"
1777
553
                          "(%"PRIu32" bytes, %"PRIu32" frames, %u samples/frame)",
1778
553
                          (char *) &xing->infotag,
1779
553
                          xing->i_bytes, xing->i_frames,
1780
553
                          p_sys->mpgah.i_samples_per_frame );
1781
1782
        /* We'll need to skip that part for playback
1783
         * and avoid using it as container frame could be different rate/size */
1784
553
        p_sys->i_stream_offset += p_sys->mpgah.i_frame_size;
1785
553
    }
1786
1787
11.6k
    return VLC_SUCCESS;
1788
11.7k
}
1789
1790
/*****************************************************************************
1791
 * AAC
1792
 *****************************************************************************/
1793
static int AacProbe( demux_t *p_demux, uint64_t *pi_offset )
1794
16.2k
{
1795
16.2k
    bool   b_forced;
1796
16.2k
    bool   b_forced_demux;
1797
1798
16.2k
    uint64_t i_offset;
1799
16.2k
    const uint8_t *p_peek;
1800
1801
16.2k
    b_forced = demux_IsPathExtension( p_demux, ".aac" ) ||
1802
16.2k
               demux_IsPathExtension( p_demux, ".aacp" );
1803
16.2k
    b_forced_demux = demux_IsForced( p_demux, "m4a" ) ||
1804
16.2k
                     demux_IsForced( p_demux, "aac" ) ||
1805
16.2k
                     demux_IsForced( p_demux, "mp4a" );
1806
1807
16.2k
    if( !b_forced_demux && !b_forced )
1808
16.2k
        return VLC_EGENERIC;
1809
1810
0
    i_offset = vlc_stream_Tell( p_demux->s );
1811
1812
    /* peek the beginning (10 is for adts header) */
1813
0
    if( vlc_stream_Peek( p_demux->s, &p_peek, 10 ) < 10 )
1814
0
        return VLC_EGENERIC;
1815
1816
0
    if( !strncmp( (char *)p_peek, "ADIF", 4 ) )
1817
0
    {
1818
0
        msg_Err( p_demux, "ADIF file. Not yet supported. (Please report)" );
1819
0
        return VLC_EGENERIC;
1820
0
    }
1821
1822
0
    *pi_offset = i_offset;
1823
0
    return VLC_SUCCESS;
1824
0
}
1825
static int AacInit( demux_t *p_demux )
1826
0
{
1827
0
    demux_sys_t *p_sys = p_demux->p_sys;
1828
1829
0
    p_sys->i_packet_size = 4096;
1830
0
    p_sys->i_original = VLC_FOURCC('H','E','A','D');
1831
1832
0
    return VLC_SUCCESS;
1833
0
}
1834
1835
1836
/*****************************************************************************
1837
 * A52
1838
 *****************************************************************************/
1839
static int A52CheckSync( const uint8_t *p_peek, bool *p_big_endian, unsigned *pi_samples, bool b_eac3 )
1840
8.52M
{
1841
8.52M
    vlc_a52_header_t header;
1842
8.52M
    uint8_t p_tmp[VLC_A52_MIN_HEADER_SIZE];
1843
1844
8.52M
    *p_big_endian =  p_peek[0] == 0x0b && p_peek[1] == 0x77;
1845
8.52M
    if( !*p_big_endian )
1846
8.43M
    {
1847
8.43M
        swab( p_peek, p_tmp, VLC_A52_MIN_HEADER_SIZE );
1848
8.43M
        p_peek = p_tmp;
1849
8.43M
    }
1850
1851
8.52M
    if( vlc_a52_header_Parse( &header, p_peek, VLC_A52_MIN_HEADER_SIZE ) )
1852
8.29M
        return VLC_EGENERIC;
1853
1854
229k
    if( !header.b_eac3 != !b_eac3 )
1855
207k
        return VLC_EGENERIC;
1856
22.1k
    if( pi_samples )
1857
20.4k
        *pi_samples = header.i_samples;
1858
22.1k
    return header.i_size;
1859
229k
}
1860
static int EA52CheckSyncProbe( const uint8_t *p_peek, unsigned *pi_samples )
1861
2.69M
{
1862
2.69M
    bool b_dummy;
1863
2.69M
    return A52CheckSync( p_peek, &b_dummy, pi_samples, true );
1864
2.69M
}
1865
1866
static int EA52Probe( demux_t *p_demux, uint64_t *pi_offset )
1867
2.41k
{
1868
2.41k
    const char *ppsz_name[] = { "eac3", NULL };
1869
2.41k
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_A52, WAVE_FORMAT_UNKNOWN };
1870
1871
2.41k
    return GenericProbe( p_demux, pi_offset, ppsz_name, EA52CheckSyncProbe,
1872
2.41k
                         VLC_A52_MIN_HEADER_SIZE,
1873
2.41k
                         1920 + VLC_A52_MIN_HEADER_SIZE + 1,
1874
2.41k
                         WAV_EXTRA_PROBE_SIZE,
1875
2.41k
                         true, rgi_twocc, GenericFormatCheck );
1876
2.41k
}
1877
1878
static int A52CheckSyncProbe( const uint8_t *p_peek, unsigned *pi_samples )
1879
5.82M
{
1880
5.82M
    bool b_dummy;
1881
5.82M
    return A52CheckSync( p_peek, &b_dummy, pi_samples, false );
1882
5.82M
}
1883
1884
static int A52Probe( demux_t *p_demux, uint64_t *pi_offset )
1885
3.90k
{
1886
3.90k
    const char *ppsz_name[] = { "a52", "ac3", NULL };
1887
3.90k
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_A52, WAVE_FORMAT_UNKNOWN };
1888
1889
3.90k
    return GenericProbe( p_demux, pi_offset, ppsz_name, A52CheckSyncProbe,
1890
3.90k
                         VLC_A52_MIN_HEADER_SIZE,
1891
3.90k
                         1920 + VLC_A52_MIN_HEADER_SIZE + 1,
1892
3.90k
                         WAV_EXTRA_PROBE_SIZE,
1893
3.90k
                         true, rgi_twocc, GenericFormatCheck );
1894
3.90k
}
1895
1896
static int A52Init( demux_t *p_demux )
1897
3.05k
{
1898
3.05k
    demux_sys_t *p_sys = p_demux->p_sys;
1899
1900
3.05k
    p_sys->b_big_endian = false;
1901
3.05k
    p_sys->i_packet_size = 1024;
1902
1903
3.05k
    const uint8_t *p_peek;
1904
1905
    /* peek the beginning */
1906
3.05k
    if( vlc_stream_Peek( p_demux->s, &p_peek, VLC_A52_MIN_HEADER_SIZE ) >= VLC_A52_MIN_HEADER_SIZE )
1907
2.34k
    {
1908
2.34k
        A52CheckSync( p_peek, &p_sys->b_big_endian, NULL, true );
1909
2.34k
    }
1910
3.05k
    return VLC_SUCCESS;
1911
3.05k
}
1912
1913
/*****************************************************************************
1914
 * DTS
1915
 *****************************************************************************/
1916
static int DtsCheckSync( const uint8_t *p_peek, unsigned *pi_samples )
1917
5.14M
{
1918
5.14M
    VLC_UNUSED(pi_samples);
1919
1920
5.14M
    vlc_dts_header_t dts;
1921
5.14M
    if( vlc_dts_header_Parse( &dts, p_peek, VLC_DTS_HEADER_SIZE ) == VLC_SUCCESS
1922
7.53k
     && dts.i_frame_size > 0 && dts.i_frame_size <= 8192 )
1923
4.61k
    {
1924
4.61k
        if( pi_samples )
1925
4.32k
            *pi_samples = dts.i_frame_length;
1926
4.61k
        return dts.i_frame_size;
1927
4.61k
    }
1928
5.14M
    else
1929
5.14M
        return VLC_EGENERIC;
1930
5.14M
}
1931
1932
static int DtsProbe( demux_t *p_demux, uint64_t *pi_offset )
1933
851
{
1934
851
    const char *ppsz_name[] = { "dts", NULL };
1935
851
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_DTSINC_DTS, WAVE_FORMAT_UNKNOWN };
1936
1937
851
    return GenericProbe( p_demux, pi_offset, ppsz_name, DtsCheckSync,
1938
851
                         VLC_DTS_HEADER_SIZE,
1939
851
                         16384 + VLC_DTS_HEADER_SIZE + 1,
1940
851
                         WAV_EXTRA_PROBE_SIZE,
1941
851
                         false, rgi_twocc, NULL );
1942
851
}
1943
static int DtsInit( demux_t *p_demux )
1944
551
{
1945
551
    demux_sys_t *p_sys = p_demux->p_sys;
1946
1947
551
    p_sys->i_packet_size = 16384;
1948
1949
551
    return VLC_SUCCESS;
1950
551
}
1951
1952
/*****************************************************************************
1953
 * MLP
1954
 *****************************************************************************/
1955
static int MlpCheckSync( const uint8_t *p_peek, unsigned *pi_samples )
1956
3.47M
{
1957
3.47M
    if( p_peek[4+0] != 0xf8 || p_peek[4+1] != 0x72 || p_peek[4+2] != 0x6f )
1958
3.38M
        return -1;
1959
1960
91.3k
    if( p_peek[4+3] != 0xbb )
1961
91.3k
        return -1;
1962
1963
    /* TODO checksum and real size for robustness */
1964
12
    VLC_UNUSED(pi_samples);
1965
12
    return 0;
1966
91.3k
}
1967
static int ThdCheckSync( const uint8_t *p_peek, unsigned *pi_samples )
1968
113k
{
1969
113k
    if( p_peek[4+0] != 0xf8 || p_peek[4+1] != 0x72 || p_peek[4+2] != 0x6f )
1970
113k
        return -1;
1971
1972
191
    if( p_peek[4+3] != 0xba )
1973
27
        return -1;
1974
1975
    /* TODO checksum and real size for robustness */
1976
164
    VLC_UNUSED(pi_samples);
1977
164
    return 0;
1978
191
}
1979
static int MlpProbe( demux_t *p_demux, uint64_t *pi_offset )
1980
300
{
1981
300
    const char *ppsz_name[] = { "mlp", NULL };
1982
300
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_UNKNOWN };
1983
1984
300
    return GenericProbe( p_demux, pi_offset, ppsz_name, MlpCheckSync,
1985
300
                         4+28+16*4, BASE_PROBE_SIZE, WAV_EXTRA_PROBE_SIZE,
1986
300
                         false, rgi_twocc, GenericFormatCheck );
1987
300
}
1988
static int ThdProbe( demux_t *p_demux, uint64_t *pi_offset )
1989
285
{
1990
285
    const char *ppsz_name[] = { "thd", NULL };
1991
285
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_UNKNOWN };
1992
1993
285
    return GenericProbe( p_demux, pi_offset, ppsz_name, ThdCheckSync,
1994
285
                         4+28+16*4, BASE_PROBE_SIZE, WAV_EXTRA_PROBE_SIZE,
1995
285
                         false, rgi_twocc, GenericFormatCheck );
1996
285
}
1997
static int MlpInit( demux_t *p_demux )
1998
1999
184
{
2000
184
    demux_sys_t *p_sys = p_demux->p_sys;
2001
2002
184
    p_sys->i_packet_size = 4096;
2003
2004
184
    return VLC_SUCCESS;
2005
184
}
2006
2007
/*****************************************************************************
2008
 * Video
2009
 *****************************************************************************/
2010
static int VideoInit( demux_t *p_demux )
2011
0
{
2012
0
    demux_sys_t *p_sys = p_demux->p_sys;
2013
2014
0
    p_sys->i_packet_size = 4096;
2015
2016
0
    return VLC_SUCCESS;
2017
0
}