v_hcresampler: Added default filter coefficients

-Added filter coefficient table for 4/6/8/10 taps.
-Added API to load the default coefficients
-Added API to allow user to load coefficients

Signed-off-by: Rohit Consul <rohit.consul@xilinx.com>
Reviewed-by: Andrei Simion <andreis@xilinx.com>
This commit is contained in:
Rohit Consul 2015-07-31 13:47:39 -07:00 committed by Nava kishore Manne
parent 533b4d0587
commit 4054a7aa4e
4 changed files with 359 additions and 36 deletions

View file

@ -1,9 +1,33 @@
# ==============================================================
# File generated by Vivado(TM) HLS - High-Level Synthesis from C, C++ and SystemC
# Version: 2015.1
# Copyright (C) 2015 Xilinx Inc. All rights reserved.
##############################################################################
#
# ==============================================================
# Copyright (C) 2015 Xilinx, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"),to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# Use of the Software is limited solely to applications:
# (a) running on a Xilinx device, or
# (b) that interact with a Xilinx device through a bus or interconnect.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
# Except as contained in this notice, the name of the Xilinx shall not be used
# in advertising or otherwise to promote the sale, use or other dealings in
# this Software without prior written authorization from Xilinx.
###############################################################################
OPTION psf_version = 2.1;

View file

