前言
四分屏显示+分屏时视频自动移动可以分成两个部分,本文先介绍如何实现四路视频源的拼接。
硬件平台:anPH1A 开发板链接
软件版本:TD6.0
本工程所有的代码均已上传至Github,开源工程链接,可以把bit流文件直接烧录至anPH1A开发板进行验证。还请大家给点点star喽~ ,如果有不理解的地方,欢迎评论区讨论~ 。有写错的地方也请大家评论区批评指正~
一、设计概述
除去DDR3控制器、FIFO等常用IP,本设计所用到的主要的IP模块如下。
IP | 功能 | 来源 |
---|---|---|
uidbuf | 基于FDMA信号时序的缓存控制器 适合用于基于RGB时序的视频数据或者数据流传输 | 米联客 |
uiFDMA | 基于AXI总线的自定义内存控制器 简化AXI总线的控制,完成数据的搬运 | 米联客 |
uivtc | 视频时序控制器,产生视频时序信号 | 米联客 |
uidbufw_interconnect | 基于FDMA信号时序的多路数据仲裁模块 不必使用AXI interconnectIP核,减少逻辑资源的使用 | 个人开发 |
其中uidbufw_interconnect模块相比于AXI interconnect IP模块,使用简单,在搭建四路视频拼接时,可以节省更多的逻辑资源,具体原因见下文。
二、系统实现方案
2.1 理论分析
我们首先需要理解显示器是如何通过逐行扫描来显示图像的。如图所示,这种扫描方式是从左到右、从上到下进行的。在读取DDR3中存储的数据时,是按照地址顺序读取的,那么为了在屏幕上实现多个视频画面的分屏显示,我们需要一种特殊的数据存储和寻址策略,以确保每个视频画面能够正确地显示在屏幕上的指定区域。
以video1为例,以下是实现分屏显示所需的关键参数和步骤:
1、视频数据存储格式:视频数据以RGB565格式存储,即每个像素由两个字节组成,一个像素对应两个地址。(在uidbuf IP中,一个地址对应的是一个字节)
2、存储地址的计算:一帧视频数据不是连续顺序写入DDR3,而是在写入一行数据后进行地址的跳跃。假设整个屏幕的分辨率为1280×720,video1、2、3、4的分辨率为640×360。
那么在存储video1的数据时,每当写入Video1 hsize(640)个数据后,就会进行一次地址跳跃,跳过Video1 hstride(1280)与Video1 hsize(640)之间的差值,即640×2个地址(乘2是因为每个像素由两个字节组成,一个像素对应两个地址),开始存储下一行像素。因此可以设置每次突发写入DDR3一行的数据量(640个数据)。
每一个视频的第n行的起始像素的存储地址的计算方式均为W_BASEADDR+n× 1280×2,唯一的区别就是W_BASEADDR不同。举个例子,以video1为例,W_BASEADDR=0,第一行第一个像素点写入的地址为0,第二行第一个像素点写入的地址为1280×2=2560。乘2是因为每个像素由两个字节组成,一个像素对应两个地址。(在uidbuf IP中,一个地址对应的是一个字节)。
四路视频第一个像素的写入地址如下表所示
四路视频 | W_BASEADDR(第一个像素起始地址) |
---|---|
video1 | 0 |
video2 | 640×2=1280 |
video3 | 1280×360×2=921600 |
video4 | 921600 + 640×2=922880 |
2.2 系统框图
关于四路视频拼接,目前已经有一些例程,比如米联客的基于 fdma ddr 多路视频数据构架方案,其系统方案如下。
该方案就是把每一路视频数据在写入的时候都对应一个uidbuf + uiFDMA,然后使用AXI interconnect IP进行四路数据的仲裁写入。
由于写的时候已经把像素点写入了DDR3对应的位置(需要四个uidbuf_w),那么在读取的时候直接顺序读取(需要一个uidbuf_r)就可以实现分屏显示的效果。
最开始我也想采用这种方案进行四路视频的拼接,但是由于刚开始是使用的TD5.6进行开发,该软件内没有AXI interconnect IP核,所以不得不考虑如何更方便的进行数据的仲裁。于是便有了自己开发的uidbufw_interconnect IP,该IP直接对uibuf与fdma之间的信号进行仲裁,此方案框图如下:
可以把这个和上述已有的方案进行对比,不难发现,我们只使用一个FDMA就可以,只需要对uidbuf和uiFDMA之间的信号进行仲裁即可,不必像上述方案那样,每一路视频都对应一个FDMA模块,在节省逻辑资源使用的同时也很好的解决了没有AXI interconnect IP 的问题。
三、移植注意事项
1、 在本工程中,为了减少ERAM资源的使用,我们将图像像素点在DDR3中的存储和读取格式设置为RGB565格式,其中每个像素点占用16bit,并将DDR3的数据位宽设置为16bit。由于DDR3的突发传输长度固定为8,每次突发传输8次16bit数据,即总共传输128bit。因此,在进行DDR3存取时,FIFO的读写位宽可以设置为16bit和128bit。与此不同,若将图像像素点的存储格式设置为RGB888格式,每个像素点将占用24bit,并将DDR3的数据位宽设置为32bit。在这种情况下,进行存取时,FIFO的读写位宽将为32bit和256bit,这样会导致ERAM资源消耗的加倍。
2、本工程把四路视频源拼接模块输入的视频分辨率为1280×720,如果要改为1920×1080,需要更改
down_samping_2x2、uidbuf、uivtc模块的参数。
四、上板验证
四路视频数据是由FPGA内部产生的测试数据,四路视频拼接效果图如下。
五、总结
此方案的四分屏显示是从写的角度出发,在写的时候进行跳跃地址写入,把像素按照分屏显示的顺序排列好,这样读取的时候顺序读取即可。可以考虑一下如果写的时候是正常写,从读的角度出发,该如何实现四分屏?下一篇文章:分屏时视频的自动移动便是从读的角度出发设计的方案。文章链接