Coverage Report

Created: 2023-06-07 06:30

/src/vlc/modules/packetizer/mpeg4audio.c
Line
Count
Source (jump to first uncovered line)
1
/*****************************************************************************
2
 * mpeg4audio.c: parse and packetize an MPEG 4 audio stream
3
 *****************************************************************************
4
 * Copyright (C) 2001, 2002, 2006 VLC authors and VideoLAN
5
 *
6
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7
 *          Gildas Bazin <gbazin@netcourrier.com>
8
 *
9
 * This program is free software; you can redistribute it and/or modify it
10
 * under the terms of the GNU Lesser General Public License as published by
11
 * the Free Software Foundation; either version 2.1 of the License, or
12
 * (at your option) any later version.
13
 *
14
 * This program is distributed in the hope that it will be useful,
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17
 * GNU Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program; if not, write to the Free Software Foundation,
21
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22
 *****************************************************************************/
23
24
/*****************************************************************************
25
 * Preamble
26
 *****************************************************************************/
27
28
#ifdef HAVE_CONFIG_H
29
# include "config.h"
30
#endif
31
32
#include <vlc_common.h>
33
#include <vlc_plugin.h>
34
#include <vlc_codec.h>
35
#include <vlc_block.h>
36
#include <vlc_bits.h>
37
38
#include <vlc_block_helper.h>
39
#include "packetizer_helper.h"
40
#include "mpeg4audio.h"
41
42
#include <assert.h>
43
44
/* AAC Config in ES:
45
 *
46
 * AudioObjectType          5 bits
47
 * samplingFrequencyIndex   4 bits
48
 * if (samplingFrequencyIndex == 0xF)
49
 *  samplingFrequency   24 bits
50
 * channelConfiguration     4 bits
51
 * GA_SpecificConfig
52
 *  FrameLengthFlag         1 bit 1024 or 960
53
 *  DependsOnCoreCoder      1 bit (always 0)
54
 *  ExtensionFlag           1 bit (always 0)
55
 */
56
57
/*****************************************************************************
58
 * decoder_sys_t : decoder descriptor
59
 *****************************************************************************/
60
typedef struct
61
{
62
    enum mpeg4_audioObjectType i_object_type;
63
    unsigned i_samplerate;
64
    uint8_t i_channel_configuration;
65
    int8_t i_sbr;          // 0: no sbr, 1: sbr, -1: unknown
66
    int8_t i_ps;           // 0: no ps,  1: ps,  -1: unknown
67
68
    struct
69
    {
70
        enum mpeg4_audioObjectType i_object_type;
71
        unsigned i_samplerate;
72
        uint8_t i_channel_configuration;
73
    } extension;
74
75
    /* GASpecific */
76
    unsigned i_frame_length;   // 1024 or 960
77
78
} mpeg4_asc_t;
79
80
#define LATM_MAX_EXTRA_SIZE 64
81
typedef struct
82
{
83
    uint8_t i_program;
84
    uint8_t i_layer;
85
86
    unsigned i_frame_length;         // type 1
87
    uint8_t i_frame_length_type;
88
    uint8_t i_frame_length_index;   // type 3 4 5 6 7
89
90
    mpeg4_asc_t cfg;
91
92
    /* Raw configuration */
93
    size_t i_extra;
94
    uint8_t extra[LATM_MAX_EXTRA_SIZE];
95
96
} latm_stream_t;
97
98
#define LATM_MAX_LAYER (8)
99
#define LATM_MAX_PROGRAM (16)
100
typedef struct
101
{
102
    bool b_same_time_framing;
103
    uint8_t i_sub_frames;
104
    uint8_t i_programs;
105
106
    uint8_t pi_layers[LATM_MAX_PROGRAM];
107
108
    uint8_t pi_stream[LATM_MAX_PROGRAM][LATM_MAX_LAYER];
109
110
    uint8_t i_streams;
111
    latm_stream_t stream[LATM_MAX_PROGRAM*LATM_MAX_LAYER];
112
113
    uint32_t i_other_data;
114
    int16_t  i_crc;  /* -1 if not set */
115
} latm_mux_t;
116
117
typedef struct
118
{
119
    /*
120
     * Input properties
121
     */
122
    int i_state;
123
    int i_type;
124
125
    block_bytestream_t bytestream;
126
127
    /*
128
     * Common properties
129
     */
130
    date_t  end_date;
131
    vlc_tick_t i_pts;
132
    bool b_discontuinity;
133
134
    int i_frame_size;
135
    unsigned int i_channels;
136
    unsigned int i_rate, i_frame_length, i_header_size;
137
    int i_aac_profile;
138
139
    int i_input_rate;
140
141
    /* LOAS */
142
    bool b_latm_cfg;
143
    latm_mux_t latm;
144
145
    int i_warnings;
146
} decoder_sys_t;
147
148
enum
149
{
150
    WARN_CRC_UNSUPPORTED = 1
151
};
152
153
0
#define WARN_ONCE(warn, msg) do{\
154
0
        decoder_sys_t *p_sys = p_dec->p_sys;\
155
0
        if( (p_sys->i_warnings & warn) == 0 )\
156
0
        {\
157
0
            p_sys->i_warnings |= warn;\
158
0
            msg_Warn( p_dec, msg );\
159
0
        }\
160
0
    } while(0)
161
162
enum {
163
    TYPE_UNKNOWN, /* AAC samples with[out] headers */
164
    TYPE_UNKNOWN_NONRAW, /* [un]packetized ADTS or LOAS */
165
    TYPE_RAW,    /* RAW AAC frames */
166
    TYPE_ADTS,
167
    TYPE_LOAS
168
};
169
170
static const int pi_sample_rates[16] =
171
{
172
    96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
173
    16000, 12000, 11025, 8000,  7350,  0,     0,     0
174
};
175
176
177
static int ChannelConfigurationToVLC(uint8_t i_channel)
178
0
{
179
0
    if (i_channel == 7)
180
0
        return 8; // 7.1
181
0
    if (i_channel >= 8)
182
0
        return -1;
183
0
    return i_channel;
184
0
}
185
186
static int AOTtoAACProfile(uint8_t i_object_type)
187
0
{
188
0
    switch(i_object_type)
189
0
    {
190
0
        case AOT_AAC_MAIN:
191
0
        case AOT_AAC_LC:
192
0
        case AOT_AAC_SSR:
193
0
        case AOT_AAC_LTP:
194
0
        case AOT_AAC_SBR:
195
0
        case AOT_AAC_SC:
196
0
        case AOT_ER_AAC_LD:
197
0
        case AOT_AAC_PS:
198
0
        case AOT_ER_AAC_ELD:
199
0
            {
200
0
            static_assert(AOT_AAC_MAIN == AAC_PROFILE_MAIN + 1,
201
0
                          "invalid profile to object mapping");
202
0
            return i_object_type - 1;
203
0
            }
204
0
        default:
205
0
            return -1;
206
0
    }
207
0
}
208
209
0
#define ADTS_HEADER_SIZE 9
210
0
#define LOAS_HEADER_SIZE 3
211
212
/****************************************************************************
213
 * Local prototypes
214
 ****************************************************************************/
215
static int  OpenPacketizer(vlc_object_t *);
216
static void ClosePacketizer(vlc_object_t *);
217
218
static block_t *Packetize    (decoder_t *, block_t **);
219
static void     Flush( decoder_t * );
220
221
static int Mpeg4ReadAudioSpecificConfig(bs_t *s, mpeg4_asc_t *p_cfg, bool);
222
223
/*****************************************************************************
224
 * Module descriptor
225
 *****************************************************************************/
226
4
vlc_module_begin ()
227
2
    set_subcategory(SUBCAT_SOUT_PACKETIZER)
228
2
    set_description(N_("MPEG4 audio packetizer"))
229
2
    set_capability("packetizer", 50)
230
4
    set_callbacks(OpenPacketizer, ClosePacketizer)
231
2
vlc_module_end ()
232
233
/*****************************************************************************
234
 * OpenPacketizer: probe the packetizer and return score
235
 *****************************************************************************/
236
static int OpenPacketizer(vlc_object_t *p_this)
237
37
{
238
37
    decoder_t *p_dec = (decoder_t*)p_this;
239
37
    decoder_sys_t *p_sys;
240
241
37
    if (p_dec->fmt_in->i_codec != VLC_CODEC_MP4A)
242
37
        return VLC_EGENERIC;
243
244
    /* Allocate the memory needed to store the decoder's structure */
245
0
    if ((p_dec->p_sys = p_sys = (decoder_sys_t *)malloc(sizeof(decoder_sys_t))) == NULL)
246
0
        return VLC_ENOMEM;
247
248
    /* Misc init */
249
0
    p_sys->i_state = STATE_NOSYNC;
250
0
    p_sys->b_discontuinity = false;
251
0
    block_BytestreamInit(&p_sys->bytestream);
252
0
    p_sys->b_latm_cfg = false;
253
0
    p_sys->i_warnings = 0;
254
255
    /* Set output properties */
256
0
    p_dec->fmt_out.i_codec = VLC_CODEC_MP4A;
257
258
0
    msg_Dbg(p_dec, "running MPEG4 audio packetizer");
259
260
    /*
261
     * We need to handle 3 cases.
262
     * Case 1 : RAW AAC samples without sync header
263
     *          The demuxer shouldn't need packetizer, see next case.
264
     * Case 2 : AAC samples with ADTS or LOAS/LATM header
265
     *          Some mux (avi) can't distinguish the both
266
     *          cases above, and then forwards to packetizer
267
     *          which should check for header and rewire to case below
268
     * Case 3 : Non packetized ADTS or LOAS/LATM
269
     *          The demuxer needs to set original_codec for hardwiring
270
     */
271
272
0
    switch (p_dec->fmt_in->i_original_fourcc)
273
0
    {
274
0
        case VLC_FOURCC('L','A','T','M'):
275
0
            p_sys->i_type = TYPE_LOAS;
276
0
            msg_Dbg(p_dec, "LOAS/LATM Mode");
277
0
            break;
278
279
0
        case VLC_FOURCC('A','D','T','S'):
280
0
            p_sys->i_type = TYPE_ADTS;
281
0
            msg_Dbg(p_dec, "ADTS Mode");
282
0
            break;
283
284
0
        case VLC_FOURCC('H','E','A','D'):
285
0
            p_sys->i_type = TYPE_UNKNOWN_NONRAW;
286
0
            break;
287
288
0
        default:
289
0
            p_sys->i_type = TYPE_UNKNOWN;
290
0
            break;
291
0
    }
292
293
    /* Some mux (avi) do send RAW AAC without extradata,
294
       and LATM can be sent with out-of-band audioconfig,
295
       (avformat sets m4a extradata in both cases)
296
       so we can't rely on extradata to guess multiplexing */
297
0
    p_dec->fmt_out.audio.i_rate = p_dec->fmt_in->audio.i_rate;
298
299
0
    if(p_dec->fmt_in->i_extra)
300
0
    {
301
0
        mpeg4_asc_t asc;
302
0
        bs_t s;
303
0
        bs_init(&s, p_dec->fmt_in->p_extra, p_dec->fmt_in->i_extra);
304
0
        if(Mpeg4ReadAudioSpecificConfig(&s, &asc, true) == VLC_SUCCESS)
305
0
        {
306
0
            p_dec->fmt_out.audio.i_rate = asc.i_samplerate;
307
0
            p_dec->fmt_out.audio.i_frame_length = asc.i_frame_length;
308
0
            p_dec->fmt_out.audio.i_channels =
309
0
                    ChannelConfigurationToVLC(asc.i_channel_configuration);
310
0
            if(p_dec->fmt_out.i_profile != -1)
311
0
                p_dec->fmt_out.i_profile = AOTtoAACProfile(asc.i_object_type);
312
313
0
            msg_Dbg(p_dec, "%sAAC%s %dHz %d samples/frame",
314
0
                    (asc.i_sbr) ? "HE-" : "",
315
0
                    (asc.i_ps) ? "v2" : "",
316
0
                    (asc.i_sbr) ? p_dec->fmt_out.audio.i_rate << 1
317
0
                                : p_dec->fmt_out.audio.i_rate,
318
0
                    p_dec->fmt_out.audio.i_frame_length);
319
0
        }
320
321
0
        p_dec->fmt_out.p_extra = malloc(p_dec->fmt_in->i_extra);
322
0
        if (!p_dec->fmt_out.p_extra)
323
0
            return VLC_ENOMEM;
324
0
        p_dec->fmt_out.i_extra = p_dec->fmt_in->i_extra;
325
0
        memcpy(p_dec->fmt_out.p_extra, p_dec->fmt_in->p_extra,
326
0
                p_dec->fmt_in->i_extra);
327
0
    }
328
    /* else() We will try to create a AAC Config from adts/loas */
329
330
0
    date_Init(&p_sys->end_date, p_dec->fmt_out.audio.i_rate ?
331
0
                                p_dec->fmt_out.audio.i_rate : 48000, 1);
332
333
    /* Set callbacks */
334
0
    p_dec->pf_packetize = Packetize;
335
0
    p_dec->pf_flush = Flush;
336
0
    p_dec->pf_get_cc = NULL;
337
338
0
    return VLC_SUCCESS;
339
0
}
340
341
/*****************************************************************************
342
 * ClosePacketizer: clean up the packetizer
343
 *****************************************************************************/
344
static void ClosePacketizer(vlc_object_t *p_this)
345
0
{
346
0
    decoder_t *p_dec = (decoder_t *)p_this;
347
0
    decoder_sys_t *p_sys = p_dec->p_sys;
348
349
0
    block_BytestreamRelease(&p_sys->bytestream);
350
0
    free(p_sys);
351
0
}
352
353
/****************************************************************************
354
 * ForwardRawBlock:
355
 ****************************************************************************
356
 * This function must be fed with complete frames.
357
 ****************************************************************************/
358
static block_t *ForwardRawBlock(decoder_t *p_dec, block_t **pp_block)
359
0
{
360
0
    decoder_sys_t *p_sys = p_dec->p_sys;
361
0
    block_t *p_block;
362
363
0
    if (!pp_block || !*pp_block)
364
0
        return NULL;
365
366
0
    p_block = *pp_block;
367
0
    *pp_block = NULL; /* Don't reuse this block */
368
369
0
    vlc_tick_t i_diff = 0;
370
0
    if (p_block->i_pts != VLC_TICK_INVALID &&
371
0
        p_block->i_pts != date_Get(&p_sys->end_date))
372
0
    {
373
0
        if(date_Get(&p_sys->end_date) != VLC_TICK_INVALID)
374
0
            i_diff = llabs( date_Get(&p_sys->end_date) - p_block->i_pts );
375
0
        date_Set(&p_sys->end_date, p_block->i_pts);
376
0
    }
377
378
0
    p_block->i_pts = p_block->i_dts = date_Get(&p_sys->end_date);
379
380
    /* Might not be known due to missing extradata,
381
       will be set to block pts above */
382
0
    if(p_dec->fmt_out.audio.i_frame_length && p_block->i_pts != VLC_TICK_INVALID)
383
0
    {
384
0
        p_block->i_length = date_Increment(&p_sys->end_date,
385
0
            p_dec->fmt_out.audio.i_frame_length) - p_block->i_pts;
386
387
0
        if( i_diff > p_block->i_length )
388
0
            p_sys->b_discontuinity = true;
389
0
    }
390
391
0
    return p_block;
392
0
}
393
394
/****************************************************************************
395
 * ADTS helpers
396
 ****************************************************************************/
397
static int ADTSSyncInfo(decoder_t * p_dec, const uint8_t * p_buf,
398
                         unsigned int * pi_channels,
399
                         unsigned int * pi_sample_rate,
400
                         unsigned int * pi_frame_length,
401
                         unsigned int * pi_header_size)
