Coverage Report

Created: 2025-07-18 08:04

/src/vlc/modules/demux/caf.c
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
 * caf.c: Core Audio File Format demuxer
3
 *****************************************************************************
4
 * Copyright (C) 2013 VLC authors and VideoLAN
5
 *
6
 * Authors: Matthias Keiser <matthias@tristan-inc.com>
7
 *
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation; either version 2.1 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program; if not, write to the Free Software Foundation,
20
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21
 *****************************************************************************/
22
23
/*****************************************************************************
24
 * Preamble
25
 *****************************************************************************/
26
27
#ifdef HAVE_CONFIG_H
28
# include "config.h"
29
#endif
30
#include <math.h>
31
#include <limits.h>
32
#include <vlc_common.h>
33
#include <vlc_plugin.h>
34
#include <vlc_demux.h>
35
#include <vlc_codecs.h>
36
37
/* TODO:
38
 *
39
 * - handle channel layout
40
 * - 64 bit float LPCM is broken (sound has artifacts with little endian, only silence plays for big endian).
41
 */
42
43
/*****************************************************************************
44
 * Module descriptor
45
 *****************************************************************************/
46
static int  Open    ( vlc_object_t * );
47
static void Close  ( vlc_object_t * );
48
49
104
vlc_module_begin ()
50
52
set_subcategory( SUBCAT_INPUT_DEMUX )
51
52
set_description( N_( "CAF demuxer" ))
52
52
set_capability( "demux", 140 )
53
104
set_callbacks( Open, Close )
54
52
add_shortcut( "caf" )
55
52
vlc_module_end ()
56
57
/*****************************************************************************
58
 * Local prototypes
59
 *****************************************************************************/
60
static int Demux  ( demux_t * );
61
static int Control( demux_t *, int i_query, va_list args );
62
63
typedef struct frame_span_t
64
{
65
    uint64_t i_frames;
66
    uint64_t i_samples;
67
    uint64_t i_bytes;
68
    uint64_t i_desc_bytes;
69
} frame_span_t;
70
71
typedef struct packet_table_t
72
{
73
    uint64_t i_num_packets;
74
    uint64_t i_num_valid_frames;
75
    uint32_t i_num_priming_frames;
76
    uint32_t i_num_remainder_frames;
77
    uint64_t i_descriptions_start;
78
} packet_table_t;
79
80
typedef struct
81
{
82
    es_format_t  fmt;
83
    es_out_id_t *es;
84
    unsigned i_max_frames;
85
86
    uint64_t i_data_offset;
87
    uint64_t i_data_size;
88
89
    frame_span_t position;
90
    packet_table_t packet_table;
91
} demux_sys_t;
92
93
/*
94
 We use this value to indicate that the data section extends until the end of the file.
95
*/
96
static const uint64_t kCHUNK_SIZE_EOF = UINT64_C( 0xffffffffffffffff );
97
98
/*****************************************************************************
99
 * Various Utility Functions
100
 *****************************************************************************/
101
102
/* ParseVarLenInteger parses a var length integer as found in the packet descriptions
103
 (and in the aac magic cookie). In theorie a var length integer could be bigger than
104
 an uint64_t, but I think it's unlikely to ever be a problem... */
105
106
static int ParseVarLenInteger( const uint8_t *p_buff, size_t i_buff_len, uint64_t *pi_value_out, uint32_t *i_len_out )
107
0
{
108
0
    *i_len_out = 0;
109
110
0
    uint64_t i_value = 0;
111
0
    bool finished = false;
112
113
0
    for( uint32_t i = 0; i < i_buff_len; i++ )
114
0
    {
115
0
        if( (( i_value >> 32 ) << 7 ) > UINT32_MAX )
116
0
        {
117
0
            return VLC_EGENERIC; /* overflow */
118
0
        }
119
0
        uint8_t i_byte = p_buff[i];
120
0
        i_value = ( i_value << 7 ) | ( i_byte & 0x7f );
121
122
0
        ( *i_len_out )++;
123
124
0
        if( !( i_byte & 0x80 ))
125
0
        {
126
0
            finished = true;
127
0
            break;
128
0
        }
129
0
    }
130
131
0
    if( !finished )
132
0
    {
133
0
        return VLC_EGENERIC;
134
0
    }
135
136
0
    *pi_value_out = i_value;
137
138
0
    return VLC_SUCCESS;
139
0
}
140
141
/* Utility function that reads a big endian double from the input buffer. */
142
143
static inline double GetDBLBE( const uint8_t *p )
144
0
{
145
0
    union
146
0
    {
147
0
        uint64_t uint64;
148
0
        double dbl;
149
0
    } u_64;
150
151
0
    u_64.uint64 = GetQWBE( p );
152
0
    return u_64.dbl;
153
0
}
154
155
/* Utility function that reads a big endian signed 32 bit integer into an unsigned 32 bit variable.
156
   If the read value is negative, this function returns an error.
157
 */
158
159
static inline int ReadBEInt32ToUInt32( const uint8_t *p, uint32_t *i_out )
160
0
{
161
0
    uint32_t i_value = GetDWBE( p );
162
163
0
    if( i_value > INT32_MAX ) return VLC_EGENERIC;
164
165
0
    *i_out = i_value;
166
0
    return VLC_SUCCESS;
167
0
}
168
169
/* Utility function that reads a big endian signed 64 bit integer into an unsigned 64 bit variable.
170
   If the read value is negative, this function returns an error.
171
*/
172
173
static inline int ReadBEInt64ToUInt64( const uint8_t *p, uint64_t *i_out )
174
0
{
175
0
    uint64_t i_value = GetQWBE( p );
176
177
0
    if( i_value > INT64_MAX ) return VLC_EGENERIC;
178
179
0
    *i_out = i_value;
180
0
    return VLC_SUCCESS;
181
0
}
182
183
static inline bool NeedsPacketTable( demux_sys_t *p_sys )
184
0
{
185
0
    return ( !p_sys->fmt.audio.i_bytes_per_frame || !p_sys->fmt.audio.i_frame_length );
186
0
}
187
188
static uint64_t TotalNumFrames( demux_t *p_demux )
189
0
{
190
0
    demux_sys_t *p_sys = p_demux->p_sys;
191
192
0
    if( !NeedsPacketTable( p_sys ))
193
0
    {
194
0
        uint64_t i_data_size;
195
196
0
        if( p_sys->i_data_size != kCHUNK_SIZE_EOF)
197
0
        {
198
0
            i_data_size = p_sys->i_data_size;
199
0
        }
200
0
        else
201
0
        {
202
0
            int64_t i_stream_size = stream_Size( p_demux->s );
203
0
            if(i_stream_size >= 0 && (uint64_t)i_stream_size >= p_sys->i_data_offset)
204
0
                i_data_size = i_stream_size - p_sys->i_data_offset;
205
0
            else
206
0
                i_data_size = 0;
207
0
        }
208
209
0
        return i_data_size / p_sys->fmt.audio.i_bytes_per_frame;
210
0
    }
211
0
    else
212
0
    {
213
0
        return p_sys->packet_table.i_num_packets;
214
0
    }
215
0
}
216
217
static uint64_t TotalNumSamples( demux_t *p_demux )
218
0
{
219
0
    demux_sys_t *p_sys = p_demux->p_sys;
220
221
0
    if( !NeedsPacketTable( p_sys ))
222
0
    {
223
0
        return TotalNumFrames( p_demux ) * p_sys->fmt.audio.i_frame_length;
224
0
    }
225
0
    else
226
0
    {
227
0
        return p_sys->packet_table.i_num_valid_frames + p_sys->packet_table.i_num_priming_frames +
228
0
                p_sys->packet_table.i_num_remainder_frames;
229
0
    }
230
0
}
231
232
static inline vlc_fourcc_t ReadFOURCC( const uint8_t *p )
233
0
{
234
0
    return VLC_FOURCC( p[0], p[1], p[2], p[3] );
235
0
}
236
237
/*****************************************************************************
238
 * FrameSpan Functions
239
 *****************************************************************************
240
 *  A FrameSpan structure contains the relationship between a number of
241
 frames, the number of samples they contain, the amount of data they
242
 use, and the length of their packet descriptions (if any).
243
 *****************************************************************************/
244
245
/* FrameSpanAddSpan adds span2 to span1 */
246
247
static inline void FrameSpanAddSpan( frame_span_t *span1, frame_span_t *span2 )
248
0
{
249
0
    span1->i_frames += span2->i_frames;
250
0
    span1->i_samples += span2->i_samples;
251
0
    span1->i_bytes += span2->i_bytes;
252
0
    span1->i_desc_bytes += span2->i_desc_bytes;
253
0
}
254
255
/* Adds the frame that is described at i_desc_offset to span */
256
257
static int FrameSpanAddDescription( demux_t *p_demux, uint64_t i_desc_offset, frame_span_t *span )
258
0
{
259
0
    demux_sys_t *p_sys  = p_demux->p_sys;
260
261
    /* Avoid seeking + peeking for simple case (PCM) */
262
0
    if( p_sys->fmt.audio.i_bytes_per_frame && p_sys->fmt.audio.i_frame_length )
263
0
    {
264
0
        span->i_bytes += p_sys->fmt.audio.i_bytes_per_frame;
265
0
        span->i_samples += p_sys->fmt.audio.i_frame_length;
266
0
        span->i_frames++;
267
0
        return VLC_SUCCESS;
268
0
    }
269
270
0
    uint32_t i_desc_size = 0;
271
272
0
    if( vlc_stream_Seek( p_demux->s, p_sys->packet_table.i_descriptions_start + i_desc_offset ))
273
0
    {
274
0
        msg_Err( p_demux, "Couldn't seek packet description." );
275
0
        return VLC_EGENERIC;
276
0
    }
277
278
0
    const uint8_t *p_peek;
279
0
    int i_peek_len = vlc_stream_Peek( p_demux->s, &p_peek, 2 * 10 );
280
    /* Peeking the maximum number of bytes that two 64 bit numbers could use
281
     * (( 64 + 6 ) / 7 = 10). */
282
0
    if( i_peek_len < 0 )
283
0
        i_peek_len = 0;
284
285
0
    if( p_sys->fmt.audio.i_bytes_per_frame )
286
0
    {
287
0
        span->i_bytes += p_sys->fmt.audio.i_bytes_per_frame;
288
0
    }
289
0
    else
290
0
    {
291
0
        uint64_t i_size;
292
0
        uint32_t i_this_int;
293
0
        if( ParseVarLenInteger( p_peek, i_peek_len, &i_size, &i_this_int ))
294
0
        {
295
0
            return VLC_EGENERIC;
296
0
        }
297
298
0
        i_desc_size += i_this_int;
299
0
        span->i_bytes += i_size;
300
0
    }
301
302
0
    if( p_sys->fmt.audio.i_frame_length )
303
0
    {
304
0
        span->i_samples += p_sys->fmt.audio.i_frame_length;
305
0
    }
306
0
    else
307
0
    {
308
0
        if( i_desc_size >= (unsigned)i_peek_len )
309
0
        {
310
0
            return VLC_EGENERIC;
311
0
        }
312
313
0
        uint64_t i_num_samples;
314
0
        uint32_t i_this_int;
315
0
        if( ParseVarLenInteger( p_peek + i_desc_size, i_peek_len - i_desc_size, &i_num_samples, &i_this_int ))
316
0
        {
317
0
            return VLC_EGENERIC;
318
0
        }
319
320
0
        i_desc_size += i_this_int;
321
0
        span->i_samples += i_num_samples;
322
0
    }
323
0
    span->i_desc_bytes += i_desc_size;
324
0
    span->i_frames++;
325
326
0
    return VLC_SUCCESS;
327
0
}
328
329
/* FrameSpanGetTime returns the time span represented by the frame span. */
330
331
static inline vlc_tick_t FrameSpanGetTime( frame_span_t *span, uint32_t i_sample_rate )
332
0
{
333
0
    if( !i_sample_rate )
334
0
        return VLC_TICK_INVALID;
335
336
0
    return vlc_tick_from_samples( span->i_samples, i_sample_rate) + VLC_TICK_0;
337
0
}
338
339
/* SetSpanWithSample returns the span from the beginning of the file up to and
340
 including the specified sample. This works at frame granularity, so the
341
 returned span may not represent the exact target sample.
342
 Since we might have to lineraly search the packet descriptions, this is a
343
 potentially slow operation! */
344
345
static int SetSpanWithSample( demux_t *p_demux, frame_span_t *p_span, uint64_t i_target_sample )
346
0
{
347
0
    demux_sys_t *p_sys = p_demux->p_sys;
348
349
0
    uint64_t i_num_frames = TotalNumFrames( p_demux );
350
351
0
    if( !NeedsPacketTable( p_sys ))
352
0
    {
353
0
        uint64_t i_frame = i_target_sample / p_sys->fmt.audio.i_frame_length;
354
0
        uint64_t i_remaining = i_target_sample - i_frame * p_sys->fmt.audio.i_frame_length;
355
0
        if( i_remaining > ( p_sys->fmt.audio.i_frame_length / 2 ))
356
0
            i_frame++;
357
358
0
        if( i_frame > i_num_frames )
359
0
            i_frame = i_num_frames;
360
361
0
        p_span->i_frames = i_frame;
362
0
        p_span->i_samples = i_frame * p_sys->fmt.audio.i_frame_length;
363
0
        p_span->i_bytes = i_frame * p_sys->fmt.audio.i_bytes_per_frame;
364
0
        p_span->i_desc_bytes = 0;
365
0
    }
366
0
    else
367
0
    {
368
0
        *p_span = (frame_span_t){0};
369
0
        frame_span_t prev_span;
370
371
0
        while( p_span->i_samples < i_target_sample && p_span->i_frames < i_num_frames )
372
0
        {
373
0
            prev_span = *p_span;
374
375
0
            if( FrameSpanAddDescription( p_demux, p_span->i_desc_bytes, p_span ))
376
0
                return VLC_EGENERIC;
377
378
0
            if( p_span->i_samples >= i_target_sample )
379
0
            {
380
0
                uint64_t i_this_samples = p_span->i_samples - prev_span.i_samples;
381
382
0
                if( i_target_sample - prev_span.i_samples < i_this_samples / 2 )
383
0
                    *p_span = prev_span;
384
385
0
                break;
386
0
            }
387
0
        }
388
0
    }
389
390
0
    return VLC_SUCCESS;
391
0
}
392
393
/*****************************************************************************
394
 * CAF Parsing Functions
395
 *****************************************************************************/
396
397
/* The NextChunk function returns the four char code and the (sanitized) size at the current file position.
398
   Upon return the file position points to the start of the chunk payload.
399
   Note that the ReadXXXChunk functions expect the chunk to size to be sanitized
400
   (i.e. they don't check if it is bigger than INT64_MAX, but note the special case of the 'data' chunk, which can be kCHUNK_SIZE_EOF).
401
 */
402
403
static int NextChunk( demux_t *p_demux, vlc_fourcc_t *p_fcc, uint64_t *pi_size )
404
0
{
405
0
    uint8_t p_read[12];
406
407
0
    if( vlc_stream_Read( p_demux->s, p_read, 12 ) < 12 )
408
0
        return VLC_EGENERIC;
409
410
0
    *p_fcc = ReadFOURCC( p_read );
411
0
    uint64_t i_size = GetQWBE( p_read + 4 );
412
413
    /* We accept no negative sizes for chunks, except -1 for the data chunk. */
414
415
0
    if( i_size > INT64_MAX )
416
0
    {
417
0
        if( *p_fcc == VLC_FOURCC( 'd', 'a', 't', 'a' ) && i_size == UINT64_C( -1 ))
418
0
            i_size = kCHUNK_SIZE_EOF;
419
0
        else
420
0
            return VLC_EGENERIC;
421
0
    }
422
423
0
    *pi_size = i_size;
424
425
0
    return VLC_SUCCESS;
426
0
}
427
428
static int ReadDescChunk( demux_t *p_demux )
429
0
{
430
0
    demux_sys_t *p_sys = p_demux->p_sys;
431
432
0
    const uint8_t *p_peek;
433
434
0
    if ( vlc_stream_Peek( p_demux->s, &p_peek, 8 + 6 * 4 ) < ( 8 + 6 * 4 ))
435
0
    {
436
0
        return VLC_EGENERIC;
437
0
    }
438
439
0
    vlc_fourcc_t i_fmt = ReadFOURCC( p_peek + 8 );
440
0
    uint32_t i_fmt_flags = GetDWBE( p_peek + 12 );
441
442
0
    uint32_t i_bits_per_channel = GetDWBE( p_peek + 28 );
443
0
    uint32_t i_bytes_per_packet = GetDWBE( p_peek + 16 );
444
0
    uint32_t i_frames_per_packet = GetDWBE( p_peek + 20 );
445
0
    uint32_t i_channels_per_frame = GetDWBE( p_peek + 24 );
446
447
0
    if( i_fmt == VLC_CODEC_DVD_LPCM )
448
0
    {
449
0
        if( !i_frames_per_packet || !i_channels_per_frame )
450
0
        {
451
0
            msg_Err( p_demux, "Absurd LPCM parameters (frames_per_packet: %u, channels_per_frame: %u).", i_frames_per_packet, i_channels_per_frame );
452
0
            return VLC_EGENERIC;
453
0
        }
454
455
0
        uint32_t i_unpacked_bits_per_sample = ( i_bytes_per_packet / i_frames_per_packet / i_channels_per_frame ) * 8;
456
457
0
        bool b_is_float = !!( i_fmt_flags & ( 1 << 0 ) );
458
0
        bool b_is_be = !( i_fmt_flags & ( 1 << 1 ) );
459
460
0
        vlc_fourcc_t i_basic_codec = 0;
461
462
0
        if( !b_is_float )
463
0
        {
464
0
            i_basic_codec = b_is_be ? VLC_FOURCC( 't', 'w', 'o', 's' ) : VLC_FOURCC( 's', 'o', 'w', 't' );
465
0
            es_format_Init( &p_sys->fmt, AUDIO_ES, vlc_fourcc_GetCodecAudio( i_basic_codec, i_unpacked_bits_per_sample ));
466
0
        }
467
0
        else
468
0
        {
469
0
            if( i_bits_per_channel == 32 )
470
0
                i_basic_codec = b_is_be ? VLC_CODEC_F32B : VLC_CODEC_F32L;
471
0
            else if( i_bits_per_channel == 64 )
472
0
                i_basic_codec = b_is_be ? VLC_CODEC_F64B : VLC_CODEC_F64L;
473
474
0
            if( i_basic_codec )
475
0
                es_format_Init( &p_sys->fmt, AUDIO_ES, vlc_fourcc_GetCodecAudio( i_basic_codec, i_bits_per_channel ));
476
0
        }
477
0
    }
478
0
    else if( i_fmt == VLC_FOURCC( 'a', 'a', 'c', ' ' ))
479
0
    {
480
0
        const uint32_t kMP4Audio_AAC_LC_ObjectType = 2;
481
482
0
        if( i_fmt_flags != kMP4Audio_AAC_LC_ObjectType )
483
0
        {
484
0
            msg_Warn( p_demux, "The only documented format flag for aac is 2 (kMP4Audio_AAC_LC_ObjectType), but is %i. Continuing anyways.", i_fmt_flags );
485
0
        }
486
487
0
        es_format_Init( &p_sys->fmt, AUDIO_ES, vlc_fourcc_GetCodecAudio( VLC_CODEC_MP4A, 0 ));
488
489
0
    }
490
0
    else
491
0
    {
492
0
        es_format_Init( &p_sys->fmt, AUDIO_ES, vlc_fourcc_GetCodecAudio( i_fmt, 0 ));
493
0
    }
494
495
0
    if( !p_sys->fmt.i_codec )
496
0
    {
497
0
        msg_Err( p_demux, "could not determine codec" );
498
0
        return VLC_EGENERIC;
499
0
    }
500
501
0
    double d_rate = round( GetDBLBE( p_peek ));
502
503
0
    if( d_rate <= 0 || d_rate > UINT_MAX )
504
0
        return VLC_EGENERIC;
505
506
0
    p_sys->fmt.audio.i_rate = (unsigned int)lround( d_rate );
507
0
    if( !p_sys->fmt.audio.i_rate )
508
0
    {
509
0
        msg_Err( p_demux, "Sample rate must be non-zero" );
510
0
        return VLC_EGENERIC;
511
0
    }
512
0
    p_sys->fmt.audio.i_channels = i_channels_per_frame;
513
0
    p_sys->fmt.audio.i_bytes_per_frame = i_bytes_per_packet; /* "mBytesPerPacket" in Apple parlance */
514
0
    p_sys->fmt.audio.i_frame_length = i_frames_per_packet; /* "mFramesPerPacket" in Apple parlance */
515
0
    p_sys->fmt.audio.i_bitspersample = i_bits_per_channel; /* mBitsPerChannel */
516
0
    p_sys->fmt.audio.i_blockalign = i_bytes_per_packet;
517
0
    p_sys->fmt.i_bitrate = i_bits_per_channel * p_sys->fmt.audio.i_rate * i_channels_per_frame;
518
519
0
    if( p_sys->fmt.i_codec == VLC_CODEC_OPUS )
520
0
    {
521
0
        p_sys->i_max_frames = 1;
522
0
    }
523
0
    else p_sys->i_max_frames = UINT_MAX;
524
525
0
    return VLC_SUCCESS;
526
0
}
527
528
/*  This is lifted from cafdec.c in libavformat (function read_kuki_chunk). Apparently the
529
    alac library expects the cookie to be of length 36, but current alac files
530
    have a cookie length of 24.
531
 */
532
static int ProcessALACCookie( demux_t *p_demux, const uint8_t *p, uint64_t i_size )
533
0
{
534
0
    demux_sys_t *p_sys = p_demux->p_sys;
535
536
0
    const size_t kALAC_NEW_KUKI_SIZE = 24;
537
0
    const size_t kALAC_LIB_REQ_KUKI_SIZE = 36;
538
0
    size_t i_extra;
539
540
0
    if( i_size == kALAC_NEW_KUKI_SIZE || i_size == kALAC_LIB_REQ_KUKI_SIZE )
541
0
    {
542
0
        i_extra = kALAC_LIB_REQ_KUKI_SIZE;
543
0
    }
544
0
    else
545
0
    {
546
0
        msg_Warn( p_demux, "Unknown alac magic cookie. Passing it on to the decoder as is and hoping for the best." );
547
0
        i_extra = i_size;
548
0
    }
549
550
0
    p_sys->fmt.i_extra = i_extra;
551
0
    p_sys->fmt.p_extra = malloc( i_extra );
552
553
0
    if( !p_sys->fmt.p_extra )
554
0
        return VLC_ENOMEM;
555
556
0
    uint8_t *p_extra = ( uint8_t * )p_sys->fmt.p_extra;
557
558
0
    if( i_size == kALAC_NEW_KUKI_SIZE )
559
0
    {
560
0
        SetDWBE( p_extra, 36 );
561
0
        memcpy( p_extra + 4, "alac", 4 );
562
0
        SetDWBE( p_extra + 8, 0 );
563
0
        memcpy( p_extra + 12, p, 24 );
564
0
    }
565
0
    else
566
0
    {
567
0
        memcpy( p_sys->fmt.p_extra, p, i_size );
568
0
    }
569
570
0
    return VLC_SUCCESS;
571
0
}
572
573
/* Helper functions for AAC cookie processing. */
574
575
static inline bool AACCookieGetTag( uint8_t *p_tag, const uint8_t *p, uint64_t *p_offset, uint64_t i_size )
576
0
{
577
0
    if( *p_offset + 1 > i_size )
578
0
        return false;
579
580
0
    *p_tag = *( p + *p_offset );
581
0
    *p_offset += 1;
582
583
0
    return true;
584
0
}
585
586
static inline bool AACCookieTagLen( uint64_t *p_tag_len, const uint8_t *p, uint64_t *p_offset, uint64_t i_size )
587
0
{
588
0
    uint32_t i_int_size;
589
590
0
    if( ParseVarLenInteger( p + *p_offset, i_size - *p_offset, p_tag_len, &i_int_size ))
591
0
        return false;
592
593
0
    *p_offset += i_int_size;
594
595
0
    return true;
596
0
}
597
598
static inline bool AACCookieChkLen( int64_t i_length, uint64_t i_size, uint64_t i_offset )
599
0
{
600
0
    return ( i_offset + i_length <= i_size );
601
0
}
602
603
/*  This is lifted from libmp4.c in the mp4 demuxer module (function MP4_ReadBox_esds). The aac
604
    library only want a subset of the magic cookie ("decoder specific info"), so we have to parse it.
605
 */
606
static int ProcessAACCookie( demux_t *p_demux, const uint8_t *p, uint64_t i_size )
607
0
{
608
0
    const uint8_t kAAC_ES_DESCR_TAG = 3;
609
0
    const uint8_t kAAC_DEC_CONFIG_DESCR_TAG = 4;
610
0
    const uint8_t kAAC_DEC_SPEC_INFO_TAG = 5;
611
612
0
    demux_sys_t *p_sys = p_demux->p_sys;
613
614
0
    uint64_t i_offset = 0;
615
0
    uint64_t i_kuki_size = 0;
616
0
    uint64_t i_tag_len;
617
0
    uint8_t i_tag;
618
619
0
    if( !AACCookieGetTag( &i_tag, p, &i_offset, i_size )) goto aac_kuki_finish;
620
621
0
    if( i_tag == kAAC_ES_DESCR_TAG )
622
0
    {
623
624
0
        if( !AACCookieTagLen( &i_tag_len, p, &i_offset, i_size )) goto aac_kuki_finish;
625
626
0
        if( !AACCookieChkLen( 3, i_size, i_offset )) goto aac_kuki_finish;
627
0
        i_offset += 2; /* don't care (ES ID) */
628
0
        uint8_t i_flags = *( p + i_offset++ );
629
630
0
        if( i_flags&0x80 )
631
0
        {
632
0
            if( !AACCookieChkLen( 2, i_size, i_offset )) goto aac_kuki_finish;
633
0
            i_offset += 2; /* don't care (dependence) */
634
0
        }
635
0
        if( i_flags&0x40 )
636
0
        {
637
0
            if( !AACCookieChkLen( 1, i_size, i_offset )) goto aac_kuki_finish;
638
0
            uint8_t i_url_len = *( p + i_offset++ );
639
0
            i_offset += i_url_len; /* don't care (url) */
640
0
        }
641
0
        if( i_flags&0x20 )
642
0
        {
643
0
            if( !AACCookieChkLen( 2, i_size, i_offset )) goto aac_kuki_finish;
644
0
            i_offset += 2; /* don't care (OCR) */
645
0
        }
646
647
0
        if( !AACCookieGetTag( &i_tag, p, &i_offset, i_size )) goto aac_kuki_finish;
648
0
    }
649
650
0
    if( i_tag != kAAC_DEC_CONFIG_DESCR_TAG )
651
0
        goto aac_kuki_finish;
652
653
0
    if( !AACCookieTagLen( &i_tag_len, p, &i_offset, i_size )) goto aac_kuki_finish;
654
655
0
    if( !AACCookieChkLen( 1 + 1 + 3 + 4 + 4, i_size, i_offset )) goto aac_kuki_finish;
656
0
    i_offset += ( 1 + 1 + 3 + 4 + 4 ); /* don't care */
657
658
0
    if( !AACCookieGetTag( &i_tag, p, &i_offset, i_size )) goto aac_kuki_finish;
659
660
0
    if( i_tag != kAAC_DEC_SPEC_INFO_TAG ) /* this is the one we need */
661
0
        goto aac_kuki_finish;
662
663
0
    if( !AACCookieTagLen( &i_tag_len, p, &i_offset, i_size )) goto aac_kuki_finish;
664
665
0
    if( i_offset + i_tag_len > i_size )
666
0
        goto aac_kuki_finish;
667
668
0
    i_kuki_size = i_tag_len;
669
670
0
aac_kuki_finish:
671
672
0
    if( !i_kuki_size )
673
0
    {
674
0
        msg_Warn( p_demux, "Error parsing aac cookie. Passing it on to the decoder as is and hoping for the best." );
675
0
        i_kuki_size = i_size;
676
0
        i_offset = 0;
677
0
    }
678
679
0
    p_sys->fmt.i_extra = i_kuki_size;
680
0
    p_sys->fmt.p_extra = malloc( i_kuki_size );
681
682
0
    if( !p_sys->fmt.p_extra )
683
0
    {
684
0
        return VLC_ENOMEM;
685
0
    }
686
687
0
    memcpy( p_sys->fmt.p_extra, p + i_offset, i_kuki_size );
688
689
0
    return VLC_SUCCESS;
690
0
}
691
692
static int ReadKukiChunk( demux_t *p_demux, uint64_t i_size )
693
0
{
694
0
    demux_sys_t *p_sys = p_demux->p_sys;
695
0
    const uint8_t *p_peek;
696
697
0
    if( i_size > SSIZE_MAX )
698
0
    {
699
0
        msg_Err( p_demux, "Magic Cookie chunk too big" );
700
0
        return VLC_EGENERIC;
701
0
    }
702
703
0
    if( vlc_stream_Peek( p_demux->s, &p_peek, i_size ) < (ssize_t)i_size )
704
0
    {
705
0
        msg_Err( p_demux, "Couldn't peek extra data" );
706
0
        return VLC_EGENERIC;
707
0
    }
708
709
0
    if( p_sys->fmt.i_codec  == VLC_CODEC_ALAC )
710
0
    {
711
0
        int error = ProcessALACCookie( p_demux, p_peek, i_size );
712
0
        if( error ) return error;
713
0
    }
714
0
    else if( p_sys->fmt.i_codec == VLC_CODEC_MP4A )
715
0
    {
716
0
        int error = ProcessAACCookie( p_demux, p_peek, i_size );
717
0
        if( error ) return error;
718
0
    }
719
0
    else if( p_sys->fmt.i_codec != 0 )
720
0
    {
721
0
        p_sys->fmt.i_extra = i_size;
722
0
        p_sys->fmt.p_extra = malloc( i_size );
723
724
0
        if( !p_sys->fmt.p_extra )
725
0
        {
726
0
            return VLC_ENOMEM;
727
0
        }
728
0
        memcpy( p_sys->fmt.p_extra, p_peek, p_sys->fmt.i_extra );
729
0
    }
730
731
0
    return VLC_SUCCESS;
732
0
}
733
734
static int ReadDataChunk( demux_t *p_demux, uint64_t i_size )
735
0
{
736
0
    if( i_size < 4 )
737
0
        return VLC_EGENERIC;
738
739
0
    demux_sys_t *p_sys = p_demux->p_sys;
740
741
0
    p_sys->i_data_offset = vlc_stream_Tell( p_demux->s ) + 4; /* skip edit count */
742
0
    p_sys->i_data_size = i_size == kCHUNK_SIZE_EOF ? kCHUNK_SIZE_EOF : ( i_size - 4 );
743
744
0
    return VLC_SUCCESS;
745
0
}
746
747
static int ReadPaktChunk( demux_t *p_demux )
748
0
{
749
0
    demux_sys_t *p_sys = p_demux->p_sys;
750
751
0
    const uint8_t *p_peek;
752
753
0
    if ( vlc_stream_Peek( p_demux->s, &p_peek, 8 + 8 + 4 + 4 ) < ( 8 + 8 + 4 + 4 ))
754
0
    {
755
0
        msg_Err( p_demux, "Couldn't peek packet descriptions" );
756
0
        return VLC_EGENERIC;
757
0
    }
758
759
0
    if( ReadBEInt64ToUInt64( p_peek, &p_sys->packet_table.i_num_packets ))
760
0
    {
761
0
        msg_Err( p_demux, "Invalid packet table: i_num_packets is negative.");
762
0
        return VLC_EGENERIC;
763
0
    }
764
0
    if( ReadBEInt64ToUInt64( p_peek + 8, &p_sys->packet_table.i_num_valid_frames ))
765
0
    {
766
0
        msg_Err( p_demux, "Invalid packet table: i_num_valid_frames is negative.");
767
0
        return VLC_EGENERIC;
768
0
    }
769
0
    if( ReadBEInt32ToUInt32( p_peek + 16, &p_sys->packet_table.i_num_priming_frames ))
770
0
    {
771
0
        msg_Err( p_demux, "Invalid packet table: i_num_priming_frames is negative.");
772
0
        return VLC_EGENERIC;
773
0
    }
774
0
    if( ReadBEInt32ToUInt32( p_peek + 20, &p_sys->packet_table.i_num_remainder_frames ))
775
0
    {
776
0
        msg_Err( p_demux, "Invalid packet table: i_num_remainder_frames is negative.");
777
0
        return VLC_EGENERIC;
778
0
    }
779
780
0
    p_sys->packet_table.i_descriptions_start = vlc_stream_Tell( p_demux->s ) + 24;
781
782
0
    return VLC_SUCCESS;
783
0
}
784
785
/*****************************************************************************
786
 * Open
787
 *****************************************************************************/
788
static int Open( vlc_object_t *p_this )
789
0
{
790
0
    int i_error = VLC_SUCCESS;
791
792
0
    demux_t     *p_demux = (demux_t*)p_this;
793
0
    demux_sys_t *p_sys;
794
795
0
    const uint8_t *p_peek;
796
797
0
    if( vlc_stream_Peek( p_demux->s, &p_peek, 8 ) < 8 )
798
0
        return VLC_EGENERIC;
799
800
    /* Is it a caf file? */
801
0
    if( memcmp( p_peek, "caff", 4 ))
802
0
        return VLC_EGENERIC;
803
804
    /* check file version (we only handle version 1) */
805
0
    uint16_t i_version = GetWBE( p_peek + 4 );
806
0
    if( i_version != 1 )
807
0
    {
808
0
        msg_Dbg( p_demux, "Unknown caf file version %d.", i_version );
809
0
        return VLC_EGENERIC;
810
0
    }
811
812
    /* check file flags (must be 0) */
813
0
    uint16_t i_flags = GetWBE( p_peek + 6 );
814
0
    if( i_flags != 0 )
815
0
    {
816
0
        msg_Dbg( p_demux, "Unknown caf file flags %d.", i_flags );
817
0
        return VLC_EGENERIC;
818
0
    }
819
820
0
    if( vlc_stream_Read( p_demux->s, NULL, 8 ) != 8 )
821
0
        return VLC_EGENERIC; /* This would be very strange since we justed peeked at these bytes. */
822
823
0
    p_demux->p_sys = calloc( 1, sizeof( demux_sys_t ));
824
0
    if( !p_demux->p_sys ) return VLC_ENOMEM;
825
826
    /* From this point on, we have to free p_sys if we return an error (e.g. "goto caf_open_end") */
827
828
0
    p_sys = p_demux->p_sys;
829
0
    es_format_Init( &p_sys->fmt, AUDIO_ES, 0 );
830
831
0
    vlc_fourcc_t i_fcc;
832
0
    uint64_t i_size;
833
0
    uint64_t i_idx = 0;
834
835
0
    while( NextChunk( p_demux, &i_fcc, &i_size ) == VLC_SUCCESS )
836
0
    {
837
0
        bool b_handled = true;
838
839
0
        switch ( i_fcc )
840
0
        {
841
0
            case VLC_FOURCC( 'd', 'e', 's', 'c' ):
842
843
0
                if( i_idx != 0 )
844
0
                {
845
0
                    msg_Err( p_demux, "The audio description chunk must be the first chunk in a caf file." );
846
0
                    i_error = VLC_EGENERIC;
847
0
                    goto caf_open_end;
848
0
                }
849
850
0
                i_error = ReadDescChunk( p_demux );
851
0
                break;
852
853
0
            case VLC_FOURCC( 'd', 'a', 't', 'a' ):
854
855
0
                i_error = ReadDataChunk( p_demux, i_size );
856
0
                break;
857
858
0
            case VLC_FOURCC( 'p', 'a', 'k', 't' ):
859
860
0
                i_error = ReadPaktChunk( p_demux );
861
0
                break;
862
863
0
            case VLC_FOURCC( 'k', 'u', 'k', 'i' ):
864
865
0
                i_error = ReadKukiChunk( p_demux, i_size );
866
0
                break;
867
868
0
            default:
869
870
0
                b_handled = false;
871
0
                break;
872
0
        }
873
874
0
        if( i_error )
875
0
            goto caf_open_end;
876
877
0
        if( b_handled )
878
0
            msg_Dbg( p_demux, "Found '%4.4s' chunk.", ( char * )&i_fcc );
879
0
        else
880
0
            msg_Dbg( p_demux, "Ignoring '%4.4s' chunk.", ( char * )&i_fcc );
881
882
0
        if( i_size == kCHUNK_SIZE_EOF )
883
0
            break;
884
885
0
        if( vlc_stream_Seek( p_demux->s, vlc_stream_Tell( p_demux->s ) + i_size ) != VLC_SUCCESS )
886
0
            break;
887
888
0
        i_idx++;
889
0
    }
890
891
0
    if ( !p_sys->i_data_offset || p_sys->fmt.i_cat != AUDIO_ES || !p_sys->fmt.audio.i_rate ||
892
0
        ( NeedsPacketTable( p_sys ) && !p_sys->packet_table.i_descriptions_start ))
893
0
    {
894
0
        msg_Err( p_demux, "Did not find all necessary chunks." );
895
0
        i_error = VLC_EGENERIC;
896
0
        goto caf_open_end;
897
0
    }
898
899
0
    p_sys->fmt.i_id = 0;
900
0
    p_sys->es = es_out_Add( p_demux->out, &p_sys->fmt );
901
902
0
    if( !p_sys->es )
903
0
    {
904
0
        msg_Err( p_demux, "Could not add elementary stream." );
905
0
        i_error = VLC_EGENERIC;
906
0
        goto caf_open_end;
907
0
    }
908
909
0
    p_demux->pf_control = Control;
910
0
    p_demux->pf_demux = Demux;
911
0
    return VLC_SUCCESS;
912
913
0
caf_open_end:
914
0
    es_format_Clean( &p_sys->fmt );
915
0
    free( p_sys  );
916
0
    return i_error;
917
0
}
918
919
/*****************************************************************************
920
 * Demux:
921
 *****************************************************************************/
922
static int Demux( demux_t *p_demux )
923
0
{
924
0
    demux_sys_t *p_sys = p_demux->p_sys;
925
0
    block_t     *p_block;
926
927
0
    if( p_sys->i_data_size != kCHUNK_SIZE_EOF && p_sys->position.i_bytes >= p_sys->i_data_size )
928
0
    {
929
        /* EOF */
930
0
        return VLC_DEMUXER_EOF;
931
0
    }
932
933
0
    frame_span_t advance = (frame_span_t){0};
934
935
    /* we will read 50ms at once */
936
0
    uint64_t i_req_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 );
937
938
0
    if( !NeedsPacketTable( p_sys )) /* PCM/IMA4 */
939
0
    {
940
0
        int64_t i_req_frames = ( i_req_samples + ( p_sys->fmt.audio.i_frame_length - 1 )) / p_sys->fmt.audio.i_frame_length;
941
942
0
        if( p_sys->i_data_size != kCHUNK_SIZE_EOF && ( p_sys->position.i_bytes + i_req_frames * p_sys->fmt.audio.i_bytes_per_frame ) > p_sys->i_data_size )
943
0
        {
944
0
            i_req_frames = ( p_sys->i_data_size - p_sys->position.i_frames * p_sys->fmt.audio.i_bytes_per_frame ) / p_sys->fmt.audio.i_bytes_per_frame;
945
0
        }
946
947
0
        advance.i_frames = i_req_frames;
948
0
        advance.i_samples = i_req_frames * p_sys->fmt.audio.i_frame_length;
949
0
        advance.i_bytes = p_sys->fmt.audio.i_bytes_per_frame * advance.i_frames;
950
0
    }
951
0
    else /* use packet table */
952
0
    {
953
0
        uint64_t i_max_frames;
954
0
        if( p_sys->packet_table.i_num_packets > p_sys->position.i_frames )
955
0
            i_max_frames = p_sys->packet_table.i_num_packets - p_sys->position.i_frames;
956
0
        else
957
0
            i_max_frames = 1; /* will be rejected on FrameSpanAddDescription below */
958
959
0
        if( i_max_frames > p_sys->i_max_frames )
960
0
            i_max_frames = p_sys->i_max_frames;
961
962
0
        do
963
0
        {
964
0
            if( FrameSpanAddDescription( p_demux, p_sys->position.i_desc_bytes + advance.i_desc_bytes, &advance ))
965
0
                break;
966
0
        }
967
0
        while ( i_req_samples > advance.i_samples && advance.i_frames < i_max_frames );
968
0
    }
969
970
0
    if( !advance.i_frames )
971
0
    {
972
0
        msg_Err( p_demux, "Unexpected end of file" );
973
0
        return VLC_DEMUXER_EGENERIC;
974
0
    }
975
976
0
    if( vlc_stream_Seek( p_demux->s, p_sys->i_data_offset + p_sys->position.i_bytes ))
977
0
    {
978
0
        if( p_sys->i_data_size == kCHUNK_SIZE_EOF)
979
0
            return VLC_DEMUXER_EOF;
980
981
0
        msg_Err( p_demux, "cannot seek data" );
982
0
        return VLC_DEMUXER_EGENERIC;
983
0
    }
984
985
0
    p_block = vlc_stream_Block( p_demux->s, (int)advance.i_bytes );
986
0
    if( p_block == NULL )
987
0
    {
988
0
        msg_Err( p_demux, "cannot read data" );
989
0
        return VLC_DEMUXER_EGENERIC;
990
0
    }
991
992
0
    p_block->i_dts =
993
0
    p_block->i_pts = FrameSpanGetTime( &p_sys->position, p_sys->fmt.audio.i_rate );
994
995
0
    FrameSpanAddSpan( &p_sys->position, &advance );
996
997
0
    es_out_SetPCR( p_demux->out, p_block->i_pts );
998
0
    es_out_Send( p_demux->out, p_sys->es, p_block );
999
1000
0
    return VLC_DEMUXER_SUCCESS;
1001
0
}
1002
1003
/*****************************************************************************
1004
 * Control:
1005
 *****************************************************************************/
1006
static int Control( demux_t *p_demux, int i_query, va_list args )
1007
0
{
1008
0
    int64_t i_sample;
1009
0
    double f, *pf;
1010
0
    frame_span_t position;
1011
1012
0
    demux_sys_t *p_sys  = p_demux->p_sys;
1013
0
    uint64_t i_num_samples = TotalNumSamples( p_demux );
1014
1015
0
    switch( i_query )
1016
0
    {
1017
0
        case DEMUX_CAN_SEEK:
1018
0
            *va_arg( args, bool * ) = true;
1019
0
            return VLC_SUCCESS;
1020
1021
0
        case DEMUX_GET_LENGTH:
1022
0
            *va_arg( args, vlc_tick_t * ) =
1023
0
                vlc_tick_from_samples( i_num_samples, p_sys->fmt.audio.i_rate );
1024
0
            return VLC_SUCCESS;
1025
1026
0
        case DEMUX_GET_TIME:
1027
0
            *va_arg( args, vlc_tick_t * ) =
1028
0
                vlc_tick_from_samples( p_sys->position.i_samples, p_sys->fmt.audio.i_rate );
1029
0
            return VLC_SUCCESS;
1030
1031
0
        case DEMUX_GET_POSITION:
1032
0
            pf = va_arg( args, double * );
1033
0
            *pf = i_num_samples ? (double)p_sys->position.i_samples / (double)i_num_samples : 0.0;
1034
0
            return VLC_SUCCESS;
1035
1036
0
        case DEMUX_SET_POSITION:
1037
0
            f = va_arg( args, double );
1038
0
            i_sample = f * i_num_samples;
1039
0
            if( SetSpanWithSample( p_demux, &position, i_sample ))
1040
0
                return VLC_EGENERIC;
1041
0
            p_sys->position = position;
1042
0
            return VLC_SUCCESS;
1043
1044
0
        case DEMUX_SET_TIME:
1045
0
            i_sample =
1046
0
                samples_from_vlc_tick( va_arg( args, vlc_tick_t ), p_sys->fmt.audio.i_rate );
1047
0
            if( SetSpanWithSample( p_demux, &position, i_sample ))
1048
0
                return VLC_EGENERIC;
1049
0
            p_sys->position = position;
1050
0
            return VLC_SUCCESS;
1051
1052
0
        case DEMUX_GET_META:
1053
0
            return vlc_stream_Control( p_demux->s, STREAM_GET_META, args );
1054
1055
0
        case DEMUX_CAN_PAUSE:
1056
0
        case DEMUX_SET_PAUSE_STATE:
1057
0
        case DEMUX_CAN_CONTROL_PACE:
1058
0
        case DEMUX_GET_PTS_DELAY:
1059
0
            return demux_vaControlHelper( p_demux->s, p_sys->i_data_offset,
1060
0
                                          p_sys->i_data_size, 0, 1, i_query, args );
1061
1062
0
        default:
1063
0
            return VLC_EGENERIC;
1064
0
    }
1065
1066
0
    return VLC_EGENERIC;
1067
0
}
1068
1069
/*****************************************************************************
1070
 * Close
1071
 *****************************************************************************/
1072
static void Close( vlc_object_t *p_this )
1073
0
{
1074
0
    demux_t     *p_demux = (demux_t*)p_this;
1075
0
    demux_sys_t *p_sys = p_demux->p_sys;
1076
1077
0
    es_format_Clean( &p_sys->fmt );
1078
0
    free( p_sys );
1079
0
}