aac_plugin.c 11.2 KB
Newer Older
1
/* the Music Player Daemon (MPD)
2
 * Copyright (C) 2003-2007 by Warren Dukes (warren.dukes@gmail.com)
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * This project's homepage is: http://www.musicpd.org
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

19
#include "../decoder_api.h"
20
#include "config.h"
21 22 23

#define AAC_MAX_CHANNELS	6

24
#include <assert.h>
25
#include <unistd.h>
26
#include <faad.h>
27 28 29 30
#include <glib.h>

#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "aac"
31 32 33

/* all code here is either based on or copied from FAAD2's frontend code */
typedef struct {
Max Kellermann's avatar
Max Kellermann committed
34
	struct decoder *decoder;
35
	struct input_stream *inStream;
Max Kellermann's avatar
Max Kellermann committed
36 37 38
	size_t bytesIntoBuffer;
	size_t bytesConsumed;
	off_t fileOffset;
39
	unsigned char buffer[FAAD_MIN_STREAMSIZE * AAC_MAX_CHANNELS];
40 41
} AacBuffer;

42 43 44 45 46 47 48 49 50 51 52 53 54
static void aac_buffer_shift(AacBuffer * b, size_t length)
{
	assert(length >= b->bytesConsumed);
	assert(length <= b->bytesConsumed + b->bytesIntoBuffer);

	memmove(b->buffer, b->buffer + length,
		b->bytesConsumed + b->bytesIntoBuffer - length);

	length -= b->bytesConsumed;
	b->bytesConsumed = 0;
	b->bytesIntoBuffer -= length;
}

Avuton Olrich's avatar
Avuton Olrich committed
55 56
static void fillAacBuffer(AacBuffer * b)
{
57
	size_t rest, bread;
58

59 60 61 62 63
	if (b->bytesConsumed > 0)
		aac_buffer_shift(b, b->bytesConsumed);

	rest = sizeof(b->buffer) - b->bytesIntoBuffer;
	if (rest == 0)
64
		/* buffer already full */
65 66
		return;

67 68 69 70
	bread = decoder_read(b->decoder, b->inStream,
			     (void *)(b->buffer + b->bytesIntoBuffer),
			     rest);
	b->bytesIntoBuffer += bread;
71 72 73 74 75 76

	if ((b->bytesIntoBuffer > 3 && memcmp(b->buffer, "TAG", 3) == 0) ||
	    (b->bytesIntoBuffer > 11 &&
	     memcmp(b->buffer, "LYRICSBEGIN", 11) == 0) ||
	    (b->bytesIntoBuffer > 8 && memcmp(b->buffer, "APETAGEX", 8) == 0))
		b->bytesIntoBuffer = 0;
77 78
}

Max Kellermann's avatar
Max Kellermann committed
79
static void advanceAacBuffer(AacBuffer * b, size_t bytes)
Avuton Olrich's avatar
Avuton Olrich committed
80 81
{
	b->fileOffset += bytes;
82
	b->bytesConsumed = bytes;
Avuton Olrich's avatar
Avuton Olrich committed
83
	b->bytesIntoBuffer -= bytes;
84 85
}

86
static const unsigned adtsSampleRates[] =
Avuton Olrich's avatar
Avuton Olrich committed
87 88 89
    { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
	16000, 12000, 11025, 8000, 7350, 0, 0, 0
};
90

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
/**
 * Check whether the buffer head is an AAC frame, and return the frame
 * length.  Returns 0 if it is not a frame.
 */
static size_t adts_check_frame(AacBuffer * b)
{
	if (b->bytesIntoBuffer <= 7)
		return 0;

	/* check syncword */
	if (!((b->buffer[0] == 0xFF) && ((b->buffer[1] & 0xF6) == 0xF0)))
		return 0;

	return (((unsigned int)b->buffer[3] & 0x3) << 11) |
		(((unsigned int)b->buffer[4]) << 3) |
		(b->buffer[5] >> 5);
}

Max Kellermann's avatar
Max Kellermann committed
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
/**
 * Find the next AAC frame in the buffer.  Returns 0 if no frame is
 * found or if not enough data is available.
 */
static size_t adts_find_frame(AacBuffer * b)
{
	const unsigned char *p;
	size_t frame_length;

	while ((p = memchr(b->buffer, 0xff, b->bytesIntoBuffer)) != NULL) {
		/* discard data before 0xff */
		if (p > b->buffer)
			aac_buffer_shift(b, p - b->buffer);

		if (b->bytesIntoBuffer <= 7)
			/* not enough data yet */
			return 0;

		/* is it a frame? */
		frame_length = adts_check_frame(b);
		if (frame_length > 0)
			/* yes, it is */
			return frame_length;

		/* it's just some random 0xff byte; discard and and
		   continue searching */
		aac_buffer_shift(b, 1);
	}

	/* nothing at all; discard the whole buffer */
	aac_buffer_shift(b, b->bytesIntoBuffer);
	return 0;
}

143
static void adtsParse(AacBuffer * b, float *length)
Avuton Olrich's avatar
Avuton Olrich committed
144
{
Max Kellermann's avatar
Max Kellermann committed
145
	unsigned int frames, frameLength;
146
	unsigned sample_rate = 0;
147
	float framesPerSec;
148 149

	/* Read all frames to ensure correct time and bitrate */
Avuton Olrich's avatar
Avuton Olrich committed
150
	for (frames = 0;; frames++) {
151 152
		fillAacBuffer(b);

Max Kellermann's avatar
Max Kellermann committed
153
		frameLength = adts_find_frame(b);
154
		if (frameLength > 0) {
Avuton Olrich's avatar
Avuton Olrich committed
155
			if (frames == 0) {
156 157 158
				sample_rate = adtsSampleRates[(b->
							       buffer[2] & 0x3c)
							      >> 2];
159 160
			}

Avuton Olrich's avatar
Avuton Olrich committed
161 162
			if (frameLength > b->bytesIntoBuffer)
				break;
163

Avuton Olrich's avatar
Avuton Olrich committed
164 165 166
			advanceAacBuffer(b, frameLength);
		} else
			break;
167 168
	}

169
	framesPerSec = (float)sample_rate / 1024.0;
170
	if (framesPerSec > 0)
Avuton Olrich's avatar
Avuton Olrich committed
171
		*length = (float)frames / framesPerSec;
172 173
}

174 175 176
static void
initAacBuffer(AacBuffer * b, struct decoder *decoder,
	      struct input_stream *inStream)
177
{
Avuton Olrich's avatar
Avuton Olrich committed
178
	memset(b, 0, sizeof(AacBuffer));
179

Max Kellermann's avatar
Max Kellermann committed
180
	b->decoder = decoder;
181
	b->inStream = inStream;
182 183 184 185 186 187 188 189 190 191
}

static void aac_parse_header(AacBuffer * b, float *length)
{
	size_t fileread;
	size_t tagsize;

	if (length)
		*length = -1;

192
	fileread = b->inStream->size >= 0 ? b->inStream->size : 0;
193

194
	fillAacBuffer(b);
195 196

	tagsize = 0;
197
	if (b->bytesIntoBuffer >= 10 && !memcmp(b->buffer, "ID3", 3)) {
198
		tagsize = (b->buffer[6] << 21) | (b->buffer[7] << 14) |
Avuton Olrich's avatar
Avuton Olrich committed
199
		    (b->buffer[8] << 7) | (b->buffer[9] << 0);
200

Avuton Olrich's avatar
Avuton Olrich committed
201 202
		tagsize += 10;
		advanceAacBuffer(b, tagsize);
203 204 205
		fillAacBuffer(b);
	}

Avuton Olrich's avatar
Avuton Olrich committed
206 207
	if (length == NULL)
		return;
208

209 210
	if (b->inStream->seekable &&
	    b->bytesIntoBuffer >= 2 &&
211
	    (b->buffer[0] == 0xFF) && ((b->buffer[1] & 0xF6) == 0xF0)) {
212
		adtsParse(b, length);
213
		input_stream_seek(b->inStream, tagsize, SEEK_SET);
214

215
		b->bytesIntoBuffer = 0;
216 217
		b->bytesConsumed = 0;
		b->fileOffset = tagsize;
218 219

		fillAacBuffer(b);
Avuton Olrich's avatar
Avuton Olrich committed
220
	} else if (memcmp(b->buffer, "ADIF", 4) == 0) {
221 222 223
		unsigned bitRate;
		size_t skipSize = (b->buffer[4] & 0x80) ? 9 : 0;

224 225 226 227 228 229

		if (8 + skipSize > b->bytesIntoBuffer)
			/* not enough data yet; skip parsing this
			   header */
			return;

Avuton Olrich's avatar
Avuton Olrich committed
230 231 232 233 234 235 236 237 238 239 240 241 242
		bitRate =
		    ((unsigned int)(b->
				    buffer[4 +
					   skipSize] & 0x0F) << 19) | ((unsigned
									int)b->
								       buffer[5
									      +
									      skipSize]
								       << 11) |
		    ((unsigned int)b->
		     buffer[6 + skipSize] << 3) | ((unsigned int)b->buffer[7 +
									   skipSize]
						   & 0xE0);
243

244 245 246 247
		if (fileread != 0 && bitRate != 0)
			*length = fileread * 8.0 / bitRate;
		else
			*length = fileread;
248 249 250
	}
}

