audio.c 14.6 KB
Newer Older
1 2 3
/*****************************************************************************
 * audio.c: audio decoder using ffmpeg library
 *****************************************************************************
4
 * Copyright (C) 1999-2003 the VideoLAN team
5
 * $Id$
6 7
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8
 *          Gildas Bazin <gbazin@videolan.org>
9 10 11 12 13
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
14
 *
15 16 17 18 19 20 21
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
Antoine Cellerier's avatar
Antoine Cellerier committed
22
 * 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
#include <vlc_common.h>
Clément Stenac's avatar
Clément Stenac committed
33 34
#include <vlc_aout.h>
#include <vlc_codec.h>
35
#include <vlc_avcodec.h>
36

Gildas Bazin's avatar
 
Gildas Bazin committed
37
/* ffmpeg header */
38 39 40
#ifdef HAVE_LIBAVCODEC_AVCODEC_H
#   include <libavcodec/avcodec.h>
#elif defined(HAVE_FFMPEG_AVCODEC_H)
41
#   include <ffmpeg/avcodec.h>
Gildas Bazin's avatar
 
Gildas Bazin committed
42 43 44
#else
#   include <avcodec.h>
#endif
45

46
#include "avcodec.h"
47

48
static const unsigned int pi_channels_maps[9] =
49 50
{
    0,
51 52 53 54 55 56 57 58 59 60 61 62 63 64
    AOUT_CHAN_CENTER,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
        AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
        AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
        AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
        AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER |
        AOUT_CHAN_MIDDLELEFT | AOUT_CHAN_MIDDLERIGHT |
        AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE,
65
};
66 67

/*****************************************************************************
Gildas Bazin's avatar
 
Gildas Bazin committed
68
 * decoder_sys_t : decoder descriptor
69
 *****************************************************************************/
Gildas Bazin's avatar
 
Gildas Bazin committed
70 71
struct decoder_sys_t
{
72
    FFMPEG_COMMON_MEMBERS
Gildas Bazin's avatar
 
Gildas Bazin committed
73 74

    /* Temporary buffer for libavcodec */
75
    int     i_output_max;
Gildas Bazin's avatar
 
Gildas Bazin committed
76 77 78 79 80 81 82
    uint8_t *p_output;

    /*
     * Output properties
     */
    audio_sample_format_t aout_format;
    audio_date_t          end_date;
83 84 85 86 87 88

    /*
     *
     */
    uint8_t *p_samples;
    int     i_samples;
89 90 91

    /* */
    int     i_reject_count;
Gildas Bazin's avatar
 
Gildas Bazin committed
92
};
93

94 95
static void SetupOutputCodec( decoder_t *p_dec );

96
/*****************************************************************************
Gildas Bazin's avatar
 
Gildas Bazin committed
97
 * InitAudioDec: initialize audio decoder
98
 *****************************************************************************
Gildas Bazin's avatar
 
Gildas Bazin committed
99
 * The ffmpeg codec will be opened, some memory allocated.
100
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
101
int InitAudioDec( decoder_t *p_dec, AVCodecContext *p_context,
102
                      AVCodec *p_codec, int i_codec_id, const char *psz_namecodec )
103
{
Gildas Bazin's avatar
 
Gildas Bazin committed
104
    decoder_sys_t *p_sys;
105

Gildas Bazin's avatar
 
Gildas Bazin committed
106
    /* Allocate the memory needed to store the decoder's structure */
107
    if( ( p_dec->p_sys = p_sys = malloc(sizeof(*p_sys)) ) == NULL )
108
    {
109
        return VLC_ENOMEM;
Gildas Bazin's avatar
 
Gildas Bazin committed
110 111
    }

112 113 114 115
    p_sys->p_context = p_context;
    p_sys->p_codec = p_codec;
    p_sys->i_codec_id = i_codec_id;
    p_sys->psz_namecodec = psz_namecodec;
116
    p_sys->b_delayed_open = false;
Gildas Bazin's avatar
 
Gildas Bazin committed
117

118
    /* ***** Fill p_context with init values ***** */
Gildas Bazin's avatar
 
Gildas Bazin committed
119 120
    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;
121 122 123 124 125 126 127 128 129 130 131 132
    if( !p_dec->fmt_in.audio.i_physical_channels )
    {
        msg_Warn( p_dec, "Physical channel configuration not set : guessing" );
        p_dec->fmt_in.audio.i_original_channels =
            p_dec->fmt_in.audio.i_physical_channels =
                pi_channels_maps[p_sys->p_context->channels];
    }

    p_dec->fmt_out.audio.i_physical_channels =
        p_dec->fmt_out.audio.i_original_channels =
        p_dec->fmt_in.audio.i_physical_channels;

Gildas Bazin's avatar
 
Gildas Bazin committed
133 134
    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;
