📄 cem847x.c
字号:
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 + -