00001 /* 00002 * Faad decoder 00003 * Copyright (c) 2003 Zdenek Kabelac 00004 * Copyright (c) 2004 Thomas Raivio 00005 * 00006 * This file is part of FFmpeg. 00007 * 00008 * FFmpeg is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * FFmpeg is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with FFmpeg; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00030 #include "avcodec.h" 00031 #include "faad.h" 00032 00033 #ifndef FAADAPI 00034 #define FAADAPI 00035 #endif 00036 00037 /* 00038 * when CONFIG_LIBFAADBIN is true libfaad will be opened at runtime 00039 */ 00040 //#undef CONFIG_LIBFAADBIN 00041 //#define CONFIG_LIBFAADBIN 0 00042 //#define CONFIG_LIBFAADBIN 1 00043 00044 #if CONFIG_LIBFAADBIN 00045 #include <dlfcn.h> 00046 static const char* const libfaadname = "libfaad.so"; 00047 #else 00048 #define dlopen(a) 00049 #define dlclose(a) 00050 #endif 00051 00052 typedef struct { 00053 void* handle; /* dlopen handle */ 00054 void* faac_handle; /* FAAD library handle */ 00055 int sample_size; 00056 int init; 00057 00058 /* faad calls */ 00059 faacDecHandle FAADAPI (*faacDecOpen)(void); 00060 faacDecConfigurationPtr FAADAPI (*faacDecGetCurrentConfiguration)(faacDecHandle hDecoder); 00061 #ifndef FAAD2_VERSION 00062 int FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, 00063 faacDecConfigurationPtr config); 00064 int FAADAPI (*faacDecInit)(faacDecHandle hDecoder, 00065 unsigned char *buffer, 00066 unsigned long *samplerate, 00067 unsigned long *channels); 00068 int FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, 00069 unsigned long SizeOfDecoderSpecificInfo, 00070 unsigned long *samplerate, unsigned long *channels); 00071 int FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, 00072 unsigned char *buffer, 00073 unsigned long *bytesconsumed, 00074 short *sample_buffer, 00075 unsigned long *samples); 00076 #else 00077 unsigned char FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, 00078 faacDecConfigurationPtr config); 00079 long FAADAPI (*faacDecInit)(faacDecHandle hDecoder, 00080 unsigned char *buffer, 00081 unsigned long buffer_size, 00082 unsigned long *samplerate, 00083 unsigned char *channels); 00084 char FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, 00085 unsigned long SizeOfDecoderSpecificInfo, 00086 unsigned long *samplerate, unsigned char *channels); 00087 void *FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, 00088 faacDecFrameInfo *hInfo, 00089 unsigned char *buffer, 00090 unsigned long buffer_size); 00091 char* FAADAPI (*faacDecGetErrorMessage)(unsigned char errcode); 00092 #endif 00093 00094 void FAADAPI (*faacDecClose)(faacDecHandle hDecoder); 00095 00096 00097 } FAACContext; 00098 00099 static const unsigned long faac_srates[] = 00100 { 00101 96000, 88200, 64000, 48000, 44100, 32000, 00102 24000, 22050, 16000, 12000, 11025, 8000 00103 }; 00104 00105 static void channel_setup(AVCodecContext *avctx) 00106 { 00107 #ifdef FAAD2_VERSION 00108 FAACContext *s = avctx->priv_data; 00109 if (avctx->request_channels > 0 && avctx->request_channels == 2 && 00110 avctx->request_channels < avctx->channels) { 00111 faacDecConfigurationPtr faac_cfg; 00112 avctx->channels = 2; 00113 faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle); 00114 faac_cfg->downMatrix = 1; 00115 s->faacDecSetConfiguration(s->faac_handle, faac_cfg); 00116 } 00117 #endif 00118 } 00119 00120 static av_cold int faac_init_mp4(AVCodecContext *avctx) 00121 { 00122 FAACContext *s = avctx->priv_data; 00123 unsigned long samplerate; 00124 #ifndef FAAD2_VERSION 00125 unsigned long channels; 00126 #else 00127 unsigned char channels; 00128 #endif 00129 int r = 0; 00130 00131 if (avctx->extradata){ 00132 r = s->faacDecInit2(s->faac_handle, (uint8_t*) avctx->extradata, 00133 avctx->extradata_size, 00134 &samplerate, &channels); 00135 if (r < 0){ 00136 av_log(avctx, AV_LOG_ERROR, 00137 "faacDecInit2 failed r:%d sr:%ld ch:%ld s:%d\n", 00138 r, samplerate, (long)channels, avctx->extradata_size); 00139 } else { 00140 avctx->sample_rate = samplerate; 00141 avctx->channels = channels; 00142 channel_setup(avctx); 00143 s->init = 1; 00144 } 00145 } 00146 00147 return r; 00148 } 00149 00150 static int faac_decode_frame(AVCodecContext *avctx, 00151 void *data, int *data_size, 00152 uint8_t *buf, int buf_size) 00153 { 00154 FAACContext *s = avctx->priv_data; 00155 #ifndef FAAD2_VERSION 00156 unsigned long bytesconsumed; 00157 short *sample_buffer = NULL; 00158 unsigned long samples; 00159 int out; 00160 #else 00161 faacDecFrameInfo frame_info; 00162 void *out; 00163 #endif 00164 if(buf_size == 0) 00165 return 0; 00166 #ifndef FAAD2_VERSION 00167 out = s->faacDecDecode(s->faac_handle, 00168 (unsigned char*)buf, 00169 &bytesconsumed, 00170 data, 00171 &samples); 00172 samples *= s->sample_size; 00173 if (data_size) 00174 *data_size = samples; 00175 return (buf_size < (int)bytesconsumed) 00176 ? buf_size : (int)bytesconsumed; 00177 #else 00178 00179 if(!s->init){ 00180 unsigned long srate; 00181 unsigned char channels; 00182 int r = s->faacDecInit(s->faac_handle, buf, buf_size, &srate, &channels); 00183 if(r < 0){ 00184 av_log(avctx, AV_LOG_ERROR, "faac: codec init failed.\n"); 00185 return -1; 00186 } 00187 avctx->sample_rate = srate; 00188 avctx->channels = channels; 00189 channel_setup(avctx); 00190 s->init = 1; 00191 } 00192 00193 out = s->faacDecDecode(s->faac_handle, &frame_info, (unsigned char*)buf, (unsigned long)buf_size); 00194 00195 if (frame_info.error > 0) { 00196 av_log(avctx, AV_LOG_ERROR, "faac: frame decoding failed: %s\n", 00197 s->faacDecGetErrorMessage(frame_info.error)); 00198 return -1; 00199 } 00200 if (!avctx->frame_size) 00201 avctx->frame_size = frame_info.samples/avctx->channels; 00202 frame_info.samples *= s->sample_size; 00203 memcpy(data, out, frame_info.samples); // CHECKME - can we cheat this one 00204 00205 if (data_size) 00206 *data_size = frame_info.samples; 00207 00208 return (buf_size < (int)frame_info.bytesconsumed) 00209 ? buf_size : (int)frame_info.bytesconsumed; 00210 #endif 00211 } 00212 00213 static av_cold int faac_decode_end(AVCodecContext *avctx) 00214 { 00215 FAACContext *s = avctx->priv_data; 00216 00217 s->faacDecClose(s->faac_handle); 00218 00219 dlclose(s->handle); 00220 return 0; 00221 } 00222 00223 static av_cold int faac_decode_init(AVCodecContext *avctx) 00224 { 00225 FAACContext *s = avctx->priv_data; 00226 faacDecConfigurationPtr faac_cfg; 00227 00228 #if CONFIG_LIBFAADBIN 00229 const char* err = 0; 00230 00231 s->handle = dlopen(libfaadname, RTLD_LAZY); 00232 if (!s->handle) 00233 { 00234 av_log(avctx, AV_LOG_ERROR, "FAAD library: %s could not be opened! \n%s\n", 00235 libfaadname, dlerror()); 00236 return -1; 00237 } 00238 00239 #define dfaac(a) do { \ 00240 const char* n = AV_STRINGIFY(faacDec ## a); \ 00241 if (!err && !(s->faacDec ## a = dlsym(s->handle, n))) { \ 00242 err = n; \ 00243 } \ 00244 } while(0) 00245 #else /* !CONFIG_LIBFAADBIN */ 00246 #define dfaac(a) s->faacDec ## a = faacDec ## a 00247 #endif /* CONFIG_LIBFAADBIN */ 00248 00249 // resolve all needed function calls 00250 dfaac(Open); 00251 dfaac(Close); 00252 dfaac(GetCurrentConfiguration); 00253 dfaac(SetConfiguration); 00254 dfaac(Init); 00255 dfaac(Init2); 00256 dfaac(Decode); 00257 #ifdef FAAD2_VERSION 00258 dfaac(GetErrorMessage); 00259 #endif 00260 00261 #undef dfaac 00262 00263 #if CONFIG_LIBFAADBIN 00264 if (err) { 00265 dlclose(s->handle); 00266 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot resolve %s in %s!\n", 00267 err, libfaadname); 00268 return -1; 00269 } 00270 #endif 00271 00272 s->faac_handle = s->faacDecOpen(); 00273 if (!s->faac_handle) { 00274 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot create handler!\n"); 00275 faac_decode_end(avctx); 00276 return -1; 00277 } 00278 00279 00280 faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle); 00281 00282 if (faac_cfg) { 00283 switch (avctx->bits_per_coded_sample) { 00284 case 8: av_log(avctx, AV_LOG_ERROR, "FAADlib unsupported bps %d\n", avctx->bits_per_coded_sample); break; 00285 default: 00286 case 16: 00287 #ifdef FAAD2_VERSION 00288 faac_cfg->outputFormat = FAAD_FMT_16BIT; 00289 #endif 00290 s->sample_size = 2; 00291 break; 00292 case 24: 00293 #ifdef FAAD2_VERSION 00294 faac_cfg->outputFormat = FAAD_FMT_24BIT; 00295 #endif 00296 s->sample_size = 3; 00297 break; 00298 case 32: 00299 #ifdef FAAD2_VERSION 00300 faac_cfg->outputFormat = FAAD_FMT_32BIT; 00301 #endif 00302 s->sample_size = 4; 00303 break; 00304 } 00305 00306 faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate; 00307 faac_cfg->defObjectType = LC; 00308 } 00309 00310 s->faacDecSetConfiguration(s->faac_handle, faac_cfg); 00311 00312 faac_init_mp4(avctx); 00313 00314 if(!s->init && avctx->channels > 0) 00315 channel_setup(avctx); 00316 00317 avctx->sample_fmt = SAMPLE_FMT_S16; 00318 return 0; 00319 } 00320 00321 #define AAC_CODEC(id, name, long_name_) \ 00322 AVCodec name ## _decoder = { \ 00323 #name, \ 00324 CODEC_TYPE_AUDIO, \ 00325 id, \ 00326 sizeof(FAACContext), \ 00327 faac_decode_init, \ 00328 NULL, \ 00329 faac_decode_end, \ 00330 faac_decode_frame, \ 00331 .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ 00332 } 00333 00334 // FIXME - raw AAC files - maybe just one entry will be enough 00335 AAC_CODEC(CODEC_ID_AAC, libfaad, "libfaad AAC (Advanced Audio Codec)"); 00336 00337 #undef AAC_CODEC