⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cem847x.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 5 页
字号:
		return E_NOT_SUPPORTED;	}		return Q_OK;}QRESULT CEM847xAB__SetAudioInOutConfig(IDecoder* pIDecoder,	EM847xAudioInOutConfigEnum AudioInOutConfig){	CQuasar *this = (CQuasar*) pIDecoder;	// Normal=I2SInv doesn't need EM847x frame inversion!	this->SerialCtrl0Config = Q3_ASctrl0_CkoutInverted | Q3_ASctrl0_MSbitfirst;	if(this->QuasarVersion == EM85XX_JASPER)		this->SerialCtrl1Config = 0x0200 | Q3_ASctrl1_Irclkin;// enable the divider	else		this->SerialCtrl1Config = 0x0000 | Q3_ASctrl1_Irclkin;	switch(AudioInOutConfig)	{	case I2SInv_SCkinSCIN_Jda1CkinGCK_ScinIN_DamckIN:	// Normal=I2SInv playback		break;	case I2S_SCkinSCIN_Jda1CkinGCK_ScinIN_DamckIN:		// I2S needs EM84xx frame inversion		this->SerialCtrl0Config |= Q3_ASctrl0_FrameInverted;		break;	case I2S_SCkinDAMCK_Jda1CkinGCK_ScinOUT_DamckIN:	// DAMCK in, JDA1 disabled		this->SerialCtrl1Config |= 0x0400;		break;	case I2S_SCkinJDA1CK_Jda1CkinGCK_ScinOUT_DamckOUT:	// I2S !		this->SerialCtrl0Config |= Q3_ASctrl0_FrameInverted;		this->SerialCtrl1Config |= 0x0800;		break;	case I2S_SCkinJDA1CK_Jda1CkinDAMCK_ScinOUT_DamckIN:	// I2S !		this->SerialCtrl0Config |= Q3_ASctrl0_FrameInverted;		this->SerialCtrl1Config |= 0x0c00;		break;	case JDA1_SCkinJDA1CK_Jda1CkinGCK_ScinOUT_DamckOUT:	// Jda1 normal playback		this->SerialCtrl1Config |= 0x1800;		break;	case JDA1_SCkinDAMCK_Jda1CkinGCK_ScinOUT_DamckIN:	// Jda1 playback using DAMCK for Sckin (capture)		this->SerialCtrl1Config |= 0x1400;		break;	case JDA1_SCkinJDA1CK_Jda1CkinDAMCK_ScinOUT_DamckIN:// Jda1 playback using VCXO(27M) or 1.5x(40M) speed for Jda1		this->SerialCtrl1Config |= 0x1C00;		break;	default:		return E_NOT_SUPPORTED;	}		return Q_OK;}QRESULT CEM847X__SetProperty( IDecoder* pIDecoder,	DWORD PropSet, DWORD PropId, DWORD Flags, void* pData, DWORD dwSizeIn, DWORD* pdwSizeOut){	CQuasar *this = (CQuasar*) pIDecoder;	Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ;	// DECODER use DWORD for changing information and size condition is already checked	DWORD Value = *(DWORD*)pData;	QDbgLog((QLOG_TRACE, QDebugLevelTrace,		TEXT("   --> CEM847X__SetProperty: set=%x id=%x flags=%x sz=%x value=%x"),		PropSet, PropId, Flags, dwSizeIn, Value));	switch(PropSet)	{	case DECODER_SET:		switch(PropId)		{		case edecAudioInOutConfig:		if( (this->QuasarVersion == EM848XA_Q4) || (this->QuasarVersion == EM847XC_Q4) )			return CEM847xC__SetAudioInOutConfig(pIDecoder, *(EM847xAudioInOutConfigEnum*)pData);		else			return CEM847xAB__SetAudioInOutConfig(pIDecoder, *(EM847xAudioInOutConfigEnum*)pData);		return E_NOT_SUPPORTED;		case edecOsdFlicker:			CQuasar__WaitForUpdateFlag(pIDecoder, pQ4->OSD_WinUpdateFlag.addr);			IDecoder_WriteDM(pIDecoder, pQ4->OSD_Phase.addr,				(IDecoder_ReadDM(pIDecoder, pQ4->OSD_Phase.addr) & ~0x0F00) | ((Value & 0xF)<<8) );			CQuasar__WriteDM(pIDecoder, pQ4->OSD_WinUpdateFlag.addr,1);			return Q_OK;		case edecVideoStd:			QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("edecVideoStd = %x"), Value));			IDecoder_WriteDM(pIDecoder, pQ4->VideoStd.addr, Value ? 1:0);			return Q_OK;		case edecForceFixedVOPRate:			CHECK_SIZE(edecForceFixedVOPRate)			this->FixedVopTimeIncrVal = ((edecForceFixedVOPRate_type*)pData)->dwFixedVopTimeIncr;	// def 1000			this->FixedTimeIncrResVal = ((edecForceFixedVOPRate_type*)pData)->dwFixedTimeIncrRes;	// def 24000			IDecoder_WriteDM(pIDecoder, pQ4->FixedVopTimeIncrVal.addr, ((edecForceFixedVOPRate_type*)pData)->dwFixedVopTimeIncr);	// def 1000			IDecoder_WriteDM(pIDecoder, pQ4->FixedTimeIncrResVal.addr, ((edecForceFixedVOPRate_type*)pData)->dwFixedTimeIncrRes);	// def 24000			IDecoder_WriteDM(pIDecoder, pQ4->ForceFixedVOPRate.addr, ((edecForceFixedVOPRate_type*)pData)->dwForceFixedVOPRate);	// force the video frame rate			return Q_OK;		case edecPciBurst:			/*The register to control the PCI burst length is at address 0x1FEC:			bit[2:0] min	max			000		 4		 4			001		 4		 8			010		 8		 8			011		 4		16			100		 8		16			101		16		16*/			QDbgLog((QLOG_TRACE, QDebugLevelError, TEXT("edecPciBurst = %x"), Value));			IDecoder_WriteReg(pIDecoder, QPM_Pci_Burst, Value);			return Q_OK;			break;		default:			return CQuasar__SetProperty(pIDecoder, PropSet, PropId, Flags, pData, dwSizeIn, pdwSizeOut);		}	default:		return CQuasar__SetProperty(pIDecoder, PropSet, PropId, Flags, pData, dwSizeIn, pdwSizeOut);	}	return Q_OK;}QRESULT CEM847X__GetProperty( IDecoder* pIDecoder,	DWORD PropSet, DWORD PropId, DWORD Flags, void* pData, DWORD dwSizeIn, DWORD* pdwSizeOut){	CQuasar *this = (CQuasar*) pIDecoder;	Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ;	// DECODER use DWORD for changing information and size condition is already checked	DWORD Value;	switch(PropId)	{	case edecOsdFlicker:		Value = (IDecoder_ReadDM(pIDecoder, pQ4->OSD_Phase.addr) & ~0x0F00)>>8;		break;	case edecVideoStd:		Value = IDecoder_ReadDM(pIDecoder, pQ4->VideoStd.addr);		break;	case edecForceFixedVOPRate:		CHECK_SIZE(edecForceFixedVOPRate)		((edecForceFixedVOPRate_type*)pData)->dwFixedVopTimeIncr = IDecoder_ReadDM(pIDecoder, pQ4->FixedVopTimeIncrVal.addr);		((edecForceFixedVOPRate_type*)pData)->dwFixedTimeIncrRes = IDecoder_ReadDM(pIDecoder, pQ4->FixedTimeIncrResVal.addr);		((edecForceFixedVOPRate_type*)pData)->dwForceFixedVOPRate = IDecoder_ReadDM(pIDecoder, pQ4->ForceFixedVOPRate.addr);		return Q_OK;	case edecPciBurst:		Value = IDecoder_ReadReg(pIDecoder, QPM_Pci_Burst);		break;	default:		return CQuasar__GetProperty(pIDecoder, PropSet, PropId, Flags, pData, dwSizeIn, pdwSizeOut);	}	*(DWORD*)pData = Value;	QDbgLog((QLOG_TRACE, QDebugLevelTrace,		TEXT("   <-- CEM847X__GetProperty: set=%x id=%x flags=%x sz=%x value=%x"),		PropSet, PropId, Flags, dwSizeIn, Value));	return Q_OK;}void CEM847X__InitPropertySet(IDecoder* pIDecoder, void* pPropSet, DWORD dwSize){	CQuasar *this = (CQuasar*) pIDecoder;	if(dwSize != sizeof(PROPERTY_SET_ITEM))		return;	InitPropSet(pIDecoder, pPropSet, DECODER_SET, edecMax,\		this->DecoderPropertyList, CEM847X__SetProperty, CEM847X__GetProperty)	// init some variables here	OSmemcpy(this->Horizontal4tapLumaCoef, Default4TapDisplayFilter, 32);	OSmemcpy(this->Horizontal4tapChromaCoef, Default4TapDisplayFilter, 32);	OSmemcpy(this->Vertical2tapLumaCoef, Default4TapDisplayFilter, 32);	OSmemcpy(this->Vertical2tapChromaCoef, Default4TapDisplayFilter, 32);	OSmemcpy(this->Vertical4tapLumaCoef, Default4TapDisplayFilter, 32);	OSmemcpy(this->Vertical4tapChromaCoef, Default4TapDisplayFilter, 32);}/********************************************************************************************/// new for Mpeg4void CEM847X__InitPtsFifo(IDecoder* pIDecoder, DWORD type){#define VPTS_ENTRIES_SIZE		4		// 16 bits words#define APTS_ENTRIES_SIZE		5		// 16 bits words#define SPTS_ENTRIES_SIZE		2		// 16 bits words	CQuasar *this = (CQuasar*) pIDecoder;	Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ;	PTS_FIFO* p = &this->PtsFifo[type];	switch (type)	{	case AUDIO:		p->Start = pQ4->Audio_PTSFifo.addr;		p->EntrySize = APTS_ENTRIES_SIZE;		p->Size = CQuasar__ReadDM(pIDecoder, pQ4->Audio_PTSSize.addr) / p->EntrySize;		break;	case SUBPICTURE:		p->Start = pQ4->SP_PTSFifo.addr;		p->EntrySize = SPTS_ENTRIES_SIZE;		p->Size = CQuasar__ReadDM(pIDecoder, pQ4->SP_PTSSize.addr) / p->EntrySize;		break;	case VIDEO:	default:		p->Start = pQ4->MV_PTSFifo.addr;		p->EntrySize = VPTS_ENTRIES_SIZE;		p->Size = CQuasar__ReadDM(pIDecoder, pQ4->MV_PTSSize.addr) / p->EntrySize;		break;	}	p->RdPtr = 0;	p->WrPtr = 0;	p->Emptiness = p->Size;	p->Fullness = 0;}DWORD CEM847X__PtsFifoEmptiness(IDecoder* pIDecoder, DWORD type){	CQuasar *this = (CQuasar*) pIDecoder;	Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ;	PTS_FIFO* p = &this->PtsFifo[type];	switch (type)	{	case AUDIO:		p->RdPtr = (CQuasar__ReadDM(pIDecoder, pQ4->Audio_PTSRdPtr.addr) - p->Start) / p->EntrySize;		break;	case SUBPICTURE:		p->RdPtr = (CQuasar__ReadDM(pIDecoder, pQ4->SP_PTSRdPtr.addr) - p->Start) / p->EntrySize;		break;	case VIDEO:	default:		p->RdPtr = (CQuasar__ReadDM(pIDecoder, pQ4->MV_PTSRdPtr.addr) - p->Start) / p->EntrySize;		break;	}	p->Emptiness = (p->Size + p->RdPtr - p->WrPtr - 1) % p->Size + 1;// number of empty entries	p->Fullness = p->Size - p->Emptiness;// number of non-empty entries	if( p->Emptiness == 1)	{		QDbgLog((QLOG_TRACE, QDebugLevelTrace, TEXT("EM847X_%s FifoPts E=%x F=%x Rd=%x Wr=%x"),			(type==AUDIO)?"A": (type==VIDEO)?"V":"S", p->Emptiness, p->Fullness, p->RdPtr, p->WrPtr ));	}	return p->Emptiness;}BOOL CEM847X__WritePTS(IDecoder* pIDecoder, DWORD type, DWORD ByteCount, MPEG_SCR PtsIn){	// Size, RdPtr, WrPtr are in "EntrySize" units, RdPtr, WrPtr are relative to Start	// I receive 32 bits for all types, VOPTimeIncrRes is on 16 bits only	CQuasar *this = (CQuasar*) pIDecoder;	Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ;	PTS_FIFO* p = &this->PtsFifo[type & HWLIB_DATA_TYPE_MASK];	int AbsoluteWrPtr = p->Start + p->EntrySize * p->WrPtr;	DWORD LoPts = DWORDLONG_Cast_DWORD(PtsIn);	DWORD HiPts = DWORDLONG_Cast_HIDWORD(PtsIn);	p->WrPtr = (p->WrPtr + 1)%p->Size;	switch (type & HWLIB_DATA_TYPE_MASK)	{	case SUBPICTURE:	// PtsIn has 45k unit		CQuasar__WriteDM(pIDecoder, AbsoluteWrPtr + 0, HIWORD(LoPts));		CQuasar__WriteDM(pIDecoder, AbsoluteWrPtr + 1, (LOWORD(LoPts)) | 1);	// enable new PTS entry		break;	case AUDIO:		CQuasar__WriteDM(pIDecoder, AbsoluteWrPtr + 0, HIWORD(ByteCount));		CQuasar__WriteDM(pIDecoder, AbsoluteWrPtr + 1, LOWORD(ByteCount));		// for both Mpeg1,2,4 receive last 32 bits (either 45k unit either VideoCts unit)		// and on bits 47..32 the fractional part for Mpeg4 and 0 for Mpeg1,2		CQuasar__WriteDM(pIDecoder, AbsoluteWrPtr + 2, HIWORD(LoPts));		CQuasar__WriteDM(pIDecoder, AbsoluteWrPtr + 3, LOWORD(LoPts) );		CQuasar__WriteDM(pIDecoder, AbsoluteWrPtr + 4, LOWORD(HiPts));		QDbgLog((QLOG_TRACE, QDebugLevelTrace,			TEXT("APts32.fr= %x_%04x.%04x n= %x"),			HIWORD(LoPts), LOWORD(LoPts), LOWORD(HiPts), ByteCount));		CQuasar__WriteDM(pIDecoder, pQ4->Audio_PTSWrPtr.addr, p->Start + p->WrPtr * p->EntrySize);		break;	case VIDEO:	default:		CQuasar__WriteDM(pIDecoder, AbsoluteWrPtr + 0, HIWORD(ByteCount));		CQuasar__WriteDM(pIDecoder, AbsoluteWrPtr + 1, LOWORD(ByteCount));		// for both Mpeg1,2,4 receive only 32 bits (either 45k unit either VideoCts unit)		CQuasar__WriteDM(pIDecoder, AbsoluteWrPtr + 2, HIWORD(LoPts));		CQuasar__WriteDM(pIDecoder, AbsoluteWrPtr + 3, LOWORD(LoPts) );		QDbgLog((QLOG_TRACE, QDebugLevelTrace,			TEXT("VPts32.fr= %x_%04x.0000 n= %x"),			HIWORD(LoPts), LOWORD(LoPts), ByteCount));		CQuasar__WriteDM(pIDecoder, pQ4->MV_PTSWrPtr.addr, p->Start + p->WrPtr * p->EntrySize);		break;	}	return TRUE;}QRESULT CEM847X__WritePCR(IDecoder* pIDecoder, MPEG_SCR PcrIn){	CQuasar *this = (CQuasar*) pIDecoder;	Q4SymbolTable* pQ4 = (Q4SymbolTable*)this->pQ;	// PcrIn has 45k unit	DWORD pcr = DWORDLONG_Cast_DWORD(PcrIn);	if( IDecoder_ReadDM(pIDecoder, pQ4->PCR_Frac.addr) == 0 )	{		IDecoder_WriteDM(pIDecoder, pQ4->PCR_Hi.addr, HIWORD(pcr) );		IDecoder_WriteDM(pIDecoder, pQ4->PCR_Lo.addr, LOWORD(pcr) );		IDecoder_WriteDM(pIDecoder, pQ4->PCR_Frac.addr, 1 );		return Q_OK;	}	return Q_FAIL;}/********************************************************************************************//****f* HwLib/IDecoder_SetPIODir * USAGE *	QRESULT IDecoder_SetPIODir(IDecoder* pIDecoder, DWORD PIONumber, DWORD Dir) *	QRESULT CEM840X__SetPIODir(IDecoder* pIDecoder, DWORD PIONumber, DWORD Dir) *	QRESULT CEM847X__SetPIODir(IDecoder* pIDecoder, DWORD PIONumber, DWORD Dir) * DESCRIPTION *	EM840x has 8 input/output pins PIOs *	EM847x has 16 input/output pins PIOs *	IDecoder_SetPIODir sets the direction(input or output) of PIONumber pin. * PARAMETERS *	IN IDecoder* pIDecoder - pointer to the decoder object *	IN DWORD PIONumber - one of PIO0 ... PIO15. *	IN DWORD Dir - TRUE means output, FALSE input. * RETURN VALUE *	The return value is Q_FAIL if PIONumber is greater then the maximum number of PIOs supported./********************************************************************************************/QRESULT CEM847X__SetPIODir(IDecoder* pIDecoder, DWORD PIONumber, DWORD Dir){	CQuasar *this = (CQuasar*) pIDecoder;	if(PIONumber < 8)	{		CQuasar__WriteReg(pIDecoder, this->Pio07DirReg,			((Dir ? 0x0101:0x0100) << PIONumber) );	}	else	{		CQuasar__WriteReg(pIDecoder, this->Pio8fDirReg,			((Dir ? 0x0101:0x0100) << (PIONumber-8)) );	}	return Q_OK;}/****f* HwLib/IDecoder_WritePIO * USAGE *	QRESULT IDecoder_WritePIO(IDecoder* pIDecoder, DWORD PIONumber, DWORD Data) *	QRESULT CEM840X__WritePIO(IDecoder* pIDecoder, DWORD PIONumber, DWORD Data) *	QRESULT CEM847X__WritePIO(IDecoder* pIDecoder, DWORD PIONumber, DWORD Data) * DESCRIPTION *	EM840x has 8 input/output pins PIOs *	EM847x has 16 input/output pins PIOs *	IDecoder_WritePIO sets "Data" value for pin "PIONumber" and sets the direction to output. * PARAMETERS *	IN IDecoder* pIDecoder - pointer to the decoder object *	IN DWORD PIONumber - one of PIO0 ... PIO15. *	IN DWORD Data - 1 means high level, 0 means low level for PIO. * RETURN VALUE *	The return value is Q_FAIL if PIONumber is greater then the maximum number of PIOs supported./********************************************************************************************/QRESULT CEM847X__WritePIO(IDecoder* pIDecoder, DWORD PIONumber, DWORD Data){	CQuasar *this = (CQuasar*) pIDecoder;	QDbgLog((QLOG_TRACE, QDebugLevelTrace, TEXT("   PIO%d set to %d"), PIONumber, Data ));	// don't assume that PIO is output	if(PIONumber < 8)	{		CQuasar__WriteReg(pIDecoder, this->Pio07DataReg,			((Data? 0x0101:0x0100) << PIONumber));		CQuasar__WriteReg(pIDecoder, this->Pio07DirReg,			(0x0101 << PIONumber));	}	else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -