Coverage Report

Created: 2025-08-29 07:30

/src/vlc/modules/demux/mpeg/es.c
Line
Count
Source (jump to first uncovered line)
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
104
vlc_module_begin ()
63
52
    set_subcategory( SUBCAT_INPUT_DEMUX )
64
52
    set_description( N_("MPEG-I/II/4 / A52 / DTS / MLP audio" ) )
65
52
    set_shortname( N_("Audio ES") )
66
52
    set_capability( "demux", 155 )
67
104
    set_callbacks( OpenAudio, Close )
68
69
52
    add_shortcut( "mpga", "mp3",
70
52
                  "m4a", "mp4a", "aac",
71
52
                  "ac3", "a52",
72
52
                  "eac3",
73
52
                  "dts",
74
52
                  "mlp", "thd" )
75
76
52
    add_submodule()
77
52
    set_description( N_("MPEG-4 video" ) )
78
52
    set_capability( "demux", 7 )
79
104
    set_callbacks( OpenVideo, Close )
80
52
    add_float( "es-fps", 25, FPS_TEXT, FPS_LONGTEXT )
81
82
52
    add_shortcut( "m4v" )
83
52
    add_shortcut( "mp4v" )
84
52
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
1.59M
#define WAV_PROBE_SIZE (512*1024)
93
3.91k
#define BASE_PROBE_SIZE (8000)
94
22.7k
#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
/* Mpga specific */
131
469
#define XING_FIELD_STREAMFRAMES    (1 << 0)
132
469
#define XING_FIELD_STREAMBYTES     (1 << 1)
133
469
#define XING_FIELD_TOC             (1 << 2)
134
469
#define XING_FIELD_QUALITY         (1 << 3)
135
3.09k
#define XING_MIN_TAG_SIZE           42
136
210
#define XING_TOC_COUNTBYTES         100
137
#define XING_MAX_TAG_SIZE          (XING_MIN_TAG_SIZE + 4 + 4 + XING_TOC_COUNTBYTES + 4 + 2)
138
#define XING_SUB_ETE_NOK_OTAE       XING_MIN_TAG_SIZE
139
140
struct xing_info_s
141
{
142
    uint32_t i_frames;
143
    uint32_t i_bytes;
144
    uint32_t i_quality;
145
    vlc_fourcc_t infotag;
146
    vlc_fourcc_t encoder;
147
    uint8_t  rgi_toc[XING_TOC_COUNTBYTES];
148
    float f_peak_signal;
149
    float f_radio_replay_gain;
150
    float f_audiophile_replay_gain;
151
    enum
152
    {
153
        XING_MODE_UNKNOWN   = 0,
154
        XING_MODE_CBR       = 1,
155
        XING_MODE_ABR       = 2,
156
        XING_MODE_VBR1      = 3,
157
        XING_MODE_VBR2      = 4,
158
        XING_MODE_VBR3      = 5,
159
        XING_MODE_VBR4      = 6,
160
        XING_MODE_CBR_2PASS = 8,
161
        XING_MODE_ABR_2PASS = 9,
162
    } brmode;
163
    enum
164
    {
165
        XING_AUDIOMODE_UNKNOWN    = 0,
166
        XING_AUDIOMODE_DPL        = 1,
167
        XING_AUDIOMODE_DPL2       = 2,
168
        XING_AUDIOMODE_AMBISONICS = 3,
169
    } audiomode;
170
    uint8_t  bitrate_avg;
171
    uint16_t i_delay_samples;
172
    uint16_t i_padding_samples;
173
    uint32_t i_music_length;
174
};
175
176
static int ParseXing( const uint8_t *p_buf, size_t i_buf, struct xing_info_s *xing )
177
2.62k
{
178
2.62k
    if( i_buf < XING_MIN_TAG_SIZE )
179
243
        return VLC_EGENERIC;
180
181
2.38k
    vlc_fourcc_t infotag = VLC_FOURCC(p_buf[0], p_buf[1], p_buf[2], p_buf[3]);
182
183
    /* L3Enc VBR info */
184
2.38k
    if( infotag == VLC_FOURCC('V','B','R','I') )
185
231
    {
186
231
        if( GetWBE( &p_buf[4] ) != 0x0001 )
187
42
            return VLC_EGENERIC;
188
189
        xing->i_bytes = GetDWBE( &p_buf[10] );
189
189
        xing->i_frames = GetDWBE( &p_buf[14] );
190
189
        xing->infotag = infotag;
191
189
        return VLC_SUCCESS;
192
231
    }
193
    /* Xing VBR/CBR tags */
194
2.15k
    else if( infotag != VLC_FOURCC('X','i','n','g') &&
195
2.15k
             infotag != VLC_FOURCC('I','n','f','o') )
196
1.67k
    {
197
1.67k
        return VLC_EGENERIC;
198
1.67k
    }
199
200
475
    xing->infotag = infotag;
201
202
475
    const uint32_t i_flags = GetDWBE( &p_buf[4] );
203
    /* compute our variable struct size for early checks */
204
475
    const unsigned varsz[4] = { ((i_flags & 0x01) ? 4 : 0),
205
475
                                ((i_flags & 0x02) ? 4 : 0),
206
475
                                ((i_flags & 0x04) ? XING_TOC_COUNTBYTES : 0),
207
475
                                ((i_flags & 0x08) ? 4 : 0) };
208
475
    const unsigned i_varallsz = varsz[0] + varsz[1] + varsz[2] + varsz[3];
209
475
    const unsigned i_tag_total = XING_MIN_TAG_SIZE + i_varallsz;
210
211
475
    if( i_buf < i_tag_total )
212
6
        return VLC_EGENERIC;
213
214
469
    if( i_flags & XING_FIELD_STREAMFRAMES )
215
228
        xing->i_frames = GetDWBE( &p_buf[8] );
216
469
    if( i_flags & XING_FIELD_STREAMBYTES )
217
221
        xing->i_bytes = GetDWBE( &p_buf[8 + varsz[0]] );
218
469
    if( i_flags & XING_FIELD_TOC )
219
104
        memcpy( xing->rgi_toc, &p_buf[8 + varsz[0] + varsz[1]], XING_TOC_COUNTBYTES );
220
469
    if( i_flags & XING_FIELD_QUALITY )
221
144
        xing->i_quality = GetDWBE( &p_buf[8 + varsz[0] + varsz[1] + varsz[2]] );
222
223
    /* pointer past optional members */
224
469
    const uint8_t *p_fixed = &p_buf[8 + i_varallsz];
225
226
    /* Original Xing encoder header stops here */
227
228
469
    xing->encoder = VLC_FOURCC(p_fixed[0], p_fixed[1], p_fixed[2], p_fixed[3]); /* char version[9] start */
229
230
469
    if( xing->encoder != VLC_FOURCC('L','A','M','E') &&
231
469
        xing->encoder != VLC_FOURCC('L','a','v','c') &&
232
469
        xing->encoder != VLC_FOURCC('L','a','v','f') )
233
398
        return VLC_SUCCESS;
234
235
71
    xing->brmode  = p_fixed[9] & 0x0f; /* version upper / mode lower */
236
71
    uint32_t peak_signal  = GetDWBE( &p_fixed[11] );
237
71
    xing->f_peak_signal = peak_signal / 8388608.0; /* pow(2, 23) */
238
71
    uint16_t gain = GetWBE( &p_fixed[15] );
239
71
    xing->f_radio_replay_gain = (gain & 0x1FF) / /* 9bits val stored x10 */
240
71
                                ((gain & 0x200) ? -10.0 : 10.0); /* -sign bit on bit 6 */
241
71
    gain = GetWBE( &p_fixed[17] );
242
71
    xing->f_radio_replay_gain = (gain & 0x1FF) / /* 9bits val stored x10 */
243
71
                                ((gain & 0x200) ? -10.0 : 10.0); /* -sign bit on bit 6 */
244
    /* flags @19 */
245
71
    xing->bitrate_avg = (p_fixed[20] != 0xFF) ? p_fixed[20] : 0; /* clipped to 255, so it's unknown from there */
246
71
    xing->i_delay_samples = (p_fixed[21] << 4) | (p_fixed[22] >> 4); /* upper 12bits */
247
71
    xing->i_padding_samples = ((p_fixed[22] & 0x0F) << 8) | p_fixed[23]; /* lower 12bits */
248
71
    xing->audiomode = (p_fixed[26] >> 3) & 0x07; /* over 16bits, 2b unused / 3b mode / 11b preset */
249
71
    xing->i_music_length  = GetDWBE( &p_fixed[28] );
250
251
71
    return VLC_SUCCESS;
252
469
}
253
254
static int MpgaGetCBRSeekpoint( const struct mpga_frameheader_s *mpgah,
255
                                const struct xing_info_s *xing,
256
                                uint64_t i_seekablesize,
257
                                double f_pos, vlc_tick_t *pi_time, uint64_t *pi_offset )
258
0
{
259
0
    if( xing->infotag != 0 &&
260
0
        xing->infotag != VLC_FOURCC('I','n','f','o') &&
261
0
        xing->brmode != XING_MODE_CBR &&
262
0
        xing->brmode != XING_MODE_CBR_2PASS )
263
0
        return -1;
264
265
0
    if( !mpgah->i_sample_rate || !mpgah->i_samples_per_frame || !mpgah->i_frame_size )
266
0
        return -1;
267
268
0
    uint32_t i_total_frames = xing->i_frames ? xing->i_frames
269
0
                                             : i_seekablesize / mpgah->i_frame_size;
270
271
    /* xing must be optional here */
272
0
    uint32_t i_frame = i_total_frames * f_pos;
273
0
    *pi_offset = i_frame * mpgah->i_frame_size;
274
0
    *pi_time = vlc_tick_from_samples( i_frame * mpgah->i_samples_per_frame,
275
0
                                      mpgah->i_sample_rate ) + VLC_TICK_0;
276
277
0
    return 0;
278
0
}
279
280
static int SeekByPosUsingXingTOC( const struct mpga_frameheader_s *mpgah,
281
                                  const struct xing_info_s *xing,double pos,
282
                                  vlc_tick_t *pi_time, uint64_t *pi_offset )
283
0
{
284
0
    if( !xing->rgi_toc[XING_TOC_COUNTBYTES - 1] ||
285
0
        !mpgah->i_sample_rate || !mpgah->i_samples_per_frame )
286
0
        return -1;
287
288
0
    unsigned syncentry = pos * XING_TOC_COUNTBYTES;
289
0
    syncentry = VLC_CLIP(syncentry, 0, XING_TOC_COUNTBYTES - 1);
290
0
    unsigned syncframe = syncentry * xing->i_frames / XING_TOC_COUNTBYTES;
291
292
0
    *pi_time = vlc_tick_from_samples( syncframe * mpgah->i_samples_per_frame,
293
0
                                      mpgah->i_sample_rate ) + VLC_TICK_0;
294
0
    *pi_offset = xing->rgi_toc[syncentry] * xing->i_bytes / 256;
295
296
0
    return 0;
297
0
}
298
299
static int SeekByTimeUsingXingTOC( const struct mpga_frameheader_s *mpgah,
300
                                   const struct xing_info_s *xing,
301
                                   vlc_tick_t *pi_time, uint64_t *pi_offset )
302
0
{
303
0
    if( !mpgah->i_sample_rate || !mpgah->i_samples_per_frame || !xing->i_frames ||
304
0
        *pi_time < VLC_TICK_0 )
305
0
        return -1;
306
307
0
    uint32_t sample = samples_from_vlc_tick( *pi_time - VLC_TICK_0, mpgah->i_sample_rate );
308
0
    uint64_t totalsamples = mpgah->i_samples_per_frame * (uint64_t) xing->i_frames;
309
310
0
    return SeekByPosUsingXingTOC( mpgah, xing, (double)sample / totalsamples,
311
0
                                  pi_time, pi_offset );
312
0
}
313
314
static int MpgaSeek( const struct mpga_frameheader_s *mpgah,
315
                     const struct xing_info_s *xing,
316
                     uint64_t i_seekablesize, double f_pos,
317
                     vlc_tick_t *pi_time, uint64_t *pi_offset )
318
0
{
319
0
    if( f_pos >= 0 ) /* Set Pos */
320
0
    {
321
0
        if( !MpgaGetCBRSeekpoint( mpgah, xing, i_seekablesize,
322
0
                                  f_pos, pi_time, pi_offset ) )
323
0
        {
324
0
             return 0;
325
0
        }
326
0
    }
327
328
0
    if( *pi_time != VLC_TICK_INVALID &&
329
0
        !SeekByTimeUsingXingTOC( mpgah, xing, pi_time, pi_offset ) )
330
0
        return 0;
331
332
0
    return SeekByPosUsingXingTOC( mpgah, xing, f_pos, pi_time, pi_offset );
333
0
}
334
335
typedef struct
336
{
337
    codec_t codec;
338
    vlc_fourcc_t i_original;
339
340
    es_out_id_t *p_es;
341
342
    bool  b_start;
343
    decoder_t   *p_packetizer;
344
    block_t     *p_packetized_data;
345
346
    vlc_tick_t  i_pts;
347
    vlc_tick_t  i_time_offset;
348
    uint64_t    i_bytes;
349
350
    bool        b_big_endian;
351
    bool        b_estimate_bitrate;
352
    unsigned    i_bitrate;  /* extracted from Xing header */
353
    vlc_tick_t  i_duration;
354
355
    bool b_initial_sync_failed;
356
357
    unsigned i_packet_size;
358
359
    uint64_t i_stream_offset;
360
    unsigned i_demux_flags;
361
362
    float   f_fps;
363
364
    /* Mpga specific */
365
    struct mpga_frameheader_s mpgah;
366
    struct xing_info_s xing;
367
368
    audio_replay_gain_t audio_replay_gain;
369
370
    sync_table_t mllt;
371
    struct
372
    {
373
        size_t i_count;
374
        size_t i_current;
375
        chap_entry_t *p_entry;
376
    } chapters;
377
} demux_sys_t;
378
379
static int MpgaProbe( demux_t *p_demux, uint64_t *pi_offset );
380
static int MpgaInit( demux_t *p_demux );
381
382
static int AacProbe( demux_t *p_demux, uint64_t *pi_offset );
383
static int AacInit( demux_t *p_demux );
384
385
static int EA52Probe( demux_t *p_demux, uint64_t *pi_offset );
386
static int A52Probe( demux_t *p_demux, uint64_t *pi_offset );
387
static int A52Init( demux_t *p_demux );
388
389
static int DtsProbe( demux_t *p_demux, uint64_t *pi_offset );
390
static int DtsInit( demux_t *p_demux );
391
392
static int MlpProbe( demux_t *p_demux, uint64_t *pi_offset );
393
static int ThdProbe( demux_t *p_demux, uint64_t *pi_offset );
394
static int MlpInit( demux_t *p_demux );
395
396
static bool Parse( demux_t *p_demux, block_t **pp_output );
397
static int SeekByMlltTable( sync_table_t *, vlc_tick_t *, uint64_t * );
398
399
static const codec_t p_codecs[] = {
400
    { VLC_CODEC_MP4A, false, "mp4 audio",  AacProbe,  AacInit },
401
    { VLC_CODEC_MPGA, false, "mpeg audio", MpgaProbe, MpgaInit },
402
    { VLC_CODEC_A52, true,  "a52 audio",  A52Probe,  A52Init },
403
    { VLC_CODEC_EAC3, true,  "eac3 audio", EA52Probe, A52Init },
404
    { VLC_CODEC_DTS, false, "dts audio",  DtsProbe,  DtsInit },
405
    { VLC_CODEC_MLP, false, "mlp audio",  MlpProbe,  MlpInit },
406
    { VLC_CODEC_TRUEHD, false, "TrueHD audio",  ThdProbe,  MlpInit },
407
408
    { 0, false, NULL, NULL, NULL }
409
};
410
411
static int VideoInit( demux_t *p_demux );
412
413
static const codec_t codec_m4v = {
414
    VLC_CODEC_MP4V, false, "mp4 video", NULL,  VideoInit
415
};
416
417
/*****************************************************************************
418
 * OpenCommon: initializes demux structures
419
 *****************************************************************************/
420
static int OpenCommon( demux_t *p_demux,
421
                       int i_cat, const codec_t *p_codec, uint64_t i_bs_offset )
422
9.33k
{
423
9.33k
    demux_sys_t *p_sys;
424
425
9.33k
    es_format_t fmt;
426
427
9.33k
    DEMUX_INIT_COMMON(); p_sys = p_demux->p_sys;
428
9.33k
    memset( p_sys, 0, sizeof( demux_sys_t ) );
429
9.33k
    p_sys->codec = *p_codec;
430
9.33k
    p_sys->p_es = NULL;
431
9.33k
    p_sys->b_start = true;
432
9.33k
    p_sys->i_stream_offset = i_bs_offset;
433
9.33k
    p_sys->b_estimate_bitrate = true;
434
9.33k
    p_sys->i_bitrate = 0;
435
9.33k
    p_sys->i_duration = 0;
436
9.33k
    p_sys->b_big_endian = false;
437
9.33k
    p_sys->f_fps = var_InheritFloat( p_demux, "es-fps" );
438
9.33k
    p_sys->p_packetized_data = NULL;
439
9.33k
    p_sys->chapters.i_current = 0;
440
9.33k
    p_sys->xing.f_peak_signal = NAN;
441
9.33k
    p_sys->xing.f_radio_replay_gain = NAN;
442
9.33k
    p_sys->xing.f_audiophile_replay_gain = NAN;
443
9.33k
    TAB_INIT(p_sys->chapters.i_count, p_sys->chapters.p_entry);
444
445
9.33k
    if( vlc_stream_Seek( p_demux->s, p_sys->i_stream_offset ) )
446
0
    {
447
0
        free( p_sys );
448
0
        return VLC_EGENERIC;
449
0
    }
450
451
9.33k
    if( p_sys->codec.pf_init( p_demux ) )
452
0
    {
453
0
        free( p_sys );
454
0
        return VLC_EGENERIC;
455
0
    }
456
457
9.33k
    if( vlc_stream_Seek( p_demux->s, p_sys->i_stream_offset ) )
458
0
    {
459
0
        free( p_sys );
460
0
        return VLC_EGENERIC;
461
0
    }
462
463
9.33k
    msg_Dbg( p_demux, "detected format %4.4s", (const char*)&p_sys->codec.i_codec );
464
465
    /* Load the audio packetizer */
466
9.33k
    es_format_Init( &fmt, i_cat, p_sys->codec.i_codec );
467
9.33k
    fmt.i_original_fourcc = p_sys->i_original;
468
9.33k
    p_sys->p_packetizer = demux_PacketizerNew( VLC_OBJECT(p_demux), &fmt, p_sys->codec.psz_name );
469
9.33k
    if( !p_sys->p_packetizer )
470
0
    {
471
0
        free( p_sys );
472
0
        return VLC_EGENERIC;
473
0
    }
474
475
9.33k
    es_format_t *p_fmt = &p_sys->p_packetizer->fmt_out;
476
9.33k
    replay_gain_Merge( &p_fmt->audio_replay_gain, &p_sys->audio_replay_gain );
477
478
9.33k
    for( ;; )
479
77.4k
    {
480
77.4k
        if( Parse( p_demux, &p_sys->p_packetized_data ) )
481
5.07k
            break;
482
72.4k
        if( p_sys->p_packetized_data )
483
4.25k
            break;
484
72.4k
    }
485
486
9.33k
    return VLC_SUCCESS;
487
9.33k
}
488
static int OpenAudio( vlc_object_t *p_this )
489
10.3k
{
490
10.3k
    demux_t *p_demux = (demux_t*)p_this;
491
44.5k
    for( int i = 0; p_codecs[i].i_codec != 0; i++ )
492
43.5k
    {
493
43.5k
        uint64_t i_offset;
494
43.5k
        if( !p_codecs[i].pf_probe( p_demux, &i_offset ) )
495
9.33k
            return OpenCommon( p_demux, AUDIO_ES, &p_codecs[i], i_offset );
496
43.5k
    }
497
1.02k
    return VLC_EGENERIC;
498
10.3k
}
499
static int OpenVideo( vlc_object_t *p_this )
500
0
{
501
0
    demux_t *p_demux = (demux_t*)p_this;
502
503
    /* Only m4v is supported for the moment */
504
0
    bool b_m4v_ext    = demux_IsPathExtension( p_demux, ".m4v" );
505
0
    bool b_re4_ext    = !b_m4v_ext && demux_IsPathExtension( p_demux, ".re4" );
506
0
    bool b_m4v_forced = demux_IsForced( p_demux, "m4v" ) ||
507
0
                        demux_IsForced( p_demux, "mp4v" );
508
509
0
    if( !b_m4v_ext && !b_m4v_forced && !b_re4_ext )
510
0
        return VLC_EGENERIC;
511
512
0
    ssize_t i_off = b_re4_ext ? 220 : 0;
513
0
    const uint8_t *p_peek;
514
0
    if( vlc_stream_Peek( p_demux->s, &p_peek, i_off + 4 ) < i_off + 4 )
515
0
        return VLC_EGENERIC;
516
0
    if( p_peek[i_off + 0] != 0x00 || p_peek[i_off + 1] != 0x00 || p_peek[i_off + 2] != 0x01 )
517
0
    {
518
0
        if( !b_m4v_forced)
519
0
            return VLC_EGENERIC;
520
0
        msg_Warn( p_demux,
521
0
                  "this doesn't look like an MPEG ES stream, continuing anyway" );
522
0
    }
523
0
    return OpenCommon( p_demux, VIDEO_ES, &codec_m4v, i_off );
524
0
}
525
526
static void IncreaseChapter( demux_t *p_demux, vlc_tick_t i_time )
527
70.9k
{
528
70.9k
    demux_sys_t *p_sys = p_demux->p_sys;
529
70.9k
    while( p_sys->chapters.i_current + 1 < p_sys->chapters.i_count )
530
0
    {
531
0
        const chap_entry_t *p = &p_sys->chapters.p_entry[p_sys->chapters.i_current + 1];
532
0
        if( (p->i_offset != UINT32_MAX && vlc_stream_Tell( p_demux->s ) < p->i_offset) ||
533
0
            (i_time == VLC_TICK_INVALID || p->p_seekpoint->i_time_offset + VLC_TICK_0 > i_time) )
534
0
            break;
535
0
        ++p_sys->chapters.i_current;
536
0
        p_sys->i_demux_flags |= INPUT_UPDATE_SEEKPOINT;
537
0
    }
538
70.9k
}
539
540
/*****************************************************************************
541
 * Demux: reads and demuxes data packets
542
 *****************************************************************************
543
 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
544
 *****************************************************************************/
545
static int Demux( demux_t *p_demux )
546
70.9k
{
547
70.9k
    int ret = 1;
548
70.9k
    demux_sys_t *p_sys = p_demux->p_sys;
549
550
70.9k
    block_t *p_block_out = p_sys->p_packetized_data;
551
70.9k
    if( p_block_out )
552
5.37k
        p_sys->p_packetized_data = NULL;
553
65.5k
    else
554
65.5k
        ret = Parse( p_demux, &p_block_out ) ? 0 : 1;
555
556
    /* Update chapter if any */
557
70.9k
    IncreaseChapter( p_demux,
558
70.9k
                     p_block_out ? p_sys->i_time_offset + p_block_out->i_dts
559
70.9k
                                 : VLC_TICK_INVALID );
560
561
1.42M
    while( p_block_out )
562
1.35M
    {
563
1.35M
        block_t *p_next = p_block_out->p_next;
564
565
        /* Correct timestamp */
566
1.35M
        if( p_sys->p_packetizer->fmt_out.i_cat == VIDEO_ES )
567
0
        {
568
0
            if( p_block_out->i_pts == VLC_TICK_INVALID &&
569
0
                p_block_out->i_dts == VLC_TICK_INVALID )
570
0
                p_block_out->i_dts = VLC_TICK_0 + p_sys->i_pts + VLC_TICK_FROM_SEC(1) / p_sys->f_fps;
571
0
            if( p_block_out->i_dts != VLC_TICK_INVALID )
572
0
                p_sys->i_pts = p_block_out->i_dts - VLC_TICK_0;
573
0
        }
574
1.35M
        else
575
1.35M
        {
576
1.35M
            p_sys->i_pts = p_block_out->i_pts - VLC_TICK_0;
577
1.35M
        }
578
579
1.35M
        if( p_block_out->i_pts != VLC_TICK_INVALID )
580
1.34M
        {
581
1.34M
            p_block_out->i_pts += p_sys->i_time_offset;
582
1.34M
        }
583
1.35M
        if( p_block_out->i_dts != VLC_TICK_INVALID )
584
1.34M
        {
585
1.34M
            p_block_out->i_dts += p_sys->i_time_offset;
586
1.34M
            es_out_SetPCR( p_demux->out, p_block_out->i_dts );
587
1.34M
        }
588
        /* Re-estimate bitrate */
589
1.35M
        if( p_sys->b_estimate_bitrate && p_sys->i_pts > VLC_TICK_FROM_MS(500) )
590
1.29M
            p_sys->i_bitrate = 8 * CLOCK_FREQ * p_sys->i_bytes
591
1.29M
                                   / (p_sys->i_pts - 1);
592
1.35M
        p_sys->i_bytes += p_block_out->i_buffer;
593
594
595
1.35M
        p_block_out->p_next = NULL;
596
1.35M
        es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
597
598
1.35M
        p_block_out = p_next;
599
1.35M
    }
600
70.9k
    return ret;
601
70.9k
}
602
603
/*****************************************************************************
604
 * Close: frees unused data
605
 *****************************************************************************/
606
static void Close( vlc_object_t * p_this )
607
9.33k
{
608
9.33k
    demux_t     *p_demux = (demux_t*)p_this;
609
9.33k
    demux_sys_t *p_sys = p_demux->p_sys;
610
611
9.33k
    if( p_sys->p_packetized_data )
612
0
        block_ChainRelease( p_sys->p_packetized_data );
613
9.33k
    for( size_t i=0; i< p_sys->chapters.i_count; i++ )
614
0
        vlc_seekpoint_Delete( p_sys->chapters.p_entry[i].p_seekpoint );
615
9.33k
    TAB_CLEAN( p_sys->chapters.i_count, p_sys->chapters.p_entry );
616
9.33k
    if( p_sys->mllt.p_bits )
617
0
        free( p_sys->mllt.p_bits );
618
9.33k
    demux_PacketizerDestroy( p_sys->p_packetizer );
619
9.33k
    free( p_sys );
620
9.33k
}
621
622
/*****************************************************************************
623
 * Time seek:
624
 *****************************************************************************/
625
static void PostSeekCleanup( demux_sys_t *p_sys, vlc_tick_t i_time )
626
0
{
627
    /* Fix time_offset */
628
0
    if( i_time >= 0 )
629
0
        p_sys->i_time_offset = i_time - p_sys->i_pts;
630
    /* And reset buffered data */
631
0
    if( p_sys->p_packetized_data )
632
0
        block_ChainRelease( p_sys->p_packetized_data );
633
0
    p_sys->p_packetized_data = NULL;
634
    /* Reset chapter if any */
635
0
    p_sys->chapters.i_current = 0;
636
0
    p_sys->i_demux_flags |= INPUT_UPDATE_SEEKPOINT;
637
0
}
638
639
static int MovetoTimePos( demux_t *p_demux, vlc_tick_t i_time, uint64_t i_pos )
640
0
{
641
0
    demux_sys_t *p_sys  = p_demux->p_sys;
642
0
    int i_ret = vlc_stream_Seek( p_demux->s, p_sys->i_stream_offset + i_pos );
643
0
    if( i_ret != VLC_SUCCESS )
644
0
        return i_ret;
645
0
    PostSeekCleanup( p_sys, i_time );
646
0
    return VLC_SUCCESS;
647
0
}
648
649
/*****************************************************************************
650
 * Control:
651
 *****************************************************************************/
652
static int Control( demux_t *p_demux, int i_query, va_list args )
653
0
{
654
0
    demux_sys_t *p_sys  = p_demux->p_sys;
655
0
    bool *pb_bool;
656
657
0
    switch( i_query )
658
0
    {
659
0
        case DEMUX_HAS_UNSUPPORTED_META:
660
0
            pb_bool = va_arg( args, bool * );
661
0
            *pb_bool = true;
662
0
            return VLC_SUCCESS;
663
664
0
        case DEMUX_GET_TIME:
665
0
            *va_arg( args, vlc_tick_t * ) = p_sys->i_pts + p_sys->i_time_offset;
666
0
            return VLC_SUCCESS;
667
668
0
        case DEMUX_GET_LENGTH:
669
0
        {
670
0
            if( p_sys->i_duration > 0 )
671
0
            {
672
0
                *va_arg( args, vlc_tick_t * ) = p_sys->i_duration;
673
0
                return VLC_SUCCESS;
674
0
            }
675
            /* compute length from bitrate */
676
0
            va_list ap;
677
0
            int i_ret;
678
679
0
            va_copy ( ap, args );
680
0
            i_ret = demux_vaControlHelper( p_demux->s, p_sys->i_stream_offset,
681
0
                                    -1, p_sys->i_bitrate, 1, i_query, ap );
682
0
            va_end( ap );
683
684
            /* No bitrate, we can't have it precisely, but we can compute
685
             * a raw approximation with time/position */
686
0
            if( i_ret && !p_sys->i_bitrate )
687
0
            {
688
0
                float f_pos = (double)(uint64_t)( vlc_stream_Tell( p_demux->s ) ) /
689
0
                              (double)(uint64_t)( stream_Size( p_demux->s ) );
690
                /* The first few seconds are guaranteed to be very whacky,
691
                 * don't bother trying ... Too bad */
692
0
                if( f_pos < 0.01f ||
693
0
                    (p_sys->i_pts + p_sys->i_time_offset) < VLC_TICK_FROM_SEC(8) )
694
0
                {
695
0
                    return VLC_EGENERIC;
696
0
                }
697
698
0
                *va_arg( args, vlc_tick_t * ) =
699
0
                    (p_sys->i_pts + p_sys->i_time_offset) / f_pos;
700
0
                return VLC_SUCCESS;
701
0
            }
702
0
            return i_ret;
703
0
        }
704
705
0
        case DEMUX_SET_TIME:
706
0
        case DEMUX_SET_POSITION:
707
0
        {
708
0
            vlc_tick_t i_time;
709
0
            double f_pos;
710
0
            uint64_t i_offset;
711
712
0
            va_list ap;
713
0
            va_copy ( ap, args ); /* don't break args for helper fallback */
714
0
            if( i_query == DEMUX_SET_TIME )
715
0
            {
716
0
                i_time = va_arg(ap, vlc_tick_t);
717
0
                f_pos = p_sys->i_duration ? i_time / (double) p_sys->i_duration : -1.0;
718
0
                if( f_pos > 1.0 )
719
0
                    f_pos = 1.0;
720
0
            }
721
0
            else
722
0
            {
723
0
                f_pos = va_arg(ap, double);
724
0
                i_time = p_sys->i_duration ? p_sys->i_duration * f_pos : VLC_TICK_INVALID;
725
0
            }
726
0
            va_end( ap );
727
728
            /* Try to use ID3 table */
729
0
            if( !SeekByMlltTable( &p_sys->mllt, &i_time, &i_offset ) )
730
0
                return MovetoTimePos( p_demux, i_time, i_offset );
731
732
0
            if( p_sys->codec.i_codec == VLC_CODEC_MPGA )
733
0
            {
734
0
                uint64_t streamsize;
735
0
                if( !vlc_stream_GetSize( p_demux->s, &streamsize ) &&
736
0
                    streamsize > p_sys->i_stream_offset )
737
0
                    streamsize -= p_sys->i_stream_offset;
738
0
                else
739
0
                    streamsize = 0;
740
741
0
                if( !MpgaSeek( &p_sys->mpgah, &p_sys->xing,
742
0
                           streamsize, f_pos, &i_time, &i_offset ) )
743
0
                {
744
0
                    return MovetoTimePos( p_demux, i_time, i_offset );
745
0
                }
746
0
            }
747
748
            /* fallback on bitrate / file position seeking */
749
0
            i_time = VLC_TICK_INVALID;
750
0
            int ret = demux_vaControlHelper( p_demux->s, p_sys->i_stream_offset, -1,
751
0
                                             p_sys->i_bitrate, 1, i_query, args );
752
0
            if( ret != VLC_SUCCESS )
753
0
                return ret; /* not much we can do */
754
755
0
            if( p_sys->i_bitrate > 0 )
756
0
            {
757
0
                i_offset = vlc_stream_Tell( p_demux->s ); /* new pos */
758
0
                i_time = VLC_TICK_0;
759
0
                if( likely(i_offset > p_sys->i_stream_offset) )
760
0
                {
761
0
                    i_offset -= p_sys->i_stream_offset;
762
0
                    i_time += vlc_tick_from_samples( i_offset * 8, p_sys->i_bitrate );
763
0
                }
764
0
            }
765
0
            PostSeekCleanup( p_sys, i_time );
766
767
            /* FIXME TODO: implement a high precision seek (with mp3 parsing)
768
             * needed for multi-input */
769
0
            return VLC_SUCCESS;
770
0
        }
771
772
0
        case DEMUX_GET_TITLE_INFO:
773
0
        {
774
0
            if( p_sys->chapters.i_count == 0 )
775
0
                return VLC_EGENERIC;
776
0
            input_title_t **pp_title = malloc( sizeof(*pp_title) );
777
0
            if( !pp_title )
778
0
                return VLC_EGENERIC;
779
0
            *pp_title = vlc_input_title_New();
780
0
            if( !*pp_title )
781
0
            {
782
0
                free( pp_title );
783
0
                return VLC_EGENERIC;
784
0
            }
785
0
            (*pp_title)->seekpoint = vlc_alloc( p_sys->chapters.i_count, sizeof(seekpoint_t) );
786
0
            if( !(*pp_title)->seekpoint )
787
0
            {
788
0
                free( *pp_title );
789
0
                free( pp_title );
790
0
                return VLC_EGENERIC;
791
0
            }
792
0
            for( size_t i=0; i<p_sys->chapters.i_count; i++ )
793
0
            {
794
0
                seekpoint_t *s = vlc_seekpoint_Duplicate( p_sys->chapters.p_entry[i].p_seekpoint );
795
0
                if( s )
796
0
                    (*pp_title)->seekpoint[(*pp_title)->i_seekpoint++] = s;
797
0
            }
798
0
            *(va_arg( args, input_title_t *** )) = pp_title;
799
0
            *(va_arg( args, int* )) = 1;
800
0
            *(va_arg( args, int* )) = 0;
801
0
            *(va_arg( args, int* )) = 0;
802
0
            return VLC_SUCCESS;
803
0
        }
804
0
        break;
805
806
0
        case DEMUX_GET_TITLE:
807
0
            if( p_sys->chapters.i_count == 0 )
808
0
                return VLC_EGENERIC;
809
0
            *(va_arg( args, int* )) = 0;
810
0
            return VLC_SUCCESS;
811
812
0
        case DEMUX_GET_SEEKPOINT:
813
0
            if( p_sys->chapters.i_count == 0 )
814
0
                return VLC_EGENERIC;
815
0
            *(va_arg( args, int* )) = p_sys->chapters.i_current;
816
0
            return VLC_SUCCESS;
817
818
0
        case DEMUX_SET_TITLE:
819
0
            return va_arg( args, int) == 0 ? VLC_SUCCESS : VLC_EGENERIC;
820
821
0
        case DEMUX_SET_SEEKPOINT:
822
0
        {
823
0
            int i = va_arg( args, int );
824
0
            if( (size_t)i>=p_sys->chapters.i_count )
825
0
                return VLC_EGENERIC;
826
0
            const chap_entry_t *p = &p_sys->chapters.p_entry[i];
827
0
            if( p_sys->chapters.p_entry[i].i_offset == UINT32_MAX )
828
0
                return demux_Control( p_demux, DEMUX_SET_TIME, p->p_seekpoint->i_time_offset );
829
0
            int i_ret= MovetoTimePos( p_demux, p->p_seekpoint->i_time_offset, p->i_offset );
830
0
            if( i_ret == VLC_SUCCESS )
831
0
                p_sys->chapters.i_current = i;
832
0
            return i_ret;
833
0
        }
834
835
0
        case DEMUX_TEST_AND_CLEAR_FLAGS:
836
0
        {
837
0
            unsigned *restrict flags = va_arg( args, unsigned * );
838
0
            *flags &= p_sys->i_demux_flags;
839
0
            p_sys->i_demux_flags &= ~*flags;
840
0
            return VLC_SUCCESS;
841
0
        }
842
0
    }
843
844
0
    return demux_vaControlHelper( p_demux->s, p_sys->i_stream_offset, -1,
845
0
                                  p_sys->i_bitrate, 1, i_query, args );
846
0
}
847
848
/*****************************************************************************
849
 * Makes a link list of buffer of parsed data
850
 * Returns true if EOF
851
 *****************************************************************************/
