Coverage Report

Created: 2026-07-12 08:57

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
168
vlc_module_begin ()
51
84
set_subcategory( SUBCAT_INPUT_DEMUX )
52
84
set_description( N_( "CAF demuxer" ))
53
84
set_capability( "demux", 140 )
54
168
set_callbacks( Open, Close )
55
84
add_shortcut( "caf" )
56
84
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
0
{
109
0
    *i_len_out = 0;
110
111
0
    uint64_t i_value = 0;
112
0
    bool finished = false;
113
114
0
    for( uint32_t i = 0; i < i_buff_len; i++ )
115
0
    {
116
0
        if( (( i_value >> 32 ) << 7 ) > UINT32_MAX )
117
0
        {
118
0
            return VLC_EGENERIC; /* overflow */
119
0
        }
120
0
        uint8_t i_byte = p_buff[i];
121
0
        i_value = ( i_value << 7 ) | ( i_byte & 0x7f );
122
123
0
        ( *i_len_out )++;
124
125
0
        if( !( i_byte & 0x80 ))
126
0
        {
127
0
            finished = true;
128
0
            break;
129
0
        }
130
0
    }
131
132
0
    if( !finished )
133
0
    {
134
0
        return VLC_EGENERIC;
135
0
    }
136
137
0
    *pi_value_out = i_value;
138
139
0
    return VLC_SUCCESS;
140
0
}
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
{
146
1
    union
147
1
    {
148
1
        uint64_t uint64;
149
1
        double dbl;
150
1
    } u_64;
151
152
1
    u_64.uint64 = GetQWBE( p );
153
1
    return u_64.dbl;
154
1
}
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
0
{
162
0
    uint32_t i_value = GetDWBE( p );
163
164
0
    if( i_value > INT32_MAX ) return VLC_EGENERIC;
165
166
0
    *i_out = i_value;
167
0
    return VLC_SUCCESS;
168
0
}
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
0
{
176
0
    uint64_t i_value = GetQWBE( p );
177
178
0
    if( i_value > INT64_MAX ) return VLC_EGENERIC;
179
180
0
    *i_out = i_value;
181
0
    return VLC_SUCCESS;
182
0
}
183
184
static inline bool NeedsPacketTable( demux_sys_t *p_sys )
185
164k
{
186
164k
    return ( !p_sys->fmt.audio.i_bytes_per_frame || !p_sys->fmt.audio.i_frame_length );
187
164k
}
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
3
{
235
3
    return VLC_FOURCC( p[0], p[1], p[2], p[3] );
236
3
}
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
164k
{
250
164k
    span1->i_frames += span2->i_frames;
251
164k
    span1->i_samples += span2->i_samples;
252
164k
    span1->i_bytes += span2->i_bytes;
253
164k
    span1->i_desc_bytes += span2->i_desc_bytes;
254
164k
}
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
164k
{
334
164k
    if( !i_sample_rate )
335
0
        return VLC_TICK_INVALID;
336
337
164k
    return vlc_tick_from_samples( span->i_samples, i_sample_rate) + VLC_TICK_0;
338
164k
}
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
3
{
406
3
    uint8_t p_read[12];
407
408
3
    if( vlc_stream_Read( p_demux->s, p_read, 12 ) < 12 )
409
1
        return VLC_EGENERIC;
410
411
2
    *p_fcc = ReadFOURCC( p_read );
412
2
    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
2
    if( i_size > INT64_MAX )
417
0
    {
418
0
        if( *p_fcc == VLC_FOURCC( 'd', 'a', 't', 'a' ) && i_size == UINT64_C( -1 ))
419
0
            i_size = kCHUNK_SIZE_EOF;
420
0
        else
421
0
            return VLC_EGENERIC;
422
0
    }
423
424
2
    *pi_size = i_size;
425
426
2
    return VLC_SUCCESS;
427
2
}
428
429
static int ReadDescChunk( demux_t *p_demux )
430
1
{
431
1
    demux_sys_t *p_sys = p_demux->p_sys;
432
433
1
    const uint8_t *p_peek;
434
435
1
    if ( vlc_stream_Peek( p_demux->s, &p_peek, 8 + 6 * 4 ) < ( 8 + 6 * 4 ))
436
0
    {
437
0
        return VLC_EGENERIC;
438
0
    }
439
440
1
    vlc_fourcc_t i_fmt = ReadFOURCC( p_peek + 8 );
441
1
    uint32_t i_fmt_flags = GetDWBE( p_peek + 12 );
442
443
1
    uint32_t i_bits_per_channel = GetDWBE( p_peek + 28 );
444
1
    uint32_t i_bytes_per_packet = GetDWBE( p_peek + 16 );
445
1
    uint32_t i_frames_per_packet = GetDWBE( p_peek + 20 );
446
1
    uint32_t i_channels_per_frame = GetDWBE( p_peek + 24 );
447
448
1
    if( i_fmt == VLC_CODEC_DVD_LPCM )
449
0
    {
450
0
        if( !i_frames_per_packet || !i_channels_per_frame )
451
0
        {
452
0
            msg_Err( p_demux, "Absurd LPCM parameters (frames_per_packet: %u, channels_per_frame: %u).", i_frames_per_packet, i_channels_per_frame );
453
0
            return VLC_EGENERIC;
454
0
        }
455
456
0
        uint32_t i_unpacked_bits_per_sample = ( i_bytes_per_packet / i_frames_per_packet / i_channels_per_frame ) * 8;
457
458
0
        bool b_is_float = !!( i_fmt_flags & ( 1 << 0 ) );
459
0
        bool b_is_be = !( i_fmt_flags & ( 1 << 1 ) );
460
461
0
        vlc_fourcc_t i_basic_codec = 0;
462
463
0
        if( !b_is_float )
464
0
        {
465
0
            i_basic_codec = b_is_be ? VLC_FOURCC( 't', 'w', 'o', 's' ) : VLC_FOURCC( 's', 'o', 'w', 't' );
466
0
            es_format_Init( &p_sys->fmt, AUDIO_ES, vlc_fourcc_GetCodecAudio( i_basic_codec, i_unpacked_bits_per_sample ));
467
0
        }
468
0
        else
469
0
        {
470
0
            if( i_bits_per_channel == 32 )
471
0
                i_basic_codec = b_is_be ? VLC_CODEC_F32B : VLC_CODEC_F32L;
472
0
            else if( i_bits_per_channel == 64 )
473
0
                i_basic_codec = b_is_be ? VLC_CODEC_F64B : VLC_CODEC_F64L;
474
475
0
            if( i_basic_codec )
476
0
                es_format_Init( &p_sys->fmt, AUDIO_ES, vlc_fourcc_GetCodecAudio( i_basic_codec, i_bits_per_channel ));
477
0
        }
478
0
    }
479
1
    else if( i_fmt == VLC_FOURCC( 'a', 'a', 'c', ' ' ))
480
0
    {
481
0
        const uint32_t kMP4Audio_AAC_LC_ObjectType = 2;
482
483
0
        if( i_fmt_flags != kMP4Audio_AAC_LC_ObjectType )
484
0
        {
485
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 );
486
0
        }
487
488
0
        es_format_Init( &p_sys->fmt, AUDIO_ES, vlc_fourcc_GetCodecAudio( VLC_CODEC_MP4A, 0 ));
489
490
0
    }
491
1
    else
492
1
    {
493
1
        es_format_Init( &p_sys->fmt, AUDIO_ES, vlc_fourcc_GetCodecAudio( i_fmt, 0 ));
494
1
    }
495
496
1
    if( !p_sys->fmt.i_codec )
497
0
    {
498
0
        msg_Err( p_demux, "could not determine codec" );
499
0
        return VLC_EGENERIC;
500
0
    }
501
502
1
    double d_rate = round( GetDBLBE( p_peek ));
503
504
1
    if( d_rate <= 0 || d_rate > UINT_MAX )
505
0
        return VLC_EGENERIC;
506
507
1
    p_sys->fmt.audio.i_rate = (unsigned int)lround( d_rate );
508
1
    if( !p_sys->fmt.audio.i_rate )
509
0
    {
510
0
        msg_Err( p_demux, "Sample rate must be non-zero" );
511
0
        return VLC_EGENERIC;
512
0
    }
513
1
    if( i_channels_per_frame > AOUT_CHAN_MAX)
514
0
    {
515
0
        msg_Err( p_demux, "Too many channels %" PRIu32, i_channels_per_frame );
516
0
        return VLC_EGENERIC;
517
0
    }
518
1
    p_sys->fmt.audio.i_channels = i_channels_per_frame;
519
1
    p_sys->fmt.audio.i_bytes_per_frame = i_bytes_per_packet; /* "mBytesPerPacket" in Apple parlance */
520
1
    p_sys->fmt.audio.i_frame_length = i_frames_per_packet; /* "mFramesPerPacket" in Apple parlance */
521
1
    p_sys->fmt.audio.i_bitspersample = i_bits_per_channel; /* mBitsPerChannel */
522
1
    p_sys->fmt.audio.i_blockalign = i_bytes_per_packet;
523
1
    p_sys->fmt.i_bitrate = i_bits_per_channel * p_sys->fmt.audio.i_rate * i_channels_per_frame;
524
525
1
    if( p_sys->fmt.i_codec == VLC_CODEC_OPUS )
526
0
    {
527
0
        p_sys->i_max_frames = 1;
528
0
    }
529
1
    else p_sys->i_max_frames = UINT_MAX;
530
531
1
    return VLC_SUCCESS;
532
1
}
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
    free(p_sys->fmt.p_extra);
557
0
    p_sys->fmt.i_extra = i_extra;
558
0
    p_sys->fmt.p_extra = i_extra == 0 ? NULL : malloc( i_extra );
559
560
0
    if( i_extra && !p_sys->fmt.p_extra )
561
0
        return VLC_ENOMEM;
562
563
0
    if( i_size == kALAC_NEW_KUKI_SIZE )
564
0
    {
565
0
        uint8_t *p_extra = ( uint8_t * )p_sys->fmt.p_extra;
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 if (i_size != 0)
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
0
{
583
0
    if( *p_offset + 1 > i_size )
584
0
        return false;
585
586
0
    *p_tag = *( p + *p_offset );
587
0
    *p_offset += 1;
588
589
0
    return true;
590
0
}
591
592
static inline bool AACCookieTagLen( uint64_t *p_tag_len, const uint8_t *p, uint64_t *p_offset, uint64_t i_size )
593
0
{
594
0
    uint32_t i_int_size;
595
596
0
    if( ParseVarLenInteger( p + *p_offset, i_size - *p_offset, p_tag_len, &i_int_size ))
597
0
        return false;
598
599
0
    *p_offset += i_int_size;
600
601
0
    return true;
602
0
}
603
604
static inline bool AACCookieChkLen( int64_t i_length, uint64_t i_size, uint64_t i_offset )
605
0
{
606
0
    return ( i_offset + i_length <= i_size );
607
0
}
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
0
{
614
0
    const uint8_t kAAC_ES_DESCR_TAG = 3;
615
0
    const uint8_t kAAC_DEC_CONFIG_DESCR_TAG = 4;
616
0
    const uint8_t kAAC_DEC_SPEC_INFO_TAG = 5;
617
618
0
    demux_sys_t *p_sys = p_demux->p_sys;
619
620
0
    uint64_t i_offset = 0;
621
0
    uint64_t i_kuki_size = 0;
622
0
    uint64_t i_tag_len;
623
0
    uint8_t i_tag;
624
625
0
    if( !AACCookieGetTag( &i_tag, p, &i_offset, i_size )) goto aac_kuki_finish;
626
627
0
    if( i_tag == kAAC_ES_DESCR_TAG )
628
0
    {
629
630
0
        if( !AACCookieTagLen( &i_tag_len, p, &i_offset, i_size )) goto aac_kuki_finish;
631
632
0
        if( !AACCookieChkLen( 3, i_size, i_offset )) goto aac_kuki_finish;
633
0
        i_offset += 2; /* don't care (ES ID) */
634
0
        uint8_t i_flags = *( p + i_offset++ );
635
636
0
        if( i_flags&0x80 )
637
0
        {
638
0
            if( !AACCookieChkLen( 2, i_size, i_offset )) goto aac_kuki_finish;
639
0
            i_offset += 2; /* don't care (dependence) */
640
0
        }
641
0
        if( i_flags&0x40 )
642
0
        {
643
0
            if( !AACCookieChkLen( 1, i_size, i_offset )) goto aac_kuki_finish;
644
0
            uint8_t i_url_len = *( p + i_offset++ );
645
0
            i_offset += i_url_len; /* don't care (url) */
646
0
        }
647
0
        if( i_flags&0x20 )
648
0
        {
649
0
            if( !AACCookieChkLen( 2, i_size, i_offset )) goto aac_kuki_finish;
650
0
            i_offset += 2; /* don't care (OCR) */
651
0
        }
652
653
0
        if( !AACCookieGetTag( &i_tag, p, &i_offset, i_size )) goto aac_kuki_finish;
654
0
    }
655
656
0
    if( i_tag != kAAC_DEC_CONFIG_DESCR_TAG )
657
0
        goto aac_kuki_finish;
658
659
0
    if( !AACCookieTagLen( &i_tag_len, p, &i_offset, i_size )) goto aac_kuki_finish;
660
661
0
    if( !AACCookieChkLen( 1 + 1 + 3 + 4 + 4, i_size, i_offset )) goto aac_kuki_finish;
662
0
    i_offset += ( 1 + 1 + 3 + 4 + 4 ); /* don't care */
663
664
0
    if( !AACCookieGetTag( &i_tag, p, &i_offset, i_size )) goto aac_kuki_finish;
665
666
0
    if( i_tag != kAAC_DEC_SPEC_INFO_TAG ) /* this is the one we need */
667
0
        goto aac_kuki_finish;
668
669
0
    if( !AACCookieTagLen( &i_tag_len, p, &i_offset, i_size )) goto aac_kuki_finish;
670
671
0
    if( i_offset + i_tag_len > i_size )
672
0
        goto aac_kuki_finish;
673
674
0
    i_kuki_size = i_tag_len;
675
676
0
aac_kuki_finish:
677
678
0
    if( !i_kuki_size )
679
0
    {
680
0
        msg_Warn( p_demux, "Error parsing aac cookie. Passing it on to the decoder as is and hoping for the best." );
681
0
        i_kuki_size = i_size;
682
0
        i_offset = 0;
683
0
    }
684
685
0
    free(p_sys->fmt.p_extra);
686
0
    p_sys->fmt.i_extra = i_kuki_size;
687
0
    p_sys->fmt.p_extra = i_kuki_size == 0 ? NULL : malloc( i_kuki_size );
688
689
0
    if( i_kuki_size && !p_sys->fmt.p_extra )
690
0
    {
691
0
        return VLC_ENOMEM;
692
0
    }
693
0
    if ( i_kuki_size )
694
0
    {
695
0
        memcpy( p_sys->fmt.p_extra, p + i_offset, i_kuki_size );
696
0
    }
697
698
0
    return VLC_SUCCESS;
699
0
}
700
701
static int ReadKukiChunk( demux_t *p_demux, uint64_t i_size )
702
0
{
703
0
    demux_sys_t *p_sys = p_demux->p_sys;
704
0
    const uint8_t *p_peek;
705
706
0
    if( i_size > SSIZE_MAX )
707
0
    {
708
0
        msg_Err( p_demux, "Magic Cookie chunk too big" );
709
0
        return VLC_EGENERIC;
710
0
    }
711
712
0
    if( vlc_stream_Peek( p_demux->s, &p_peek, i_size ) < (ssize_t)i_size )
713
0
    {
714
0
        msg_Err( p_demux, "Couldn't peek extra data" );
715
0
        return VLC_EGENERIC;
716
0
    }
717
718
0
    if( p_sys->fmt.i_codec  == VLC_CODEC_ALAC )
719
0
    {
720
0
        int error = ProcessALACCookie( p_demux, p_peek, i_size );
721
0
        if( error ) return error;
722
0
    }
723
0
    else if( p_sys->fmt.i_codec == VLC_CODEC_MP4A )
724
0
    {
725
0
        int error = ProcessAACCookie( p_demux, p_peek, i_size );
726
0
        if( error ) return error;
727
0
    }
728
0
    else if( p_sys->fmt.i_codec != 0 )
729
0
    {
730
0
        free(p_sys->fmt.p_extra);
731
0
        p_sys->fmt.i_extra = i_size;
732
0
        p_sys->fmt.p_extra = i_size == 0 ? NULL : malloc( i_size );
733
734
0
        if( i_size && !p_sys->fmt.p_extra )
735
0
        {
736
0
            return VLC_ENOMEM;
737
0
        }
738
0
        if ( i_size != 0)
739
0
        {
740
0
            memcpy( p_sys->fmt.p_extra, p_peek, p_sys->fmt.i_extra );
741
0
        }
742
0
    }
743
744
0
    return VLC_SUCCESS;
745
0
}
746
747
static int ReadDataChunk( demux_t *p_demux, uint64_t i_size )
748
1
{
749
1
    if( i_size < 4 )
750
0
        return VLC_EGENERIC;
751
752
1
    demux_sys_t *p_sys = p_demux->p_sys;
753
754
1
    p_sys->i_data_offset = vlc_stream_Tell( p_demux->s ) + 4; /* skip edit count */
755
1
    p_sys->i_data_size = i_size == kCHUNK_SIZE_EOF ? kCHUNK_SIZE_EOF : ( i_size - 4 );
756
757
1
    return VLC_SUCCESS;
758
1
}
759
760
static int ReadPaktChunk( demux_t *p_demux )
761
0
{
762
0
    demux_sys_t *p_sys = p_demux->p_sys;
763
764
0
    const uint8_t *p_peek;
765
766
0
    if ( vlc_stream_Peek( p_demux->s, &p_peek, 8 + 8 + 4 + 4 ) < ( 8 + 8 + 4 + 4 ))
767
0
    {
768
0
        msg_Err( p_demux, "Couldn't peek packet descriptions" );
769
0
        return VLC_EGENERIC;
770
0
    }
771
772
0
    if( ReadBEInt64ToUInt64( p_peek, &p_sys->packet_table.i_num_packets ))
773
0
    {
774
0
        msg_Err( p_demux, "Invalid packet table: i_num_packets is negative.");
775
0
        return VLC_EGENERIC;
776
0
    }
777
0
    if( ReadBEInt64ToUInt64( p_peek + 8, &p_sys->packet_table.i_num_valid_frames ))
778
0
    {
779
0
        msg_Err( p_demux, "Invalid packet table: i_num_valid_frames is negative.");
780
0
        return VLC_EGENERIC;
781
0
    }
782
0
    if( ReadBEInt32ToUInt32( p_peek + 16, &p_sys->packet_table.i_num_priming_frames ))
783
0
    {
784
0
        msg_Err( p_demux, "Invalid packet table: i_num_priming_frames is negative.");
785
0
        return VLC_EGENERIC;
786
0
    }
787
0
    if( ReadBEInt32ToUInt32( p_peek + 20, &p_sys->packet_table.i_num_remainder_frames ))
788
0
    {
789
0
        msg_Err( p_demux, "Invalid packet table: i_num_remainder_frames is negative.");
790
0
        return VLC_EGENERIC;
791
0
    }
792
793
0
    p_sys->packet_table.i_descriptions_start = vlc_stream_Tell( p_demux->s ) + 24;
794
795
0
    return VLC_SUCCESS;
796
0
}
797
798
/*****************************************************************************
799
 * Open
800
 *****************************************************************************/
801
static int Open( vlc_object_t *p_this )
802
12
{
803
12
    int i_error = VLC_SUCCESS;
804
805
12
    demux_t     *p_demux = (demux_t*)p_this;
806
12
    demux_sys_t *p_sys;
807
808
12
    const uint8_t *p_peek;
809
810
12
    if( vlc_stream_Peek( p_demux->s, &p_peek, 8 ) < 8 )
811
0
        return VLC_EGENERIC;
812
813
    /* Is it a caf file? */
814
12
    if( memcmp( p_peek, "caff", 4 ))
815
11
        return VLC_EGENERIC;
816
817
    /* check file version (we only handle version 1) */
818
1
    uint16_t i_version = GetWBE( p_peek + 4 );
819
1
    if( i_version != 1 )
820
0
    {
821
0
        msg_Dbg( p_demux, "Unknown caf file version %d.", i_version );
822
0
        return VLC_EGENERIC;
823
0
    }
824
825
    /* check file flags (must be 0) */
826
1
    uint16_t i_flags = GetWBE( p_peek + 6 );
827
1
    if( i_flags != 0 )
828
0
    {
829
0
        msg_Dbg( p_demux, "Unknown caf file flags %d.", i_flags );
830
0
        return VLC_EGENERIC;
831
0
    }
832
833
1
    if( vlc_stream_Read( p_demux->s, NULL, 8 ) != 8 )
834
0
        return VLC_EGENERIC; /* This would be very strange since we justed peeked at these bytes. */
835
836
1
    p_demux->p_sys = calloc( 1, sizeof( demux_sys_t ));
837
1
    if( !p_demux->p_sys ) return VLC_ENOMEM;
838
839
    /* From this point on, we have to free p_sys if we return an error (e.g. "goto caf_open_end") */
840
841
1
    p_sys = p_demux->p_sys;
842
1
    es_format_Init( &p_sys->fmt, AUDIO_ES, 0 );
843
844
1
    vlc_fourcc_t i_fcc;
845
1
    uint64_t i_size;
846
1
    uint64_t i_idx = 0;
847
848
3
    while( NextChunk( p_demux, &i_fcc, &i_size ) == VLC_SUCCESS )
849
2
    {
850
2
        bool b_handled = true;
851
852
2
        switch ( i_fcc )
853
2
        {
854
1
            case VLC_FOURCC( 'd', 'e', 's', 'c' ):
855
856
1
                if( i_idx != 0 )
857
0
                {
858
0
                    msg_Err( p_demux, "The audio description chunk must be the first chunk in a caf file." );
859
0
                    i_error = VLC_EGENERIC;
860
0
                    goto caf_open_end;
861
0
                }
862
863
1
                i_error = ReadDescChunk( p_demux );
864
1
                break;
865
866
1
            case VLC_FOURCC( 'd', 'a', 't', 'a' ):
867
868
1
                i_error = ReadDataChunk( p_demux, i_size );
869
1
                break;
870
871
0
            case VLC_FOURCC( 'p', 'a', 'k', 't' ):
872
873
0
                i_error = ReadPaktChunk( p_demux );
874
0
                break;
875
876
0
            case VLC_FOURCC( 'k', 'u', 'k', 'i' ):
877
878
0
                i_error = ReadKukiChunk( p_demux, i_size );
879
0
                break;
880
881
0
            default:
882
883
0
                b_handled = false;
884
0
                break;
885
2
        }
886
887
2
        if( i_error )
888
0
            goto caf_open_end;
889
890
2
        if( b_handled )
891
2
            msg_Dbg( p_demux, "Found '%4.4s' chunk.", ( char * )&i_fcc );
892
0
        else
893
2
            msg_Dbg( p_demux, "Ignoring '%4.4s' chunk.", ( char * )&i_fcc );
894
895
2
        if( i_size == kCHUNK_SIZE_EOF )
896
0
            break;
897
898
2
        if( vlc_stream_Seek( p_demux->s, vlc_stream_Tell( p_demux->s ) + i_size ) != VLC_SUCCESS )
899
0
            break;
900
901
2
        i_idx++;
902
2
    }
903
904
1
    if ( !p_sys->i_data_offset || p_sys->fmt.i_cat != AUDIO_ES || !p_sys->fmt.audio.i_rate ||
905
1
        ( NeedsPacketTable( p_sys ) && !p_sys->packet_table.i_descriptions_start ))
906
0
    {
907
0
        msg_Err( p_demux, "Did not find all necessary chunks." );
908
0
        i_error = VLC_EGENERIC;
909
0
        goto caf_open_end;
910
0
    }
911
912
1
    p_sys->fmt.i_id = 0;
913
1
    p_sys->es = es_out_Add( p_demux->out, &p_sys->fmt );
914
915
1
    if( !p_sys->es )
916
0
    {
917
0
        msg_Err( p_demux, "Could not add elementary stream." );
918
0
        i_error = VLC_EGENERIC;
919
0
        goto caf_open_end;
920
0
    }
921
922
1
    p_demux->pf_control = Control;
923
1
    p_demux->pf_demux = Demux;
924
1
    return VLC_SUCCESS;
925
926
0
caf_open_end:
927
0
    es_format_Clean( &p_sys->fmt );
928
0
    free( p_sys  );
929
0
    return i_error;
930
1
}
931
932
/*****************************************************************************
933
 * Demux:
934
 *****************************************************************************/
935
static int Demux( demux_t *p_demux )
936
164k
{
937
164k
    demux_sys_t *p_sys = p_demux->p_sys;
938
164k
    block_t     *p_block;
939
940
164k
    if( p_sys->i_data_size != kCHUNK_SIZE_EOF && p_sys->position.i_bytes >= p_sys->i_data_size )
941
0
    {
942
        /* EOF */
943
0
        return VLC_DEMUXER_EOF;
944
0
    }
945
946
164k
    frame_span_t advance = (frame_span_t){0};
947
948
    /* we will read 50ms at once */
949
164k
    uint64_t i_req_samples = __MAX( p_sys->fmt.audio.i_rate / 20, 1 );
950
951
164k
    if( !NeedsPacketTable( p_sys )) /* PCM/IMA4 */
952
164k
    {
953
164k
        int64_t i_req_frames = ( i_req_samples + ( p_sys->fmt.audio.i_frame_length - 1 )) / p_sys->fmt.audio.i_frame_length;
954
955
164k
        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 )
956
0
        {
957
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;
958
0
        }
959
960
164k
        advance.i_frames = i_req_frames;
961
164k
        advance.i_samples = i_req_frames * p_sys->fmt.audio.i_frame_length;
962
164k
        advance.i_bytes = p_sys->fmt.audio.i_bytes_per_frame * advance.i_frames;
963
164k
    }
964
0
    else /* use packet table */
965
0
    {
966
0
        uint64_t i_max_frames;
967
0
        if( p_sys->packet_table.i_num_packets > p_sys->position.i_frames )
968
0
            i_max_frames = p_sys->packet_table.i_num_packets - p_sys->position.i_frames;
969
0
        else
970
0
            i_max_frames = 1; /* will be rejected on FrameSpanAddDescription below */
971
972
0
        if( i_max_frames > p_sys->i_max_frames )
973
0
            i_max_frames = p_sys->i_max_frames;
974
975
0
        do
976
0
        {
977
0
            if( FrameSpanAddDescription( p_demux, p_sys->position.i_desc_bytes + advance.i_desc_bytes, &advance ))
978
0
                break;
979
0
        }
980
0
        while ( i_req_samples > advance.i_samples && advance.i_frames < i_max_frames );
981
0
    }
982
983
164k
    if( !advance.i_frames )
984
0
    {
985
0
        msg_Err( p_demux, "Unexpected end of file" );
986
0
        return VLC_DEMUXER_EGENERIC;
987
0
    }
988
989
164k
    if( vlc_stream_Seek( p_demux->s, p_sys->i_data_offset + p_sys->position.i_bytes ))
990
0
    {
991
0
        if( p_sys->i_data_size == kCHUNK_SIZE_EOF)
992
0
            return VLC_DEMUXER_EOF;
993
994
0
        msg_Err( p_demux, "cannot seek data" );
995
0
        return VLC_DEMUXER_EGENERIC;
996
0
    }
997
998
164k
    p_block = vlc_stream_Block( p_demux->s, (int)advance.i_bytes );
999
164k
    if( p_block == NULL )
1000
1
    {
1001
1
        msg_Err( p_demux, "cannot read data" );
1002
1
        return VLC_DEMUXER_EGENERIC;
1003
1
    }
1004
1005
164k
    p_block->i_dts =
1006
164k
    p_block->i_pts = FrameSpanGetTime( &p_sys->position, p_sys->fmt.audio.i_rate );
1007
1008
164k
    FrameSpanAddSpan( &p_sys->position, &advance );
1009
1010
164k
    es_out_SetPCR( p_demux->out, p_block->i_pts );
1011
164k
    es_out_Send( p_demux->out, p_sys->es, p_block );
1012
1013
164k
    return VLC_DEMUXER_SUCCESS;
1014
164k
}
1015
1016
/*****************************************************************************
1017
 * Control:
1018
 *****************************************************************************/
1019
static int Control( demux_t *p_demux, int i_query, va_list args )
1020
0
{
1021
0
    int64_t i_sample;
1022
0
    double f, *pf;
1023
0
    frame_span_t position;
1024
1025
0
    demux_sys_t *p_sys  = p_demux->p_sys;
1026
0
    uint64_t i_num_samples = TotalNumSamples( p_demux );
1027
1028
0
    switch( i_query )
1029
0
    {
1030
0
        case DEMUX_CAN_SEEK:
1031
0
            *va_arg( args, bool * ) = true;
1032
0
            return VLC_SUCCESS;
1033
1034
0
        case DEMUX_GET_LENGTH:
1035
0
            *va_arg( args, vlc_tick_t * ) =
1036
0
                vlc_tick_from_samples( i_num_samples, p_sys->fmt.audio.i_rate );
1037
0
            return VLC_SUCCESS;
1038
1039
0
        case DEMUX_GET_TIME:
1040
0
            *va_arg( args, vlc_tick_t * ) =
1041
0
                vlc_tick_from_samples( p_sys->position.i_samples, p_sys->fmt.audio.i_rate );
1042
0
            return VLC_SUCCESS;
1043
1044
0
        case DEMUX_GET_POSITION:
1045
0
            pf = va_arg( args, double * );
1046
0
            *pf = i_num_samples ? (double)p_sys->position.i_samples / (double)i_num_samples : 0.0;
1047
0
            return VLC_SUCCESS;
1048
1049
0
        case DEMUX_SET_POSITION:
1050
0
            f = va_arg( args, double );
1051
0
            i_sample = f * i_num_samples;
1052
0
            if( SetSpanWithSample( p_demux, &position, i_sample ))
1053
0
                return VLC_EGENERIC;
1054
0
            p_sys->position = position;
1055
0
            return VLC_SUCCESS;
1056
1057
0
        case DEMUX_SET_TIME:
1058
0
            i_sample =
1059
0
                samples_from_vlc_tick( va_arg( args, vlc_tick_t ), p_sys->fmt.audio.i_rate );
1060
0
            if( SetSpanWithSample( p_demux, &position, i_sample ))
1061
0
                return VLC_EGENERIC;
1062
0
            p_sys->position = position;
1063
0
            return VLC_SUCCESS;
1064
1065
0
        case DEMUX_GET_META:
1066
0
            return vlc_stream_Control( p_demux->s, STREAM_GET_META, args );
1067
1068
0
        case DEMUX_CAN_PAUSE:
1069
0
        case DEMUX_SET_PAUSE_STATE:
1070
0
        case DEMUX_CAN_CONTROL_PACE:
1071
0
        case DEMUX_GET_PTS_DELAY:
1072
0
            return demux_vaControlHelper( p_demux->s, p_sys->i_data_offset,
1073
0
                                          p_sys->i_data_size, 0, 1, i_query, args );
1074
1075
0
        default:
1076
0
            return VLC_EGENERIC;
1077
0
    }
1078
1079
0
    return VLC_EGENERIC;
1080
0
}
1081
1082
/*****************************************************************************
1083
 * Close
1084
 *****************************************************************************/
1085
static void Close( vlc_object_t *p_this )
1086
1
{
1087
1
    demux_t     *p_demux = (demux_t*)p_this;
1088
1
    demux_sys_t *p_sys = p_demux->p_sys;
1089
1090
1
    es_format_Clean( &p_sys->fmt );
1091
1
    free( p_sys );
1092
1
}