402
0
{
403
0
    int i_profile, i_sample_rate_idx, i_frame_size;
404
0
    bool b_crc;
405
406
    /* Fixed header between frames */
407
    //int i_id = ((p_buf[1] >> 3) & 0x01) ? 2 : 4; /* MPEG-2 or 4 */
408
0
    b_crc = !(p_buf[1] & 0x01);
409
0
    i_profile = p_buf[2] >> 6;
410
0
    i_sample_rate_idx = (p_buf[2] >> 2) & 0x0f;
411
0
    *pi_sample_rate = pi_sample_rates[i_sample_rate_idx];
412
    //private_bit = (p_buf[2] >> 1) & 0x01;
413
0
    *pi_channels = ((p_buf[2] & 0x01) << 2) | ((p_buf[3] >> 6) & 0x03);
414
0
    if (*pi_channels == 0) /* workaround broken streams */
415
0
        *pi_channels = 2;
416
    //original_copy = (p_buf[3] >> 5) & 0x01;
417
    //home = (p_buf[3] >> 4) & 0x01;
418
419
    /* Variable header */
420
    //copyright_id_bit = (p_buf[3] >> 3) & 0x01;
421
    //copyright_id_start = (p_buf[3] >> 2) & 0x01;
422
0
    i_frame_size = ((p_buf[3] & 0x03) << 11) | (p_buf[4] << 3) |
423
0
                   ((p_buf[5] >> 5) /*& 0x7*/);
424
    //uint16_t buffer_fullness = ((p_buf[5] & 0x1f) << 6) | (p_buf[6] >> 2);
425
0
    unsigned short i_raw_blocks_in_frame = p_buf[6] & 0x03;
426
427
0
    if (!*pi_sample_rate || !i_frame_size) {
428
0
        msg_Warn(p_dec, "Invalid ADTS header");
429
0
        return 0;
430
0
    }
431
432
0
    *pi_frame_length = 1024;
433
434
0
    if (i_raw_blocks_in_frame == 0) {
435
0
        if (b_crc) {
436
0
            WARN_ONCE(WARN_CRC_UNSUPPORTED, "ADTS CRC not supported");
437
            //uint16_t crc = (p_buf[7] << 8) | p_buf[8];
438
0
        }
439
0
    } else {
440
0
        msg_Err(p_dec, "Multiple blocks per frame in ADTS not supported");
441
0
        return 0;
442
#if 0
443
        int i;
444
        const uint8_t *p_pos = p_buf + 7;
445
        uint16_t crc_block;
446
        uint16_t i_block_pos[3];
447
        if (b_crc) {
448
            for (i = 0 ; i < i_raw_blocks_in_frame ; i++) {
449
                /* the 1st block's position is known ... */
450
                i_block_pos[i] = (*p_pos << 8) | *(p_pos+1);
451
                p_pos += 2;
452
            }
453
            crc_block = (*p_pos << 8) | *(p_pos+1);
454
            p_pos += 2;
455
        }
456
        for (i = 0 ; i <= i_raw_blocks_in_frame ; i++) {
457
            //read 1 block
458
            if (b_crc) {
459
                WARN_ONCE(WARN_CRC_UNSUPPORTED, "ADTS CRC not supported");
460
                //uint16_t crc = (*p_pos << 8) | *(p_pos+1);
461
                //p_pos += 2;
462
            }
463
        }
464
#endif
465
0
    }
466
467
468
    /* Build the decoder specific info header */
469
0
    if (!p_dec->fmt_out.i_extra) {
470
0
        p_dec->fmt_out.p_extra = malloc(2);
471
0
        if (!p_dec->fmt_out.p_extra)
472
0
            return 0;
473
0
        p_dec->fmt_out.i_extra = 2;
474
0
        ((uint8_t *)p_dec->fmt_out.p_extra)[0] =
475
0
            (i_profile + 1) << 3 | (i_sample_rate_idx >> 1);
476
0
        ((uint8_t *)p_dec->fmt_out.p_extra)[1] =
477
0
            ((i_sample_rate_idx & 0x01) << 7) | (*pi_channels <<3);
478
0
    }
479
480
    /* ADTS header length */
481
0
    *pi_header_size = b_crc ? 9 : 7;
482
483
0
    return i_frame_size - *pi_header_size;
484
0
}
485
486
/****************************************************************************
487
 * LOAS helpers
488
 ****************************************************************************/
489
static int LOASSyncInfo(uint8_t p_header[LOAS_HEADER_SIZE], unsigned int *pi_header_size)
490
0
{
491
0
    *pi_header_size = 3;
492
0
    return ((p_header[1] & 0x1f) << 8) + p_header[2];
493
0
}
494
495
static int Mpeg4GAProgramConfigElement(bs_t *s)
496
0
{
497
    /* TODO compute channels count ? */
498
0
    int i_tag = bs_read(s, 4);
499
0
    if (i_tag != 0x05)
500
0
        return -1;
501
0
    bs_skip(s, 2 + 4); // object type + sampling index
502
0
    int i_num_front = bs_read(s, 4);
503
0
    int i_num_side = bs_read(s, 4);
504
0
    int i_num_back = bs_read(s, 4);
505
0
    int i_num_lfe = bs_read(s, 2);
506
0
    int i_num_assoc_data = bs_read(s, 3);
507
0
    int i_num_valid_cc = bs_read(s, 4);
508
509
0
    if (bs_read1(s))
510
0
        bs_skip(s, 4); // mono downmix
511
0
    if (bs_read1(s))
512
0
        bs_skip(s, 4); // stereo downmix
513
0
    if (bs_read1(s))
514
0
        bs_skip(s, 2+1); // matrix downmix + pseudo_surround
515
516
0
    bs_skip(s, i_num_front * (1+4));
517
0
    bs_skip(s, i_num_side * (1+4));
518
0
    bs_skip(s, i_num_back * (1+4));
519
0
    bs_skip(s, i_num_lfe * (4));
520
0
    bs_skip(s, i_num_assoc_data * (4));
521
0
    bs_skip(s, i_num_valid_cc * (5));
522
0
    bs_align(s);
523
0
    int i_comment = bs_read(s, 8);
524
0
    bs_skip(s, i_comment * 8);
525
0
    return 0;
526
0
}
527
528
static int Mpeg4GASpecificConfig(mpeg4_asc_t *p_cfg, bs_t *s)
529
0
{
530
0
    p_cfg->i_frame_length = bs_read1(s) ? 960 : 1024;
531
0
    if(p_cfg->i_object_type == AOT_ER_AAC_LD) /* 14496-3 4.5.1.1 */
532
0
        p_cfg->i_frame_length >>= 1;
533
0
    else if(p_cfg->i_object_type == AOT_AAC_SSR)
534
0
        p_cfg->i_frame_length = 256;
535
536
0
    if (bs_read1(s))     // depend on core coder
537
0
        bs_skip(s, 14);   // core coder delay
538
539
0
    int i_extension_flag = bs_read1(s);
540
0
    if (p_cfg->i_channel_configuration == 0)
541
0
        Mpeg4GAProgramConfigElement(s);
542
0
    if (p_cfg->i_object_type == AOT_AAC_SC ||
543
0
        p_cfg->i_object_type == AOT_ER_AAC_SC)
544
0
        bs_skip(s, 3);    // layer
545
546
0
    if (i_extension_flag) {
547
0
        if (p_cfg->i_object_type == AOT_ER_BSAC)
548
0
            bs_skip(s, 5 + 11);   // numOfSubFrame + layer length
549
0
        if (p_cfg->i_object_type == AOT_ER_AAC_LC ||
550
0
            p_cfg->i_object_type == AOT_ER_AAC_LTP ||
551
0
            p_cfg->i_object_type == AOT_ER_AAC_SC ||
552
0
            p_cfg->i_object_type == AOT_ER_AAC_LD)
553
0
            bs_skip(s, 1+1+1);    // ER data : section scale spectral */
554
0
        if (bs_read1(s))     // extension 3
555
0
            fprintf(stderr, "Mpeg4GASpecificConfig: error 1\n");
556
0
    }
557
0
    return 0;
558
0
}
559
560
static int Mpeg4ELDSpecificConfig(mpeg4_asc_t *p_cfg, bs_t *s)
561
0
{
562
0
    p_cfg->i_frame_length = bs_read1(s) ? 480 : 512;
563
564
    /* ELDSpecificConfig Table 4.180 */
565
566
0
    bs_skip(s, 3);
567
0
    if(bs_read1(s)) /* ldSbrPresentFlag */
568
0
    {
569
0
        bs_skip(s, 2);
570
        /* ld_sbr_header(channelConfiguration) Table 4.181 */
571
0
        unsigned numSbrHeader;
572
0
        switch(p_cfg->i_channel_configuration)
573
0
        {
574
0
            case 1: case 2:
575
0
                numSbrHeader = 1;
576
0
                break;
577
0
            case 3:
578
0
                numSbrHeader = 2;
579
0
                break;
580
0
            case 4: case 5: case 6:
581
0
                numSbrHeader = 3;
582
0
                break;
583
0
            case 7:
584
0
                numSbrHeader = 4;
585
0
                break;
586
0
            default:
587
0
                numSbrHeader = 0;
588
0
                break;
589
0
        }
590
0
        for( ; numSbrHeader; numSbrHeader-- )
591
0
        {
592
            /* sbr_header() Table 4.63 */
593
0
            bs_read(s, 14);
594
0
            bool header_extra_1 = bs_read1(s);
595
0
            bool header_extra_2 = bs_read1(s);
596
0
            if(header_extra_1)
597
0
                bs_read(s, 5);
598
0
            if(header_extra_2)
599
0
                bs_read(s, 6);
600
0
        }
601
0
    }
602
603
0
    for(unsigned eldExtType = bs_read(s, 4);
604
0
        eldExtType != 0x0 /* ELDEXT_TERM */;
605
0
        eldExtType = bs_read(s, 4))
606
0
    {
607
0
        unsigned eldExtLen = bs_read(s, 4);
608
0
        unsigned eldExtLenAdd = 0;
609
0
        if(eldExtLen == 15)
610
0
        {
611
0
            eldExtLenAdd = bs_read(s, 8);
612
0
            eldExtLen += eldExtLenAdd;
613
0
        }
614
0
        if(eldExtLenAdd == 255)
615
0
            eldExtLen += bs_read(s, 16);
616
        /* reserved extensions */
617
0
        for(; eldExtLen; eldExtLen--)
618
0
            bs_skip(s, 8);
619
0
    }
620
621
0
    return 0;
622
0
}
623
624
static enum mpeg4_audioObjectType Mpeg4ReadAudioObjectType(bs_t *s)
625
0
{
626
0
    int i_type = bs_read(s, 5);
627
0
    if (i_type == 31)
628
0
        i_type = 32 + bs_read(s, 6);
629
0
    return i_type;
630
0
}
631
632
static unsigned Mpeg4ReadAudioSamplerate(bs_t *s)
633
0
{
634
0
    int i_index = bs_read(s, 4);
635
0
    if (i_index != 0x0f)
636
0
        return pi_sample_rates[i_index];
637
0
    return bs_read(s, 24);
638
0
}
639
640
static int Mpeg4ReadAudioSpecificConfig(bs_t *s, mpeg4_asc_t *p_cfg, bool b_withext)
641
0
{
642
0
    p_cfg->i_object_type = Mpeg4ReadAudioObjectType(s);
643
0
    p_cfg->i_samplerate = Mpeg4ReadAudioSamplerate(s);
644
0
    p_cfg->i_channel_configuration = bs_read(s, 4);
645
646
0
    p_cfg->i_sbr = -1;
647
0
    p_cfg->i_ps  = -1;
648
0
    p_cfg->extension.i_object_type = 0;
649
0
    p_cfg->extension.i_samplerate = 0;
650
0
    p_cfg->extension.i_channel_configuration = 0;
651
0
    p_cfg->i_frame_length = 0;
652
653
0
    if (p_cfg->i_object_type == AOT_AAC_SBR ||
654
0
        p_cfg->i_object_type == AOT_AAC_PS) {
655
0
        p_cfg->i_sbr = 1;
656
0
        if (p_cfg->i_object_type == AOT_AAC_PS)
657
0
           p_cfg->i_ps = 1;
658
0
        p_cfg->extension.i_object_type = AOT_AAC_SBR;
659
0
        p_cfg->extension.i_samplerate = Mpeg4ReadAudioSamplerate(s);
660
661
0
        p_cfg->i_object_type = Mpeg4ReadAudioObjectType(s);
662
0
        if(p_cfg->i_object_type == AOT_ER_BSAC)
663
0
            p_cfg->extension.i_channel_configuration = bs_read(s, 4);
664
0
    }
665
666
0
    switch(p_cfg->i_object_type)
667
0
    {
668
0
    case AOT_AAC_MAIN:
669
0
    case AOT_AAC_LC:
670
0
    case AOT_AAC_SSR:
671
0
    case AOT_AAC_LTP:
672
0
    case AOT_AAC_SC:
673
0
    case AOT_TWINVQ:
674
0
    case AOT_ER_AAC_LC:
675
0
    case AOT_ER_AAC_LTP:
676
0
    case AOT_ER_AAC_SC:
677
0
    case AOT_ER_TWINVQ:
678
0
    case AOT_ER_BSAC:
679
0
    case AOT_ER_AAC_LD:
680
0
        Mpeg4GASpecificConfig(p_cfg, s);
681
0
        break;
682
0
    case AOT_CELP:
683
        // CelpSpecificConfig();
684
0
    case AOT_HVXC:
685
        // HvxcSpecificConfig();
686
0
    case AOT_TTSI:
687
        // TTSSSpecificConfig();
688
0
    case AOT_MAIN_SYNTHETIC:
689
0
    case AOT_WAVETABLES:
690
0
    case AOT_GENERAL_MIDI:
691
0
    case AOT_ALGORITHMIC:
692
        // StructuredAudioSpecificConfig();
693
0
    case AOT_ER_CELP:
694
        // ERCelpSpecificConfig();
695
0
    case AOT_ER_HXVC:
696
        // ERHvxcSpecificConfig();
697
0
    case AOT_ER_HILN:
698
0
    case AOT_ER_Parametric:
699
        // ParametricSpecificConfig();
700
0
    case AOT_SSC:
701
        // SSCSpecificConfig();
702
0
    case AOT_LAYER1:
703
0
    case AOT_LAYER2:
704
0
    case AOT_LAYER3:
705
        // MPEG_1_2_SpecificConfig();
706
0
    case AOT_DST:
707
        // DSTSpecificConfig();
708
0
    case AOT_ALS:
709
        // ALSSpecificConfig();
710
0
    case AOT_SLS:
711
0
    case AOT_SLS_NON_CORE:
712
        // SLSSpecificConfig();
713
0
    case AOT_ER_AAC_ELD:
714
0
        Mpeg4ELDSpecificConfig(p_cfg, s);
715
0
        break;
716
0
    case AOT_SMR_SIMPLE:
717
0
    case AOT_SMR_MAIN:
718
        // SymbolicMusicSpecificConfig();
719
0
    default:
720
        // error
721
0
        return VLC_EGENERIC;
722
0
    }
723
724
0
    switch(p_cfg->i_object_type)
725
0
    {
726
0
    case AOT_ER_AAC_LC:
727
0
    case AOT_ER_AAC_LTP:
728
0
    case AOT_ER_AAC_SC:
729
0
    case AOT_ER_TWINVQ:
730
0
    case AOT_ER_BSAC:
731
0
    case AOT_ER_AAC_LD:
732
0
    case AOT_ER_CELP:
733
0
    case AOT_ER_HXVC:
734
0
    case AOT_ER_HILN:
735
0
    case AOT_ER_Parametric:
736
0
    case AOT_ER_AAC_ELD:
737
0
    {
738
0
        int epConfig = bs_read(s, 2);
739
0
        if (epConfig == 2 || epConfig == 3)
740
            //ErrorProtectionSpecificConfig();
741
0
        if (epConfig == 3)
742
0
            if (bs_read1(s)) {
743
                // TODO : directMapping
744
0
            }
745
0
        break;
746
0
    }
747
0
    default:
748
0
        break;
749
0
    }
750
751
0
    if (b_withext && p_cfg->extension.i_object_type != AOT_AAC_SBR &&
752
0
        !bs_eof(s) && bs_read(s, 11) == 0x2b7)
753
0
    {
754
0
        p_cfg->extension.i_object_type = Mpeg4ReadAudioObjectType(s);
755
0
        if (p_cfg->extension.i_object_type == AOT_AAC_SBR)
756
0
        {
757
0
            p_cfg->i_sbr  = bs_read1(s);
758
0
            if (p_cfg->i_sbr == 1) {
759
0
                p_cfg->extension.i_samplerate = Mpeg4ReadAudioSamplerate(s);
760
0
                if (bs_read(s, 11) == 0x548)
761
0
                   p_cfg->i_ps = bs_read1(s);
762
0
            }
763
0
        }
764
0
        else if (p_cfg->extension.i_object_type == AOT_ER_BSAC)
765
0
        {
766
0
            p_cfg->i_sbr  = bs_read1(s);
767
0
            if(p_cfg->i_sbr)
768
0
                p_cfg->extension.i_samplerate = Mpeg4ReadAudioSamplerate(s);
769
0
            p_cfg->extension.i_channel_configuration = bs_read(s, 4);
770
0
        }
771
0
    }
772
773
#if 0
774
    static const char *ppsz_otype[] = {
775
        "NULL",
776
        "AAC Main", "AAC LC", "AAC SSR", "AAC LTP", "SBR", "AAC Scalable",
777
        "TwinVQ",
778
        "CELP", "HVXC",
779
        "Reserved", "Reserved",
780
        "TTSI",
781
        "Main Synthetic", "Wavetables Synthesis", "General MIDI",
782
        "Algorithmic Synthesis and Audio FX",
783
        "ER AAC LC",
784
        "Reserved",
785
        "ER AAC LTP", "ER AAC Scalable", "ER TwinVQ", "ER BSAC", "ER AAC LD",
786
        "ER CELP", "ER HVXC", "ER HILN", "ER Parametric",
787
        "SSC",
788
        "PS", "MPEG Surround", "Escape",
789
        "Layer 1", "Layer 2", "Layer 3",
790
        "DST", "ALS", "SLS", "SLS non-core", "ELD",
791
        "SMR Simple", "SMR Main",
792
    };
793
794
    fprintf(stderr, "Mpeg4ReadAudioSpecificInfo: t=%s(%d)f=%d c=%d sbr=%d\n",
795
            ppsz_otype[p_cfg->i_object_type], p_cfg->i_object_type,
796
            p_cfg->i_samplerate, p_cfg->i_channel, p_cfg->i_sbr);
797
#endif
798
0
    return bs_error(s) ? VLC_EGENERIC : VLC_SUCCESS;
799
0
}
800
801
static uint32_t LatmGetValue(bs_t *s)
802
0
{
803
0
    uint32_t v = 0;
804
0
    for (int i = 1 + bs_read(s, 2); i > 0; i--)
805
0
        v = (v << 8) + bs_read(s, 8);
806
0
    return v;
807
0
}
808
809
static size_t AudioSpecificConfigBitsToBytes(bs_t *s, uint32_t i_bits, uint8_t *p_data)
810
0
{
811
0
    size_t i_extra = __MIN((i_bits + 7) / 8, LATM_MAX_EXTRA_SIZE);
812
0
    for (size_t i = 0; i < i_extra; i++) {
813
0
        const uint32_t i_read = __MIN(8, i_bits - 8*i);
814
0
        p_data[i] = bs_read(s, i_read) << (8-i_read);
815
0
    }
816
0
    return i_extra;
817
0
}
818
819
static int LatmReadStreamMuxConfiguration(latm_mux_t *m, bs_t *s)
820
0
{
821
0
    int i_mux_version;
822
0
    int i_mux_versionA;
823
824
0
    i_mux_version = bs_read(s, 1);
825
0
    i_mux_versionA = 0;
826
0
    if (i_mux_version)
827
0
        i_mux_versionA = bs_read(s, 1);
828
829
0
    if (i_mux_versionA != 0) /* support only A=0 */
830
0
        return -1;
831
832
0
    memset(m, 0, sizeof(*m));
833
834
0
    if (i_mux_versionA == 0)
835
0
        if (i_mux_version == 1)
836
0
            LatmGetValue(s); /* taraBufferFullness */
837
838
0
    if(bs_eof(s))
839
0
        return -1;
840
841
0
    m->b_same_time_framing = bs_read1(s);
842
0
    m->i_sub_frames = 1 + bs_read(s, 6);
843
0
    m->i_programs = 1 + bs_read(s, 4);
844
845
0
    for (uint8_t i_program = 0; i_program < m->i_programs; i_program++) {
846
0
        if(bs_eof(s))
847
0
            return -1;
848
0
        m->pi_layers[i_program] = 1+bs_read(s, 3);
849
850
0
        for (uint8_t i_layer = 0; i_layer < m->pi_layers[i_program]; i_layer++) {
851
0
            latm_stream_t *st = &m->stream[m->i_streams];
852
0
            bool b_previous_cfg;
853
854
0
            m->pi_stream[i_program][i_layer] = m->i_streams;
855
0
            st->i_program = i_program;
856
0
            st->i_layer = i_layer;
857
858
0
            b_previous_cfg = false;
859
0
            if (i_program != 0 || i_layer != 0)
860
0
                b_previous_cfg = bs_read1(s);
861
862
0
            if (b_previous_cfg) {
863
0
                assert(m->i_streams > 0);
864
0
                st->cfg = m->stream[m->i_streams-1].cfg;
865
0
            } else {
866
0
                uint32_t asc_size = 0;
867
0
                if(i_mux_version > 0)
868
0
                    asc_size = LatmGetValue(s);
869
0
                bs_t asc_bs = *s;
870
0
                Mpeg4ReadAudioSpecificConfig(&asc_bs, &st->cfg, i_mux_version > 0);
871
0
                if (i_mux_version == 0)
872
0
                    asc_size = bs_pos(&asc_bs) - bs_pos(s);
873
0
                asc_bs = *s;
874
0
                st->i_extra = AudioSpecificConfigBitsToBytes(&asc_bs, asc_size, st->extra);
875
0
                bs_skip(s, asc_size);
876
0
            }
877
878
0
            st->i_frame_length_type = bs_read(s, 3);
879
0
            switch(st->i_frame_length_type)
880
0
            {
881
0
            case 0:
882
0
            {
883
0
                bs_skip(s, 8); /* latmBufferFullnes */
884
0
                if (!m->b_same_time_framing)
885
0
                    if (st->cfg.i_object_type == AOT_AAC_SC ||
886
0
                        st->cfg.i_object_type == AOT_CELP ||
887
0
                        st->cfg.i_object_type == AOT_ER_AAC_SC ||
888
0
                        st->cfg.i_object_type == AOT_ER_CELP)
889
0
                        bs_skip(s, 6); /* eFrameOffset */
890
0
                break;
891
0
            }
892
0
            case 1:
893
0
                st->i_frame_length = bs_read(s, 9);
894
0
                break;
895
0
            case 3: case 4: case 5:
896
0
                st->i_frame_length_index = bs_read(s, 6); // celp
897
0
                break;
898
0
            case 6: case 7:
899
0
                st->i_frame_length_index = bs_read(s, 1); // hvxc
900
0
            default:
901
0
                break;
902
0
            }
903
            /* Next stream */
904
0
            m->i_streams++;
905
0
        }
906
0
    }
907
908
0
    if(bs_error(s) || bs_eof(s))
909
0
        return -1;
910
911
    /* other data */
912
0
    if (bs_read1(s)) {
913
0
        if (i_mux_version == 1)
914
0
            m->i_other_data = LatmGetValue(s);
915
0
        else {
916
0
            int b_continue;
917
0
            do {
918
0
                b_continue = bs_read1(s);
919
0
                m->i_other_data = (m->i_other_data << 8) + bs_read(s, 8);
920
0
            } while (b_continue);
921
0
        }
922
0
    }
923
924
    /* crc */
925
0
    m->i_crc = -1;
926
0
    if (bs_read1(s))
927
0
        m->i_crc = bs_read(s, 8);
928
929
0
    return bs_error(s) ? -1 : 0;
930
0
}
931
932
static int LOASParse(decoder_t *p_dec, uint8_t *p_buffer, int i_buffer)
933
0
{
934
0
    decoder_sys_t *p_sys = p_dec->p_sys;
935
0
    bs_t s;
936
0
    int i_accumulated = 0;
937
938
0
    bs_init(&s, p_buffer, i_buffer);
939
940
    /* Read the stream mux configuration if present */
941
0
    if (!bs_read1(&s) && !LatmReadStreamMuxConfiguration(&p_sys->latm, &s) &&
942
0
            p_sys->latm.i_streams > 0) {
943
0
        const latm_stream_t *st = &p_sys->latm.stream[0];
944
945
0
        if(st->cfg.i_samplerate == 0 || st->cfg.i_frame_length == 0 ||
946
0
           ChannelConfigurationToVLC(st->cfg.i_channel_configuration) == 0)
947
0
            return 0;
948
949
0
        p_sys->i_channels = ChannelConfigurationToVLC(st->cfg.i_channel_configuration);
950
0
        p_sys->i_rate = st->cfg.i_samplerate;
951
0
        p_sys->i_frame_length = st->cfg.i_frame_length;
952
0
        p_sys->i_aac_profile = AOTtoAACProfile(st->cfg.i_object_type);
953
954
0
        if (p_sys->i_channels && p_sys->i_rate && p_sys->i_frame_length > 0)
955
0
        {
956
0
            if((size_t)p_dec->fmt_out.i_extra != st->i_extra ||
957
0
               (p_dec->fmt_out.i_extra > 0 &&
958
0
                memcmp(p_dec->fmt_out.p_extra, st->extra, st->i_extra)) )
959
0
            {
960
0
                if(p_dec->fmt_out.i_extra)
961
0
                    free(p_dec->fmt_out.p_extra);
962
0
                p_dec->fmt_out.p_extra = malloc(st->i_extra);
963
0
                if(p_dec->fmt_out.p_extra)
964
0
                {
965
0
                    p_dec->fmt_out.i_extra = st->i_extra;
966
0
                    memcpy(p_dec->fmt_out.p_extra, st->extra, st->i_extra);
967
0
                    p_sys->b_latm_cfg = true;
968
0
                }
969
0
                else
970
0
                {
971
0
                    p_dec->fmt_out.i_extra = 0;
972
0
                    p_sys->b_latm_cfg = false;
973
0
                }
974
0
            }
975
0
        }
976
0
    }
977
978
    /* Wait for the configuration */
979
0
    if (!p_sys->b_latm_cfg)
980
0
    {
981
        /* WAVE_FORMAT_MPEG_LOAS, configuration provided as AAC header :/ */
982
0
        if( p_dec->fmt_in->i_extra > 0 &&
983
0
            p_sys->i_channels && p_sys->i_rate && p_sys->i_frame_length )
984
0
        {
985
0
            p_sys->b_latm_cfg = true;
986
0
        }
987
0
        else return 0;
988
0
    }
989
990
0
    if(bs_eof(&s) && i_buffer)
991
0
        goto truncated;
992
993
    /* FIXME do we need to split the subframe into independent packet ? */
994
0
    if (p_sys->latm.i_sub_frames > 1)
995
0
        msg_Err(p_dec, "latm sub frames not yet supported, please send a sample");
996
997
0
    for (uint8_t i_sub = 0; i_sub < p_sys->latm.i_sub_frames; i_sub++) {
998
0
        unsigned pi_payload[LATM_MAX_PROGRAM][LATM_MAX_LAYER];
999
0
        if (p_sys->latm.b_same_time_framing) {
1000
            /* Payload length */
1001
0
            for (uint8_t i_program = 0; i_program < p_sys->latm.i_programs; i_program++) {
1002
0
                for (uint8_t i_layer = 0; i_layer < p_sys->latm.pi_layers[i_program]; i_layer++) {
1003
0
                    latm_stream_t *st = &p_sys->latm.stream[p_sys->latm.pi_stream[i_program][i_layer]];
1004
0
                    if (st->i_frame_length_type == 0) {
1005
0
                        unsigned i_payload = 0;
1006
0
                        for (;;) {
1007
0
                            uint8_t i_tmp = bs_read(&s, 8);
1008
0
                            i_payload += i_tmp;
1009
0
                            if (i_tmp != 255)
1010
0
                                break;
1011
0
                        }
1012
0
                        pi_payload[i_program][i_layer] = i_payload;
1013
0
                    } else if (st->i_frame_length_type == 1) {
1014
0
                        pi_payload[i_program][i_layer] = st->i_frame_length / 8; /* XXX not correct */
1015
0
                    } else if ((st->i_frame_length_type == 3) ||
1016
0
                             (st->i_frame_length_type == 5) ||
1017
0
                             (st->i_frame_length_type == 7)) {
1018
0
                        bs_skip(&s, 2); // muxSlotLengthCoded
1019
0
                        pi_payload[i_program][i_layer] = 0; /* TODO */
1020
0
                    } else {
1021
0
                        pi_payload[i_program][i_layer] = 0; /* TODO */
1022
0
                    }
1023
0
                }
1024
0
            }
1025
1026
            /* Payload Data */
1027
0
            for (uint8_t i_program = 0; i_program < p_sys->latm.i_programs; i_program++) {
1028
0
                for (uint8_t i_layer = 0; i_layer < p_sys->latm.pi_layers[i_program]; i_layer++) {
1029
                    /* XXX we only extract 1 stream */
1030
0
                    if (i_program != 0 || i_layer != 0)
1031
0
                        break;
1032
1033
0
                    if (pi_payload[i_program][i_layer] <= 0)
1034
0
                        continue;
1035
1036
                    /* FIXME that's slow (and a bit ugly to write in place) */
1037
0
                    for (unsigned i = 0; i < pi_payload[i_program][i_layer]; i++) {
1038
0
                        if (i_accumulated >= i_buffer)
1039
0
                            return 0;
1040
0
                        p_buffer[i_accumulated++] = bs_read(&s, 8);
1041
0
                        if(bs_error(&s))
1042
0
                            goto truncated;
1043
0
                    }
1044
0
                }
1045
0
            }
1046
0
        } else {
1047
0
            const int i_chunks = bs_read(&s, 4);
1048
#if 0
1049
            int pi_program[16];
1050
            int pi_layer[16];
1051
#endif
1052
1053
0
            msg_Err(p_dec, "latm without same time frameing not yet supported, please send a sample");
1054
1055
0
            for (int i_chunk = 0; i_chunk < i_chunks; i_chunk++) {
1056
0
                const int streamIndex = bs_read(&s, 4);
1057
0
                latm_stream_t *st = &p_sys->latm.stream[streamIndex];
1058
0
                const int i_program = st->i_program;
1059
0
                const int i_layer = st->i_layer;
1060
1061
#if 0
1062
                pi_program[i_chunk] = i_program;
1063
                pi_layer[i_chunk] = i_layer;
1064
#endif
1065
1066
0
                if (st->i_frame_length_type == 0) {
1067
0
                    int i_payload = 0;
1068
0
                    for (;;) {
1069
0
                        int i_tmp = bs_read(&s, 8);
1070
0
                        i_payload += i_tmp;
1071
0
                        if (i_tmp != 255)
1072
0
                            break;
1073
0
                    }
1074
0
                    pi_payload[i_program][i_layer] = i_payload;
1075
0
                    bs_skip(&s, 1); // auEndFlag
1076
0
                } else if (st->i_frame_length_type == 1) {
1077
0
                    pi_payload[i_program][i_layer] = st->i_frame_length / 8; /* XXX not correct */
1078
0
                } else if ((st->i_frame_length_type == 3) ||
1079
0
                         (st->i_frame_length_type == 5) ||
1080
0
                         (st->i_frame_length_type == 7)) {
1081
0
                    bs_read(&s, 2); // muxSlotLengthCoded
1082
0
                }
1083
0
            }
1084
#if 0
1085
            for (int i_chunk = 0; i_chunk < i_chunks; i_chunk++) {
1086
                //const int i_program = pi_program[i_chunk];
1087
                //const int i_layer = pi_layer[i_chunk];
1088
1089
                /* TODO ? Payload */
1090
            }
1091
#endif
1092
0
        }
1093
0
    }
1094
1095
#if 0
1096
    if (p_sys->latm.i_other_data > 0)
1097
        ; // TODO
1098
#endif
1099
0
    bs_align(&s);
1100
1101
0
    return i_accumulated;
1102
1103
0
truncated:
1104
0
    msg_Warn(p_dec,"Truncated LOAS packet. Wrong format ?");
1105
0
    return 0;
1106
0
}
1107
1108
/*****************************************************************************
1109
 *
1110
 *****************************************************************************/
1111
static void SetupOutput(decoder_t *p_dec, block_t *p_block)
1112
0
{
1113
0
    decoder_sys_t *p_sys = p_dec->p_sys;
1114
1115
0
    if (p_dec->fmt_out.audio.i_rate != p_sys->i_rate && p_sys->i_rate > 0)
1116
0
    {
1117
0
        msg_Info(p_dec, "AAC channels: %d samplerate: %d",
1118
0
                  p_sys->i_channels, p_sys->i_rate);
1119
0
        date_Change(&p_sys->end_date, p_sys->i_rate, 1);
1120
0
    }
1121
1122
0
    p_dec->fmt_out.audio.i_rate     = p_sys->i_rate;
1123
0
    p_dec->fmt_out.audio.i_channels = p_sys->i_channels;
1124
0
    p_dec->fmt_out.audio.i_bytes_per_frame = p_sys->i_frame_size;
1125
0
    p_dec->fmt_out.audio.i_frame_length = p_sys->i_frame_length;
1126
    /* Will reload extradata on change */
1127
0
    p_dec->fmt_out.i_profile = p_sys->i_aac_profile;
1128
1129
#if 0
1130
    p_dec->fmt_out.audio.i_physical_channels = p_sys->i_channels_conf;
1131
#endif
1132
1133
0
    p_block->i_pts = p_block->i_dts = date_Get(&p_sys->end_date);
1134
1135
0
    p_block->i_length =
1136
0
        date_Increment(&p_sys->end_date, p_sys->i_frame_length) - p_block->i_pts;
1137
0
}
1138
1139
/*****************************************************************************
1140
 * FlushStreamBlock:
1141
 *****************************************************************************/
1142
static void Flush(decoder_t *p_dec)
1143
0
{
1144
0
    decoder_sys_t *p_sys = p_dec->p_sys;
1145
1146
0
    p_sys->i_state = STATE_NOSYNC;
1147
0
    block_BytestreamEmpty(&p_sys->bytestream);
1148
0
    date_Set(&p_sys->end_date, VLC_TICK_INVALID);
1149
0
    p_sys->b_discontuinity = true;
1150
0
}
1151
1152
static inline bool HasADTSHeader( const uint8_t *p_header )
1153
0
{
1154
0
    return p_header[0] == 0xff && (p_header[1] & 0xf6) == 0xf0;
1155
0
}
1156
1157
static inline bool HasLoasHeader( const uint8_t *p_header )
1158
0
{
1159
0
    return p_header[0] == 0x56 && (p_header[1] & 0xe0) == 0xe0;
1160
0
}
1161
1162
/****************************************************************************
1163
 * PacketizeStreamBlock: ADTS/LOAS packetizer
1164
 ****************************************************************************/
1165
static block_t *PacketizeStreamBlock(decoder_t *p_dec, block_t **pp_block)
1166
0
{
1167
0
    decoder_sys_t *p_sys = p_dec->p_sys;
1168
0
    uint8_t p_header[ADTS_HEADER_SIZE + LOAS_HEADER_SIZE];
1169
0
    block_t *p_out_buffer;
1170
0
    uint8_t *p_buf;
1171
1172
0
    block_t *p_block = pp_block ? *pp_block : NULL;
1173
1174
0
    if(p_block)
1175
0
    {
1176
0
        block_BytestreamPush(&p_sys->bytestream, p_block);
1177
0
        *pp_block = NULL;
1178
0
    }
1179
1180
0
    for (;;) switch(p_sys->i_state) {
1181
0
    case STATE_NOSYNC:
1182
0
        while (block_PeekBytes(&p_sys->bytestream, p_header, 2) == VLC_SUCCESS) {
1183
            /* Look for sync word - should be 0xfff(adts) or 0x2b7(loas) */
1184
0
            if ((p_sys->i_type == TYPE_ADTS || p_sys->i_type == TYPE_UNKNOWN_NONRAW) &&
1185
0
                HasADTSHeader( p_header ) )
1186
0
            {
1187
0
                if (p_sys->i_type != TYPE_ADTS)
1188
0
                    msg_Dbg(p_dec, "detected ADTS format");
1189
1190
0
                p_sys->i_state = STATE_SYNC;
1191
0
                p_sys->i_type = TYPE_ADTS;
1192
0
                break;
1193
0
            }
1194
0
            else if ((p_sys->i_type == TYPE_LOAS || p_sys->i_type == TYPE_UNKNOWN_NONRAW) &&
1195
0
                      HasLoasHeader( p_header ) )
1196
0
            {
1197
0
                if (p_sys->i_type != TYPE_LOAS)
1198
0
                    msg_Dbg(p_dec, "detected LOAS format");
1199
1200
0
                p_sys->i_state = STATE_SYNC;
1201
0
                p_sys->i_type = TYPE_LOAS;
1202
0
                break;
1203
0
            }
1204
0
            block_SkipByte(&p_sys->bytestream);
1205
0
        }
1206
0
        if (p_sys->i_state != STATE_SYNC) {
1207
0
            block_BytestreamFlush(&p_sys->bytestream);
1208
1209
            /* Need more data */
1210
0
            return NULL;
1211
0
        }
1212
        /* fallthrough */
1213
1214
0
    case STATE_SYNC:
1215
        /* New frame, set the Presentation Time Stamp */
1216
0
        p_sys->i_pts = p_sys->bytestream.p_block->i_pts;
1217
0
        if (p_sys->i_pts != VLC_TICK_INVALID &&
1218
0
            p_sys->i_pts != date_Get(&p_sys->end_date))
1219
0
            date_Set(&p_sys->end_date, p_sys->i_pts);
1220
0
        p_sys->i_state = STATE_HEADER;
1221
0
        break;
1222
1223
0
    case STATE_HEADER:
1224
0
        if (p_sys->i_type == TYPE_ADTS) {
1225
            /* Get ADTS frame header (ADTS_HEADER_SIZE bytes) */
1226
0
            if (block_PeekBytes(&p_sys->bytestream, p_header,
1227
0
                        ADTS_HEADER_SIZE) != VLC_SUCCESS)
1228
0
                return NULL; /* Need more data */
1229
1230
            /* Check if frame is valid and get frame info */
1231
0
            p_sys->i_frame_size = ADTSSyncInfo(p_dec, p_header,
1232
0
                    &p_sys->i_channels,
1233
0
                    &p_sys->i_rate,
1234
0
                    &p_sys->i_frame_length,
1235
0
                    &p_sys->i_header_size);
1236
0
        } else {
1237
0
            assert(p_sys->i_type == TYPE_LOAS);
1238
            /* Get LOAS frame header (LOAS_HEADER_SIZE bytes) */
1239
0
            if (block_PeekBytes(&p_sys->bytestream, p_header,
1240
0
                        LOAS_HEADER_SIZE) != VLC_SUCCESS)
1241
0
                return NULL; /* Need more data */
1242
1243
            /* Check if frame is valid and get frame info */
1244
0
            p_sys->i_frame_size = LOASSyncInfo(p_header, &p_sys->i_header_size);
1245
0
        }
1246
1247
0
        if (p_sys->i_frame_size <= 0) {
1248
0
            msg_Dbg(p_dec, "emulated sync word");
1249
0
            block_SkipByte(&p_sys->bytestream);
1250
0
            p_sys->i_state = STATE_NOSYNC;
1251
0
            break;
1252
0
        }
1253
1254
0
        p_sys->i_state = STATE_NEXT_SYNC;
1255
        /* fallthrough */
1256
1257
0
    case STATE_NEXT_SYNC:
1258
0
        if (p_sys->bytestream.p_block == NULL) {
1259
0
            p_sys->i_state = STATE_NOSYNC;
1260
0
            block_BytestreamFlush(&p_sys->bytestream);
1261
0
            return NULL;
1262
0
        }
1263
1264
        /* Check if next expected frame contains the sync word */
1265
0
        if (block_PeekOffsetBytes(&p_sys->bytestream, p_sys->i_frame_size
1266
0
                    + p_sys->i_header_size, p_header, 2) != VLC_SUCCESS)
1267
0
        {
1268
0
            if(p_block == NULL) /* drain */
1269
0
            {
1270
0
                p_sys->i_state = STATE_SEND_DATA;
1271
0
                break;
1272
0
            }
1273
0
            return NULL; /* Need more data */
1274
0
        }
1275
1276
0
        assert((p_sys->i_type == TYPE_ADTS) || (p_sys->i_type == TYPE_LOAS));
1277
0
        if ( (p_sys->i_type == TYPE_ADTS && !HasADTSHeader( p_header )) ||
1278
0
             (p_sys->i_type == TYPE_LOAS && !HasLoasHeader( p_header )) )
1279
0
        {
1280
            /* Check spacial padding case. Failing if need more bytes is ok since
1281
               that should have been sent as a whole block */
1282
0
            if( block_PeekOffsetBytes(&p_sys->bytestream,
1283
0
                                      p_sys->i_frame_size + p_sys->i_header_size,
1284
0
                                      p_header, 3) == VLC_SUCCESS &&
1285
0
                p_header[0] == 0x00 &&
1286
0
               ((p_sys->i_type == TYPE_ADTS && HasADTSHeader( &p_header[1] )) ||
1287
0
                (p_sys->i_type == TYPE_LOAS && !HasLoasHeader( &p_header[1] ))))
1288
0
            {
1289
0
                p_sys->i_state = STATE_SEND_DATA;
1290
0
            }
1291
0
            else
1292
0
            {
1293
0
                msg_Dbg(p_dec, "emulated sync word (no sync on following frame)"
1294
0
                               " 0x%"PRIx8" 0x%"PRIx8, p_header[0], p_header[1] );
1295
0
                p_sys->i_state = STATE_NOSYNC;
1296
0
                block_SkipByte(&p_sys->bytestream);
1297
0
            }
1298
0
            break;
1299
0
        }
1300
1301
0
        p_sys->i_state = STATE_SEND_DATA;
1302
0
        break;
1303
1304
0
    case STATE_GET_DATA:
1305
        /* Make sure we have enough data.
1306
         * (Not useful if we went through NEXT_SYNC) */
1307
0
        if (block_WaitBytes(&p_sys->bytestream, p_sys->i_frame_size +
1308
0
                    p_sys->i_header_size) != VLC_SUCCESS)
1309
0
            return NULL; /* Need more data */
1310
0
        p_sys->i_state = STATE_SEND_DATA;
1311
        /* fallthrough */
1312
1313
0
    case STATE_SEND_DATA:
1314
        /* When we reach this point we already know we have enough
1315
         * data available. */
1316
1317
0
        p_out_buffer = block_Alloc(p_sys->i_frame_size);
1318
0
        if (!p_out_buffer) {
1319
0
            return NULL;
1320
0
        }
1321
0
        p_buf = p_out_buffer->p_buffer;
1322
1323
        /* Skip the ADTS/LOAS header */
1324
0
        block_SkipBytes(&p_sys->bytestream, p_sys->i_header_size);
1325
1326
        /* Copy the whole frame into the buffer */
1327
0
        block_GetBytes(&p_sys->bytestream, p_buf, p_sys->i_frame_size);
1328
0
        if (p_sys->i_type != TYPE_ADTS) { /* parse/extract the whole frame */
1329
0
            assert(p_sys->i_type == TYPE_LOAS);
1330
0
            p_out_buffer->i_buffer = LOASParse(p_dec, p_buf, p_sys->i_frame_size);
1331
0
            if (p_out_buffer->i_buffer <= 0)
1332
0
            {
1333
0
                if (!p_sys->b_latm_cfg)
1334
0
                    msg_Warn(p_dec, "waiting for header");
1335
1336
0
                block_Release(p_out_buffer);
1337
0
                p_out_buffer = NULL;
1338
0
                p_sys->i_state = STATE_NOSYNC;
1339
0
                break;
1340
0
            }
1341
0
        }
1342
0
        SetupOutput(p_dec, p_out_buffer);
1343
        /* Make sure we don't reuse the same pts twice */
1344
0
        if (p_sys->i_pts == p_sys->bytestream.p_block->i_pts)
1345
0
            p_sys->i_pts = p_sys->bytestream.p_block->i_pts = VLC_TICK_INVALID;
1346
1347
        /* So p_block doesn't get re-added several times */
1348
0
        if( pp_block )
1349
0
            *pp_block = block_BytestreamPop(&p_sys->bytestream);
1350
1351
0
        p_sys->i_state = STATE_NOSYNC;
1352
1353
0
        return p_out_buffer;
1354
0
    }
1355
1356
0
    return NULL;
1357
0
}
1358
1359
/****************************************************************************
1360
 * Packetize: just forwards raw blocks, or packetizes LOAS/ADTS
1361
 *            and strips headers
1362
 ****************************************************************************/
1363
static block_t *Packetize(decoder_t *p_dec, block_t **pp_block)
1364
0
{
1365
0
    decoder_sys_t *p_sys = p_dec->p_sys;
1366
0
    block_t *p_block = pp_block ? *pp_block : NULL;
1367
1368
0
    if(p_block)
1369
0
    {
1370
0
        if (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED))
1371
0
        {
1372
0
            if(p_sys->i_type == TYPE_ADTS || p_sys->i_type == TYPE_LOAS)
1373
0
            {
1374
                /* First always drain complete blocks before discontinuity */
1375
0
                block_t *p_drain = PacketizeStreamBlock(p_dec, NULL);
1376
0
                if(p_drain)
1377
0
                    return p_drain;
1378
0
            }
1379
1380
0
            Flush(p_dec);
1381
1382
0
            if (p_block->i_flags & BLOCK_FLAG_CORRUPTED)
1383
0
            {
1384
0
                block_Release(p_block);
1385
0
                return NULL;
1386
0
            }
1387
0
        }
1388
1389
0
        if ( p_block->i_pts == VLC_TICK_INVALID &&
1390
0
             date_Get(&p_sys->end_date) == VLC_TICK_INVALID )
1391
0
        {
1392
            /* We've just started the stream, wait for the first PTS. */
1393
0
            block_Release(p_block);
1394
0
            return NULL;
1395
0
        }
1396
0
    }
