📄 prpclass.cpp
字号:
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_DATA_IN_MODE, PRP_CNTL_DATA_IN_MODE_RGB32);
OUTREG32(&m_pPrpReg->PRP_SOURCE_PIXEL_FORMAT_CNTL, 0x41000888);
nInputBytesPerLine = pConfigData->inputSize.width * 4;
break;
default:
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Invalid input format. \r\n"), __WFUNCTION__));
return FALSE;
}
// Setup FIFO level
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_INPUT_FIFO_LEVEL, PRP_CNTL_INPUT_FIFO_LEVEL_128W);
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_RZ_FIFO_LEVEL, PRP_CNTL_RZ_FIFO_LEVEL_64W);
#ifndef PRP_MEM_MODE_DLL
// Setup CSI windowing
if (pConfigData->bWindowing) {
// The number of pixels to skip from start of a line
// should be multiple of 2
if (pConfigData->inputStride & 0x01) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: The input stride for CSI windowing is not aligned. \r\n"),
__WFUNCTION__));
return FALSE;
}
INSREG32BF(&m_pPrpReg->PRP_SOURCE_LINE_STRIDE,
PRP_SOURCE_LINE_STRIDE_SOURCE_LINE_STRIDE, pConfigData->inputStride);
INSREG32BF(&m_pPrpReg->PRP_SOURCE_LINE_STRIDE,
PRP_SOURCE_LINE_STRIDE_CSI_LINE_SKIP, pConfigData->CSILineSkip);
INSREG32BF(&m_pPrpReg->PRP_CNTL, PRP_CNTL_WEN, PRP_CNTL_WEN_ENABLE);
}
// Setup frame skip control
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_IN_TSKIP, pConfigData->CSIInputSkip);
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH1_TSKIP, pConfigData->VfOutputSkip);
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH2_TSKIP, pConfigData->EncOutputSkip);
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_SKIP_FRAME, PRP_CNTL_SKIP_FRAME_STOP);
// Setup LOOP mode
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH1_LEN, PRP_CNTL_CH1_LEN_ENABLE);
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH2_LEN, PRP_CNTL_CH2_LEN_ENABLE);
// CSI mode
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CSIEN, PRP_CNTL_CSIEN_CSI);
#else // PRP_MEM_MODE_DLL
if (pConfigData->bWindowing) {
if (m_iInputFormat == prpInputFormat_YUV420) {
if (pConfigData->inputStride & 0x07) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: The input stride in bytes must be 8 aligned for Memory mode YUV420. \r\n"),
__WFUNCTION__));
return FALSE;
}
} else if (pConfigData->inputStride & 0x03) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: The input stride in bytes must be 4 aligned for Memory mode. \r\n"),
__WFUNCTION__));
return FALSE;
}
if (pConfigData->inputStride < nInputBytesPerLine) {
DEBUGMSG(ZONE_WARN,
(TEXT("%s: The input stride in bytes is less than the minimum valid one. \r\n"),
__WFUNCTION__));
return FALSE;
}
INSREG32BF(&m_pPrpReg->PRP_SOURCE_LINE_STRIDE,
PRP_SOURCE_LINE_STRIDE_SOURCE_LINE_STRIDE, pConfigData->inputStride);
// Enable windowing
INSREG32BF(&m_pPrpReg->PRP_CNTL, PRP_CNTL_WEN, PRP_CNTL_WEN_ENABLE);
// Only used for YUV420
m_iMemInputYSize = pConfigData->inputStride * pConfigData->inputSize.height;
} else {
INSREG32BF(&m_pPrpReg->PRP_SOURCE_LINE_STRIDE,
PRP_SOURCE_LINE_STRIDE_SOURCE_LINE_STRIDE, nInputBytesPerLine);
// Only used for YUV420
m_iMemInputYSize = nInputBytesPerLine * pConfigData->inputSize.height;
}
// Memory mode
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CSIEN, PRP_CNTL_CSIEN_MEM);
#endif // PRP_MEM_MODE_DLL
PRP_FUNCTION_EXIT();
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: PrpConfigureOutput
//
// This function configures the pre-processor output.
//
// Parameters:
// pConfigData
// [in] Pointer to configuration data structure
//
// Returns:
// TRUE if success; FALSE if failure.
//
//------------------------------------------------------------------------------
BOOL PrpClass::PrpConfigureOutput(pPrpConfigData pConfigData)
{
UINT16 nOutputVfBPP;
PRP_FUNCTION_ENTRY();
// Get output format for both viewfinding and encoding channels
m_iOutputVfFormat = pConfigData->outputVfFormat;
if (m_iOutputVfFormat == prpVfOutputFormat_Disabled)
m_bEnableVfOutput = FALSE;
else
m_bEnableVfOutput = TRUE;
m_iOutputEncFormat = pConfigData->outputEncFormat;
if (m_iOutputEncFormat == prpEncOutputFormat_Disabled)
m_bEnableEncOutput = FALSE;
else
m_bEnableEncOutput = TRUE;
// Sainty check
if ((m_bEnableVfOutput == FALSE) && (m_bEnableEncOutput == FALSE)) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Both channels are disabled so we can do nothing! \r\n"),
__WFUNCTION__));
return FALSE;
}
//
// Viewfinding channel configuration
//
if (m_bEnableVfOutput) {
// Alignment check
if (m_iOutputVfFormat == prpVfOutputFormat_RGB8) {
if (pConfigData->outputVfSize.width & 0x03) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Width of viewfinding output image in RGB8 is not aligned. \r\n"),
__WFUNCTION__));
return FALSE;
}
} else if (m_iOutputVfFormat != prpVfOutputFormat_RGB32) { // RGB16, YUV422
if (pConfigData->outputVfSize.width & 0x01) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Width of viewfinding output image in RGB16/YUV422 is not aligned. \r\n"),
__WFUNCTION__));
return FALSE;
}
}
// Boundary check
if ((pConfigData->outputVfSize.width < PRP_IMAGE_MIN_WIDTH) ||
(pConfigData->outputVfSize.height < PRP_IMAGE_MIN_HEIGHT) ||
(pConfigData->outputVfSize.width > PRP_IMAGE_MAX_WIDTH) ||
(pConfigData->outputVfSize.height > PRP_IMAGE_MAX_HEIGHT)) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Size of viewfinding output image is invalid. \r\n"),
__WFUNCTION__));
return FALSE;
}
// Setup output image size parameters
INSREG32BF(&m_pPrpReg->PRP_CH1_OUT_IMAGE_SIZE,
PRP_CH1_OUT_IMAGE_SIZE_CH1_OUT_IMAGE_WIDTH,
pConfigData->outputVfSize.width);
INSREG32BF(&m_pPrpReg->PRP_CH1_OUT_IMAGE_SIZE,
PRP_CH1_OUT_IMAGE_SIZE_CH1_OUT_IMAGE_HEIGHT,
pConfigData->outputVfSize.height);
// Setup output image format for viewfinding channel
switch (m_iOutputVfFormat) {
case prpVfOutputFormat_Disabled:
m_bEnableVfOutput = FALSE;
break;
case prpVfOutputFormat_RGB8:
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH1_OUT_MODE, PRP_CNTL_CH1_OUT_MODE_RGB8);
OUTREG32(&m_pPrpReg->PRP_CH1_PIXEL_FORMAT_CNTL, 0x14400332);
nOutputVfBPP = 1;
break;
case prpVfOutputFormat_RGB16:
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH1_OUT_MODE, PRP_CNTL_CH1_OUT_MODE_RGB16);
OUTREG32(&m_pPrpReg->PRP_CH1_PIXEL_FORMAT_CNTL, 0x2CA00565);
nOutputVfBPP = 2;
break;
case prpVfOutputFormat_RGB32:
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH1_OUT_MODE, PRP_CNTL_CH1_OUT_MODE_RGB32);
OUTREG32(&m_pPrpReg->PRP_CH1_PIXEL_FORMAT_CNTL, 0x41000888);
nOutputVfBPP = 4;
break;
case prpVfOutputFormat_YUYV422:
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH1_OUT_MODE, PRP_CNTL_CH1_OUT_MODE_YUV422);
OUTREG32(&m_pPrpReg->PRP_CH1_PIXEL_FORMAT_CNTL, 0x62000888);
nOutputVfBPP = 2;
break;
case prpVfOutputFormat_YVYU422:
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH1_OUT_MODE, PRP_CNTL_CH1_OUT_MODE_YUV422);
OUTREG32(&m_pPrpReg->PRP_CH1_PIXEL_FORMAT_CNTL, 0x60100888);
nOutputVfBPP = 2;
break;
case prpVfOutputFormat_UYVY422:
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH1_OUT_MODE, PRP_CNTL_CH1_OUT_MODE_YUV422);
OUTREG32(&m_pPrpReg->PRP_CH1_PIXEL_FORMAT_CNTL, 0x43080888);
nOutputVfBPP = 2;
break;
case prpVfOutputFormat_VYUY422:
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH1_OUT_MODE, PRP_CNTL_CH1_OUT_MODE_YUV422);
OUTREG32(&m_pPrpReg->PRP_CH1_PIXEL_FORMAT_CNTL, 0x41180888);
nOutputVfBPP = 2;
break;
default:
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Invalid output format for viewfinding channel. \r\n"),
__WFUNCTION__));
return FALSE;
}
// Setup viewfinding channel output stride
if (pConfigData->outputVfStride & 0x03) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Viewfinding channel output stride is not aligned. \r\n"),
__WFUNCTION__));
return FALSE;
}
if (pConfigData->outputVfStride <
pConfigData->outputVfSize.width * nOutputVfBPP) {
DEBUGMSG(ZONE_WARN,
(TEXT("%s: Viewfinding channel output stride needs fixup. \r\n"),
__WFUNCTION__));
INSREG32BF(&m_pPrpReg->PRP_CH1_LINE_STRIDE,
PRP_CH1_LINE_STRIDE_CH1_OUT_LINE_STRIDE,
pConfigData->outputVfSize.width * nOutputVfBPP);
} else {
INSREG32BF(&m_pPrpReg->PRP_CH1_LINE_STRIDE,
PRP_CH1_LINE_STRIDE_CH1_OUT_LINE_STRIDE,
pConfigData->outputVfStride);
}
}
//
// Encoding channel configuration
//
if (m_bEnableEncOutput) {
// Alignment check
if (m_iOutputEncFormat == prpEncOutputFormat_YUV420) {
if ((pConfigData->outputEncSize.width & 0x07) ||
(pConfigData->outputEncSize.height & 0x01)) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Size of encoding output image in YUV420 is not aligned. \r\n"),
__WFUNCTION__));
return FALSE;
}
} else { // YUV422, YUV444
if (pConfigData->outputEncSize.width & 0x01) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Width of encoding output image in YUV422/YUV444 is not aligned. \r\n"),
__WFUNCTION__));
return FALSE;
}
}
// Boundary check
if ((pConfigData->outputEncSize.width < PRP_IMAGE_MIN_WIDTH) ||
(pConfigData->outputEncSize.height < PRP_IMAGE_MIN_HEIGHT) ||
(pConfigData->outputEncSize.width > PRP_IMAGE_MAX_WIDTH) ||
(pConfigData->outputEncSize.height > PRP_IMAGE_MAX_HEIGHT)) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Size of encoding output image is invalid. \r\n"),
__WFUNCTION__));
return FALSE;
}
// Setup output image size parameters
INSREG32BF(&m_pPrpReg->PRP_CH2_OUT_IMAGE_SIZE,
PRP_CH2_OUT_IMAGE_SIZE_CH2_OUT_IMAGE_WIDTH,
pConfigData->outputEncSize.width);
INSREG32BF(&m_pPrpReg->PRP_CH2_OUT_IMAGE_SIZE,
PRP_CH2_OUT_IMAGE_SIZE_CH2_OUT_IMAGE_HEIGHT,
pConfigData->outputEncSize.height);
// Save image Y size for 4:2:0 U V buffer address calculation
// later in function PrpBufferSetup()
m_iEncOutputYSize = pConfigData->outputEncSize.width *
pConfigData->outputEncSize.height;
// Setup output image format for encoding channel
switch (m_iOutputEncFormat) {
case prpEncOutputFormat_Disabled:
m_bEnableEncOutput = FALSE;
break;
case prpEncOutputFormat_YUV420:
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH2_OUT_MODE, PRP_CNTL_CH2_OUT_MODE_YUV420);
break;
case prpEncOutputFormat_YUV422:
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH2_OUT_MODE, PRP_CNTL_CH2_OUT_MODE_YUV422);
break;
case prpEncOutputFormat_YUV444:
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH2_OUT_MODE, PRP_CNTL_CH2_OUT_MODE_YUV444);
break;
default:
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Invalid output format for encoding channel. \r\n"),
__WFUNCTION__));
return FALSE;
}
#ifndef PRP_MEM_MODE_DLL
// Enable encoding channel flow control
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH2FEN, PRP_CNTL_CH2FEN_ENABLE);
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH2B1EN, PRP_CNTL_CH2B1EN_ENABLE);
INSREG32BF(&m_pPrpReg->PRP_CNTL,
PRP_CNTL_CH2B2EN, PRP_CNTL_CH2B2EN_ENABLE);
#endif
}
PRP_FUNCTION_EXIT();
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: PrpConfigureCSC
//
// This function configures the pre-processor CSC.
//
// Parameters:
// pConfigData
// [in] Pointer to configuration data structure
//
// Returns:
// TRUE if success; FALSE if failure.
//
//-----------------------------------------------------------------------------
BOOL PrpClass::PrpConfigureCSC(pPrpConfigData pConfigData)
{
BOOL bInputRGB, bVfOutputRGB;
PRP_FUNCTION_ENTRY();
// Check if CSC is needed.
// Encoding channel always output YUV format, therefore we only need
// check input and viewfinding channel output.
bInputRGB = (pConfigData->inputFormat == prpInputFormat_RGB16) ||
(pConfigData->inputFormat == prpInputFormat_RGB32);
bVfOutputRGB = (pConfigData->outputVfFormat == prpVfOutputFormat_RGB8) ||
(pConfigData->outputVfFormat == prpVfOutputFormat_RGB16) ||
(pConfigData->outputVfFormat == prpVfOutputFormat_RGB32);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -