📄 tmicp.c
字号:
icpSetReg(ICP_DP, (UInt32) & blk);
icpStart();
return (TMLIBDEV_OK);
}
/*****************************************************************************/
/*
* Function: : icpVertFilter
* Vertical filter an image given in *scrImage *
* in SDRAM to *destImage in SDRAM.
* Parameters : 1. Instance
* 2. Pointer to the icpImageHorzVert_t block.
* Function Result : Return TMLIBDEV_OK on success
* ICP_ERR_DEVICE_IN_USE; Incorrect owner.
* ICP_ERR_SETUP_REQUIRED; ICP has not been setup.
* Use icpSetup().
* ICP_ERR_INVALID_HEIGHT; Source height <= 0.
* ICP_ERR_INVALID_WIDTH; Source width <=0.
* ICP_ERR_INVALID_STRIDE; Source or destination *
* stride <= 0.
* ICP_ERR_ADDRESS_NOT_64_ALIGNED; Address pointer *
* must be aligned at a 64 byte block boundary.
* ICP_ERR_BUSY; Attempt to call icpMove while *
* ICP is busy processing
* ICP_ERR_VERT_STRIDE_NOT_64_ALIGNED; Source stride
* is not a multiple of 64 bytes.
* Precondition : Micro code is already loaded
* Source image is assumed to be COPYBACK'ed in memory.
* Filter coefficients are already loaded.
* IMPORTANT
* Source stride must be a multiple of 64.
* Vertical filter will not work properly otherwise.
*/
tmLibdevErr_t
icpVertFilter(Int instance, icpImageHorzVert_t * image)
{
tmLibdevErr_t rval;
UInt32 tmp = (UInt32) (65536.0 *
(Float) (image->inputHeight) /
(Float) (image->outputHeight));
tmAssert(!(((UInt32) image->imageBase & 0x3f)
|| ((UInt32) image->outputImage & 0x3f)),
ICP_ERR_ADDRESS_NOT_64_ALIGNED);
/*
* Since the same block is loaded for the ICP horizontal, move, and
* vertical filter, a common function loads the block
*/
if (rval = icpCheckFillParameters(instance, image))
return (rval);
/* Error processing */
tmAssert((image->inputStride & 0x3F) == 0,
ICP_ERR_VERT_STRIDE_NOT_64_ALIGNED);
blk.fracInc = ((tmp << 16) & 0xffff0000) + ((tmp >> 16) & 0x0000ffff);
/* Copyback to memory */
_cache_copyback((UInt8 *) & blk, sizeof(icpParamTable_t));
/* Load the ICP registers */
icpSetReg(ICP_MPC, (UInt32) & aligned_ucode[2]);
icpSetReg(ICP_DP, (UInt32) & blk);
icpStart();
return (TMLIBDEV_OK);
}
/*****************************************************************************/
/*
* Function: : icpDeinterlace
* Vertical Deinterlace filter an image given in
* *scrImage in SDRAM to *destImage in SDRAM.
* Parameters : 1. Instance
* 2. Pointer to the icpImageHorzVert_t block.
* Function Result : Return TMLIBDEV_OK on success
* ICP_ERR_DEVICE_IN_USE; Incorrect owner.
* ICP_ERR_SETUP_REQUIRED; ICP has not been setup.
* Use icpSetup().
* ICP_ERR_INVALID_HEIGHT; Source height <= 0.
* ICP_ERR_INVALID_WIDTH; Source width <=0.
* ICP_ERR_INVALID_STRIDE; Source or destination *
* stride <= 0.
* ICP_ERR_ADDRESS_NOT_64_ALIGNED; Address pointer *
* must be aligned at a 64 byte block boundary.
* ICP_ERR_BUSY; Attempt to call icpMove while *
* ICP is busy processing
* ICP_ERR_VERT_STRIDE_NOT_64_ALIGNED; Source stride
* is not a multiple of 64 bytes.
* Precondition : Micro code is already loaded
* Source image is assumed to be COPYBACK'ed in memory.
* Deinterlace Filter coefficients are already loaded.
* IMPORTANT
* Source stride must be a multiple of 64.
* Vertical filter will not work properly otherwise.
*/
tmLibdevErr_t
icpDeinterlace(Int instance, icpImageHorzVert_t * image)
{
tmLibdevErr_t rval;
/*
* The scale is always '1'.
*/
UInt32 tmp = (UInt32) (65536.0);
/*
* The input height must equal the output height
*/
tmAssert(image->inputHeight == image->outputHeight, ICP_ERR_INVALID_HEIGHT);
tmAssert(!(((UInt32) image->imageBase & 0x3f)
|| ((UInt32) image->outputImage & 0x3f)),
ICP_ERR_ADDRESS_NOT_64_ALIGNED);
/*
* Since the same block is loaded for the ICP horizontal, move, and
* vertical filter, a common function loads the block
*/
if (rval = icpCheckFillParameters(instance, image))
return (rval);
/* Error processing */
tmAssert((image->inputStride & 0x3F) == 0,
ICP_ERR_VERT_STRIDE_NOT_64_ALIGNED);
blk.fracInc = ((tmp << 16) & 0xffff0000) + ((tmp >> 16) & 0x0000ffff);
/* Copyback to memory */
_cache_copyback((UInt8 *) & blk, sizeof(icpParamTable_t));
/* Load the ICP registers */
icpSetReg(ICP_MPC, (UInt32) & aligned_ucode[4]);
icpSetReg(ICP_DP, (UInt32) & blk);
icpStart();
return (TMLIBDEV_OK);
}
/****************************************************************************/
/*
* Function: : icpHorzFilter
* Horizontal filter an image given in *scrImage
* in SDRAM to *destImage in SDRAM.
* Parameters : 1. Instance
* 2. Pointer to the icpImageHorzVert_t block.
* Function Result : Return TMLIBDEV_OK on success
* ICP_ERR_DEVICE_IN_USE; Incorrect owner.
* ICP_ERR_SETUP_REQUIRED; ICP has not been setup.
* Use icpSetup().
* ICP_ERR_INVALID_HEIGHT; Source height <= 0.
* ICP_ERR_INVALID_WIDTH; Source width <=0.
* ICP_ERR_INVALID_STRIDE; Source or destination
* stride <= 0.
* ICP_ERR_ADDRESS_NOT_64_ALIGNED; Address pointer
* must be aligned at a 64 byte block boundary.
* ICP_ERR_BUSY; Attempt to call icpMove while ICP is
* busy processing
* Precondition : Micro code is already loaded
* Source image is assumed to be COPYBACK'ed in memory.
* Filter coefficients are already loaded.
* Postcondition :
*/
tmLibdevErr_t
icpHorzFilter(Int instance, icpImageHorzVert_t * image)
{
tmLibdevErr_t rval;
UInt32 tmp = (UInt32) (65536.0 *
(Float) (image->inputWidth) /
(Float) (image->outputWidth));
/*
* Since the same block is loaded for the ICP horizontal, move, and
* vertical filter, a common function loads the block
*/
if (rval = icpCheckFillParameters(instance, image))
return (rval);
blk.fracInc = ((tmp << 16) & 0xffff0000) + ((tmp >> 16) & 0x0000ffff);
/* Copyback to memory */
_cache_copyback((UInt8 *) & blk, sizeof(icpParamTable_t));
/* Load the ICP registers */
icpSetReg(ICP_MPC, (UInt32) & aligned_ucode[1]);
icpSetReg(ICP_DP, (UInt32) & blk);
icpStart();
return (TMLIBDEV_OK);
}
/*****************************************************************************/
/*
* Function : icpEnableBIU
* Enables the PCI and turns the burst mode on.
* It is important for PCI mode in color conversion.
* Parameters : None, called internally.
* Function Result : Return TMLIBDEV_OK on success
*/
tmLibdevErr_t
icpEnableBIU()
{
UInt32 biu;
Int i;
biu = MMIO(BIU_CTL);
biu &= ~0x100; /* turn off ICP_ENABLE */
for (i = 0; i < 10; i++); /* Wait a little */
biu |= 0x100; /* turn on ICP_ENABLE */
biu &= ~0x2; /* turn on burst mode */
MMIO(BIU_CTL) = biu;
return (TMLIBDEV_OK);
}
/*****************************************************************************/
/*
* Function : icpColorConversion
* Convert YUV 422, 420, 411, 420 interspersed, or 422
* interspersed to RGB 24 + alpha, RGB 24 packed, RGB 16,
* RGB 15 + alpha, RGB 8A, RGB 8R, YUV 422 sequence, or
* YUV 422 sequence + alpha formats and send the data
* to either PCI or SDRAM with or without and overlay
* or bitmask.
* Parameters : 1. Instance
* 2. Pointer to the icpImageColorConversion_t block.
* Function Result: Return TMLIBDEV_OK on success
* ICP_ERR_DEVICE_IN_USE; Incorrect owner.
* ICP_ERR_SETUP_REQUIRED; ICP has not been setup.
* Use icpSetup().
* ICP_ERR_INVALID_HEIGHT; Source or destination height <= 0.
* ICP_ERR_INVALID_WIDTH; Source or destination width <=0.
* ICP_ERR_INVALID_STRIDE; Source or destination stride <= 0.
* ICP_ERR_ADDRESS_NOT_64_ALIGNED; Address pointer must be
* aligned at a 64 byte block
* boundary.
* ICP_ERR_BUSY; Attempt to call icpMove while ICP is
* busy processing
* ICP_ERR_IMAGE_TYPE; Requested image format is not supported
* ICP_ERR_OUTPUT_NOT_DEFINED; Requested output is
* neither PCI nor SDRAM
* ICP_ERR_CANT_WRITE_TO_BIUCTRL; For PCI output,
* BIU control register
* could not be modified.
* ICP_ERR_INVALID_ALPHA; alpha is outside the range [0,1].
* ICP_ERR_SETUP_OVERLAY_REQUIRED; Overlay mode requested
* before icpSetupOverlay was
* called.
* ICP_ERR_SETUP_BITMASK_REQUIRED; Bitmask mode requested
* before icpSetupBitMask was
* called.
* Precondition : Images are already copied back.
* Filter coefficients are already loaded
* Micro code is already loaded in SDRAM
* ICP is already setup and open
*
*/
tmLibdevErr_t
icpColorConversion(Int instance, icpImageColorConversion_t * image)
{
tmLibdevErr_t err;
UInt32 tmp;
/*
* Error processing
*/
tmAssert(icp_instance == instance, TMLIBDEV_ERR_NOT_OWNER);
tmAssert(icp_setup, ICP_ERR_SETUP_REQUIRED);
tmAssert(!icpCheckBUSY(), ICP_ERR_BUSY);
tmAssert(image->inputHeight > 0, ICP_ERR_INVALID_HEIGHT);
tmAssert(image->inputWidth > 0, ICP_ERR_INVALID_WIDTH);
tmAssert(!(((UInt32) image->yBase & 0x3f) || ((UInt32) image->uBase & 0x3f)
|| ((UInt32) image->vBase & 0x3f)),
ICP_ERR_ADDRESS_NOT_64_ALIGNED);
tmAssert((image->outputDestination == icpPCI) ||
(image->outputDestination == icpSDRAM),
ICP_ERR_OUTPUT_NOT_DEFINED);
tmAssert(!((image->overlayEnable) && (!overlay_used)),
ICP_ERR_SETUP_OVERLAY_REQUIRED);
tmAssert(!((image->bitMaskEnable) && (!bitmask_used)),
ICP_ERR_SETUP_BITMASK_REQUIRED);
/*
* Take care of the line splat error (bug: PN 3072)
*/
if (image->outFormat == vdfRGB24) {
/* Only for RGB 24 packed we see the error */
tmp = (Int) image->outputImage & 0x0000ffff;
/* Get only the last 16 bits */
if ((tmp % 4 == 0) && ((image->outputWidth & 0x0000001f) == 0x16))
image->outputWidth = image->outputWidth + 1;
else if ((tmp % 4 == 1) && ((image->outputWidth & 0x0000001f) == 0x15))
image->outputWidth = image->outputWidth + 1;
else if ((tmp % 4 == 2) && ((image->outputWidth & 0x0000003f) == 0x00))
image->outputWidth = image->outputWidth + 1;
else if ((tmp % 4 == 3) && ((image->outputWidth & 0x0000003f) == 0x2b))
image->outputWidth = image->outputWidth + 1;
}
/*
* Setup the parameter block based on given information
*/
blk3.yimage_in = (UInt32) image->yBase;
blk3.uimage_in = (UInt32) image->uBase;
blk3.vimage_in = (UInt32) image->vBase;
blk3.yLineOffset = (UInt16) image->yInputStride;
blk3.uLineOffset = (UInt16) image->uvInputStride;
blk3.vLineOffset = (UInt16) image->uvInputStride;
blk3.yHeightIn = (UInt16) image->inputHeight;
blk3.yWidthIn = (UInt16) image->inputWidth;
blk3.image_out = (UInt32) image->outputImage;
blk3.lineOffsetOut = (UInt16) image->outputStride;
/*
* WARNING: Incorrect description of FracInc in the ICP manual. The
* two MS and the LS bytes need to be swapped
*/
blk3.yCntStFrac = 0;
tmp = (UInt32) (65536.0 *
(Float) image->inputWidth / (Float) image->outputWidth);
blk3.yFracInc = ((tmp << 16) & 0xffff0000) + ((tmp >> 16) & 0x0000ffff);
if ((image->inFormat == vdfYUV422Interspersed)
|| (image->inFormat == vdfYUV420Interspersed))
blk3.uCntStFrac = 0xc000;
else
blk3.uCntStFrac = 0x0000;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -