amvecm: pq: lc: add debug interface [1/1]

PD#SWPL-2583

Problem:
add debug interface

Solution:
add lc reg lut dump and write interface
add demo mode
add dump hist interface
add dump curve node interface

Verify:
x301

Change-Id: I85be40f76f252bbaa2ffc69710cc7158ed91bbc4
Signed-off-by: Bencheng Jing <bencheng.jing@amlogic.com>
This commit is contained in:
Bencheng Jing
2018-11-28 11:29:04 +08:00
committed by Jianxin Pan
parent ea91017e30
commit 1159ecefca
3 changed files with 399 additions and 23 deletions

View File

@@ -5344,6 +5344,131 @@ static ssize_t amvecm_get_hdr_type_store(struct class *cls,
return count;
}
static void lc_rd_reg(enum lc_reg_lut_e reg_sel)
{
int i, tmp, tmp1, tmp2;
switch (reg_sel) {
case SATUR_LUT:
for (i = 0; i < 31 ; i++) {
tmp = READ_VPP_REG(SRSHARP1_LC_SAT_LUT_0_1 + i);
tmp1 = (tmp >> 16) & 0xfff;
tmp2 = tmp & 0xfff;
pr_info("reg_lc_satur_lut[%d] =%4d.\n",
2*i, tmp1);
pr_info("reg_lc_satur_lut[%d] =%4d.\n",
2*i + 1, tmp2);
}
tmp = READ_VPP_REG(SRSHARP1_LC_SAT_LUT_62);
pr_info("reg_lc_satur_lut[62] =%4d.\n",
tmp & 0xfff);
break;
case YMINVAL_LMT:
for (i = 0; i < 6 ; i++) {
tmp = READ_VPP_REG(LC_CURVE_YMINVAL_LMT_0_1 + i);
tmp1 = (tmp >> 16) & 0x3ff;
tmp2 = tmp & 0x3ff;
pr_info("reg_yminVal_lmt[%d] =%4d.\n",
2*i, tmp1);
pr_info("reg_yminVal_lmt[%d] =%4d.\n",
2*i + 1, tmp2);
}
break;
case YPKBV_YMAXVAL_LMT:
for (i = 0; i < 6 ; i++) {
tmp = READ_VPP_REG(LC_CURVE_YPKBV_YMAXVAL_LMT_0_1 + i);
tmp1 = (tmp >> 16) & 0x3ff;
tmp2 = tmp & 0x3ff;
pr_info("reg_lc_ypkBV_ymaxVal_lmt[%d] =%4d.\n",
2*i, tmp1);
pr_info("reg_lc_ypkBV_ymaxVal_lmt[%d] =%4d.\n",
2*i + 1, tmp2);
}
break;
case YPKBV_RAT:
tmp = READ_VPP_REG(LC_CURVE_YPKBV_RAT);
pr_info("reg_lc_ypkBV_ratio[0] =%4d.\n",
(tmp>>24) & 0xff);
pr_info("reg_lc_ypkBV_ratio[1] =%4d.\n",
(tmp>>16) & 0xff);
pr_info("reg_lc_ypkBV_ratio[2] =%4d.\n",
(tmp>>8) & 0xff);
pr_info("reg_lc_ypkBV_ratio[3] =%4d.\n",
tmp & 0xff);
break;
case YPKBV_SLP_LMT:
tmp = READ_VPP_REG(LC_CURVE_YPKBV_SLP_LMT);
pr_info("reg_lc_ypkBV_slope_lmt[0] =%4d.\n",
(tmp>>8) & 0xff);
pr_info("reg_lc_ypkBV_slope_lmt[1] =%4d.\n",
tmp & 0xff);
break;
case CNTST_LMT:
tmp = READ_VPP_REG(LC_CURVE_CONTRAST__LMT_LH);
pr_info("reg_lc_cntstlmt_low[0] =%4d.\n",
(tmp>>24) & 0xff);
pr_info("reg_lc_cntstlmt_high[0] =%4d.\n",
(tmp>>16) & 0xff);
pr_info("reg_lc_cntstlmt_low[1] =%4d.\n",
(tmp>>8) & 0xff);
pr_info("reg_lc_cntstlmt_high[1] =%4d.\n",
tmp & 0xff);
break;
default:
break;
}
}
static void lc_wr_reg(int *p, enum lc_reg_lut_e reg_sel)
{
int i, tmp, tmp1, tmp2;
switch (reg_sel) {
case SATUR_LUT:
for (i = 0; i < 31 ; i++) {
tmp1 = *(p + 2*i);
tmp2 = *(p + 2*i + 1);
tmp = ((tmp1 & 0xfff)<<16) | (tmp2 & 0xfff);
WRITE_VPP_REG(SRSHARP1_LC_SAT_LUT_0_1 + i, tmp);
}
tmp = (*(p+62)) & 0xfff;
WRITE_VPP_REG(SRSHARP1_LC_SAT_LUT_62, tmp);
break;
case YMINVAL_LMT:
for (i = 0; i < 6 ; i++) {
tmp1 = *(p + 2*i);
tmp2 = *(p + 2*i + 1);
tmp = ((tmp1&0x3ff) << 16) | (tmp2 & 0x3ff);
WRITE_VPP_REG(LC_CURVE_YMINVAL_LMT_0_1 + i, tmp);
}
break;
case YPKBV_YMAXVAL_LMT:
for (i = 0; i < 6 ; i++) {
tmp1 = *(p + 2*i);
tmp2 = *(p + 2*i + 1);
tmp = ((tmp1&0x3ff) << 16) | (tmp2 & 0x3ff);
WRITE_VPP_REG(LC_CURVE_YPKBV_YMAXVAL_LMT_0_1 + i, tmp);
}
break;
case YPKBV_RAT:
tmp = (*p & 0xff) << 24 | (*(p+1) & 0xff) << 16 |
(*(p+2) & 0xff) << 8 | (*(p+3) & 0xff);
WRITE_VPP_REG(LC_CURVE_YPKBV_RAT, tmp);
break;
case YPKBV_SLP_LMT:
tmp = (*p & 0xff) << 8 | (*(p+1) & 0xff);
WRITE_VPP_REG(LC_CURVE_YPKBV_SLP_LMT, tmp);
break;
case CNTST_LMT:
tmp = (*p & 0xff) << 24 | (*(p+1) & 0xff) << 16 |
(*(p+2) & 0xff) << 8 | (*(p+3) & 0xff);
WRITE_VPP_REG(LC_CURVE_CONTRAST__LMT_LH, tmp);
break;
default:
break;
}
}
static ssize_t amvecm_lc_show(struct class *cla,
struct class_attribute *attr, char *buf)
{
@@ -5355,6 +5480,22 @@ static ssize_t amvecm_lc_show(struct class *cla,
"echo lc disable > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc_dbg value > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc_demo_mode enable/disable > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc_dump_reg parm1 > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo lc_rd_reg parm1 parm2 > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"parm1: 0x1,0x2,0x4,0x8,0x10,0x20...\n");
len += sprintf(buf+len,
"parm2: decimal strings, each data width is 4.\n");
len += sprintf(buf+len,
"echo dump_hist all > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo dump_hist chosen hs he vs ve cnt > /sys/class/amvecm/lc\n");
len += sprintf(buf+len,
"echo dump_curve cnt > /sys/class/amvecm/lc\n");
return len;
}
@@ -5363,6 +5504,8 @@ static ssize_t amvecm_lc_store(struct class *cls,
const char *buf, size_t count)
{
char *buf_orig, *parm[8] = {NULL};
int reg_lut[63] = {0};
enum lc_reg_lut_e reg_sel;
long val = 0;
if (!buf)
@@ -5379,10 +5522,8 @@ static ssize_t amvecm_lc_store(struct class *cls,
else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "lc_dbg")) {
if (kstrtoul(parm[1], 16, &val) < 0) {
kfree(buf_orig);
return -EINVAL;
}
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
amlc_debug = val;
} else if (!strcmp(parm[0], "lc_demo_mode")) {
if (!strcmp(parm[1], "enable"))
@@ -5391,11 +5532,85 @@ static ssize_t amvecm_lc_store(struct class *cls,
lc_demo_mode = 0;
else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "lc_dump_reg")) {
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
reg_sel = val;
if (reg_sel == SATUR_LUT)
lc_rd_reg(SATUR_LUT);
else if (reg_sel == YMINVAL_LMT)
lc_rd_reg(YMINVAL_LMT);
else if (reg_sel == YPKBV_YMAXVAL_LMT)
lc_rd_reg(YPKBV_YMAXVAL_LMT);
else if (reg_sel == YPKBV_RAT)
lc_rd_reg(YPKBV_RAT);
else if (reg_sel == YPKBV_SLP_LMT)
lc_rd_reg(YPKBV_SLP_LMT);
else if (reg_sel == CNTST_LMT)
lc_rd_reg(CNTST_LMT);
else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "lc_wr_reg")) {
if (kstrtoul(parm[1], 16, &val) < 0)
goto free_buf;
reg_sel = val;
if (parm[2] == NULL)
goto free_buf;
str_sapr_to_d(parm[2], reg_lut, 5);
if (reg_sel == SATUR_LUT)
lc_wr_reg(reg_lut, SATUR_LUT);
else if (reg_sel == YMINVAL_LMT)
lc_wr_reg(reg_lut, YMINVAL_LMT);
else if (reg_sel == YPKBV_YMAXVAL_LMT)
lc_wr_reg(reg_lut, YPKBV_YMAXVAL_LMT);
else if (reg_sel == YPKBV_RAT)
lc_wr_reg(reg_lut, YPKBV_RAT);
else if (reg_sel == YPKBV_SLP_LMT)
lc_wr_reg(reg_lut, YPKBV_SLP_LMT);
else if (reg_sel == CNTST_LMT)
lc_wr_reg(reg_lut, CNTST_LMT);
else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "dump_hist")) {
if (!strcmp(parm[1], "all")) {
/*dump all hist in one frame*/
lc_hist_prcnt = 1;
amlc_debug = 0x2;
} else if (!strcmp(parm[1], "chosen")) {
/*dump multiple frames in selected area*/
if (parm[6] == NULL)
goto free_buf;
if (kstrtoul(parm[2], 10, &val) < 0)
goto free_buf;
lc_hist_hs = val;
if (kstrtoul(parm[3], 10, &val) < 0)
goto free_buf;
lc_hist_he = val;
if (kstrtoul(parm[4], 10, &val) < 0)
goto free_buf;
lc_hist_vs = val;
if (kstrtoul(parm[5], 10, &val) < 0)
goto free_buf;
lc_hist_ve = val;
if (kstrtoul(parm[6], 10, &val) < 0)
goto free_buf;
lc_hist_prcnt = val;
amlc_debug = 0x4;
} else
pr_info("unsupprt cmd!\n");
} else if (!strcmp(parm[0], "dump_curve")) {
if (kstrtoul(parm[1], 10, &val) < 0)
goto free_buf;
lc_curve_prcnt = val;
} else
pr_info("unsupprt cmd!\n");
kfree(buf_orig);
return count;
free_buf:
kfree(buf_orig);
return -EINVAL;
}
@@ -5883,6 +6098,7 @@ static int __exit aml_vecm_remove(struct platform_device *pdev)
cancel_work_sync(&aml_lcd_vlock_param_work);
#endif
probe_ok = 0;
lc_free();
pr_info("[amvecm.] : amvecm_exit.\n");
return 0;
}
@@ -5928,6 +6144,7 @@ static void amvecm_shutdown(struct platform_device *pdev)
#ifdef CONFIG_AML_LCD
aml_lcd_notifier_unregister(&aml_lcd_gamma_nb);
#endif
lc_free();
}
static const struct of_device_id aml_vecm_dt_match[] = {

View File

@@ -21,7 +21,7 @@ int lc_en;
int lc_demo_mode;
int lc_en_chflg = 0xff;
static int lc_flag = 0xff;
static int lc_szcurve[192];
static int *lc_szcurve;
/*local contrast begin*/
static void lc_mtx_set(enum lc_mtx_sel_e mtx_sel,
@@ -403,31 +403,54 @@ static void read_lc_curve(void)
{
int blk_hnum;
int blk_vnum;
int i;
int i, j;
unsigned int dwTemp;
unsigned int temp1, temp2;
if (!lc_szcurve) {
pr_amlc_dbg("%s: lc_szcurve not init!", __func__);
return;
}
dwTemp = READ_VPP_REG(LC_CURVE_HV_NUM);
blk_hnum = (dwTemp >> 8) & 0x1f;
blk_vnum = (dwTemp) & 0x1f;
WRITE_VPP_REG(LC_CURVE_RAM_CTRL, 1);
WRITE_VPP_REG(LC_CURVE_RAM_ADDR, 0);
for (i = 0; i < blk_hnum * blk_vnum; i++) {
lc_szcurve[i*2+0] = READ_VPP_REG(LC_CURVE_RAM_DATA);
lc_szcurve[i*2+1] = READ_VPP_REG(LC_CURVE_RAM_DATA);
for (i = 0; i < blk_vnum; i++) {
for (j = 0; j < blk_hnum; j++) {
temp1 = READ_VPP_REG(LC_CURVE_RAM_DATA);
temp2 = READ_VPP_REG(LC_CURVE_RAM_DATA);
lc_szcurve[(i*blk_hnum + j)*6+0] =
temp1 & 0x3ff;/*bit0:9*/
lc_szcurve[(i*blk_hnum + j)*6+1] =
(temp1>>10) & 0x3ff;/*bit10:19*/
lc_szcurve[(i*blk_hnum + j)*6+2] =
(temp1>>20) & 0x3ff;/*bit20:29*/
lc_szcurve[(i*blk_hnum + j)*6+3] =
temp2 & 0x3ff;/*bit0:9*/
lc_szcurve[(i*blk_hnum + j)*6+4] =
(temp2>>10) & 0x3ff;/*bit10:19*/
lc_szcurve[(i*blk_hnum + j)*6+5] =
(temp2>>20) & 0x3ff;/*bit20:29*/
}
}
WRITE_VPP_REG(LC_CURVE_RAM_CTRL, 0);
}
static void lc_demo_wr_curve(int h_num, int v_num)
{
int i, j;
int i, j, temp1, temp2;
for (i = 0; i < v_num; i++) {
for (j = 0; j < h_num / 2; j++) {
WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA,
lc_szcurve[2 * (i * h_num + j) + 0]);
WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA,
lc_szcurve[2 * (i * h_num + j) + 1]);
temp1 = lc_szcurve[6 * (i * h_num + j) + 0] |
(lc_szcurve[6 * (i * h_num + j) + 1] << 10) |
(lc_szcurve[6 * (i * h_num + j) + 2] << 20);
temp2 = lc_szcurve[6 * (i * h_num + j) + 3] |
(lc_szcurve[6 * (i * h_num + j) + 4] << 10) |
(lc_szcurve[6 * (i * h_num + j) + 5] << 20);
WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA, temp1);
WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA, temp2);
}
for (j = h_num / 2; j < h_num; j++) {
WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA,
@@ -440,16 +463,23 @@ static void lc_demo_wr_curve(int h_num, int v_num)
static int lc_demo_check_curve(int h_num, int v_num)
{
int i, j, temp, flag;
int i, j, temp, temp1, flag;
flag = 0;
for (i = 0; i < v_num; i++) {
for (j = 0; j < h_num / 2; j++) {
temp = READ_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA);
if (temp != lc_szcurve[2 * (i * h_num + j) + 0])
temp1 = lc_szcurve[6 * (i * h_num + j) + 0] |
(lc_szcurve[6 * (i * h_num + j) + 1] << 10) |
(lc_szcurve[6 * (i * h_num + j) + 2] << 20);
if (temp != temp1)
flag = (2 * (i * h_num + j) + 0) | (1 << 31);
temp = READ_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA);
if (temp != lc_szcurve[2 * (i * h_num + j) + 1])
temp1 = lc_szcurve[6 * (i * h_num + j) + 3] |
(lc_szcurve[6 * (i * h_num + j) + 4] << 10) |
(lc_szcurve[6 * (i * h_num + j) + 5] << 20);
if (temp != temp1)
flag = (2 * (i * h_num + j) + 1) | (1 << 31);
}
for (j = h_num / 2; j < h_num; j++) {
@@ -468,8 +498,12 @@ static int set_lc_curve(int binit, int bcheck)
int i, h_num, v_num;
unsigned int hvTemp;
int rflag;
int temp;
int temp, temp1;
if (!lc_szcurve) {
pr_amlc_dbg("%s: lc_szcurve not init!", __func__);
return -EINVAL;
}
rflag = 0;
hvTemp = READ_VPP_REG(SRSHARP1_LC_HV_NUM);
h_num = (hvTemp >> 8) & 0x1f;
@@ -491,9 +525,13 @@ static int set_lc_curve(int binit, int bcheck)
else
for (i = 0; i < h_num * v_num; i++) {
WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA,
lc_szcurve[2 * i + 0]);
lc_szcurve[6 * i + 0]|
(lc_szcurve[6 * i + 1]<<10)|
(lc_szcurve[6 * i + 2]<<20));
WRITE_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA,
lc_szcurve[2 * i + 1]);
lc_szcurve[6 * i + 3]|
(lc_szcurve[6 * i + 4]<<10)|
(lc_szcurve[6 * i + 5]<<20));
}
}
WRITE_VPP_REG_BITS(SRSHARP1_LC_MAP_RAM_CTRL, 0, 0, 1);
@@ -506,10 +544,16 @@ static int set_lc_curve(int binit, int bcheck)
else
for (i = 0; i < h_num * v_num; i++) {
temp = READ_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA);
if (temp != lc_szcurve[2 * i + 0])
temp1 = lc_szcurve[6 * i + 0]|
(lc_szcurve[6 * i + 1]<<10)|
(lc_szcurve[6 * i + 2]<<20);
if (temp != temp1)
rflag = (2 * i + 0) | (1 << 31);
temp = READ_VPP_REG(SRSHARP1_LC_MAP_RAM_DATA);
if (temp != lc_szcurve[2 * i + 1])
temp1 = lc_szcurve[6 * i + 3]|
(lc_szcurve[6 * i + 4]<<10)|
(lc_szcurve[6 * i + 5]<<20);
if (temp != temp1)
rflag = (2 * i + 1) | (1 << 31);
}
WRITE_VPP_REG_BITS(SRSHARP1_LC_MAP_RAM_CTRL, 0, 0, 1);
@@ -524,6 +568,81 @@ static void lc_fw_curve_iir(struct vframe_s *vf)
return;
}
/*print statistics hist and curve, vlsi suggest add*/
unsigned int lc_hist_vs = 4;
unsigned int lc_hist_ve = 6;
unsigned int lc_hist_hs;
unsigned int lc_hist_he = 11;
unsigned int lc_hist_prcnt;
unsigned int lc_curve_prcnt;
static int *lc_hist;
static void lc_read_region(void)
{
int i, j, k;
int data32;
int rgb_min, rgb_max;
int dwTemp, blk_hnum, blk_vnum;
if (!lc_hist) {
pr_amlc_dbg("%s: lc_hist not init!", __func__);
return;
}
WRITE_VPP_REG_BITS(0x4037, 1, 14, 1);
dwTemp = READ_VPP_REG(LC_CURVE_HV_NUM);
blk_hnum = (dwTemp >> 8) & 0x1f;
blk_vnum = (dwTemp) & 0x1f;
data32 = READ_VPP_REG(LC_STTS_HIST_START_RD_REGION);
for (i = 0; i < blk_vnum; i++)
for (j = 0; j < blk_hnum; j++) {
data32 = READ_VPP_REG(LC_STTS_HIST_START_RD_REGION);
if ((i >= lc_hist_vs) && (i <= lc_hist_ve) &&
(j >= lc_hist_hs) && (j <= lc_hist_he) &&
(amlc_debug == 0x4))
pr_info("========[r,c](%2d,%2d)======\n", i, j);
for (k = 0; k < 17; k++) {
data32 = READ_VPP_REG(LC_STTS_HIST_READ_REGION);
lc_hist[(i*blk_hnum+j)*17 + k] = data32;
if ((i >= lc_hist_vs) && (i <= lc_hist_ve) &&
(j >= lc_hist_hs) && (j <= lc_hist_he)
&& (amlc_debug == 0x4)) {
/*print chosen hist*/
if (k == 16) {/*last bin*/
rgb_min =
(data32 >> 10) & 0x3ff;
rgb_max = (data32) & 0x3ff;
pr_info("[%2d]:%d,%d\n",
k, rgb_min, rgb_max);
} else
pr_info("[%2d]:%d\n",
k, data32);
}
}
}
if (amlc_debug == 0x2)/*print all hist data*/
for (i = 0; i < 8*12*17; i++)
pr_info("%x\n", lc_hist[i]);
}
static void lc_prt_curve(void)
{/*print curve node*/
int i, j;
int dwTemp, blk_hnum, blk_vnum;
dwTemp = READ_VPP_REG(LC_CURVE_HV_NUM);
blk_hnum = (dwTemp >> 8) & 0x1f;
blk_vnum = (dwTemp) & 0x1f;
pr_amlc_dbg("======lc_prt curve node=======\n");
for (i = 0; i < blk_hnum*blk_vnum; i++) {
for (j = 0; j < 6 ; j++)
pr_amlc_dbg("%d\n", lc_szcurve[i*6 + j]);
pr_amlc_dbg("\n");
}
}
void lc_init(void)
{
int h_num, v_num;
@@ -537,6 +656,14 @@ void lc_init(void)
if (!lc_en)
return;
lc_szcurve = kzalloc(580 * sizeof(int), GFP_KERNEL);
if (!lc_szcurve)
return;
lc_hist = kzalloc(1632 * sizeof(int), GFP_KERNEL);
if (!lc_hist) {
kfree(lc_szcurve);
return;
}
lc_top_config(0, h_num, v_num, height, width);
lc_mtx_set(INP_MTX, LC_MTX_YUV709L_RGB, 1);
@@ -570,11 +697,24 @@ void lc_process(struct vframe_s *vf,
lc_config(lc_en, vf, sps_h_en, sps_v_en);
read_lc_curve();
lc_fw_curve_iir(vf);
if (lc_curve_prcnt > 0) { /*debug lc curve node*/
lc_prt_curve();
lc_curve_prcnt--;
}
if (lc_hist_prcnt > 0) { /*debug hist*/
lc_read_region();
lc_hist_prcnt--;
}
if (set_lc_curve(0, 1))
pr_amlc_dbg("%s: set lc curve fail", __func__);
lc_flag = 0xff;
}
void lc_free(void)
{
kfree(lc_szcurve);
kfree(lc_hist);
}

View File

@@ -35,12 +35,31 @@ enum lc_mtx_csc_e {
LC_MTX_MAX
};
enum lc_reg_lut_e {
SATUR_LUT = 0x1,
YMINVAL_LMT = 0x2,
YPKBV_YMAXVAL_LMT = 0x4,
YPKBV_RAT = 0x8,
YPKBV_SLP_LMT = 0x10,
CNTST_LMT = 0x20,
MAX_REG_LUT
};
extern int amlc_debug;
extern int lc_en;
extern int lc_demo_mode;
extern unsigned int lc_hist_vs;
extern unsigned int lc_hist_ve;
extern unsigned int lc_hist_hs;
extern unsigned int lc_hist_he;
extern unsigned int lc_hist_prcnt;
extern unsigned int lc_curve_prcnt;
extern void lc_init(void);
extern void lc_process(struct vframe_s *vf,
unsigned int sps_h_en,
unsigned int sps_v_en);
extern void lc_free(void);
#endif