Coverage Report

Created: 2026-11-12 07:28

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
178
vlc_module_begin ()
61
89
    set_description( N_("AAC audio decoder (using libfaad2)") )
62
89
    set_capability( "audio decoder", 100 )
63
89
    set_subcategory( SUBCAT_INPUT_ACODEC )
64
89
    set_callbacks( Open, Close )
65
89
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
1.19M
{
114
1.19M
    decoder_t *p_dec = (decoder_t*)p_this;
115
1.19M
    decoder_sys_t *p_sys;
116
1.19M
    NeAACDecConfiguration *cfg;
117
118
1.19M
    if( p_dec->fmt_in->i_codec != VLC_CODEC_MP4A ||
119
167k
        p_dec->fmt_in->i_profile >= AAC_PROFILE_ELD ||
120
167k
        (p_dec->fmt_in->i_extra > 1 &&
121
148k
         (GetWBE(p_dec->fmt_in->p_extra) & 0xffe0) >= 0xf8e0)) /* ELD AOT */
122
1.02M
    {
123
1.02M
        return VLC_EGENERIC;
124
1.02M
    }
125
126
    /* Allocate the memory needed to store the decoder's structure */
127
166k
    if( ( p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) ) ) == NULL )
128
0
        return VLC_ENOMEM;
129
130
    /* Open a faad context */
131
166k
    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
166k
    char * vinfo[2];
139
166k
    if( NeAACDecGetVersion( &vinfo[0], &vinfo[1] ) == 0 )
140
166k
        msg_Dbg( p_dec, "using version " FAAD2_VERSION " - %s", vinfo[0] );
141
142
    /* Misc init */
143
166k
    p_dec->fmt_out.audio.channel_type = p_dec->fmt_in->audio.channel_type;
144
145
166k
    if( p_dec->fmt_in->i_extra > 0 )
146
148k
    {
147
        /* We have a decoder config so init the handle */
148
148k
        unsigned long i_rate = 0;
149
148k
        unsigned char i_channels;
150
151
148k
        mp4AudioSpecificConfig mp4Conf;
152
148k
        if( NeAACDecAudioSpecificConfig( p_dec->fmt_in->p_extra,
153
148k
                                         p_dec->fmt_in->i_extra,
154
148k
                                         &mp4Conf ) >= 0 &&
155
63.4k
            mp4Conf.samplingFrequency != 0 &&
156
63.4k
            ( NeAACDecInit2( p_sys->hfaad, p_dec->fmt_in->p_extra,
157
63.4k
                             p_dec->fmt_in->i_extra,
158
63.4k
                             &i_rate, &i_channels ) < 0 ||
159
63.4k
                i_channels >= MPEG4_ASC_MAX_INDEXEDPOS ) )
160
1.57k
        {
161
1.57k
            msg_Err( p_dec, "Failed to initialize faad using extra data" );
162
1.57k
            NeAACDecClose( p_sys->hfaad );
163
1.57k
            free( p_sys );
164
1.57k
            return VLC_EGENERIC;
165
1.57k
        }
166
167
146k
        if( i_rate != 0 )
168
61.9k
        {
169
61.9k
            p_dec->fmt_out.audio.i_rate = i_rate;
170
61.9k
            p_dec->fmt_out.audio.i_channels = i_channels;
171
61.9k
            p_dec->fmt_out.audio.i_physical_channels
172
61.9k
                = MPEG4_asc_channelsbyindex[i_channels];
173
61.9k
            date_Init( &p_sys->date, i_rate, 1 );
174
61.9k
        }
175
146k
    }
176
18.1k
    else
177
18.1k
    {
178
18.1k
        p_dec->fmt_out.audio.i_physical_channels = 0;
179
        /* Will be initialised from first frame */
180
18.1k
        p_dec->fmt_out.audio.i_rate = 0;
181
18.1k
        p_dec->fmt_out.audio.i_channels = 0;
182
18.1k
        date_Set( &p_sys->date, VLC_TICK_INVALID );
183
18.1k
    }
184
185
164k
    p_dec->fmt_out.i_codec = HAVE_FPU ? VLC_CODEC_FL32 : VLC_CODEC_S16N;
186
164k
    p_dec->fmt_out.audio.i_chan_mode = p_dec->fmt_in->audio.i_chan_mode;
187
188
    /* Set the faad config */
189
164k
    cfg = NeAACDecGetCurrentConfiguration( p_sys->hfaad );
190
164k
    if( p_dec->fmt_in->audio.i_rate )
191
74.3k
        cfg->defSampleRate = p_dec->fmt_in->audio.i_rate;
192
164k
    cfg->outputFormat = HAVE_FPU ? FAAD_FMT_FLOAT : FAAD_FMT_16BIT;
193
164k
    if( !NeAACDecSetConfiguration( p_sys->hfaad, cfg ) )
194
0
    {
195
0
        msg_Err( p_dec, "Failed to set faad configuration" );
196
0
        NeAACDecClose( p_sys->hfaad );
197
0
        free( p_sys );
198
0
        return VLC_EGENERIC;
199
0
    }
200
201
164k
    p_sys->i_last_length = 0;
202
203
    /* buffer */
204
164k
    p_sys->p_block = NULL;
205
206
164k
    p_sys->b_discontinuity =
207
164k
    p_sys->b_sbr = p_sys->b_ps = false;
208
209
164k
    p_dec->pf_decode = DecodeBlock;
210
164k
    p_dec->pf_flush  = Flush;
211
164k
    return VLC_SUCCESS;
212
164k
}
213
214
/*****************************************************************************
215
 * FlushBuffer:
216
 *****************************************************************************/
217
static void FlushBuffer( decoder_sys_t *p_sys, size_t i_used )
218
1.29M
{
219
1.29M
    block_t *p_block = p_sys->p_block;
220
1.29M
    if( p_block )
221
1.05M
    {
222
1.05M
        if( i_used < p_block->i_buffer )
223
66.1k
        {
224
            /* Drop padding */
225
149k
            for( ; i_used < p_block->i_buffer; i_used++ )
226
138k
                if( p_block->p_buffer[i_used] != 0x00 )
227
55.0k
                    break;
228
229
66.1k
            p_block->i_buffer -= i_used;
230
66.1k
            p_block->p_buffer += i_used;
231
66.1k
        }
232
991k
        else p_block->i_buffer = 0;
233
1.05M
        if( p_block->i_buffer == 0 )
234
1.00M
        {
235
1.00M
            block_Release( p_block );
236
1.00M
            p_sys->p_block = NULL;
237
1.00M
        }
238
1.05M
    }
239
1.29M
}
240
241
/*****************************************************************************
242
 * Flush:
243
 *****************************************************************************/
244
static void Flush( decoder_t *p_dec )
245
998k
{
246
998k
    decoder_sys_t *p_sys = p_dec->p_sys;
247
248
998k
    date_Set( &p_sys->date, VLC_TICK_INVALID );
249
998k
    FlushBuffer( p_sys, SIZE_MAX );
250
998k
}
251
252
/*****************************************************************************
253
 * DecodeBlock:
254
 *****************************************************************************/
255
static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
256
2.41M
{
257
2.41M
    decoder_sys_t *p_sys = p_dec->p_sys;
258
259
2.41M
    if( !p_block ) /* No Drain */
260
1.40M
        return VLCDEC_SUCCESS;
261
262
1.01M
    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY | BLOCK_FLAG_CORRUPTED) )
263
71.0k
    {
264
71.0k
        Flush( p_dec );
265
71.0k
        if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED) )
266
0
        {
267
0
            block_Release( p_block );
268
0
            return VLCDEC_SUCCESS;
269
0
        }
270
71.0k
    }
271
272
    /* Remove ADTS header if we have decoder specific config */
273
1.01M
    if( p_dec->fmt_in->i_extra && p_block->i_buffer > 7 )
274
483k
    {
275
483k
        if( p_block->p_buffer[0] == 0xff &&
276
67.4k
            ( p_block->p_buffer[1] & 0xf0 ) == 0xf0 ) /* syncword */
277
59.2k
        {   /* ADTS header present */
278
59.2k
            size_t i_header_size; /* 7 bytes (+ 2 bytes for crc) */
279
59.2k
            i_header_size = 7 + ( ( p_block->p_buffer[1] & 0x01 ) ? 0 : 2 );
280
            /* FIXME: multiple blocks per frame */
281
59.2k
            if( p_block->i_buffer > i_header_size )
282
38.1k
            {
283
38.1k
                p_block->p_buffer += i_header_size;
284
38.1k
                p_block->i_buffer -= i_header_size;
285
38.1k
            }
286
59.2k
        }
287
483k
    }
288
289
1.01M
    const vlc_tick_t i_pts = p_block->i_pts;
290
291
    /* Append block as temporary buffer */
292
1.01M
    if( p_sys->p_block == NULL )
293
1.00M
    {
294
1.00M
        p_sys->p_block = p_block;
295
1.00M
    }
296
8.52k
    else
297
8.52k
    {
298
8.52k
        p_sys->p_block->p_next = p_block;
299
8.52k
        block_t *p_prev = p_sys->p_block;
300
8.52k
        p_sys->p_block = block_ChainGather( p_sys->p_block );
301
8.52k
        if( p_sys->p_block == NULL )
302
0
            block_ChainRelease( p_prev );
303
8.52k
    }
304
305
    /* !Warn: do not use p_block beyond this point */
306
307
1.01M
    if( p_dec->fmt_out.audio.i_rate == 0 )
308
26.2k
    {
309
26.2k
        unsigned long i_rate = 0;
310
26.2k
        unsigned char i_channels;
311
26.2k
        mp4AudioSpecificConfig mp4Conf;
312
313
        /* Init from DecoderConfig */
314
26.2k
        if( p_dec->fmt_in->i_extra > 0 &&
315
15.7k
            ( NeAACDecAudioSpecificConfig( p_dec->fmt_in->p_extra,
316
15.7k
                                           p_dec->fmt_in->i_extra,
317
15.7k
                                           &mp4Conf ) < 0 ||
318
9
              mp4Conf.samplingFrequency == 0 ||
319
0
              NeAACDecInit2( p_sys->hfaad, p_dec->fmt_in->p_extra,
320
0
                             p_dec->fmt_in->i_extra, &i_rate, &i_channels ) != 0 ) )
321
15.7k
        {
322
            /* Failed, will try from data */
323
15.7k
            i_rate = 0;
324
15.7k
        }
325
326
26.2k
        if( i_rate == 0 && p_sys->p_block && p_sys->p_block->i_buffer )
327
24.3k
        {
328
            /* Init faad with the first frame */
329
24.3k
            long i_read = NeAACDecInit( p_sys->hfaad,
330
24.3k
                                        p_sys->p_block->p_buffer, p_sys->p_block->i_buffer,
331
24.3k
                                        &i_rate, &i_channels );
332
24.3k
            if( i_read < 0 || (size_t) i_read > p_sys->p_block->i_buffer )
333
9.61k
                i_rate = 0;
334
14.7k
            else
335
14.7k
                FlushBuffer( p_sys, i_read );
336
24.3k
        }
337
338
26.2k
        if( i_rate == 0 || i_channels >= MPEG4_ASC_MAX_INDEXEDPOS )
339
11.4k
        {
340
            /* Can not init decoder at all for now */
341
11.4k
            FlushBuffer( p_sys, SIZE_MAX );
342
11.4k
            return VLCDEC_SUCCESS;
343
11.4k
        }
344
345
        /* Decoder Initialized */
346
14.7k
        p_dec->fmt_out.audio.i_rate = i_rate;
347
14.7k
        p_dec->fmt_out.audio.i_channels = i_channels;
348
14.7k
        p_dec->fmt_out.audio.i_physical_channels
349
14.7k
            = MPEG4_asc_channelsbyindex[i_channels];
350
14.7k
        date_Init( &p_sys->date, i_rate, 1 );
351
14.7k
    }
352
353
999k
    if( i_pts != VLC_TICK_INVALID && i_pts != date_Get( &p_sys->date ) )
354
976k
    {
355
976k
        if( p_sys->i_last_length == 0 ||
356
            /* We need to be permissive and rebase dts when it's really way off */
357
0
            llabs( i_pts - date_Get( &p_sys->date ) ) > p_sys->i_last_length * 3 / 2  )
358
976k
            date_Set( &p_sys->date, i_pts );
359
976k
    }
