Libav
|
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 AVPacket *avpkt) 00153 { 00154 const uint8_t *buf = avpkt->data; 00155 int buf_size = avpkt->size; 00156 FAACContext *s = avctx->priv_data; 00157 #ifndef FAAD2_VERSION 00158 unsigned long bytesconsumed; 00159 short *sample_buffer = NULL; 00160 unsigned long samples; 00161 int out; 00162 #else 00163 faacDecFrameInfo frame_info; 00164 void *out; 00165 #endif 00166 if(buf_size == 0) 00167 return 0; 00168 #ifndef FAAD2_VERSION 00169 out = s->faacDecDecode(s->faac_handle, 00170 (unsigned char*)buf, 00171 &bytesconsumed, 00172 data, 00173 &samples); 00174 samples *= s->sample_size; 00175 if (data_size) 00176 *data_size = samples; 00177 return (buf_size < (int)bytesconsumed) 00178 ? buf_size : (int)bytesconsumed; 00179 #else 00180 00181 if(!s->init){ 00182 unsigned long srate; 00183 unsigned char channels; 00184 int r = s->faacDecInit(s->faac_handle, buf, buf_size, &srate, &channels); 00185 if(r < 0){ 00186 av_log(avctx, AV_LOG_ERROR, "libfaad: codec init failed.\n"); 00187 return -1; 00188 } 00189 avctx->sample_rate = srate; 00190 avctx->channels = channels; 00191 channel_setup(avctx); 00192 s->init = 1; 00193 } 00194 00195 out = s->faacDecDecode(s->faac_handle, &frame_info, (unsigned char*)buf, (unsigned long)buf_size); 00196 00197 if (frame_info.error > 0) { 00198 av_log(avctx, AV_LOG_ERROR, "libfaad: frame decoding failed: %s\n", 00199 s->faacDecGetErrorMessage(frame_info.error)); 00200 return -1; 00201 } 00202 if (!avctx->frame_size) 00203 avctx->frame_size = frame_info.samples/avctx->channels; 00204 frame_info.samples *= s->sample_size; 00205 memcpy(data, out, frame_info.samples); // CHECKME - can we cheat this one 00206 00207 if (data_size) 00208 *data_size = frame_info.samples; 00209 00210 return (buf_size < (int)frame_info.bytesconsumed) 00211 ? buf_size : (int)frame_info.bytesconsumed; 00212 #endif 00213 } 00214 00215 static av_cold int faac_decode_end(AVCodecContext *avctx) 00216 { 00217 FAACContext *s = avctx->priv_data; 00218 00219 s->faacDecClose(s->faac_handle); 00220 00221 dlclose(s->handle); 00222 return 0; 00223 } 00224 00225 static av_cold int faac_decode_init(AVCodecContext *avctx) 00226 { 00227 FAACContext *s = avctx->priv_data; 00228 faacDecConfigurationPtr faac_cfg; 00229 00230 #if CONFIG_LIBFAADBIN 00231 const char* err = 0; 00232 00233 s->handle = dlopen(libfaadname, RTLD_LAZY); 00234 if (!s->handle) 00235 { 00236 av_log(avctx, AV_LOG_ERROR, "FAAD library: %s could not be opened! \n%s\n", 00237 libfaadname, dlerror()); 00238 return -1; 00239 } 00240 00241 #define dfaac(a) do { \ 00242 const char* n = AV_STRINGIFY(faacDec ## a); \ 00243 if (!err && !(s->faacDec ## a = dlsym(s->handle, n))) { \ 00244 err = n; \ 00245 } \ 00246 } while(0) 00247 #else /* !CONFIG_LIBFAADBIN */ 00248 #define dfaac(a) s->faacDec ## a = faacDec ## a 00249 #endif /* CONFIG_LIBFAADBIN */ 00250 00251 // resolve all needed function calls 00252 dfaac(Open); 00253 dfaac(Close); 00254 dfaac(GetCurrentConfiguration); 00255 dfaac(SetConfiguration); 00256 dfaac(Init); 00257 dfaac(Init2); 00258 dfaac(Decode); 00259 #ifdef FAAD2_VERSION 00260 dfaac(GetErrorMessage); 00261 #endif 00262 00263 #undef dfaac 00264 00265 #if CONFIG_LIBFAADBIN 00266 if (err) { 00267 dlclose(s->handle); 00268 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot resolve %s in %s!\n", 00269 err, libfaadname); 00270 return -1; 00271 } 00272 #endif 00273 00274 s->faac_handle = s->faacDecOpen(); 00275 if (!s->faac_handle) { 00276 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot create handler!\n"); 00277 faac_decode_end(avctx); 00278 return -1; 00279 } 00280 00281 00282 faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle); 00283 00284 if (faac_cfg) { 00285 switch (avctx->bits_per_coded_sample) { 00286 case 8: av_log(avctx, AV_LOG_ERROR, "FAADlib unsupported bps %d\n", avctx->bits_per_coded_sample); break; 00287 default: 00288 case 16: 00289 #ifdef FAAD2_VERSION 00290 faac_cfg->outputFormat = FAAD_FMT_16BIT; 00291 #endif 00292 s->sample_size = 2; 00293 break; 00294 case 24: 00295 #ifdef FAAD2_VERSION 00296 faac_cfg->outputFormat = FAAD_FMT_24BIT; 00297 #endif 00298 s->sample_size = 3; 00299 break; 00300 case 32: 00301 #ifdef FAAD2_VERSION 00302 faac_cfg->outputFormat = FAAD_FMT_32BIT; 00303 #endif 00304 s->sample_size = 4; 00305 break; 00306 } 00307 00308 faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate; 00309 faac_cfg->defObjectType = LC; 00310 } 00311 00312 s->faacDecSetConfiguration(s->faac_handle, faac_cfg); 00313 00314 faac_init_mp4(avctx); 00315 00316 if(!s->init && avctx->channels > 0) 00317 channel_setup(avctx); 00318 00319 avctx->sample_fmt = SAMPLE_FMT_S16; 00320 return 0; 00321 } 00322 00323 AVCodec libfaad_decoder = { 00324 "libfaad", 00325 AVMEDIA_TYPE_AUDIO, 00326 CODEC_ID_AAC, 00327 sizeof(FAACContext), 00328 faac_decode_init, 00329 NULL, 00330 faac_decode_end, 00331 faac_decode_frame, 00332 .long_name = NULL_IF_CONFIG_SMALL("libfaad AAC (Advanced Audio Codec)"), 00333 };