es.c 29.6 KB
Newer Older
1
/*****************************************************************************
2
 * es.c : Generic audio ES input module for vlc
3
 *****************************************************************************
4
 * Copyright (C) 2001-2008 the VideoLAN team
5
 * $Id$
6
7
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8
 *          Gildas Bazin <gbazin@videolan.org>
9
10
11
12
13
14
15
16
17
18
19
20
21
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
dionoea's avatar
dionoea committed
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23
24
25
26
27
28
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/

29
30
31
32
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

33
#include <vlc_common.h>
34
#include <vlc_plugin.h>
zorglub's avatar
zorglub committed
35
36
#include <vlc_demux.h>
#include <vlc_codec.h>
37
#include <vlc_codecs.h>
Laurent Aimar's avatar
Laurent Aimar committed
38
#include <vlc_input.h>
zorglub's avatar
zorglub committed
39

40
41
#include "../../codec/a52.h"

42
43
44
/*****************************************************************************
 * Module descriptor
 *****************************************************************************/
45
static int  OpenAudio( vlc_object_t * );
46
static int  OpenVideo( vlc_object_t * );
47
static void Close    ( vlc_object_t * );
48

49
50
51
52
#define FPS_TEXT N_("Frames per Second")
#define FPS_LONGTEXT N_("This is the frame rate used as a fallback when " \
    "playing MPEG video elementary streams.")

53
54
55
vlc_module_begin ()
    set_category( CAT_INPUT )
    set_subcategory( SUBCAT_INPUT_DEMUX )
56
    set_description( N_("MPEG-I/II/4 / A52 / DTS / MLP audio" ) )
57
    set_capability( "demux", 155 )
58
    set_callbacks( OpenAudio, Close )
59

60
61
62
63
64
65
    add_shortcut( "mpga", "mp3",
                  "m4a", "mp4a", "aac",
                  "ac3", "a52",
                  "eac3",
                  "dts",
                  "mlp", "thd" )
66
67
68
69
70

    add_submodule()
    set_description( N_("MPEG-4 video" ) )
    set_capability( "demux", 0 )
    set_callbacks( OpenVideo, Close )
71
    add_float( "es-fps", 25, FPS_TEXT, FPS_LONGTEXT, false )
72
73
74

    add_shortcut( "m4v" )
    add_shortcut( "mp4v" )
75
vlc_module_end ()
76
77
78
79

/*****************************************************************************
 * Local prototypes
 *****************************************************************************/
Laurent Aimar's avatar
Laurent Aimar committed
80
81
static int Demux  ( demux_t * );
static int Control( demux_t *, int, va_list );
82

83
84
85
typedef struct
{
    vlc_fourcc_t i_codec;
86
    bool       b_use_word;
87
88
89
90
91
    const char *psz_name;
    int  (*pf_probe)( demux_t *p_demux, int64_t *pi_offset );
    int  (*pf_init)( demux_t *p_demux );
} codec_t;

92
93
struct demux_sys_t
{
94
95
    codec_t codec;

96
    es_out_id_t *p_es;
97

98
    bool  b_start;
99
    decoder_t   *p_packetizer;
100

101
102
    mtime_t     i_pts;
    mtime_t     i_time_offset;
103
    int64_t     i_bytes;
104

105
    bool        b_big_endian;
106
    bool        b_estimate_bitrate;
107
    int         i_bitrate_avg;  /* extracted from Xing header */
zorglub's avatar
zorglub committed
108

109
    bool b_initial_sync_failed;
110

111
    int i_packet_size;
112

113
114
    int64_t i_stream_offset;

115
116
    float   f_fps;

117
118
    /* Mpga specific */
    struct
119
    {
120
121
122
123
124
125
        int i_frames;
        int i_bytes;
        int i_bitrate_avg;
        int i_frame_samples;
    } xing;
};
126

127
128
static int MpgaProbe( demux_t *p_demux, int64_t *pi_offset );
static int MpgaInit( demux_t *p_demux );
129

130
131
132
static int AacProbe( demux_t *p_demux, int64_t *pi_offset );
static int AacInit( demux_t *p_demux );

133
static int EA52Probe( demux_t *p_demux, int64_t *pi_offset );
134
135
136
static int A52Probe( demux_t *p_demux, int64_t *pi_offset );
static int A52Init( demux_t *p_demux );

137
138
139
static int DtsProbe( demux_t *p_demux, int64_t *pi_offset );
static int DtsInit( demux_t *p_demux );

140
141
142
static int MlpProbe( demux_t *p_demux, int64_t *pi_offset );
static int MlpInit( demux_t *p_demux );

143
static const codec_t p_codecs[] = {
144
145
146
147
148
    { VLC_CODEC_MP4A, false, "mp4 audio",  AacProbe,  AacInit },
    { VLC_CODEC_MPGA, false, "mpeg audio", MpgaProbe, MpgaInit },
    { VLC_CODEC_A52, true,  "a52 audio",  A52Probe,  A52Init },
    { VLC_CODEC_EAC3, true,  "eac3 audio", EA52Probe, A52Init },
    { VLC_CODEC_DTS, false, "dts audio",  DtsProbe,  DtsInit },
149
    { VLC_CODEC_TRUEHD, false, "mlp audio",  MlpProbe,  MlpInit },
150

151
    { 0, false, NULL, NULL, NULL }
152
153
};

154
155
156
157
158
159
static int VideoInit( demux_t *p_demux );

static const codec_t codec_m4v = {
    VLC_CODEC_MP4V, false, "mp4 video", NULL,  VideoInit
};

160
/*****************************************************************************
161
 * OpenCommon: initializes demux structures
162
 *****************************************************************************/
163
164
static int OpenCommon( demux_t *p_demux,
                       int i_cat, const codec_t *p_codec, int64_t i_bs_offset )
165
{
Laurent Aimar's avatar
Laurent Aimar committed
166
    demux_sys_t *p_sys;
167

168
    es_format_t fmt;
169

170
    DEMUX_INIT_COMMON(); p_sys = p_demux->p_sys;
171
    memset( p_sys, 0, sizeof( demux_sys_t ) );
172
    p_sys->codec = *p_codec;
173
    p_sys->p_es = NULL;
174
    p_sys->b_start = true;
175
    p_sys->i_stream_offset = i_bs_offset;
176
    p_sys->b_estimate_bitrate = true;
177
    p_sys->i_bitrate_avg = 0;
178
    p_sys->b_big_endian = false;
179
    p_sys->f_fps = var_InheritFloat( p_demux, "es-fps" );
180

181
    if( stream_Seek( p_demux->s, p_sys->i_stream_offset ) )
182
    {
183
184
        free( p_sys );
        return VLC_EGENERIC;
185
186
    }

187
    if( p_sys->codec.pf_init( p_demux ) )
188
    {
189
190
        free( p_sys );
        return VLC_EGENERIC;
191
192
    }

193
194
    msg_Dbg( p_demux, "detected format %4.4s", (const char*)&p_sys->codec.i_codec );

195
    /* Load the audio packetizer */
196
    es_format_Init( &fmt, i_cat, p_sys->codec.i_codec );
197
    p_sys->p_packetizer = demux_PacketizerNew( p_demux, &fmt, p_sys->codec.psz_name );
198
199
200
201
202
    if( !p_sys->p_packetizer )
    {
        free( p_sys );
        return VLC_EGENERIC;
    }
Laurent Aimar's avatar
Laurent Aimar committed
203
    return VLC_SUCCESS;
204
}
205
206
207
208
209
210
211
212
213
214
215
static int OpenAudio( vlc_object_t *p_this )
{
    demux_t *p_demux = (demux_t*)p_this;
    for( int i = 0; p_codecs[i].i_codec != 0; i++ )
    {
        int64_t i_offset;
        if( !p_codecs[i].pf_probe( p_demux, &i_offset ) )
            return OpenCommon( p_demux, AUDIO_ES, &p_codecs[i], i_offset );
    }
    return VLC_EGENERIC;
}
216
217
218
219
220
221
222
223
224
225
static int OpenVideo( vlc_object_t *p_this )
{
    demux_t *p_demux = (demux_t*)p_this;

    /* Only m4v is supported for the moment */
    bool b_m4v_ext    = demux_IsPathExtension( p_demux, ".m4v" );
    bool b_m4v_forced = demux_IsForced( p_demux, "m4v" ) ||
                        demux_IsForced( p_demux, "mp4v" );
    if( !b_m4v_ext && !b_m4v_forced )
        return VLC_EGENERIC;
226

227
228
229
230
231
232
233
234
235
236
237
238
    const uint8_t *p_peek;
    if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 )
        return VLC_EGENERIC;
    if( p_peek[0] != 0x00 || p_peek[1] != 0x00 || p_peek[2] != 0x01 )
    {
        if( !b_m4v_forced)
            return VLC_EGENERIC;
        msg_Warn( p_demux,
                  "this doesn't look like an MPEG ES stream, continuing anyway" );
    }
    return OpenCommon( p_demux, VIDEO_ES, &codec_m4v, 0 );
}
239
240
241
242
243
/*****************************************************************************
 * Demux: reads and demuxes data packets
 *****************************************************************************
 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
 *****************************************************************************/
