📄 pfclass.cpp
字号:
PF_FUNCTION_ENTRY();
// PF must have been configured at least once
// in order to start the channel
if (!m_bConfigured)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Error. Cannot start post-processing channel without first configuring\r\n"),
__WFUNCTION__));
return FALSE;
}
if (m_bRunning)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Viewfinding channel already running.\r\n"), __WFUNCTION__));
return TRUE;
}
m_bRunning = TRUE;
// Reset EOF event, in case stale EOF events were triggered,
// which would cause Pin to believe a frame was ready.
ResetEvent(m_hEOFEvent);
if (m_pfMode == pfMode_H264Deblock) // H.264 requires output buffer equal to input
{
pStartParms->out = pStartParms->in;
if (pStartParms->h264_pause_row != 0)
{
// Enable and set up pause row
INSREG32BF(&P_IPU_REGS->PF_CONF, IPU_PF_CONF_H264_Y_PAUSE_EN,
IPU_PF_CONF_H264_Y_PAUSE_EN_ENABLE);
INSREG32BF(&P_IPU_REGS->PF_CONF, IPU_PF_CONF_H264_Y_PAUSE_ROW,
pStartParms->h264_pause_row);
m_bPauseEnabled = TRUE;
}
else
{
// Disable pause row
INSREG32BF(&P_IPU_REGS->PF_CONF, IPU_PF_CONF_H264_Y_PAUSE_EN,
IPU_PF_CONF_H264_Y_PAUSE_EN_DISABLE);
m_bPauseEnabled = FALSE;
}
}
else
{
// Disable pause row
INSREG32BF(&P_IPU_REGS->PF_CONF, IPU_PF_CONF_H264_Y_PAUSE_EN,
IPU_PF_CONF_H264_Y_PAUSE_EN_DISABLE);
m_bPauseEnabled = FALSE;
}
// Protect access to IPU_INT_CTRL_1 and IDMAC_CHA_EN registers.
// Compute bitmask and shifted bit value for IPU_INT_CTRL_1 register
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAPF_5)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_6)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_7);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAPF_5, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_6, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_7, IPU_ENABLE);
// enable IPU interrupts for channels 29, 30, 31 (PF Y, U, and V Output)
do
{
oldVal = INREG32(&P_IPU_REGS->IPU_INT_CTRL_1);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_INT_CTRL_1,
oldVal, newVal) != oldVal);
// Compute bitmask and shifted bit value for IDMAC enable register.
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAPF_0)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_2)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_3)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_4)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_5)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_6)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_7);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAPF_0, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_2, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_3, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_4, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_5, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_6, IPU_ENABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_7, IPU_ENABLE);
if (m_pfMode == pfMode_H264Deblock)
{
iMask |= CSP_BITFMASK(IPU_DMA_CHA_DMAPF_1);
iBitval |= CSP_BITFVAL(IPU_DMA_CHA_DMAPF_1, IPU_ENABLE);
}
// Set the bits to enable the IDMAC channels.
do
{
oldVal = INREG32(&P_IPU_REGS->IDMAC_CHA_EN);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IDMAC_CHA_EN,
oldVal, newVal) != oldVal);
iInputYBufPtr = (UINT32)pStartParms->in->yBufPtr;
iInputUBufPtr = iInputYBufPtr + pStartParms->in->uOffset;
iInputVBufPtr = iInputYBufPtr + pStartParms->in->vOffset;
// Program input Y, U, and V buffers into channel parameter memory
controlledWriteDMAChannelParam(PF_Y_INPUT_DMA_CHANNEL, 1, 0, iInputYBufPtr); //Buffer 0 31-0
controlledWriteDMAChannelParam(PF_U_INPUT_DMA_CHANNEL, 1, 0, (unsigned int)iInputUBufPtr); //Buffer 0 31-0
controlledWriteDMAChannelParam(PF_V_INPUT_DMA_CHANNEL, 1, 0, (unsigned int)iInputVBufPtr); //Buffer 0 31-0
iOutputYBufPtr = (UINT32)pStartParms->out->yBufPtr;
iOutputUBufPtr = iOutputYBufPtr + pStartParms->out->uOffset;
iOutputVBufPtr = iOutputYBufPtr + pStartParms->out->vOffset;
// Program output Y, U, and V buffers into channel parameter memory
controlledWriteDMAChannelParam(PF_Y_OUTPUT_DMA_CHANNEL, 1, 0, (unsigned int)iOutputYBufPtr); //Buffer 0 31-0
controlledWriteDMAChannelParam(PF_U_OUTPUT_DMA_CHANNEL, 1, 0, (unsigned int)iOutputUBufPtr); //Buffer 0 31-0
controlledWriteDMAChannelParam(PF_V_OUTPUT_DMA_CHANNEL, 1, 0, (unsigned int)iOutputVBufPtr); //Buffer 0 31-0
dumpIpuRegisters(P_IPU_REGS);
// Buffers ready for all PF DMA Channels
SETREG32(&P_IPU_REGS->IPU_CHA_BUF0_RDY,
CSP_BITFVAL(IPU_DMA_CHA_DMAPF_0, IPU_DMA_CHA_READY) |
CSP_BITFVAL(IPU_DMA_CHA_DMAPF_2, IPU_DMA_CHA_READY) |
CSP_BITFVAL(IPU_DMA_CHA_DMAPF_3, IPU_DMA_CHA_READY) |
CSP_BITFVAL(IPU_DMA_CHA_DMAPF_4, IPU_DMA_CHA_READY) |
CSP_BITFVAL(IPU_DMA_CHA_DMAPF_5, IPU_DMA_CHA_READY) |
CSP_BITFVAL(IPU_DMA_CHA_DMAPF_6, IPU_DMA_CHA_READY) |
CSP_BITFVAL(IPU_DMA_CHA_DMAPF_7, IPU_DMA_CHA_READY));
if (m_pfMode == pfMode_H264Deblock)
{
SETREG32(&P_IPU_REGS->IPU_CHA_BUF0_RDY,
CSP_BITFVAL(IPU_DMA_CHA_DMAPF_1, IPU_DMA_CHA_READY));
}
PF_FUNCTION_EXIT();
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: PfResume
//
// This function resumes the Postfilter operation after pausingstarts the post-filtering channel.
//
// Parameters:
// h264_pause_row
// [in] Specifies a new pause row for the h264 postfilter operation. This pause row
// must be greater than the original pause row in order to pause the operation. Set
// this parameter to 0 to disable pausing.
//
// Returns:
// TRUE if success
// FALSE if failure
//
//-----------------------------------------------------------------------------
DWORD PfClass::PfResume(UINT32 h264_pause_row) // Row to pause at for H.264 mode. 0 to disable pause)
{
// Only resume if we are running and were paused
if (!m_bRunning)
{
// return error since Postfilter is not running
return PF_ERR_NOT_RUNNING;
}
else if (!m_bPauseEnabled)
{
// return error since pause is not enabled
return PF_ERR_PAUSE_NOT_ENABLED;
}
else
{
if (h264_pause_row != 0)
{
if ((h264_pause_row > PF_MAX_PAUSE_ROW) || (h264_pause_row < 0))
{
// return error since pause row value is not in a valid range
return PF_ERR_INVALID_PARAMETER;
}
// Enable and set up pause row
INSREG32BF(&P_IPU_REGS->PF_CONF, IPU_PF_CONF_H264_Y_PAUSE_ROW,
h264_pause_row);
m_bPauseEnabled = TRUE;
}
else
{
// Disable pause row
INSREG32BF(&P_IPU_REGS->PF_CONF, IPU_PF_CONF_H264_Y_PAUSE_EN,
IPU_PF_CONF_H264_Y_PAUSE_EN_DISABLE);
m_bPauseEnabled = FALSE;
}
}
return PF_SUCCESS;
}
//-----------------------------------------------------------------------------
//
// Function: PfStopChannel
//
// This function halts the post-filtering channels.
//
// Parameters:
// None.
//
// Returns:
// TRUE if success
// FALSE if failure
//
//-----------------------------------------------------------------------------
BOOL PfClass::PfStopChannel(void)
{
UINT32 uTempReg, uTempReg1, uCount = 0;
UINT32 oldVal, newVal, iMask, iBitval;
PF_FUNCTION_ENTRY();
// If not running, return
if (m_bRunning == FALSE)
{
return TRUE;
}
m_bRunning = FALSE;
// initalize ... for the first time through
uTempReg = INREG32(&P_IPU_REGS->IDMAC_CHA_BUSY);
uTempReg1 = INREG32(&P_IPU_REGS->IPU_CHA_BUF0_RDY);
// We can't disable tasks until the active channels
// have completed their current frames. Make sure
// that buffers aren't set as ready (indicating that
// they are yet to start) and that channels are
// not busy (indicating that channels are still running).
while ((uTempReg1 & 0xFE000000) || (uTempReg & 0xFE000000))
{
if (uCount <= 1000)
{
//..give up the remainder of time slice
Sleep(1);
uCount++;
//.. need to check after the sleep delay
uTempReg = INREG32(&P_IPU_REGS->IDMAC_CHA_BUSY);
uTempReg1 = INREG32(&P_IPU_REGS->IPU_CHA_BUF0_RDY);
}
else
{
//.. there is something wrong ....break out
DEBUGMSG(ZONE_ERROR,
(TEXT("%s(): Error in stopping PF channel!\r\n"), __WFUNCTION__));
break;
}
}
ResetEvent(m_hEOFEvent);
// Protect access to IDMAC_CHA_EN and IPU_INT_CTRL_1 registers.
// Compute bitmask and shifted bit value for IDMAC enable register.
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAPF_0)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_1)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_2)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_3)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_4)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_5)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_6)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_7);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAPF_0, IPU_DISABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_1, IPU_DISABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_2, IPU_DISABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_3, IPU_DISABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_4, IPU_DISABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_5, IPU_DISABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_6, IPU_DISABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_7, IPU_DISABLE);
// Use interlocked function to disable the IDMAC channels.
do
{
oldVal = INREG32(&P_IPU_REGS->IDMAC_CHA_EN);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IDMAC_CHA_EN,
oldVal, newVal) != oldVal);
// Compute bitmask and shifted bit value for INT CTRL register.
iMask = CSP_BITFMASK(IPU_DMA_CHA_DMAPF_5)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_6)
| CSP_BITFMASK(IPU_DMA_CHA_DMAPF_7);
iBitval = CSP_BITFVAL(IPU_DMA_CHA_DMAPF_5, IPU_DISABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_6, IPU_DISABLE)
| CSP_BITFVAL(IPU_DMA_CHA_DMAPF_7, IPU_DISABLE);
// Use interlocked function to disable IPU interrupts
// for viewfinding channel.
do
{
oldVal = INREG32(&P_IPU_REGS->IPU_INT_CTRL_1);
newVal = (oldVal & (~iMask)) | iBitval;
} while (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_INT_CTRL_1,
oldVal, newVal) != oldVal);
dumpIpuRegisters(P_IPU_REGS);
PF_FUNCTION_EXIT();
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: controlledWriteDMAChannelParam
//
// This function uses Interlocked APIs to access IPU_IMA registers
// and then initializes the IDMAC channel parameters.
//
// Parameters:
// channel
// [in] String to identify buffer 1 EOF event.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void PfClass::controlledWriteDMAChannelParam(int channel, int row, int word, unsigned int data)
{
unsigned addr =
0x10000 // MEM_NU = DMA CPM
+ (((channel * 2) + row)<< 3) // ROW_NU = (channel*2) << 3
+ word; // WORD_NU
// Software-controlled access to IMA registers
// IMA registers may only be accessed if IMA_ADDR is
// set to 0.
while (1)
{
if (INREG32(&P_IPU_REGS->IPU_IMA_ADDR) == 0)
{
// Try to set IPU_IMA registers.
if (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_IMA_ADDR, 0, addr) == 0)
{
// Successfully set IMA_ADDR.
break;
}
}
// IPU_IMA controlled by another process.
// Surrender CPU and then try again.
Sleep(0);
}
OUTREG32(&P_IPU_REGS->IPU_IMA_DATA, data);
// Cede control of IPU_IMA registers by writing 0 to IPU_IMA_ADDR
OUTREG32(&P_IPU_REGS->IPU_IMA_ADDR, 0);
}
//-----------------------------------------------------------------------------
//
// Function: writeDMAChannelParam
//
// This function initializes the IDMAC channel parameters.
//
// Parameters:
// channel
// [in] String to identify buffer 1 EOF event.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void PfClass::writeDMAChannelParam(int channel, int row, int word, unsigned int data)
{
unsigned addr =
0x10000 // MEM_NU = DMA CPM
+ (((channel * 2) + row)<< 3) // ROW_NU = (channel*2) << 3
+ word; // WORD_NU
OUTREG32(&P_IPU_REGS->IPU_IMA_ADDR, addr);
OUTREG32(&P_IPU_REGS->IPU_IMA_DATA, data);
}
//-----------------------------------------------------------------------------
//
// Function: PfIDMACChannelConfig
//
// This function initializes the IDMAC channel parameters.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void PfClass::PfIDMACChannelConfig(UINT8 ch, pPfIDMACChannelParams pChannelParams)
{
UINT32 newVal;
PF_FUNCTION_ENTRY();
dumpChannelParams(pChannelParams);
// Software-controlled access to IMA registers
// IMA registers may only be accessed if IMA_ADDR is
// set to 0.
// Set IPU_IMA_ADDR to 1 to gain control of IPU_IMA registers.
newVal = 1;
while (1)
{
if (INREG32(&P_IPU_REGS->IPU_IMA_ADDR) == 0)
{
// Try to set IPU_IMA registers.
if (InterlockedTestExchange((LPLONG)&P_IPU_REGS->IPU_IMA_ADDR, 0, newVal) == 0)
{
// Successfully set IMA_ADDR.
break;
}
}
// IPU_IMA controlled by another process.
// Surrender CPU and then try again.
Sleep(0);
}
writeDMAChannelParam(ch, 0, 0, 0); //Variable data set to 0 31-0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -