Coverage Report

Created: 2026-05-16 07:42

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