aac decoding!
need to work on seeking for AAC also, don't reset cb->begin on seek to 0, instead just set cb->end=cb->begin, works much better for disabling seeking (like ADIF AAC's) git-svn-id: https://svn.musicpd.org/mpd/trunk@356 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
		
							
								
								
									
										151
									
								
								src/aac_decode.c
									
									
									
									
									
								
							
							
						
						
									
										151
									
								
								src/aac_decode.c
									
									
									
									
									
								
							| @@ -2,8 +2,6 @@ | ||||
|  * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) | ||||
|  * This project's homepage is: http://www.musicpd.org | ||||
|  *  | ||||
|  * libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net> | ||||
|  *  | ||||
|  * 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 | ||||
| @@ -196,7 +194,11 @@ int initAacBuffer(char * file, AacBuffer * b, float * length) { | ||||
| 		if(*length!=0 && bitRate!=0) *length = *length*8.0/bitRate; | ||||
| 	} | ||||
|  | ||||
| 	if(*length<0) return -1; | ||||
| 	if(*length<0) { | ||||
| 		fclose(b->infile); | ||||
| 		if(b->buffer) free(b->buffer); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| @@ -215,59 +217,29 @@ int getAacTotalTime(char * file) { | ||||
|  | ||||
|  | ||||
| int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { | ||||
| 	/*FILE * fh; | ||||
| 	mp4ff_t * mp4fh; | ||||
| 	mp4ff_callback_t * mp4cb;  | ||||
| 	int32_t track; | ||||
| 	float time; | ||||
| 	int32_t scale; | ||||
| 	float totalTime; | ||||
| 	faacDecHandle decoder; | ||||
| 	faacDecFrameInfo frameInfo; | ||||
| 	faacDecConfigurationPtr config; | ||||
| 	unsigned char * mp4Buffer; | ||||
| 	int mp4BufferSize; | ||||
| 	size_t bread; | ||||
| 	unsigned long sampleRate; | ||||
| 	unsigned char channels; | ||||
| 	long sampleId; | ||||
| 	long numSamples; | ||||
| 	int eof = 0; | ||||
| 	long dur; | ||||
| 	unsigned int sampleCount; | ||||
| 	char * sampleBuffer; | ||||
| 	size_t sampleBufferLen; | ||||
| 	unsigned int initial = 1; | ||||
| 	int chunkLen = 0; | ||||
| 	float * seekTable; | ||||
| 	/*float * seekTable; | ||||
| 	long seekTableEnd = -1; | ||||
| 	int seekPositionFound = 0; | ||||
| 	long offset; | ||||
| 	int seekPositionFound = 0;*/ | ||||
| 	mpd_uint16 bitRate = 0; | ||||
| 	AacBuffer b; | ||||
|  | ||||
| 	fh = fopen(dc->file,"r"); | ||||
| 	if(!fh) { | ||||
| 		ERROR("failed to open %s\n",dc->file); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	printf("aac_decode!\n"); | ||||
|  | ||||
| 	mp4cb = malloc(sizeof(mp4ff_callback_t)); | ||||
| 	mp4cb->read = mp4_readCallback; | ||||
| 	mp4cb->seek = mp4_seekCallback; | ||||
| 	mp4cb->user_data = fh; | ||||
|  | ||||
| 	mp4fh = mp4ff_open_read(mp4cb); | ||||
| 	if(!mp4fh) { | ||||
| 		ERROR("Input does not appear to be a mp4 stream.\n"); | ||||
| 		free(mp4cb); | ||||
| 		fclose(fh); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	track = mp4_getAACTrack(mp4fh); | ||||
| 	if(track < 0) { | ||||
| 		ERROR("No AAC track found in mp4 stream.\n"); | ||||
| 		mp4ff_close(mp4fh); | ||||
| 		fclose(fh); | ||||
| 		free(mp4cb); | ||||
| 	if(initAacBuffer(dc->file,&b,&totalTime) < 0) { | ||||
| 		ERROR("Not AAC file no ADTS or ADIF headers found.\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| @@ -285,48 +257,33 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { | ||||
|  | ||||
| 	af->bits = 16; | ||||
|  | ||||
| 	mp4Buffer = NULL; | ||||
| 	mp4BufferSize = 0; | ||||
| 	mp4ff_get_decoder_config(mp4fh,track,&mp4Buffer,&mp4BufferSize); | ||||
|  | ||||
| 	if(faacDecInit2(decoder,mp4Buffer,mp4BufferSize,&sampleRate,&channels) | ||||
| 			< 0) | ||||
| 	fillAacBuffer(&b); | ||||
| 	if((bread = faacDecInit(decoder,b.buffer,b.bytesIntoBuffer, | ||||
| 			&sampleRate,&channels)) < 0) | ||||
| 	{ | ||||
| 		ERROR("Error initializing AAC decoder library.\n"); | ||||
| 		ERROR("Error not a AAC stream.\n"); | ||||
| 		faacDecClose(decoder); | ||||
| 		mp4ff_close(mp4fh); | ||||
| 		free(mp4cb); | ||||
| 		fclose(fh); | ||||
| 		fclose(b.infile); | ||||
| 		if(b.buffer) free(b.buffer); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	af->sampleRate = sampleRate; | ||||
| 	af->channels = channels; | ||||
| 	time = mp4ff_get_track_duration_use_offsets(mp4fh,track); | ||||
| 	scale = mp4ff_time_scale(mp4fh,track); | ||||
|  | ||||
| 	if(mp4Buffer) free(mp4Buffer); | ||||
|  | ||||
| 	if(scale < 0) { | ||||
| 		ERROR("Error getting audio format of mp4 AAC track.\n"); | ||||
| 		faacDecClose(decoder); | ||||
| 		mp4ff_close(mp4fh); | ||||
| 		fclose(fh); | ||||
| 		free(mp4cb); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	cb->totalTime = ((float)time)/scale; | ||||
|  | ||||
| 	numSamples = mp4ff_num_samples(mp4fh,track); | ||||
| 	cb->totalTime = totalTime+0.5; | ||||
|  | ||||
| 	dc->state = DECODE_STATE_DECODE; | ||||
| 	dc->start = 0; | ||||
| 	time = 0.0; | ||||
|  | ||||
| 	seekTable = malloc(sizeof(float)*numSamples); | ||||
| 	advanceAacBuffer(&b,bread); | ||||
| 	fillAacBuffer(&b); | ||||
|  | ||||
| 	for(sampleId=0; sampleId<numSamples && !eof; sampleId++) { | ||||
| 		if(dc->seek && seekTableEnd>1 &&  | ||||
| 	/*seekTable = malloc(sizeof(float)*numSamples);*/ | ||||
|  | ||||
| 	do { | ||||
| 		/*if(dc->seek && seekTableEnd>1 &&  | ||||
| 				seekTable[seekTableEnd]>=dc->seekWhere) | ||||
| 		{ | ||||
| 			int i = 2; | ||||
| @@ -335,9 +292,6 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { | ||||
| 			time = seekTable[sampleId]; | ||||
| 		} | ||||
|  | ||||
| 		dur = mp4ff_get_sample_duration(mp4fh,track,sampleId); | ||||
| 		offset = mp4ff_get_sample_offset(mp4fh,track,sampleId); | ||||
|  | ||||
| 		if(sampleId>seekTableEnd) { | ||||
| 			seekTable[sampleId] = time; | ||||
| 			seekTableEnd = sampleId; | ||||
| @@ -358,42 +312,36 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { | ||||
| 			dc->seek = 0; | ||||
| 		} | ||||
|  | ||||
| 		if(dc->seek) continue; | ||||
| 		 | ||||
| 		if(mp4ff_read_sample(mp4fh,track,sampleId,&mp4Buffer, | ||||
| 				&mp4BufferSize) == 0) | ||||
| 		{ | ||||
| 			eof = 1; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if(dc->seek) continue;*/ | ||||
|  | ||||
| 		if(dc->seek) { | ||||
| 			/*chunkLen = 0; | ||||
| 			cb->wrap = 0; | ||||
| 			cb->end = 0;*/ | ||||
| 			dc->seekError = 1; | ||||
| 			dc->seek = 0; | ||||
| 		} | ||||
| 		 | ||||
| 		sampleBuffer = faacDecDecode(decoder,&frameInfo,b.buffer, | ||||
| 						b.bytesIntoBuffer); | ||||
| 		advanceAacBuffer(&b,frameInfo.bytesconsumed); | ||||
|  | ||||
| 		sampleBuffer = faacDecDecode(decoder,&frameInfo,mp4Buffer, | ||||
| 						mp4BufferSize); | ||||
| 		if(mp4Buffer) free(mp4Buffer); | ||||
| 		if(frameInfo.error > 0) { | ||||
| 			eof = 1; | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		if(channels*(dur+offset) > frameInfo.samples) { | ||||
| 			dur = frameInfo.samples; | ||||
| 			offset = 0; | ||||
| 		} | ||||
|  | ||||
| 		sampleCount = (unsigned long)(dur*channels); | ||||
| 		sampleCount = (unsigned long)(frameInfo.samples); | ||||
|  | ||||
| 		if(sampleCount>0) { | ||||
| 			initial =0; | ||||
| 			bitRate = frameInfo.bytesconsumed*8.0* | ||||
| 				frameInfo.channels*scale/ | ||||
| 				frameInfo.channels*sampleRate/ | ||||
| 				frameInfo.samples/1024+0.5; | ||||
| 			time+= (float)(frameInfo.samples)/channels/sampleRate; | ||||
| 		} | ||||
| 			 | ||||
|  | ||||
| 		sampleBufferLen = sampleCount*2; | ||||
|  | ||||
| 		sampleBuffer+=offset*channels*2; | ||||
|  | ||||
| 		while(sampleBufferLen>0 && !dc->seek) { | ||||
| 			size_t size = sampleBufferLen>CHUNK_SIZE-chunkLen ?  | ||||
| 							CHUNK_SIZE-chunkLen: | ||||
| @@ -427,7 +375,11 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 		fillAacBuffer(&b); | ||||
|  | ||||
| 		if(b.bytesIntoBuffer==0) eof = 1; | ||||
| 	} while (!eof); | ||||
|  | ||||
| 	if(!dc->stop && !dc->seek && chunkLen>0) { | ||||
| 		cb->chunkSize[cb->end] = chunkLen; | ||||
| @@ -440,11 +392,10 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { | ||||
| 		chunkLen = 0; | ||||
| 	} | ||||
|  | ||||
| 	free(seekTable); | ||||
| 	/*free(seekTable);*/ | ||||
| 	faacDecClose(decoder); | ||||
| 	mp4ff_close(mp4fh); | ||||
| 	fclose(fh); | ||||
| 	free(mp4cb); | ||||
| 	fclose(b.infile); | ||||
| 	if(b.buffer) free(b.buffer); | ||||
|  | ||||
| 	if(dc->seek) dc->seek = 0; | ||||
|  | ||||
| @@ -452,7 +403,7 @@ int aac_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { | ||||
| 		dc->state = DECODE_STATE_STOP; | ||||
| 		dc->stop = 0; | ||||
| 	} | ||||
| 	else dc->state = DECODE_STATE_STOP;*/ | ||||
| 	else dc->state = DECODE_STATE_STOP; | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
|   | ||||
| @@ -2,8 +2,6 @@ | ||||
|  * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) | ||||
|  * This project's homepage is: http://www.musicpd.org | ||||
|  *  | ||||
|  * libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net> | ||||
|  *  | ||||
|  * 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 | ||||
|   | ||||
| @@ -86,7 +86,7 @@ int audiofile_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) | ||||
|  | ||||
| 		while(!eof) { | ||||
| 			if(dc->seek) { | ||||
| 				cb->end = 0; | ||||
| 				cb->end = cb->begin; | ||||
| 				cb->wrap = 0; | ||||
| 				current = dc->seekWhere * af->sampleRate; | ||||
| 				afSeekFrame(af_fp, AF_DEFAULT_TRACK,current); | ||||
|   | ||||
| @@ -40,6 +40,7 @@ | ||||
| #endif | ||||
| #ifdef HAVE_FAAD | ||||
| #include "mp4_decode.h" | ||||
| #include "aac_decode.h" | ||||
| #endif | ||||
|  | ||||
| #include <signal.h> | ||||
| @@ -159,11 +160,11 @@ void decodeSeek(PlayerControl * pc, AudioFormat * af, DecoderControl * dc, | ||||
| 						pc->totalTime-0.1 :  | ||||
| 						pc->seekWhere; | ||||
| 			dc->seekWhere = 0 > dc->seekWhere ? 0 : dc->seekWhere; | ||||
| 			cb->begin = 0; | ||||
| 			dc->seekError = 0; | ||||
| 			dc->seek = 1; | ||||
| 			pc->elapsedTime = dc->seekWhere; | ||||
| 			pc->bitRate = 0; | ||||
| 			while(*decode_pid>0 && dc->seek) usleep(1000); | ||||
| 			if(dc->seekError) pc->elapsedTime = dc->seekWhere; | ||||
| 		} | ||||
| 	} | ||||
| 	pc->seek = 0; | ||||
| @@ -229,6 +230,9 @@ int decoderInit(PlayerControl * pc, Buffer * cb, AudioFormat *af, | ||||
| 					break; | ||||
| #endif | ||||
| #ifdef HAVE_FAAD | ||||
| 				case DECODE_TYPE_AAC: | ||||
| 					dc->error = aac_decode(cb,af,dc); | ||||
| 					break; | ||||
| 				case DECODE_TYPE_MP4: | ||||
| 					dc->error = mp4_decode(cb,af,dc); | ||||
| 					break; | ||||
|   | ||||
							
								
								
									
										13
									
								
								src/decode.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								src/decode.h
									
									
									
									
									
								
							| @@ -21,6 +21,8 @@ | ||||
|  | ||||
| #include "../config.h" | ||||
|  | ||||
| #include "mpd_types.h" | ||||
|  | ||||
| #include <stdio.h> | ||||
| #include <sys/param.h> | ||||
|  | ||||
| @@ -38,11 +40,12 @@ | ||||
| #define DECODE_ERROR_UNKTYPE	1 | ||||
|  | ||||
| typedef struct _DecoderControl { | ||||
| 	int state; | ||||
| 	int stop; | ||||
| 	int start; | ||||
| 	int error; | ||||
| 	int seek; | ||||
| 	mpd_sint8 state; | ||||
| 	mpd_sint8 stop; | ||||
| 	mpd_sint8 start; | ||||
| 	mpd_uint16 error; | ||||
| 	mpd_sint8 seek; | ||||
| 	mpd_sint8 seekError; | ||||
| 	double seekWhere; | ||||
| 	char file[MAXPATHLEN+1]; | ||||
| } DecoderControl; | ||||
|   | ||||
| @@ -104,7 +104,7 @@ void flacPlayFile(char *file, Buffer * cb, AudioFormat * af, | ||||
| 		if(dc->seek) { | ||||
| 			FLAC__uint64 sampleToSeek = dc->seekWhere* | ||||
| 					af->sampleRate+0.5; | ||||
| 			cb->end = 0; | ||||
| 			cb->end = cb->begin; | ||||
| 			cb->wrap = 0; | ||||
| 			if(FLAC__file_decoder_seek_absolute(flacDec, | ||||
| 						sampleToSeek)) | ||||
|   | ||||
| @@ -487,7 +487,7 @@ int mp3Read(mp3DecodeData * data, Buffer * cb, DecoderControl * dc) { | ||||
| 		if(dc->seek) { | ||||
| 			long i = 0; | ||||
| 			cb->wrap = 0; | ||||
| 			cb->end = 0; | ||||
| 			cb->end = cb->begin; | ||||
| 			data->muteFrame = 1; | ||||
| 			while(i<data->highestFrame && dc->seekWhere > | ||||
| 					((float)mad_timer_count(data->times[i], | ||||
|   | ||||
| @@ -2,8 +2,6 @@ | ||||
|  * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) | ||||
|  * This project's homepage is: http://www.musicpd.org | ||||
|  *  | ||||
|  * libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net> | ||||
|  *  | ||||
|  * 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 | ||||
| @@ -149,7 +147,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { | ||||
| 	if(faacDecInit2(decoder,mp4Buffer,mp4BufferSize,&sampleRate,&channels) | ||||
| 			< 0) | ||||
| 	{ | ||||
| 		ERROR("Error initializing AAC decoder library.\n"); | ||||
| 		ERROR("Error not a AAC stream.\n"); | ||||
| 		faacDecClose(decoder); | ||||
| 		mp4ff_close(mp4fh); | ||||
| 		free(mp4cb); | ||||
| @@ -210,7 +208,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { | ||||
| 		if(dc->seek && seekPositionFound) { | ||||
| 			seekPositionFound = 0; | ||||
| 			chunkLen = 0; | ||||
| 			cb->end = 0; | ||||
| 			cb->end = cb->begin; | ||||
| 			cb->wrap = 0; | ||||
| 			dc->seek = 0; | ||||
| 		} | ||||
| @@ -233,7 +231,7 @@ int mp4_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) { | ||||
| 		} | ||||
|  | ||||
| 		if(channels*(dur+offset) > frameInfo.samples) { | ||||
| 			dur = frameInfo.samples; | ||||
| 			dur = frameInfo.samples/channels; | ||||
| 			offset = 0; | ||||
| 		} | ||||
|  | ||||
|   | ||||
| @@ -2,8 +2,6 @@ | ||||
|  * (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu) | ||||
|  * This project's homepage is: http://www.musicpd.org | ||||
|  *  | ||||
|  * libaudiofile (wave) support added by Eric Wong <normalperson@yhbt.net> | ||||
|  *  | ||||
|  * 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 | ||||
|   | ||||
| @@ -95,7 +95,7 @@ int ogg_decode(Buffer * cb, AudioFormat * af, DecoderControl * dc) | ||||
|  | ||||
| 		while(!eof) { | ||||
| 			if(dc->seek) { | ||||
| 				cb->end = 0; | ||||
| 				cb->end = cb->begin; | ||||
| 				cb->wrap = 0; | ||||
| 				chunkpos = 0; | ||||
| 				ov_time_seek_page(&vf,dc->seekWhere); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Warren Dukes
					Warren Dukes