Coverage Report

Created: 2026-09-01 07:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/modules/codec/avcodec/audio.c
Line
Count
Source
1
/*****************************************************************************
2
 * audio.c: audio decoder using libavcodec library
3
 *****************************************************************************
4
 * Copyright (C) 1999-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
 * Preamble
26
 *****************************************************************************/
27
#ifdef HAVE_CONFIG_H
28
# include "config.h"
29
#endif
30
31
#include <assert.h>
32
33
#include <vlc_common.h>
34
#include <vlc_aout.h>
35
#include <vlc_codec.h>
36
#include <vlc_avcodec.h>
37
38
#include "avcodec.h"
39
#include "../../demux/xiph.h"
40
41
#include <stdbit.h>
42
43
#include <libavcodec/avcodec.h>
44
#include <libavutil/mem.h>
45
46
#define API_CHANNEL_LAYOUT_STRUCT (LIBAVCODEC_VERSION_CHECK(59, 24, 100)) // AVCodecContext.ch_layout
47
48
#include <libavutil/channel_layout.h>
49
50
51
/*****************************************************************************
52
 * decoder_sys_t : decoder descriptor
53
 *****************************************************************************/
54
typedef struct
55
{
56
    AVCodecContext *p_context;
57
    const AVCodec  *p_codec;
58
59
    /*
60
     * Output properties
61
     */
62
    audio_sample_format_t aout_format;
63
    date_t                end_date;
64
65
    /* */
66
    int     i_reject_count;
67
68
    /* */
69
    bool    b_extract;
70
    bool    discontinuity;
71
    int     pi_extraction[AOUT_CHAN_MAX];
72
    int     i_previous_channels;
73
    uint64_t i_previous_layout;
74
} decoder_sys_t;
75
76
4.42M
#define BLOCK_FLAG_PRIVATE_REALLOCATED (1 << BLOCK_FLAG_PRIVATE_SHIFT)
77
78
static void SetupOutputFormat( decoder_t *p_dec, bool b_trust );
79
static block_t * ConvertAVFrame( decoder_t *p_dec, AVFrame *frame );
80
static int  DecodeAudio( decoder_t *, block_t * );
81
static void Flush( decoder_t * );
82
83
static void InitDecoderConfig( decoder_t *p_dec, AVCodecContext *p_context )
84
305k
{
85
305k
    if( p_dec->fmt_in->i_extra > 0 )
86
74.5k
    {
87
74.5k
        const uint8_t * const p_src = p_dec->fmt_in->p_extra;
88
89
74.5k
        int i_offset = 0;
90
74.5k
        int i_size = p_dec->fmt_in->i_extra;
91
92
74.5k
        if( p_dec->fmt_in->i_codec == VLC_CODEC_ALAC )
93
11
        {
94
11
            static const uint8_t p_pattern[] = { 0, 0, 0, 36, 'a', 'l', 'a', 'c' };
95
            /* Find alac atom XXX it is a bit ugly */
96
272
            for( i_offset = 0; i_offset < i_size - (int)sizeof(p_pattern); i_offset++ )
97
261
            {
98
261
                if( !memcmp( &p_src[i_offset], p_pattern, sizeof(p_pattern) ) )
99
0
                    break;
100
261
            }
101
11
            i_size = __MIN( p_dec->fmt_in->i_extra - i_offset, 36 );
102
11
            if( i_size < 36 )
103
11
                i_size = 0;
104
11
        }
105
74.5k
        else if( p_dec->fmt_in->i_codec == VLC_CODEC_OPUS &&
106
0
                 i_size > 21 && !memcmp( &p_src[2], "OpusHead", 8 ) )
107
0
        {
108
            /* see opus.c decoder */
109
0
            size_t hdr_size[XIPH_MAX_HEADER_COUNT];
110
0
            const void *hdr[XIPH_MAX_HEADER_COUNT];
111
0
            size_t i_count;
112
0
            if( !xiph_SplitHeaders( hdr_size, hdr, &i_count,
113
0
                                    i_size, p_src ) && i_count >= 1 )
114
0
            {
115
0
                i_offset = (const uint8_t *)hdr[0] - p_src;
116
0
                i_size = hdr_size[0];
117
0
            }
118
0
        }
119
120
74.5k
        if( i_size > 0 )
121
74.5k
        {
122
74.5k
            p_context->extradata =
123
74.5k
                av_malloc( i_size + AV_INPUT_BUFFER_PADDING_SIZE );
124
74.5k
            if( p_context->extradata )
125
74.5k
            {
126
74.5k
                uint8_t *p_dst = p_context->extradata;
127
128
74.5k
                p_context->extradata_size = i_size;
129
130
74.5k
                memcpy( &p_dst[0],            &p_src[i_offset], i_size );
131
74.5k
                memset( &p_dst[i_size], 0, AV_INPUT_BUFFER_PADDING_SIZE );
132
74.5k
            }
133
74.5k
        }
134
74.5k
    }
135
231k
    else
136
231k
    {
137
231k
        p_context->extradata_size = 0;
138
231k
        p_context->extradata = NULL;
139
231k
    }
140
305k
}
141
142
static int OpenAudioCodec( decoder_t *p_dec )
143
305k
{
144
305k
    decoder_sys_t *p_sys = p_dec->p_sys;
145
305k
    AVCodecContext *ctx = p_sys->p_context;
146
305k
    const AVCodec *codec = p_sys->p_codec;
147
148
305k
    if( ctx->extradata_size <= 0 )
149
231k
    {
150
231k
        if( codec->id == AV_CODEC_ID_VORBIS ||
151
231k
            ( codec->id == AV_CODEC_ID_AAC &&
152
0
              !p_dec->fmt_in->b_packetized ) )
153
0
        {
154
0
            msg_Warn( p_dec, "waiting for extra data for codec %s",
155
0
                      codec->name );
156
0
            return 1;
157
0
        }
158
231k
    }
159
160
305k
    ctx->sample_rate = p_dec->fmt_in->audio.i_rate;
161
305k
#if API_CHANNEL_LAYOUT_STRUCT && LIBAVUTIL_VERSION_CHECK(57, 24, 100)
162
305k
    av_channel_layout_default( &ctx->ch_layout, p_dec->fmt_in->audio.i_channels );
163
#else
164
    ctx->channels = p_dec->fmt_in->audio.i_channels;
165
#endif
166
305k
    ctx->block_align = p_dec->fmt_in->audio.i_blockalign;
167
305k
    ctx->bit_rate = p_dec->fmt_in->i_bitrate;
168
305k
    ctx->bits_per_coded_sample = p_dec->fmt_in->audio.i_bitspersample;
169
170
305k
    if( codec->id == AV_CODEC_ID_ADPCM_G726 &&
171
67
        ctx->bit_rate > 0 &&
172
67
        ctx->sample_rate >  0)
173
14
        ctx->bits_per_coded_sample = ctx->bit_rate / ctx->sample_rate;
174
175
305k
    return ffmpeg_OpenCodec( p_dec, ctx, codec );
176
305k
}
177
178
/**
179
 * Allocates decoded audio buffer for libavcodec to use.
180
 */