251
static float getAacFloatTotalTime(const char *file)
Avuton Olrich's avatar
Avuton Olrich committed
252
{
253 254
	AacBuffer b;
	float length;
255 256
	faacDecHandle decoder;
	faacDecConfigurationPtr config;
257 258 259 260 261
	uint32_t sample_rate;
#ifdef HAVE_FAAD_LONG
	/* neaacdec.h declares all arguments as "unsigned long", but
	   internally expects uint32_t pointers.  To avoid gcc
	   warnings, use this workaround. */
262
	unsigned long *sample_rate_r = (unsigned long *)(void *)&sample_rate;
263 264 265
#else
	uint32_t *sample_rate_r = &sample_rate;
#endif
266
	unsigned char channels;
267
	struct input_stream inStream;
268
	long bread;
269

270
	if (!input_stream_open(&inStream, file))
Avuton Olrich's avatar
Avuton Olrich committed
271
		return -1;
272

Max Kellermann's avatar
Max Kellermann committed
273
	initAacBuffer(&b, NULL, &inStream);
274
	aac_parse_header(&b, &length);
275

Avuton Olrich's avatar
Avuton Olrich committed
276
	if (length < 0) {
277 278 279 280
		decoder = faacDecOpen();

		config = faacDecGetCurrentConfiguration(decoder);
		config->outputFormat = FAAD_FMT_16BIT;
Avuton Olrich's avatar
Avuton Olrich committed
281
		faacDecSetConfiguration(decoder, config);
282 283

		fillAacBuffer(&b);
284
#ifdef HAVE_FAAD_BUFLEN_FUNCS
Avuton Olrich's avatar
Avuton Olrich committed
285
		bread = faacDecInit(decoder, b.buffer, b.bytesIntoBuffer,
286
				    sample_rate_r, &channels);
287
#else
288
		bread = faacDecInit(decoder, b.buffer, sample_rate_r, &channels);
289
#endif
290
		if (bread >= 0 && sample_rate > 0 && channels > 0)
Avuton Olrich's avatar
Avuton Olrich committed
291
			length = 0;
292 293 294

		faacDecClose(decoder);
	}
295

296
	input_stream_close(&inStream);
297

298 299 300
	return length;
}

301
static int getAacTotalTime(const char *file)
Avuton Olrich's avatar
Avuton Olrich committed
302
{
303
	int file_time = -1;
304 305
	float length;

Avuton Olrich's avatar
Avuton Olrich committed
306
	if ((length = getAacFloatTotalTime(file)) >= 0)
307
		file_time = length + 0.5;
308

309
	return file_time;
310 311
}

