Coverage Report

Created: 2026-08-13 07:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/codec/faad.c
Line
Count
Source
1
/*****************************************************************************
2
 * faad.c: AAC decoder using libfaad2
3
 *****************************************************************************
4
 * Copyright (C) 2001, 2003 VLC authors and VideoLAN
5
 *
6
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7
 *          Gildas Bazin <gbazin@videolan.org>
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
 * NOTA BENE: this module requires the linking against a library which is
26
 * known to require licensing under the GNU General Public License version 2
27
 * (or later). Therefore, the result of compiling this module will normally
28
 * be subject to the terms of that later license.
29
 *****************************************************************************/
30
31
32
#ifdef HAVE_CONFIG_H
33
# include "config.h"
34
#endif
35
36
#include <assert.h>
37
#include <stdbit.h>
38
39
#include <vlc_common.h>
40
#include <vlc_plugin.h>
41
#include <vlc_input_item.h>
42
#include <vlc_codec.h>
43
#include <vlc_cpu.h>
44
#include <vlc_aout.h>
45
46
#include <faad.h>
47
#if !defined(FAAD2_VERSION) // FAAD2_VERSION added in 2.10.1
48
# define PATCH_PCA
49
#endif
50
51
#include <neaacdec.h>
52
#include "../packetizer/mpeg4audio.h"
53
54
/*****************************************************************************
55
 * Module descriptor
56
 *****************************************************************************/
57
static int  Open( vlc_object_t * );
58
static void Close( vlc_object_t * );
59
60
168
vlc_module_begin ()
61
84
    set_description( N_("AAC audio decoder (using libfaad2)") )
62
84
    set_capability( "audio decoder", 100 )
63
84
    set_subcategory( SUBCAT_INPUT_ACODEC )
64
84
    set_callbacks( Open, Close )
65
84
vlc_module_end ()
66
67
/****************************************************************************
68
 * Local prototypes
69
 ****************************************************************************/
70
static int DecodeBlock( decoder_t *, block_t * );
71
static void Flush( decoder_t * );
72
static void DoReordering( uint32_t *, uint32_t *, int, int, uint8_t * );
73
74
typedef struct
75
{
76
    /* faad handler */
77
    NeAACDecHandle *hfaad;
78
79
    /* samples */
80
    date_t date;
81
    vlc_tick_t i_last_length;
82
83
    /* temporary buffer */
84
    block_t *p_block;
85
86
    /* Channel positions of the current stream (for re-ordering) */
87
    uint32_t pi_channel_positions[MPEG4_ASC_MAX_INDEXEDPOS];
88
89
    bool b_sbr, b_ps, b_discontinuity;
90
} decoder_sys_t;
91
92
static_assert (MPEG4_ASC_MAX_INDEXEDPOS == LFE_CHANNEL, "Mismatch");
93
94
#define FAAD_CHANNEL_ID_COUNT (LFE_CHANNEL + 1)
95
static const uint32_t pi_tovlcmapping[FAAD_CHANNEL_ID_COUNT] =
96
{
97
    [UNKNOWN_CHANNEL]      = 0,
98
    [FRONT_CHANNEL_CENTER] = AOUT_CHAN_CENTER,
99
    [FRONT_CHANNEL_LEFT]   = AOUT_CHAN_LEFT,
100
    [FRONT_CHANNEL_RIGHT]  = AOUT_CHAN_RIGHT,
101
    [SIDE_CHANNEL_LEFT]    = AOUT_CHAN_MIDDLELEFT,
102
    [SIDE_CHANNEL_RIGHT]   = AOUT_CHAN_MIDDLERIGHT,
103
    [BACK_CHANNEL_LEFT]    = AOUT_CHAN_REARLEFT,
104
    [BACK_CHANNEL_RIGHT]   = AOUT_CHAN_REARRIGHT,
105
    [BACK_CHANNEL_CENTER]  = AOUT_CHAN_REARCENTER,
106
    [LFE_CHANNEL]          = AOUT_CHAN_LFE
107
};
108
109
/*****************************************************************************
110
 * OpenDecoder: probe the decoder and return score
111
 *****************************************************************************/
112
static int Open( vlc_object_t *p_this )
113
362k
{
114
362k
    decoder_t *p_dec = (decoder_t*)p_this;
115
362k
    decoder_sys_t *p_sys;
116
362k
    NeAACDecConfiguration *cfg;
117
118
362k
    if( p_dec->fmt_in->i_codec != VLC_CODEC_MP4A ||
119
91.0k
        p_dec->fmt_in->i_profile >= AAC_PROFILE_ELD ||
120
91.0k
        (p_dec->fmt_in->i_extra > 1 &&
121
78.2k
         (GetWBE(p_dec->fmt_in->p_extra) & 0xffe0) >= 0xf8e0)) /* ELD AOT */
122
272k
    {
123
272k
        return VLC_EGENERIC;
124
272k
    }
125
126
    /* Allocate the memory needed to store the decoder's structure */
127
90.1k
    if( ( p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) ) ) == NULL )
128
0
        return VLC_ENOMEM;
129
130
    /* Open a faad context */
131
90.1k
    if( ( p_sys->hfaad = NeAACDecOpen() ) == NULL )
132
0
    {
133
0
        msg_Err( p_dec, "cannot initialize faad" );
134
0
        free( p_sys );
135
0
        return VLC_EGENERIC;
136
0
    }
137
138
90.1k
    char * vinfo[2];
139
90.1k
    if( NeAACDecGetVersion( &vinfo[0], &vinfo[1] ) == 0 )
140
90.1k
        msg_Dbg( p_dec, "using version " FAAD2_VERSION " - %s", vinfo[0] );
141
142
    /* Misc init */
143
90.1k
    p_dec->fmt_out.audio.channel_type = p_dec->fmt_in->audio.channel_type;
144
145
90.1k
    if( p_dec->fmt_in->i_extra > 0 )
146
77.6k
    {
147
        /* We have a decoder config so init the handle */
148
77.6k
        unsigned long i_rate;
149
77.6k
        unsigned char i_channels;
150
151
77.6k
        if( NeAACDecInit2( p_sys->hfaad, p_dec->fmt_in->p_extra,
152
77.6k
                           p_dec->fmt_in->i_extra,
153
77.6k
                           &i_rate, &i_channels ) < 0 ||
154
4.62k
                i_channels >= MPEG4_ASC_MAX_INDEXEDPOS )
155
73.9k
        {
156
73.9k
            msg_Err( p_dec, "Failed to initialize faad using extra data" );
157
73.9k
            NeAACDecClose( p_sys->hfaad );
158
73.9k
            free( p_sys );
159
73.9k
            return VLC_EGENERIC;
160
73.9k
        }
161
162
3.62k
        p_dec->fmt_out.audio.i_rate = i_rate;
163
3.62k
        p_dec->fmt_out.audio.i_channels = i_channels;
164
3.62k
        p_dec->fmt_out.audio.i_physical_channels
165
3.62k
            = MPEG4_asc_channelsbyindex[i_channels];
166
3.62k
        date_Init( &p_sys->date, i_rate, 1 );
167
3.62k
    }
168
12.4k
    else
169
12.4k
    {
170
12.4k
        p_dec->fmt_out.audio.i_physical_channels = 0;
171
        /* Will be initialised from first frame */
172
12.4k
        p_dec->fmt_out.audio.i_rate = 0;
173
12.4k
        p_dec->fmt_out.audio.i_channels = 0;
174
12.4k
        date_Set( &p_sys->date, VLC_TICK_INVALID );
175
12.4k
    }
176
177
16.1k
    p_dec->fmt_out.i_codec = HAVE_FPU ? VLC_CODEC_FL32 : VLC_CODEC_S16N;
178
16.1k
    p_dec->fmt_out.audio.i_chan_mode = p_dec->fmt_in->audio.i_chan_mode;
179
180
    /* Set the faad config */