181
typedef struct
182
{
183
    block_t self;
184
    AVFrame *frame;
185
} vlc_av_frame_t;
186
187
static void vlc_av_frame_Release(block_t *block)
188
0
{
189
0
    vlc_av_frame_t *b = (void *)block;
190
191
0
    av_frame_free(&b->frame);
192
0
    free(b);
193
0
}
194
195
static const struct vlc_block_callbacks vlc_av_frame_cbs =
196
{
197
    vlc_av_frame_Release,
198
};
199
200
static block_t *vlc_av_frame_Wrap(AVFrame *frame)
201
0
{
202
0
    for (unsigned i = 1; i < AV_NUM_DATA_POINTERS; i++)
203
0
        assert(frame->linesize[i] == 0); /* only packed frame supported */
204
205
0
    if (av_frame_make_writable(frame)) /* TODO: read-only block_t */
206
0
        return NULL;
207
208
0
    vlc_av_frame_t *b = malloc(sizeof (*b));
209
0
    if (unlikely(b == NULL))
210
0
        return NULL;
211
212
0
    block_t *block = &b->self;
213
214
0
    block_Init(block, &vlc_av_frame_cbs,
215
0
               frame->extended_data[0], frame->linesize[0]);
216
0
    block->i_nb_samples = frame->nb_samples;
217
0
    b->frame = frame;
218
0
    return block;
219
0
}
220
221
/*****************************************************************************
222
 * EndAudio: decoder destruction
223
 *****************************************************************************
224
 * This function is called when the thread ends after a successful
225
 * initialization.
226
 *****************************************************************************/
227
void EndAudioDec( vlc_object_t *obj )
228
232k
{
229
232k
    decoder_t *p_dec = (decoder_t *)obj;
230
232k
    decoder_sys_t *sys = p_dec->p_sys;
231
232k
    AVCodecContext *ctx = sys->p_context;
232
233
232k
    avcodec_free_context( &ctx );
234
232k
    free( sys );
235
232k
}
236
237
/*****************************************************************************
238
 * InitAudioDec: initialize audio decoder
239
 *****************************************************************************
240
 * The avcodec codec will be opened, some memory allocated.
241
 *****************************************************************************/
242
int InitAudioDec( vlc_object_t *obj )
243
307k
{
244
307k
    decoder_t *p_dec = (decoder_t *)obj;
245
307k
    const AVCodec *codec;
246
307k
    AVCodecContext *avctx = ffmpeg_AllocContext( p_dec, &codec, false );
247
307k
    if( avctx == NULL )
248
2.16k
        return VLC_EGENERIC;
249
250
    /* Allocate the memory needed to store the decoder's structure */
251
305k
    decoder_sys_t *p_sys = malloc(sizeof(*p_sys));
252
305k
    if( unlikely(p_sys == NULL) )
253
0
    {
254
0
        avcodec_free_context( &avctx );
255
0
        return VLC_ENOMEM;
256
0
    }
257
258
305k
    p_dec->p_sys = p_sys;
259
305k
    p_sys->p_context = avctx;
260
305k
    p_sys->p_codec = codec;
261
262
    // Initialize decoder extradata
263
305k
    InitDecoderConfig( p_dec, avctx );
264
265
    /* ***** Open the codec ***** */
266
305k
    if( OpenAudioCodec( p_dec ) < 0 )
267
73.6k
    {
268
73.6k
        free( p_sys );
269
73.6k
        avcodec_free_context( &avctx );
270
73.6k
        return VLC_EGENERIC;
271
73.6k
    }
272
273
232k
    p_sys->i_reject_count = 0;
274
232k
    p_sys->b_extract = false;
275
232k
    p_sys->i_previous_channels = 0;
276
232k
    p_sys->i_previous_layout = 0;
277
232k
    p_sys->discontinuity = false;
278
279
    /* */
280
    /* Try to set as much information as possible but do not trust it */
281
232k
    SetupOutputFormat( p_dec, false );
282
283
232k
    if( !p_dec->fmt_out.audio.i_rate )
284
15.1k
        p_dec->fmt_out.audio.i_rate = p_dec->fmt_in->audio.i_rate;
285
232k
    if( p_dec->fmt_out.audio.i_rate )
286
216k
        date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
287
232k
    p_dec->fmt_out.audio.i_chan_mode = p_dec->fmt_in->audio.i_chan_mode;
288
289
232k
    p_dec->pf_decode = DecodeAudio;
290
232k
    p_dec->pf_flush  = Flush;
291
292
232k
    return VLC_SUCCESS;
293
305k
}
294
295
/*****************************************************************************
296
 * Flush:
297
 *****************************************************************************/
298
static void Flush( decoder_t *p_dec )
299
0
{
300
0
    decoder_sys_t *p_sys = p_dec->p_sys;
301
0
    AVCodecContext *ctx = p_sys->p_context;
302
303
0
    if( avcodec_is_open( ctx ) )
304
0
        avcodec_flush_buffers( ctx );
305
0
    date_Set( &p_sys->end_date, VLC_TICK_INVALID );
306
307
0
    if( ctx->codec_id == AV_CODEC_ID_MP2 ||
308
0
        ctx->codec_id == AV_CODEC_ID_MP3 )
309
0
        p_sys->i_reject_count = 3;
310
0
    p_sys->discontinuity = false;
311
0
}
312
313
/*****************************************************************************
314
 * DecodeBlock: Called to decode one frame
315
 *****************************************************************************/
316
static int DecodeBlock( decoder_t *p_dec, block_t **pp_block )
317
3.06M
{
318
3.06M
    decoder_sys_t *p_sys = p_dec->p_sys;
319
3.06M
    AVCodecContext *ctx = p_sys->p_context;
320
3.06M
    AVFrame *frame = NULL;
321
3.06M
    block_t *p_block = NULL;
322
3.06M
    bool b_error = false;
323
324
3.06M
    if( !ctx->extradata_size && p_dec->fmt_in->i_extra
325
0
     && !avcodec_is_open( ctx ) )
326
0
    {
327
0
        InitDecoderConfig( p_dec, ctx );
328
0
        if( OpenAudioCodec( p_dec ) < 0 )
329
0
        {
330
0
            if( pp_block != NULL && *pp_block != NULL )
331
0
                block_Release( *pp_block );
332
0
            return VLCDEC_ECRITICAL;
333
0
        }
334
0
    }
335
336
3.06M
    if( !avcodec_is_open( ctx ) )
337
0
    {
338
0
        if( pp_block )
339
0
            p_block = *pp_block;
340
0
        goto drop;
341
0
    }
342
343
3.06M
    if( pp_block == NULL ) /* Drain request */
344
849k
    {
345
        /* we don't need to care about return val */
346
849k
        (void) avcodec_send_packet( ctx, NULL );
347
849k
    }
348
2.21M
    else
349
2.21M
    {
350
2.21M
        p_block = *pp_block;
351
2.21M
    }
352
353
3.06M
    if( p_block )
354
2.21M
    {
355
2.21M
        if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
356
0
        {
357
0
            Flush( p_dec );
358
0
            goto drop;
359
0
        }
360
361
2.21M
        if( p_block->i_flags & BLOCK_FLAG_DISCONTINUITY )
362
7.20k
        {
363
7.20k
            date_Set( &p_sys->end_date, VLC_TICK_INVALID );
364
7.20k
        }
365
366
        /* We've just started the stream, wait for the first PTS. */
367
2.21M
        if( p_block->i_pts == VLC_TICK_INVALID &&
368
1.67k
            date_Get( &p_sys->end_date ) == VLC_TICK_INVALID )
369
1.67k
            goto drop;
370
371
2.21M
        if( p_block->i_buffer <= 0 )
372
194
            goto drop;
373
374
2.21M
        if( (p_block->i_flags & BLOCK_FLAG_PRIVATE_REALLOCATED) == 0 )
375
2.21M
        {
376
2.21M
            *pp_block = p_block = block_Realloc( p_block, 0, p_block->i_buffer + AV_INPUT_BUFFER_PADDING_SIZE );
377
2.21M
            if( !p_block )
378
0
                goto end;
379
2.21M
            p_block->i_buffer -= AV_INPUT_BUFFER_PADDING_SIZE;
380
2.21M
            memset( &p_block->p_buffer[p_block->i_buffer], 0, AV_INPUT_BUFFER_PADDING_SIZE );
381
382
2.21M
            p_block->i_flags |= BLOCK_FLAG_PRIVATE_REALLOCATED;
383
2.21M
        }
384
2.21M
    }
385
386
3.06M
    frame = av_frame_alloc();
387
3.06M
    if (unlikely(frame == NULL))
388
0
        goto end;
389
390
3.06M
    bool send_failed = false;
391
4.79M
    for( int ret = 0; ret == 0; )
392
3.06M
    {
393
        /* Feed in the loop as buffer could have been full on first iterations */
394
3.06M
        if( p_block )
395
2.21M
        {
396
2.21M
            AVPacket *pkt = av_packet_alloc();
397
2.21M
            if( !pkt )
398
0
                goto end;
399
2.21M
            pkt->data = p_block->p_buffer;
400
2.21M
            pkt->size = p_block->i_buffer;
401
2.21M
            ret = avcodec_send_packet( ctx, pkt );
402
2.21M
            av_packet_free(&pkt);
403
2.21M
            if( ret == 0 ) /* Block has been consumed */
404
1.34M
            {
405
                /* Only set new pts from input block if it has been used,
406
                 * otherwise let it be through interpolation */
407
1.34M
                if( p_block->i_pts > date_Get( &p_sys->end_date ) )
408
1.33M
                {
409
1.33M
                    date_Set( &p_sys->end_date, p_block->i_pts );
410
1.33M
                }
411
412
1.34M
                block_Release( p_block );
413
1.34M
                *pp_block = p_block = NULL;
414
1.34M
            }
415
868k
            else if ( ret != AVERROR(EAGAIN) ) /* Errors other than buffer full */
416
857k
            {
417
857k
                if( ret == AVERROR(ENOMEM) || ret == AVERROR(EINVAL) )
418
0
                    goto end;
419
857k
                else
420
857k
                {
421
857k
                    char errorstring[AV_ERROR_MAX_STRING_SIZE];
422
857k
                    if( !av_strerror( ret, errorstring, AV_ERROR_MAX_STRING_SIZE ) )
423
857k
                        msg_Err( p_dec, "%s", errorstring );
424
425
                    /* Signal an error, but continue to receive all output
426
                     * frames. A discontinuity will be triggered for the
427
                     * output frame coming right after the dropped one. */
428
857k
                    send_failed = true;
429
857k
                    block_Release( p_block );
430
857k
                    *pp_block = p_block = NULL;
431
857k
                }
432
857k
            }
433
2.21M
        }
434
435
        /* Try to read one or multiple frames */
436
3.06M
        ret = avcodec_receive_frame( ctx, frame );
437
3.06M
        if( ret == 0 )
438
1.33M
        {
439
1.33M
#if LIBAVUTIL_VERSION_CHECK(57, 24, 100)
440
1.33M
            int channels = frame->ch_layout.nb_channels;
441
#else
442
            int channels = ctx->channels;
443
#endif
444
            /* checks and init from first decoded frame */
445
1.33M
            if( channels <= 0 || channels > INPUT_CHAN_MAX
446
1.33M
             || ctx->sample_rate <= 0 )
447
493
            {
448
493
                msg_Warn( p_dec, "invalid audio properties channels count %d, sample rate %d",
449
493
                          channels, ctx->sample_rate );
450
493
                goto drop;
451
493
            }
452
1.33M
            else if( p_dec->fmt_out.audio.i_rate != (unsigned int)ctx->sample_rate )
453
582
            {
454
582
                date_Init( &p_sys->end_date, ctx->sample_rate, 1 );
455
582
            }
456
457
1.33M
            SetupOutputFormat( p_dec, true );
458
1.33M
            if( decoder_UpdateAudioFormat( p_dec ) )
459
1.33M
                goto drop;
460
461
0
            block_t *p_converted = ConvertAVFrame( p_dec, frame ); /* Consumes frame */
462
0
            if( p_converted )
463
0
            {
464
                /* Silent unwanted samples */
465
0
                if( p_sys->i_reject_count > 0 )
466
0
                {
467
0
                    memset( p_converted->p_buffer, 0, p_converted->i_buffer );
468
0
                    p_sys->i_reject_count--;
469
0
                }
470
0
                p_converted->i_buffer = p_converted->i_nb_samples
471
0
                                      * p_dec->fmt_out.audio.i_bytes_per_frame;
472
0
                p_converted->i_pts = date_Get( &p_sys->end_date );
473
0
                p_converted->i_length = date_Increment( &p_sys->end_date,
474
0
                                                      p_converted->i_nb_samples ) - p_converted->i_pts;
475
476
0
                if (p_sys->discontinuity)
477
0
                {
478
0
                    p_sys->discontinuity = false;
479
0
                    p_converted->i_flags |= BLOCK_FLAG_DISCONTINUITY;
480
0
                }
481
0
                decoder_QueueAudio( p_dec, p_converted );
482
0
            }
483
484
            /* Prepare new frame */
485
0
            frame = av_frame_alloc();
486
0
            if (unlikely(frame == NULL))
487
0
                break;
488
0
        }
489
1.72M
        else
490
1.72M
        {
491
            /* After draining, we need to reset decoder with a flush */
492
1.72M
            if( ret == AVERROR_EOF )
493
846k
                avcodec_flush_buffers( p_sys->p_context );
494
1.72M
            av_frame_free( &frame );
495
1.72M
        }
496
3.06M
    };
497
498
1.72M
    if (send_failed)
499
856k
    {
500
        /* Signal a discontinuity for the next output frame. */
501
856k
        p_sys->discontinuity = true;
502
856k
    }
503
504
1.72M
    return VLCDEC_SUCCESS;
505
506
0
end:
507
0
    b_error = true;
508
1.33M
drop:
509
    /* Signal a discontinuity for the next output frame. */
510
1.33M
    p_sys->discontinuity = true;
511
1.33M
    if( pp_block )
512
1.33M
    {
513
1.33M
        assert( *pp_block == p_block );
514
1.33M
        *pp_block = NULL;
515
1.33M
    }
516
1.33M
    if( p_block != NULL )
517
11.9k
        block_Release(p_block);
518
1.33M
    if( frame != NULL )
519
1.33M
        av_frame_free( &frame );
520
521
1.33M
    return (b_error) ? VLCDEC_ECRITICAL : VLCDEC_SUCCESS;
522
1.33M
}
523
524
static int DecodeAudio( decoder_t *p_dec, block_t *p_block )
525
3.06M
{
526
3.06M
    block_t **pp_block = p_block ? &p_block : NULL;
527
3.06M
    int i_ret;
528
3.06M
    do
529
3.06M
    {
530
3.06M
        i_ret = DecodeBlock( p_dec, pp_block );
531
3.06M
    }
532
3.06M
    while( i_ret == VLCDEC_SUCCESS && pp_block && *pp_block );
533
534
3.06M
    return i_ret;
535
3.06M
}
536
537
static block_t * ConvertAVFrame( decoder_t *p_dec, AVFrame *frame )
538
0
{
539
0
    decoder_sys_t *p_sys = p_dec->p_sys;
540
0
    AVCodecContext *ctx = p_sys->p_context;
541
0
    block_t *p_block;
542
543
    /* Interleave audio if required */
544
0
    if( av_sample_fmt_is_planar( ctx->sample_fmt ) )
545
0
    {
546
0
        p_block = block_Alloc(frame->linesize[0] * p_dec->fmt_out.audio.i_channels );
547
0
        if ( likely(p_block) )
548
0
        {
549
0
            const void *planes[p_dec->fmt_out.audio.i_channels];
550
0
            for (int i = 0; i < p_dec->fmt_out.audio.i_channels; i++)
551
0
                planes[i] = frame->extended_data[i];
552
553
0
            aout_Interleave(p_block->p_buffer, planes, frame->nb_samples,
554
0
                            p_dec->fmt_out.audio.i_channels, p_dec->fmt_out.audio.i_format);
555
0
            p_block->i_nb_samples = frame->nb_samples;
556
0
        }
557
0
        av_frame_free(&frame);
558
0
    }
559
0
    else
560
0
    {
561
0
        p_block = vlc_av_frame_Wrap(frame);
562
0
        frame = NULL;
563
0
    }
564
565
0
    if (p_sys->b_extract && p_block)
566
0
    {   /* TODO: do not drop channels... at least not here */
567
0
        block_t *p_buffer = block_Alloc( p_dec->fmt_out.audio.i_bytes_per_frame
568
0
                                         * p_block->i_nb_samples );
569
0
        if( likely(p_buffer) )
570
0
        {
571
0
            aout_ChannelExtract( p_buffer->p_buffer,
572
0
                                 p_dec->fmt_out.audio.i_channels,
573
0
                                 p_block->p_buffer, p_dec->fmt_out.audio.i_channels,
574
0
                                 p_block->i_nb_samples, p_sys->pi_extraction,
575
0
                                 p_dec->fmt_out.audio.i_bitspersample );
576
0
            p_buffer->i_nb_samples = p_block->i_nb_samples;
577
0
        }
578
0
        block_Release( p_block );
579
0
        p_block = p_buffer;
580
0
    }
581
582
0
    return p_block;
583
0
}
584
585
/*****************************************************************************
586
 *
587
 *****************************************************************************/
588
589
vlc_fourcc_t GetVlcAudioFormat( int fmt )
590
1.56M
{
591
1.56M
    static const vlc_fourcc_t fcc[] = {
592
1.56M
        [AV_SAMPLE_FMT_U8]    = VLC_CODEC_U8,
593
1.56M
        [AV_SAMPLE_FMT_S16]   = VLC_CODEC_S16N,
594
1.56M
        [AV_SAMPLE_FMT_S32]   = VLC_CODEC_S32N,
595
1.56M
        [AV_SAMPLE_FMT_FLT]   = VLC_CODEC_FL32,
596
1.56M
        [AV_SAMPLE_FMT_DBL]   = VLC_CODEC_FL64,
597
1.56M
        [AV_SAMPLE_FMT_U8P]   = VLC_CODEC_U8,
598
1.56M
        [AV_SAMPLE_FMT_S16P]  = VLC_CODEC_S16N,
599
1.56M
        [AV_SAMPLE_FMT_S32P]  = VLC_CODEC_S32N,
600
1.56M
        [AV_SAMPLE_FMT_FLTP]  = VLC_CODEC_FL32,
601
1.56M
        [AV_SAMPLE_FMT_DBLP]  = VLC_CODEC_FL64,
602
1.56M
    };
603
1.56M
    if( ARRAY_SIZE(fcc) > (unsigned)fmt )
604
1.54M
        return fcc[fmt];
605
21.7k
    return VLC_CODEC_S16N;
606
1.56M
}
607
608
static const uint64_t pi_channels_map[][2] =
609
{
610
    { AV_CH_FRONT_LEFT,        AOUT_CHAN_LEFT },
611
    { AV_CH_FRONT_RIGHT,       AOUT_CHAN_RIGHT },
612
    { AV_CH_FRONT_CENTER,      AOUT_CHAN_CENTER },
613
    { AV_CH_LOW_FREQUENCY,     AOUT_CHAN_LFE },
614
    { AV_CH_BACK_LEFT,         AOUT_CHAN_REARLEFT },
615
    { AV_CH_BACK_RIGHT,        AOUT_CHAN_REARRIGHT },
616
    { AV_CH_FRONT_LEFT_OF_CENTER, 0 },
617
    { AV_CH_FRONT_RIGHT_OF_CENTER, 0 },
618
    { AV_CH_BACK_CENTER,       AOUT_CHAN_REARCENTER },
619
    { AV_CH_SIDE_LEFT,         AOUT_CHAN_MIDDLELEFT },
620
    { AV_CH_SIDE_RIGHT,        AOUT_CHAN_MIDDLERIGHT },
621
    { AV_CH_TOP_CENTER,        0 },
622
    { AV_CH_TOP_FRONT_LEFT,    0 },
623
    { AV_CH_TOP_FRONT_CENTER,  0 },
624
    { AV_CH_TOP_FRONT_RIGHT,   0 },
625
    { AV_CH_TOP_BACK_LEFT,     0 },
626
    { AV_CH_TOP_BACK_CENTER,   0 },
627
    { AV_CH_TOP_BACK_RIGHT,    0 },
628
    { AV_CH_STEREO_LEFT,       0 },
629
    { AV_CH_STEREO_RIGHT,      0 },
630
    { 0, 0 },
631
};
632
633
static void SetupOutputFormat( decoder_t *p_dec, bool b_trust )
634
1.56M
{
635
1.56M
    decoder_sys_t *p_sys = p_dec->p_sys;
636
637
1.56M
    p_dec->fmt_out.i_codec = GetVlcAudioFormat( p_sys->p_context->sample_fmt );
638
1.56M
    p_dec->fmt_out.audio.channel_type = p_dec->fmt_in->audio.channel_type;
639
1.56M
    p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
640
1.56M
    p_dec->fmt_out.audio.i_rate = p_sys->p_context->sample_rate;
641
642
    /* */
643
1.56M
#if API_CHANNEL_LAYOUT_STRUCT
644
1.56M
    if( p_sys->i_previous_channels == p_sys->p_context->ch_layout.nb_channels &&
645
1.20M
        p_sys->i_previous_layout == p_sys->p_context->ch_layout.u.mask )
646
1.20M
        return;
647
368k
    if( b_trust )
648
147k
    {
649
147k
        p_sys->i_previous_channels = p_sys->p_context->ch_layout.nb_channels;
650
147k
        p_sys->i_previous_layout = p_sys->p_context->ch_layout.u.mask;
651
147k
    }
652
#else
653
    if( p_sys->i_previous_channels == p_sys->p_context->channels &&
654
        p_sys->i_previous_layout == p_sys->p_context->channel_layout )
655
        return;
656
    if( b_trust )
657
    {
658
        p_sys->i_previous_channels = p_sys->p_context->channels;
659
        p_sys->i_previous_layout = p_sys->p_context->channel_layout;
660
    }
661
#endif
662
663
368k
    int i_channels_src = 0;
664
368k
#if API_CHANNEL_LAYOUT_STRUCT
665
368k
    uint64_t channel_layout_mask = p_sys->p_context->ch_layout.u.mask;
666
368k
    int channel_count = p_sys->p_context->ch_layout.nb_channels;
667
#else
668
    uint64_t channel_layout_mask =
669
        p_sys->p_context->channel_layout ? p_sys->p_context->channel_layout :
670
        (uint64_t)av_get_default_channel_layout( p_sys->p_context->channels );
671
    int channel_count = p_sys->p_context->channels;
672
#endif
673
674
368k
    if( channel_layout_mask )
675
364k
    {
676
364k
        uint32_t* pi_order_src = calloc(channel_count,sizeof(uint32_t));
677
678
364k
        if( unlikely(pi_order_src == NULL) )
679
0
        {
680
0
            p_dec->fmt_out.audio.i_physical_channels = 0;
681
0
            p_dec->fmt_out.audio.i_channels = channel_count;
682
683
0
            aout_FormatPrepare(&p_dec->fmt_out.audio);
684
0
            p_sys->b_extract = false;
685
0
            return;
686
0
        }
687
688
364k
        assert(stdc_count_ones(channel_layout_mask) == (unsigned)channel_count);
689
690
2.07M
        for( unsigned i = 0; pi_channels_map[i][0]
691
2.06M
         && i_channels_src < channel_count; i++ )
692
1.70M
        {
693
1.70M
            if( channel_layout_mask & pi_channels_map[i][0] )
694
1.22M
                pi_order_src[i_channels_src++] = pi_channels_map[i][1];
695
1.70M
        }
696
697
364k
        if( i_channels_src != channel_count && b_trust )
698
364k
            msg_Err( p_dec, "Channel layout not understood" );
699
700
        /* Detect special dual mono case */
701
364k
        if( i_channels_src == 2 && pi_order_src[0] == AOUT_CHAN_CENTER
702
6.52k
         && pi_order_src[1] == AOUT_CHAN_CENTER )
703
0
        {
704
0
            p_dec->fmt_out.audio.i_chan_mode |= AOUT_CHANMODE_DUALMONO;
705
0
            pi_order_src[0] = AOUT_CHAN_LEFT;
706
0
            pi_order_src[1] = AOUT_CHAN_RIGHT;
707
0
        }
708
709
364k
        uint32_t i_layout_dst;
710
364k
        int      i_channels_dst;
711
364k
        p_sys->b_extract = aout_CheckChannelExtraction( p_sys->pi_extraction,
712
364k
                                                        &i_layout_dst, &i_channels_dst,
713
364k
                                                        NULL, pi_order_src, i_channels_src );
714
364k
        if( i_channels_dst != i_channels_src && b_trust )
715
364k
            msg_Warn( p_dec, "%d channels are dropped", i_channels_src - i_channels_dst );
716
717
        /* No reordering for Ambisonic order 1 channels encoded in AAC... */
718
364k
        if (p_dec->fmt_out.audio.channel_type == AUDIO_CHANNEL_TYPE_AMBISONICS
719
364k
            && p_dec->fmt_in->i_codec == VLC_CODEC_MP4A
720
0
            && i_channels_src == 4)
721
0
            p_sys->b_extract = false;
722
723
364k
        p_dec->fmt_out.audio.i_physical_channels = i_layout_dst;
724
364k
        free(pi_order_src);
725
364k
    }
726
3.77k
    else
727
3.77k
    {
728
3.77k
        msg_Warn( p_dec, "no channel layout found");
729
3.77k
        p_dec->fmt_out.audio.i_physical_channels = 0;
730
3.77k
        p_dec->fmt_out.audio.i_channels = channel_count;
731
3.77k
    }
732
733
368k
    aout_FormatPrepare( &p_dec->fmt_out.audio );
734
368k
}