FPGA纯verilog代码实现H264视频压缩 提供工程源码和技术支持

1、前言

H264视频压缩与解码在FPGA图传领域应用广泛,Xilinx高端器件已经内嵌了H264加速器,在Linux系统下调用API即可使用,但对于需要定制私有算法或者协议的H264视频压缩与解码应用或者学习研究者而言,纯verilog代码实现H264视频压缩依然具有实用价值,本设计采用纯verilog代码实现H264视频压缩,没有使用任何IP,具有参考价值;

本文详细描述了FPGA纯verilog代码实现H264视频压缩的设计方案,工程代码可综合编译上板调试,但目前只做到了仿真层面,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像压缩领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;

免责声明

本工程及其源码即有自己写的一部分,也有网络公开渠道获取的一部分(包括CSDN、Xilinx官网、Altera官网等等),若大佬们觉得有所冒犯,请私信批评教育;基于此,本工程及其源码仅限于读者或粉丝个人学习和研究,禁止用于商业用途,若由于读者或粉丝自身原因用于商业用途所导致的法律问题,与本博客及博主无关,请谨慎使用。。。

2、我这里已有的视频图像编解码方案

我这里有图像的JPEG解压缩、JPEG-LS压缩、H264编解码、H265编解码以及其他方案,后续还会出更多方案,我把他们整合在一个专栏里面,会持续更新,专栏地址:
直接点击前往

3、H264视频压缩理论

请参考这篇文章,感觉写得挺好:https://blog.csdn.net/Ciellee/article/details/91375879

4、H264视频压缩-性能表现

AVC/H.264 Baseline Profile
YUV 4:2:0视频源输入;
视频颜色深度8bit;
最高支持1080P@60Hz视频;
GOP:I/P 即帧内/帧间算法
MB: 16x16 即内部16x16图像分块
1/4 Sub-pixel interpolation
Search range: 16
All Inter Partition mode
All 9 Intra prediction mode
CAVLC
Deblocking Filter

INTRA – Intra mode decision & partition decision
a.Modify the mode priority of C model to match RTL
IME – Integer motion estimation
a.Modify the generation of mv_cost to support P frame
FME– Fractional motion estimation
a.Fix some bugs in fmv calculation and luma prediction
b.Redesign the 1/2 interpolator logic
TQ - Transformation & Quantization
a.Add QPc to quantize chroma residuals
b.Incease the bitwidth of quant modules and idct module to prevent overflow
CAVLC - Entropy coding
a.Modify the FSM to encode chroma component properly
b.Fix a bug in fetching residuals from TQ
FETCH
a.Fix several bugs in fetching predicted pixels
b.Modify the logic of reading RAM

5、H264视频压缩-设计方案

设计框图如下:
在这里插入图片描述
输入:YUV 4:2:0视频流;颜色深度8bit;最高支持1080P@60Hz视频;
压缩算法:帧间和帧内自适应流水线设计;其中I帧存于模块内部Buffer,P帧输出模块外部Buffer;详细设计算法参考第3节的理论链接;https://blog.csdn.net/Ciellee/article/details/91375879
输出:单字节的H264压缩数据;
H264视频压缩代码顶层接口如下:

module helai_h264_encode_2023 (
	input 		  				  clk             , 
	input 		  				  rst_n           ,                                   
	input						  i_sys_start     ,	//开始压缩信号,高电平脉冲     
	output						  o_sys_done      ,	//压缩完成指示信号,高有效		                			
	input						  i_sys_intra_flag,	//开始GOP信号,高电平脉冲 
	input [5:0]					  i_sys_qp        ,	//初始化QP值
	input 						  i_sys_mode      ,	//0:frame mode 1:MB mode 
	input [`PIC_W_MB_LEN-1:0] 	  i_sys_x_total   ,	//一行图像的 MB 大小    
	input [`PIC_H_MB_LEN-1:0]  	  i_sys_y_total   ,	//一列图像的 MB 大小  
	output						  o_enc_ld_start  ,
	output [`PIC_W_MB_LEN-1:0]	  o_enc_ld_x      ,
	output [`PIC_H_MB_LEN-1:0]    o_enc_ld_y      ,                             
	input [8*`BIT_DEPTH - 1:0]    i_video_data    ,	//视频数据输入
	input          				  i_video_de      ,	//视频输入有效信号,高有效
	output         				  o_video_in_ing  ,	//表示图像正在输入                        
	output [7:0]   				  o_video_data    ,	//压缩后的视频数据输出
	output         				  o_video_de      ,	//压缩后的视频数据输出有效信号,高有效                              
	output [`PIC_W_MB_LEN-1:0]    o_ext_PF_mb_x   ,	//输出 P 帧一行图像的 MB 大小	
	output [`PIC_H_MB_LEN-1:0] 	  o_ext_PF_mb_y   ,	//输出 P 帧一列图像的 MB 大小
	output                        o_ext_PF_start  ,	//输出 P 帧开始信号,高电平,相当于 VGA 时序的 VS	
	input                         i_ext_PF_done   ,	//输入 P 帧 Buffer 接收完成信号
	output [2:0]              	  o_ext_PF_mode   ,	//输出 P 帧模式:0:frame mode 1:MB mode
	input						  i_ext_PF_wen	  ,	//外部 P 帧 Buffer 输入写信号,	高有效	
	input						  i_ext_PF_ren	  ,	//外部 P 帧 Buffer 输入读信号,	高有效		
	input  [3:0]				  i_ext_PF_addr   ,	//外部 P 帧 Buffer 输入地址	
	input  [16*`BIT_DEPTH - 1:0]  i_ext_PF_data   ,	//读回 P 帧 Buffer 的视频	
	output [4*4*`BIT_DEPTH - 1:0] o_ext_PF_data   	//写入 P 帧 Buffer 的视频	
);

6、Vivado工程详解

建立Vivado工程,将源码复制进去,目的是进行功能仿真和综合;
开发板FPGA型号:xc7k325tffg676-2;
输入:测试激励YUV 4:2:0视频流文件;
输出:软件生成的压缩视频与FPGA压缩的视频逐个字节对比结果;
应用:功能仿真和综合;

代码架构如下:
在这里插入图片描述
综合后的FPGA资源消耗如下:
在这里插入图片描述

7、Vivado功能仿真

由于仿真过程比较复杂,我专门做了一个PPT教程,详细讲述了仿真流程,手把手教程,PPT教程一并在资料包里给出;位置如下:
在这里插入图片描述
正确仿真的结果如下:
在这里插入图片描述
在这里插入图片描述

8、福利:工程代码的获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:文章末尾的V名片。
网盘资料如下:
在这里插入图片描述
在这里插入图片描述

  • 8
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
你可以使用Verilog代码实现FPGA上的图像缩放。下面是一个简单的示例,展示了如何使用双线性插值算法进行图像缩放: ```verilog module image_scale ( input wire clk, input wire rst, input wire [7:0] in_width, input wire [7:0] in_height, input wire [7:0] out_width, input wire [7:0] out_height, input wire [15:0] in_image [0:1023][0:767], output wire [15:0] out_image [0:511][0:383] ); // 计算水平和垂直比例因子 reg [15:0] scale_x; reg [15:0] scale_y; always @(in_width, out_width) begin scale_x = (in_width << 16) / (out_width + 1); end always @(in_height, out_height) begin scale_y = (in_height << 16) / (out_height + 1); end // 缩放图像 always @(posedge clk or posedge rst) begin if (rst) begin // 复位状态 // ... end else begin // 缩放计算 // ... end end endmodule ``` 在上面的示例中,`in_width`和`in_height`表示输入图像的宽度和高度,`out_width`和`out_height`表示期望的输出图像的宽度和高度。`in_image`是一个二维数组,用于存储输入图像的像素值。`out_image`也是一个二维数组,用于存储输出图像的像素值。 你需要在`always @(posedge clk or posedge rst)`块中实现图像缩放的逻辑。你可以使用双线性插值算法来计算输出图像的每个像素值。具体的实现方法超出了本文的范围,但你可以参考相关资料来了解如何在Verilog实现双线性插值算法。 请注意,上述代码提供了一个基本的框架,你需要根据实际需求进行适当的修改和完善。同时,你还需要根据你使用的开发板和FPGA器件进行相应的时钟和复位处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

9527华安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值