使用说明:
在学习ZYNQ板的时候,发现不少有SD卡读图片显示的例程,但是想显示视频文件或者从SD卡读入视频数据的时候没有找到相关的资料,后面突然脑子转过来当STM32读SD卡显示不就好了。参考了一下STM32读SD的Badapple显示代码,同时结合了正点的例程,就实现了。这里就简单记录一下。
下方参考连接:stm32 播放高帧率高分辨率视频和照片详细制作过程(播放Bad Apple为例)_stm32播放视频-CSDN博客
整体的思路就是用软件工具把你想显示的视频一帧一帧保存到SD卡,然后上板读出并显示。
对视频的工作准备:
1、找一段目标视频,记一下RGB格式,显示帧率相关数据,然后使用KMPlayer 64X对视频帧进行捕获:右击 ——> 高级捕获
这里按照我的LCD屏 800*480的分辨率设置,原视频是一个20帧/秒,总长10秒的视频,所以每1/20 = 0.05s即每50毫秒捕获一次就好。设置BMP格式
在设置好的路径下会得到:
然后就是BMP转换为bin文件,用Image2Lcd批量转换一下,最后在合并bin文件就好。参考下面链接:
手把手教你在STM32上实现OLED视频播放(很简单也很硬很肝!)-腾讯云开发者社区-腾讯云
最后就能得到需要拷贝到SD卡上的bin文件
Vitis需要更改的函数:
纯使用FPGA控制SD的读写状态还是有点麻烦,所以用的ZYNQ移植FATFS系统对SD卡读取,Xilinx官方也有移植函数,非常方便。
正点原子的教程是读图片的代码,结合上面两个博客的显示代码更改显示视频的代码如下:
void load_sd_video(u8 *frame)
{
static FATFS fatfs;
FIL fil;
UINT br;
//u8 framebuffer[PIC_SIZE] = {1};
FRESULT res;
int file_size;
int offset;
// 挂载文件系统
f_mount(&fatfs, "", 1);
// 打开文件
res = f_open(&fil, "mygo.bin", FA_READ);
if (FR_OK != res)
{
xil_printf("SDcard file open failed\n\r");
}
/*2.计算这个文件的大小*/
file_size = f_size(&fil);
/*3.初始化偏移变量为0*/
offset = 0;
/*4.计算bin文件里一共包含多少张图片,然后不断的给LCD进行显示*/
/*PIC_SIZE大小 800*480*24/8 = 1152000 Byte*/
for (int i = 0; i < file_size / PIC_SIZE; i++)
{
/*5.读取一张图片,一张图片的大小是PIC_SIZE,
将读取出来的图片存放到缓存区framebuffer数组里*/
res = f_read(&fil, frame, PIC_SIZE, &br);
if (FR_OK != res)
xil_printf("SDcard read file failed\n\r");
/*7.将偏移往后加PIC_SIZE,就到了下一张图片*/
offset += PIC_SIZE;
// SD卡 FATFS系统的指针偏移
res = f_lseek(&fil, offset);
if (FR_OK != res)
xil_printf("FATFS System pointer offset failed\n\r");
}
/*8.关闭文件描述符*/
res = f_close(&fil);
if (FR_OK != res)
xil_printf("FATFS System closed failed\n\r");
Xil_DCacheFlush(); //刷新Cache,数据更新至DDR中
}
主函数调用这个load_sd_video函数就好了,放个while就循环播放了。
显示效果:
最后:
总体还是把PS端当STM32来用了,PL方面参考正点原子的教程基本不需要修改,根据不同的显示需求改一下时钟就好。第一次写博客,存在不少问题,感谢大家批评指正。