v_vscaler: Add filter table selection logic
There are 4 filter coefficient tables available. The table to be loaded in IP register bank is determined by the scaling ratio Scale Up: Always use 6tap Scale Dn: Different table selected based on scaling ratio Signed-off-by: Rohit Consul <rohit.consul@xilinx.com> Acked-by: Andrei-Liviu Simion <andrei.simion@xilinx.com>
This commit is contained in:
parent
fa04ca480c
commit
3f21bcd139
2 changed files with 118 additions and 47 deletions
|
@ -72,8 +72,13 @@ const short XV_vscaler_fixedcoeff_taps10[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_TAP
|
||||||
const short XV_vscaler_fixedcoeff_taps12[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_TAPS_12];
|
const short XV_vscaler_fixedcoeff_taps12[XV_VSCALER_MAX_V_PHASES][XV_VSCALER_TAPS_12];
|
||||||
|
|
||||||
/************************** Function Prototypes ******************************/
|
/************************** Function Prototypes ******************************/
|
||||||
|
static void XV_VScalerSelectCoeff(XV_vscaler *InstancePtr,
|
||||||
|
XV_vscaler_l2 *VscL2DataPtr,
|
||||||
|
u32 HeightIn,
|
||||||
|
u32 HeightOut);
|
||||||
|
|
||||||
static void XV_VScalerSetCoeff(XV_vscaler *pVsc,
|
static void XV_VScalerSetCoeff(XV_vscaler *pVsc,
|
||||||
XV_vscaler_l2 *pVscL2Data);
|
XV_vscaler_l2 *VscL2DataPtr);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/**
|
/**
|
||||||
|
@ -114,54 +119,119 @@ void XV_VScalerStop(XV_vscaler *InstancePtr)
|
||||||
* storage based on the selected TAP configuration
|
* storage based on the selected TAP configuration
|
||||||
*
|
*
|
||||||
* @param InstancePtr is a pointer to the core instance to be worked on.
|
* @param InstancePtr is a pointer to the core instance to be worked on.
|
||||||
* @param pVscL2Data is a pointer to the core instance layer 2 data.
|
* @param VscL2DataPtr is a pointer to the core instance layer 2 data.
|
||||||
*
|
* @param WidthIn is the input stream height
|
||||||
|
* @param Widthout is the output stream height
|
||||||
|
|
||||||
* @return None
|
* @return None
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void XV_VScalerLoadDefaultCoeff(XV_vscaler *InstancePtr,
|
static void XV_VScalerSelectCoeff(XV_vscaler *InstancePtr,
|
||||||
XV_vscaler_l2 *pVscL2Data)
|
XV_vscaler_l2 *VscL2DataPtr,
|
||||||
|
u32 HeightIn,
|
||||||
|
u32 HeightOut)
|
||||||
{
|
{
|
||||||
const short *coeff;
|
const short *coeff;
|
||||||
u16 numTaps, numPhases;
|
u16 numTaps, numPhases;
|
||||||
|
u16 ScalingRatio;
|
||||||
|
u16 IsScaleDown;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* validates input arguments
|
* validates input arguments
|
||||||
*/
|
*/
|
||||||
Xil_AssertVoid(InstancePtr != NULL);
|
Xil_AssertVoid(InstancePtr != NULL);
|
||||||
Xil_AssertVoid(pVscL2Data != NULL);
|
Xil_AssertVoid(VscL2DataPtr != NULL);
|
||||||
|
|
||||||
numTaps = InstancePtr->Config.NumTaps;
|
|
||||||
numPhases = (1<<InstancePtr->Config.PhaseShift);
|
numPhases = (1<<InstancePtr->Config.PhaseShift);
|
||||||
|
|
||||||
switch(numTaps)
|
IsScaleDown = (HeightOut < HeightIn);
|
||||||
|
/* Scale Down Mode will use dynamic filter selection logic
|
||||||
|
* Scale Up Mode (including 1:1) will always use 6 tap filter
|
||||||
|
*/
|
||||||
|
if(IsScaleDown)
|
||||||
|
{
|
||||||
|
ScalingRatio = ((HeightIn * 10)/HeightOut);
|
||||||
|
|
||||||
|
switch(InstancePtr->Config.NumTaps)
|
||||||
{
|
{
|
||||||
case XV_VSCALER_TAPS_6:
|
case XV_VSCALER_TAPS_6:
|
||||||
coeff = &XV_vscaler_fixedcoeff_taps6[0][0];
|
coeff = &XV_vscaler_fixedcoeff_taps6[0][0];
|
||||||
|
numTaps = XV_VSCALER_TAPS_6;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XV_VSCALER_TAPS_8:
|
case XV_VSCALER_TAPS_8:
|
||||||
|
if(ScalingRatio > 15)
|
||||||
|
{
|
||||||
coeff = &XV_vscaler_fixedcoeff_taps8[0][0];
|
coeff = &XV_vscaler_fixedcoeff_taps8[0][0];
|
||||||
|
numTaps = XV_VSCALER_TAPS_8;
|
||||||
|
}
|
||||||
|
else // <= 1.5
|
||||||
|
{
|
||||||
|
coeff = &XV_vscaler_fixedcoeff_taps6[0][0];
|
||||||
|
numTaps = XV_VSCALER_TAPS_6;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XV_VSCALER_TAPS_10:
|
case XV_VSCALER_TAPS_10:
|
||||||
|
if(ScalingRatio > 25) // >2.5
|
||||||
|
{
|
||||||
coeff = &XV_vscaler_fixedcoeff_taps10[0][0];
|
coeff = &XV_vscaler_fixedcoeff_taps10[0][0];
|
||||||
|
numTaps = XV_VSCALER_TAPS_10;
|
||||||
|
}
|
||||||
|
else if(ScalingRatio > 15) // 1.6 < ratio <= 2.5
|
||||||
|
{
|
||||||
|
coeff = &XV_vscaler_fixedcoeff_taps8[0][0];
|
||||||
|
numTaps = XV_VSCALER_TAPS_8;
|
||||||
|
}
|
||||||
|
else // <= 1.5
|
||||||
|
{
|
||||||
|
coeff = &XV_vscaler_fixedcoeff_taps6[0][0];
|
||||||
|
numTaps = XV_VSCALER_TAPS_6;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XV_VSCALER_TAPS_12:
|
case XV_VSCALER_TAPS_12:
|
||||||
|
if(ScalingRatio > 35) // > 3.5
|
||||||
|
{
|
||||||
coeff = &XV_vscaler_fixedcoeff_taps12[0][0];
|
coeff = &XV_vscaler_fixedcoeff_taps12[0][0];
|
||||||
|
numTaps = XV_VSCALER_TAPS_12;
|
||||||
|
}
|
||||||
|
else if(ScalingRatio > 25) //2.6 < Ratio <= 3.5
|
||||||
|
{
|
||||||
|
coeff = &XV_vscaler_fixedcoeff_taps10[0][0];
|
||||||
|
numTaps = XV_VSCALER_TAPS_10;
|
||||||
|
}
|
||||||
|
else if(ScalingRatio > 15) //1.6 < Ratio <= 2.5
|
||||||
|
{
|
||||||
|
coeff = &XV_vscaler_fixedcoeff_taps8[0][0];
|
||||||
|
numTaps = XV_VSCALER_TAPS_8;
|
||||||
|
}
|
||||||
|
else // <= 1.5
|
||||||
|
{
|
||||||
|
coeff = &XV_vscaler_fixedcoeff_taps6[0][0];
|
||||||
|
numTaps = XV_VSCALER_TAPS_6;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
xil_printf("ERR: V-Scaler %d Taps Not Supported",numTaps);
|
xil_printf("ERR: H-Scaler %d Taps Not Supported",numTaps);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else //Scale Up
|
||||||
|
{
|
||||||
|
coeff = &XV_vscaler_fixedcoeff_taps6[0][0];
|
||||||
|
numTaps = XV_VSCALER_TAPS_6;
|
||||||
|
}
|
||||||
|
|
||||||
XV_VScalerLoadUsrCoeff(InstancePtr,
|
XV_VScalerLoadExtCoeff(InstancePtr,
|
||||||
pVscL2Data,
|
VscL2DataPtr,
|
||||||
numPhases,
|
numPhases,
|
||||||
numTaps,
|
numTaps,
|
||||||
coeff);
|
coeff);
|
||||||
|
|
||||||
|
/* Disable use of external coefficients */
|
||||||
|
VscL2DataPtr->UseExtCoeff = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -170,7 +240,7 @@ void XV_VScalerLoadDefaultCoeff(XV_vscaler *InstancePtr,
|
||||||
* storage
|
* storage
|
||||||
*
|
*
|
||||||
* @param InstancePtr is a pointer to the core instance to be worked on.
|
* @param InstancePtr is a pointer to the core instance to be worked on.
|
||||||
* @param pVscL2Data is a pointer to the core instance layer 2 data.
|
* @param VscL2DataPtr is a pointer to the core instance layer 2 data.
|
||||||
* @param num_phases is the number of phases in coefficient table
|
* @param num_phases is the number of phases in coefficient table
|
||||||
* @param num_taps is the number of taps in coefficient table
|
* @param num_taps is the number of taps in coefficient table
|
||||||
* @param Coeff is a pointer to user defined filter coefficients table
|
* @param Coeff is a pointer to user defined filter coefficients table
|
||||||
|
@ -178,8 +248,8 @@ void XV_VScalerLoadDefaultCoeff(XV_vscaler *InstancePtr,
|
||||||
* @return None
|
* @return None
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void XV_VScalerLoadUsrCoeff(XV_vscaler *InstancePtr,
|
void XV_VScalerLoadExtCoeff(XV_vscaler *InstancePtr,
|
||||||
XV_vscaler_l2 *pVscL2Data,
|
XV_vscaler_l2 *VscL2DataPtr,
|
||||||
u16 num_phases,
|
u16 num_phases,
|
||||||
u16 num_taps,
|
u16 num_taps,
|
||||||
const short *Coeff)
|
const short *Coeff)
|
||||||
|
@ -190,7 +260,7 @@ void XV_VScalerLoadUsrCoeff(XV_vscaler *InstancePtr,
|
||||||
* validate input arguments
|
* validate input arguments
|
||||||
*/
|
*/
|
||||||
Xil_AssertVoid(InstancePtr != NULL);
|
Xil_AssertVoid(InstancePtr != NULL);
|
||||||
Xil_AssertVoid(pVscL2Data != NULL);
|
Xil_AssertVoid(VscL2DataPtr != NULL);
|
||||||
Xil_AssertVoid(num_taps <= InstancePtr->Config.NumTaps);
|
Xil_AssertVoid(num_taps <= InstancePtr->Config.NumTaps);
|
||||||
Xil_AssertVoid(num_phases == (1<<InstancePtr->Config.PhaseShift));
|
Xil_AssertVoid(num_phases == (1<<InstancePtr->Config.PhaseShift));
|
||||||
Xil_AssertVoid(Coeff != NULL);
|
Xil_AssertVoid(Coeff != NULL);
|
||||||
|
@ -209,7 +279,7 @@ void XV_VScalerLoadUsrCoeff(XV_vscaler *InstancePtr,
|
||||||
}
|
}
|
||||||
|
|
||||||
//determine if coefficient needs padding (effective vs. max taps)
|
//determine if coefficient needs padding (effective vs. max taps)
|
||||||
pad = XV_VSCALER_MAX_V_TAPS - InstancePtr->Config.NumTaps;
|
pad = XV_VSCALER_MAX_V_TAPS - num_taps;
|
||||||
offset = ((pad) ? (pad>>1) : 0);
|
offset = ((pad) ? (pad>>1) : 0);
|
||||||
|
|
||||||
//Load User defined coefficients into scaler coefficient table
|
//Load User defined coefficients into scaler coefficient table
|
||||||
|
@ -217,7 +287,7 @@ void XV_VScalerLoadUsrCoeff(XV_vscaler *InstancePtr,
|
||||||
{
|
{
|
||||||
for (j=0; j<num_taps; ++j)
|
for (j=0; j<num_taps; ++j)
|
||||||
{
|
{
|
||||||
pVscL2Data->coeff[i][j+offset] = Coeff[i*num_taps+j];
|
VscL2DataPtr->coeff[i][j+offset] = Coeff[i*num_taps+j];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,18 +298,18 @@ void XV_VScalerLoadUsrCoeff(XV_vscaler *InstancePtr,
|
||||||
//pad left
|
//pad left
|
||||||
for (j = 0; j < offset; j++)
|
for (j = 0; j < offset; j++)
|
||||||
{
|
{
|
||||||
pVscL2Data->coeff[i][j] = 0;
|
VscL2DataPtr->coeff[i][j] = 0;
|
||||||
}
|
}
|
||||||
//pad right
|
//pad right
|
||||||
for (j = (num_taps+offset); j < XV_VSCALER_MAX_V_TAPS; j++)
|
for (j = (num_taps+offset); j < XV_VSCALER_MAX_V_TAPS; j++)
|
||||||
{
|
{
|
||||||
pVscL2Data->coeff[i][j] = 0;
|
VscL2DataPtr->coeff[i][j] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable use of external coefficients */
|
/* Enable use of external coefficients */
|
||||||
pVscL2Data->UseExtCoeff = TRUE;
|
VscL2DataPtr->UseExtCoeff = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -260,7 +330,7 @@ void XV_VScalerLoadUsrCoeff(XV_vscaler *InstancePtr,
|
||||||
* computed coefficients
|
* computed coefficients
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
static void XV_VScalerSetCoeff(XV_vscaler *pVsc,
|
static void XV_VScalerSetCoeff(XV_vscaler *pVsc,
|
||||||
XV_vscaler_l2 *pVscL2Data)
|
XV_vscaler_l2 *VscL2DataPtr)
|
||||||
{
|
{
|
||||||
int num_phases = 1<<pVsc->Config.PhaseShift;
|
int num_phases = 1<<pVsc->Config.PhaseShift;
|
||||||
int num_taps = pVsc->Config.NumTaps/2;
|
int num_taps = pVsc->Config.NumTaps/2;
|
||||||
|
@ -274,7 +344,7 @@ static void XV_VScalerSetCoeff(XV_vscaler *pVsc,
|
||||||
for(j=0; j < num_taps; j++)
|
for(j=0; j < num_taps; j++)
|
||||||
{
|
{
|
||||||
rdIndx = j*2+offset;
|
rdIndx = j*2+offset;
|
||||||
val = (pVscL2Data->coeff[i][rdIndx+1] << 16) | (pVscL2Data->coeff[i][rdIndx] & XVSC_MASK_LOW_16BITS);
|
val = (VscL2DataPtr->coeff[i][rdIndx+1] << 16) | (VscL2DataPtr->coeff[i][rdIndx] & XVSC_MASK_LOW_16BITS);
|
||||||
Xil_Out32(baseAddr+((i*num_taps+j)*4), val);
|
Xil_Out32(baseAddr+((i*num_taps+j)*4), val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -294,7 +364,7 @@ static void XV_VScalerSetCoeff(XV_vscaler *pVsc,
|
||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
void XV_VScalerSetup(XV_vscaler *InstancePtr,
|
void XV_VScalerSetup(XV_vscaler *InstancePtr,
|
||||||
XV_vscaler_l2 *pVscL2Data,
|
XV_vscaler_l2 *VscL2DataPtr,
|
||||||
u32 WidthIn,
|
u32 WidthIn,
|
||||||
u32 HeightIn,
|
u32 HeightIn,
|
||||||
u32 HeightOut)
|
u32 HeightOut)
|
||||||
|
@ -305,7 +375,7 @@ void XV_VScalerSetup(XV_vscaler *InstancePtr,
|
||||||
* Assert validates the input arguments
|
* Assert validates the input arguments
|
||||||
*/
|
*/
|
||||||
Xil_AssertVoid(InstancePtr != NULL);
|
Xil_AssertVoid(InstancePtr != NULL);
|
||||||
Xil_AssertVoid(pVscL2Data != NULL);
|
Xil_AssertVoid(VscL2DataPtr != NULL);
|
||||||
Xil_AssertVoid((WidthIn>0) && (WidthIn<=InstancePtr->Config.MaxWidth));
|
Xil_AssertVoid((WidthIn>0) && (WidthIn<=InstancePtr->Config.MaxWidth));
|
||||||
Xil_AssertVoid((HeightIn>0) && (HeightIn<=InstancePtr->Config.MaxHeight));
|
Xil_AssertVoid((HeightIn>0) && (HeightIn<=InstancePtr->Config.MaxHeight));
|
||||||
Xil_AssertVoid((HeightOut>0) && (HeightOut<=InstancePtr->Config.MaxHeight));
|
Xil_AssertVoid((HeightOut>0) && (HeightOut<=InstancePtr->Config.MaxHeight));
|
||||||
|
@ -314,14 +384,17 @@ void XV_VScalerSetup(XV_vscaler *InstancePtr,
|
||||||
|
|
||||||
if(InstancePtr->Config.ScalerType == XV_VSCALER_POLYPHASE)
|
if(InstancePtr->Config.ScalerType == XV_VSCALER_POLYPHASE)
|
||||||
{
|
{
|
||||||
if(!pVscL2Data->UseExtCoeff) //No predefined coefficients
|
if(!VscL2DataPtr->UseExtCoeff) //No user defined coefficients
|
||||||
{
|
{
|
||||||
xil_printf("\r\nERR: V Scaler coefficients not programmed\r\n");
|
/* Determine coefficient table to use */
|
||||||
return;
|
XV_VScalerSelectCoeff(InstancePtr,
|
||||||
|
VscL2DataPtr,
|
||||||
|
HeightIn,
|
||||||
|
HeightOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Program coefficients into the IP register bank */
|
/* Program coefficients into the IP register bank */
|
||||||
XV_VScalerSetCoeff(InstancePtr, pVscL2Data);
|
XV_VScalerSetCoeff(InstancePtr, VscL2DataPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
LineRate = (HeightIn * STEP_PRECISION)/HeightOut;
|
LineRate = (HeightIn * STEP_PRECISION)/HeightOut;
|
||||||
|
|
|
@ -160,15 +160,13 @@ typedef struct
|
||||||
/************************** Function Prototypes ******************************/
|
/************************** Function Prototypes ******************************/
|
||||||
void XV_VScalerStart(XV_vscaler *InstancePtr);
|
void XV_VScalerStart(XV_vscaler *InstancePtr);
|
||||||
void XV_VScalerStop(XV_vscaler *InstancePtr);
|
void XV_VScalerStop(XV_vscaler *InstancePtr);
|
||||||
void XV_VScalerLoadDefaultCoeff(XV_vscaler *InstancePtr,
|
void XV_VScalerLoadExtCoeff(XV_vscaler *InstancePtr,
|
||||||
XV_vscaler_l2 *pVscL2Data);
|
XV_vscaler_l2 *VscL2DataPtr,
|
||||||
void XV_VScalerLoadUsrCoeff(XV_vscaler *InstancePtr,
|
|
||||||
XV_vscaler_l2 *pVscL2Data,
|
|
||||||
u16 num_phases,
|
u16 num_phases,
|
||||||
u16 num_taps,
|
u16 num_taps,
|
||||||
const short *Coeff);
|
const short *Coeff);
|
||||||
void XV_VScalerSetup(XV_vscaler *InstancePtr,
|
void XV_VScalerSetup(XV_vscaler *InstancePtr,
|
||||||
XV_vscaler_l2 *pVscL2Data,
|
XV_vscaler_l2 *VscL2DataPtr,
|
||||||
u32 WidthIn,
|
u32 WidthIn,
|
||||||
u32 HeightIn,
|
u32 HeightIn,
|
||||||
u32 HeightOut);
|
u32 HeightOut);
|
||||||
|
|
Loading…
Add table
Reference in a new issue