Alexis Ballier's avatar
Alexis Ballier committed
135
#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)
136
    p_sys->p_context->bits_per_sample = p_dec->fmt_in.audio.i_bitspersample;
Alexis Ballier's avatar
Alexis Ballier committed
137 138 139
#else
    p_sys->p_context->bits_per_coded_sample = p_dec->fmt_in.audio.i_bitspersample;
#endif
140

Laurent Aimar's avatar
Laurent Aimar committed
141
    if( p_dec->fmt_in.i_extra > 0 )
142
    {
Laurent Aimar's avatar
Laurent Aimar committed
143 144 145
        const uint8_t * const p_src = p_dec->fmt_in.p_extra;
        int i_offset;
        int i_size;
146 147

        if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'f', 'l', 'a', 'c' ) )
Laurent Aimar's avatar
Laurent Aimar committed
148
        {
149
            i_offset = 8;
Laurent Aimar's avatar
Laurent Aimar committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
            i_size = p_dec->fmt_in.i_extra - 8;
        }
        else if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'a', 'l', 'a', 'c' ) )
        {
            static const uint8_t p_pattern[] = { 0, 0, 0, 36, 'a', 'l', 'a', 'c' };
            /* Find alac atom XXX it is a bit ugly */
            for( i_offset = 0; i_offset < p_dec->fmt_in.i_extra - sizeof(p_pattern); i_offset++ )
            {
                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;
        }
        else
        {
            i_offset = 0;
            i_size = p_dec->fmt_in.i_extra;
        }
170

Laurent Aimar's avatar
Laurent Aimar committed
171
        if( i_size > 0 )
Rémi Duraffort's avatar
Rémi Duraffort committed
172
        {
Laurent Aimar's avatar
Laurent Aimar committed
173 174 175 176 177 178 179 180 181 182 183
            p_sys->p_context->extradata =
                malloc( i_size + FF_INPUT_BUFFER_PADDING_SIZE );
            if( p_sys->p_context->extradata )
            {
                uint8_t *p_dst = p_sys->p_context->extradata;

                p_sys->p_context->extradata_size = i_size;

                memcpy( &p_dst[0],            &p_src[i_offset], i_size );
                memset( &p_dst[i_size], 0, FF_INPUT_BUFFER_PADDING_SIZE );
            }
Rémi Duraffort's avatar
Rémi Duraffort committed
184
        }
185
    }
186
    else
Laurent Aimar's avatar
Laurent Aimar committed
187 188
    {
        p_sys->p_context->extradata_size = 0;
189
        p_sys->p_context->extradata = NULL;
Laurent Aimar's avatar
Laurent Aimar committed
190
    }
191

192
    /* ***** Open the codec ***** */
193 194 195 196 197
    int ret;
    vlc_avcodec_lock();
    ret = avcodec_open( p_sys->p_context, p_sys->p_codec );
    vlc_avcodec_unlock();
    if( ret < 0 )
198
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
199
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
200
        free( p_sys->p_context->extradata );
201
        free( p_sys );
Gildas Bazin's avatar
 
Gildas Bazin committed
202
        return VLC_EGENERIC;
203
    }
204 205

    msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );
206

207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224
    switch( i_codec_id )
    {
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 51, 16, 0 )
    case CODEC_ID_WAVPACK:
        p_sys->i_output_max = 8 * sizeof(int32_t) * 131072;
        break;
#endif
    case CODEC_ID_FLAC:
        p_sys->i_output_max = 8 * sizeof(int32_t) * 65535;
        break;
    default:
        p_sys->i_output_max = 0;
        break;
    }
    if( p_sys->i_output_max < AVCODEC_MAX_AUDIO_FRAME_SIZE )
        p_sys->i_output_max = AVCODEC_MAX_AUDIO_FRAME_SIZE;
    msg_Dbg( p_dec, "Using %d bytes output buffer", p_sys->i_output_max );
    p_sys->p_output = malloc( p_sys->i_output_max );
225 226
    p_sys->p_samples = NULL;
    p_sys->i_samples = 0;
227
    p_sys->i_reject_count = 0;
228

Laurent Aimar's avatar
Laurent Aimar committed
229
    aout_DateSet( &p_sys->end_date, 0 );
230 231
    if( p_dec->fmt_in.audio.i_rate )
        aout_DateInit( &p_sys->end_date, p_dec->fmt_in.audio.i_rate );
232

Gildas Bazin's avatar
 
Gildas Bazin committed
233 234
    /* Set output properties */
    p_dec->fmt_out.i_cat = AUDIO_ES;
235

236
    SetupOutputCodec( p_dec );
Gildas Bazin's avatar
 
Gildas Bazin committed
237

Gildas Bazin's avatar
 
Gildas Bazin committed
238
    return VLC_SUCCESS;
239 240
}