Laurent Aimar's avatar
Laurent Aimar committed
244
static int Demux( demux_t *p_demux )
245
{
Laurent Aimar's avatar
Laurent Aimar committed
246
    demux_sys_t *p_sys = p_demux->p_sys;
247
    block_t *p_block_in, *p_block_out;
248

249
250
251
252
253
254
255
256
    if( p_sys->codec.b_use_word )
    {
        /* Make sure we are word aligned */
        int64_t i_pos = stream_Tell( p_demux->s );
        if( i_pos % 2 )
            stream_Read( p_demux->s, NULL, 1 );
    }

257
    if( ( p_block_in = stream_Block( p_demux->s, p_sys->i_packet_size ) ) == NULL )
258
        return 0;
259

260
261
262
263
264
265
    if( p_sys->codec.b_use_word && !p_sys->b_big_endian && p_block_in->i_buffer > 0 )
    {
        /* Convert to big endian */
        swab( p_block_in->p_buffer, p_block_in->p_buffer, p_block_in->i_buffer );
    }

266
    p_block_in->i_pts = p_block_in->i_dts = p_sys->b_start || p_sys->b_initial_sync_failed ? VLC_TS_0 : VLC_TS_INVALID;
267
    p_sys->b_initial_sync_failed = p_sys->b_start; /* Only try to resync once */
268

269
    while( ( p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, &p_block_in ) ) )
270
    {
271
        p_sys->b_initial_sync_failed = false;
272
        while( p_block_out )
273
        {
274
            block_t *p_next = p_block_out->p_next;
275

276
277
278
279
280
281
            if( !p_sys->p_es )
            {
                p_sys->p_packetizer->fmt_out.b_packetized = true;
                p_sys->p_es = es_out_Add( p_demux->out,
                                          &p_sys->p_packetizer->fmt_out);

282
283
284
285
286
287
288
289

                /* Try the xing header */
                if( p_sys->xing.i_bytes && p_sys->xing.i_frames &&
                    p_sys->xing.i_frame_samples )
                {
                    p_sys->i_bitrate_avg = p_sys->xing.i_bytes * INT64_C(8) *
                        p_sys->p_packetizer->fmt_out.audio.i_rate /
                        p_sys->xing.i_frames / p_sys->xing.i_frame_samples;
290
291
292

                    if( p_sys->i_bitrate_avg > 0 )
                        p_sys->b_estimate_bitrate = false;
293
                }
294
295
                /* Use the bitrate as initual value */
                if( p_sys->b_estimate_bitrate )
296
297
                    p_sys->i_bitrate_avg = p_sys->p_packetizer->fmt_out.i_bitrate;
            }
298
299
300
301
302
303
304
305
306
307
308
309
            if( p_sys->p_packetizer->fmt_out.i_cat == VIDEO_ES )
            {
                if( p_block_out->i_pts <= VLC_TS_INVALID &&
                    p_block_out->i_dts <= VLC_TS_INVALID )
                    p_block_out->i_dts = VLC_TS_0 + p_sys->i_pts + 1000000 / p_sys->f_fps;
                if( p_block_out->i_dts > VLC_TS_INVALID )
                    p_sys->i_pts = p_block_out->i_dts - VLC_TS_0;
            }
            else
            {
                p_sys->i_pts = p_block_out->i_pts - VLC_TS_0;
            }
310

311
            /* Re-estimate bitrate */
312
            if( p_sys->b_estimate_bitrate && p_sys->i_pts > INT64_C(500000) )
313
314
315
                p_sys->i_bitrate_avg = 8*INT64_C(1000000)*p_sys->i_bytes/(p_sys->i_pts-1);
            p_sys->i_bytes += p_block_out->i_buffer;

316
            /* Correct timestamp */
317
318
319
320
321
322
323
324
325
            if( p_block_out->i_pts > VLC_TS_INVALID )
            {
                p_block_out->i_pts += p_sys->i_time_offset;
            }
            if( p_block_out->i_dts > VLC_TS_INVALID )
            {
                p_block_out->i_dts += p_sys->i_time_offset;
                es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block_out->i_dts );
            }
326

327
            es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
328

329
330
331
            p_block_out = p_next;
        }
    }
332
333
334
335

    if( p_sys->b_initial_sync_failed )
        msg_Dbg( p_demux, "did not sync on first block" );
    p_sys->b_start = false;
336
    return 1;
337
338
339
340
341
342
343
}

/*****************************************************************************
 * Close: frees unused data
 *****************************************************************************/
static void Close( vlc_object_t * p_this )
{
Laurent Aimar's avatar
Laurent Aimar committed
344
345
    demux_t     *p_demux = (demux_t*)p_this;
    demux_sys_t *p_sys = p_demux->p_sys;
346

347
    demux_PacketizerDestroy( p_sys->p_packetizer );
348
349
350
    free( p_sys );
}

Laurent Aimar's avatar
Laurent Aimar committed
351
352
353
354
355
356
/*****************************************************************************
 * Control:
 *****************************************************************************/
static int Control( demux_t *p_demux, int i_query, va_list args )
{
    demux_sys_t *p_sys  = p_demux->p_sys;
357
    int64_t *pi64;
358
    bool *pb_bool;
359
    int i_ret;
360
361
362
    va_list args_save;

    va_copy ( args_save, args );
zorglub's avatar
zorglub committed
363
364
365

    switch( i_query )
    {
366
        case DEMUX_HAS_UNSUPPORTED_META:
367
368
            pb_bool = (bool*)va_arg( args, bool* );
            *pb_bool = true;
369
370
            return VLC_SUCCESS;

371
372
        case DEMUX_GET_TIME:
            pi64 = (int64_t*)va_arg( args, int64_t * );
373
            *pi64 = p_sys->i_pts + p_sys->i_time_offset;
374
375
            return VLC_SUCCESS;

376
        case DEMUX_GET_LENGTH:
377
            i_ret = demux_vaControlHelper( p_demux->s, p_sys->i_stream_offset, -1,
378
379
                                            p_sys->i_bitrate_avg, 1, i_query,
                                            args );
380
381
            /* No bitrate, we can't have it precisely, but we can compute
             * a raw approximation with time/position */
382
            if( i_ret && !p_sys->i_bitrate_avg )
383
            {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
384
385
                float f_pos = (double)(uint64_t)( stream_Tell( p_demux->s ) ) /
                              (double)(uint64_t)( stream_Size( p_demux->s ) );
386
387
388
389
390
391
                /* The first few seconds are guaranteed to be very whacky,
                 * don't bother trying ... Too bad */
                if( f_pos < 0.01 ||
                    (p_sys->i_pts + p_sys->i_time_offset) < 8000000 )
                    return VLC_EGENERIC;

392
                pi64 = (int64_t *)va_arg( args_save, int64_t * );
393
394
395
                *pi64 = (p_sys->i_pts + p_sys->i_time_offset) / f_pos;
                return VLC_SUCCESS;
            }
396
397
398
            va_end( args_save );
            return i_ret;

399
400
401
        case DEMUX_SET_TIME:
            /* FIXME TODO: implement a high precision seek (with mp3 parsing)
             * needed for multi-input */
402
        default:
403
            i_ret = demux_vaControlHelper( p_demux->s, p_sys->i_stream_offset, -1,
404
405
                                            p_sys->i_bitrate_avg, 1, i_query,
                                            args );
406
            if( !i_ret && p_sys->i_bitrate_avg > 0 &&
407
                (i_query == DEMUX_SET_POSITION || i_query == DEMUX_SET_TIME) )
408
            {
409
                int64_t i_time = INT64_C(8000000) * ( stream_Tell(p_demux->s) - p_sys->i_stream_offset ) /
410
                    p_sys->i_bitrate_avg;
411

412
                /* Fix time_offset */
413
414
                if( i_time >= 0 )
                    p_sys->i_time_offset = i_time - p_sys->i_pts;
415
416
            }
            return i_ret;
zorglub's avatar
zorglub committed
417
    }
Laurent Aimar's avatar
Laurent Aimar committed
418
}
419

Laurent Aimar's avatar
Laurent Aimar committed
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
/*****************************************************************************
 * Wav header skipper
 *****************************************************************************/
#define WAV_PROBE_SIZE (512*1024)
static int WavSkipHeader( demux_t *p_demux, int *pi_skip, const int pi_format[] )
{
    const uint8_t *p_peek;
    int         i_peek = 0;

    /* */
    *pi_skip = 0;

    /* Check if we are dealing with a WAV file */
    if( stream_Peek( p_demux->s, &p_peek, 12+8 ) != 12 + 8 )
        return VLC_SUCCESS;

    if( memcmp( p_peek, "RIFF", 4 ) || memcmp( &p_peek[8], "WAVE", 4 ) )
        return VLC_SUCCESS;

    /* Find the wave format header */
    i_peek = 12 + 8;
    while( memcmp( p_peek + i_peek - 8, "fmt ", 4 ) )
    {
        uint32_t i_len = GetDWLE( p_peek + i_peek - 4 );
        if( i_len > WAV_PROBE_SIZE || i_peek + i_len > WAV_PROBE_SIZE )
            return VLC_EGENERIC;

        i_peek += i_len + 8;
        if( stream_Peek( p_demux->s, &p_peek, i_peek ) != i_peek )
            return VLC_EGENERIC;
    }

    /* Sanity check the wave format header */
    uint32_t i_len = GetDWLE( p_peek + i_peek - 4 );
    if( i_len > WAV_PROBE_SIZE )
        return VLC_EGENERIC;

    i_peek += i_len + 8;
    if( stream_Peek( p_demux->s, &p_peek, i_peek ) != i_peek )
        return VLC_EGENERIC;
    const int i_format = GetWLE( p_peek + i_peek - i_len - 8 /* wFormatTag */ );
    int i_format_idx;
    for( i_format_idx = 0; pi_format[i_format_idx] != WAVE_FORMAT_UNKNOWN; i_format_idx++ )
    {
        if( i_format == pi_format[i_format_idx] )
            break;
    }
    if( pi_format[i_format_idx] == WAVE_FORMAT_UNKNOWN )
        return VLC_EGENERIC;

    if( i_format == WAVE_FORMAT_PCM )
    {
        if( GetWLE( p_peek + i_peek - i_len - 6 /* nChannels */ ) != 2 )
            return VLC_EGENERIC;
        if( GetDWLE( p_peek + i_peek - i_len - 4 /* nSamplesPerSec */ ) !=
            44100 )
            return VLC_EGENERIC;
    }

    /* Skip the wave header */
    while( memcmp( p_peek + i_peek - 8, "data", 4 ) )
    {
        uint32_t i_len = GetDWLE( p_peek + i_peek - 4 );
        if( i_len > WAV_PROBE_SIZE || i_peek + i_len > WAV_PROBE_SIZE )
            return VLC_EGENERIC;

        i_peek += i_len + 8;
        if( stream_Peek( p_demux->s, &p_peek, i_peek ) != i_peek )
            return VLC_EGENERIC;
    }
    *pi_skip = i_peek;
    return VLC_SUCCESS;
}

static int GenericProbe( demux_t *p_demux, int64_t *pi_offset,
                         const char * ppsz_name[],
496
                         int (*pf_check)( const uint8_t *, int * ), int i_check_size,
Laurent Aimar's avatar
Laurent Aimar committed
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
                         const int pi_wav_format[] )
{
    bool   b_forced_demux;

    int64_t i_offset;
    const uint8_t *p_peek;
    int i_skip;

    b_forced_demux = false;
    for( int i = 0; ppsz_name[i] != NULL; i++ )
    {
        b_forced_demux |= demux_IsForced( p_demux, ppsz_name[i] );
    }

    i_offset = stream_Tell( p_demux->s );

    if( WavSkipHeader( p_demux, &i_skip, pi_wav_format ) )
    {
        if( !b_forced_demux )
            return VLC_EGENERIC;
    }
    const bool b_wav = i_skip > 0;

    /* peek the begining
521
     * It is common that wav files have some sort of garbage at the begining
522
     * We will accept probing 0.5s of data in this case.
523
     */
524
    const int i_probe = i_skip + i_check_size + 8000 + ( b_wav ? (44000/2*2*2) : 0);
Laurent Aimar's avatar
Laurent Aimar committed
525
526
527
528
529
530
531
532
533
534
535
536
537
538
    const int i_peek = stream_Peek( p_demux->s, &p_peek, i_probe );
    if( i_peek < i_skip + i_check_size )
    {
        msg_Err( p_demux, "cannot peek" );
        return VLC_EGENERIC;
    }
    for( ;; )
    {
        if( i_skip + i_check_size > i_peek )
        {
            if( !b_forced_demux )
                return VLC_EGENERIC;
            break;
        }
539
540
        int i_samples = 0;
        int i_size = pf_check( &p_peek[i_skip], &i_samples );
Laurent Aimar's avatar
Laurent Aimar committed
541
542
        if( i_size >= 0 )
        {
543
            if( i_size == 0 )
Laurent Aimar's avatar
Laurent Aimar committed
544
545
546
                break;

            /* If we have the frame size, check the next frame for
547
548
549
550
551
             * extra robustness
             * The second test is because some .wav have paddings
             */
            bool b_ok = false;
            for( int t = 0; t < 1 + !!b_wav; t++ )
Laurent Aimar's avatar
Laurent Aimar committed
552
            {
553
554
555
556
557
558
559
560
                if( t == 1 )
                    i_size = i_samples * 2 * 2;
                if( i_skip + i_check_size + i_size <= i_peek )
                {
                    b_ok = pf_check( &p_peek[i_skip+i_size], NULL ) >= 0;
                    if( b_ok )
                        break;
                }
Laurent Aimar's avatar
Laurent Aimar committed
561
            }
562
563
            if( b_ok )
                break;
Laurent Aimar's avatar
Laurent Aimar committed
564
565
        }
        i_skip++;
566
567
        if( !b_wav && !b_forced_demux )
            return VLC_EGENERIC;
Laurent Aimar's avatar
Laurent Aimar committed
568
569
570
571
572
573
    }

    *pi_offset = i_offset + i_skip;
    return VLC_SUCCESS;
}

574
575
576
/*****************************************************************************
 * Mpeg I/II Audio
 *****************************************************************************/