181
16.1k
    cfg = NeAACDecGetCurrentConfiguration( p_sys->hfaad );
182
16.1k
    if( p_dec->fmt_in->audio.i_rate )
183
5.29k
        cfg->defSampleRate = p_dec->fmt_in->audio.i_rate;
184
16.1k
    cfg->outputFormat = HAVE_FPU ? FAAD_FMT_FLOAT : FAAD_FMT_16BIT;
185
16.1k
    if( !NeAACDecSetConfiguration( p_sys->hfaad, cfg ) )
186
0
    {
187
0
        msg_Err( p_dec, "Failed to set faad configuration" );
188
0
        NeAACDecClose( p_sys->hfaad );
189
0
        free( p_sys );
190
0
        return VLC_EGENERIC;
191
0
    }
192
193
16.1k
    p_sys->i_last_length = 0;
194
195
    /* buffer */
196
16.1k
    p_sys->p_block = NULL;
197
198
16.1k
    p_sys->b_discontinuity =
199
16.1k
    p_sys->b_sbr = p_sys->b_ps = false;
200
201
16.1k
    p_dec->pf_decode = DecodeBlock;
202
16.1k
    p_dec->pf_flush  = Flush;
203
16.1k
    return VLC_SUCCESS;
204
16.1k
}
205
206
/*****************************************************************************
207
 * FlushBuffer:
208
 *****************************************************************************/
209
static void FlushBuffer( decoder_sys_t *p_sys, size_t i_used )
210
189k
{
211
189k
    block_t *p_block = p_sys->p_block;
212
189k
    if( p_block )
213
165k
    {
214
165k
        if( i_used < p_block->i_buffer )
215
4.47k
        {
216
            /* Drop padding */
217
6.05k
            for( ; i_used < p_block->i_buffer; i_used++ )
218
6.01k
                if( p_block->p_buffer[i_used] != 0x00 )
219
4.43k
                    break;
220
221
4.47k
            p_block->i_buffer -= i_used;
222
4.47k
            p_block->p_buffer += i_used;
223
4.47k
        }
224
160k
        else p_block->i_buffer = 0;
225
165k
        if( p_block->i_buffer == 0 )
226
160k
        {
227
160k
            block_Release( p_block );
228
160k
            p_sys->p_block = NULL;
229
160k
        }
230
165k
    }
231
189k
}
232
233
/*****************************************************************************
234
 * Flush:
235
 *****************************************************************************/
236
static void Flush( decoder_t *p_dec )
237
141k
{
238
141k
    decoder_sys_t *p_sys = p_dec->p_sys;
239
240
141k
    date_Set( &p_sys->date, VLC_TICK_INVALID );
241
141k
    FlushBuffer( p_sys, SIZE_MAX );
242
141k
}
243
244
/*****************************************************************************
245
 * DecodeBlock:
246
 *****************************************************************************/
247
static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
248
408k
{
249
408k
    decoder_sys_t *p_sys = p_dec->p_sys;
250
251
408k
    if( !p_block ) /* No Drain */
252
246k
        return VLCDEC_SUCCESS;
253
254
162k
    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
255
8.06k
    {
256
8.06k
        Flush( p_dec );
257
8.06k
        if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED) )
258
0
        {
259
0
            block_Release( p_block );
260
0
            return VLCDEC_SUCCESS;
261
0
        }
262
8.06k
    }
263
264
    /* Remove ADTS header if we have decoder specific config */
265
162k
    if( p_dec->fmt_in->i_extra && p_block->i_buffer > 7 )
266
43.6k
    {
267
43.6k
        if( p_block->p_buffer[0] == 0xff &&
268
828
            ( p_block->p_buffer[1] & 0xf0 ) == 0xf0 ) /* syncword */
269
554
        {   /* ADTS header present */
270
554
            size_t i_header_size; /* 7 bytes (+ 2 bytes for crc) */
271
554
            i_header_size = 7 + ( ( p_block->p_buffer[1] & 0x01 ) ? 0 : 2 );
272
            /* FIXME: multiple blocks per frame */
273
554
            if( p_block->i_buffer > i_header_size )
274
554
            {
275
554
                p_block->p_buffer += i_header_size;
276
554
                p_block->i_buffer -= i_header_size;
277
554
            }
278
554
        }
279
43.6k
    }
280
281
162k
    const vlc_tick_t i_pts = p_block->i_pts;
282
283
    /* Append block as temporary buffer */
284
162k
    if( p_sys->p_block == NULL )
285
160k
    {
286
160k
        p_sys->p_block = p_block;
287
160k
    }
288
1.36k
    else
289
1.36k
    {
290
1.36k
        p_sys->p_block->p_next = p_block;
291
1.36k
        block_t *p_prev = p_sys->p_block;
292
1.36k
        p_sys->p_block = block_ChainGather( p_sys->p_block );
293
1.36k
        if( p_sys->p_block == NULL )
294
0
            block_ChainRelease( p_prev );
295
1.36k
    }
296
297
    /* !Warn: do not use p_block beyond this point */
298
299
162k
    if( p_dec->fmt_out.audio.i_rate == 0 )
300
5.32k
    {
301
5.32k
        unsigned long i_rate = 0;
302
5.32k
        unsigned char i_channels;
303
304
        /* Init from DecoderConfig */
305
5.32k
        if( p_dec->fmt_in->i_extra > 0 &&
306
0
            NeAACDecInit2( p_sys->hfaad, p_dec->fmt_in->p_extra,
307
0
                           p_dec->fmt_in->i_extra, &i_rate, &i_channels ) != 0 )
308
0
        {
309
            /* Failed, will try from data */
310
0
            i_rate = 0;
311
0
        }
312
313
5.32k
        if( i_rate == 0 && p_sys->p_block && p_sys->p_block->i_buffer )
314
4.82k
        {
315
            /* Init faad with the first frame */
316
4.82k
            long i_read = NeAACDecInit( p_sys->hfaad,
317
4.82k
                                        p_sys->p_block->p_buffer, p_sys->p_block->i_buffer,
318
4.82k
                                        &i_rate, &i_channels );
319
4.82k
            if( i_read < 0 || (size_t) i_read > p_sys->p_block->i_buffer )
320
1.87k
                i_rate = 0;
321
2.94k
            else
322
2.94k
                FlushBuffer( p_sys, i_read );
323
4.82k
        }
324
325
5.32k
        if( i_rate == 0 )
326
2.37k
        {
327
            /* Can not init decoder at all for now */
328
2.37k
            FlushBuffer( p_sys, SIZE_MAX );
329
2.37k
            return VLCDEC_SUCCESS;
330
2.37k
        }
331
332
        /* Decoder Initialized */
333
2.94k
        p_dec->fmt_out.audio.i_rate = i_rate;
334
2.94k
        p_dec->fmt_out.audio.i_channels = i_channels;
335
2.94k
        p_dec->fmt_out.audio.i_physical_channels
336
2.94k
            = MPEG4_asc_channelsbyindex[i_channels];
337
2.94k
        date_Init( &p_sys->date, i_rate, 1 );
338
2.94k
    }
339
340
159k
    if( i_pts != VLC_TICK_INVALID && i_pts != date_Get( &p_sys->date ) )
341
145k
    {
342
145k
        if( p_sys->i_last_length == 0 ||
343
            /* We need to be permissive and rebase dts when it's really way off */
344
0
            llabs( i_pts - date_Get( &p_sys->date ) ) > p_sys->i_last_length * 3 / 2  )
345
145k
            date_Set( &p_sys->date, i_pts );
346
145k
    }
347
14.1k
    else if( date_Get( &p_sys->date ) == VLC_TICK_INVALID )
348
0
    {
349
        /* We've just started the stream, wait for the first PTS. */
350
0
        FlushBuffer( p_sys, SIZE_MAX );
351
0
        return VLCDEC_SUCCESS;
352
0
    }
353
354
    /* Decode all data */
355
319k
    while( p_sys->p_block && p_sys->p_block->i_buffer > 0 )
356
159k
    {
357
159k
        void *samples;
358
159k
        NeAACDecFrameInfo frame;
359
159k
        block_t *p_out = NULL;
360
361
159k
        samples = NeAACDecDecode( p_sys->hfaad, &frame,
362
159k
                                  p_sys->p_block->p_buffer,
363
159k
                                  p_sys->p_block->i_buffer );
364
365
159k
        if( frame.error > 0 )
366
133k
        {
367
133k
            msg_Warn( p_dec, "%s", NeAACDecGetErrorMessage( frame.error ) );
368
369
133k
            if( frame.error == 21 || frame.error == 12 )
370
14.8k
            {
371
                /*
372
                 * Once an "Unexpected channel configuration change"
373
                 * or a "Invalid number of channels" error
374
                 * occurs, it will occurs afterwards, and we got no sound.
375
                 * Reinitialization of the decoder is required.
376
                 */
377
14.8k
                unsigned long i_rate;
378
14.8k
                unsigned char i_channels;
379
14.8k
                NeAACDecHandle *hfaad;
380
14.8k
                NeAACDecConfiguration *cfg,*oldcfg;
381
382
14.8k
                oldcfg = NeAACDecGetCurrentConfiguration( p_sys->hfaad );
383
14.8k
                hfaad = NeAACDecOpen();
384
14.8k
                cfg = NeAACDecGetCurrentConfiguration( hfaad );
385
14.8k
                if( oldcfg->defSampleRate )
386
14.8k
                    cfg->defSampleRate = oldcfg->defSampleRate;
387
14.8k
                cfg->defObjectType = oldcfg->defObjectType;
388
14.8k
                cfg->outputFormat = oldcfg->outputFormat;
389
14.8k
                NeAACDecSetConfiguration( hfaad, cfg );
390
391
14.8k
                if( NeAACDecInit( hfaad,
392
14.8k
                                  p_sys->p_block->p_buffer,
393
14.8k
                                  p_sys->p_block->i_buffer,
394
14.8k
                                  &i_rate,&i_channels ) < 0 )
395
8.09k
                {
396
                    /* reinitialization failed */
397
8.09k
                    NeAACDecClose( hfaad );
398
8.09k
                    NeAACDecSetConfiguration( p_sys->hfaad, oldcfg );
399
8.09k
                }
400
6.72k
                else
401
6.72k
                {
402
6.72k
                    NeAACDecClose( p_sys->hfaad );
403
6.72k
                    p_sys->hfaad = hfaad;
404
6.72k
                    p_dec->fmt_out.audio.i_rate = i_rate;
405
6.72k
                    p_dec->fmt_out.audio.i_channels = i_channels;
406
6.72k
                    p_dec->fmt_out.audio.i_physical_channels
407
6.72k
                        = MPEG4_asc_channelsbyindex[i_channels];
408
6.72k
                    date_Init( &p_sys->date, i_rate, 1 );
409
6.72k
                }
410
14.8k
            }
411
412
133k
            Flush( p_dec );
413
133k
            p_sys->b_discontinuity = true;
414
415
133k
            continue;
416
133k
        }
417
418
26.6k
        if( frame.channels == 0 || frame.channels >= 64 )
419
12
        {
420
12
            msg_Warn( p_dec, "invalid channels count: %i", frame.channels );
421
12
            if( frame.channels == 0 )
422
12
                p_sys->b_discontinuity = true;
423
12
            FlushBuffer( p_sys, frame.bytesconsumed ? frame.bytesconsumed : SIZE_MAX );
424
12
            continue;
425
12
        }
426
427
26.6k
        if( frame.samples == 0 )
428
1.98k
        {
429
1.98k
            msg_Warn( p_dec, "decoded zero sample" );
430
1.98k
            FlushBuffer( p_sys, frame.bytesconsumed ? frame.bytesconsumed : SIZE_MAX );
431
1.98k
            continue;
432
1.98k
        }
433
434
        /* We decoded a valid frame */
435
24.6k
        if( p_dec->fmt_out.audio.i_rate != frame.samplerate )
436
5
        {
437
5
            date_Init( &p_sys->date, frame.samplerate, 1 );
438
5
            date_Set( &p_sys->date, i_pts );
439
5
        }
440
441
24.6k
        p_dec->fmt_out.audio.i_rate = frame.samplerate;
442
443
        /* Adjust stream info when dealing with SBR/PS */
444
24.6k
        bool b_sbr = (frame.sbr == 1) || (frame.sbr == 2);
445
24.6k
        if( p_sys->b_sbr != b_sbr || p_sys->b_ps != frame.ps )
446
196
        {
447
196
            const char *psz_ext = (b_sbr && frame.ps) ? "SBR+PS" :
448
196
                                    b_sbr ? "SBR" : "PS";
449
450
196
            msg_Dbg( p_dec, "AAC %s (channels: %u, samplerate: %lu)",
451
196
                    psz_ext, frame.channels, frame.samplerate );
452
453
196
            if( !p_dec->p_description )
454
196
                p_dec->p_description = vlc_meta_New();
455
196
            if( p_dec->p_description )
456
196
                vlc_meta_SetExtra( p_dec->p_description, _("AAC extension"), psz_ext );
457
458
196
            p_sys->b_sbr = b_sbr;
459
196
            p_sys->b_ps = frame.ps;
460
196
        }
461
462
#ifdef PATCH_PCA
463
        /* PS Enabled FAAD PCA bug hotfix (contribs has patch) */
464
        if( frame.channels == 8 )
465
        {
466
            const uint8_t psbugconfig[3][8] = { { 2, 3, 2, 3, 2, 3, 6, 7 },  /* fdk 7.1 (4 Front) */
467
                                                { 2, 3, 2, 3, 2, 3, 4, 5 },  /* 7.1 */
468
                                                { 1, 2, 3, 4, 5, 6, 7, 9 } };/* fixed */
469
            for( size_t i=0; i<2; i++ )
470
            {
471
                if( !memcmp( frame.channel_position, psbugconfig[i], 8 ) )
472
                {
473
                    msg_Warn( p_dec, "Unpatched FAAD2 library with PS Bug. Trying to workaround !" );
474
                    memcpy( frame.channel_position, psbugconfig[2], 8 );
475
                    break;
476
                }
477
            }
478
        }
479
480
        /* Hotfix channels misdetection/repetition for FDK 7.1 */
481
        struct
482
        {
483
            const uint8_t chans;
484
            const uint8_t faulty[8];
485
            const uint8_t fixed[8];
486
        } const channel_repeat_fixes[] = {
487
            { 7, { 2, 3, 2, 3, 2, 3, 6 },    { 1, 2, 3, 6, 7, 8, 9 }    }, /* 3F 3R LFE #18273 */
488
            { 8, { 1, 2, 3, 6, 7, 6, 7, 9 }, { 1, 2, 3, 6, 7, 4, 5, 9 } }, /* FDK encoded 7.1 */
489
        };
490
491
        for( size_t i=0; i<ARRAY_SIZE(channel_repeat_fixes); i++ )
492
        {
493
            if( channel_repeat_fixes[i].chans == frame.channels &&
494
                !memcmp( frame.channel_position, channel_repeat_fixes[i].faulty,
495
                                                 channel_repeat_fixes[i].chans ) )
496
            {
497
                msg_Warn( p_dec, "Patching for Front channel repeat bug" );
498
                memcpy( frame.channel_position, channel_repeat_fixes[i].fixed,
499
                                                channel_repeat_fixes[i].chans );
500
                break;
501
            }
502
        }
503
#endif
504
        /* Handle > 1 local pair 5.1 setups.
505
           In case of more than 1 channel pair per area, faad will have repeats
506
           in channels sequence. We need to remap to available surround channels.
507
           Front > Middle > Rear:
508
           In case of 4 middle, it maps to 2F 2M if no previous front.
509
           In case of 4 rear, it maps to 2M 2R if no previous rear.
510
        */
511
24.6k
        unsigned i_faadused = 0;
512
101k
        for( unsigned i=0; i<frame.channels; i++ )
513
76.5k
            if( frame.channel_position[i] > 0 )
514
53.8k
                i_faadused |= 1 << frame.channel_position[i];
515
516
45.0k
        for( size_t i=3; i<frame.channels; i++ )
517
20.4k
        {
518
20.4k
             if( frame.channel_position[i - 3] == frame.channel_position[i - 1] &&
519
5.65k
                 frame.channel_position[i - 2] == frame.channel_position[i] &&
520
5.65k
                 frame.channel_position[i - 1] >= SIDE_CHANNEL_LEFT &&
521
1
                 frame.channel_position[i - 1] <= BACK_CHANNEL_CENTER &&
522
1
                 frame.channel_position[i - 1] >= SIDE_CHANNEL_LEFT &&
523
1
                 frame.channel_position[i - 1] <= BACK_CHANNEL_CENTER )
524
1
             {
525
1
                if( ( (1 << (frame.channel_position[i - 3] - 2)) & i_faadused ) == 0 &&
526
1
                    ( (1 << (frame.channel_position[i - 2] - 2)) & i_faadused ) == 0 )
527
1
                {
528
1
                    frame.channel_position[i - 3] -= 2;
529
1
                    frame.channel_position[i - 2] -= 2;
530
1
                    i_faadused |= 1 << frame.channel_position[i - 3];
531
1
                    i_faadused |= 1 << frame.channel_position[i - 2];
532
1
                }
533
1
             }
534
20.4k
        }
535
536
        /* Convert frame.channel_position to our own channel values */
537
24.6k
        p_dec->fmt_out.audio.i_physical_channels = 0;
538
539
24.6k
        uint8_t  pi_neworder_table[64] = {0};
540
24.6k
        uint32_t pi_faad_channels_positions[64 + 1] = {0};
541
542
24.6k
        bool b_reorder = false;
543
24.6k
        if (p_dec->fmt_out.audio.channel_type == AUDIO_CHANNEL_TYPE_BITMAP)
544
24.6k
        {
545
101k
            for( size_t i = 0; i < frame.channels; i++ )
546
76.5k
            {
547
76.5k
                unsigned pos = frame.channel_position[i];
548
76.5k
                if( likely(pos < FAAD_CHANNEL_ID_COUNT) )
549
76.5k
                {
550
76.5k
                    pi_faad_channels_positions[i] = pi_tovlcmapping[pos];
551
76.5k
                    p_dec->fmt_out.audio.i_physical_channels |= pi_faad_channels_positions[i];
552
76.5k
                }
553
0
                else pi_faad_channels_positions[i] = 0;
554
76.5k
            }
555
24.6k
        }
556
0
        else if (p_dec->fmt_out.audio.channel_type == AUDIO_CHANNEL_TYPE_AMBISONICS
557
0
            && frame.channels == 4)
558
0
        {
559
0
            pi_faad_channels_positions[0] = AOUT_CHAN_REARCENTER;
560
0
            pi_faad_channels_positions[1] = AOUT_CHAN_LEFT;
561
0
            pi_faad_channels_positions[2] = AOUT_CHAN_RIGHT;
562
0
            pi_faad_channels_positions[3] = AOUT_CHAN_CENTER;
563
0
            p_dec->fmt_out.audio.i_physical_channels =
564
0
                AOUT_CHAN_CENTER | AOUT_CHAN_LEFT
565
0
                | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER;
566
0
        }
567
568
24.6k
        b_reorder = aout_CheckChannelReorder( pi_faad_channels_positions, NULL,
569
24.6k
            p_dec->fmt_out.audio.i_physical_channels, pi_neworder_table );
570
571
24.6k
        p_dec->fmt_out.audio.i_channels = stdc_count_ones(p_dec->fmt_out.audio.i_physical_channels);
572
573
24.6k
        if( !decoder_UpdateAudioFormat( p_dec ) && p_dec->fmt_out.audio.i_channels > 0 )
574
0
            p_out = decoder_NewAudioBuffer( p_dec, frame.samples / p_dec->fmt_out.audio.i_channels );
575
576
24.6k
        if( p_out )
577
0
        {
578
0
            p_out->i_pts = date_Get( &p_sys->date );
579
0
            p_out->i_length = date_Increment( &p_sys->date,
580
0
                                              frame.samples / frame.channels )
581
0
                              - p_out->i_pts;
582
0
            p_sys->i_last_length = p_out->i_length;
583
0
            if ( p_dec->fmt_out.audio.channel_type == AUDIO_CHANNEL_TYPE_BITMAP )
584
0
            {
585
                /* Don't kill speakers if some weird mapping does not gets 1:1 */
586
0
                if( stdc_count_ones(p_dec->fmt_out.audio.i_physical_channels) != frame.channels )
587
0
                    memset( p_out->p_buffer, 0, p_out->i_buffer );
588
0
            }
589
590
            /* FIXME: replace when aout_channel_reorder can take samples from a different buffer */
591
0
            if( b_reorder )
592
0
                DoReordering( (uint32_t *)p_out->p_buffer, samples,
593
0
                              frame.samples / frame.channels, frame.channels,
594
0
                              pi_neworder_table );
595
0
            else
596
0
                 memcpy( p_out->p_buffer, samples, p_out->i_buffer );
597
598
0
            if( p_sys->b_discontinuity )
599
0
            {
600
0
                p_out->i_flags |= BLOCK_FLAG_DISCONTINUITY;
601
0
                p_sys->b_discontinuity = false;
602
0
            }
603
604
0
            decoder_QueueAudio( p_dec, p_out );
605
0
        }
606
24.6k
        else
607
24.6k
        {
608
24.6k
            date_Increment( &p_sys->date, frame.samples / frame.channels );
609
24.6k
        }
610
611
24.6k
        FlushBuffer( p_sys, frame.bytesconsumed ? frame.bytesconsumed : SIZE_MAX );
612
613
24.6k
        if( p_sys->p_block && p_sys->p_block->i_buffer == 1 )
614
2
        {
615
            /* Drop byte of padding */
616
2
            FlushBuffer( p_sys, 0 );
617
2
        }
618
24.6k
    }
