📄 ppclass.cpp
字号:
m_hPpIntrThread = NULL;
}
if (m_hPpBufThread != NULL) {
TerminateThread(m_hPpBufThread, 0);
CloseHandle(m_hPpBufThread);
m_hPpBufThread = NULL;
}
PP_FUNCTION_EXIT();
}
//-----------------------------------------------------------------------------
//
// Function: PpEnable
//
// This function enables post-processor.
//
// Parameters:
// None.
//
// Returns:
// TRUE if successful; FALSE if failed.
//
//-----------------------------------------------------------------------------
BOOL PpClass::PpEnable(void)
{
PP_FUNCTION_ENTRY();
// Enable eMMA clock
if (!BSPPpSetClockGatingMode(TRUE)) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Enable PP failed. It probably is being used by someone. \r\n"),
__WFUNCTION__));
return FALSE;
}
// Software reset post-processor
INSREG32BF(&m_pPpReg->PP_CNTL, PP_CNTL_SWRST, PP_CNTL_SWRST_RESET);
// Suppose it will clear itself after software reset
while (EXTREG32BF(&m_pPpReg->PP_CNTL, PP_CNTL_SWRST)) {
Sleep(0); // Relinquish current time slot for other thread
}
// Enable interrupts for frame completing and error occuring
// Disable the MB completing interrupt, since we don't support it
OUTREG32(&m_pPpReg->PP_INTRCNTL,
CSP_BITFVAL(PP_INTRCNTL_FRAME_COMP_INTR_EN,
PP_INTRCNTL_FRAME_COMP_INTR_EN_ENABLE) |
CSP_BITFVAL(PP_INTRCNTL_ERR_INTR_EN,
PP_INTRCNTL_ERR_INTR_EN_ENABLE));
// Empty buffer queue
PpClearBuffers();
PP_FUNCTION_EXIT();
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: PpDisable
//
// This function disables post-processor.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
void PpClass::PpDisable(void)
{
PP_FUNCTION_ENTRY();
// Disable post-processor first
OUTREG32(&m_pPpReg->PP_CNTL, 0);
// In case there is still one last pending interrupt
// Clear interrupt status (w1c)
OUTREG32(&m_pPpReg->PP_INTRSTATUS,
CSP_BITFVAL(PP_INTRSTATUS_ERR_INTR, 1) |
CSP_BITFVAL(PP_INTRSTATUS_FRAME_COMP_INTR, 1));
// Disable interrupt
OUTREG32(&m_pPpReg->PP_INTRCNTL, 0);
// Disable eMMA clock
BSPPpSetClockGatingMode(FALSE);
// Revert flag
m_bConfigured = FALSE;
PP_FUNCTION_EXIT();
}
//------------------------------------------------------------------------------
//
// Function: PpConfigure
//
// This function is used to configure post-processor registers.
//
// Parameters:
// pConfigData
// [in] Pointer to configuaration data structure.
//
// Returns:
// TRUE if success; FALSE if failure.
//
//------------------------------------------------------------------------------
BOOL PpClass::PpConfigure(pPpConfigData pConfigData)
{
PP_FUNCTION_ENTRY();
if (pConfigData == NULL) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Invalid configuration data!\r\n"), __WFUNCTION__));
return FALSE;
}
// Enable required operations
if (pConfigData->bDeblock)
INSREG32BF(&m_pPpReg->PP_CNTL,
PP_CNTL_DEBLOCKEN, PP_CNTL_DEBLOCKEN_ENABLE);
else
INSREG32BF(&m_pPpReg->PP_CNTL,
PP_CNTL_DEBLOCKEN, PP_CNTL_DEBLOCKEN_DISABLE);
if (pConfigData->bDering)
INSREG32BF(&m_pPpReg->PP_CNTL,
PP_CNTL_DERINGEN, PP_CNTL_DERINGEN_ENABLE);
else
INSREG32BF(&m_pPpReg->PP_CNTL,
PP_CNTL_DERINGEN, PP_CNTL_DERINGEN_DISABLE);
// Indicates if we need quantizer parameter from user
m_bNeedQP = (pConfigData->bDeblock || pConfigData->bDering);
if (!PpConfigureInput(pConfigData))
goto _error;
if (!PpConfigureOutput(pConfigData))
goto _error;
if (!PpConfigureCSC(pConfigData))
goto _error;
if (!PpConfigureResize(pConfigData))
goto _error;
// Indicates the configuration is done
m_bConfigured = TRUE;
PP_FUNCTION_EXIT();
return TRUE;
_error:
// Make a software reset
INSREG32BF(&m_pPpReg->PP_CNTL, PP_CNTL_SWRST, PP_CNTL_SWRST_RESET);
// Suppose it will clear itself after software reset
while (EXTREG32BF(&m_pPpReg->PP_CNTL, PP_CNTL_SWRST)) {
Sleep(0); // Relinquish current time slot for other thread
}
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Post-processor configuration failed\r\n"),
__WFUNCTION__));
return FALSE;
}
//-----------------------------------------------------------------------------
//
// Function: PpConfigureInput
//
// This function configures the Post-processor input source.
//
// Parameters:
// pConfigData
// [in] Pointer to configuration data structure
//
// Returns:
// TRUE if success; FALSE if failure.
//
//-----------------------------------------------------------------------------
BOOL PpClass::PpConfigureInput(pPpConfigData pConfigData)
{
UINT16 iQFWidth;
UINT16 iInputStride;
PP_FUNCTION_ENTRY();
// Alignment check
if ((pConfigData->inputSize.width & 0x07) ||
(pConfigData->inputSize.height & 0x07) ||
(pConfigData->inputStride & 0x07)) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Input image size is not aligned\r\n"), __WFUNCTION__));
return FALSE;
}
// Boundary check
if ((pConfigData->inputSize.width < PP_IMAGE_MIN_WIDTH) ||
(pConfigData->inputSize.height < PP_IMAGE_MIN_HEIGHT) ||
(pConfigData->inputSize.width > PP_IMAGE_MAX_WIDTH) ||
(pConfigData->inputSize.height > PP_IMAGE_MAX_HEIGHT)) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Input image size is invalid\r\n"), __WFUNCTION__));
return FALSE;
}
// Set input frame parameter register
INSREG32BF(&m_pPpReg->PP_PROCESS_FRAME_PARA,
PP_PROCESS_FRAME_PARA_PROCESS_FRAME_HEIGHT,
pConfigData->inputSize.height);
INSREG32BF(&m_pPpReg->PP_PROCESS_FRAME_PARA,
PP_PROCESS_FRAME_PARA_PROCESS_FRAME_WIDTH,
pConfigData->inputSize.width);
// Set quantizer frame width if need
if (m_bNeedQP) {
// Must be multiple of 4 bytes
iQFWidth = pConfigData->inputSize.width / PP_MB_SIZE;
iQFWidth = ((iQFWidth + 3) >> 2) << 2;
INSREG32BF(&m_pPpReg->PP_SOURCE_FRAME_WIDTH,
PP_SOURCE_FRAME_WIDTH_QUANTIZER_FRAME_WIDTH, iQFWidth);
}
// Set input line stride
if (pConfigData->inputStride == 0) {
// The case it's zero
iInputStride = pConfigData->inputSize.width;
} else {
if (pConfigData->inputStride < pConfigData->inputSize.width) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Input stride (%d) is less than the least valid value (%d)\r\n"),
__WFUNCTION__,
pConfigData->inputStride, pConfigData->inputSize.width));
return FALSE;
} else {
iInputStride = pConfigData->inputStride;
}
}
INSREG32BF(&m_pPpReg->PP_SOURCE_FRAME_WIDTH,
PP_SOURCE_FRAME_WIDTH_Y_INPUT_LINE_STRIDE, iInputStride);
m_iInBufSize = iInputStride * pConfigData->inputSize.height;
PP_FUNCTION_EXIT();
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: PpConfigureOutput
//
// This function configures the Post-processor output.
//
// Parameters:
// pConfigData
// [in] Pointer to configuration data structure
//
// Returns:
// TRUE if success; FALSE if failure.
//
//-----------------------------------------------------------------------------
BOOL PpClass::PpConfigureOutput(pPpConfigData pConfigData)
{
UINT8 iBpp;
UINT16 iOutputStride;
PP_FUNCTION_ENTRY();
// Alignment check
if ((pConfigData->outputSize.width & 0x01) ||
(pConfigData->outputSize.height & 0x01) ||
(pConfigData->outputStride & 0x03)) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Output image size is not aligned\r\n"), __WFUNCTION__));
return FALSE;
}
// Boundary check
if ((pConfigData->outputSize.width < PP_IMAGE_MIN_WIDTH) ||
(pConfigData->outputSize.height < PP_IMAGE_MIN_HEIGHT) ||
(pConfigData->outputSize.width > PP_IMAGE_MAX_WIDTH) ||
(pConfigData->outputSize.height > PP_IMAGE_MAX_HEIGHT)) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Output image size is invalid\r\n"), __WFUNCTION__));
return FALSE;
}
// Set output image parameter register
INSREG32BF(&m_pPpReg->PP_DEST_IMAGE_SIZE,
PP_DEST_IMAGE_SIZE_OUT_IMAGE_HEIGHT, pConfigData->outputSize.height);
INSREG32BF(&m_pPpReg->PP_DEST_IMAGE_SIZE,
PP_DEST_IMAGE_SIZE_OUT_IMAGE_WIDTH, pConfigData->outputSize.width);
// Parameters validity check
switch (pConfigData->outputFormat) {
case ppCSCOutputFormat_RGB16:
case ppCSCOutputFormat_YUV422:
iBpp = 2;
break;
case ppCSCOutputFormat_RGB32:
iBpp = 4;
break;
}
if ((pConfigData->outputStride != 0) &&
(pConfigData->outputStride < (pConfigData->outputSize.width * iBpp))) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Output stride %d is less than least valid value %d!\r\n"),
__WFUNCTION__,
pConfigData->outputStride, pConfigData->outputSize.width * iBpp));
return FALSE;
}
// Set output line stride
iOutputStride = pConfigData->outputStride;
if (iOutputStride == 0) {
// The case it's zero
iOutputStride = pConfigData->outputSize.width * iBpp;
// Output stride should always be rounded up as a multiple of 4 bytes
iOutputStride = ((iOutputStride + 3) >> 2) << 2;
}
INSREG32BF(&m_pPpReg->PP_DEST_DISPLAY_WIDTH,
PP_DEST_DISPLAY_WIDTH_OUPUT_LINE_STRIDE, iOutputStride);
// Setup DEST_FRAME_FORMAT_CNTL regsiter for RGB/YUV422
OUTREG32(&m_pPpReg->PP_DEST_FRAME_FORMAT_CNTL,
CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_BLUE_WIDTH,
pConfigData->outputPixelFormat.component2_width) |
CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_GREEN_WIDTH,
pConfigData->outputPixelFormat.component1_width) |
CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_RED_WIDTH,
pConfigData->outputPixelFormat.component0_width) |
CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_BLUE_OFFSET,
pConfigData->outputPixelFormat.component2_offset) |
CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_GREEN_OFFSET,
pConfigData->outputPixelFormat.component1_offset) |
CSP_BITFVAL(PP_DEST_FRAME_FORMAT_CNTL_RED_OFFSET,
pConfigData->outputPixelFormat.component0_offset));
m_iOutBufSize = iOutputStride * pConfigData->outputSize.height;
PP_FUNCTION_EXIT();
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: PpConfigureCSC
//
// This function configures the Post-processor CSC.
//
// Parameters:
// pConfigData
// [in] Pointer to configuration data structure
//
// Returns:
// TRUE if success; FALSE if failure.
//
//-----------------------------------------------------------------------------
BOOL PpClass::PpConfigureCSC(pPpConfigData pConfigData)
{
PP_FUNCTION_ENTRY();
if (pConfigData->outputFormat == ppCSCOutputFormat_YUV422) {
// The output format is YUV422
DEBUGMSG(ZONE_INFO,
(TEXT("%s: Output format is YUV422\r\n"), __WFUNCTION__));
INSREG32BF(&m_pPpReg->PP_CNTL, PP_CNTL_CSCEN, PP_CNTL_CSCEN_YUV);
} else {
// The output format is RGB
switch (pConfigData->outputFormat) {
case ppCSCOutputFormat_RGB16:
DEBUGMSG(ZONE_INFO,
(TEXT("%s: Output format is RGB16\r\n"), __WFUNCTION__));
break;
case ppCSCOutputFormat_RGB32:
DEBUGMSG(ZONE_INFO,
(TEXT("%s: Output format is RGB32\r\n"), __WFUNCTION__));
break;
default:
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Invalid CSC output format (%d)\r\n"),
__WFUNCTION__, pConfigData->outputFormat));
return FALSE;
}
// Set CSC equation
if ((pConfigData->CSCEquation != ppCSCEquationA_1) &&
(pConfigData->CSCEquation != ppCSCEquationA_0) &&
(pConfigData->CSCEquation != ppCSCEquationB_1) &&
(pConfigData->CSCEquation != ppCSCEquationB_0)) {
DEBUGMSG(ZONE_ERROR,
(TEXT("%s: Invalid CSC equation (%d)\r\n"),
__WFUNCTION__, pConfigData->CSCEquation));
return FALSE;
} else {
OUTREG32(&m_pPpReg->PP_CSC_COEF_0123,
CSP_BITFVAL(PP_CSC_COEF_0123_C0,
yuv2rgb_tbl[pConfigData->CSCEquation][0]) |
CSP_BITFVAL(PP_CSC_COEF_0123_C1,
yuv2rgb_tbl[pConfigData->CSCEquation][1]) |
CSP_BITFVAL(PP_CSC_COEF_0123_C2,
yuv2rgb_tbl[pConfigData->CSCEquation][2]) |
CSP_BITFVAL(PP_CSC_COEF_0123_C3,
yuv2rgb_tbl[pConfigData->CSCEquation][3]));
OUTREG32(&m_pPpReg->PP_CSC_COEF_4,
CSP_BITFVAL(PP_CSC_COEF_4_C4,
yuv2rgb_tbl[pConfigData->CSCEquation][4]) |
CSP_BITFVAL(PP_CSC_COEF_4_X0,
yuv2rgb_tbl[pConfigData->CSCEquation][5]));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -