FPGA纯verilog代码实现H265视频压缩 支持4K30帧分辨率 提供工程源码和技术支持

1、前言

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

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

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

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

3、H265–视频压缩理论

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

4、H265–视频压缩–性能表现

性能表现如下:
输入视频格式:YUV4:2:0;
输出视频码流:h265视频流;8位;伴随数据有效信号;
支持分辨率:最大4K@30Hz;
GOP:I/P;即帧内帧间预测算法;
多达35种预测模式;
CTU:64x64;
CU:8x8~64x64;
PU:4x4~64x64;
TU:4x4/8x8/16x16/32x32;
1/4 Sub-pixel;
Search range:64;
CABAC熵编码;
SAO(Sample Adaptive Offset);
SKIP/MERGE;

5、H265–视频压缩–设计方案

在这里插入图片描述
视频压缩编码的基本过程可以概括如下 :
1、 利用某种方式对当前处理图像块像素进行预测 ;
2、 将原始的像素值与预测出来的像素值相减得到残差值 ;
3、 将残差进行变换及量化处理,得到输出的残差系数再进过熵编码形成最后的压缩码流 ;
4、残差系数经过反量化及反变换处理,再与之前得到的预测像素相加得到重建像素,存储作为预测的参考像素。

H264视频压缩代码顶层接口如下:

module helai_h265_encode_2023(
  input                         clk                   ,	//系统时钟,最大支持 400MHz
  input                         rstn                  ,	//系统复位--低电平有效 
  //初始化配置
  //db -->Deblocking filter 块滤波器
  //sao-->sample adaptive offseta 自适应采样偏移  
  input                         i_h265_start          ,	//输入--开启h265压缩--高电平有效
  output                        o_h265_ec_OK          ,	//输出--h265压缩完成标志--高电平有效
  input  [`PIC_WIDTH -1 :0]     i_yuv_width           , //输入--压缩视频总宽度
  input  [`PIC_HEIGHT-1 :0]     i_yuv_height          , //输入--压缩视频总高度
  input  [5             :0]     i_init_QP             , //输入--初始化QP值--例程给的27
  input                         i_DataRate_type       , //输入--码流类型: 0-->Intra ; 1-->Inter
  input                         i_IinP_en             , //输入--enable I block in P frame
  input                         i_db_en               ,	//输入--块滤波器使能
  input                         i_sao_en              ,	//输入--SAO使能--SAO(Sample Adaptive Offset)
  input  [5-1:0]                i_blok4x4bit          ,	//输入--4X4模块则填入4                               
  input   [32-1:0]              i_skip_cost_thre_08   ,	//输入--skip开销阈值;例程设置为0
  input   [32-1:0]              i_skip_cost_thre_16   ,
  input   [32-1:0]              i_skip_cost_thre_32   ,
  input   [32-1:0]              i_skip_cost_thre_64   ,
  // RC(Rate control) 配置
  // roi(region of interest_--图像感兴趣区域
  output [32             -1 :0] o_rc_mod64_sum        ,	//输出--mod64校验
  input  [32             -1 :0] i_rc_bitnum           ,	//输入--cabac编码bit数,一般为10000
  input  [16             -1 :0] i_rc_k                ,	//输入--rc k 值,一般给0
  input  [6              -1 :0] i_rc_roi_height       ,	//输入--roi 高度
  input  [7              -1 :0] i_rc_roi_width        ,	//输入--roi 宽度
  input  [7              -1 :0] i_rc_roi_x            ,	//输入--roi 起始 X 轴坐标
  input  [7              -1 :0] i_rc_roi_y            ,	//输入--roi 起始 Y 轴坐标
  input                         i_rc_roi_en           ,	//输入--roi 使能
  input  [10             -1 :0] i_rc_L1_frame_byte    , //输入--一级流水线处理帧数
  input  [10             -1 :0] i_rc_L2_frame_byte    , //输入--二级流水线处理帧数
  input                         i_rc_lcu_en           ,	//输入--LCU 使能
  input  [6              -1 :0] i_rc_QP_max           ,	//输入--QP最大值
  input  [6              -1 :0] i_rc_QP_min           ,	//输入--QP最小值
  input  [6              -1 :0] i_rc_QP_delta         ,	//输入--roi QP值
  //IME 配置                                           
  input  [CMD_NUM_WIDTH  -1 :0] i_IME_cmd_num         ,	//输入--IME指令
  input  [CMD_DAT_WIDTH  -1 :0] i_IME_cmd_data        ,	//输入--IME数据
  //外部缓存包括(原始输入视频缓存--重构缓存)   
  //ori-->original : ori_yuv_mem-->原始输入视频缓存器
  //rb -->rebuild  : rb_pix_mem -->像素重构缓存器
  output [1-1              : 0] o_rb_pix_mem_video_vs ,	//输出--告诉像素重构缓存开始接收,相当于VGA时序的vs
  input  [1-1              : 0] i_rb_pix_mem_video_OK ,	//输入--像素重构缓存告诉h265压缩模块,接收一帧视频结束
  output [5-1              : 0] o_ext_mem_do_mode     ,	//输出--告诉外部缓存操作指示,详情请看文章
  output [6+`PIC_X_WIDTH -1: 0] o_ext_mem_x_position  ,	//输出--告诉外部缓存当前视频的 X 坐标
  output [6+`PIC_Y_WIDTH -1: 0] o_ext_mem_y_position  ,	//输出--告诉外部缓存当前视频的 Y 坐标
  output [8-1              : 0] o_ext_mem_video_width ,	//输出--告诉外部缓存--视频总宽度
  output [8-1              : 0] o_ext_mem_video_height,	//输出--告诉外部缓存--视频总高度
  input                         i_ori_yuv_mem_video_de,	//输入--原始输入视频缓存--输入的 yuv4:2:0 视频数据有效
  input  [16*`PIXEL_WIDTH-1: 0] i_ori_yuv_mem_video   ,	//输入--原始输入视频缓存--输入的 yuv4:2:0 视频数据
  input                         i_rb_pix_mem_video_de ,	//输入--像素重构缓存告诉h265压缩模块--我需要像素数据
  output [16*`PIXEL_WIDTH-1: 0] o_rb_pix_mem_video    ,	//输出--给像素重构缓存灌的像素数据 
  // h265 output
  output                        o_h265_video_de       ,	//输出--压缩后的 h265 视频数据有效	
  output  [7               : 0] o_h265_video           	//输出--压缩后的 h265 视频数据
  );

6、H265–视频压缩–时序

输入输出操作时序图请参考资料包里的vivado工程里的仿真波形图,料包里有仿真教程;
输入部分时序如下:
在这里插入图片描述
在这里插入图片描述
输出部分时序如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7、Vivado工程详解

建立Vivado工程,将源码复制进去,目的是进行功能仿真和综合;
开发板FPGA型号:xc7k410tffg676-2;
输入:测试激励YUV 4:2:0视频流文件;
应用:功能仿真和综合;
在这里插入图片描述
FPGA资源消耗如下:
资源消耗比较大,请参考自己的FPGA是否满足资源要求;
在这里插入图片描述

8、移植上板应用

由于我这里只做到了仿真层面,还没上板调试,但你可以拿去移植上板,移植上板只需解决两个问题,1是输入时序,2是预估FPGA资源;
输入时序请参考vivado工程的仿真文件和仿真波形,查看仿真输入激励文件和波形就能了解驶入时序,然后对应着灌入数据即可;FPGA资源消耗请看上面的“7、Vivado工程详解中的FPGA资源消耗”;另外,移植上板可提供技术支持;

9、Vivado功能仿真

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

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

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

猜你喜欢

转载自blog.csdn.net/qq_41667729/article/details/130774853