H264视频压缩与解码在FPGA图传领域应用广泛,Xilinx高端器件已经内嵌了H264加速器,在Linux系统下调用API即可使用,但对于需要定制私有算法或者协议的H264视频压缩与解码应用或者学习研究者而言,纯verilog代码实现H264视频压缩依然具有实用价值,本设计采用纯verilog代码实现H264视频压缩,没有使用任何IP,具有参考价值;
本文详细描述了FPGA纯verilog代码实现H264视频压缩的设计方案,工程代码可综合编译上板调试,但目前只做到了仿真层面,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像压缩领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;
我这里有图像的JPEG解压缩、JPEG-LS压缩、H264编解码、H265编解码以及其他方案,后续还会出更多方案,我把他们整合在一个专栏里面,会持续更新,专栏地址:
直接点击前往
请参考这篇文章,感觉写得挺好:https://blog.csdn.net/Ciellee/article/details/91375879
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
设计框图如下:
输入: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 的视频
);
建立Vivado工程,将源码复制进去,目的是进行功能仿真和综合;
开发板FPGA型号:xc7k325tffg676-2;
输入:测试激励YUV 4:2:0视频流文件;
输出:软件生成的压缩视频与FPGA压缩的视频逐个字节对比结果;
应用:功能仿真和综合;
由于仿真过程比较复杂,我专门做了一个PPT教程,详细讲述了仿真流程,手把手教程,PPT教程一并在资料包里给出;位置如下:
正确仿真的结果如下:
福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:文章末尾的V名片。
网盘资料如下: