00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00028 #include "avcodec.h"
00029 #include "faad.h"
00030
00031 #ifndef FAADAPI
00032 #define FAADAPI
00033 #endif
00034
00035
00036
00037
00038
00039
00040
00041 #ifdef CONFIG_FAADBIN
00042 #include <dlfcn.h>
00043 static const char* libfaadname = "libfaad.so.0";
00044 #else
00045 #define dlopen(a)
00046 #define dlclose(a)
00047 #endif
00048
00049 typedef struct {
00050 void* handle;
00051 void* faac_handle;
00052 int frame_size;
00053 int sample_size;
00054 int flags;
00055
00056
00057 faacDecHandle FAADAPI (*faacDecOpen)(void);
00058 faacDecConfigurationPtr FAADAPI (*faacDecGetCurrentConfiguration)(faacDecHandle hDecoder);
00059 #ifndef FAAD2_VERSION
00060 int FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder,
00061 faacDecConfigurationPtr config);
00062 int FAADAPI (*faacDecInit)(faacDecHandle hDecoder,
00063 unsigned char *buffer,
00064 unsigned long *samplerate,
00065 unsigned long *channels);
00066 int FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer,
00067 unsigned long SizeOfDecoderSpecificInfo,
00068 unsigned long *samplerate, unsigned long *channels);
00069 int FAADAPI (*faacDecDecode)(faacDecHandle hDecoder,
00070 unsigned char *buffer,
00071 unsigned long *bytesconsumed,
00072 short *sample_buffer,
00073 unsigned long *samples);
00074 #else
00075 unsigned char FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder,
00076 faacDecConfigurationPtr config);
00077 long FAADAPI (*faacDecInit)(faacDecHandle hDecoder,
00078 unsigned char *buffer,
00079 unsigned long buffer_size,
00080 unsigned long *samplerate,
00081 unsigned char *channels);
00082 char FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer,
00083 unsigned long SizeOfDecoderSpecificInfo,
00084 unsigned long *samplerate, unsigned char *channels);
00085 void *FAADAPI (*faacDecDecode)(faacDecHandle hDecoder,
00086 faacDecFrameInfo *hInfo,
00087 unsigned char *buffer,
00088 unsigned long buffer_size);
00089 char* FAADAPI (*faacDecGetErrorMessage)(unsigned char errcode);
00090 #endif
00091
00092 void FAADAPI (*faacDecClose)(faacDecHandle hDecoder);
00093
00094
00095 } FAACContext;
00096
00097 static const unsigned long faac_srates[] =
00098 {
00099 96000, 88200, 64000, 48000, 44100, 32000,
00100 24000, 22050, 16000, 12000, 11025, 8000
00101 };
00102
00103 static int faac_init_mp4(AVCodecContext *avctx)
00104 {
00105 FAACContext *s = (FAACContext *) avctx->priv_data;
00106 unsigned long samplerate;
00107 #ifndef FAAD2_VERSION
00108 unsigned long channels;
00109 #else
00110 unsigned char channels;
00111 #endif
00112 int r = 0;
00113
00114 if (avctx->extradata)
00115 r = s->faacDecInit2(s->faac_handle, (uint8_t*) avctx->extradata,
00116 avctx->extradata_size,
00117 &samplerate, &channels);
00118
00119
00120 if (r < 0)
00121 av_log(avctx, AV_LOG_ERROR, "faacDecInit2 failed r:%d sr:%ld ch:%ld s:%d\n",
00122 r, samplerate, (long)channels, avctx->extradata_size);
00123 avctx->sample_rate = samplerate;
00124 avctx->channels = channels;
00125
00126 return r;
00127 }
00128
00129 static int faac_decode_frame(AVCodecContext *avctx,
00130 void *data, int *data_size,
00131 uint8_t *buf, int buf_size)
00132 {
00133 FAACContext *s = (FAACContext *) avctx->priv_data;
00134 #ifndef FAAD2_VERSION
00135 unsigned long bytesconsumed;
00136 short *sample_buffer = NULL;
00137 unsigned long samples;
00138 int out;
00139 #else
00140 faacDecFrameInfo frame_info;
00141 void *out;
00142 #endif
00143 if(buf_size == 0)
00144 return 0;
00145 #ifndef FAAD2_VERSION
00146 out = s->faacDecDecode(s->faac_handle,
00147 (unsigned char*)buf,
00148 &bytesconsumed,
00149 data,
00150 &samples);
00151 samples *= s->sample_size;
00152 if (data_size)
00153 *data_size = samples;
00154 return (buf_size < (int)bytesconsumed)
00155 ? buf_size : (int)bytesconsumed;
00156 #else
00157
00158 out = s->faacDecDecode(s->faac_handle, &frame_info, (unsigned char*)buf, (unsigned long)buf_size);
00159
00160 if (frame_info.error > 0) {
00161 av_log(avctx, AV_LOG_ERROR, "faac: frame decoding failed: %s\n",
00162 s->faacDecGetErrorMessage(frame_info.error));
00163 return 0;
00164 }
00165
00166 frame_info.samples *= s->sample_size;
00167 memcpy(data, out, frame_info.samples);
00168
00169 if (data_size)
00170 *data_size = frame_info.samples;
00171
00172 return (buf_size < (int)frame_info.bytesconsumed)
00173 ? buf_size : (int)frame_info.bytesconsumed;
00174 #endif
00175 }
00176
00177 static int faac_decode_end(AVCodecContext *avctx)
00178 {
00179 FAACContext *s = (FAACContext *) avctx->priv_data;
00180
00181 if (s->faacDecClose)
00182 s->faacDecClose(s->faac_handle);
00183
00184 dlclose(s->handle);
00185 return 0;
00186 }
00187
00188 static int faac_decode_init(AVCodecContext *avctx)
00189 {
00190 FAACContext *s = (FAACContext *) avctx->priv_data;
00191 faacDecConfigurationPtr faac_cfg;
00192
00193 #ifdef CONFIG_FAADBIN
00194 const char* err = 0;
00195
00196 s->handle = dlopen(libfaadname, RTLD_LAZY);
00197 if (!s->handle)
00198 {
00199 av_log(avctx, AV_LOG_ERROR, "FAAD library: %s could not be opened! \n%s\n",
00200 libfaadname, dlerror());
00201 return -1;
00202 }
00203 #define dfaac(a, b) \
00204 do { static const char* n = "faacDec" #a; \
00205 if ((s->faacDec ## a = b dlsym( s->handle, n )) == NULL) { err = n; break; } } while(0)
00206 for(;;) {
00207 #else
00208 #define dfaac(a, b) s->faacDec ## a = faacDec ## a
00209 #endif
00210
00211
00212 dfaac(Open, (faacDecHandle FAADAPI (*)(void)));
00213 dfaac(GetCurrentConfiguration, (faacDecConfigurationPtr
00214 FAADAPI (*)(faacDecHandle)));
00215 #ifndef FAAD2_VERSION
00216 dfaac(SetConfiguration, (int FAADAPI (*)(faacDecHandle,
00217 faacDecConfigurationPtr)));
00218
00219 dfaac(Init, (int FAADAPI (*)(faacDecHandle, unsigned char*,
00220 unsigned long*, unsigned long*)));
00221 dfaac(Init2, (int FAADAPI (*)(faacDecHandle, unsigned char*,
00222 unsigned long, unsigned long*,
00223 unsigned long*)));
00224 dfaac(Close, (void FAADAPI (*)(faacDecHandle hDecoder)));
00225 dfaac(Decode, (int FAADAPI (*)(faacDecHandle, unsigned char*,
00226 unsigned long*, short*, unsigned long*)));
00227 #else
00228 dfaac(SetConfiguration, (unsigned char FAADAPI (*)(faacDecHandle,
00229 faacDecConfigurationPtr)));
00230 dfaac(Init, (long FAADAPI (*)(faacDecHandle, unsigned char*,
00231 unsigned long, unsigned long*, unsigned char*)));
00232 dfaac(Init2, (char FAADAPI (*)(faacDecHandle, unsigned char*,
00233 unsigned long, unsigned long*,
00234 unsigned char*)));
00235 dfaac(Decode, (void *FAADAPI (*)(faacDecHandle, faacDecFrameInfo*,
00236 unsigned char*, unsigned long)));
00237 dfaac(GetErrorMessage, (char* FAADAPI (*)(unsigned char)));
00238 #endif
00239 #undef dfacc
00240
00241 #ifdef CONFIG_FAADBIN
00242 break;
00243 }
00244 if (err) {
00245 dlclose(s->handle);
00246 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot resolve %s in %s!\n",
00247 err, libfaadname);
00248 return -1;
00249 }
00250 #endif
00251
00252 s->faac_handle = s->faacDecOpen();
00253 if (!s->faac_handle) {
00254 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot create handler!\n");
00255 faac_decode_end(avctx);
00256 return -1;
00257 }
00258
00259
00260 faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle);
00261
00262 if (faac_cfg) {
00263 switch (avctx->bits_per_sample) {
00264 case 8: av_log(avctx, AV_LOG_ERROR, "FAADlib unsupported bps %d\n", avctx->bits_per_sample); break;
00265 default:
00266 case 16:
00267 #ifdef FAAD2_VERSION
00268 faac_cfg->outputFormat = FAAD_FMT_16BIT;
00269 #endif
00270 s->sample_size = 2;
00271 break;
00272 case 24:
00273 #ifdef FAAD2_VERSION
00274 faac_cfg->outputFormat = FAAD_FMT_24BIT;
00275 #endif
00276 s->sample_size = 3;
00277 break;
00278 case 32:
00279 #ifdef FAAD2_VERSION
00280 faac_cfg->outputFormat = FAAD_FMT_32BIT;
00281 #endif
00282 s->sample_size = 4;
00283 break;
00284 }
00285
00286 faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate;
00287 faac_cfg->defObjectType = LC;
00288 }
00289
00290 s->faacDecSetConfiguration(s->faac_handle, faac_cfg);
00291
00292 faac_init_mp4(avctx);
00293
00294 return 0;
00295 }
00296
00297 #define AAC_CODEC(id, name) \
00298 AVCodec name ## _decoder = { \
00299 #name, \
00300 CODEC_TYPE_AUDIO, \
00301 id, \
00302 sizeof(FAACContext), \
00303 faac_decode_init, \
00304 NULL, \
00305 faac_decode_end, \
00306 faac_decode_frame, \
00307 }
00308
00309
00310 AAC_CODEC(CODEC_ID_AAC, aac);
00311
00312 AAC_CODEC(CODEC_ID_MPEG4AAC, mpeg4aac);
00313
00314 #undef AAC_CODEC