1/* 2 * Faad decoder 3 * Copyright (c) 2003 Zdenek Kabelac 4 * Copyright (c) 2004 Thomas Raivio 5 * 6 * This file is part of FFmpeg. 7 * 8 * FFmpeg is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * FFmpeg is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with FFmpeg; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 */ 22 23/** 24 * @file libavcodec/libfaad.c 25 * AAC decoder. 26 * 27 * still a bit unfinished - but it plays something 28 */ 29 30#include "avcodec.h" 31#include "faad.h" 32 33#ifndef FAADAPI 34#define FAADAPI 35#endif 36 37/* 38 * when CONFIG_LIBFAADBIN is true libfaad will be opened at runtime 39 */ 40//#undef CONFIG_LIBFAADBIN 41//#define CONFIG_LIBFAADBIN 0 42//#define CONFIG_LIBFAADBIN 1 43 44#if CONFIG_LIBFAADBIN 45#include <dlfcn.h> 46static const char* const libfaadname = "libfaad.so"; 47#else 48#define dlopen(a) 49#define dlclose(a) 50#endif 51 52typedef struct { 53 void* handle; /* dlopen handle */ 54 void* faac_handle; /* FAAD library handle */ 55 int sample_size; 56 int init; 57 58 /* faad calls */ 59 faacDecHandle FAADAPI (*faacDecOpen)(void); 60 faacDecConfigurationPtr FAADAPI (*faacDecGetCurrentConfiguration)(faacDecHandle hDecoder); 61#ifndef FAAD2_VERSION 62 int FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, 63 faacDecConfigurationPtr config); 64 int FAADAPI (*faacDecInit)(faacDecHandle hDecoder, 65 unsigned char *buffer, 66 unsigned long *samplerate, 67 unsigned long *channels); 68 int FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, 69 unsigned long SizeOfDecoderSpecificInfo, 70 unsigned long *samplerate, unsigned long *channels); 71 int FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, 72 unsigned char *buffer, 73 unsigned long *bytesconsumed, 74 short *sample_buffer, 75 unsigned long *samples); 76#else 77 unsigned char FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, 78 faacDecConfigurationPtr config); 79 long FAADAPI (*faacDecInit)(faacDecHandle hDecoder, 80 unsigned char *buffer, 81 unsigned long buffer_size, 82 unsigned long *samplerate, 83 unsigned char *channels); 84 char FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, 85 unsigned long SizeOfDecoderSpecificInfo, 86 unsigned long *samplerate, unsigned char *channels); 87 void *FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, 88 faacDecFrameInfo *hInfo, 89 unsigned char *buffer, 90 unsigned long buffer_size); 91 char* FAADAPI (*faacDecGetErrorMessage)(unsigned char errcode); 92#endif 93 94 void FAADAPI (*faacDecClose)(faacDecHandle hDecoder); 95 96 97} FAACContext; 98 99static const unsigned long faac_srates[] = 100{ 101 96000, 88200, 64000, 48000, 44100, 32000, 102 24000, 22050, 16000, 12000, 11025, 8000 103}; 104 105static void channel_setup(AVCodecContext *avctx) 106{ 107#ifdef FAAD2_VERSION 108 FAACContext *s = avctx->priv_data; 109 if (avctx->request_channels > 0 && avctx->request_channels == 2 && 110 avctx->request_channels < avctx->channels) { 111 faacDecConfigurationPtr faac_cfg; 112 avctx->channels = 2; 113 faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle); 114 faac_cfg->downMatrix = 1; 115 s->faacDecSetConfiguration(s->faac_handle, faac_cfg); 116 } 117#endif 118} 119 120static av_cold int faac_init_mp4(AVCodecContext *avctx) 121{ 122 FAACContext *s = avctx->priv_data; 123 unsigned long samplerate; 124#ifndef FAAD2_VERSION 125 unsigned long channels; 126#else 127 unsigned char channels; 128#endif 129 int r = 0; 130 131 if (avctx->extradata){ 132 r = s->faacDecInit2(s->faac_handle, (uint8_t*) avctx->extradata, 133 avctx->extradata_size, 134 &samplerate, &channels); 135 if (r < 0){ 136 av_log(avctx, AV_LOG_ERROR, 137 "faacDecInit2 failed r:%d sr:%ld ch:%ld s:%d\n", 138 r, samplerate, (long)channels, avctx->extradata_size); 139 } else { 140 avctx->sample_rate = samplerate; 141 avctx->channels = channels; 142 channel_setup(avctx); 143 s->init = 1; 144 } 145 } 146 147 return r; 148} 149 150static int faac_decode_frame(AVCodecContext *avctx, 151 void *data, int *data_size, 152 uint8_t *buf, int buf_size) 153{ 154 FAACContext *s = avctx->priv_data; 155#ifndef FAAD2_VERSION 156 unsigned long bytesconsumed; 157 short *sample_buffer = NULL; 158 unsigned long samples; 159 int out; 160#else 161 faacDecFrameInfo frame_info; 162 void *out; 163#endif 164 if(buf_size == 0) 165 return 0; 166#ifndef FAAD2_VERSION 167 out = s->faacDecDecode(s->faac_handle, 168 (unsigned char*)buf, 169 &bytesconsumed, 170 data, 171 &samples); 172 samples *= s->sample_size; 173 if (data_size) 174 *data_size = samples; 175 return (buf_size < (int)bytesconsumed) 176 ? buf_size : (int)bytesconsumed; 177#else 178 179 if(!s->init){ 180 unsigned long srate; 181 unsigned char channels; 182 int r = s->faacDecInit(s->faac_handle, buf, buf_size, &srate, &channels); 183 if(r < 0){ 184 av_log(avctx, AV_LOG_ERROR, "faac: codec init failed.\n"); 185 return -1; 186 } 187 avctx->sample_rate = srate; 188 avctx->channels = channels; 189 channel_setup(avctx); 190 s->init = 1; 191 } 192 193 out = s->faacDecDecode(s->faac_handle, &frame_info, (unsigned char*)buf, (unsigned long)buf_size); 194 195 if (frame_info.error > 0) { 196 av_log(avctx, AV_LOG_ERROR, "faac: frame decoding failed: %s\n", 197 s->faacDecGetErrorMessage(frame_info.error)); 198 return -1; 199 } 200 if (!avctx->frame_size) 201 avctx->frame_size = frame_info.samples/avctx->channels; 202 frame_info.samples *= s->sample_size; 203 memcpy(data, out, frame_info.samples); // CHECKME - can we cheat this one 204 205 if (data_size) 206 *data_size = frame_info.samples; 207 208 return (buf_size < (int)frame_info.bytesconsumed) 209 ? buf_size : (int)frame_info.bytesconsumed; 210#endif 211} 212 213static av_cold int faac_decode_end(AVCodecContext *avctx) 214{ 215 FAACContext *s = avctx->priv_data; 216 217 s->faacDecClose(s->faac_handle); 218 219 dlclose(s->handle); 220 return 0; 221} 222 223static av_cold int faac_decode_init(AVCodecContext *avctx) 224{ 225 FAACContext *s = avctx->priv_data; 226 faacDecConfigurationPtr faac_cfg; 227 228#if CONFIG_LIBFAADBIN 229 const char* err = 0; 230 231 s->handle = dlopen(libfaadname, RTLD_LAZY); 232 if (!s->handle) 233 { 234 av_log(avctx, AV_LOG_ERROR, "FAAD library: %s could not be opened! \n%s\n", 235 libfaadname, dlerror()); 236 return -1; 237 } 238 239#define dfaac(a) do { \ 240 const char* n = AV_STRINGIFY(faacDec ## a); \ 241 if (!err && !(s->faacDec ## a = dlsym(s->handle, n))) { \ 242 err = n; \ 243 } \ 244 } while(0) 245#else /* !CONFIG_LIBFAADBIN */ 246#define dfaac(a) s->faacDec ## a = faacDec ## a 247#endif /* CONFIG_LIBFAADBIN */ 248 249 // resolve all needed function calls 250 dfaac(Open); 251 dfaac(Close); 252 dfaac(GetCurrentConfiguration); 253 dfaac(SetConfiguration); 254 dfaac(Init); 255 dfaac(Init2); 256 dfaac(Decode); 257#ifdef FAAD2_VERSION 258 dfaac(GetErrorMessage); 259#endif 260 261#undef dfaac 262 263#if CONFIG_LIBFAADBIN 264 if (err) { 265 dlclose(s->handle); 266 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot resolve %s in %s!\n", 267 err, libfaadname); 268 return -1; 269 } 270#endif 271 272 s->faac_handle = s->faacDecOpen(); 273 if (!s->faac_handle) { 274 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot create handler!\n"); 275 faac_decode_end(avctx); 276 return -1; 277 } 278 279 280 faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle); 281 282 if (faac_cfg) { 283 switch (avctx->bits_per_coded_sample) { 284 case 8: av_log(avctx, AV_LOG_ERROR, "FAADlib unsupported bps %d\n", avctx->bits_per_coded_sample); break; 285 default: 286 case 16: 287#ifdef FAAD2_VERSION 288 faac_cfg->outputFormat = FAAD_FMT_16BIT; 289#endif 290 s->sample_size = 2; 291 break; 292 case 24: 293#ifdef FAAD2_VERSION 294 faac_cfg->outputFormat = FAAD_FMT_24BIT; 295#endif 296 s->sample_size = 3; 297 break; 298 case 32: 299#ifdef FAAD2_VERSION 300 faac_cfg->outputFormat = FAAD_FMT_32BIT; 301#endif 302 s->sample_size = 4; 303 break; 304 } 305 306 faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate; 307 faac_cfg->defObjectType = LC; 308 } 309 310 s->faacDecSetConfiguration(s->faac_handle, faac_cfg); 311 312 faac_init_mp4(avctx); 313 314 if(!s->init && avctx->channels > 0) 315 channel_setup(avctx); 316 317 avctx->sample_fmt = SAMPLE_FMT_S16; 318 return 0; 319} 320 321#define AAC_CODEC(id, name, long_name_) \ 322AVCodec name ## _decoder = { \ 323 #name, \ 324 CODEC_TYPE_AUDIO, \ 325 id, \ 326 sizeof(FAACContext), \ 327 faac_decode_init, \ 328 NULL, \ 329 faac_decode_end, \ 330 faac_decode_frame, \ 331 .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ 332} 333 334// FIXME - raw AAC files - maybe just one entry will be enough 335AAC_CODEC(CODEC_ID_AAC, libfaad, "libfaad AAC (Advanced Audio Codec)"); 336 337#undef AAC_CODEC 338