Mercurial > libavcodec.hg
annotate faad.c @ 1893:779bdf5063ce libavcodec
1000000l (using uninitalized variable for initalizing bits per MV table)
| author | michael |
|---|---|
| date | Tue, 16 Mar 2004 16:57:27 +0000 |
| parents | fdb8244da1e5 |
| children | d4525c3065d0 |
| rev | line source |
|---|---|
| 1245 | 1 /* |
| 2 * Faad decoder | |
| 3 * Copyright (c) 2003 Zdenek Kabelac. | |
| 4 * | |
| 5 * This library is free software; you can redistribute it and/or | |
| 6 * modify it under the terms of the GNU Lesser General Public | |
| 7 * License as published by the Free Software Foundation; either | |
| 8 * version 2 of the License, or (at your option) any later version. | |
| 9 * | |
| 10 * This library is distributed in the hope that it will be useful, | |
| 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 * Lesser General Public License for more details. | |
| 14 * | |
| 15 * You should have received a copy of the GNU Lesser General Public | |
| 16 * License along with this library; if not, write to the Free Software | |
| 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 18 */ | |
| 19 | |
| 20 /** | |
| 21 * @file faad.c | |
| 22 * AAC decoder. | |
| 23 * | |
| 24 * still a bit unfinished - but it plays something | |
| 25 */ | |
| 26 | |
| 27 #include "avcodec.h" | |
| 28 #include "faad.h" | |
| 29 | |
| 30 /* | |
| 31 * when CONFIG_FAADBIN is defined the libfaad will be opened at runtime | |
| 32 */ | |
| 33 //#undef CONFIG_FAADBIN | |
| 34 //#define CONFIG_FAADBIN | |
| 35 | |
| 36 #ifdef CONFIG_FAADBIN | |
| 37 #include <dlfcn.h> | |
| 38 static const char* libfaadname = "libfaad.so.0"; | |
| 39 #else | |
| 40 #define dlopen(a) | |
| 41 #define dlclose(a) | |
| 42 #endif | |
| 43 | |
| 44 typedef struct { | |
| 45 void* handle; /* dlopen handle */ | |
| 46 void* faac_handle; /* FAAD library handle */ | |
| 47 int frame_size; | |
| 48 int sample_size; | |
| 49 int flags; | |
| 50 | |
| 51 /* faad calls */ | |
| 52 faacDecHandle FAADAPI (*faacDecOpen)(void); | |
| 53 faacDecConfigurationPtr FAADAPI (*faacDecGetCurrentConfiguration)(faacDecHandle hDecoder); | |
| 54 unsigned char FAADAPI (*faacDecSetConfiguration)(faacDecHandle hDecoder, | |
| 55 faacDecConfigurationPtr config); | |
| 56 long FAADAPI (*faacDecInit)(faacDecHandle hDecoder, | |
| 57 unsigned char *buffer, | |
| 58 unsigned long *samplerate, | |
| 59 unsigned char *channels); | |
| 60 char FAADAPI (*faacDecInit2)(faacDecHandle hDecoder, unsigned char *pBuffer, | |
| 61 unsigned long SizeOfDecoderSpecificInfo, | |
| 62 unsigned long *samplerate, unsigned char *channels); | |
| 63 void FAADAPI (*faacDecClose)(faacDecHandle hDecoder); | |
| 64 void* FAADAPI (*faacDecDecode)(faacDecHandle hDecoder, | |
| 65 faacDecFrameInfo *hInfo, | |
| 66 unsigned char *buffer); | |
| 67 unsigned char* FAADAPI (*faacDecGetErrorMessage)(unsigned char errcode); | |
| 68 } FAACContext; | |
| 69 | |
| 70 static const unsigned long faac_srates[] = | |
| 71 { | |
| 72 96000, 88200, 64000, 48000, 44100, 32000, | |
| 73 24000, 22050, 16000, 12000, 11025, 8000 | |
| 74 }; | |
| 75 | |
| 76 static int faac_init_mp4(AVCodecContext *avctx) | |
| 77 { | |
| 78 FAACContext *s = (FAACContext *) avctx->priv_data; | |
| 79 unsigned long samplerate; | |
| 80 unsigned char channels; | |
| 81 int r = 0; | |
| 82 | |
| 83 if (avctx->extradata) | |
| 84 r = s->faacDecInit2(s->faac_handle, (uint8_t*) avctx->extradata, | |
| 85 avctx->extradata_size, | |
| 86 &samplerate, &channels); | |
| 87 // else r = s->faacDecInit(s->faac_handle ... ); | |
| 88 | |
| 89 if (r < 0) | |
|
1602
fdb8244da1e5
av_log patch(2 of ?) by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1245
diff
changeset
|
90 av_log(avctx, AV_LOG_ERROR, "faacDecInit2 failed r:%d sr:%ld ch:%d s:%d\n", |
| 1245 | 91 r, samplerate, channels, avctx->extradata_size); |
| 92 | |
| 93 return r; | |
| 94 } | |
| 95 | |
| 96 static int faac_init_aac(AVCodecContext *avctx) | |
| 97 { | |
| 98 FAACContext *s = (FAACContext *) avctx->priv_data; | |
| 99 return 0; | |
| 100 } | |
| 101 | |
| 102 static int faac_decode_frame(AVCodecContext *avctx, | |
| 103 void *data, int *data_size, | |
| 104 uint8_t *buf, int buf_size) | |
| 105 { | |
| 106 FAACContext *s = (FAACContext *) avctx->priv_data; | |
| 107 faacDecFrameInfo frame_info; | |
| 108 void* out = s->faacDecDecode(s->faac_handle, &frame_info, (unsigned char*)buf); | |
| 109 //printf("DECODE FRAME %d, %d, %d - %p\n", buf_size, frame_info.samples, frame_info.bytesconsumed, out); | |
| 110 | |
| 111 if (frame_info.error > 0) { | |
|
1602
fdb8244da1e5
av_log patch(2 of ?) by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1245
diff
changeset
|
112 av_log(avctx, AV_LOG_ERROR, "faac: frame decodinf failed: %s\n", |
| 1245 | 113 s->faacDecGetErrorMessage(frame_info.error)); |
| 114 return 0; | |
| 115 } | |
| 116 | |
| 117 frame_info.samples *= s->sample_size; | |
| 118 memcpy(data, out, frame_info.samples); // CHECKME - can we cheat this one | |
| 119 | |
| 120 if (data_size) | |
| 121 *data_size = frame_info.samples; | |
| 122 | |
| 123 return (buf_size < (int)frame_info.bytesconsumed) | |
| 124 ? buf_size : (int)frame_info.bytesconsumed; | |
| 125 } | |
| 126 | |
| 127 static int faac_decode_end(AVCodecContext *avctx) | |
| 128 { | |
| 129 FAACContext *s = (FAACContext *) avctx->priv_data; | |
| 130 | |
| 131 if (s->faacDecClose) | |
| 132 s->faacDecClose(s->faac_handle); | |
| 133 | |
| 134 dlclose(s->handle); | |
| 135 return 0; | |
| 136 } | |
| 137 | |
| 138 static int faac_decode_init(AVCodecContext *avctx) | |
| 139 { | |
| 140 FAACContext *s = (FAACContext *) avctx->priv_data; | |
| 141 faacDecConfigurationPtr faac_cfg; | |
| 142 | |
| 143 #ifdef CONFIG_FAADBIN | |
| 144 const char* err = 0; | |
| 145 | |
| 146 s->handle = dlopen(libfaadname, RTLD_LAZY); | |
| 147 if (!s->handle) | |
| 148 { | |
|
1602
fdb8244da1e5
av_log patch(2 of ?) by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1245
diff
changeset
|
149 av_log(avctx, AV_LOG_ERROR, "FAAD library: %s could not be opened! \n%s\n", |
| 1245 | 150 libfaadname, dlerror()); |
| 151 return -1; | |
| 152 } | |
| 153 #define dfaac(a, b) \ | |
| 154 do { static const char* n = "faacDec" #a; \ | |
| 155 if ((s->faacDec ## a = b dlsym( s->handle, n )) == NULL) { err = n; break; } } while(0) | |
| 156 for(;;) { | |
| 157 #else /* !CONFIG_FAADBIN */ | |
| 158 #define dfaac(a, b) s->faacDec ## a = faacDec ## a | |
| 159 #endif /* CONFIG_FAADBIN */ | |
| 160 | |
| 161 // resolve all needed function calls | |
| 162 dfaac(Open, (faacDecHandle FAADAPI (*)(void))); | |
| 163 dfaac(GetCurrentConfiguration, (faacDecConfigurationPtr | |
| 164 FAADAPI (*)(faacDecHandle))); | |
| 165 dfaac(SetConfiguration, (unsigned char FAADAPI (*)(faacDecHandle, | |
| 166 faacDecConfigurationPtr))); | |
| 167 | |
| 168 dfaac(Init, (long FAADAPI (*)(faacDecHandle, unsigned char*, | |
| 169 unsigned long*, unsigned char*))); | |
| 170 dfaac(Init2, (char FAADAPI (*)(faacDecHandle, unsigned char*, | |
| 171 unsigned long, unsigned long*, | |
| 172 unsigned char*))); | |
| 173 dfaac(Close, (void FAADAPI (*)(faacDecHandle hDecoder))); | |
| 174 dfaac(Decode, (void* FAADAPI (*)(faacDecHandle, faacDecFrameInfo*, | |
| 175 unsigned char*))); | |
| 176 | |
| 177 dfaac(GetErrorMessage, (unsigned char* FAADAPI (*)(unsigned char))); | |
| 178 #undef dfacc | |
| 179 | |
| 180 #ifdef CONFIG_FAADBIN | |
| 181 break; | |
| 182 } | |
| 183 if (err) { | |
| 184 dlclose(s->handle); | |
|
1602
fdb8244da1e5
av_log patch(2 of ?) by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1245
diff
changeset
|
185 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot resolve %s in %s!\n", |
| 1245 | 186 err, libfaadname); |
| 187 return -1; | |
| 188 } | |
| 189 #endif | |
| 190 | |
| 191 s->faac_handle = s->faacDecOpen(); | |
| 192 if (!s->faac_handle) { | |
|
1602
fdb8244da1e5
av_log patch(2 of ?) by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1245
diff
changeset
|
193 av_log(avctx, AV_LOG_ERROR, "FAAD library: cannot create handler!\n"); |
| 1245 | 194 faac_decode_end(avctx); |
| 195 return -1; | |
| 196 } | |
| 197 | |
| 198 | |
| 199 faac_cfg = s->faacDecGetCurrentConfiguration(s->faac_handle); | |
| 200 | |
| 201 if (faac_cfg) { | |
| 202 switch (avctx->bits_per_sample) { | |
|
1602
fdb8244da1e5
av_log patch(2 of ?) by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents:
1245
diff
changeset
|
203 case 8: av_log(avctx, AV_LOG_ERROR, "FAADlib unsupported bps %d\n", avctx->bits_per_sample); break; |
| 1245 | 204 default: |
| 205 case 16: | |
| 206 faac_cfg->outputFormat = FAAD_FMT_16BIT; | |
| 207 s->sample_size = 2; | |
| 208 break; | |
| 209 case 24: | |
| 210 faac_cfg->outputFormat = FAAD_FMT_24BIT; | |
| 211 s->sample_size = 3; | |
| 212 break; | |
| 213 case 32: | |
| 214 faac_cfg->outputFormat = FAAD_FMT_32BIT; | |
| 215 s->sample_size = 4; | |
| 216 break; | |
| 217 } | |
| 218 | |
| 219 faac_cfg->defSampleRate = (!avctx->sample_rate) ? 44100 : avctx->sample_rate; | |
| 220 faac_cfg->defObjectType = LC; | |
| 221 } | |
| 222 | |
| 223 s->faacDecSetConfiguration(s->faac_handle, faac_cfg); | |
| 224 | |
| 225 faac_init_mp4(avctx); | |
| 226 | |
| 227 return 0; | |
| 228 } | |
| 229 | |
| 230 #define AAC_CODEC(id, name) \ | |
| 231 AVCodec name ## _decoder = { \ | |
| 232 #name, \ | |
| 233 CODEC_TYPE_AUDIO, \ | |
| 234 id, \ | |
| 235 sizeof(FAACContext), \ | |
| 236 faac_decode_init, \ | |
| 237 NULL, \ | |
| 238 faac_decode_end, \ | |
| 239 faac_decode_frame, \ | |
| 240 } | |
| 241 | |
| 242 // FIXME - raw AAC files - maybe just one entry will be enough | |
| 243 AAC_CODEC(CODEC_ID_AAC, aac); | |
| 244 // If it's mp4 file - usually embeded into Qt Mov | |
| 245 AAC_CODEC(CODEC_ID_MPEG4AAC, mpeg4aac); | |
| 246 | |
| 247 #undef AAC_CODEC |