312
static void
313
aac_stream_decode(struct decoder *mpd_decoder, struct input_stream *inStream)
314 315 316 317 318 319 320
{
	float file_time;
	float totalTime = 0;
	faacDecHandle decoder;
	faacDecFrameInfo frameInfo;
	faacDecConfigurationPtr config;
	long bread;
321 322 323 324 325
	uint32_t sample_rate;
#ifdef HAVE_FAAD_LONG
	/* neaacdec.h declares all arguments as "unsigned long", but
	   internally expects uint32_t pointers.  To avoid gcc
	   warnings, use this workaround. */
326
	unsigned long *sample_rate_r = (unsigned long *)(void *)&sample_rate;
327 328 329
#else
	uint32_t *sample_rate_r = &sample_rate;
#endif
330 331 332 333
	unsigned char channels;
	unsigned int sampleCount;
	char *sampleBuffer;
	size_t sampleBufferLen;
334
	uint16_t bitRate = 0;
335
	AacBuffer b;
336
	bool initialized = false;
337
	enum decoder_command cmd;
338

Max Kellermann's avatar
Max Kellermann committed
339
	initAacBuffer(&b, mpd_decoder, inStream);
340
	aac_parse_header(&b, &totalTime);
341 342 343 344 345 346 347 348 349 350 351 352 353

	decoder = faacDecOpen();

	config = faacDecGetCurrentConfiguration(decoder);
	config->outputFormat = FAAD_FMT_16BIT;
#ifdef HAVE_FAACDECCONFIGURATION_DOWNMATRIX
	config->downMatrix = 1;
#endif
#ifdef HAVE_FAACDECCONFIGURATION_DONTUPSAMPLEIMPLICITSBR
	config->dontUpSampleImplicitSBR = 0;
#endif
	faacDecSetConfiguration(decoder, config);

354
	while (b.bytesIntoBuffer < sizeof(b.buffer) &&
355
	       !input_stream_eof(b.inStream) &&
356 357 358 359 360 361 362 363
	       decoder_get_command(mpd_decoder) == DECODE_COMMAND_NONE) {
	       	fillAacBuffer(&b);
		adts_find_frame(&b);
		fillAacBuffer(&b);
	}

#ifdef HAVE_FAAD_BUFLEN_FUNCS
	bread = faacDecInit(decoder, b.buffer, b.bytesIntoBuffer,
364
			    sample_rate_r, &channels);
365
#else
366
	bread = faacDecInit(decoder, b.buffer, sample_rate_r, &channels);
367 368
#endif
	if (bread < 0) {
369
		g_warning("Error not a AAC stream.\n");
370
		faacDecClose(decoder);
371
		return;
372 373 374 375 376 377
	}

	file_time = 0.0;

	advanceAacBuffer(&b, bread);

378
	do {
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393
		fillAacBuffer(&b);
		adts_find_frame(&b);
		fillAacBuffer(&b);

		if (b.bytesIntoBuffer == 0)
			break;

#ifdef HAVE_FAAD_BUFLEN_FUNCS
		sampleBuffer = faacDecDecode(decoder, &frameInfo, b.buffer,
					     b.bytesIntoBuffer);
#else
		sampleBuffer = faacDecDecode(decoder, &frameInfo, b.buffer);
#endif

		if (frameInfo.error > 0) {
394 395
			g_warning("error decoding AAC stream: %s\n",
				  faacDecGetErrorMessage(frameInfo.error));
396 397 398
			break;
		}
#ifdef HAVE_FAACDECFRAMEINFO_SAMPLERATE
399
		sample_rate = frameInfo.samplerate;
400 401 402
#endif

		if (!initialized) {
403 404 405 406 407 408
			const struct audio_format audio_format = {
				.bits = 16,
				.channels = frameInfo.channels,
				.sample_rate = sample_rate,
			};

409 410 411 412 413
			if (!audio_format_valid(&audio_format)) {
				g_warning("aac: invalid audio format\n");
				break;
			}

414 415
			decoder_initialized(mpd_decoder, &audio_format,
					    false, totalTime);
416
			initialized = true;
417 418 419 420 421 422 423 424
		}

		advanceAacBuffer(&b, frameInfo.bytesconsumed);

		sampleCount = (unsigned long)(frameInfo.samples);

		if (sampleCount > 0) {
			bitRate = frameInfo.bytesconsumed * 8.0 *
425
			    frameInfo.channels * sample_rate /
426 427 428
			    frameInfo.samples / 1000 + 0.5;
			file_time +=
			    (float)(frameInfo.samples) / frameInfo.channels /
429
			    sample_rate;
430 431 432 433
		}

		sampleBufferLen = sampleCount * 2;

434 435 436
		cmd = decoder_data(mpd_decoder, NULL, sampleBuffer,
				   sampleBufferLen, file_time,
				   bitRate, NULL);
437 438 439
		if (cmd == DECODE_COMMAND_SEEK)
			decoder_seek_error(mpd_decoder);
	} while (cmd != DECODE_COMMAND_STOP);
440 441 442 443

	faacDecClose(decoder);
}

444
static struct tag *aacTagDup(const char *file)
Avuton Olrich's avatar
Avuton Olrich committed
445
{
446
	int file_time = getAacTotalTime(file);
447
	struct tag *tag;
Warren Dukes's avatar
Warren Dukes committed
448

449
	if (file_time < 0) {
450 451
		g_debug("aacTagDup: Failed to get total song time from: %s\n",
			file);
452
		return NULL;
453
	}
Warren Dukes's avatar
Warren Dukes committed
454

455 456 457
	tag = tag_new();
	tag->time = file_time;
	return tag;
Warren Dukes's avatar
Warren Dukes committed
458 459
}

460 461
static const char *const aac_suffixes[] = { "aac", NULL };
static const char *const aac_mimeTypes[] = { "audio/aac", "audio/aacp", NULL };
Warren Dukes's avatar
Warren Dukes committed
462

463
const struct decoder_plugin aacPlugin = {
464 465 466 467 468
	.name = "aac",
	.stream_decode = aac_stream_decode,
	.tag_dup = aacTagDup,
	.suffixes = aac_suffixes,
	.mime_types = aac_mimeTypes
Warren Dukes's avatar
Warren Dukes committed
469
};