852
static bool Parse( demux_t *p_demux, block_t **pp_output )
853
143k
{
854
143k
    demux_sys_t *p_sys = p_demux->p_sys;
855
143k
    block_t *p_block_in, *p_block_out;
856
857
143k
    *pp_output = NULL;
858
859
143k
    if( p_sys->codec.b_use_word )
860
61.0k
    {
861
        /* Make sure we are word aligned */
862
61.0k
        int64_t i_pos = vlc_stream_Tell( p_demux->s );
863
61.0k
        if( (i_pos & 1) && vlc_stream_Read( p_demux->s, NULL, 1 ) != 1 )
864
1.04k
            return true;
865
61.0k
    }
866
867
142k
    p_block_in = vlc_stream_Block( p_demux->s, p_sys->i_packet_size );
868
142k
    bool b_eof = p_block_in == NULL;
869
870
142k
    if( p_block_in )
871
128k
    {
872
128k
        if( p_sys->codec.b_use_word && !p_sys->b_big_endian && p_block_in->i_buffer > 0 )
873
20.4k
        {
874
            /* Convert to big endian */
875
20.4k
            block_t *old = p_block_in;
876
20.4k
            p_block_in = block_Alloc( p_block_in->i_buffer );
877
20.4k
            if( p_block_in )
878
20.4k
            {
879
20.4k
                block_CopyProperties( p_block_in, old );
880
20.4k
                swab( old->p_buffer, p_block_in->p_buffer, old->i_buffer );
881
20.4k
            }
882
20.4k
            block_Release( old );
883
20.4k
        }
884
885
128k
        if( p_block_in )
886
128k
        {
887
128k
            p_block_in->i_pts =
888
128k
            p_block_in->i_dts = (p_sys->b_start || p_sys->b_initial_sync_failed) ?
889
128k
                                 VLC_TICK_0 : VLC_TICK_INVALID;
890
128k
        }
891
128k
    }
892
142k
    p_sys->b_initial_sync_failed = p_sys->b_start; /* Only try to resync once */
893
894
142k
    decoder_t *p_packetizer = p_sys->p_packetizer;
895
1.49M
    while( ( p_block_out = p_packetizer->pf_packetize( p_packetizer, p_block_in ? &p_block_in : NULL ) ) )
896
1.35M
    {
897
1.35M
        p_sys->b_initial_sync_failed = false;
898
2.70M
        while( p_block_out )
899
1.35M
        {
900
1.35M
            if( !p_sys->p_es )
901
5.37k
            {
902
5.37k
                es_format_t fmt;
903
5.37k
                es_format_Init( &fmt, p_packetizer->fmt_out.i_cat, p_packetizer->fmt_out.i_codec );
904
5.37k
                es_format_Copy( &fmt, &p_packetizer->fmt_out );
905
906
5.37k
                switch( p_sys->xing.audiomode )
907
5.37k
                {
908
2
                    case XING_AUDIOMODE_AMBISONICS:
909
2
                        fmt.audio.channel_type = AUDIO_CHANNEL_TYPE_AMBISONICS;
910
2
                        break;
911
5.36k
                    default:
912
5.36k
                        break;
913
5.37k
                }
914
915
5.37k
                fmt.b_packetized = true;
916
5.37k
                fmt.i_id = 0;
917
5.37k
                p_sys->p_es = es_out_Add( p_demux->out, &fmt );
918
919
                /* Use the bitrate as initual value */
920
5.37k
                if( p_sys->b_estimate_bitrate )
921
5.23k
                    p_sys->i_bitrate = fmt.i_bitrate;
922
923
5.37k
                es_format_Clean( &fmt );
924
5.37k
            }
925
926
1.35M
            block_t *p_next = p_block_out->p_next;
927
1.35M
            p_block_out->p_next = NULL;
928
929
1.35M
            block_ChainLastAppend( &pp_output, p_block_out );
930
931
1.35M
            p_block_out = p_next;
932
1.35M
        }
933
1.35M
    }
934
935
142k
    if( p_sys->b_initial_sync_failed )
936
142k
        msg_Dbg( p_demux, "did not sync on first block" );
937
142k
    p_sys->b_start = false;
938
939
142k
    return b_eof;
940
142k
}
941
942
/* Check to apply to WAVE fmt header */
943
static int GenericFormatCheck( int i_format, const uint8_t *p_head )
944
11.2k
{
945
11.2k
    if ( i_format == WAVE_FORMAT_PCM )
946
8.44k
    {
947
8.44k
        if( GetWLE( p_head /* nChannels */ ) != 2 )
948
3.34k
            return VLC_EGENERIC;
949
5.10k
        if( GetDWLE( p_head + 2 /* nSamplesPerSec */ ) != 44100 )
950
690
            return VLC_EGENERIC;
951
5.10k
    }
952
7.23k
    return VLC_SUCCESS;
953
11.2k
}
954
955
/*****************************************************************************
956
 * Wav header skipper
957
 *****************************************************************************/
958
static int WavSkipHeader( demux_t *p_demux, uint64_t *pi_skip,
959
                          const uint16_t rgi_twocc[],
960
                          int (*pf_format_check)( int, const uint8_t * ) )
961
33.1k
{
962
33.1k
    const uint8_t *p_peek;
963
33.1k
    size_t i_peek = 0;
964
33.1k
    uint32_t i_len;
965
966
    /* */
967
33.1k
    *pi_skip = 0;
968
969
    /* Check if we are dealing with a WAV file */
970
33.1k
    if( vlc_stream_Peek( p_demux->s, &p_peek, 12+8 ) != 12 + 8 )
971
2.08k
        return VLC_SUCCESS;
972
973
31.0k
    if( memcmp( p_peek, "RIFF", 4 ) || memcmp( &p_peek[8], "WAVE", 4 ) )
974
10.4k
        return VLC_SUCCESS;
975
976
    /* Find the wave format header */
977
20.5k
    i_peek = 12 + 8;
978
404k
    while( memcmp( p_peek + i_peek - 8, "fmt ", 4 ) )
979
385k
    {
980
385k
        i_len = GetDWLE( p_peek + i_peek - 4 );
981
385k
        if( i_len > WAV_PROBE_SIZE || i_peek + i_len > WAV_PROBE_SIZE )
982
334
            return VLC_EGENERIC;
983
984
384k
        i_peek += i_len + 8;
985
384k
        if( vlc_stream_Peek( p_demux->s, &p_peek, i_peek ) != (ssize_t) i_peek )
986
608
            return VLC_EGENERIC;
987
384k
    }
988
989
    /* Sanity check the wave format header */
990
19.6k
    i_len = GetDWLE( p_peek + i_peek - 4 );
991
19.6k
    if( i_len > WAV_PROBE_SIZE )
992
208
        return VLC_EGENERIC;
993
994
19.4k
    i_peek += i_len + 8;
995
19.4k
    if( vlc_stream_Peek( p_demux->s, &p_peek, i_peek ) != (ssize_t) i_peek )
996
340
        return VLC_EGENERIC;
997
19.0k
    const uint16_t i_twocc = GetWLE( p_peek + i_peek - i_len - 8 /* wFormatTag */ );
998
19.0k
    int i_format_idx;
999
31.7k
    for( i_format_idx = 0; rgi_twocc[i_format_idx] != WAVE_FORMAT_UNKNOWN; i_format_idx++ )
1000
26.6k
    {
1001
26.6k
        if( i_twocc == rgi_twocc[i_format_idx] )
1002
13.9k
            break;
1003
26.6k
    }
1004
19.0k
    if( rgi_twocc[i_format_idx] == WAVE_FORMAT_UNKNOWN )
1005
5.12k
        return VLC_EGENERIC;
1006
1007
13.9k
    if( pf_format_check &&
1008
13.9k
        pf_format_check( i_twocc, p_peek + i_peek - i_len - 6 ) != VLC_SUCCESS )
1009
4.03k
            return VLC_EGENERIC;
1010
1011
    /* Skip the wave header */
1012
150k
    while( memcmp( p_peek + i_peek - 8, "data", 4 ) )
1013
141k
    {
1014
141k
        i_len = GetDWLE( p_peek + i_peek - 4 );
1015
141k
        if( i_len > WAV_PROBE_SIZE || i_peek + i_len > WAV_PROBE_SIZE )
1016
142
            return VLC_EGENERIC;
1017
1018
140k
        i_peek += i_len + 8;
1019
140k
        if( vlc_stream_Peek( p_demux->s, &p_peek, i_peek ) != (ssize_t) i_peek )
1020
137
            return VLC_EGENERIC;
1021
140k
    }
1022
9.64k
    *pi_skip = i_peek;
1023
9.64k
    return VLC_SUCCESS;
1024
9.92k
}
1025
1026
static int GenericProbe( demux_t *p_demux, uint64_t *pi_offset,
1027
                         const char * ppsz_name[],
1028
                         int (*pf_check)( const uint8_t *, unsigned * ),
1029
                         unsigned i_check_size,
1030
                         unsigned i_base_probing,
1031
                         unsigned i_wav_extra_probing,
1032
                         bool b_use_word,
1033
                         const uint16_t pi_twocc[],
1034
                         int (*pf_format_check)( int, const uint8_t * ) )
1035
22.7k
{
1036
22.7k
    bool   b_forced_demux;
1037
1038
22.7k
    uint64_t i_offset;
1039
22.7k
    const uint8_t *p_peek;
1040
22.7k
    uint64_t i_skip;
1041
1042
22.7k
    b_forced_demux = false;
1043
52.8k
    for( size_t i = 0; ppsz_name[i] != NULL; i++ )
1044
30.0k
    {
1045
30.0k
        b_forced_demux |= demux_IsForced( p_demux, ppsz_name[i] );
1046
30.0k
    }
1047
1048
22.7k
    i_offset = vlc_stream_Tell( p_demux->s );
1049
1050
22.7k
    if( WavSkipHeader( p_demux, &i_skip, pi_twocc, pf_format_check ) )
1051
6.38k
    {
1052
6.38k
        if( !b_forced_demux )
1053
5.97k
            return VLC_EGENERIC;
1054
6.38k
    }
1055
16.8k
    const bool b_wav = i_skip > 0;
1056
1057
    /* peek the beginning
1058
     * It is common that wav files have some sort of garbage at the beginning
1059
     * We will accept probing 0.5s of data in this case.
1060
     */
1061
16.8k
    const size_t i_probe = i_skip + i_check_size + i_base_probing + ( b_wav ? i_wav_extra_probing : 0);
1062
16.8k
    const ssize_t i_peek = vlc_stream_Peek( p_demux->s, &p_peek, i_probe );
1063
1064
16.8k
    if( i_peek < 0 || (size_t)i_peek < i_skip + i_check_size )
1065
458
        return VLC_EGENERIC;
1066
1067
16.3k
    for( ;; )
1068
41.4M
    {
1069
        /* i_peek > 0 so we can cast into size_t. */
1070
41.4M
        if( i_skip + i_check_size > (size_t)i_peek )
1071
7.18k
        {
1072
7.18k
            if( !b_forced_demux )
1073
6.35k
                return VLC_EGENERIC;
1074
824
            break;
1075
7.18k
        }
1076
41.4M
        unsigned i_samples = 0;
1077
41.4M
        int i_size = pf_check( &p_peek[i_skip], &i_samples );
1078
41.4M
        if( i_size >= 0 )
1079
59.5k
        {
1080
59.5k
            if( i_size == 0 || /* 0 sized frame ?? */
1081
59.5k
                i_skip == 0 /* exact match from start, we're not WAVE either, so skip multiple checks (would break if padding) */ )
1082
3.05k
                break;
1083
1084
            /* If we have the frame size, check the next frame for
1085
             * extra robustness
1086
             * The second test is because some .wav have paddings
1087
             */
1088
56.4k
            bool b_ok = false;
1089
157k
            for( int t = 0; t < 1 + !!b_wav; t++ )
1090
105k
            {
1091
105k
                if( t == 1 )
1092
49.4k
                {
1093
49.4k
                    if(!i_samples)
1094
2.93k
                        break;
1095
46.4k
                    i_size = i_samples * 2 * 2;
1096
46.4k
                }
1097
1098
102k
                if( i_skip + i_check_size + i_size <= (size_t)i_peek )
1099
76.9k
                {
1100
76.9k
                    b_ok = pf_check( &p_peek[i_skip+i_size], NULL ) >= 0;
1101
76.9k
                    if( b_ok )
1102
2.31k
                        break;
1103
76.9k
                }
1104
102k
            }
1105
56.4k
            if( b_ok )
1106
2.31k
                break;
1107
56.4k
        }
1108
41.4M
        if( b_use_word )
1109
20.1M
            i_skip += ((i_offset + i_skip) % 2 == 0) ? 2 : 1;
1110
21.2M
        else
1111
21.2M
            i_skip++;
1112
41.4M
        if( !b_wav && !b_forced_demux )
1113
3.81k
            return VLC_EGENERIC;
1114
41.4M
    }
1115
1116
6.19k
    *pi_offset = i_offset + i_skip;
1117
6.19k
    return VLC_SUCCESS;
1118
16.3k
}
1119
1120
/*****************************************************************************
1121
 * Mpeg I/II Audio
1122
 *****************************************************************************/
1123
static int MpgaCheckSync( const uint8_t *p_peek )
1124
167k
{
1125
167k
    uint32_t h = GetDWBE( p_peek );
1126
1127
167k
    if( ((( h >> 21 )&0x07FF) != 0x07FF )   /* header sync */
1128
167k
        || (((h >> 19)&0x03) == 1 )         /* valid version ID ? */
1129
167k
        || (((h >> 17)&0x03) == 0 )         /* valid layer ?*/
1130
167k
        || (((h >> 12)&0x0F) == 0x0F )      /* valid bitrate ?*/
1131
167k
        || (((h >> 10) & 0x03) == 0x03 )    /* valid sampling freq ? */
1132
167k
        || ((h & 0x03) == 0x02 ))           /* valid emphasis ? */
1133
162k
    {
1134
162k
        return false;
1135
162k
    }
1136
5.60k
    return true;
1137
167k
}
1138
1139
2.64k
#define MPGA_VERSION( h )   ( 1 - (((h)>>19)&0x01) )
1140
2.64k
#define MPGA_MODE(h)        (((h)>> 6)&0x03)
1141
1142
static int MpgaProbe( demux_t *p_demux, uint64_t *pi_offset )
1143
10.3k
{
1144
10.3k
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_MPEG, WAVE_FORMAT_MPEGLAYER3, WAVE_FORMAT_UNKNOWN };
1145
10.3k
    bool   b_forced;
1146
10.3k
    bool   b_forced_demux;
1147
10.3k
    uint64_t i_offset;
1148
1149
10.3k
    const uint8_t *p_peek;
1150
10.3k
    uint64_t i_skip;
1151
10.3k
    ssize_t i_peek;
1152
1153
10.3k
    b_forced = demux_IsPathExtension( p_demux, ".mp3" );
1154
10.3k
    b_forced_demux = demux_IsForced( p_demux, "mp3" ) ||
1155
10.3k
                     demux_IsForced( p_demux, "mpga" );
1156
1157
10.3k
    i_offset = vlc_stream_Tell( p_demux->s );
1158
1159
10.3k
    if( WavSkipHeader( p_demux, &i_skip, rgi_twocc, NULL ) )
1160
4.54k
    {
1161
4.54k
        if( !b_forced_demux )
1162
575
            return VLC_EGENERIC;
1163
1164
3.96k
        return VLC_EGENERIC;
1165
4.54k
    }
1166
1167
5.81k
    i_peek = vlc_stream_Peek( p_demux->s, &p_peek, i_skip + 4 );
1168
5.81k
    if( i_peek <= 0 || (uint64_t) i_peek < i_skip + 4 )
1169
11
        return VLC_EGENERIC;
1170
1171
5.80k
    if( !MpgaCheckSync( &p_peek[i_skip] ) )
1172
3.14k
    {
1173
3.14k
        bool b_ok = false;
1174
1175
3.14k
        if( !b_forced_demux && !b_forced )
1176
2.66k
            return VLC_EGENERIC;
1177
1178
483
        i_peek = vlc_stream_Peek( p_demux->s, &p_peek, i_skip + 8096 );
1179
159k
        while( i_peek > 0 && i_skip + 4 < (uint64_t) i_peek )
1180
159k
        {
1181
159k
            if( MpgaCheckSync( &p_peek[i_skip] ) )
1182
298
            {
1183
298
                b_ok = true;
1184
298
                break;
1185
298
            }
1186
159k
            i_skip++;
1187
159k
        }
1188
483
        if( !b_ok && !b_forced_demux )
1189
0
            return VLC_EGENERIC;
1190
483
    }
1191
3.14k
    *pi_offset = i_offset + i_skip;
1192
3.14k
    return VLC_SUCCESS;
1193
5.80k
}
1194
1195
static int SeekByMlltTable( sync_table_t *mllt, vlc_tick_t *pi_time, uint64_t *pi_offset )
1196
0
{
1197
0
    if( !mllt->p_bits )
1198
0
        return -1;
1199
1200
0
    sync_table_ctx_t *p_cur = &mllt->current;
1201
1202
    /* reset or init context */
1203
0
    if( *pi_time < p_cur->i_time || !p_cur->br.p )
1204
0
    {
1205
0
        p_cur->i_time = 0;
1206
0
        p_cur->i_pos = 0;
1207
0
        bs_init(&p_cur->br, mllt->p_bits, mllt->i_bits);
1208
0
    }
1209
1210
0
    while(!bs_eof(&p_cur->br))
1211
0
    {
1212
0
        const uint32_t i_bytesdev = bs_read(&p_cur->br, mllt->i_bits_per_bytes_dev);
1213
0
        const uint32_t i_msdev = bs_read(&p_cur->br, mllt->i_bits_per_ms_dev);
1214
0
        if(bs_error(&p_cur->br))
1215
0
            break;
1216
0
        const vlc_tick_t i_deltatime = VLC_TICK_FROM_MS(mllt->i_ms_btw_refs + i_msdev);
1217
0
        if( p_cur->i_time + i_deltatime > *pi_time )
1218
0
            break;
1219
0
        p_cur->i_time += i_deltatime;
1220
0
        p_cur->i_pos += mllt->i_bytes_btw_refs + i_bytesdev;
1221
0
    }
1222
0
    *pi_time = p_cur->i_time;
1223
0
    *pi_offset = p_cur->i_pos;
1224
1225
0
    return 0;
1226
0
}
1227
1228
static int ID3TAG_Parse_Handler( uint32_t i_tag, const uint8_t *p_payload, size_t i_payload, void *p_priv )
1229
0
{
1230
0
    demux_t *p_demux = (demux_t *) p_priv;
1231
0
    demux_sys_t *p_sys = p_demux->p_sys;
1232
1233
0
    if( i_tag == VLC_FOURCC('M', 'L', 'L', 'T') )
1234
0
    {
1235
0
        if( i_payload > 20 )
1236
0
        {
1237
0
            p_sys->mllt.i_frames_btw_refs = GetWBE(p_payload);
1238
0
            p_sys->mllt.i_bytes_btw_refs = GetDWBE(&p_payload[1]) & 0x00FFFFFF;
1239
0
            p_sys->mllt.i_ms_btw_refs = GetDWBE(&p_payload[4]) & 0x00FFFFFF;
1240
0
            if( !p_sys->mllt.i_frames_btw_refs || !p_sys->mllt.i_bytes_btw_refs ||
1241
0
                    !p_sys->mllt.i_ms_btw_refs ||
1242
0
                    p_payload[8] > 31 || p_payload[9] > 31 || /* bits length sanity check */
1243
0
                    ((p_payload[8] + p_payload[9]) % 4) || p_payload[8] + p_payload[9] < 4 )
1244
0
                return VLC_EGENERIC;
1245
0
            p_sys->mllt.i_bits_per_bytes_dev = p_payload[8];
1246
0
            p_sys->mllt.i_bits_per_ms_dev = p_payload[9];
1247
0
            p_sys->mllt.p_bits = malloc(i_payload - 10);
1248
0
            if( likely(p_sys->mllt.p_bits) )
1249
0
            {
1250
0
                p_sys->mllt.i_bits = i_payload - 10;
1251
0
                memcpy(p_sys->mllt.p_bits, &p_payload[10], p_sys->mllt.i_bits);
1252
0
                msg_Dbg(p_demux, "read MLLT sync table with %zu entries",
1253
0
                        (p_sys->mllt.i_bits * 8) / (p_sys->mllt.i_bits_per_bytes_dev + p_sys->mllt.i_bits_per_ms_dev) );
1254
0
            }
1255
0
        }
1256
0
        return VLC_EGENERIC;
1257
0
    }
1258
0
    else if( i_tag == VLC_FOURCC('T', 'X', 'X', 'X') )
1259
0
    {
1260
0
        vlc_meta_t *p_meta = vlc_meta_New();
1261
0
        if( p_meta )
1262
0
        {
1263
0
            bool b_updated;
1264
0
            if( ID3HandleTag( p_payload, i_payload, i_tag, p_meta, &b_updated ) )
1265
0
            {
1266
0
                vlc_replay_gain_CopyFromMeta( &p_sys->audio_replay_gain, p_meta );
1267
0
            }
1268
0
            vlc_meta_Delete( p_meta );
1269
0
        }
1270
0
    }
1271
0
    else if ( i_tag == VLC_FOURCC('C', 'H', 'A', 'P') && i_payload >= 17 )
1272
0
    {
1273
0
        char *psz_title = strndup( (const char *)p_payload, i_payload - 16 );
1274
0
        size_t i_offset = psz_title ? strlen( psz_title ) : 0;
1275
0
        if( p_payload[i_offset] != 0 )
1276
0
        {
1277
0
            free( psz_title );
1278
0
            return VLC_EGENERIC;
1279
0
        }
1280
0
        chap_entry_t e;
1281
0
        e.p_seekpoint = vlc_seekpoint_New();
1282
0
        if( e.p_seekpoint )
1283
0
        {
1284
0
            e.p_seekpoint->psz_name = psz_title;
1285
0
            e.p_seekpoint->i_time_offset = VLC_TICK_FROM_MS(GetDWBE(&p_payload[1 + i_offset]));
1286
0
            e.i_offset = GetDWBE(&p_payload[1 + i_offset + 8]);
1287
0
            p_payload += i_offset + 1 + 16;
1288
0
            i_payload -= i_offset + 1 + 16;
1289
0
            if( 12 < i_payload && !memcmp("TIT2", p_payload, 4) )
1290
0
            {
1291
0
                psz_title = NULL; /* optional alloc */
1292
0
                const char *psz = ID3TextConvert(&p_payload[10], i_payload-12, &psz_title);
1293
0
                if( psz ) /* replace with TIT2 */
1294
0
                {
1295
0
                    free( e.p_seekpoint->psz_name );
1296
0
                    e.p_seekpoint->psz_name = (psz_title) ? psz_title : strdup( psz );
1297
0
                }
1298
0
            }
1299
0
            TAB_APPEND(p_sys->chapters.i_count, p_sys->chapters.p_entry, e);
1300
0
        } else free( psz_title );
1301
0
    }
1302
1303
0
    return VLC_SUCCESS;
1304
0
}
1305
1306
static int ID3Parse( demux_t *p_demux,
1307
                     int (*pf_callback)(uint32_t, const uint8_t *, size_t, void *) )
1308
3.14k
{
1309
3.14k
    const block_t *p_tags = NULL;
1310
1311
3.14k
    if( vlc_stream_Control( p_demux->s, STREAM_GET_TAGS, &p_tags ) != VLC_SUCCESS )
1312
3.14k
        return VLC_EGENERIC;
1313
1314
0
    for( ; p_tags; p_tags = p_tags->p_next )
1315
0
        ID3TAG_Parse( p_tags->p_buffer, p_tags->i_buffer, pf_callback, (void *) p_demux );
1316
1317
0
    return VLC_SUCCESS;
1318
3.14k
}
1319
1320
static int MpgaInit( demux_t *p_demux )
1321
3.14k
{
1322
3.14k
    demux_sys_t *p_sys = p_demux->p_sys;
1323
1324
3.14k
    const uint8_t *p_peek;
1325
3.14k
    int i_peek;
1326
1327
    /* */
1328
3.14k
    p_sys->i_packet_size = 1024;
1329
1330
3.14k
    ID3Parse( p_demux, ID3TAG_Parse_Handler );
1331
1332
    /* Load a potential xing header */
1333
3.14k
    i_peek = vlc_stream_Peek( p_demux->s, &p_peek, 4 + 1024 );
1334
3.14k
    if( i_peek < 4 + 21 )
1335
484
        return VLC_SUCCESS;
1336
1337
2.65k
    const uint32_t header = GetDWBE( p_peek );
1338
2.65k
    if( !MpgaCheckSync( p_peek ) || mpga_decode_frameheader( header, &p_sys->mpgah ) )
1339
10
        return VLC_SUCCESS;
1340
1341
2.64k
    if( p_sys->mpgah.i_layer == 3 )
1342
1.33k
        p_sys->codec.i_codec = VLC_CODEC_MP3;
1343
1344
    /* Xing header */
1345
2.64k
    int i_skip;
1346
1347
2.64k
    if( MPGA_VERSION( header ) == 0 )
1348
1.07k
        i_skip = MPGA_MODE( header ) != 3 ? 36 : 21;
1349
1.57k
    else
1350
1.57k
        i_skip = MPGA_MODE( header ) != 3 ? 21 : 13;
1351
1352
2.64k
    if( i_skip >= i_peek )
1353
24
        return VLC_SUCCESS;
1354
1355
2.62k
    struct xing_info_s *xing = &p_sys->xing;
1356
2.62k
    if( ParseXing( &p_peek[i_skip], i_peek - i_skip, xing ) == VLC_SUCCESS )
1357
658
    {
1358
658
        const uint64_t i_total_samples = xing->i_frames * (uint64_t) p_sys->mpgah.i_samples_per_frame;
1359
658
        const uint64_t i_dropped_samples = xing->i_delay_samples + xing->i_padding_samples;
1360
1361
658
        if( p_sys->mpgah.i_sample_rate && i_dropped_samples < i_total_samples )
1362
411
        {
1363
411
            uint64_t i_stream_size;
1364
            /* We only set duration if we can't check (then compute it using bitrate/size)
1365
               or if we verified the file isn't truncated */
1366
411
            if( xing->i_bytes == 0 ||
1367
411
                vlc_stream_GetSize( p_demux->s, &i_stream_size ) ||
1368
411
               (i_stream_size >= xing->i_bytes &&
1369
382
                i_stream_size <= xing->i_bytes + p_sys->mpgah.i_frame_size) )
1370
45
            {
1371
45
                p_sys->i_duration = vlc_tick_from_samples( i_total_samples - i_dropped_samples,
1372
45
                                                           p_sys->mpgah.i_sample_rate );
1373
45
            }
1374
411
        }
1375
1376
658
        unsigned i_bitrate = 0;
1377
658
        if( xing->brmode == XING_MODE_ABR || xing->brmode == XING_MODE_ABR_2PASS )
1378
28
            i_bitrate = xing->bitrate_avg * 1000;
1379
1380
658
        if( !i_bitrate && p_sys->mpgah.i_sample_rate &&
1381
658
            xing->i_bytes > p_sys->mpgah.i_frame_size )
1382
361
        {
1383
361
            unsigned d = vlc_tick_from_samples( i_total_samples, p_sys->mpgah.i_sample_rate );
1384
361
            if( d )
1385
346
                i_bitrate = (xing->i_bytes - p_sys->mpgah.i_frame_size) * 8 * CLOCK_FREQ / d;
1386
361
        }
1387
1388
658
        if( i_bitrate )
1389
301
        {
1390
301
            p_sys->i_bitrate = i_bitrate;
1391
301
            p_sys->b_estimate_bitrate = false;
1392
301
        }
1393
1394
658
        if( isfinite(xing->f_radio_replay_gain) )
1395
71
        {
1396
71
            p_sys->audio_replay_gain.pb_gain[AUDIO_REPLAY_GAIN_TRACK] = true;
1397
71
            p_sys->audio_replay_gain.pf_gain[AUDIO_REPLAY_GAIN_TRACK] = xing->f_radio_replay_gain;
1398
71
        }
1399
1400
658
        if( isfinite(xing->f_peak_signal) )
1401
71
        {
1402
71
            p_sys->audio_replay_gain.pb_peak[AUDIO_REPLAY_GAIN_TRACK] = true;
1403
71
            p_sys->audio_replay_gain.pf_peak[AUDIO_REPLAY_GAIN_TRACK] = xing->f_peak_signal;
1404
71
        }
1405
1406
658
        if( isfinite(xing->f_audiophile_replay_gain) )
1407
0
        {
1408
0
            p_sys->audio_replay_gain.pb_gain[AUDIO_REPLAY_GAIN_ALBUM] = true;
1409
0
            p_sys->audio_replay_gain.pf_gain[AUDIO_REPLAY_GAIN_ALBUM] = xing->f_audiophile_replay_gain;
1410
0
        }
1411
1412
658
        msg_Dbg( p_demux, "Using '%4.4s' infotag"
1413
658
                          "(%"PRIu32" bytes, %"PRIu32" frames, %u samples/frame)",
1414
658
                          (char *) &xing->infotag,
1415
658
                          xing->i_bytes, xing->i_frames,
1416
658
                          p_sys->mpgah.i_samples_per_frame );
1417
1418
        /* We'll need to skip that part for playback
1419
         * and avoid using it as container frame could be different rate/size */
1420
658
        p_sys->i_stream_offset += p_sys->mpgah.i_frame_size;
1421
658
    }
1422
1423
2.62k
    return VLC_SUCCESS;
1424
2.64k
}
1425
1426
/*****************************************************************************
1427
 * AAC
1428
 *****************************************************************************/
1429
static int AacProbe( demux_t *p_demux, uint64_t *pi_offset )
1430
10.3k
{
1431
10.3k
    bool   b_forced;
1432
10.3k
    bool   b_forced_demux;
1433
1434
10.3k
    uint64_t i_offset;
1435
10.3k
    const uint8_t *p_peek;
1436
1437
10.3k
    b_forced = demux_IsPathExtension( p_demux, ".aac" ) ||
1438
10.3k
               demux_IsPathExtension( p_demux, ".aacp" );
1439
10.3k
    b_forced_demux = demux_IsForced( p_demux, "m4a" ) ||
1440
10.3k
                     demux_IsForced( p_demux, "aac" ) ||
1441
10.3k
                     demux_IsForced( p_demux, "mp4a" );
1442
1443
10.3k
    if( !b_forced_demux && !b_forced )
1444
10.3k
        return VLC_EGENERIC;
1445
1446
0
    i_offset = vlc_stream_Tell( p_demux->s );
1447
1448
    /* peek the beginning (10 is for adts header) */
1449
0
    if( vlc_stream_Peek( p_demux->s, &p_peek, 10 ) < 10 )
1450
0
        return VLC_EGENERIC;
1451
1452
0
    if( !strncmp( (char *)p_peek, "ADIF", 4 ) )
1453
0
    {
1454
0
        msg_Err( p_demux, "ADIF file. Not yet supported. (Please report)" );
1455
0
        return VLC_EGENERIC;
1456
0
    }
1457
1458
0
    *pi_offset = i_offset;
1459
0
    return VLC_SUCCESS;
1460
0
}
1461
static int AacInit( demux_t *p_demux )
1462
0
{
1463
0
    demux_sys_t *p_sys = p_demux->p_sys;
1464
1465
0
    p_sys->i_packet_size = 4096;
1466
0
    p_sys->i_original = VLC_FOURCC('H','E','A','D');
1467
1468
0
    return VLC_SUCCESS;
1469
0
}
1470
1471
1472
/*****************************************************************************
1473
 * A52
1474
 *****************************************************************************/
1475
static int A52CheckSync( const uint8_t *p_peek, bool *p_big_endian, unsigned *pi_samples, bool b_eac3 )
1476
20.2M
{
1477
20.2M
    vlc_a52_header_t header;
1478
20.2M
    uint8_t p_tmp[VLC_A52_MIN_HEADER_SIZE];
1479
1480
20.2M
    *p_big_endian =  p_peek[0] == 0x0b && p_peek[1] == 0x77;
1481
20.2M
    if( !*p_big_endian )
1482
20.0M
    {
1483
20.0M
        swab( p_peek, p_tmp, VLC_A52_MIN_HEADER_SIZE );
1484
20.0M
        p_peek = p_tmp;
1485
20.0M
    }
1486
1487
20.2M
    if( vlc_a52_header_Parse( &header, p_peek, VLC_A52_MIN_HEADER_SIZE ) )
1488
19.7M
        return VLC_EGENERIC;
1489
1490
450k
    if( !header.b_eac3 != !b_eac3 )
1491
402k
        return VLC_EGENERIC;
1492
47.9k
    if( pi_samples )
1493
44.9k
        *pi_samples = header.i_samples;
1494
47.9k
    return header.i_size;
1495
450k
}
1496
static int EA52CheckSyncProbe( const uint8_t *p_peek, unsigned *pi_samples )
1497
7.41M
{
1498
7.41M
    bool b_dummy;
1499
7.41M
    return A52CheckSync( p_peek, &b_dummy, pi_samples, true );
1500
7.41M
}
1501
1502
static int EA52Probe( demux_t *p_demux, uint64_t *pi_offset )
1503
6.75k
{
1504
6.75k
    const char *ppsz_name[] = { "eac3", NULL };
1505
6.75k
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_A52, WAVE_FORMAT_UNKNOWN };
1506
1507
6.75k
    return GenericProbe( p_demux, pi_offset, ppsz_name, EA52CheckSyncProbe,
1508
6.75k
                         VLC_A52_MIN_HEADER_SIZE,
1509
6.75k
                         1920 + VLC_A52_MIN_HEADER_SIZE + 1,
1510
6.75k
                         WAV_EXTRA_PROBE_SIZE,
1511
6.75k
                         true, rgi_twocc, GenericFormatCheck );
1512
6.75k
}
1513
1514
static int A52CheckSyncProbe( const uint8_t *p_peek, unsigned *pi_samples )
1515
12.8M
{
1516
12.8M
    bool b_dummy;
1517
12.8M
    return A52CheckSync( p_peek, &b_dummy, pi_samples, false );
1518
12.8M
}
1519
1520
static int A52Probe( demux_t *p_demux, uint64_t *pi_offset )
1521
7.21k
{
1522
7.21k
    const char *ppsz_name[] = { "a52", "ac3", NULL };
1523
7.21k
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_A52, WAVE_FORMAT_UNKNOWN };
1524
1525
7.21k
    return GenericProbe( p_demux, pi_offset, ppsz_name, A52CheckSyncProbe,
1526
7.21k
                         VLC_A52_MIN_HEADER_SIZE,
1527
7.21k
                         1920 + VLC_A52_MIN_HEADER_SIZE + 1,
1528
7.21k
                         WAV_EXTRA_PROBE_SIZE,
1529
7.21k
                         true, rgi_twocc, GenericFormatCheck );
1530
7.21k
}
1531
1532
static int A52Init( demux_t *p_demux )
1533
2.30k
{
1534
2.30k
    demux_sys_t *p_sys = p_demux->p_sys;
1535
1536
2.30k
    p_sys->b_big_endian = false;
1537
2.30k
    p_sys->i_packet_size = 1024;
1538
1539
2.30k
    const uint8_t *p_peek;
1540
1541
    /* peek the beginning */
1542
2.30k
    if( vlc_stream_Peek( p_demux->s, &p_peek, VLC_A52_MIN_HEADER_SIZE ) >= VLC_A52_MIN_HEADER_SIZE )
1543
2.30k
    {
1544
2.30k
        A52CheckSync( p_peek, &p_sys->b_big_endian, NULL, true );
1545
2.30k
    }
1546
2.30k
    return VLC_SUCCESS;
1547
2.30k
}
1548
1549
/*****************************************************************************
1550
 * DTS
1551
 *****************************************************************************/
1552
static int DtsCheckSync( const uint8_t *p_peek, unsigned *pi_samples )
1553
12.9M
{
1554
12.9M
    VLC_UNUSED(pi_samples);
1555
1556
12.9M
    vlc_dts_header_t dts;
1557
12.9M
    if( vlc_dts_header_Parse( &dts, p_peek, VLC_DTS_HEADER_SIZE ) == VLC_SUCCESS
1558
12.9M
     && dts.i_frame_size > 0 && dts.i_frame_size <= 8192 )
1559
14.7k
    {
1560
14.7k
        if( pi_samples )
1561
13.6k
            *pi_samples = dts.i_frame_length;
1562
14.7k
        return dts.i_frame_size;
1563
14.7k
    }
1564
12.8M
    else
1565
12.8M
        return VLC_EGENERIC;
1566
12.9M
}
1567
1568
static int DtsProbe( demux_t *p_demux, uint64_t *pi_offset )
1569
4.91k
{
1570
4.91k
    const char *ppsz_name[] = { "dts", NULL };
1571
4.91k
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_DTSINC_DTS, WAVE_FORMAT_UNKNOWN };
1572
1573
4.91k
    return GenericProbe( p_demux, pi_offset, ppsz_name, DtsCheckSync,
1574
4.91k
                         VLC_DTS_HEADER_SIZE,
1575
4.91k
                         16384 + VLC_DTS_HEADER_SIZE + 1,
1576
4.91k
                         WAV_EXTRA_PROBE_SIZE,
1577
4.91k
                         false, rgi_twocc, NULL );
1578
4.91k
}
1579
static int DtsInit( demux_t *p_demux )
1580
2.92k
{
1581
2.92k
    demux_sys_t *p_sys = p_demux->p_sys;
1582
1583
2.92k
    p_sys->i_packet_size = 16384;
1584
1585
2.92k
    return VLC_SUCCESS;
1586
2.92k
}
1587
1588
/*****************************************************************************
1589
 * MLP
1590
 *****************************************************************************/
1591
static int MlpCheckSync( const uint8_t *p_peek, unsigned *pi_samples )
1592
8.33M
{
1593
8.33M
    if( p_peek[4+0] != 0xf8 || p_peek[4+1] != 0x72 || p_peek[4+2] != 0x6f )
1594
8.17M
        return -1;
1595
1596
164k
    if( p_peek[4+3] != 0xbb )
1597
163k
        return -1;
1598
1599
    /* TODO checksum and real size for robustness */
1600
69
    VLC_UNUSED(pi_samples);
1601
69
    return 0;
1602
164k
}
1603
static int ThdCheckSync( const uint8_t *p_peek, unsigned *pi_samples )
1604
65.2k
{
1605
65.2k
    if( p_peek[4+0] != 0xf8 || p_peek[4+1] != 0x72 || p_peek[4+2] != 0x6f )
1606
64.0k
        return -1;
1607
1608
1.12k
    if( p_peek[4+3] != 0xba )
1609
226
        return -1;
1610
1611
    /* TODO checksum and real size for robustness */
1612
896
    VLC_UNUSED(pi_samples);
1613
896
    return 0;
1614
1.12k
}
1615
static int MlpProbe( demux_t *p_demux, uint64_t *pi_offset )
1616
1.99k
{
1617
1.99k
    const char *ppsz_name[] = { "mlp", NULL };
1618
1.99k
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_UNKNOWN };
1619
1620
1.99k
    return GenericProbe( p_demux, pi_offset, ppsz_name, MlpCheckSync,
1621
1.99k
                         4+28+16*4, BASE_PROBE_SIZE, WAV_EXTRA_PROBE_SIZE,
1622
1.99k
                         false, rgi_twocc, GenericFormatCheck );
1623
1.99k
}
1624
static int ThdProbe( demux_t *p_demux, uint64_t *pi_offset )
1625
1.92k
{
1626
1.92k
    const char *ppsz_name[] = { "thd", NULL };
1627
1.92k
    const uint16_t rgi_twocc[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_UNKNOWN };
1628
1629
1.92k
    return GenericProbe( p_demux, pi_offset, ppsz_name, ThdCheckSync,
1630
1.92k
                         4+28+16*4, BASE_PROBE_SIZE, WAV_EXTRA_PROBE_SIZE,
1631
1.92k
                         false, rgi_twocc, GenericFormatCheck );
1632
1.92k
}
1633
static int MlpInit( demux_t *p_demux )
1634
1635
965
{
1636
965
    demux_sys_t *p_sys = p_demux->p_sys;
1637
1638
965
    p_sys->i_packet_size = 4096;
1639
1640
965
    return VLC_SUCCESS;
1641
965
}
1642
1643
/*****************************************************************************
1644
 * Video
1645
 *****************************************************************************/
1646
static int VideoInit( demux_t *p_demux )
1647
0
{
1648
0
    demux_sys_t *p_sys = p_demux->p_sys;
1649
1650
0
    p_sys->i_packet_size = 4096;
1651
1652
0
    return VLC_SUCCESS;
1653
0
}