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 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 AVPacket *avpkt) 153{ 154 const uint8_t *buf = avpkt->data; 155 int buf_size = avpkt->size; 156 FAACContext *s = avctx->priv_data; 157#ifndef FAAD2_VERSION 158 unsigned long bytesconsumed; 159 short *sample_buffer = NULL; 160 unsigned long samples; 161 int out; 162#else 163 faacDecFrameInfo frame_info; 164 void *out; 165#endif 166 if(buf_size == 0) 167 return 0; 168#ifndef FAAD2_VERSION 169 out = s->faacDecDecode(s->faac_handle, 170 (unsigned char*)buf, 171 &bytesconsumed, 172 data, 173 &samples); 174 samples *= s->sample_size; 175 if (data_size) 176 *data_size = samples; 177 return (buf_size < (int)bytesconsumed) 178 ? buf_size : (int)bytesconsumed; 179#else 180 181 if(!s->init){ 182 unsigned long srate; 183 unsigned char channels; 184 int r = s->faacDecInit(s->faac_handle, buf, buf_size, &srate, &channels); 185 if(r < 0){ 186 av_log(avctx, AV_LOG_ERROR, "libfaad: codec init failed.\n"); 187 return -1; 188 } 189 avctx->sample_rate = srate; 190 avctx->channels = channels; 191 channel_setup(avctx); 192 s->init = 1; 193 } 194 195 out = s->faacDecDecode(s->faac_handle, &frame_info, (unsigned char*)buf, (unsigned long)buf_size); 196 197 if (frame_info.error > 0) { 198 av_log(avctx, AV_LOG_ERROR, "libfaad: frame decoding failed: %s\n", 199 s->faacDecGetErrorMessage(frame_info.error)); 200 return -1; 201 } 202 if (!avctx->frame_size) 203 avctx->frame_size = frame_info.samples/avctx->channels; 204 frame_info.samples *= s->sample_size; 205 memcpy(data, out, frame_info.samples); // CHECKME - can we cheat this one 206 207 if (data_size) 208 *data_size = frame_info.samples; 209 210 return (buf_size < (int)frame_info.bytesconsumed) 211 ? buf_size : (int)frame_info.bytesconsumed; 212#endif 213} 214 215static av_cold int faac_decode_end(AVCodecContext *avctx) 216{ 217 FAACContext *s = avctx->priv_data; 218 219 s->faacDecClose(s->faac_handle); 220 221 dlclose(s->handle); 222 return 0; 223} 224 225static av_cold int faac_decode_init(AVCodecContext *avctx) 226{ 227 FAACContext *s = avctx->priv_data; 228 faacDecConfigurationPtr faac_cfg; 229 230#if CONFIG_LIBFAADBIN 231 const char* err = 0; 232 233 s->handle = dlopen(libfaadname, RTLD_LAZY); 234 if (!s->handle) 235 { 236 av_log(avctx, AV_LOG_ERROR, "FAAD library: %s could not be opened! \n%s\n", 237 libfaadname, dlerror()); 238 return -1; 239 } 240 241#define dfaac(a) do { \ 242 const char* n = AV_STRINGIFY(faacDec ## a); \ 243 if (!err && !(s->faacDec ## a = dlsym(s->handle, n))) { \ 244 err = n; \ 245 } \ 246 } while(0) 247#else /* !CONFIG_LIBFAADBIN */ 248#define dfaac(a) s->faacDec ## a = faacDec ## a 249#endif /* CONFIG_LIBFAADBIN */ 250 251 // resolve all needed function calls 252 dfaac(Open); 253 dfaac(Close); 254 dfaac(GetCurrentConfiguration); 255 dfaac(SetConfiguration); 256 dfaac(Init); 257 dfaac(Init2); 258 dfaac(Decode); 259#ifdef FAAD2_VERSION 260 dfaac(GetErrorMessage); 261#endif 262 263#undef dfaac 264 265#if CONFIG_LIBFAADBIN 266 if (err) { 267 dlclose(s->handle); 268 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot resolve %s in %s!\n", 269 err, libfaadname); 270 return -1; 271 } 272#endif 273 274 s->faac_handle = s->faacDecOpen(); 275 if (!s->faac_handle) { 276 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot create handler!\n"); 277 faac_decode_end(avctx); 278 return -1; 279 } 280 281 282 faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle); 283 284 if (faac_cfg) { 285 switch (avctx->bits_per_coded_sample) { 286 case 8: av_log(avctx, AV_LOG_ERROR, "FAADlib unsupported bps %d\n", avctx->bits_per_coded_sample); break; 287 default: 288 case 16: 289#ifdef FAAD2_VERSION 290 faac_cfg->outputFormat = FAAD_FMT_16BIT; 291#endif 292 s->sample_size = 2; 293 break; 294 case 24: 295#ifdef FAAD2_VERSION 296 faac_cfg->outputFormat = FAAD_FMT_24BIT; 297#endif 298 s->sample_size = 3; 299 break; 300 case 32: 301#ifdef FAAD2_VERSION 302 faac_cfg->outputFormat = FAAD_FMT_32BIT; 303#endif 304 s->sample_size = 4; 305 break; 306 } 307 308 faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate; 309 faac_cfg->defObjectType = LC; 310 } 311 312 s->faacDecSetConfiguration(s->faac_handle, faac_cfg); 313 314 faac_init_mp4(avctx); 315 316 if(!s->init && avctx->channels > 0) 317 channel_setup(avctx); 318 319 avctx->sample_fmt = SAMPLE_FMT_S16; 320 return 0; 321} 322 323AVCodec libfaad_decoder = { 324 "libfaad", 325 AVMEDIA_TYPE_AUDIO, 326 CODEC_ID_AAC, 327 sizeof(FAACContext), 328 faac_decode_init, 329 NULL, 330 faac_decode_end, 331 faac_decode_frame, 332 .long_name = NULL_IF_CONFIG_SMALL("libfaad AAC (Advanced Audio Codec)"), 333}; 334