360
23.3k
    else if( date_Get( &p_sys->date ) == VLC_TICK_INVALID )
361
0
    {
362
        /* We've just started the stream, wait for the first PTS. */
363
0
        FlushBuffer( p_sys, SIZE_MAX );
364
0
        return VLCDEC_SUCCESS;
365
0
    }
366
367
    /* Decode all data */
368
2.02M
    while( p_sys->p_block && p_sys->p_block->i_buffer > 0 )
369
1.02M
    {
370
1.02M
        void *samples;
371
1.02M
        NeAACDecFrameInfo frame;
372
1.02M
        block_t *p_out = NULL;
373
374
1.02M
        samples = NeAACDecDecode( p_sys->hfaad, &frame,
375
1.02M
                                  p_sys->p_block->p_buffer,
376
1.02M
                                  p_sys->p_block->i_buffer );
377
378
1.02M
        if( frame.error > 0 )
379
927k
        {
380
927k
            msg_Warn( p_dec, "%s", NeAACDecGetErrorMessage( frame.error ) );
381
382
927k
            if( frame.error == 21 || frame.error == 12 )
383
113k
            {
384
                /*
385
                 * Once an "Unexpected channel configuration change"
386
                 * or a "Invalid number of channels" error
387
                 * occurs, it will occurs afterwards, and we got no sound.
388
                 * Reinitialization of the decoder is required.
389
                 */
390
113k
                unsigned long i_rate;
391
113k
                unsigned char i_channels;
392
113k
                NeAACDecHandle *hfaad;
393
113k
                NeAACDecConfiguration *cfg,*oldcfg;
394
395
113k
                oldcfg = NeAACDecGetCurrentConfiguration( p_sys->hfaad );
396
113k
                hfaad = NeAACDecOpen();
397
113k
                cfg = NeAACDecGetCurrentConfiguration( hfaad );
398
113k
                if( oldcfg->defSampleRate )
399
113k
                    cfg->defSampleRate = oldcfg->defSampleRate;
400
113k
                cfg->defObjectType = oldcfg->defObjectType;
401
113k
                cfg->outputFormat = oldcfg->outputFormat;
402
113k
                NeAACDecSetConfiguration( hfaad, cfg );
403
404
113k
                if( NeAACDecInit( hfaad,
405
113k
                                  p_sys->p_block->p_buffer,
406
113k
                                  p_sys->p_block->i_buffer,
407
113k
                                  &i_rate,&i_channels ) < 0 ||
408
73.7k
                    i_channels >= MPEG4_ASC_MAX_INDEXEDPOS )
409
39.7k
                {
410
                    /* reinitialization failed */
411
39.7k
                    NeAACDecClose( hfaad );
412
39.7k
                    NeAACDecSetConfiguration( p_sys->hfaad, oldcfg );
413
39.7k
                }
414
73.5k
                else
415
73.5k
                {
416
73.5k
                    NeAACDecClose( p_sys->hfaad );
417
73.5k
                    p_sys->hfaad = hfaad;
418
73.5k
                    p_dec->fmt_out.audio.i_rate = i_rate;
419
73.5k
                    p_dec->fmt_out.audio.i_channels = i_channels;
420
73.5k
                    p_dec->fmt_out.audio.i_physical_channels
421
73.5k
                        = MPEG4_asc_channelsbyindex[i_channels];
422
73.5k
                    date_Init( &p_sys->date, i_rate, 1 );
423
73.5k
                }
424
113k
            }
425
426
927k
            Flush( p_dec );
427
927k
            p_sys->b_discontinuity = true;
428
429
927k
            continue;
430
927k
        }
431
432
101k
        if( frame.channels == 0 || frame.channels >= 64 )
433
177
        {
434
177
            msg_Warn( p_dec, "invalid channels count: %i", frame.channels );
435
177
            if( frame.channels == 0 )
436
177
                p_sys->b_discontinuity = true;
437
177
            FlushBuffer( p_sys, frame.bytesconsumed ? frame.bytesconsumed : SIZE_MAX );
438
177
            continue;
439
177
        }
440
441
101k
        if( frame.samples == 0 )
442
12.0k
        {
443
12.0k
            msg_Warn( p_dec, "decoded zero sample" );
444
12.0k
            FlushBuffer( p_sys, frame.bytesconsumed ? frame.bytesconsumed : SIZE_MAX );
445
12.0k
            continue;
446
12.0k
        }
447
448
        /* We decoded a valid frame */
449
89.7k
        if( p_dec->fmt_out.audio.i_rate != frame.samplerate )
450
40
        {
451
40
            date_Init( &p_sys->date, frame.samplerate, 1 );
452
40
            date_Set( &p_sys->date, i_pts );
453
40
        }
454
455
89.7k
        p_dec->fmt_out.audio.i_rate = frame.samplerate;
456
457
        /* Adjust stream info when dealing with SBR/PS */
458
89.7k
        bool b_sbr = (frame.sbr == 1) || (frame.sbr == 2);
459
89.7k
        if( p_sys->b_sbr != b_sbr || p_sys->b_ps != frame.ps )
460
2.62k
        {
461
2.62k
            const char *psz_ext = (b_sbr && frame.ps) ? "SBR+PS" :
462
2.62k
                                    b_sbr ? "SBR" : "PS";
463
464
2.62k
            msg_Dbg( p_dec, "AAC %s (channels: %u, samplerate: %lu)",
465
2.62k
                    psz_ext, frame.channels, frame.samplerate );
466
467
2.62k
            if( !p_dec->p_description )
468
1.16k
                p_dec->p_description = vlc_meta_New();
469
2.62k
            if( p_dec->p_description )
470
2.62k
                vlc_meta_SetExtra( p_dec->p_description, _("AAC extension"), psz_ext );
471
472
2.62k
            p_sys->b_sbr = b_sbr;
473
2.62k
            p_sys->b_ps = frame.ps;
474
2.62k
        }
475
476
#ifdef PATCH_PCA
477
        /* PS Enabled FAAD PCA bug hotfix (contribs has patch) */
478
        if( frame.channels == 8 )
479
        {
480
            const uint8_t psbugconfig[3][8] = { { 2, 3, 2, 3, 2, 3, 6, 7 },  /* fdk 7.1 (4 Front) */
481
                                                { 2, 3, 2, 3, 2, 3, 4, 5 },  /* 7.1 */
482
                                                { 1, 2, 3, 4, 5, 6, 7, 9 } };/* fixed */
483
            for( size_t i=0; i<2; i++ )
484
            {
485
                if( !memcmp( frame.channel_position, psbugconfig[i], 8 ) )
486
                {
487
                    msg_Warn( p_dec, "Unpatched FAAD2 library with PS Bug. Trying to workaround !" );
488
                    memcpy( frame.channel_position, psbugconfig[2], 8 );
489
                    break;
490
                }
491
            }
492
        }
493
494
        /* Hotfix channels misdetection/repetition for FDK 7.1 */
495
        struct
496
        {
497
            const uint8_t chans;
498
            const uint8_t faulty[8];
499
            const uint8_t fixed[8];
500
        } const channel_repeat_fixes[] = {
501
            { 7, { 2, 3, 2, 3, 2, 3, 6 },    { 1, 2, 3, 6, 7, 8, 9 }    }, /* 3F 3R LFE #18273 */
502
            { 8, { 1, 2, 3, 6, 7, 6, 7, 9 }, { 1, 2, 3, 6, 7, 4, 5, 9 } }, /* FDK encoded 7.1 */
503
        };
504
505
        for( size_t i=0; i<ARRAY_SIZE(channel_repeat_fixes); i++ )
506
        {
507
            if( channel_repeat_fixes[i].chans == frame.channels &&
508
                !memcmp( frame.channel_position, channel_repeat_fixes[i].faulty,
509
                                                 channel_repeat_fixes[i].chans ) )
510
            {
511
                msg_Warn( p_dec, "Patching for Front channel repeat bug" );
512
                memcpy( frame.channel_position, channel_repeat_fixes[i].fixed,
513
                                                channel_repeat_fixes[i].chans );
514
                break;
515
            }
516
        }
517
#endif
518
        /* Handle > 1 local pair 5.1 setups.
519
           In case of more than 1 channel pair per area, faad will have repeats
520
           in channels sequence. We need to remap to available surround channels.
521
           Front > Middle > Rear:
522
           In case of 4 middle, it maps to 2F 2M if no previous front.
523
           In case of 4 rear, it maps to 2M 2R if no previous rear.
524
        */
525
89.7k
        unsigned i_faadused = 0;
526
330k
        for( unsigned i=0; i<frame.channels; i++ )
527
240k
            if( frame.channel_position[i] > 0 )
528
203k
                i_faadused |= 1 << frame.channel_position[i];
529
530
133k
        for( size_t i=3; i<frame.channels; i++ )
531
43.8k
        {
532
43.8k
             if( frame.channel_position[i - 3] == frame.channel_position[i - 1] &&
533
12.1k
                 frame.channel_position[i - 2] == frame.channel_position[i] &&
534
11.6k
                 frame.channel_position[i - 1] >= SIDE_CHANNEL_LEFT &&
535
389
                 frame.channel_position[i - 1] <= BACK_CHANNEL_CENTER &&
536
389
                 frame.channel_position[i - 1] >= SIDE_CHANNEL_LEFT &&
537
389
                 frame.channel_position[i - 1] <= BACK_CHANNEL_CENTER )
538
389
             {
539
389
                if( ( (1 << (frame.channel_position[i - 3] - 2)) & i_faadused ) == 0 &&
540
365
                    ( (1 << (frame.channel_position[i - 2] - 2)) & i_faadused ) == 0 )
541
365
                {
542
365
                    frame.channel_position[i - 3] -= 2;
543
365
                    frame.channel_position[i - 2] -= 2;
544
365
                    i_faadused |= 1 << frame.channel_position[i - 3];
545
365
                    i_faadused |= 1 << frame.channel_position[i - 2];
546
365
                }
547
389
             }
548
43.8k
        }
549
550
        /* Convert frame.channel_position to our own channel values */
551
89.7k
        p_dec->fmt_out.audio.i_physical_channels = 0;
552
553
89.7k
        uint8_t  pi_neworder_table[64] = {0};
554
89.7k
        uint32_t pi_faad_channels_positions[64 + 1] = {0};
555
556
89.7k
        bool b_reorder = false;
557
89.7k
        if (p_dec->fmt_out.audio.channel_type == AUDIO_CHANNEL_TYPE_BITMAP)
558
89.7k
        {
559
330k
            for( size_t i = 0; i < frame.channels; i++ )
560
240k
            {
561
240k
                unsigned pos = frame.channel_position[i];
562
240k
                if( likely(pos < FAAD_CHANNEL_ID_COUNT) )
563
240k
                {
564
240k
                    pi_faad_channels_positions[i] = pi_tovlcmapping[pos];
565
240k
                    p_dec->fmt_out.audio.i_physical_channels |= pi_faad_channels_positions[i];
566
240k
                }
567
0
                else pi_faad_channels_positions[i] = 0;
568
240k
            }
569
89.7k
        }
570
0
        else if (p_dec->fmt_out.audio.channel_type == AUDIO_CHANNEL_TYPE_AMBISONICS
571
0
            && frame.channels == 4)
572
0
        {
573
0
            pi_faad_channels_positions[0] = AOUT_CHAN_REARCENTER;
574
0
            pi_faad_channels_positions[1] = AOUT_CHAN_LEFT;
575
0
            pi_faad_channels_positions[2] = AOUT_CHAN_RIGHT;
576
0
            pi_faad_channels_positions[3] = AOUT_CHAN_CENTER;
577
0
            p_dec->fmt_out.audio.i_physical_channels =
578
0
                AOUT_CHAN_CENTER | AOUT_CHAN_LEFT
579
0
                | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER;
580
0
        }
581
582
89.7k
        b_reorder = aout_CheckChannelReorder( pi_faad_channels_positions, NULL,
583
89.7k
            p_dec->fmt_out.audio.i_physical_channels, pi_neworder_table );
584
585
89.7k
        p_dec->fmt_out.audio.i_channels = stdc_count_ones(p_dec->fmt_out.audio.i_physical_channels);
586
587
89.7k
        if( !decoder_UpdateAudioFormat( p_dec ) && p_dec->fmt_out.audio.i_channels > 0 )
588
0
            p_out = decoder_NewAudioBuffer( p_dec, frame.samples / p_dec->fmt_out.audio.i_channels );
589
590
89.7k
        if( p_out )
591
0
        {
592
0
            p_out->i_pts = date_Get( &p_sys->date );
593
0
            p_out->i_length = date_Increment( &p_sys->date,
594
0
                                              frame.samples / frame.channels )
595
0
                              - p_out->i_pts;
596
0
            p_sys->i_last_length = p_out->i_length;
597
0
            if ( p_dec->fmt_out.audio.channel_type == AUDIO_CHANNEL_TYPE_BITMAP )
598
0
            {
599
                /* Don't kill speakers if some weird mapping does not gets 1:1 */
600
0
                if( stdc_count_ones(p_dec->fmt_out.audio.i_physical_channels) != frame.channels )
601
0
                    memset( p_out->p_buffer, 0, p_out->i_buffer );
602
0
            }
603
604
            /* FIXME: replace when aout_channel_reorder can take samples from a different buffer */
605
0
            if( b_reorder )
606
0
                DoReordering( (uint32_t *)p_out->p_buffer, samples,
607
0
                              frame.samples / frame.channels, frame.channels,
608
0
                              pi_neworder_table );
609
0
            else
610
0
                 memcpy( p_out->p_buffer, samples, p_out->i_buffer );
611
612
0
            if( p_sys->b_discontinuity )
613
0
            {
614
0
                p_out->i_flags |= BLOCK_FLAG_DISCONTINUITY;
615
0
                p_sys->b_discontinuity = false;
616
0
            }
617
618
0
            decoder_QueueAudio( p_dec, p_out );
619
0
        }
620
89.7k
        else
621
89.7k
        {
622
89.7k
            date_Increment( &p_sys->date, frame.samples / frame.channels );
623
89.7k
        }
624
625
89.7k
        FlushBuffer( p_sys, frame.bytesconsumed ? frame.bytesconsumed : SIZE_MAX );
626
627
89.7k
        if( p_sys->p_block && p_sys->p_block->i_buffer == 1 )
628
737
        {
629
            /* Drop byte of padding */
630
737
            FlushBuffer( p_sys, 0 );
631
737
        }
632
89.7k
    }