619
620
159k
    return VLCDEC_SUCCESS;
621
159k
}
622
623
/*****************************************************************************
624
 * Close:
625
 *****************************************************************************/
626
static void Close( vlc_object_t *p_this )
627
16.1k
{
628
16.1k
    decoder_t *p_dec = (decoder_t *)p_this;
629
16.1k
    decoder_sys_t *p_sys = p_dec->p_sys;
630
631
16.1k
    NeAACDecClose( p_sys->hfaad );
632
16.1k
    FlushBuffer( p_sys, SIZE_MAX );
633
16.1k
    free( p_sys );
634
16.1k
}
635
636
/*****************************************************************************
637
 * DoReordering: do some channel re-ordering (the ac3 channel order is
638
 *   different from the aac one).
639
 *****************************************************************************/
640
static void DoReordering( uint32_t *p_out, uint32_t *p_in, int i_samples,
641
                          int i_nb_channels, uint8_t *pi_chan_positions )
642
0
{
643
0
#if HAVE_FPU
644
0
    #define CAST_SAMPLE(a) a
645
#else
646
    #define CAST_SAMPLE(a) ((uint16_t *)a)
647
#endif
648
    /* Do the actual reordering */
649
0
    for( int i = 0; i < i_samples; i++ )
650
0
    {
651
0
        for( int j = 0; j < i_nb_channels; j++ )
652
0
        {
653
0
            CAST_SAMPLE(p_out)[i * i_nb_channels + pi_chan_positions[j]] =
654
0
                CAST_SAMPLE(p_in)[i * i_nb_channels + j];
655
0
        }
656
0
    }
657
0
}