引言
展示的是可以如何使用 AXI Video Direct Memory Access (VDMA) IP 来实现视频剪裁、画中画或软模式生成器功能。
示例 1:使用 AXI VDMA IP 的视频裁剪
视频裁剪
在某些情况下,您可能需要输出分辨率比输入分辨率小。视频剪裁是您可以通过 AXI 视频直接存储器访问 (VDMA) IP 执行的一项操作。
视频剪裁是对图像的特定部分进行的“剪切”。我们可以通过只读取传入视频的一部分来完成此操作。
通过 AXI VDMA IP 来实现
在此示例中,我要将测试模式生成器 (TPG) IP 用作源,并且将 AXI VDMA IP 配置为已启用读写通道。这与视频系列 24 中的设计相同。
在这个应用中,我要把 TPG IP 设置为可以生成分辨率为 1024x768 的视频(而会把 HDMI 输出分辨率固定为 800x600)
//Configure the TPG
app_hdmi_conf_tpg(&tpg_inst, 768, 1024, 0x2, XTPG_BKGND_COLOR_BARS);
必须完成的主要配置是 AXI VDMA IP。
写入接口被设置为 1024x768
//S2MM Frame delay / Stride register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA8, 1024*2);
// S2MM HSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA4, 1024*2);
// S2MM VSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA0, 768);
读取接口被设置为 800x600。
// MM2S Frame delay / Stride register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x58, 1024*2);
// MM2S HSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x54, 800*2);
// MM2S VSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x50, 600);
请注意,此处的 STRIDE 参数不等于 HSIZE 参数。这是我们确实可以使用此参数的一种情况。
如果 STRIDE 等于 HSIZE,那么 AXI VDMA IP 会在没有任何跳转的情况下读取帧缓存。但是,由于输入大小大于输出大小,我们需要在地址之间跳转以便能够正确地对齐下一行的开头。
STRIDE 参数用于描述每个视频行第一个像素之间的地址的字节数。
如果我们想在输入帧中移动剪裁窗口,我们只需在帧缓存地址中添加偏移,使 HSIZE 和 STRIDE 参数值保持一致即可。
例如,如果我们想要让剪裁窗口水平居中,可以为读取接口的帧缓存地址添加 224 的偏移 ((hsize_in –hsize_out)/2 * bytes/pixel = (1024 - 800)/2 * 2 = 224)。
// MM2S Start Address 1
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x5C, 0x10000000 + 224);
// MM2S Start Address 2
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x60, 0x10200000 + 224);
// MM2S Start Address 3
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0x64, 0x10400000 + 224);
注意:在此示例中,偏移需要是存储器映射数据宽度字节(32 位)的倍数,因为在“AXI VDMA IP”配置中未启用“Allow Unaligned Transfers”。
示例 2:使用 AXI VDMA IP 的画中画
画中画
如果设计中的输入分辨率小于输出分辨率,则可能采用的解决方案就是使用画中画。例如,我们可以添加蓝色背景,然后使输入居中。
通过 AXI VDMA IP 来实现
设计的硬件与示例 1 中的硬件相同。
在这个应用中,TPG IP 被设置为可以生成分辨率为 640x480 的视频(而 HDMI 输出分辨率固定为800x600)
//Configure the TPG
app_hdmi_conf_tpg(&tpg_inst,480,640, 0x2, XTPG_BKGND_COLOR_BARS);
我们需要做的第一件事就是用背景的蓝色填充帧缓存。
这是通过代码中的以下行来完成的:
UINTPTR Addr1=0x10000000,Addr2=0x10200000,Addr3=0x10400000;
…
print("Initialize frame buffer data...");
//Disable the data cache to initialize the frame buffer with a blue color
Xil_DCacheDisable();
//Write a blue background in the memory
for(line=0; line < OUTPUT_HEIGHT; line++)
{
for(column=0; column < OUTPUT_WIDTH/2; column++)
{
//Write the blue color to the frame buffer(0x6B1DFF1D in YUV422)
Xil_Out32(Addr1, 0x6B1DFF1D);
Xil_Out32(Addr2, 0x6B1DFF1D);
Xil_Out32(Addr3, 0x6B1DFF1D);
Addr1+=4;
Addr2+=4;
Addr3+=4;
}
}
//Re-enable the data cache
Xil_DCacheEnable();
print("Done\n\r");
您可以看到,在将数据写入内存之前,我会禁用数据高速缓存(Xil_DCacheDisable())并在写入完成后重新启用它。
写入或读入高速缓存存储器而不是 DDR 存储器是一个常见的错误。使用内存时,您需要确保从正确的位置读取/写入。
然后,在进行 AXI VDMA IP 配置时,我们将执行与示例 1 中所执行操作相反的操作。
在这个示例中,我们会使用写入接口(而不是前面示例中的读取接口)上的步幅(现在已与 HSIZE 不同)在 800 * 600 背景上正确地写入内存。
对于缓存存储器地址,我添加了一个偏移以便能够使输入水平和垂直居中。
//Offset to center the pattern on the buffer
offset = 0x177A0;
//S2MM Start Address 1
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xAC, 0x10000000 + offset);
//S2MM Start Address 2
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xB0, 0x10200000 + offset);
//S2MM Start Address 3
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xB4, 0x10400000 + offset);
//S2MM Frame delay / Stride register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA8, OUTPUT_WIDTH*2);
// S2MM HSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA4, 640*2);
// S2MM VSIZE register
Xil_Out32(XPAR_AXI_VDMA_0_BASEADDR + 0xA0, 480);
示例 3:使用 AXI VDMA IP 的软模式发生器
通过 AXI VDMA IP 来实现
在此示例中,AXI VDMA IP 配置为仅启用读取接口。
在应用开始时,处理器在 DDR 中写入模式。
在 Vivado Design 中,我删除了“测试模式生成器”:
因为我们正在读取一个静止模式,所以在 AXI VDMA IP 读取时不会同时写入与帧缓存对应的存储器。因此,AAXI VDMA IP 中只需要一个帧缓存器。
写入存储器的方式与示例 2 中所用的方式类似,在需要访问 DDR 存储器时禁用高速缓存。
另外请注意,在配置 AXI VDMA IP 的 MM2S 接口时,同步锁相会被禁用。
构建 SDK 工作空间和 Vivado Designs
注意:这些示例仅针对 ZC702 电路板。
构建 SDK 工程
下载教程文件,然后解压缩文件夹。
启动赛灵思软件命令行工具 (XSCT) 2018.1。
从 Windows 菜单中选择以下内容:
“Start > All Program > Xilinx Design Tools > Xilinx Software Command Line Tool 2018.1”。
从命令行:
使用 xsct 命令(需要设置 SDK 2018.1 的环境变量)。
在 xsct 中,使用 cd 导航到您要构建的示例的路径 (example_x/sw)。
然后输入下列命令:
source create_SW_proj.tcl打开 SDK,然后选择“example_x/sw/sdk_workspace”作为工作空间。
构建 Vivado Design
打开 Vivado 。
在 Tcl 控制台中,使用 cd 导航到解压缩的目录 (cd example_x/hw)。
在 Tcl 控制台中,用 source 来写脚本 tcl (source ./create_proj.tcl)。