241 242 243 244
/*****************************************************************************
 * SplitBuffer: Needed because aout really doesn't like big audio chunk and
 * wma produces easily > 30000 samples...
 *****************************************************************************/
Clément Stenac's avatar
Clément Stenac committed
245
static aout_buffer_t *SplitBuffer( decoder_t *p_dec )
246 247 248 249 250
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    int i_samples = __MIN( p_sys->i_samples, 4096 );
    aout_buffer_t *p_buffer;

251 252
    if( i_samples == 0 ) return NULL;

253
    if( ( p_buffer = decoder_NewAudioBuffer( p_dec, i_samples ) ) == NULL )
254 255 256
        return NULL;

    p_buffer->start_date = aout_DateGet( &p_sys->end_date );
257
    p_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
258 259 260 261 262 263 264 265 266

    memcpy( p_buffer->p_buffer, p_sys->p_samples, p_buffer->i_nb_bytes );

    p_sys->p_samples += p_buffer->i_nb_bytes;
    p_sys->i_samples -= i_samples;

    return p_buffer;
}

267
/*****************************************************************************
Gildas Bazin's avatar
 
Gildas Bazin committed
268
 * DecodeAudio: Called to decode one frame
269
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
270
aout_buffer_t * DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
271
{
Gildas Bazin's avatar
 
Gildas Bazin committed
272
    decoder_sys_t *p_sys = p_dec->p_sys;
273
    int i_used, i_output;
Gildas Bazin's avatar
 
Gildas Bazin committed
274 275 276 277
    aout_buffer_t *p_buffer;
    block_t *p_block;

    if( !pp_block || !*pp_block ) return NULL;
278

Gildas Bazin's avatar
 
Gildas Bazin committed
279
    p_block = *pp_block;
280

Laurent Aimar's avatar
Laurent Aimar committed
281 282 283 284
    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
    {
        block_Release( p_block );
        avcodec_flush_buffers( p_sys->p_context );
285 286
        p_sys->i_samples = 0;
        aout_DateSet( &p_sys->end_date, 0 );
287 288 289

        if( p_sys->i_codec_id == CODEC_ID_MP2 || p_sys->i_codec_id == CODEC_ID_MP3 )
            p_sys->i_reject_count = 3;
Laurent Aimar's avatar
Laurent Aimar committed
290 291 292 293
        return NULL;
    }

    if( p_sys->i_samples > 0 )
294 295 296
    {
        /* More data */
        p_buffer = SplitBuffer( p_dec );
297
        if( !p_buffer ) block_Release( p_block );
298 299 300
        return p_buffer;
    }

Gildas Bazin's avatar
 
Gildas Bazin committed
301 302 303 304
    if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
    {
        /* We've just started the stream, wait for the first PTS. */
        block_Release( p_block );
Gildas Bazin's avatar
 
Gildas Bazin committed
305
        return NULL;
Gildas Bazin's avatar
 
Gildas Bazin committed
306
    }
307

Laurent Aimar's avatar
Laurent Aimar committed
308
    if( p_block->i_buffer <= 0 )
309
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
310 311 312
        block_Release( p_block );
        return NULL;
    }
313 314
    i_output = __MAX( p_block->i_buffer, p_sys->i_output_max );
    if( i_output < p_sys->i_output_max )
315 316 317 318 319
    {
        /* Grow output buffer if necessary (eg. for PCM data) */
        p_sys->p_output = realloc(p_sys->p_output, p_block->i_buffer);
    }

Laurent Aimar's avatar
Laurent Aimar committed
320 321 322 323 324 325
    *pp_block = p_block = block_Realloc( p_block, 0, p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE );
    if( !p_block )
        return NULL;
    p_block->i_buffer -= FF_INPUT_BUFFER_PADDING_SIZE;
    memset( &p_block->p_buffer[p_block->i_buffer], 0, FF_INPUT_BUFFER_PADDING_SIZE );

326
#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(0<<8)+0)
Laurent Aimar's avatar
Laurent Aimar committed
327
    i_used = avcodec_decode_audio2( p_sys->p_context,
Gildas Bazin's avatar
 
Gildas Bazin committed
328 329
                                   (int16_t*)p_sys->p_output, &i_output,
                                   p_block->p_buffer, p_block->i_buffer );
330 331 332 333 334
#else
    i_used = avcodec_decode_audio( p_sys->p_context,
                                   (int16_t*)p_sys->p_output, &i_output,
                                   p_block->p_buffer, p_block->i_buffer );
#endif
Gildas Bazin's avatar
 
Gildas Bazin committed
335

336
    if( i_used < 0 || i_output < 0 )
Gildas Bazin's avatar
 
