audio.c 16.7 KB
Newer Older
1
/*****************************************************************************
2
 * audio.c: audio decoder using libavcodec library
3
 *****************************************************************************
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
4
 * Copyright (C) 1999-2003 VLC authors and VideoLAN
5
 * $Id$
6 7
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
gbazin's avatar
gbazin committed
8
 *          Gildas Bazin <gbazin@videolan.org>
9
 *
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
10 11 12
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
13
 * (at your option) any later version.
14
 *
15 16
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
17 18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
19
 *
Jean-Baptiste Kempf's avatar
LGPL  
Jean-Baptiste Kempf committed
20 21 22
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 24 25 26 27
 *****************************************************************************/

/*****************************************************************************
 * Preamble
 *****************************************************************************/
28 29 30 31
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

32 33
#include <assert.h>

34
#include <vlc_common.h>
zorglub's avatar
zorglub committed
35 36
#include <vlc_aout.h>
#include <vlc_codec.h>
37
#include <vlc_avcodec.h>
38

39 40
#include "avcodec.h"

41
#include <libavcodec/avcodec.h>
42
#include <libavutil/mem.h>
43

44
#include <libavutil/channel_layout.h>
45

46 47

/*****************************************************************************
gbazin's avatar
 
gbazin committed
48
 * decoder_sys_t : decoder descriptor
49
 *****************************************************************************/
gbazin's avatar
 
gbazin committed
50 51
struct decoder_sys_t
{
52
    AVCODEC_COMMON_MEMBERS
gbazin's avatar
 
gbazin committed
53 54 55 56 57

    /*
     * Output properties
     */
    audio_sample_format_t aout_format;
58
    date_t                end_date;
59

60 61
    /* */
    int     i_reject_count;
62 63 64 65 66

    /* */
    bool    b_extract;
    int     pi_extraction[AOUT_CHAN_MAX];
    int     i_previous_channels;
67
    uint64_t i_previous_layout;
gbazin's avatar
 
gbazin committed
68
};
69

70 71
#define BLOCK_FLAG_PRIVATE_REALLOCATED (1 << BLOCK_FLAG_PRIVATE_SHIFT)

72
static void SetupOutputFormat( decoder_t *p_dec, bool b_trust );
73
static block_t *DecodeAudio( decoder_t *, block_t ** );
74

75
static void InitDecoderConfig( decoder_t *p_dec, AVCodecContext *p_context )
76
{
Laurent Aimar's avatar
Laurent Aimar committed
77
    if( p_dec->fmt_in.i_extra > 0 )
78
    {
Laurent Aimar's avatar
Laurent Aimar committed
79
        const uint8_t * const p_src = p_dec->fmt_in.p_extra;
80

81 82 83 84
        int i_offset = 0;
        int i_size = p_dec->fmt_in.i_extra;

        if( p_dec->fmt_in.i_codec == VLC_CODEC_ALAC )
Laurent Aimar's avatar
Laurent Aimar committed
85 86 87
        {
            static const uint8_t p_pattern[] = { 0, 0, 0, 36, 'a', 'l', 'a', 'c' };
            /* Find alac atom XXX it is a bit ugly */
88
            for( i_offset = 0; i_offset < i_size - (int)sizeof(p_pattern); i_offset++ )
Laurent Aimar's avatar
Laurent Aimar committed
89 90 91 92 93 94 95 96
            {
                if( !memcmp( &p_src[i_offset], p_pattern, sizeof(p_pattern) ) )
                    break;
            }
            i_size = __MIN( p_dec->fmt_in.i_extra - i_offset, 36 );
            if( i_size < 36 )
                i_size = 0;
        }
97

Laurent Aimar's avatar
Laurent Aimar committed
98
        if( i_size > 0 )
ivoire's avatar
ivoire committed
99
        {
100
            p_context->extradata =
101
                av_malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
102
            if( p_context->extradata )
Laurent Aimar's avatar
Laurent Aimar committed
103
            {
104
                uint8_t *p_dst = p_context->extradata;
Laurent Aimar's avatar
Laurent Aimar committed
105

106
                p_context->extradata_size = i_size;
Laurent Aimar's avatar
Laurent Aimar committed
107 108 109 110

                memcpy( &p_dst[0],            &p_src[i_offset], i_size );
                memset( &p_dst[i_size], 0, FF_INPUT_BUFFER_PADDING_SIZE );
            }
ivoire's avatar
ivoire committed
111
        }
112
    }
113
    else
Laurent Aimar's avatar
Laurent Aimar committed
114
    {
115 116 117 118 119
        p_context->extradata_size = 0;
        p_context->extradata = NULL;
    }
}

