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 #include <vlc/vlc.h>
00026 #include <vlc/aout.h>
00027 #include <vlc/decoder.h>
00028
00029 #include <faad.h>
00030
00031
00032
00033
00034 static int Open( vlc_object_t * );
00035 static void Close( vlc_object_t * );
00036
00037 vlc_module_begin();
00038 set_description( _("AAC audio decoder (using libfaad2)") );
00039 set_capability( "decoder", 100 );
00040 set_category( CAT_INPUT );
00041 set_subcategory( SUBCAT_INPUT_ACODEC );
00042 set_callbacks( Open, Close );
00043 vlc_module_end();
00044
00045
00046
00047
00048 static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
00049 static void DoReordering( decoder_t *, uint32_t *, uint32_t *, int, int,
00050 uint32_t * );
00051
00052 #define MAX_CHANNEL_POSITIONS 9
00053
00054 struct decoder_sys_t
00055 {
00056
00057 faacDecHandle *hfaad;
00058
00059
00060 audio_date_t date;
00061
00062
00063 uint8_t *p_buffer;
00064 int i_buffer;
00065 int i_buffer_size;
00066
00067
00068 uint32_t pi_channel_positions[MAX_CHANNEL_POSITIONS];
00069 };
00070
00071 static const uint32_t pi_channels_in[MAX_CHANNEL_POSITIONS] =
00072 { FRONT_CHANNEL_CENTER, FRONT_CHANNEL_LEFT, FRONT_CHANNEL_RIGHT,
00073 SIDE_CHANNEL_LEFT, SIDE_CHANNEL_RIGHT,
00074 BACK_CHANNEL_LEFT, BACK_CHANNEL_RIGHT,
00075 BACK_CHANNEL_CENTER, LFE_CHANNEL };
00076 static const uint32_t pi_channels_out[MAX_CHANNEL_POSITIONS] =
00077 { AOUT_CHAN_CENTER, AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
00078 AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT,
00079 AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
00080 AOUT_CHAN_REARCENTER, AOUT_CHAN_LFE };
00081 static const uint32_t pi_channels_ordered[MAX_CHANNEL_POSITIONS] =
00082 { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
00083 AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT,
00084 AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
00085 AOUT_CHAN_CENTER, AOUT_CHAN_REARCENTER, AOUT_CHAN_LFE
00086 };
00087
00088
00089
00090
00091 static int Open( vlc_object_t *p_this )
00092 {
00093 decoder_t *p_dec = (decoder_t*)p_this;
00094 decoder_sys_t *p_sys = p_dec->p_sys;
00095 faacDecConfiguration *cfg;
00096
00097 if( p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','4','a') )
00098 {
00099 return VLC_EGENERIC;
00100 }
00101
00102
00103 if( ( p_dec->p_sys = p_sys =
00104 (decoder_sys_t *)malloc(sizeof(decoder_sys_t)) ) == NULL )
00105 {
00106 msg_Err( p_dec, "out of memory" );
00107 return VLC_EGENERIC;
00108 }
00109
00110
00111 if( ( p_sys->hfaad = faacDecOpen() ) == NULL )
00112 {
00113 msg_Err( p_dec, "cannot initialize faad" );
00114 return VLC_EGENERIC;
00115 }
00116
00117
00118 aout_DateSet( &p_sys->date, 0 );
00119 p_dec->fmt_out.i_cat = AUDIO_ES;
00120
00121 if (p_this->p_libvlc->i_cpu & CPU_CAPABILITY_FPU)
00122 p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
00123 else
00124 p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
00125 p_dec->pf_decode_audio = DecodeBlock;
00126
00127 p_dec->fmt_out.audio.i_physical_channels =
00128 p_dec->fmt_out.audio.i_original_channels = 0;
00129
00130 if( p_dec->fmt_in.i_extra > 0 )
00131 {
00132
00133 unsigned long i_rate;
00134 unsigned char i_channels;
00135
00136 if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,
00137 p_dec->fmt_in.i_extra,
00138 &i_rate, &i_channels ) < 0 )
00139 {
00140 return VLC_EGENERIC;
00141 }
00142
00143 p_dec->fmt_out.audio.i_rate = i_rate;
00144 p_dec->fmt_out.audio.i_channels = i_channels;
00145 aout_DateInit( &p_sys->date, i_rate );
00146 }
00147 else
00148 {
00149
00150 p_dec->fmt_out.audio.i_rate = 0;
00151 p_dec->fmt_out.audio.i_channels = 0;
00152 }
00153
00154
00155 cfg = faacDecGetCurrentConfiguration( p_sys->hfaad );
00156 if (p_this->p_libvlc->i_cpu & CPU_CAPABILITY_FPU)
00157 cfg->outputFormat = FAAD_FMT_FLOAT;
00158 else
00159 cfg->outputFormat = FAAD_FMT_16BIT;
00160 faacDecSetConfiguration( p_sys->hfaad, cfg );
00161
00162
00163 p_sys->i_buffer = p_sys->i_buffer_size = 0;
00164 p_sys->p_buffer = 0;
00165
00166
00167 p_dec->b_need_packetized = VLC_TRUE;
00168
00169 return VLC_SUCCESS;
00170 }
00171
00172
00173
00174
00175 static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
00176 {
00177 decoder_sys_t *p_sys = p_dec->p_sys;
00178 block_t *p_block;
00179
00180 if( !pp_block || !*pp_block ) return NULL;
00181
00182 p_block = *pp_block;
00183
00184 if( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
00185 {
00186 block_Release( p_block );
00187 return NULL;
00188 }
00189
00190
00191 if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer )
00192 {
00193 p_sys->i_buffer_size = p_sys->i_buffer + p_block->i_buffer;
00194 p_sys->p_buffer = realloc( p_sys->p_buffer, p_sys->i_buffer_size );
00195 }
00196
00197 if( p_block->i_buffer )
00198 {
00199 memcpy( &p_sys->p_buffer[p_sys->i_buffer],
00200 p_block->p_buffer, p_block->i_buffer );
00201 p_sys->i_buffer += p_block->i_buffer;
00202 p_block->i_buffer = 0;
00203 }
00204
00205 if( p_dec->fmt_out.audio.i_rate == 0 && p_dec->fmt_in.i_extra > 0 )
00206 {
00207
00208 unsigned long i_rate;
00209 unsigned char i_channels;
00210
00211 if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,
00212 p_dec->fmt_in.i_extra,
00213 &i_rate, &i_channels ) >= 0 )
00214 {
00215 p_dec->fmt_out.audio.i_rate = i_rate;
00216 p_dec->fmt_out.audio.i_channels = i_channels;
00217 aout_DateInit( &p_sys->date, i_rate );
00218 }
00219 }
00220
00221 if( p_dec->fmt_out.audio.i_rate == 0 && p_sys->i_buffer )
00222 {
00223 unsigned long i_rate;
00224 unsigned char i_channels;
00225
00226
00227 if( faacDecInit( p_sys->hfaad,
00228 p_sys->p_buffer, p_sys->i_buffer,
00229 &i_rate, &i_channels ) < 0 )
00230 {
00231 block_Release( p_block );
00232 return NULL;
00233 }
00234
00235 p_dec->fmt_out.audio.i_rate = i_rate;
00236 p_dec->fmt_out.audio.i_channels = i_channels;
00237 aout_DateInit( &p_sys->date, i_rate );
00238 }
00239
00240 if( p_block->i_pts != 0 && p_block->i_pts != aout_DateGet( &p_sys->date ) )
00241 {
00242 aout_DateSet( &p_sys->date, p_block->i_pts );
00243 }
00244 else if( !aout_DateGet( &p_sys->date ) )
00245 {
00246
00247 block_Release( p_block );
00248 p_sys->i_buffer = 0;
00249 return NULL;
00250 }
00251
00252
00253 if( p_sys->i_buffer )
00254 {
00255 void *samples;
00256 faacDecFrameInfo frame;
00257 aout_buffer_t *p_out;
00258 int i, j;
00259
00260 samples = faacDecDecode( p_sys->hfaad, &frame,
00261 p_sys->p_buffer, p_sys->i_buffer );
00262
00263 if( frame.error > 0 )
00264 {
00265 msg_Warn( p_dec, "%s", faacDecGetErrorMessage( frame.error ) );
00266
00267
00268 p_sys->i_buffer = 0;
00269 block_Release( p_block );
00270 return NULL;
00271 }
00272
00273 if( frame.channels <= 0 || frame.channels > 8 || frame.channels == 7 )
00274 {
00275 msg_Warn( p_dec, "invalid channels count: %i", frame.channels );
00276
00277
00278 p_sys->i_buffer -= frame.bytesconsumed;
00279 if( p_sys->i_buffer > 0 )
00280 {
00281 memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed],
00282 p_sys->i_buffer );
00283 }
00284 block_Release( p_block );
00285 return NULL;
00286 }
00287
00288 if( frame.samples <= 0 )
00289 {
00290 msg_Warn( p_dec, "decoded zero sample" );
00291
00292
00293 p_sys->i_buffer -= frame.bytesconsumed;
00294 if( p_sys->i_buffer > 0 )
00295 {
00296 memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed],
00297 p_sys->i_buffer );
00298 }
00299 block_Release( p_block );
00300 return NULL;
00301 }
00302
00303
00304 if( p_dec->fmt_out.audio.i_rate != frame.samplerate )
00305 {
00306 aout_DateInit( &p_sys->date, frame.samplerate );
00307 aout_DateSet( &p_sys->date, p_block->i_pts );
00308 }
00309 p_block->i_pts = 0;
00310
00311 p_dec->fmt_out.audio.i_rate = frame.samplerate;
00312 p_dec->fmt_out.audio.i_channels = frame.channels;
00313
00314
00315
00316 for( i = 0; i < frame.channels; i++ )
00317 {
00318
00319 for( j = 0; j < MAX_CHANNEL_POSITIONS; j++ )
00320 {
00321 if( frame.channel_position[i] == pi_channels_in[j] )
00322 {
00323 p_sys->pi_channel_positions[i] = pi_channels_out[j];
00324 p_dec->fmt_out.audio.i_physical_channels |=
00325 pi_channels_out[j];
00326 break;
00327 }
00328 }
00329
00330 if( j == MAX_CHANNEL_POSITIONS )
00331 {
00332 msg_Warn( p_dec, "unknown channel ordering" );
00333 block_Release( p_block );
00334 return NULL;
00335 }
00336 }
00337 p_dec->fmt_out.audio.i_original_channels =
00338 p_dec->fmt_out.audio.i_physical_channels;
00339
00340 p_out = p_dec->pf_aout_buffer_new(p_dec, frame.samples/frame.channels);
00341 if( p_out == NULL )
00342 {
00343 p_sys->i_buffer = 0;
00344 block_Release( p_block );
00345 return NULL;
00346 }
00347
00348 p_out->start_date = aout_DateGet( &p_sys->date );
00349 p_out->end_date = aout_DateIncrement( &p_sys->date,
00350 frame.samples / frame.channels );
00351
00352 DoReordering( p_dec, (uint32_t *)p_out->p_buffer, samples,
00353 frame.samples / frame.channels, frame.channels,
00354 p_sys->pi_channel_positions );
00355
00356 p_sys->i_buffer -= frame.bytesconsumed;
00357 if( p_sys->i_buffer > 0 )
00358 {
00359 memmove( p_sys->p_buffer, &p_sys->p_buffer[frame.bytesconsumed],
00360 p_sys->i_buffer );
00361 }
00362
00363 return p_out;
00364 }
00365
00366 block_Release( p_block );
00367 return NULL;
00368 }
00369
00370
00371
00372
00373 static void Close( vlc_object_t *p_this )
00374 {
00375 decoder_t *p_dec = (decoder_t *)p_this;
00376 decoder_sys_t *p_sys = p_dec->p_sys;
00377
00378 faacDecClose( p_sys->hfaad );
00379 free( p_sys );
00380 }
00381
00382
00383
00384
00385
00386 static void DoReordering( decoder_t *p_dec,
00387 uint32_t *p_out, uint32_t *p_in, int i_samples,
00388 int i_nb_channels, uint32_t *pi_chan_positions )
00389 {
00390 int pi_chan_table[MAX_CHANNEL_POSITIONS];
00391 int i, j, k;
00392
00393
00394 for( i = 0, j = 0; i < MAX_CHANNEL_POSITIONS; i++ )
00395 {
00396 for( k = 0; k < i_nb_channels; k++ )
00397 {
00398 if( pi_channels_ordered[i] == pi_chan_positions[k] )
00399 {
00400 pi_chan_table[k] = j++;
00401 break;
00402 }
00403 }
00404 }
00405
00406
00407 if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_FPU )
00408 for( i = 0; i < i_samples; i++ )
00409 for( j = 0; j < i_nb_channels; j++ )
00410 p_out[i * i_nb_channels + pi_chan_table[j]] =
00411 p_in[i * i_nb_channels + j];
00412 else
00413 for( i = 0; i < i_samples; i++ )
00414 for( j = 0; j < i_nb_channels; j++ )
00415 ((uint16_t *)p_out)[i * i_nb_channels + pi_chan_table[j]] =
00416 ((uint16_t *)p_in)[i * i_nb_channels + j];
00417 }