00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <vlc/vlc.h>
00029 #include <vlc/decoder.h>
00030
00031
00032 #ifdef HAVE_FFMPEG_AVCODEC_H
00033 # include <ffmpeg/avcodec.h>
00034 #else
00035 # include <avcodec.h>
00036 #endif
00037
00038 #include "ffmpeg.h"
00039
00040 static unsigned int pi_channels_maps[7] =
00041 {
00042 0,
00043 AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
00044 AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
00045 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
00046 | AOUT_CHAN_REARRIGHT,
00047 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
00048 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
00049 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
00050 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_LFE
00051 };
00052
00053
00054
00055
00056 struct decoder_sys_t
00057 {
00058
00059 int i_cat;
00060 int i_codec_id;
00061 char *psz_namecodec;
00062 AVCodecContext *p_context;
00063 AVCodec *p_codec;
00064
00065
00066 uint8_t *p_output;
00067
00068
00069
00070
00071 audio_sample_format_t aout_format;
00072 audio_date_t end_date;
00073
00074
00075
00076
00077 uint8_t *p_samples;
00078 int i_samples;
00079 };
00080
00081
00082
00083
00084
00085
00086 int E_(InitAudioDec)( decoder_t *p_dec, AVCodecContext *p_context,
00087 AVCodec *p_codec, int i_codec_id, char *psz_namecodec )
00088 {
00089 decoder_sys_t *p_sys;
00090 vlc_value_t lockval;
00091
00092 var_Get( p_dec->p_libvlc, "avcodec", &lockval );
00093
00094
00095 if( ( p_dec->p_sys = p_sys =
00096 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
00097 {
00098 msg_Err( p_dec, "out of memory" );
00099 return VLC_EGENERIC;
00100 }
00101
00102 p_sys->p_context = p_context;
00103 p_sys->p_codec = p_codec;
00104 p_sys->i_codec_id = i_codec_id;
00105 p_sys->psz_namecodec = psz_namecodec;
00106
00107
00108 p_sys->p_context->sample_rate = p_dec->fmt_in.audio.i_rate;
00109 p_sys->p_context->channels = p_dec->fmt_in.audio.i_channels;
00110 p_sys->p_context->block_align = p_dec->fmt_in.audio.i_blockalign;
00111 p_sys->p_context->bit_rate = p_dec->fmt_in.i_bitrate;
00112 p_sys->p_context->bits_per_sample = p_dec->fmt_in.audio.i_bitspersample;
00113
00114 if( ( p_sys->p_context->extradata_size = p_dec->fmt_in.i_extra ) > 0 )
00115 {
00116 int i_offset = 0;
00117
00118 if( p_dec->fmt_in.i_codec == VLC_FOURCC( 'f', 'l', 'a', 'c' ) )
00119 i_offset = 8;
00120
00121 p_sys->p_context->extradata_size -= i_offset;
00122 p_sys->p_context->extradata =
00123 malloc( p_sys->p_context->extradata_size +
00124 FF_INPUT_BUFFER_PADDING_SIZE );
00125 memcpy( p_sys->p_context->extradata,
00126 (char*)p_dec->fmt_in.p_extra + i_offset,
00127 p_sys->p_context->extradata_size );
00128 memset( (char*)p_sys->p_context->extradata +
00129 p_sys->p_context->extradata_size, 0,
00130 FF_INPUT_BUFFER_PADDING_SIZE );
00131 }
00132
00133
00134 vlc_mutex_lock( lockval.p_address );
00135 if (avcodec_open( p_sys->p_context, p_sys->p_codec ) < 0)
00136 {
00137 vlc_mutex_unlock( lockval.p_address );
00138 msg_Err( p_dec, "cannot open codec (%s)", p_sys->psz_namecodec );
00139 free( p_sys );
00140 return VLC_EGENERIC;
00141 }
00142 vlc_mutex_unlock( lockval.p_address );
00143
00144 msg_Dbg( p_dec, "ffmpeg codec (%s) started", p_sys->psz_namecodec );
00145
00146 p_sys->p_output = malloc( 3 * AVCODEC_MAX_AUDIO_FRAME_SIZE );
00147 p_sys->p_samples = NULL;
00148 p_sys->i_samples = 0;
00149
00150 if( p_dec->fmt_in.audio.i_rate )
00151 {
00152 aout_DateInit( &p_sys->end_date, p_dec->fmt_in.audio.i_rate );
00153 aout_DateSet( &p_sys->end_date, 0 );
00154 }
00155
00156
00157 p_dec->fmt_out.i_cat = AUDIO_ES;
00158 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
00159 p_dec->fmt_out.audio.i_bitspersample = 16;
00160
00161 return VLC_SUCCESS;
00162 }
00163
00164
00165
00166
00167
00168 aout_buffer_t *SplitBuffer( decoder_t *p_dec )
00169 {
00170 decoder_sys_t *p_sys = p_dec->p_sys;
00171 int i_samples = __MIN( p_sys->i_samples, 4096 );
00172 aout_buffer_t *p_buffer;
00173
00174 if( i_samples == 0 ) return NULL;
00175
00176 if( ( p_buffer = p_dec->pf_aout_buffer_new( p_dec, i_samples ) ) == NULL )
00177 {
00178 msg_Err( p_dec, "cannot get aout buffer" );
00179 return NULL;
00180 }
00181
00182 p_buffer->start_date = aout_DateGet( &p_sys->end_date );
00183 p_buffer->end_date = aout_DateIncrement( &p_sys->end_date, i_samples );
00184
00185 memcpy( p_buffer->p_buffer, p_sys->p_samples, p_buffer->i_nb_bytes );
00186
00187 p_sys->p_samples += p_buffer->i_nb_bytes;
00188 p_sys->i_samples -= i_samples;
00189
00190 return p_buffer;
00191 }
00192
00193
00194
00195
00196 aout_buffer_t *E_( DecodeAudio )( decoder_t *p_dec, block_t **pp_block )
00197 {
00198 decoder_sys_t *p_sys = p_dec->p_sys;
00199 int i_used, i_output;
00200 aout_buffer_t *p_buffer;
00201 block_t *p_block;
00202
00203 if( !pp_block || !*pp_block ) return NULL;
00204
00205 p_block = *pp_block;
00206
00207 if( p_block->i_buffer <= 0 && p_sys->i_samples > 0 )
00208 {
00209
00210 p_buffer = SplitBuffer( p_dec );
00211 if( !p_buffer ) block_Release( p_block );
00212 return p_buffer;
00213 }
00214
00215 if( !aout_DateGet( &p_sys->end_date ) && !p_block->i_pts )
00216 {
00217
00218 block_Release( p_block );
00219 return NULL;
00220 }
00221
00222 if( p_block->i_buffer <= 0 || ( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) )
00223 {
00224 block_Release( p_block );
00225 return NULL;
00226 }
00227
00228 i_used = avcodec_decode_audio( p_sys->p_context,
00229 (int16_t*)p_sys->p_output, &i_output,
00230 p_block->p_buffer, p_block->i_buffer );
00231
00232 if( i_used < 0 || i_output < 0 )
00233 {
00234 if( i_used < 0 )
00235 msg_Warn( p_dec, "cannot decode one frame (%d bytes)",
00236 p_block->i_buffer );
00237
00238 block_Release( p_block );
00239 return NULL;
00240 }
00241 else if( i_used > p_block->i_buffer )
00242 {
00243 i_used = p_block->i_buffer;
00244 }
00245
00246 p_block->i_buffer -= i_used;
00247 p_block->p_buffer += i_used;
00248
00249 if( p_sys->p_context->channels <= 0 || p_sys->p_context->channels > 6 )
00250 {
00251 msg_Warn( p_dec, "invalid channels count %d",
00252 p_sys->p_context->channels );
00253 block_Release( p_block );
00254 return NULL;
00255 }
00256
00257 if( p_dec->fmt_out.audio.i_rate != (unsigned int)p_sys->p_context->sample_rate )
00258 {
00259 aout_DateInit( &p_sys->end_date, p_sys->p_context->sample_rate );
00260 aout_DateSet( &p_sys->end_date, p_block->i_pts );
00261 }
00262
00263
00264 p_dec->fmt_out.audio.i_rate = p_sys->p_context->sample_rate;
00265 p_dec->fmt_out.audio.i_channels = p_sys->p_context->channels;
00266 p_dec->fmt_out.audio.i_original_channels =
00267 p_dec->fmt_out.audio.i_physical_channels =
00268 pi_channels_maps[p_sys->p_context->channels];
00269
00270 if( p_block->i_pts != 0 &&
00271 p_block->i_pts != aout_DateGet( &p_sys->end_date ) )
00272 {
00273 aout_DateSet( &p_sys->end_date, p_block->i_pts );
00274 }
00275 p_block->i_pts = 0;
00276
00277
00278 p_sys->i_samples = i_output / 2 / p_sys->p_context->channels;
00279 p_sys->p_samples = p_sys->p_output;
00280
00281 p_buffer = SplitBuffer( p_dec );
00282 if( !p_buffer ) block_Release( p_block );
00283 return p_buffer;
00284 }
00285
00286
00287
00288
00289 void E_(EndAudioDec)( decoder_t *p_dec )
00290 {
00291 decoder_sys_t *p_sys = p_dec->p_sys;
00292
00293 if( p_sys->p_output ) free( p_sys->p_output );
00294 }