首先,致谢微凉大侠的工作,让驱动TVD模块,得以成为可能。
分享F1C100S的TVD源码,TVIN0接CVBS摄像头采集数据显示到LCD屏
https://whycan.com/t_5612.html
经过两天的研究,搜遍整个互联网,综合所有能找到的资料,编写了一个TVD驱动,虽然不完美,还有很多坑,但还是在这里总结下,避免后人重复踩坑。
1,首先是修改pll video时钟,因为TVD模块需要使用27MHZ,这里一般需要将pll设为297MHZ, 但因为需要兼容某些屏幕,这个时钟偏低,重新计算了一个时钟378MHZ,这个也可以方便的分频出27MHZ出来。
2,关于TVD寄存器,这个全志是完全没有释放出来,我这里找到了D1手册,还有F133手册里有TVD的相关说明,虽然完全对不上,但可以用来理解TVD模块,然后有针对性的去找参考。
3,实验平台采用歪朵拉r3,这个硬件上应该存在异常,我这边测试时,去掉了R30这个75欧匹配电组,不然完全找不到信号,一直蓝屏,还有一个需要注意的,CVBS的地也不能接,如果接了,就白屏,验证过,不是驱动的亮度设置问题,即使设成亮度最低,也一样白屏。怀疑要么是我信号源问题,要么是歪朵拉硬件问题。
4,检测外部信号的制式,在初始化后,需要做个延时,大概100ms不然无法正常检测。
5,现在驱动里,做了制式的判断,PAL制720X576,NTSC制720X480, YUV为常用的NV12格式。通过video_frame_to_argb函数可以很方便的转成RGB
6,现在显示效果不太好,怀疑是我这边环境问题,感兴趣的可以测试下。
测试方法:
1,使用歪朵拉的R3,去掉R30这个电阻,接入CVBS信号,不共地。
2,编译源码,见https://gitee.com/xboot/xboot/blob/master/src/arch/arm32/mach-f1c200s/README-zh-CN.md
3, 打开白盒测试选项,在Makefile中的CFG_WBOXTEST ?= n 改成y就行
4,启动程序,进入命令行后,键入 wboxtest camera preview命令即可在屏幕上看到图像,屏幕为5寸800x480 rgb接口通用屏幕。
驱动文件路径
https://gitee.com/xboot/xboot/blob/master/src/arch/arm32/mach-f1c200s/driver/cam-f1c200s-tvd.c
演示视频
欢迎大家继续研究TVD模块,全志的TVD模块技术上比较先进,自动增益控制,3D梳状滤波器,对比度,饱和度,亮度,都可以调节,3D滤波器需要4M的内存,貌似有点大。
离线
补充一个命令,如果你想用CVBS摄像头来扫描二维码,则只需执行如下命令,就可以扫描二维码了
wboxtest camera qrcode
离线
微凉VeiLiang 说:赞,显示效果上个月又调试了一下,发现有个寄存器需要调下,锯齿效果会好很多,晚点发出来
TVD_REG_BASE+0x001c 这个寄存器的bit0 要等于0.原来初始化写的0x0087002f改成0x0087002a 显示效果好很多
已参考你的BoloRTT里面的配置,这个bit已设为0了,现在我这边环境应该有点问题,现在没能找到带有全志参考电路的板子,没办法进一步确认显示效果。
不知哪位同学有这种板子,可以测试下,看看效果,怎么样,荔枝派,歪朵拉,都是没有的这种电路的。
离线
按全志参考电路的板子,接的模拟摄像头,信号和地都接上的。效果如下:https://whycan.com/files/members/2190/微信图片_20210718161821.jpg
效果看起来还不错,估计还是歪朵拉没有按参考电路设计的问题,信号源出问题的概率太低,只有可能是这个原因了。
离线
看驱动代码
https://gitee.com/xboot/xboot/blob/master/src/arch/arm32/mach-f1c200s/driver/cam-f1c200s-tvd.c
case 0xd5d73dfe: /* "camera-set-saturation" */
if(p)
{
f1c200s_tvd_set_saturation(pdat, *p);
return 0;
}
break;
case 0x0ed48a72: /* "camera-get-saturation" */
if(p)
{
*p = f1c200s_tvd_get_saturation(pdat);
return 0;
}
break;
case 0xdae4842d: /* "camera-set-brightness" */
if(p)
{
f1c200s_tvd_set_brightness(pdat, *p);
return 0;
}
break;
case 0x13e1d0a1: /* "camera-get-brightness" */
if(p)
{
*p = f1c200s_tvd_get_brightness(pdat);
return 0;
}
break;
case 0xf3916322: /* "camera-set-contrast" */
if(p)
{
f1c200s_tvd_set_contrast(pdat, *p);
return 0;
}
break;
case 0xa8290296: /* "camera-get-contrast" */
if(p)
{
*p = f1c200s_tvd_get_contrast(pdat);
return 0;
}
break;
离线
修改 matrix参数进行仿射变换,想做啥效果都可以,移位,缩放,旋转,镜像。。。。想怎么来就怎么来。
离线
贴一段xui里矩阵操作代码吧,4种填充模式。
switch(opt & (0x3 << 12))
{
case XUI_IMAGE_NONE:
sx = 1.0;
sy = 1.0;
break;
case XUI_IMAGE_CONTAIN:
sx = (double)r->w / (double)surface_get_width(s);
sy = (double)r->h / (double)surface_get_height(s);
if(sx >= sy)
sx = sy;
else
sy = sx;
break;
case XUI_IMAGE_COVER:
sx = (double)r->w / (double)surface_get_width(s);
sy = (double)r->h / (double)surface_get_height(s);
if(sx <= sy)
sx = sy;
else
sy = sx;
break;
case XUI_IMAGE_FILL:
sx = (double)r->w / (double)surface_get_width(s);
sy = (double)r->h / (double)surface_get_height(s);
break;
default:
sx = 1.0;
sy = 1.0;
break;
}
matrix_init_translate(&m, r->x + r->w / 2, r->y + r->h / 2);
if(angle != 0.0)
matrix_rotate(&m, angle);
matrix_translate(&m, -surface_get_width(s) / 2 * sx, -surface_get_height(s) / 2 * sy);
matrix_scale(&m, sx, sy);
离线
具体4种模式,参考css里面的objtct-fit。
===============================================
object-fit:指定可替换元素的内容应该如何适应到其使用的高度和宽度确定的框。与我们熟悉的background-size属性有点相似。
contain被替换的内容将被缩放,以在填充元素的内容框时保持其宽高比。 整个对象在填充盒子的同时保留其长宽比,因此如果宽高比与框的宽高比不匹配,该对象将被添加“黑边”。
cover被替换的内容在保持其宽高比的同时填充元素的整个内容框。如果对象的宽高比与内容框不相匹配,该对象将被剪裁以适应内容框。
fill被替换的内容正好填充元素的内容框。整个对象将完全填充此框。如果对象的宽高比与内容框不相匹配,那么该对象将被拉伸以适应内容框。
none被替换的内容将保持其原有的尺寸。
scale-down内容的尺寸与 none 或 contain 中的一个相同,取决于它们两个之间谁得到的对象尺寸会更小一些。
离线
没有垂直同步,如果你仅预览,建议将TVIN的格式转换后的buffer直接作为LCD的显示buffer吧,这样可以避免拷贝,当然最好能用上DE,FE这种硬件模块,效率更高
离线
@godzhou0909
是裸奔的吗?我现在在T113平台山裸奔TVD,还有点小问题,估计又是寄存器配置了
离线
T113平台的效果是这样,NTSC格式的信号。
离线