577
static int MpgaCheckSync( const uint8_t *p_peek )
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
{
    uint32_t h = GetDWBE( p_peek );

    if( ((( h >> 21 )&0x07FF) != 0x07FF )   /* header sync */
        || (((h >> 17)&0x03) == 0 )         /* valid layer ?*/
        || (((h >> 12)&0x0F) == 0x0F )
        || (((h >> 12)&0x0F) == 0x00 )      /* valid bitrate ? */
        || (((h >> 10) & 0x03) == 0x03 )    /* valide sampling freq ? */
        || ((h & 0x03) == 0x02 ))           /* valid emphasis ? */
    {
        return false;
    }
    return true;
}

#define MPGA_VERSION( h )   ( 1 - (((h)>>19)&0x01) )
#define MPGA_MODE(h)        (((h)>> 6)&0x03)

static int MpgaGetFrameSamples( uint32_t h )
{
    const int i_layer = 3 - (((h)>>17)&0x03);
    switch( i_layer )
    {
    case 0:
        return 384;
    case 1:
        return 1152;
    case 2:
        return MPGA_VERSION(h) ? 576 : 1152;
    default:
        return 0;
    }
}

static int MpgaProbe( demux_t *p_demux, int64_t *pi_offset )
{
614
    const int pi_wav[] = { WAVE_FORMAT_MPEG, WAVE_FORMAT_MPEGLAYER3, WAVE_FORMAT_UNKNOWN };
615
616
617
618
    bool   b_forced;
    bool   b_forced_demux;
    int64_t i_offset;

619
620
    const uint8_t *p_peek;
    int i_skip;
621
622
623
624
625
626

    b_forced = demux_IsPathExtension( p_demux, ".mp3" );
    b_forced_demux = demux_IsForced( p_demux, "mp3" ) ||
                     demux_IsForced( p_demux, "mpga" );

    i_offset = stream_Tell( p_demux->s );
627
628
629
630
631
632

    if( WavSkipHeader( p_demux, &i_skip, pi_wav ) )
    {
        if( !b_forced_demux )
            return VLC_EGENERIC;

633
        return VLC_EGENERIC;
634
    }
635

636
637
638
639
    if( stream_Peek( p_demux->s, &p_peek, i_skip + 4 ) < i_skip + 4 )
        return VLC_EGENERIC;

    if( !MpgaCheckSync( &p_peek[i_skip] ) )
640
641
642
643
644
645
646
    {
        bool b_ok = false;
        int i_peek;

        if( !b_forced_demux && !b_forced )
            return VLC_EGENERIC;

647
648
        i_peek = stream_Peek( p_demux->s, &p_peek, i_skip + 8096 );
        while( i_skip + 4 < i_peek )
649
        {
650
            if( MpgaCheckSync( &p_peek[i_skip] ) )
651
652
653
654
            {
                b_ok = true;
                break;
            }
655
            i_skip++;
656
657
658
659
        }
        if( !b_ok && !b_forced_demux )
            return VLC_EGENERIC;
    }
660
    *pi_offset = i_offset + i_skip;
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
    return VLC_SUCCESS;
}

static void MpgaXingSkip( const uint8_t **pp_xing, int *pi_xing, int i_count )
{
    if(i_count > *pi_xing )
        i_count = *pi_xing;

    (*pp_xing) += i_count;
    (*pi_xing) -= i_count;
}

static uint32_t MpgaXingGetDWBE( const uint8_t **pp_xing, int *pi_xing, uint32_t i_default )
{
    if( *pi_xing < 4 )
        return i_default;

    uint32_t v = GetDWBE( *pp_xing );

    MpgaXingSkip( pp_xing, pi_xing, 4 );

    return v;
}