1397
1398
0
    if(p_block && p_sys->i_type == TYPE_UNKNOWN)
1399
0
    {
1400
0
        p_sys->i_type = TYPE_RAW;
1401
0
        if(p_block->i_buffer > 1)
1402
0
        {
1403
0
            if(p_block->p_buffer[0] == 0xff && (p_block->p_buffer[1] & 0xf6) == 0xf0)
1404
0
            {
1405
0
                p_sys->i_type = TYPE_ADTS;
1406
0
            }
1407
0
            else if(p_block->p_buffer[0] == 0x56 && (p_block->p_buffer[1] & 0xe0) == 0xe0)
1408
0
            {
1409
0
                p_sys->i_type = TYPE_LOAS;
1410
0
            }
1411
0
        }
1412
0
    }
1413
1414
0
    if(p_sys->i_type == TYPE_RAW)
1415
0
        p_block = ForwardRawBlock(p_dec, pp_block);
1416
0
    else
1417
0
        p_block = PacketizeStreamBlock(p_dec, pp_block);
1418
1419
0
    if(p_block && p_sys->b_discontuinity)
1420
0
    {
1421
0
        p_block->i_flags |= BLOCK_FLAG_DISCONTINUITY;
1422
0
        p_sys->b_discontuinity = false;
1423
0
    }
1424
1425
0
    return p_block;
1426
0
}