www.pudn.com > tcpmp.src.0.72RC1.rar > faad.c, change:2006-01-19,size:9622b


/***************************************************************************** 
 * 
 * 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 
 * 
 * $Id: faad.c 598 2006-01-18 21:27:40Z picard $ 
 * 
 * The Core Pocket Media Player 
 * Copyright (c) 2004-2005 Gabor Kovacs 
 * 
 ****************************************************************************/ 
#include "../common/common.h" 
#include "faad.h" 
#include "faad2/include/neaacdec.h" 
#if SAFETAIL < 12 
#error Minimum 12 bytes tail needed in buffer 
#endif 
#define STACK_SIZE			0x20000 
#define MAX_CHANNELS		6  
#define BUFFER_NEEDED		(FAAD_MIN_STREAMSIZE * MAX_CHANNELS) 
#define HEADER_NEEDED		16384 
typedef struct faad 
{ 
	codec Codec; 
	buffer Buffer; 
	NeAACDecHandle Decoder; 
	bool_t ErrorMessage; 
	bool_t Inited; 
	bool_t PacketBased; 
	tick_t NextRefTime; 
	int FormatSet; 
	char* Stack; 
} faad; 
static int UpdateInput( faad* p ) 
{ 
	if (p->Decoder) 
	{ 
	    NeAACDecClose(p->Decoder); 
		p->Decoder = NULL; 
	} 
#ifdef SWAPSP2 
	if (p->Stack) 
	{ 
		int i; 
		for (i=0;i<STACK_SIZE;++i) 
			if (p->Stack[i] != 0x11) 
			{ 
				DebugMessage("Stack usage: %d",STACK_SIZE-i); 
				ThreadSleep(300); 
				break; 
			} 
	} 
	free(p->Stack); 
	p->Stack = NULL; 
#endif 
	p->Inited = 0; 
	p->ErrorMessage = 0; 
	BufferClear(&p->Buffer); 
	if (p->Codec.In.Format.Type == PACKET_AUDIO) 
	{ 
	    NeAACDecConfigurationPtr Config; 
		p->Decoder = NeAACDecOpen(); 
		Config = NeAACDecGetCurrentConfiguration(p->Decoder); 
		Config->defObjectType = LC; 
		Config->outputFormat = FAAD_FMT_INTERNAL; 
		Config->downMatrix = 1; // force downmix to stereo 
		NeAACDecSetConfiguration(p->Decoder, Config); 
		if (p->Codec.In.Format.ExtraLength) 
		{ 
			unsigned long SampleRate; 
			uint8_t Channels; 
		    if (NeAACDecInit2(p->Decoder, p->Codec.In.Format.Extra, p->Codec.In.Format.ExtraLength,  
				&SampleRate, &Channels) < 0) 
			{ 
				ShowError(p->Codec.Node.Class,AACFULL_ID,FAAD_NOT_SUPPORTED); 
				NeAACDecClose(p->Decoder); 
				p->Decoder = NULL; 
				return ERR_NOT_SUPPORTED; 
			} 
			p->Codec.In.Format.Format.Audio.SampleRate = SampleRate; 
			p->Codec.In.Format.Format.Audio.Channels = Channels; 
			p->Inited = 1; 
		} 
		PacketFormatPCM(&p->Codec.Out.Format,&p->Codec.In.Format,30); 
		p->Codec.Out.Format.Format.Audio.Flags = PCM_PLANES; 
		p->PacketBased = (p->Codec.In.Format.Format.Audio.Flags & PCM_PACKET_BASED) != 0; 
		p->FormatSet = 0; 
#ifdef SWAPSP2 
		p->Stack = malloc(STACK_SIZE); 
		if (!p->Stack) 
			return ERR_OUT_OF_MEMORY; 
		memset(p->Stack,0x11,STACK_SIZE); 
#endif 
	} 
	return ERR_NONE; 
} 
static NOINLINE int Process2( faad* p, const packet* Packet, const flowstate* State ) 
{ 
	bool_t Eof = !Packet && State; 
	if (Packet) 
	{ 
		// set new reftime 
		if (Packet->RefTime >= 0) 
		{ 
			if (p->PacketBased) 
			{ 
				p->Codec.Packet.RefTime = p->NextRefTime; 
				p->NextRefTime = Packet->RefTime; 
			} 
			else 
			{ 
				p->Codec.Packet.RefTime = Packet->RefTime; 
				if (p->Codec.In.Format.ByteRate>0) 
				{ 
					p->Codec.Packet.RefTime -= Scale(p->Buffer.WritePos - p->Buffer.ReadPos,TICKSPERSEC,p->Codec.In.Format.ByteRate); 
					if (p->Codec.Packet.RefTime<0) 
						p->Codec.Packet.RefTime=0; 
				} 
			} 
		} 
		// add new packet to buffer 
		BufferPack(&p->Buffer,0); 
		BufferWrite(&p->Buffer,Packet->Data[0],Packet->Length,2048); 
		if (!p->Inited) 
		{ 
			unsigned long SampleRate; 
			uint8_t Channels; 
			int Readed; 
			uint8_t* Buffer = p->Buffer.Data + p->Buffer.ReadPos; 
			int Length = p->Buffer.WritePos - p->Buffer.ReadPos; 
			if (!Eof && !p->PacketBased && Length < HEADER_NEEDED) 
				return ERR_NEED_MORE_DATA; 
			if (memcmp(Buffer, "ADIF", 4) == 0)  
			{ 
				int BitRate; 
				if (Buffer[4] & 0x80) // copyright_id present? 
					Buffer += 9; 
				BitRate = (((int)Buffer[4] & 0x0F) << 19) | 
						  ((int)Buffer[5] << 11) | 
						  ((int)Buffer[6] << 3) | 
						  ((int)Buffer[7] & 0xE0); 
				p->Codec.In.Format.ByteRate = BitRate/8; 
			} 
			else 
			{ 
				int Trash = 0; 
				for (Trash=0;Trash<Length-16;++Trash) 
					if (Buffer[Trash] == 0xFF && (Buffer[Trash+1] & 0xF6)==0xF0) 
						break; 
				if (Trash<Length-16) 
				{ 
					static const int SampleRates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0}; 
					int Samples = 0; 
					int Bytes = 0; 
					Buffer += Trash; 
					Length -= Trash; 
					SampleRate = SampleRates[(Buffer[2] & 0x3C) >> 2]; 
					// check for SBR profile, double samples ??? 
					while (Length > 7) 
					{ 
						int n; 
						if (Buffer[0] != 0xFF || (Buffer[1] & 0xF6)!=0xF0) 
							break; 
						n = (((int)Buffer[3] & 3) << 11) | (((int)Buffer[4]) << 3) | (Buffer[5] >> 5); 
						Bytes += n; 
						Samples += 1024;  
						Length -= n; 
						Buffer += n; 
					} 
					p->Codec.In.Format.ByteRate = Scale(Bytes,SampleRate,Samples); 
					if (Length < 256 || Samples >= 32*1024) // successfull 
						p->Buffer.ReadPos += Trash; 
 				} 
			} 
			Readed = NeAACDecInit(p->Decoder, p->Buffer.Data + p->Buffer.ReadPos, 
				p->Buffer.WritePos - p->Buffer.ReadPos, &SampleRate, &Channels); 
			if (Readed < 0) 
			{ 
				if (!p->ErrorMessage) 
				{ 
					ShowError(p->Codec.Node.Class,AACFULL_ID,FAAD_NOT_SUPPORTED); 
					p->ErrorMessage = 1; 
				} 
				BufferDrop(&p->Buffer); 
				return ERR_NOT_SUPPORTED; 
			} 
			p->Inited = 1; 
			p->Buffer.ReadPos += Readed; 
		} 
	} 
	else 
	if (p->Inited) 
		p->Codec.Packet.RefTime = TIME_UNKNOWN; 
	while ((p->PacketBased && Packet) || Eof || p->Buffer.WritePos >= p->Buffer.ReadPos+BUFFER_NEEDED) 
	{ 
	    NeAACDecFrameInfo FrameInfo; 
	    void* Buffer[16]; 
		int Size = p->Buffer.WritePos-p->Buffer.ReadPos; 
		if (Size <= 0) 
			break; 
        NeAACDecDecode2(p->Decoder, &FrameInfo,p->Buffer.Data+p->Buffer.ReadPos,Size,Buffer,MAX_INT); 
		if (p->PacketBased) 
			p->Buffer.ReadPos = p->Buffer.WritePos; 
		else 
			p->Buffer.ReadPos += FrameInfo.bytesconsumed; 
        if (!FrameInfo.error && FrameInfo.samples>0) 
		{ 
			if (p->Codec.Out.Format.Format.Audio.SampleRate != (int)FrameInfo.samplerate || 
				p->Codec.Out.Format.Format.Audio.Channels != (int)FrameInfo.channels) 
			{ 
				if (p->FormatSet && (p->Codec.Out.Format.Format.Audio.Channels!=1 || FrameInfo.channels!=2)) // allow PS mono->stereo 
				{ 
					p->FormatSet--; 
					break; // probably a bad frame, drop it 
				} 
				p->Codec.In.Format.Format.Audio.SampleRate =  
				p->Codec.Out.Format.Format.Audio.SampleRate = FrameInfo.samplerate; 
				p->Codec.In.Format.Format.Audio.Channels =  
				p->Codec.Out.Format.Format.Audio.Channels = FrameInfo.channels; 
				ConnectionUpdate(&p->Codec.Node,CODEC_OUTPUT,p->Codec.Out.Pin.Node,p->Codec.Out.Pin.No); 
			} 
			p->FormatSet = 16; // reset countdown 
			p->Codec.Packet.Length = FrameInfo.samples * sizeof(int32_t); 
			p->Codec.Packet.Data[0] = Buffer[0]; 
			p->Codec.Packet.Data[1] = Buffer[1]; 
			return ERR_NONE; 
		} 
		if (FrameInfo.error==28) 
		{ 
			BufferDrop(&p->Buffer); 
			return ERR_OUT_OF_MEMORY; 
		} 
		if (p->PacketBased) 
			break; 
		if (!FrameInfo.bytesconsumed) 
			p->Buffer.ReadPos++; 
	} 
	return ERR_NEED_MORE_DATA; 
} 
static int Process( faad* p, const packet* Packet, const flowstate* State ) 
{ 
	int Result; 
#ifdef SWAPSP2 
	void* Old = SwapSP(p->Stack+STACK_SIZE); 
#endif 
	Result = Process2(p,Packet,State); 
#ifdef SWAPSP2 
	SwapSP(Old); 
#endif 
	return Result; 
} 
extern void *faad_malloc(size_t size); 
uint8_t safestack(uint8_t (*decode)(NeAACDecHandle hDecoder, void *ics),NeAACDecHandle hDecoder, void *ics, void** stack) 
{ 
	uint8_t ret; 
#ifdef SWAPSP 
	void* old; 
	if (!*stack) 
	{ 
		*stack = faad_malloc(STACK_SIZE); 
		if (!*stack) 
			return 1; 
	} 
	old = SwapSP(*stack+STACK_SIZE); 
#endif 
	ret = decode(hDecoder,ics); 
#ifdef SWAPSP 
	SwapSP(old); 
#endif 
	return ret; 
} 
static int Flush(faad* p) 
{ 
	p->NextRefTime = TIME_UNKNOWN; 
	BufferDrop(&p->Buffer); 
	if (p->Decoder) 
		NeAACDecPostSeekReset(p->Decoder,0); 
	return ERR_NONE; 
} 
static int Create(faad* p) 
{ 
	p->Codec.Process = (packetprocess)Process; 
	p->Codec.UpdateInput = (nodefunc)UpdateInput; 
	p->Codec.Flush = (nodefunc)Flush; 
	return ERR_NONE; 
} 
static const nodedef FAAD =  
{ 
	sizeof(faad), 
#ifdef AACFULL_EXPORTS 
	AACFULL_ID, 
	CODEC_CLASS, 
	PRI_DEFAULT+256, 
#else 
	FAAD_ID, 
	CODEC_CLASS, 
	PRI_DEFAULT, 
#endif 
	(nodecreate)Create, 
}; 
static const nodedef AAC =  
{ 
	0, //parent size 
	AAC_ID, 
	RAWAUDIO_CLASS, 
#ifdef AACFULL_EXPORTS 
	PRI_DEFAULT-4, 
#else 
	PRI_DEFAULT-5, 
#endif 
}; 
void FAAD_Init() 
{ 
	NodeRegisterClass(&FAAD); 
	NodeRegisterClass(&AAC); 
} 
void FAAD_Done() 
{ 
	NodeUnRegisterClass(FAAD.Class); 
	NodeUnRegisterClass(AAC_ID); 
} 
#ifdef __SYMBIAN32__ 
uint32_t random_int2(void) 
{ 
    return rand()|(rand()<<16); 
} 
#endif 

2018无需申请注册送58体验金