jpg是一种压缩的图片格式,之所以压缩是为了减小图片所占空间,jpg压缩原理这里不罗嗦,可以自行百度或者b站,大佬讲的比我好,jpg解压缩就是逆向过程,用opencv啥的解压缩就是一句话的事儿,但对于fpga硬件来说就是大型工程了。
 整个工程思路框图如下:
 
第一步:百度下载一张1280X720尺寸的jpg格式图片,用matlab等工具将jpg图片转为c语言数组;
 第二步:用vivado的sdk将c语言数组拷贝到zynq的ps端ddr3;
 第三步:用axi4主控制器从zynq的ps端ddr3中把jpg图像读到zynq的pl端fpga,并转为axis数据流;
 第四步:jpg图像的axis数据流进入jpg解码器模块,并解码转化为rgb数据,并生成场同步信号vs和数据有效信号de;
 第五步:用fdma方案将rgb数据写入ddr3做三帧缓存并读出;
 第六步:读出的rgb图像数据送hdmi显示模块输出显示器;
 补充说明:
 1:由于jpg是单张图片,并不像视频那样是连续的,所以这里从ps端ddr3中读取图像需要认为的给一个脉冲信号,相当于视频的场同步信号vs,由于使用的是zynq,所以直接用axi_gpio输出给fpga,这样就能由sdk软件控制jpg图片的读取;
 2:第五步中的fdma方案是我一直用的图像缓存方案,可参考我之前的文章fdma三帧缓存方案
FPGA工程如下:
 BD部分:
 
 FPGA代码部分:
 
 SDK代码部分:
int main()
{
    init_platform();
    write_pic();	//拷贝jpg数组到内存
	XGpioCfg = XGpio_LookupConfig(XPAR_AXI_GPIO_0_DEVICE_ID);
	XGpio_CfgInitialize(&video_gpio, XGpioCfg, XGpioCfg->BaseAddress);
	XGpio_SetDataDirection(&video_gpio, 1, 0);
	XGpio_SetDataDirection(&video_gpio, 2, 0);
	XGpio_DiscreteWrite(&video_gpio, 2, 4096*30);
	XGpio_DiscreteWrite(&video_gpio, 1, 1);
	while(1){
		XGpio_DiscreteWrite(&video_gpio, 1, 1);
		usleep(30000);
		XGpio_DiscreteWrite(&video_gpio, 1, 3);	//SDK触发jpg读脉冲,切记要用debug单步调试模式
		XGpio_DiscreteWrite(&video_gpio, 1, 1);
	}
    cleanup_platform();
    return 0;
}
上板调试:
 开发板:米联客zynq7100开发板;
 开发环境:vivado2019.1;
 输入:1280X720尺寸jpg图片;
 输出:720P分辨率HDMI视频,rgb888格式;
 调试要点:
 1、运行SDK时切记要用debug单步调试模式,这样才能稳步触发jpg读图片并解码,因为在while(1)死循环里时间间隔太小,硬件反应不过来,如果需要持续触发则需要加适当的延时;
 2、SDK拷贝图片进ddr3时需要4K对齐;
 3、XGpio_DiscreteWrite(&video_gpio, 2, 4096*30);这句话是jpg读图片的地址长度,可以适当设置大一些,因为jpg解码器在读到jpg数据包帧尾时就完成了解码,多余的数据不会再利用;
 直接上调试结果:
 
左边屏幕为jpg原图;左边屏幕为解码后输出hdmi显示的rgb视频;
 福利:快**“关注并私信我”**获得源码及工程吧。。。










