~ubuntu-branches/ubuntu/maverick/vlc/maverick

« back to all changes in this revision

Viewing changes to modules/codec/ffmpeg/audio.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-09-17 21:56:14 UTC
  • mfrom: (1.1.17 upstream)
  • Revision ID: james.westby@ubuntu.com-20080917215614-tj0vx8xzd57e52t8
Tags: 0.9.2-1ubuntu1
* New Upstream Release, exception granted by
    - dktrkranz, norsetto, Hobbsee (via irc). LP: #270404

Changes done in ubuntu:

* add libxul-dev to build-depends
* make sure that vlc is build against libxul in configure. This doesn't
  change anything in the package, but makes it more robust if building
  in an 'unclean' chroot or when modifying the package.
* debian/control: make Vcs-* fields point to the motumedia branch
* add libx264-dev and libass-dev to build-depends
  LP: #210354, #199870
* actually enable libass support by passing --enable-libass to configure
* enable libdca: add libdca-dev to build depends and --enable-libdca
* install the x264 plugin.

Changes already in the pkg-multimedia branch in debian:

* don't install usr/share/vlc/mozilla in debian/mozilla-plugin-vlc.install  
* new upstream .desktop file now registers flash video mimetype LP: #261567
* add Xb-Npp-Applications to mozilla-plugin-vlc
* remove duplicate entries in debian/vlc-nox.install

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 * audio.c: audio decoder using ffmpeg library
3
 
 *****************************************************************************
4
 
 * Copyright (C) 1999-2003 the VideoLAN team
5
 
 * $Id: e9bbbf4f02c1ed03a675a01a454e20da950a1d2c $
6
 
 *
7
 
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8
 
 *          Gildas Bazin <gbazin@videolan.org>
9
 
 *
10
 
 * This program is free software; you can redistribute it and/or modify
11
 
 * it under the terms of the GNU General Public License as published by
12
 
 * the Free Software Foundation; either version 2 of the License, or
13
 
 * (at your option) any later version.
14
 
 *
15
 
 * This program is distributed in the hope that it will be useful,
16
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
 * GNU General Public License for more details.
19
 
 *
20
 
 * You should have received a copy of the GNU General Public License
21
 
 * along with this program; if not, write to the Free Software
22
 
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23
 
 *****************************************************************************/
24
 
 
25
 
/*****************************************************************************
26
 
 * Preamble
27
 
 *****************************************************************************/
28
 
#include <vlc/vlc.h>
29
 
#include <vlc/decoder.h>
30
 
 
31
 
/* ffmpeg header */
32
 
#ifdef HAVE_LIBAVCODEC_AVCODEC_H
33
 
#   include <libavcodec/avcodec.h>
34
 
#elif defined(HAVE_FFMPEG_AVCODEC_H)
35
 
#   include <ffmpeg/avcodec.h>
36
 
#else
37
 
#   include <avcodec.h>
38
 
#endif
39
 
 
40
 
#include "ffmpeg.h"
41
 
 
42
 
static unsigned int pi_channels_maps[7] =
43
 
{
44
 
    0,
45
 
    AOUT_CHAN_CENTER,   AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
46
 
    AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
47
 
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
48
 
     | AOUT_CHAN_REARRIGHT,
49
 
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
50
 
     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
51
 
    AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
52
 
     | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE
53
 
};
54
 
 
55
 
/*****************************************************************************
56
 
 * decoder_sys_t : decoder descriptor
57
 
 *****************************************************************************/
58
 
struct decoder_sys_t
59
 
{
60
 
    /* Common part between video and audio decoder */
61
 
    int i_cat;
62
 
    int i_codec_id;
63
 
    char *psz_namecodec;
64
 
    AVCodecContext      *p_context;
65
 
    AVCodec             *p_codec;
66
 
 
67
 
    /* Temporary buffer for libavcodec */
68
 
    uint8_t *p_output;
69
 
 
70
 
    /*
71
 
     * Output properties
72
 
     */
73
 
    audio_sample_format_t aout_format;
74
 
    audio_date_t          end_date;
75
 
 
76
 
    /*
77
 
     *
78
 
     */
79
 
    uint8_t *p_samples;
80
 
    int     i_samples;
81
 
};
82
 
 
83
 
/*****************************************************************************
84
 
 * InitAudioDec: initialize audio decoder
85
 
 *****************************************************************************
86
 
 * The ffmpeg codec will be opened, some memory allocated.
87
 
 *****************************************************************************/
88
 
int E_(InitAudioDec)( decoder_t *p_dec, AVCodecContext *p_context,
89
 
                      AVCodec *p_codec, int i_codec_id, char *psz_namecodec )
90
 
{
91
 
    decoder_sys_t *p_sys;
92
 
    vlc_value_t lockval;
93
 
 
94
 
    var_Get( p_dec->p_libvlc, "avcodec", &lockval );
95
 
 
96
 
    /* Allocate the memory needed to store the decoder's structure */
97
 
    if( ( p_dec->p_sys = p_sys =
98
 
          (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
99
 
    {
100
 
        msg_Err( p_dec, "out of memory" );
101
 
        return VLC_EGENERIC;
102
 
    }
103
 
 
104
 
    p_sys->p_context = p_context;
105
 
    p_sys->p_codec = p_codec;
106
 
    p_sys->i_codec_id = i_codec_id;
107
 
    p_sys->psz_namecodec = psz_namecodec;
108
 
 
109
 
    /* ***** Fill p_context with init values ***** */
110
 
    p_sys->p_context->sample_rate = p_dec->fmt_in.audio.i_rate;
111
 
    p_sys->p_context->channels = p_dec->fmt_in.audio.i_channels;
112
 
    p_sys->p_context->block_align = p_dec->fmt_in.audio.i_blockalign;
113
 
    p_sys->p_context->bit_rate = p_dec->fmt_in.i_bitrate;
114
 
    p_sys->p_context->bits_per_sample = p_dec->fmt_in.audio.i_bitspersample;
115
 
 
116
 
    if( ( p_sys->p_context->extradata_size = p_dec->fmt_in.i_extra ) > 0 )
117
 
    {
118
 
        int i_offset = 0;
119
 
 
120
 
        if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'f', 'l', 'a', 'c' ) )
121
 
            i_offset = 8;
122
 
 
123
 
        p_sys->p_context->extradata_size -= i_offset;
124
 
        p_sys->p_context->extradata =
125
 
            malloc( p_sys->p_context->extradata_size +
126
 
                    FF_INPUT_BUFFER_PADDING_SIZE );
127
 
        memcpy( p_sys->p_context->extradata,
128
 
                (char*)p_dec->fmt_in.p_extra + i_offset,
129
 
                p_sys->p_context->extradata_size );
130
 
        memset( (char*)p_sys->p_context->extradata +
131
 
                p_sys->p_context->extradata_size, 0,
132
 
                FF_INPUT_BUFFER_PADDING_SIZE );
133
 
    }
134
 
 
135
 
    /* ***** Open the codec ***** */
136
 
    vlc_mutex_lock( lockval.p_address );
137
 
    if (avcodec_open( p_sys->p_context, p_sys->p_codec ) < 0)
138
 
    {
139
 
        vlc_mutex_unlock( lockval.p_address );
140
 
        msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
141
 
        free( p_sys );
142
 
        return VLC_EGENERIC;
143
 
    }
144
 
    vlc_mutex_unlock( lockval.p_address );
145
 
 
146
 
    msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );
147
 
 
148
 
    p_sys->p_output = malloc( AVCODEC_MAX_AUDIO_FRAME_SIZE );
149
 
    p_sys->p_samples = NULL;
150
 
    p_sys->i_samples = 0;
151
 
 
152
 
    if( p_dec->fmt_in.audio.i_rate )
153
 
    {
154
 
        aout_DateInit( &p_sys->end_date, p_dec->fmt_in.audio.i_rate );
155
 
        aout_DateSet( &p_sys->end_date, 0 );
156
 
    }
157
 
 
158
 
    /* Set output properties */
159
 
    p_dec->fmt_out.i_cat = AUDIO_ES;
160
 
    p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
161
 
    p_dec->fmt_out.audio.i_bitspersample = 16;
162
 
 
163
 
    return VLC_SUCCESS;
164
 
}
165
 
 
166
 
/*****************************************************************************
167
 
 * SplitBuffer: Needed because aout really doesn't like big audio chunk and
168
 
 * wma produces easily > 30000 samples...
169
 
 *****************************************************************************/
170
 
aout_buffer_t *SplitBuffer( decoder_t *p_dec )
171
 
{
172
 
    decoder_sys_t *p_sys = p_dec->p_sys;
173
 
    int i_samples = __MIN( p_sys->i_samples, 4096 );
174
 
    aout_buffer_t *p_buffer;
175
 
 
176
 
    if( i_samples == 0 ) return NULL;
177
 
 
178
 
    if( ( p_buffer = p_dec->pf_aout_buffer_new( p_dec, i_samples ) ) == NULL )
179
 
    {
180
 
        msg_Err( p_dec, "cannot get aout buffer" );
181
 
        return NULL;
182
 
    }
183
 
 
184
 
    p_buffer->start_date = aout_DateGet( &p_sys->end_date );
185
 
    p_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
186
 
 
187
 
    memcpy( p_buffer->p_buffer, p_sys->p_samples, p_buffer->i_nb_bytes );
188
 
 
189
 
    p_sys->p_samples += p_buffer->i_nb_bytes;
190
 
    p_sys->i_samples -= i_samples;
191
 
 
192
 
    return p_buffer;
193
 
}
194
 
 
195
 
/*****************************************************************************
196
 
 * DecodeAudio: Called to decode one frame
197
 
 *****************************************************************************/
198
 
aout_buffer_t *E_( DecodeAudio )( decoder_t *p_dec, block_t **pp_block )
199
 
{
200
 
    decoder_sys_t *p_sys = p_dec->p_sys;
201
 
    int i_used, i_output;
202
 
    aout_buffer_t *p_buffer;
203
 
    block_t *p_block;
204
 
 
205
 
    if( !pp_block || !*pp_block ) return NULL;
206
 
 
207
 
    p_block = *pp_block;
208
 
 
209
 
    if( p_block->i_buffer <= 0 && p_sys->i_samples > 0 )
210
 
    {
211
 
        /* More data */
212
 
        p_buffer = SplitBuffer( p_dec );
213
 
        if( !p_buffer ) block_Release( p_block );
214
 
        return p_buffer;
215
 
    }
216
 
 
217
 
    if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
218
 
    {
219
 
        /* We've just started the stream, wait for the first PTS. */
220
 
        block_Release( p_block );
221
 
        return NULL;
222
 
    }
223
 
 
224
 
    if( p_block->i_buffer <= 0 ||
225
 
        (p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED)) )
226
 
    {
227
 
        block_Release( p_block );
228
 
        return NULL;
229
 
    }
230
 
 
231
 
    if( p_block->i_buffer > AVCODEC_MAX_AUDIO_FRAME_SIZE )
232
 
    {
233
 
        /* Grow output buffer if necessary (eg. for PCM data) */
234
 
        p_sys->p_output = realloc(p_sys->p_output, p_block->i_buffer);
235
 
    }
236
 
 
237
 
    i_used = avcodec_decode_audio( p_sys->p_context,
238
 
                                   (int16_t*)p_sys->p_output, &i_output,
239
 
                                   p_block->p_buffer, p_block->i_buffer );
240
 
 
241
 
    if( i_used < 0 || i_output < 0 )
242
 
    {
243
 
        if( i_used < 0 )
244
 
            msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
245
 
                      p_block->i_buffer );
246
 
 
247
 
        block_Release( p_block );
248
 
        return NULL;
249
 
    }
250
 
    else if( i_used > p_block->i_buffer )
251
 
    {
252
 
        i_used = p_block->i_buffer;
253
 
    }
254
 
 
255
 
    p_block->i_buffer -= i_used;
256
 
    p_block->p_buffer += i_used;
257
 
 
258
 
    if( p_sys->p_context->channels <= 0 || p_sys->p_context->channels > 6 )
259
 
    {
260
 
        msg_Warn( p_dec, "invalid channels count %d",
261
 
                  p_sys->p_context->channels );
262
 
        block_Release( p_block );
263
 
        return NULL;
264
 
    }
265
 
 
266
 
    if( p_dec->fmt_out.audio.i_rate != (unsigned int)p_sys->p_context->sample_rate )
267
 
    {
268
 
        aout_DateInit( &p_sys->end_date, p_sys->p_context->sample_rate );
269
 
        aout_DateSet( &p_sys->end_date, p_block->i_pts );
270
 
    }
271
 
 
272
 
    /* **** Set audio output parameters **** */
273
 
    p_dec->fmt_out.audio.i_rate     = p_sys->p_context->sample_rate;
274
 
    p_dec->fmt_out.audio.i_channels = p_sys->p_context->channels;
275
 
    p_dec->fmt_out.audio.i_original_channels =
276
 
        p_dec->fmt_out.audio.i_physical_channels =
277
 
            pi_channels_maps[p_sys->p_context->channels];
278
 
 
279
 
    if( p_block->i_pts != 0 &&
280
 
        p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
281
 
    {
282
 
        aout_DateSet( &p_sys->end_date, p_block->i_pts );
283
 
    }
284
 
    p_block->i_pts = 0;
285
 
 
286
 
    /* **** Now we can output these samples **** */
287
 
    p_sys->i_samples = i_output / 2 / p_sys->p_context->channels;
288
 
    p_sys->p_samples = p_sys->p_output;
289
 
 
290
 
    p_buffer = SplitBuffer( p_dec );
291
 
    if( !p_buffer ) block_Release( p_block );
292
 
    return p_buffer;
293
 
}
294
 
 
295
 
/*****************************************************************************
296
 
 * EndAudioDec: audio decoder destruction
297
 
 *****************************************************************************/
298
 
void E_(EndAudioDec)( decoder_t *p_dec )
299
 
{
300
 
    decoder_sys_t *p_sys = p_dec->p_sys;
301
 
 
302
 
    if( p_sys->p_output ) free( p_sys->p_output );
303
 
}