Gildas Bazin committed
337
    {
Gildas Bazin's avatar
 
Gildas Bazin committed
338
        if( i_used < 0 )
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
339
            msg_Warn( p_dec, "cannot decode one frame (%zu bytes)",
Gildas Bazin's avatar
 
Gildas Bazin committed
340 341 342 343
                      p_block->i_buffer );

        block_Release( p_block );
        return NULL;
344
    }
345
    else if( (size_t)i_used > p_block->i_buffer )
346 347 348
    {
        i_used = p_block->i_buffer;
    }
349

Gildas Bazin's avatar
 
Gildas Bazin committed
350 351 352
    p_block->i_buffer -= i_used;
    p_block->p_buffer += i_used;

353
    if( p_sys->p_context->channels <= 0 || p_sys->p_context->channels > 8 ||
354
        p_sys->p_context->sample_rate <= 0 )
Gildas Bazin's avatar
 
Gildas Bazin committed
355
    {
356 357
        msg_Warn( p_dec, "invalid audio properties channels count %d, sample rate %d",
                  p_sys->p_context->channels, p_sys->p_context->sample_rate );
Gildas Bazin's avatar
 
Gildas Bazin committed
358 359 360 361
        block_Release( p_block );
        return NULL;
    }

362
    if( p_dec->fmt_out.audio.i_rate != (unsigned int)p_sys->p_context->sample_rate )
Gildas Bazin's avatar
 
Gildas Bazin committed
363 364 365 366 367 368
    {
        aout_DateInit( &p_sys->end_date, p_sys->p_context->sample_rate );
        aout_DateSet( &p_sys->end_date, p_block->i_pts );
    }

    /* **** Set audio output parameters **** */
369
    SetupOutputCodec( p_dec );
Gildas Bazin's avatar
 
Gildas Bazin committed
370 371 372 373 374 375 376 377 378 379 380
    p_dec->fmt_out.audio.i_rate     = p_sys->p_context->sample_rate;
    p_dec->fmt_out.audio.i_channels = p_sys->p_context->channels;
    p_dec->fmt_out.audio.i_original_channels =
        p_dec->fmt_out.audio.i_physical_channels =
            pi_channels_maps[p_sys->p_context->channels];

    if( p_block->i_pts != 0 &&
        p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
    {
        aout_DateSet( &p_sys->end_date, p_block->i_pts );
    }
381
    p_block->i_pts = 0;
Gildas Bazin's avatar
 
Gildas Bazin committed
382 383

    /* **** Now we can output these samples **** */
384
    p_sys->i_samples = i_output / (p_dec->fmt_out.audio.i_bitspersample / 8) / p_sys->p_context->channels;
385
    p_sys->p_samples = p_sys->p_output;
Gildas Bazin's avatar
 
Gildas Bazin committed
386

387 388 389 390 391 392 393
    /* Silent unwanted samples */
    if( p_sys->i_reject_count > 0 )
    {
        memset( p_sys->p_output, 0, i_output );
        p_sys->i_reject_count--;
    }

394
    p_buffer = SplitBuffer( p_dec );
395
    if( !p_buffer ) block_Release( p_block );
Gildas Bazin's avatar
 
Gildas Bazin committed
396
    return p_buffer;
397 398 399
}

/*****************************************************************************
Gildas Bazin's avatar
 
Gildas Bazin committed
400
 * EndAudioDec: audio decoder destruction
401
 *****************************************************************************/
Rémi Denis-Courmont's avatar
Rémi Denis-Courmont committed
402
void EndAudioDec( decoder_t *p_dec )
403
{
Gildas Bazin's avatar
 
Gildas Bazin committed
404 405
    decoder_sys_t *p_sys = p_dec->p_sys;

406
    free( p_sys->p_output );
407
}
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446

/*****************************************************************************
 *
 *****************************************************************************/
static void SetupOutputCodec( decoder_t *p_dec )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

#if defined(AV_VERSION_INT) && LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 51, 65, 0 )
    switch( p_sys->p_context->sample_fmt )
    {
    case SAMPLE_FMT_U8:
        p_dec->fmt_out.i_codec = VLC_FOURCC('u','8',' ',' ');
        p_dec->fmt_out.audio.i_bitspersample = 8;
        break;
    case SAMPLE_FMT_S32:
        p_dec->fmt_out.i_codec = AOUT_FMT_S32_NE;
        p_dec->fmt_out.audio.i_bitspersample = 32;
        break;
    case SAMPLE_FMT_FLT:
        p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
        p_dec->fmt_out.audio.i_bitspersample = 32;
        break;
    case SAMPLE_FMT_DBL:
        p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','6','4');
        p_dec->fmt_out.audio.i_bitspersample = 64;
        break;

    case SAMPLE_FMT_S16:
    default:
        p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
        p_dec->fmt_out.audio.i_bitspersample = 16;
        break;
    }
#else
    p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
    p_dec->fmt_out.audio.i_bitspersample = 16;
#endif
}