1 /*****************************************************************************
2 * audio.c: audio decoder using ffmpeg library
3 *****************************************************************************
4 * Copyright (C) 1999-2003 VideoLAN
5 * $Id: audio.c,v 1.28 2004/02/25 17:48:52 fenrir Exp $
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Gildas Bazin <gbazin@netcourrier.com>
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
29 #include <vlc/decoder.h>
32 #ifdef HAVE_FFMPEG_AVCODEC_H
33 # include <ffmpeg/avcodec.h>
40 static unsigned int pi_channels_maps[6] =
43 AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
44 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
45 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
46 | AOUT_CHAN_REARRIGHT,
47 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
48 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
51 /*****************************************************************************
52 * decoder_sys_t : decoder descriptor
53 *****************************************************************************/
56 /* Common part between video and audio decoder */
60 AVCodecContext *p_context;
63 /* Temporary buffer for libavcodec */
69 audio_sample_format_t aout_format;
70 audio_date_t end_date;
73 /*****************************************************************************
74 * InitAudioDec: initialize audio decoder
75 *****************************************************************************
76 * The ffmpeg codec will be opened, some memory allocated.
77 *****************************************************************************/
78 int E_(InitAudioDec)( decoder_t *p_dec, AVCodecContext *p_context,
79 AVCodec *p_codec, int i_codec_id, char *psz_namecodec )
84 var_Get( p_dec->p_libvlc, "avcodec", &lockval );
86 /* Allocate the memory needed to store the decoder's structure */
87 if( ( p_dec->p_sys = p_sys =
88 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
90 msg_Err( p_dec, "out of memory" );
94 p_dec->p_sys->p_context = p_context;
95 p_dec->p_sys->p_codec = p_codec;
96 p_dec->p_sys->i_codec_id = i_codec_id;
97 p_dec->p_sys->psz_namecodec = psz_namecodec;
99 /* ***** Fill p_context with init values ***** */
100 p_sys->p_context->sample_rate = p_dec->fmt_in.audio.i_rate;
101 p_sys->p_context->channels = p_dec->fmt_in.audio.i_channels;
102 p_sys->p_context->block_align = p_dec->fmt_in.audio.i_blockalign;
103 p_sys->p_context->bit_rate = p_dec->fmt_in.i_bitrate;
105 if( ( p_sys->p_context->extradata_size = p_dec->fmt_in.i_extra ) > 0 )
107 p_sys->p_context->extradata =
108 malloc( p_dec->fmt_in.i_extra + FF_INPUT_BUFFER_PADDING_SIZE );
109 memcpy( p_sys->p_context->extradata,
110 p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
111 memset( p_sys->p_context->extradata + p_dec->fmt_in.i_extra, 0,
112 FF_INPUT_BUFFER_PADDING_SIZE );
115 /* ***** Open the codec ***** */
116 vlc_mutex_lock( lockval.p_address );
117 if (avcodec_open( p_sys->p_context, p_sys->p_codec ) < 0)
119 vlc_mutex_unlock( lockval.p_address );
120 msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
123 vlc_mutex_unlock( lockval.p_address );
125 msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );
127 p_sys->p_output = malloc( 3 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
129 aout_DateSet( &p_sys->end_date, 0 );
131 /* Set output properties */
132 p_dec->fmt_out.i_cat = AUDIO_ES;
133 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
138 /*****************************************************************************
139 * DecodeAudio: Called to decode one frame
140 *****************************************************************************/
141 aout_buffer_t *E_( DecodeAudio )( decoder_t *p_dec, block_t **pp_block )
143 decoder_sys_t *p_sys = p_dec->p_sys;
144 int i_used, i_output, i_samples;
146 aout_buffer_t *p_buffer;
149 if( !pp_block || !*pp_block ) return NULL;
153 if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
155 /* We've just started the stream, wait for the first PTS. */
156 block_Release( p_block );
160 if( p_block->i_buffer <= 0 ||
161 ( p_block->i_flags&BLOCK_FLAG_DISCONTINUITY ) )
163 block_Release( p_block );
167 i_used = avcodec_decode_audio( p_sys->p_context,
168 (int16_t*)p_sys->p_output, &i_output,
169 p_block->p_buffer, p_block->i_buffer );
171 if( i_used < 0 )//|| i_output == 0 )
174 msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
177 block_Release( p_block );
180 else if( i_used > p_block->i_buffer )
182 i_used = p_block->i_buffer;
185 p_block->i_buffer -= i_used;
186 p_block->p_buffer += i_used;
188 if( p_sys->p_context->channels <= 0 || p_sys->p_context->channels > 6 )
190 msg_Warn( p_dec, "invalid channels count %d",
191 p_sys->p_context->channels );
192 block_Release( p_block );
196 if( p_dec->fmt_out.audio.i_rate != p_sys->p_context->sample_rate )
198 aout_DateInit( &p_sys->end_date, p_sys->p_context->sample_rate );
199 aout_DateSet( &p_sys->end_date, p_block->i_pts );
202 /* **** Set audio output parameters **** */
203 p_dec->fmt_out.audio.i_rate = p_sys->p_context->sample_rate;
204 p_dec->fmt_out.audio.i_channels = p_sys->p_context->channels;
205 p_dec->fmt_out.audio.i_original_channels =
206 p_dec->fmt_out.audio.i_physical_channels =
207 pi_channels_maps[p_sys->p_context->channels];
209 if( p_block->i_pts != 0 &&
210 p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
212 aout_DateSet( &p_sys->end_date, p_block->i_pts );
216 /* **** Now we can output these samples **** */
217 i_samples = i_output / 2 / p_sys->p_context->channels;
218 p_samples = p_sys->p_output;
220 p_buffer = p_dec->pf_aout_buffer_new( p_dec, i_samples );
223 msg_Err( p_dec, "cannot get aout buffer" );
224 block_Release( p_block );
228 p_buffer->start_date = aout_DateGet( &p_sys->end_date );
229 p_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
231 memcpy( p_buffer->p_buffer, p_samples, p_buffer->i_nb_bytes );
236 /*****************************************************************************
237 * EndAudioDec: audio decoder destruction
238 *****************************************************************************/
239 void E_(EndAudioDec)( decoder_t *p_dec )
241 decoder_sys_t *p_sys = p_dec->p_sys;
243 if( p_sys->p_output ) free( p_sys->p_output );