@ -0,0 +1,104 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xv_hcresampler_coeff.c
* @addtogroup v_hcresampler_v1_0
* @{
* @details
*
* This file provides the default fixed coefficient sets for supported taps
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 rco 07/31/15 Initial Release
* </pre>
*
******************************************************************************/
#include "xv_hcresampler_l2.h"
// 4 tap filter
const short XV_hcrsmplrcoeff_taps4[XV_HCRSMPLR_NUM_CONVERSIONS][XV_HCRSMPLR_MAX_PHASES][XV_HCRSMPLR_TAPS_4] =
{
//444->422
{{ 0, 1024, 2048, 1024},
{ 0, 0, 0, 0}
},
//422->444
{{ 0, 0, 4096, 0},
{ 506, 1542, 1542, 506}
}
};
// 6 tap filter
const short XV_hcrsmplrcoeff_taps6[XV_HCRSMPLR_NUM_CONVERSIONS][XV_HCRSMPLR_MAX_PHASES][XV_HCRSMPLR_TAPS_6] =
{
//444->422
{{ 0, 0, 1298, 1500, 1298, 0},
{ 0, 0, 0, 0, 0, 0}
},
//422->444
{{ 0, 0, 0, 4096, 0, 0},
{-327, 792, 1583, 1583, 792, -327}
}
};
// 8 tap filter
const short XV_hcrsmplrcoeff_taps8[XV_HCRSMPLR_NUM_CONVERSIONS][XV_HCRSMPLR_MAX_PHASES][XV_HCRSMPLR_TAPS_8] =
{
//444->422
{{ 0, -988, 0, 1703, 2666, 1703, 0, -988},
{ 0, 0, 0, 0, 0, 0, 0, 0}
},
//422->444
{{ 0, 0, 0, 0, 4096, 0, 0, 0},
{-423, -903, 977, 2397, 2397, 977, -903, -423}
}
};
// 10 tap filter
const short XV_hcrsmplrcoeff_taps10[XV_HCRSMPLR_NUM_CONVERSIONS][XV_HCRSMPLR_MAX_PHASES][XV_HCRSMPLR_TAPS_10] =
{
//444->422
{{ 0, 0, -988, 0, 1703, 2666, 1703, 0, -988, 0},
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
},
//422->444
{{ 0, 0, 0, 0, 0, 4096, 0, 0, 0, 0},
{ 305, -638, -586, 705, 2262, 2262, 705, -586, -638, 305}
}
};

View file

@ -61,9 +61,16 @@
/**************************** Type Definitions *******************************/
/**************************** Local Global *******************************/
const short XV_hcrsmplrcoeff_taps4[XV_HCRSMPLR_NUM_CONVERSIONS][XV_HCRSMPLR_MAX_PHASES][XV_HCRSMPLR_TAPS_4];
const short XV_hcrsmplrcoeff_taps6[XV_HCRSMPLR_NUM_CONVERSIONS][XV_HCRSMPLR_MAX_PHASES][XV_HCRSMPLR_TAPS_6];
const short XV_hcrsmplrcoeff_taps8[XV_HCRSMPLR_NUM_CONVERSIONS][XV_HCRSMPLR_MAX_PHASES][XV_HCRSMPLR_TAPS_8];
const short XV_hcrsmplrcoeff_taps10[XV_HCRSMPLR_NUM_CONVERSIONS][XV_HCRSMPLR_MAX_PHASES][XV_HCRSMPLR_TAPS_10];
/************************** Function Prototypes ******************************/
static void hcrUpdateCoefficients(XV_hcresampler *pHCrsmplr, u32 coeff[2][4]);
static void XV_hcresampler_SetCoefficients(XV_hcresampler *pHCrsmplr,
XV_hcresampler_l2 *pHcrsmplL2Data,
XV_HCRESAMPLER_CONVERSION convType);
/*****************************************************************************/
/**
@ -98,6 +105,144 @@ void XV_HCrsmplStop(XV_hcresampler *InstancePtr)
XV_hcresampler_DisableAutoRestart(InstancePtr);
}
/*****************************************************************************/
/**
* This function loads default filter coefficients in the chroma resampler
* coefficient storage based on the selected TAP configuration
*
* @param InstancePtr is a pointer to the core instance to be worked on.
* @param pHcrsmplL2Data is a pointer to the core instance layer 2 data.
*
* @return None
*
******************************************************************************/
void XV_HCrsmplLoadDefaultCoeff(XV_hcresampler *InstancePtr,
XV_hcresampler_l2 *pHcrsmplL2Data)
{
u16 numTaps;
const short *coeff;
/*
* validates input arguments
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(pHcrsmplL2Data != NULL);
numTaps = InstancePtr->Config.NumTaps;
switch(numTaps)
{
case XV_HCRSMPLR_TAPS_4:
coeff = &XV_hcrsmplrcoeff_taps4[0][0][0];
break;
case XV_HCRSMPLR_TAPS_6:
coeff = &XV_hcrsmplrcoeff_taps6[0][0][0];
break;
case XV_HCRSMPLR_TAPS_8:
coeff = &XV_hcrsmplrcoeff_taps8[0][0][0];
break;
case XV_HCRSMPLR_TAPS_10:
coeff = &XV_hcrsmplrcoeff_taps10[0][0][0];
break;
default:
xil_printf("ERR: H Chroma Resampler %d Taps Not Supported",numTaps);
return;
}
XV_HCrsmplrLoadUsrCoeff(InstancePtr,
pHcrsmplL2Data,
numTaps,
coeff);
}
/*****************************************************************************/
/**
* This function loads user defined filter coefficients in the horiz. chroma
* resampler coefficient storage
*
* @param InstancePtr is a pointer to the core instance to be worked on.
* @param pHcrsmplL2Data is a pointer to the core instance layer 2 data.
* @param num_taps is the number of taps
* @param Coeff is a pointer to user defined filter coefficients table
*
* @return None
*
******************************************************************************/
void XV_HCrsmplrLoadUsrCoeff(XV_hcresampler *InstancePtr,
XV_hcresampler_l2 *pHcrsmplL2Data,
u16 num_taps,
const short *Coeff)
{
int pad, offset;
int index, phase, tap, conversion;
/*
* validate input arguments
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(pHcrsmplL2Data != NULL);
Xil_AssertVoid(num_taps <= InstancePtr->Config.NumTaps);
Xil_AssertVoid(Coeff != NULL);
switch(num_taps)
{
case XV_HCRSMPLR_TAPS_4:
case XV_HCRSMPLR_TAPS_6:
case XV_HCRSMPLR_TAPS_8:
case XV_HCRSMPLR_TAPS_10:
break;
default:
xil_printf("\r\nERR: H Chroma Resampler %d TAPS not supported. (Select from 4/6/8/10)\r\n");
return;
}
//determine if coefficient needs padding (effective vs. max taps)
pad = XV_HCRSMPLR_MAX_TAPS - InstancePtr->Config.NumTaps;
offset = ((pad) ? (pad>>1) : 0);
index = 0;
//Load User defined coefficients into coefficient storage
for (conversion = 0; conversion < XV_HCRSMPLR_NUM_CONVERSIONS; ++conversion)
{
for (phase = 0; phase < XV_HCRSMPLR_MAX_PHASES; ++phase)
{
for (tap = 0; tap < num_taps; ++tap)
{
index = (conversion*XV_HCRSMPLR_MAX_PHASES*num_taps) + (phase*num_taps) + tap;
pHcrsmplL2Data->coeff[conversion][phase][tap+offset] = Coeff[index];
}
}
}
if(pad) //effective taps < max_taps
{
for (conversion = 0; conversion < XV_HCRSMPLR_NUM_CONVERSIONS; ++conversion)
{
for(phase = 0; phase < XV_HCRSMPLR_MAX_PHASES; ++phase)
{
//pad left
for (tap = 0; tap < offset; ++tap)
{
pHcrsmplL2Data->coeff[conversion][phase][tap] = 0;
}
//pad right
for (tap = (num_taps+offset); tap < XV_HCRSMPLR_MAX_TAPS; ++tap)
{
pHcrsmplL2Data->coeff[conversion][phase][tap] = 0;
}
}
}
}
/* Enable use of external coefficients */
pHcrsmplL2Data->UseExtCoeff = TRUE;
}
/*****************************************************************************/
/**
* This function configures the Chroma resampler active resolution
@ -125,6 +270,7 @@ void XV_HCrsmplSetActiveSize(XV_hcresampler *InstancePtr,
* conversion
*
* @param InstancePtr is a pointer to the core instance to be worked on.
* @param pHcrsmplL2Data is a pointer to the core instance layer 2 data.
* @param formatIn is the input chroma format
* @param formatOut is required chroma format
*
@ -132,15 +278,17 @@ void XV_HCrsmplSetActiveSize(XV_hcresampler *InstancePtr,
*
******************************************************************************/
void XV_HCrsmplSetFormat(XV_hcresampler *InstancePtr,
XV_hcresampler_l2 *pHcrsmplL2Data,
XVidC_ColorFormat formatIn,
XVidC_ColorFormat formatOut)
{
u32 K[2][4] = {{0}};
XV_HCRESAMPLER_CONVERSION convType;
/*
* Assert validates the input arguments
* validates the input arguments
*/
Xil_AssertVoid(InstancePtr != NULL);
Xil_AssertVoid(pHcrsmplL2Data != NULL);
XV_hcresampler_Set_HwReg_input_video_format(InstancePtr, formatIn);
XV_hcresampler_Set_HwReg_output_video_format(InstancePtr, formatOut);
@ -148,29 +296,14 @@ void XV_HCrsmplSetFormat(XV_hcresampler *InstancePtr,
if((formatIn == XVIDC_CSF_YCRCB_422) &&
(formatOut == XVIDC_CSF_YCRCB_444))
{
K[0][0] = 0;
K[0][1] = 0;
K[0][2] = 4096;
K[0][3] = 0;
K[1][0] = 506;
K[1][1] = 1542;
K[1][2] = 1542;
K[1][3] = 506;
convType = XV_HCRSMPLR_422_TO_444;
}
else if((formatIn == XVIDC_CSF_YCRCB_444) &&
(formatOut == XVIDC_CSF_YCRCB_422))
{
K[0][0] = 0;
K[0][1] = 1024;
K[0][2] = 2048;
K[0][3] = 1024;
K[1][0] = 0;
K[1][1] = 0;
K[1][2] = 0;
K[1][3] = 0;
convType = XV_HCRSMPLR_444_TO_422;
}
hcrUpdateCoefficients(InstancePtr, K);
XV_hcresampler_SetCoefficients(InstancePtr, pHcrsmplL2Data, convType);
}
/*****************************************************************************/
@ -179,21 +312,36 @@ void XV_HCrsmplSetFormat(XV_hcresampler *InstancePtr,
* required conversion
*
* @param pHCrsmplr is a pointer to the core instance to be worked on.
* @param coeff is the array holding computed coefficients
* @param pHcrsmplL2Data is a pointer to the core instance layer 2 data.
* @param convType is the format conversion requested
*
* @return None
*
******************************************************************************/
static void hcrUpdateCoefficients(XV_hcresampler *pHCrsmplr, u32 coeff[2][4])
static void XV_hcresampler_SetCoefficients(XV_hcresampler *pHCrsmplr,
XV_hcresampler_l2 *pHcrsmplL2Data,
XV_HCRESAMPLER_CONVERSION convType)
{
XV_hcresampler_Set_HwReg_coefs_0_0(pHCrsmplr, coeff[0][0]);
XV_hcresampler_Set_HwReg_coefs_0_1(pHCrsmplr, coeff[0][1]);
XV_hcresampler_Set_HwReg_coefs_0_2(pHCrsmplr, coeff[0][2]);
XV_hcresampler_Set_HwReg_coefs_0_3(pHCrsmplr, coeff[0][3]);
XV_hcresampler_Set_HwReg_coefs_1_0(pHCrsmplr, coeff[1][0]);
XV_hcresampler_Set_HwReg_coefs_1_1(pHCrsmplr, coeff[1][1]);
XV_hcresampler_Set_HwReg_coefs_1_2(pHCrsmplr, coeff[1][2]);
XV_hcresampler_Set_HwReg_coefs_1_3(pHCrsmplr, coeff[1][3]);
u16 pad, offset;
u32 baseaddr;
u16 tap, phase,regcount;
//determine if coefficients are padded
pad = XV_HCRSMPLR_MAX_TAPS - pHCrsmplr->Config.NumTaps;
offset = ((pad) ? (pad>>1) : 0);
regcount = 0; //number of registers being written
baseaddr = XV_HCRESAMPLER_CTRL_ADDR_HWREG_COEFS_0_0_DATA;
baseaddr += pHCrsmplr->Config.BaseAddress;
for(phase = 0; phase < XV_HCRSMPLR_MAX_PHASES; ++phase)
{
for(tap = 0; tap < pHCrsmplr->Config.NumTaps; ++tap)
{
Xil_Out32((baseaddr+(regcount*8)), pHcrsmplL2Data->coeff[convType][phase][offset+tap]);
++regcount;
}
}
}
/*****************************************************************************/

View file

@ -106,18 +106,65 @@ extern "C" {
#include "xv_hcresampler.h"
/************************** Constant Definitions *****************************/
/** @name Hw Configuration
* @{
* The following constants define the horiz. resampler HW MAX configuration
*
*/
#define XV_HCRSMPLR_MAX_TAPS (10)
#define XV_HCRSMPLR_MAX_PHASES (2)
/**************************** Type Definitions *******************************/
/**
* This typedef enumerates the supported taps
*/
typedef enum
{
XV_HCRSMPLR_TAPS_4 = 4,
XV_HCRSMPLR_TAPS_6 = 6,
XV_HCRSMPLR_TAPS_8 = 8,
XV_HCRSMPLR_TAPS_10 = 10,
XV_HCRSMPLR_NUM_SUPPORTED_TAPS_CONFIG = 4
}XV_HCRESAMPLER_TAPS;
/**
* This typedef enumerates the conversion type
*/
typedef enum
{
XV_HCRSMPLR_444_TO_422 = 0,
XV_HCRSMPLR_422_TO_444 ,
XV_HCRSMPLR_NUM_CONVERSIONS
}XV_HCRESAMPLER_CONVERSION;
/**
* H Chroma Resampler Layer 2 data. The user is required to allocate a
* variable of this type for every H chroma resampler device in the system.
* A pointer to a variable of this type is then passed to the driver API
* functions.
*/
typedef struct
{
u16 UseExtCoeff;
short coeff[XV_HCRSMPLR_NUM_CONVERSIONS][XV_HCRSMPLR_MAX_PHASES][XV_HCRSMPLR_MAX_TAPS];
}XV_hcresampler_l2;
/************************** Function Prototypes ******************************/
void XV_HCrsmplStart(XV_hcresampler *InstancePtr);
void XV_HCrsmplStop(XV_hcresampler *InstancePtr);
void XV_HCrsmplLoadDefaultCoeff(XV_hcresampler *InstancePtr,
XV_hcresampler_l2 *pHcrsmplL2Data);
void XV_HCrsmplrLoadUsrCoeff(XV_hcresampler *InstancePtr,
XV_hcresampler_l2 *pHcrsmplL2Data,
u16 num_taps,
const short *Coeff);
void XV_HCrsmplSetActiveSize(XV_hcresampler *InstancePtr,
u32 width,
u32 height);
void XV_HCrsmplSetFormat(XV_hcresampler *InstancePtr,
XV_hcresampler_l2 *pHcrsmplL2Data,
XVidC_ColorFormat formatIn,
XVidC_ColorFormat formatOut);