1 #include <stdint.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #include <neaacdec.h>
6
7 #include <audacious/audtag.h>
8 #include <libaudcore/i18n.h>
9 #include <libaudcore/plugin.h>
10 #include <libaudcore/runtime.h>
11
12 class AACDecoder : public InputPlugin
13 {
14 public:
15 static const char * const exts[];
16 static const char * const mimes[];
17
18 static constexpr PluginInfo info = {
19 N_("AAC (Raw) Decoder"),
20 PACKAGE
21 };
22
AACDecoder()23 constexpr AACDecoder () : InputPlugin (info, InputInfo ()
24 .with_exts (exts)
25 .with_mimes (mimes)) {}
26
27 bool is_our_file (const char * filename, VFSFile & file);
28 bool read_tag (const char * filename, VFSFile & file, Tuple & tuple, Index<char> * image);
29 bool play (const char * filename, VFSFile & file);
30 };
31
32 EXPORT AACDecoder aud_plugin_instance;
33
34 const char * const AACDecoder::exts[] = {"aac", nullptr};
35 const char * const AACDecoder::mimes[] = {"audio/aac", nullptr};
36
37 /*
38 * BUFFER_SIZE is the highest amount of memory that can be pulled.
39 * We use this for sanity checks, among other things, as mp4ff needs
40 * a labotomy sometimes.
41 */
42 #define BUFFER_SIZE (FAAD_MIN_STREAMSIZE * 16)
43
44 /*
45 * These routines are derived from MPlayer.
46 */
47
48 /// \param srate (out) sample rate
49 /// \param num (out) number of audio frames in this ADTS frame
50 /// \return size of the ADTS frame in bytes
51 /// aac_parse_frames needs a buffer at least 8 bytes long
aac_parse_frame(unsigned char * buf,int * srate,int * num)52 int aac_parse_frame (unsigned char * buf, int *srate, int *num)
53 {
54 int i = 0, sr, fl = 0;
55 static int srates[] =
56 { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000,
57 11025, 8000, 0, 0, 0 };
58
59 if ((buf[i] != 0xFF) || ((buf[i + 1] & 0xF6) != 0xF0))
60 return 0;
61
62 /* We currently have no use for the id below.
63 id = (buf[i+1] >> 3) & 0x01; //id=1 mpeg2, 0: mpeg4
64 */
65 sr = (buf[i + 2] >> 2) & 0x0F;
66 if (sr > 11)
67 return 0;
68 *srate = srates[sr];
69
70 fl =
71 ((buf[i + 3] & 0x03) << 11) | (buf[i + 4] << 3) | ((buf[i +
72 5] >> 5) & 0x07);
73 *num = (buf[i + 6] & 0x02) + 1;
74
75 return fl;
76 }
77
78 #define PROBE_DEBUG(...)
79
80 /* Searches <length> bytes of data for an ADTS header. Returns the offset of
81 * the first header or -1 if none is found. Sets <size> to the length of the
82 * frame. */
find_aac_header(unsigned char * data,int length,int * size)83 static int find_aac_header (unsigned char * data, int length, int * size)
84 {
85 int offset, a, b;
86
87 for (offset = 0; offset <= length - 8; offset++)
88 {
89 if (data[offset] != 255)
90 continue;
91
92 *size = aac_parse_frame (data + offset, &a, &b);
93
94 if (*size < 8)
95 continue;
96
97 return offset;
98 }
99
100 return -1;
101 }
102
is_our_file(const char * filename,VFSFile & stream)103 bool AACDecoder::is_our_file (const char * filename, VFSFile & stream)
104 {
105 unsigned char data[8192];
106 int offset, found, inner, size;
107
108 size = 0; /* avoid bogus uninitialized variable warning */
109
110 if (stream.fread (data, 1, sizeof data) != sizeof data)
111 {
112 PROBE_DEBUG ("Read failed.\n");
113 return false;
114 }
115
116 offset = 0;
117
118 for (found = 0; found < 3; found++)
119 {
120 inner = find_aac_header (data + offset, sizeof data - offset, &size);
121
122 if (!(inner == 0 || (found == 0 && inner > 0)))
123 {
124 PROBE_DEBUG ("Only %d ADTS headers.\n", found);
125 return false;
126 }
127
128 offset += inner + size;
129 }
130
131 PROBE_DEBUG ("Accepted.\n");
132 return true;
133 }
134
135 /* Quick search for an ADTS or ADIF header in the first <len> bytes of <buf>.
136 * Returns the byte offset of the header or <len> if none is found. */
137
aac_probe(unsigned char * buf,int len)138 static int aac_probe (unsigned char * buf, int len)
139 {
140 for (int i = 0; i <= len - 4; i ++)
141 {
142 if ((buf[i] == 0xff && (buf[i + 1] & 0xf6) == 0xf0) || ! strncmp
143 ((char *) buf + i, "ADIF", 4))
144 return i;
145 }
146
147 return len;
148 }
149
150 /* Gets info (some approximated) from an AAC/ADTS file. <length> is
151 * milliseconds, <bitrate> is kilobits per second. Any parameters that cannot
152 * be read are set to -1. */
calc_aac_info(VFSFile & handle,int * length,int * bitrate,int * samplerate,int * channels)153 static void calc_aac_info (VFSFile & handle, int * length, int * bitrate,
154 int * samplerate, int * channels)
155 {
156 NeAACDecHandle decoder;
157 NeAACDecFrameInfo frame;
158 bool initted = false;
159 int size = handle.fsize ();
160 unsigned char buffer[BUFFER_SIZE];
161 int offset = 0, filled = 0;
162 int found, bytes_used = 0, time_used = 0;
163
164 decoder = nullptr; /* avoid bogus uninitialized variable warning */
165
166 *length = -1;
167 *bitrate = -1;
168 *samplerate = -1;
169 *channels = -1;
170
171 /* look for a representative bitrate in the middle of the file */
172 if (size < 0 || handle.fseek (size / 2, VFS_SEEK_SET) < 0)
173 goto DONE;
174
175 for (found = 0; found < 32; found++)
176 {
177 if (filled < BUFFER_SIZE / 2)
178 {
179 memmove (buffer, buffer + offset, filled);
180 offset = 0;
181
182 if (handle.fread (buffer + filled, 1, BUFFER_SIZE - filled)
183 != BUFFER_SIZE - filled)
184 {
185 PROBE_DEBUG ("Read failed.\n");
186 goto DONE;
187 }
188
189 filled = BUFFER_SIZE;
190 }
191
192 if (!initted)
193 {
194 int inner, a;
195 unsigned long r;
196 unsigned char ch;
197
198 inner = find_aac_header (buffer + offset, filled, &a);
199
200 if (inner < 0)
201 {
202 PROBE_DEBUG ("No ADTS header.\n");
203 goto DONE;
204 }
205
206 offset += inner;
207 filled -= inner;
208
209 decoder = NeAACDecOpen ();
210 inner = NeAACDecInit (decoder, buffer + offset, filled, &r, &ch);
211
212 if (inner < 0)
213 {
214 PROBE_DEBUG ("Decoder init failed.\n");
215 NeAACDecClose (decoder);
216 goto DONE;
217 }
218
219 offset += inner;
220 filled -= inner;
221 bytes_used += inner;
222
223 *samplerate = r;
224 *channels = ch;
225 initted = true;
226 }
227
228 if (NeAACDecDecode (decoder, &frame, buffer + offset, filled) == nullptr)
229 {
230 PROBE_DEBUG ("Decode failed.\n");
231 goto DONE;
232 }
233
234 if ((int)frame.samplerate != *samplerate || (int)frame.channels != *channels)
235 {
236 PROBE_DEBUG ("Parameter mismatch.\n");
237 goto DONE;
238 }
239
240 offset += frame.bytesconsumed;
241 filled -= frame.bytesconsumed;
242 bytes_used += frame.bytesconsumed;
243 time_used += frame.samples / frame.channels * (int64_t) 1000 /
244 frame.samplerate;
245 }
246
247 /* bits per millisecond = kilobits per second */
248 *bitrate = bytes_used * 8 / time_used;
249
250 if (size > 0)
251 *length = size * (int64_t) time_used / bytes_used;
252
253 DONE:
254 if (initted)
255 NeAACDecClose (decoder);
256 }
257
read_tag(const char * filename,VFSFile & file,Tuple & tuple,Index<char> * image)258 bool AACDecoder::read_tag (const char * filename, VFSFile & file, Tuple & tuple,
259 Index<char> * image)
260 {
261 int length, bitrate, samplerate, channels;
262
263 tuple.set_str (Tuple::Codec, "MPEG-2/4 AAC");
264
265 // TODO: error handling
266 calc_aac_info (file, &length, &bitrate, &samplerate, &channels);
267
268 if (length > 0)
269 tuple.set_int (Tuple::Length, length);
270 if (bitrate > 0)
271 tuple.set_int (Tuple::Bitrate, bitrate);
272 if (channels > 0)
273 tuple.set_int (Tuple::Channels, channels);
274
275 tuple.fetch_stream_info (file);
276
277 return true;
278 }
279
aac_seek(VFSFile & file,NeAACDecHandle dec,int time,int len,void * buf,int size,int * buflen)280 static void aac_seek (VFSFile & file, NeAACDecHandle dec, int time, int len,
281 void * buf, int size, int * buflen)
282 {
283 /* == ESTIMATE BYTE OFFSET == */
284
285 int64_t total = file.fsize ();
286 if (total < 0)
287 {
288 AUDERR ("File is not seekable.\n");
289 return;
290 }
291
292 /* == SEEK == */
293
294 if (file.fseek (total * time / len, VFS_SEEK_SET))
295 return;
296
297 * buflen = file.fread (buf, 1, size);
298
299 /* == FIND FRAME HEADER == */
300
301 int used = aac_probe ((unsigned char *) buf, * buflen);
302
303 if (used == * buflen)
304 {
305 AUDERR ("No valid frame header found.\n");
306 * buflen = 0;
307 return;
308 }
309
310 if (used)
311 {
312 * buflen -= used;
313 memmove (buf, (char *) buf + used, * buflen);
314 * buflen += file.fread ((char *) buf + * buflen, 1, size - * buflen);
315 }
316
317 /* == START DECODING == */
318
319 unsigned char chan;
320 unsigned long rate;
321
322 if ((used = NeAACDecInit (dec, (unsigned char *) buf, * buflen, & rate, & chan)))
323 {
324 * buflen -= used;
325 memmove (buf, (char *) buf + used, * buflen);
326 * buflen += file.fread ((char *) buf + * buflen, 1, size - * buflen);
327 }
328 }
329
play(const char * filename,VFSFile & file)330 bool AACDecoder::play (const char * filename, VFSFile & file)
331 {
332 NeAACDecHandle decoder = 0;
333 NeAACDecConfigurationPtr decoder_config;
334 unsigned long samplerate = 0;
335 unsigned char channels = 0;
336
337 Tuple tuple = get_playback_tuple ();
338 int bitrate = 1000 * aud::max (0, tuple.get_int (Tuple::Bitrate));
339
340 if ((decoder = NeAACDecOpen ()) == nullptr)
341 {
342 AUDERR ("Open Decoder Error\n");
343 return false;
344 }
345
346 decoder_config = NeAACDecGetCurrentConfiguration (decoder);
347 decoder_config->outputFormat = FAAD_FMT_FLOAT;
348 NeAACDecSetConfiguration (decoder, decoder_config);
349
350 /* == FILL BUFFER == */
351
352 unsigned char buf[BUFFER_SIZE];
353 int buflen;
354 buflen = file.fread (buf, 1, sizeof buf);
355
356 /* == SKIP ID3 TAG == */
357
358 if (buflen >= 10 && ! strncmp ((char *) buf, "ID3", 3))
359 {
360 int tagsize = 10 + (buf[6] << 21) + (buf[7] << 14) + (buf[8] << 7) + buf[9];
361
362 if (file.fseek (tagsize, VFS_SEEK_SET))
363 {
364 AUDERR ("Failed to seek past ID3v2 tag.\n");
365 goto ERR_CLOSE_DECODER;
366 }
367
368 buflen = file.fread (buf, 1, sizeof buf);
369 }
370
371 /* == FIND FRAME HEADER == */
372
373 int used;
374 used = aac_probe (buf, buflen);
375
376 if (used == buflen)
377 {
378 AUDERR ("No valid frame header found.\n");
379 goto ERR_CLOSE_DECODER;
380 }
381
382 if (used)
383 {
384 buflen -= used;
385 memmove (buf, buf + used, buflen);
386 buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
387 }
388
389 /* == START DECODING == */
390
391 if ((used = NeAACDecInit (decoder, buf, buflen, & samplerate, & channels)))
392 {
393 buflen -= used;
394 memmove (buf, buf + used, buflen);
395 buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
396 }
397
398 /* == CHECK FOR METADATA == */
399
400 if (tuple.fetch_stream_info (file))
401 set_playback_tuple (tuple.ref ());
402
403 set_stream_bitrate (bitrate);
404
405 /* == START PLAYBACK == */
406
407 open_audio (FMT_FLOAT, samplerate, channels);
408
409 /* == MAIN LOOP == */
410
411 while (! check_stop ())
412 {
413 /* == HANDLE SEEK REQUESTS == */
414
415 int seek_value = check_seek ();
416
417 if (seek_value >= 0)
418 {
419 int length = tuple.get_int (Tuple::Length);
420 if (length > 0)
421 aac_seek (file, decoder, seek_value, length, buf, sizeof buf, & buflen);
422 }
423
424 /* == CHECK FOR END OF FILE == */
425
426 if (! buflen)
427 break;
428
429 /* == CHECK FOR METADATA == */
430
431 if (tuple.fetch_stream_info (file))
432 set_playback_tuple (tuple.ref ());
433
434 /* == DECODE A FRAME == */
435
436 NeAACDecFrameInfo info;
437 void * audio = NeAACDecDecode (decoder, & info, buf, buflen);
438
439 if (info.error)
440 {
441 AUDERR ("%s.\n", NeAACDecGetErrorMessage (info.error));
442
443 if (buflen)
444 {
445 used = 1 + aac_probe (buf + 1, buflen - 1);
446 buflen -= used;
447 memmove (buf, buf + used, buflen);
448 buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
449 }
450
451 continue;
452 }
453
454 if ((used = info.bytesconsumed))
455 {
456 buflen -= used;
457 memmove (buf, buf + used, buflen);
458 buflen += file.fread (buf + buflen, 1, sizeof buf - buflen);
459 }
460
461 /* == PLAY THE SOUND == */
462
463 if (audio && info.samples)
464 write_audio (audio, sizeof (float) * info.samples);
465 }
466
467 NeAACDecClose (decoder);
468 return true;
469
470 ERR_CLOSE_DECODER:
471 NeAACDecClose (decoder);
472 return false;
473 }
474