static int MpgaInit( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;

    const uint8_t *p_peek;
    int i_peek;

    /* */
    p_sys->i_packet_size = 1024;

    /* Load a potential xing header */
    i_peek = stream_Peek( p_demux->s, &p_peek, 4 + 1024 );
    if( i_peek < 4 + 21 )
        return VLC_SUCCESS;

    const uint32_t header = GetDWBE( p_peek );
701
    if( !MpgaCheckSync( p_peek ) )
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
        return VLC_SUCCESS;

    /* Xing header */
    const uint8_t *p_xing = p_peek;
    int i_xing = i_peek;
    int i_skip;

    if( MPGA_VERSION( header ) == 0 )
        i_skip = MPGA_MODE( header ) != 3 ? 36 : 21;
    else
        i_skip = MPGA_MODE( header ) != 3 ? 21 : 13;

    if( i_skip + 8 >= i_xing || memcmp( &p_xing[i_skip], "Xing", 4 ) )
        return VLC_SUCCESS;

    const uint32_t i_flags = GetDWBE( &p_xing[i_skip+4] );

    MpgaXingSkip( &p_xing, &i_xing, i_skip + 8 );

    if( i_flags&0x01 )
        p_sys->xing.i_frames = MpgaXingGetDWBE( &p_xing, &i_xing, 0 );
    if( i_flags&0x02 )
        p_sys->xing.i_bytes = MpgaXingGetDWBE( &p_xing, &i_xing, 0 );
    if( i_flags&0x04 ) /* TODO Support XING TOC to improve seeking accuracy */
        MpgaXingSkip( &p_xing, &i_xing, 100 );
    if( i_flags&0x08 )
    {
        /* FIXME: doesn't return the right bitrage average, at least
           with some MP3's */
        p_sys->xing.i_bitrate_avg = MpgaXingGetDWBE( &p_xing, &i_xing, 0 );
        msg_Dbg( p_demux, "xing vbr value present (%d)",
                 p_sys->xing.i_bitrate_avg );
    }

    if( p_sys->xing.i_frames > 0 && p_sys->xing.i_bytes > 0 )
    {
        p_sys->xing.i_frame_samples = MpgaGetFrameSamples( header );
        msg_Dbg( p_demux, "xing frames&bytes value present "
                 "(%d bytes, %d frames, %d samples/frame)",
                 p_sys->xing.i_bytes, p_sys->xing.i_frames,
                 p_sys->xing.i_frame_samples );
    }
    return VLC_SUCCESS;
}

747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
/*****************************************************************************
 * AAC
 *****************************************************************************/
static int AacProbe( demux_t *p_demux, int64_t *pi_offset )
{
    bool   b_forced;
    bool   b_forced_demux;

    int64_t i_offset;
    const uint8_t *p_peek;

    b_forced = demux_IsPathExtension( p_demux, ".aac" ) ||
               demux_IsPathExtension( p_demux, ".aacp" );
    b_forced_demux = demux_IsForced( p_demux, "m4a" ) ||
                     demux_IsForced( p_demux, "aac" ) ||
                     demux_IsForced( p_demux, "mp4a" );

    if( !b_forced_demux && !b_forced )
        return VLC_EGENERIC;

    i_offset = stream_Tell( p_demux->s );

    /* peek the begining (10 is for adts header) */
    if( stream_Peek( p_demux->s, &p_peek, 10 ) < 10 )
    {
        msg_Err( p_demux, "cannot peek" );
        return VLC_EGENERIC;
    }
    if( !strncmp( (char *)p_peek, "ADIF", 4 ) )
    {
        msg_Err( p_demux, "ADIF file. Not yet supported. (Please report)" );
        return VLC_EGENERIC;
    }

    *pi_offset = i_offset;
    return VLC_SUCCESS;
}
static int AacInit( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;

    p_sys->i_packet_size = 4096;

    return VLC_SUCCESS;
}

793

794
795
796
/*****************************************************************************
 * A52
 *****************************************************************************/
797
static int A52CheckSync( const uint8_t *p_peek, bool *p_big_endian, int *pi_samples, bool b_eac3 )
798
{
799
800
    vlc_a52_header_t header;
    uint8_t p_tmp[VLC_A52_HEADER_SIZE];
801

802
803
    *p_big_endian =  p_peek[0] == 0x0b && p_peek[1] == 0x77;
    if( !*p_big_endian )
804
    {
805
806
        swab( p_peek, p_tmp, VLC_A52_HEADER_SIZE );
        p_peek = p_tmp;
807
808
    }

809
810
811
812
813
    if( vlc_a52_header_Parse( &header, p_peek, VLC_A52_HEADER_SIZE ) )
        return VLC_EGENERIC;

    if( !header.b_eac3 != !b_eac3 )
        return VLC_EGENERIC;
814
815
    if( pi_samples )
        *pi_samples = header.i_samples;
816
    return header.i_size;
817
}
818
static int EA52CheckSyncProbe( const uint8_t *p_peek, int *pi_samples )
819
820
{
    bool b_dummy;
821
    return A52CheckSync( p_peek, &b_dummy, pi_samples, true );
822
823
824
825
826
}

static int EA52Probe( demux_t *p_demux, int64_t *pi_offset )
{
    const char *ppsz_name[] = { "eac3", NULL };
827
    const int pi_wav[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_A52, WAVE_FORMAT_UNKNOWN };
828

829
    return GenericProbe( p_demux, pi_offset, ppsz_name, EA52CheckSyncProbe, VLC_A52_HEADER_SIZE, pi_wav );
830
831
}

832
static int A52CheckSyncProbe( const uint8_t *p_peek, int *pi_samples )
833
834
{
    bool b_dummy;
835
    return A52CheckSync( p_peek, &b_dummy, pi_samples, false );
836
837
838
839
840
}

static int A52Probe( demux_t *p_demux, int64_t *pi_offset )
{
    const char *ppsz_name[] = { "a52", "ac3", NULL };
841
    const int pi_wav[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_A52, WAVE_FORMAT_UNKNOWN };
842

843
    return GenericProbe( p_demux, pi_offset, ppsz_name, A52CheckSyncProbe, VLC_A52_HEADER_SIZE, pi_wav );
844
845
}

846
847
848
849
850
851
852
853
854
static int A52Init( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;

    p_sys->b_big_endian = false;
    p_sys->i_packet_size = 1024;

    const uint8_t *p_peek;

855
856
    /* peek the begining */
    if( stream_Peek( p_demux->s, &p_peek, VLC_A52_HEADER_SIZE ) >= VLC_A52_HEADER_SIZE )
857
    {
858
        A52CheckSync( p_peek, &p_sys->b_big_endian, NULL, true );
859
860
861
862
    }
    return VLC_SUCCESS;
}

863
864
865
/*****************************************************************************
 * DTS
 *****************************************************************************/
866
static int DtsCheckSync( const uint8_t *p_peek, int *pi_samples )
867
{
868
869
    /* TODO return frame size for robustness */

870
871
872
873
874
    /* 14 bits, little endian version of the bitstream */
    if( p_peek[0] == 0xff && p_peek[1] == 0x1f &&
        p_peek[2] == 0x00 && p_peek[3] == 0xe8 &&
        (p_peek[4] & 0xf0) == 0xf0 && p_peek[5] == 0x07 )
    {
875
        return 0;
876
877
878
879
880
881
    }
    /* 14 bits, big endian version of the bitstream */
    else if( p_peek[0] == 0x1f && p_peek[1] == 0xff &&
             p_peek[2] == 0xe8 && p_peek[3] == 0x00 &&
             p_peek[4] == 0x07 && (p_peek[5] & 0xf0) == 0xf0)
    {
882
        return 0;
883
884
885
886
887
    }
    /* 16 bits, big endian version of the bitstream */
    else if( p_peek[0] == 0x7f && p_peek[1] == 0xfe &&
             p_peek[2] == 0x80 && p_peek[3] == 0x01 )
    {
888
        return 0;
889
890
891
892
893
    }
    /* 16 bits, little endian version of the bitstream */
    else if( p_peek[0] == 0xfe && p_peek[1] == 0x7f &&
             p_peek[2] == 0x01 && p_peek[3] == 0x80 )
    {
894
        return 0;
895
896
    }

897
    VLC_UNUSED(pi_samples);
898
    return VLC_EGENERIC;
899
900
901
902
903
}

static int DtsProbe( demux_t *p_demux, int64_t *pi_offset )
{
    const char *ppsz_name[] = { "dts", NULL };
904
    const int pi_wav[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_DTS, WAVE_FORMAT_UNKNOWN };
905

906
    return GenericProbe( p_demux, pi_offset, ppsz_name, DtsCheckSync, 11, pi_wav );
907
908
909
910
911
912
913
914
915
916
}
static int DtsInit( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;

    p_sys->i_packet_size = 16384;

    return VLC_SUCCESS;
}

917
918
919
/*****************************************************************************
 * MLP
 *****************************************************************************/
920
static int MlpCheckSync( const uint8_t *p_peek, int *pi_samples )
921
922
{
    if( p_peek[4+0] != 0xf8 || p_peek[4+1] != 0x72 || p_peek[4+2] != 0x6f )
923
        return -1;
924
925

    if( p_peek[4+3] != 0xba && p_peek[4+3] != 0xbb )
926
        return -1;
927

928
    /* TODO checksum and real size for robustness */
929
    VLC_UNUSED(pi_samples);
930
    return 0;
931
932
933
}
static int MlpProbe( demux_t *p_demux, int64_t *pi_offset )
{
934
    const char *ppsz_name[] = { "mlp", "thd", NULL };
935
    const int pi_wav[] = { WAVE_FORMAT_PCM, WAVE_FORMAT_UNKNOWN };
936

937
    return GenericProbe( p_demux, pi_offset, ppsz_name, MlpCheckSync, 4+28+16*4, pi_wav );
938
939
940
941
942
943
944
945
946
947
948
}
static int MlpInit( demux_t *p_demux )

{
    demux_sys_t *p_sys = p_demux->p_sys;

    p_sys->i_packet_size = 4096;

    return VLC_SUCCESS;
}

949
950
951
952
953
954
955
956
957
958
959
/*****************************************************************************
 * Video
 *****************************************************************************/
static int VideoInit( demux_t *p_demux )
{
    demux_sys_t *p_sys = p_demux->p_sys;

    p_sys->i_packet_size = 4096;

    return VLC_SUCCESS;
}