120 121 122 123 124 125
static int OpenAudioCodec( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    if( p_sys->p_context->extradata_size <= 0 )
    {
126 127
        if( p_sys->p_codec->id == AV_CODEC_ID_VORBIS ||
            ( p_sys->p_codec->id == AV_CODEC_ID_AAC &&
128 129 130
              !p_dec->fmt_in.b_packetized ) )
        {
            msg_Warn( p_dec, "waiting for extra data for codec %s",
131
                      p_sys->p_codec->name );
132 133 134 135 136 137 138 139 140 141 142
            return 1;
        }
    }

    p_sys->p_context->sample_rate = p_dec->fmt_in.audio.i_rate;
    p_sys->p_context->channels = p_dec->fmt_in.audio.i_channels;
    p_sys->p_context->block_align = p_dec->fmt_in.audio.i_blockalign;
    p_sys->p_context->bit_rate = p_dec->fmt_in.i_bitrate;
    p_sys->p_context->bits_per_coded_sample =
                                           p_dec->fmt_in.audio.i_bitspersample;

143
    if( p_sys->p_codec->id == AV_CODEC_ID_ADPCM_G726 &&
144 145 146 147 148 149 150 151
        p_sys->p_context->bit_rate > 0 &&
        p_sys->p_context->sample_rate >  0)
        p_sys->p_context->bits_per_coded_sample = p_sys->p_context->bit_rate
                                               / p_sys->p_context->sample_rate;

    return ffmpeg_OpenCodec( p_dec );
}

152 153 154
/**
 * Allocates decoded audio buffer for libavcodec to use.
 */
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
typedef struct
{
    block_t self;
    AVFrame *frame;
} vlc_av_frame_t;

static void vlc_av_frame_Release(block_t *block)
{
    vlc_av_frame_t *b = (void *)block;

    av_frame_free(&b->frame);
    free(b);
}

static block_t *vlc_av_frame_Wrap(AVFrame *frame)
{
    for (unsigned i = 1; i < AV_NUM_DATA_POINTERS; i++)
        assert(frame->linesize[i] == 0); /* only packed frame supported */

    if (av_frame_make_writable(frame)) /* TODO: read-only block_t */
        return NULL;

    vlc_av_frame_t *b = malloc(sizeof (*b));
    if (unlikely(b == NULL))
        return NULL;

    block_t *block = &b->self;

    block_Init(block, frame->extended_data[0], frame->linesize[0]);
    block->i_nb_samples = frame->nb_samples;
    block->pf_release = vlc_av_frame_Release;
    b->frame = frame;
    return block;
}
189

190 191 192
/*****************************************************************************
 * InitAudioDec: initialize audio decoder
 *****************************************************************************
193
 * The avcodec codec will be opened, some memory allocated.
194 195
 *****************************************************************************/
int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
196
                  const AVCodec *p_codec )
197 198 199 200 201 202 203
{
    decoder_sys_t *p_sys;

    /* Allocate the memory needed to store the decoder's structure */
    if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
    {
        return VLC_ENOMEM;
Laurent Aimar's avatar
Laurent Aimar committed
204
    }
205

206
    p_context->refcounted_frames = true;
207 208
    p_sys->p_context = p_context;
    p_sys->p_codec = p_codec;
209
    p_sys->b_delayed_open = true;
210 211 212 213

    // Initialize decoder extradata
    InitDecoderConfig( p_dec, p_context);

214
    /* ***** Open the codec ***** */
215
    if( OpenAudioCodec( p_dec ) < 0 )
216
    {
217
        free( p_sys );
gbazin's avatar
 
gbazin committed
218
        return VLC_EGENERIC;
219
    }
220

221
    p_sys->i_reject_count = 0;
222 223 224
    p_sys->b_extract = false;
    p_sys->i_previous_channels = 0;
    p_sys->i_previous_layout = 0;
225

226
    /* */
227
    p_dec->fmt_out.i_cat = AUDIO_ES;
ivoire's avatar
ivoire committed
228
    /* Try to set as much information as possible but do not trust it */
229
    SetupOutputFormat( p_dec, false );
230

231
    date_Set( &p_sys->end_date, VLC_TS_INVALID );
232 233 234 235
    if( p_dec->fmt_out.audio.i_rate )
        date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
    else if( p_dec->fmt_in.audio.i_rate )
        date_Init( &p_sys->end_date, p_dec->fmt_in.audio.i_rate, 1 );
gbazin's avatar
 
gbazin committed
236

237
    p_dec->pf_decode_audio = DecodeAudio;
gbazin's avatar
 
gbazin committed
238
    return VLC_SUCCESS;
239 240 241
}

/*****************************************************************************
gbazin's avatar
 
gbazin committed
242
 * DecodeAudio: Called to decode one frame
243
 *****************************************************************************/
244
static block_t *DecodeAudio( decoder_t *p_dec, block_t **pp_block )
245
{
gbazin's avatar
 
gbazin committed
246
    decoder_sys_t *p_sys = p_dec->p_sys;
247
    AVCodecContext *ctx = p_sys->p_context;
Thomas Guillem's avatar
Thomas Guillem committed
248
    AVFrame *frame = NULL;
gbazin's avatar
 
gbazin committed
249

250 251
    if( !pp_block || !*pp_block )
        return NULL;
252

253
    block_t *p_block = *pp_block;
254

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
255
    if( !ctx->extradata_size && p_dec->fmt_in.i_extra && p_sys->b_delayed_open)
256
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
257
        InitDecoderConfig( p_dec, ctx );
258
        OpenAudioCodec( p_dec );
259
    }
260

261
    if( p_sys->b_delayed_open )
262
        goto end;
263

264
    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
Laurent Aimar's avatar
Laurent Aimar committed
265
    {
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
266
        avcodec_flush_buffers( ctx );
267
        date_Set( &p_sys->end_date, VLC_TS_INVALID );
268

269 270
        if( ctx->codec_id == AV_CODEC_ID_MP2 ||
            ctx->codec_id == AV_CODEC_ID_MP3 )
271
            p_sys->i_reject_count = 3;
272 273

        goto end;
Laurent Aimar's avatar
Laurent Aimar committed
274 275
    }

276
    /* We've just started the stream, wait for the first PTS. */
277
    if( !date_Get( &p_sys->end_date ) && p_block->i_pts <= VLC_TS_INVALID )
278
        goto end;
279

Laurent Aimar's avatar
Laurent Aimar committed
280
    if( p_block->i_buffer <= 0 )
281
        goto end;
282

283 284
    if( (p_block->i_flags & BLOCK_FLAG_PRIVATE_REALLOCATED) == 0 )
    {
285
        p_block = block_Realloc( p_block, 0, p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE );
286 287
        if( !p_block )
            return NULL;
288
        *pp_block = p_block;
289 290 291 292 293
        p_block->i_buffer -= FF_INPUT_BUFFER_PADDING_SIZE;
        memset( &p_block->p_buffer[p_block->i_buffer], 0, FF_INPUT_BUFFER_PADDING_SIZE );

        p_block->i_flags |= BLOCK_FLAG_PRIVATE_REALLOCATED;
    }
Laurent Aimar's avatar
Laurent Aimar committed
294

Thomas Guillem's avatar
Thomas Guillem committed
295
    frame = av_frame_alloc();
296 297
    if (unlikely(frame == NULL))
        goto end;
298 299

    for( int got_frame = 0; !got_frame; )
300
    {
301 302
        if( p_block->i_buffer == 0 )
            goto end;
303

304
        AVPacket pkt;
305 306 307
        av_init_packet( &pkt );
        pkt.data = p_block->p_buffer;
        pkt.size = p_block->i_buffer;
gbazin's avatar
 
gbazin committed
308

309
        int used = avcodec_decode_audio4( ctx, frame, &got_frame, &pkt );
310
        if( used < 0 )
311
        {
312 313
            msg_Warn( p_dec, "cannot decode one frame (%zu bytes)",
                      p_block->i_buffer );
314
            goto end;
315
        }
316

317
        assert( p_block->i_buffer >= (unsigned)used );
318
        if( (unsigned)used > p_block->i_buffer )
319 320
            used = p_block->i_buffer;

321 322 323
        p_block->p_buffer += used;
        p_block->i_buffer -= used;
    }
gbazin's avatar
 
gbazin committed
324

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
325
    if( ctx->channels <= 0 || ctx->channels > 8 || ctx->sample_rate <= 0 )
gbazin's avatar
 
gbazin committed
326
    {
327
        msg_Warn( p_dec, "invalid audio properties channels count %d, sample rate %d",
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
328
                  ctx->channels, ctx->sample_rate );
329
        goto end;
gbazin's avatar
 
gbazin committed
330 331
    }

Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
332 333
    if( p_dec->fmt_out.audio.i_rate != (unsigned int)ctx->sample_rate )
        date_Init( &p_sys->end_date, ctx->sample_rate, 1 );
gbazin's avatar
 
gbazin committed
334

335
    if( p_block->i_pts > date_Get( &p_sys->end_date ) )
gbazin's avatar
 
gbazin committed
336
    {
337
        date_Set( &p_sys->end_date, p_block->i_pts );
gbazin's avatar
 
gbazin committed
338 339
    }

340 341 342
    if( p_block->i_buffer == 0 )
    {   /* Done with this buffer */
        block_Release( p_block );
343
        p_block = NULL;
344 345
        *pp_block = NULL;
    }
346

347
    /* NOTE WELL: Beyond this point, p_block refers to the DECODED block! */
348
    SetupOutputFormat( p_dec, true );
349 350
    if( decoder_UpdateAudioFormat( p_dec ) )
        goto drop;
gbazin's avatar
 
gbazin committed
351

352 353
    /* Interleave audio if required */
    if( av_sample_fmt_is_planar( ctx->sample_fmt ) )
354
    {
355 356 357
        p_block = block_Alloc(frame->linesize[0] * ctx->channels);
        if (unlikely(p_block == NULL))
            goto drop;
358

359 360 361
        const void *planes[ctx->channels];
        for (int i = 0; i < ctx->channels; i++)
            planes[i] = frame->extended_data[i];
362

363 364 365 366 367 368 369 370 371 372
        aout_Interleave(p_block->p_buffer, planes, frame->nb_samples,
                        ctx->channels, p_dec->fmt_out.audio.i_format);
        p_block->i_nb_samples = frame->nb_samples;
        av_frame_free(&frame);
    }
    else
    {
        p_block = vlc_av_frame_Wrap(frame);
        if (unlikely(p_block == NULL))
            goto drop;
ssbssa's avatar
ssbssa committed
373
        frame = NULL;
374
    }
375 376

    if (p_sys->b_extract)
377
    {   /* TODO: do not drop channels... at least not here */
378
        block_t *p_buffer = block_Alloc( p_dec->fmt_out.audio.i_bytes_per_frame
379
                                         * p_block->i_nb_samples );
380
        if( unlikely(p_buffer == NULL) )
381
            goto drop;
382
        aout_ChannelExtract( p_buffer->p_buffer,
383
                             p_dec->fmt_out.audio.i_channels,
384
                             p_block->p_buffer, ctx->channels,
385
                             p_block->i_nb_samples, p_sys->pi_extraction,
386
                             p_dec->fmt_out.audio.i_bitspersample );
387
        p_buffer->i_nb_samples = p_block->i_nb_samples;
388
        block_Release( p_block );
389 390
        p_block = p_buffer;
    }
391

392 393 394 395 396 397 398
    /* Silent unwanted samples */
    if( p_sys->i_reject_count > 0 )
    {
        memset( p_block->p_buffer, 0, p_block->i_buffer );
        p_sys->i_reject_count--;
    }

399
    p_block->i_buffer = p_block->i_nb_samples
400 401
                        * p_dec->fmt_out.audio.i_bytes_per_frame;
    p_block->i_pts = date_Get( &p_sys->end_date );
402 403
    p_block->i_length = date_Increment( &p_sys->end_date,
                                      p_block->i_nb_samples ) - p_block->i_pts;
404
    return p_block;
405 406

end:
407
    *pp_block = NULL;
408
drop:
ssbssa's avatar
ssbssa committed
409
    av_frame_free(&frame);
410 411
    if( p_block != NULL )
        block_Release(p_block);
412
    return NULL;
413 414
}

415 416 417
/*****************************************************************************
 *
 *****************************************************************************/
Laurent Aimar's avatar
Laurent Aimar committed
418

419
vlc_fourcc_t GetVlcAudioFormat( int fmt )
420
{
421
    static const vlc_fourcc_t fcc[] = {
422 423 424 425 426 427 428 429 430 431
        [AV_SAMPLE_FMT_U8]    = VLC_CODEC_U8,
        [AV_SAMPLE_FMT_S16]   = VLC_CODEC_S16N,
        [AV_SAMPLE_FMT_S32]   = VLC_CODEC_S32N,
        [AV_SAMPLE_FMT_FLT]   = VLC_CODEC_FL32,
        [AV_SAMPLE_FMT_DBL]   = VLC_CODEC_FL64,
        [AV_SAMPLE_FMT_U8P]   = VLC_CODEC_U8,
        [AV_SAMPLE_FMT_S16P]  = VLC_CODEC_S16N,
        [AV_SAMPLE_FMT_S32P]  = VLC_CODEC_S32N,
        [AV_SAMPLE_FMT_FLTP]  = VLC_CODEC_FL32,
        [AV_SAMPLE_FMT_DBLP]  = VLC_CODEC_FL64,
432
    };
433
    if( (sizeof(fcc) / sizeof(fcc[0])) > (unsigned)fmt )
434 435
        return fcc[fmt];
    return VLC_CODEC_S16N;
436 437
}

438 439
static const uint64_t pi_channels_map[][2] =
{
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459
    { AV_CH_FRONT_LEFT,        AOUT_CHAN_LEFT },
    { AV_CH_FRONT_RIGHT,       AOUT_CHAN_RIGHT },
    { AV_CH_FRONT_CENTER,      AOUT_CHAN_CENTER },
    { AV_CH_LOW_FREQUENCY,     AOUT_CHAN_LFE },
    { AV_CH_BACK_LEFT,         AOUT_CHAN_REARLEFT },
    { AV_CH_BACK_RIGHT,        AOUT_CHAN_REARRIGHT },
    { AV_CH_FRONT_LEFT_OF_CENTER, 0 },
    { AV_CH_FRONT_RIGHT_OF_CENTER, 0 },
    { AV_CH_BACK_CENTER,       AOUT_CHAN_REARCENTER },
    { AV_CH_SIDE_LEFT,         AOUT_CHAN_MIDDLELEFT },
    { AV_CH_SIDE_RIGHT,        AOUT_CHAN_MIDDLERIGHT },
    { AV_CH_TOP_CENTER,        0 },
    { AV_CH_TOP_FRONT_LEFT,    0 },
    { AV_CH_TOP_FRONT_CENTER,  0 },
    { AV_CH_TOP_FRONT_RIGHT,   0 },
    { AV_CH_TOP_BACK_LEFT,     0 },
    { AV_CH_TOP_BACK_CENTER,   0 },
    { AV_CH_TOP_BACK_RIGHT,    0 },
    { AV_CH_STEREO_LEFT,       0 },
    { AV_CH_STEREO_RIGHT,      0 },
460 461
};

462
static void SetupOutputFormat( decoder_t *p_dec, bool b_trust )
463 464 465
{
    decoder_sys_t *p_sys = p_dec->p_sys;

466 467
    p_dec->fmt_out.i_codec = GetVlcAudioFormat( p_sys->p_context->sample_fmt );
    p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
468
    p_dec->fmt_out.audio.i_rate = p_sys->p_context->sample_rate;
469 470

    /* */
471 472 473
    if( p_sys->i_previous_channels == p_sys->p_context->channels &&
        p_sys->i_previous_layout == p_sys->p_context->channel_layout )
        return;
474 475 476 477 478
    if( b_trust )
    {
        p_sys->i_previous_channels = p_sys->p_context->channels;
        p_sys->i_previous_layout = p_sys->p_context->channel_layout;
    }
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497

    /* Specified order
     * FIXME should we use fmt_in.audio.i_physical_channels or not ?
     */
    const unsigned i_order_max = 8 * sizeof(p_sys->p_context->channel_layout);
    uint32_t pi_order_src[i_order_max];
    int i_channels_src = 0;

    if( p_sys->p_context->channel_layout )
    {
        for( unsigned i = 0; i < sizeof(pi_channels_map)/sizeof(*pi_channels_map); i++ )
        {
            if( p_sys->p_context->channel_layout & pi_channels_map[i][0] )
                pi_order_src[i_channels_src++] = pi_channels_map[i][1];
        }
    }
    else
    {
        /* Create default order  */
498 499
        if( b_trust )
            msg_Warn( p_dec, "Physical channel configuration not set : guessing" );
500 501 502 503 504 505
        for( unsigned int i = 0; i < __MIN( i_order_max, (unsigned)p_sys->p_context->channels ); i++ )
        {
            if( i < sizeof(pi_channels_map)/sizeof(*pi_channels_map) )
                pi_order_src[i_channels_src++] = pi_channels_map[i][1];
        }
    }
506
    if( i_channels_src != p_sys->p_context->channels && b_trust )
507 508 509 510 511 512 513
        msg_Err( p_dec, "Channel layout not understood" );

    uint32_t i_layout_dst;
    int      i_channels_dst;
    p_sys->b_extract = aout_CheckChannelExtraction( p_sys->pi_extraction,
                                                    &i_layout_dst, &i_channels_dst,
                                                    NULL, pi_order_src, i_channels_src );
514
    if( i_channels_dst != i_channels_src && b_trust )
515 516 517 518
        msg_Warn( p_dec, "%d channels are dropped", i_channels_src - i_channels_dst );

    p_dec->fmt_out.audio.i_physical_channels =
    p_dec->fmt_out.audio.i_original_channels = i_layout_dst;
519
    aout_FormatPrepare( &p_dec->fmt_out.audio );
520
}
521