633
634
999k
    return VLCDEC_SUCCESS;
635
999k
}
636
637
/*****************************************************************************
638
 * Close:
639
 *****************************************************************************/
640
static void Close( vlc_object_t *p_this )
641
164k
{
642
164k
    decoder_t *p_dec = (decoder_t *)p_this;
643
164k
    decoder_sys_t *p_sys = p_dec->p_sys;
644
645
164k
    NeAACDecClose( p_sys->hfaad );
646
164k
    FlushBuffer( p_sys, SIZE_MAX );
647
164k
    free( p_sys );
648
164k
}
649
650
/*****************************************************************************
651
 * DoReordering: do some channel re-ordering (the ac3 channel order is
652
 *   different from the aac one).
653
 *****************************************************************************/
654
static void DoReordering( uint32_t *p_out, uint32_t *p_in, int i_samples,
655
                          int i_nb_channels, uint8_t *pi_chan_positions )
656
0
{
657
0
#if HAVE_FPU
658
0
    #define CAST_SAMPLE(a) a
659
#else
660
    #define CAST_SAMPLE(a) ((uint16_t *)a)
661
#endif
662
    /* Do the actual reordering */
663
0
    for( int i = 0; i < i_samples; i++ )
664
0
    {
665
0
        for( int j = 0; j < i_nb_channels; j++ )
666
0
        {
667
0
            CAST_SAMPLE(p_out)[i * i_nb_channels + pi_chan_positions[j]] =
668
0
                CAST_SAMPLE(p_in)[i * i_nb_channels + j];
669
0
        }
670
0
    }
671
0
}