📄 decoder.c
字号:
M24VAError eRtn = M24VAError_OK;
/* Transfer Data to Buffer, assumes alway one free location in buffer */
*g_M24VAState.sCMDSlavePort.pSPBuffer++ = ui32Data;
if(g_M24VAState.sCMDSlavePort.pSPBuffer >= g_M24VAState.sCMDSlavePort.pSPFlushThreshold)
{
AcquireMPEG();
eRtn = M24VA_SPBufferFlush(&g_M24VAState.sCMDSlavePort);
M24VA_SPBufferFlush(&g_M24VAState.sIZZSlavePort);
ReleaseMPEG();
}
return(eRtn);
}
/*****************************************************************************
FUNCTION : M24VA_WriteMCCmdBlock
PURPOSE : Write Motion compensation command datain batches
PARAMETERS :
RETURNS : M24VAError
Notes :
*****************************************************************************/
M24VAError PVRAPI M24VA_WriteMCCmdBlock(IMG_UINT32 *pui32Data,
IMG_UINT32 ui32Count)
{
M24VAError eRtn = M24VAError_OK;
register IMG_UINT32 *pui32Buffer = g_M24VAState.sCMDSlavePort.pSPBuffer;
register IMG_UINT32 *pui32Threshold = g_M24VAState.sCMDSlavePort.pSPFlushThreshold;
register IMG_UINT32 ui32LoopCount;
/* test to see if we will need to flush before the end of this block */
AcquireMPEG();
while(ui32Count)
{
if((pui32Buffer + ui32Count) >= pui32Threshold)
{
ui32LoopCount = pui32Threshold - pui32Buffer;
ui32Count -= ui32LoopCount;
}
else
{
ui32LoopCount = ui32Count;
ui32Count = 0;
}
while(ui32LoopCount--)
{
*pui32Buffer++ = *(pui32Data)++;
}
/* flush now rather than checking as we copy */
g_M24VAState.sCMDSlavePort.pSPBuffer = pui32Buffer;
eRtn = M24VA_SPBufferFlush(&g_M24VAState.sCMDSlavePort);
M24VA_SPBufferFlush(&g_M24VAState.sIZZSlavePort);
pui32Buffer = g_M24VAState.sCMDSlavePort.pSPBuffer;
}
ReleaseMPEG();
g_M24VAState.sCMDSlavePort.pSPBuffer = pui32Buffer;
return(eRtn);
}
/*****************************************************************************
FUNCTION : M24VA_WriteResidualDifferenceData
PURPOSE : Write Residual Difference Data
PARAMETERS :
RETURNS : M24VAError
Notes : pi16Data must be 32 bit aligned
*****************************************************************************/
M24VAError PVRAPI M24VA_WriteResidualDifferenceData(IMG_INT16 *pi16Data,
IMG_UINT32 ui32Count)
{
M24VAError eRtn = M24VAError_OK;
register IMG_UINT32 *pui32Buffer;
register IMG_UINT32 ui32LoopCount;
/* Transfer Data to Buffer */
ui32Count /= 2;
AcquireMPEG();
M24VA_SPBufferFlush(&g_M24VAState.sCMDSlavePort);
pui32Buffer = g_M24VAState.sIDCTSlavePort.pui32SlavePortLinAddr + g_M24VAState.sIDCTSlavePort.ui32SPAddOn;
g_M24VAState.sIDCTSlavePort.ui32SPAddOn = (g_M24VAState.sIDCTSlavePort.ui32SPAddOn + ui32Count) & SP_WRITE_MASK;
while(ui32Count)
{
if(g_M24VAState.sIDCTSlavePort.iu32SPFree == 0)
{
UpdateSPFreeCounters();
}
if( ui32Count >= g_M24VAState.sIDCTSlavePort.iu32SPFree)
{
ui32LoopCount = g_M24VAState.sIDCTSlavePort.iu32SPFree;
ui32Count -= ui32LoopCount;
}
else
{
ui32LoopCount = ui32Count;
ui32Count = 0;
}
if(ui32LoopCount)
{
g_M24VAState.sIDCTSlavePort.iu32SPFree-=ui32LoopCount;
while(ui32LoopCount--)
{
/* this code assumes that the pi16Data is 32 bit aligned */
*pui32Buffer++ = *((IMG_UINT32 *)pi16Data)++;
}
}
}
ReleaseMPEG();
return(eRtn);
}
/*****************************************************************************
FUNCTION : M24VA_SetIZZMode
PURPOSE :Set IZZ mode
PARAMETERS :
RETURNS : nothing
Notes :
*****************************************************************************/
#ifndef IMG_M24VAg
M24VAError PVRAPI M24VA_SetIZZMode(M24VA_IZZMODE eMode)
{
DWORD dwData;
switch(eMode)
{
case M24VA_ZigZagScanOrder: dwData = M24VA_IZZ_SCAN_ZIG_ZAG; break;
case M24VA_AltVertScanOrder: dwData = M24VA_IZZ_SCAN_ALT_VERT; break;
case M24VA_AltHorzScanOrder: dwData = M24VA_IZZ_SCAN_ALT_HORIZ; break;
case M24VA_RasterScanOrder: dwData = M24VA_IZZ_SCAN_RASTER; break;
default: return(M24VAError_GenericError);
}
dwData |= M24VA_IZZ_MODE_CHANGE;
return(M24VA_IZZ_SPBufferWrite(&dwData, 1));
}
#endif
/*****************************************************************************
FUNCTION : M24VA_WriteIZZData
PURPOSE :Write IZZ data
PARAMETERS :
RETURNS : nothing
Notes :
*****************************************************************************/
M24VAError PVRAPI M24VA_WriteIZZData(IMG_INT32 i32Coeff, IMG_UINT32 ui32Index, IMG_BOOL bEOB)
{
DWORD dwData = (i32Coeff << 16) | (ui32Index << 1) | (bEOB ? 1 : 0);
return(M24VA_IZZ_SPBufferWrite(&dwData, 1));
}
/*****************************************************************************
FUNCTION : M24VA_WriteIZZBlock
PURPOSE :Write a block of IZZ data
PARAMETERS :
RETURNS : nothing
Notes :
*****************************************************************************/
M24VAError PVRAPI M24VA_WriteIZZBlock(IMG_INT32 *pi32Data,
IMG_UINT32 ui32Count)
{
M24VAError eRtn = M24VAError_OK;
register IMG_UINT32 *pui32Buffer = g_M24VAState.sIZZSlavePort.pSPBuffer;
register IMG_UINT32 *pui32Threshold = g_M24VAState.sIZZSlavePort.pSPFlushThreshold;
register IMG_UINT32 ui32LoopCount;
/* Transfer Data to Buffer, assumes alway one free location in buffer */
AcquireMPEG();
while(ui32Count)
{
if((pui32Buffer + ui32Count) >= pui32Threshold)
{
ui32LoopCount = pui32Threshold - pui32Buffer;
ui32Count -= ui32LoopCount;
}
else
{
ui32LoopCount = ui32Count;
ui32Count = 0;
}
while(ui32LoopCount--)
{
*pui32Buffer++ = *pi32Data++;
}
/* now flush */
g_M24VAState.sIZZSlavePort.pSPBuffer = pui32Buffer;
M24VA_SPBufferFlush(&g_M24VAState.sCMDSlavePort);
eRtn = M24VA_SPBufferFlush(&g_M24VAState.sIZZSlavePort);
pui32Buffer = g_M24VAState.sIZZSlavePort.pSPBuffer;
}
ReleaseMPEG();
g_M24VAState.sIZZSlavePort.pSPBuffer = pui32Buffer;
return(eRtn);
}
/*****************************************************************************
FUNCTION : M24VA_FlushHardware
PURPOSE : Flush hardware of any pending MC commands
PARAMETERS :
RETURNS : nothing
Notes :
*****************************************************************************/
M24VAError PVRAPI M24VA_FlushHardware(IMG_BOOL bMCUnit, IMG_BOOL bFCUnit)
{
IMG_UINT32 ui32FlushIntMsk = 0;
M24VAError eError = M24VAError_OK;
/**************** Only do MC flush is dummy image write sent to hardware */
if(bMCUnit && g_M24VAState.bDummyImageWriteSent)
{
M24VA_WriteMCCmdData(M24VA_CMD_END_OF_FRAME); /* Trigger MC complete interrupt */
ui32FlushIntMsk |= M24VA_INTERRUPT_MC;
/* Flush IDCT and Command write buffers */
AcquireMPEG();
M24VA_SPBufferFlush(&g_M24VAState.sCMDSlavePort);
M24VA_SPBufferFlush(&g_M24VAState.sIZZSlavePort);
ReleaseMPEG();
}
if(bFCUnit && g_M24VAState.bFCInProgress)
{
ui32FlushIntMsk |= M24VA_INTERRUPT_YUVCONV;
}
#ifdef INIFINTELY_FAST_HW
return(eError);
#endif
/******************************************************** Flush hardware */
if(ui32FlushIntMsk)
{
int iPolls, iTrys;
IMG_UINT32 ui32Int;
DEBUG_MODE_ONLY(g_M24VAState.ui32FlushCount++);
for(iTrys = 10; iTrys; iTrys --)
{
AcquireMPEG();
for(iPolls = 100; iPolls; iPolls--)
{
DEBUG_MODE_ONLY(g_M24VAState.ui32InterruptPolls++);
ui32Int = M24VA_READREG(M24VAREG_INTERRUPT_STATUS) & (M24VA_INTERRUPT_MC | M24VA_INTERRUPT_YUVCONV);
if(ui32Int == ui32FlushIntMsk)
{
if(g_eScriptMode != M24VA_NoScript)
{
M24VA_PDUMP(("-- poll for completion \nPOL :REG:%08X %08X %08X\n",
M24VAREG_INTERRUPT_STATUS, M24VA_INTERRUPT_MASTER | ui32FlushIntMsk,
M24VA_INTERRUPT_MASTER | ui32FlushIntMsk));
}
M24VA_WRITEREG(M24VAREG_INTERRUPT_CLEAR,ui32FlushIntMsk, NULL); /* Clear interrupts */
if(ui32FlushIntMsk & M24VA_INTERRUPT_YUVCONV)
{
g_M24VAState.bFCInProgress = FALSE;
}
ReleaseMPEG();
return(M24VAError_OK);
}
}
ReleaseMPEG();
DEBUG_MODE_ONLY(g_M24VAState.ui32InterruptTrys++);
Sleep(1);
}
DEBUG_MODE_ONLY(g_M24VAState.ui32InterruptOverflows++);
eError = M24VAError_GenericError;
}
return(eError);
}
/*****************************************************************************
FUNCTION : M24VA_FrameConvert
PURPOSE : Convert output frame to either 422 or 24RGB
PARAMETERS :
RETURNS : M24VAError
Notes :
*****************************************************************************/
M24VAError PVRAPI M24VA_FrameConvert(SMSurface hDestSurface, SMSurface hSourSurface)
{
PINT_SM_HANDLE pDestSurface = (PINT_SM_HANDLE) hDestSurface;
PINT_SM_HANDLE pSourSurface = (PINT_SM_HANDLE) hSourSurface;
/******************************* Validate source and destination formats */
if(pSourSurface->eFormat != M24VA_SURF_FORMAT_420 ||
(pDestSurface->eFormat != M24VA_SURF_FORMAT_422 && pDestSurface->eFormat != M24VA_SURF_FORMAT_RGB24))
{
return(M24VAError_IncorrectSurfaceFormat);
}
/******************************************************** Convert to 422 */
/* Flush MC and FC units */
M24VA_FlushHardware(TRUE, TRUE);
AcquireMPEG();
if(pDestSurface->eFormat == M24VA_SURF_FORMAT_422)
{
M24VA_PDUMP(("-- Setting up YUV 420 to 422 conversion\n"));
M24VA_WRITEREG(M24VAREG_YUV_CONV_A,(DWORD)(pSourSurface->ui32FBOffset)>>M24VAREG_BASE_SHIFT,pSourSurface);
M24VA_WRITEREG(M24VAREG_YUV_CONV_B,(DWORD)(pDestSurface->ui32FBOffset)>>M24VAREG_BASE_SHIFT,pDestSurface);
M24VA_WRITEREG(M24VAREG_YUV_CONV_C,(pDestSurface->ui32Width << M24VA_YUV_C_WIDTH_SHIFT) |
(pDestSurface->ui32Height << M24VA_YUV_C_HGHT_SHIFT), NULL);
M24VA_WRITEREG(M24VAREG_YUV_CONV_D,((pSourSurface->ui32Stride>>3)<<M24VA_YUV_D_420_STRIDE_SHIFT) |
((pDestSurface->ui32Stride>>2)<<M24VA_YUV_D_422_STRIDE_SHIFT), NULL);
M24VA_WRITEREG(M24VAREG_YUV_CONV_STATE,M24VA_YUV_CONV_START_ENABLE, NULL);
}
/******************************************************** Convert to RGB */
else if(pDestSurface->eFormat == M24VA_SURF_FORMAT_RGB24)
{
M24VA_PDUMP(("-- Setting up YUV to RGB conversion\n"));
M24VA_WRITEREG(M24VAREG_YUV_CONV_A,(DWORD)(pSourSurface->ui32FBOffset)>>M24VAREG_BASE_SHIFT,pSourSurface);
M24VA_WRITEREG(M24VAREG_YUV_CONV_E,(DWORD)(pDestSurface->ui32FBOffset)>>M24VAREG_BASE_SHIFT,pDestSurface);
M24VA_WRITEREG(M24VAREG_YUV_CONV_C,(pDestSurface->ui32Width << M24VA_YUV_C_WIDTH_SHIFT) |
(pDestSurface->ui32Height << M24VA_YUV_C_HGHT_SHIFT), NULL);
M24VA_WRITEREG(M24VAREG_YUV_CONV_D,(pSourSurface->ui32Stride>>3)<<M24VA_YUV_D_420_STRIDE_SHIFT, NULL);
M24VA_WRITEREG(M24VAREG_YUV_CONV_F, pDestSurface->ui32Stride>>3, NULL);
M24VA_WRITEREG(M24VAREG_YUV_CONV_STATE,M24VA_YUV_CONV_START_ENABLE | M24VA_YUV_CONV_RGB_ENABLE, NULL);
}
ReleaseMPEG();
g_M24VAState.bFCInProgress = TRUE; /* Conversion in progress */
if(g_eScriptMode != M24VA_NoScript)
{
/* PDUMP mode always flush */
M24VA_FlushHardware(FALSE, TRUE);
}
return(M24VAError_OK);
}
/***********************************************************************************
Function Name : M24VA_MakeSMHandle
Inputs : pDDSurface
Outputs : phSurface
Returns : M24VAError
Description : This function is called by a DirectDraw application in order
to allocate and initialize an INT_SM_HANDLE.
************************************************************************************/
M24VAError PVRAPI M24VA_MakeSMHandle(SMSurface *phSurface,
LPDIRECTDRAWSURFACE4 pDDSurface)
{
IMG_UINT32 ui32PixelFormatValid = IMG_FALSE;
PINT_SM_HANDLE pSurface;
HRESULT hRet;
DDSURFACEDESC2 DDSurfaceDesc;
DDSurfaceDesc.dwSize = sizeof(DDSURFACEDESC2);
hRet = IDirectDrawSurface4_GetSurfaceDesc(pDDSurface, &DDSurfaceDesc);
if (hRet != DD_OK)
{
return M24VAError_GenericError;
}
/* Allocate INT_SM_HANDLE */
if((pSurface = (PINT_SM_HANDLE) malloc(sizeof(INT_SM_HANDLE))) == NULL)
{
return M24VAError_GenericError;
}
/* Get pointer to DirectDrawSurface */
pSurface->pDDSurface = pDDSurface;
/* Get surface width */
if ((DDSurfaceDesc.dwFlags & DDSD_WIDTH) && (DDSurfaceDesc.dwWidth == g_M24VAState.ui32Width))
{
pSurface->ui32Width = DDSurfaceDesc.dwWidth;
}
else
{
return M24VAError_GenericError;
}
/* Get surface height */
if ((DDSurfaceDesc.dwFlags & DDSD_HEIGHT) && (DDSurfaceDesc.dwHeight == g_M24VAState.ui32Height))
{
pSurface->ui32Height = DDSurfaceDesc.dwHeight;
}
else
{
return M24VAError_GenericError;
}
/* Get the surface stride */
if (DDSurfaceDesc.dwFlags & DDSD_PITCH)
{
pSurface->ui32Stride = DDSurfaceDesc.lPitch;
}
else
{
return M24VAError_GenericError;
}
/* Get pixel format */
if (DDSurfaceDesc.dwFlags & DDSD_PIXELFORMAT)
{
if (DDSurfaceDesc.ddpfPixelFormat.dwFlags & DDPF_FOURCC)
{
if (DDSurfaceDesc.ddpfPixelFormat.dwFourCC == MAKEFOURCC('I','M','C','2'))
{
pSurface->eFormat = M24VA_SURF_FORMAT_420;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -