IT6801FN图像质量调优

        联阳IT6801FN是HDMI转RGB/BT.1120桥接芯片,海思Hi3536 NVR芯片的Vin只支持BT.1120接口输入,因为Hi3536支持4K@30的编码,所以找到了IT6801FN,它支持行场内嵌、时钟双边沿采样、yuv422 16bit格式输出,刚好能对接海思芯片。当然也可以使用FPGA对接Hi3536,参考我另一篇文章《FPGA实现BT.1120编码》,实现了单边沿采样的BT.1120。

        不用不知道,一用满是坑!官方提供的demo代码写得太乱了。其实像这种芯片没必要提供寄存器手册(你提供了又写得不够详细),应该代码写好点,封装成api接口让我们调用,方便使用才是顾客至上,这样我们还更愿意买你们的芯片!lattice公司的芯片有些是提供api接口的,譬如sii9777s、sii9396s等,不过多线程调用还是难用!

      移植好官方提供的demo其实就可以正常使用了,但我使用IT6801过程中,发现它的图像质量不太好,没有ADV7604等ADI公司的好。

对于rgb转yuv422,0x67寄存器的bit0需要打开,可以滤波,改善图像质量:

觉得色彩不太好的话,可以尝试修改色彩空间转换公式:

这几个寄存器的值对应色彩空间转换方程的系数

#include <stdio.h>

struct coefficient
{
  float fR;
  float fG;
  float fB;
  int   iOffset;
};

struct matrix_param
{
  struct coefficient stY;
  struct coefficient stCb;
  struct coefficient stCr;
};

static int get_coefficient(float data, unsigned char* table)
{
	unsigned short wtmp = 0;
    float tmp = data * 2048;
	if(tmp < 0)
    {
        tmp = 16384.0 + tmp;
    }
	
	wtmp = (unsigned short)(tmp + 0.5); //四舍五入
    table[0] = wtmp&0xff;
    table[1] = (wtmp>>8)&0x3f;
	return 0;
}

static int get_matrix_table(struct matrix_param *pParam, unsigned char CscRegTab[21])
{
    if(!pParam)
    {
      return -1;
    }
	
    CscRegTab[0] = pParam->stY.iOffset;
    CscRegTab[1] = pParam->stCb.iOffset;
    CscRegTab[2] = 0x10;
    get_coefficient(pParam->stY.fG, &CscRegTab[3]);
    get_coefficient(pParam->stY.fR, &CscRegTab[3 + 2]);
    get_coefficient(pParam->stY.fB, &CscRegTab[3 + 4]);
    
    get_coefficient(pParam->stCr.fG, &CscRegTab[3 + 6]);
    get_coefficient(pParam->stCr.fR, &CscRegTab[3 + 8]);
    get_coefficient(pParam->stCr.fB, &CscRegTab[3 + 10]);
    
    get_coefficient(pParam->stCb.fG, &CscRegTab[3 + 12]);
    get_coefficient(pParam->stCb.fR, &CscRegTab[3 + 14]);
    get_coefficient(pParam->stCb.fB, &CscRegTab[3 + 16]);
    
    return 0;
}

static void printMatrix(unsigned char CscRegTab[21])
{
	int i = 0;
	for(i = 0; i < 21; i++)
	{
		if(!i || i%2)
		{
			printf("  ");
		}
		printf("0x%x, ", CscRegTab[i]);
		if((i == 2) || (i == 8) || (i == 14) || (i == 20))
		{
			printf("\n");
		}
	}
	printf("\n");

}

int main(void)
{
    unsigned char CscRegTab[21] = {0};
    struct matrix_param stMatrix= {0};
/**
Y709 =  0.715G +  0.213R +  0.072B + 0
Cr   = -0.464G +  0.511R + -0.047B + 128
Cb   = -0.394G + -0.117R +  0.511B + 128
*/
    stMatrix.stY.fR = 0.213;
	stMatrix.stY.fG = 0.715;
	stMatrix.stY.fB = 0.072;
	stMatrix.stY.iOffset = 0;

	stMatrix.stCr.fR = 0.511;
	stMatrix.stCr.fG = -0.464;
	stMatrix.stCr.fB = -0.047;
	stMatrix.stCr.iOffset = 128;

	stMatrix.stCb.fR = -0.117;
	stMatrix.stCb.fG = -0.394;
	stMatrix.stCb.fB = 0.511;
	stMatrix.stCb.iOffset = 128;

    get_matrix_table(&stMatrix, CscRegTab);
	printMatrix(CscRegTab);
	
  return 0;
}

上面的tool可打印出矩阵列表,bCSCMtx_RGB2YUV_ITU709_16_235:

//以下代码均摘抄自官方demo
static void chgbank(int bank)
{
   hdmirxset(0x0F, 0x03, bank&3); //i2c写接口,0x03是掩码,只对0xf寄存器的bit0和bit1操作,其他位不变,可参考官方demo代码
}

const static unsigned char bCSCMtx_RGB2YUV_ITU709_16_235[]=
{
    0x00,        0x80,        0x10,
    0xB8, 0x05,  0xB4, 0x01,  0x94,0x00,
    0x4A, 0x3C,  0x17, 0x04,  0x9F,0x3F,
    0xD9, 0x3C,  0x10, 0x3F,  0x17,0x04
};

// 设置CSC矩阵Reg170 ~ Reg184
chgbank(1);
hdmirxbwr(REG_RX_170,
          sizeof(bCSCMtx_RGB2YUV_ITU709_16_235),
          bCSCMtx_RGB2YUV_ITU709_16_235);
chgbank(0);
hdmirxwr(REG_RX_067, 0x80 | B_RX_EN_UDFILTER); //RGB24 to YUV422 need up/dn filter.

值得注意的是,上述RGB转yuv公式指的是RGB转yuv4:4:4,因为每一个RGB点均对应一对u、v值。

最后得出结论,IT6801FN还是不用为好!!! 最后发现图像质量是Hi3536的VI引起的,跟IT6801FN无关。

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值