海思3518E开发笔记2.7——海思VENC(Video Encode)模块详解
作者:互联网
目录
海思Video Encode模块架构介绍
VENC 模块,即视频编码模块。本模块支持多路实时编码,且每路编码独立,编码协议和编码 profile (BP、MP、HP)可以不同。
本模块支持视频编码同时,调度 Region 模块对编码图像内容进行叠加和遮挡。
海思Video Encode相关概念
VENC 模块的输入源包括三类:
- 用户态读取图像文件向编码模块发送数据;
- 视频输入( VIU)模块采集的图像经视频处理子系统( VPSS)发送到编码模块;
- 视频输入( VIU)模块采集的图像直接发送到编码模块;
H.264 profile: 图像清晰度的一个标准(可以理解为普通的清晰度,高清的清晰度)
H.264有四种画质级别,分别是BP、EP、MP、HP:
-
1、BP-Baseline Profile:基本画质。支持I/P 帧,只支持无交错(Progressive)和CAVLC;
-
2、EP-Extended profile:进阶画质。支持I/P/B/SP/SI 帧,只支持无交错(Progressive)和CAVLC;
-
3、MP-Main profile:主流画质。提供I/P/B 帧,支持无交错(Progressive)和交错(Interlaced),也支持CAVLC 和CABAC 的支持;
-
4、HP-High profile:高级画质。在main Profile 的基础上增加了8x8内部预测、自定义量化、 无损视频编码和更多的YUV 格式;
H.264 Baseline Profile对应MPEG-4 SP
H.264 Main Profile对应MPEG-4 ASP
H.264 Extended Profile对应MPEG-4 ARTS or FGS
H.264 Baseline Profile对应MPEG-4 Studio。
MOTION JPEG(MJPEG) : 早于H.264的视频压缩标准,过时了
H.265 只支持MP
码率控制
什么是码率?
码率就是数据传输时单位时间传送的数据位数。一般我们用的单位是kbps即千位每秒。
通俗一点理解就是取样率,单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件。
但是文件体积与取样率是成正比的,所以几乎所有的编码格式重视的都是如何用最低的码率达到最少的失真。
码率控制器实现对编码码率进行控制。
为什么要控制码率?
从信息学的角度分析,图像的压缩比越低,压缩图像的质量越高;图像压缩比例越高,压缩图像的质量越低。对于场景变化的真实场景,图像质量稳定,编码码率会波动;编码码率稳定,图像质量会波动。
以 H.264 编码为例,通常图像 Qp 越低,图像的质量越好,码率越高;图像 Qp 越高,图像质量越差,码率越低。码率控制是针对连续的编码码流而言,所以, JPEG 协议编码通道不包括码率控制功能。
码率控制器分别提供了对 H.264\H.265\MJPEG 协议编码通道 CBR、 VBR、 FIXQP 等三种码率控制模式,对图像质量和码率进行调节。
Hi3518EV200 不支持 H.265 编码,所以,也不支持 H.265 类型的码率控制。
海思Video Encode模块功能介绍
典型的编码流程包括了输入图像的接收、图像内容的遮挡和覆盖、图像的编码、以及码流的输出等过程。
VENC 模块由编码通道子模块( VENC)和编码协议子模块( H.264/H.265/JPEG/MJPEG)组成。
通道支持接收 YUV 格式图像输入,支持格式为 Semi-planar YUV 4:2:0 或 Semi-planar YUV 4:2:2,其中 H.264/H.265 只支持 Semi-planar YUV 4:2:0, JPEG/MJPEG 支持 Semiplanar YUV 4:2:0 或 Semi-planar YUV 4:2:2。另外, Hi3518EV200 能够支持单分量输入(只存在 Y 分量)。通道模块接收外部原始图像数据,而不关心图像数据是来自哪个外部模块。
通道接收到图像之后,比较图像尺寸和编码通道尺寸:
- 如果输入图像比编码通道尺寸大, VENC 将按照编码通道尺寸大小,调用 VGS 对源图像进行缩小,然后对缩小之后的图像进行编码。
- 如果输入图像比编码通道尺寸小, VENC 丢弃源图像。 VENC 不支持放大输入图像编码。
- 如果输入图像与编码通道尺寸相当, VENC 直接接受源图像,进行编码。
REGION 模块支持对图像内容的遮挡和叠加。
完成视频区域管理之后,图像被送入具体协议类型编码通道,完成视频编码,输出码流。
编码通道
编码通道作为基本容器,保存编码通道的多种用户设置和管理编码通道的多种内部资源。编码通道完成图像转化为码流的功能,具体由码率控制器和编码器协同完成。这里的编码器指的是狭义上的编码器,只完成编码功能。码率控制器提供了对编码参数的控制和调整,从而对输出码率进行控制。
- encoder是真正的编码器
- RC可以理解为类似CPU的控制单元,用于控制单位时间内传输的数据量,通俗点来说就是一秒输出多少帧图像
ROI
ROI( Region Of Interest)编码,感兴趣区域编码。
用户可以通过配置 ROI 区域,对该区域的图像 Qp 进行限制从而实现图像中该区域的 Qp 与其他图像区域的差异化。
系统现仅支持对 H.264/H.265 通道进行 ROI 设置。系统提供了 8 个感兴趣区域,可供用户同时使用。
8 个区域可以互相叠加,且叠加时的优先级按照 0~7 的索引号依次提高,这里,叠加优先级是指发生叠加时,图像区域的最终 Qp 值的判定,最终的区域 Qp 值按照优先级最高的区域设定。 ROI 区域可配置绝对 Qp 和相对 Qp 两种模式。
- 绝对 Qp: ROI 区域的 Qp 为用户设定的 Qp 值。
- 相对 Qp: ROI 区域的 Qp 为码率控制产生的 Qp 与用户设定的 Qp 偏移值的和
以下示例编码图像采用 FixQp 模式,设置图像 Qp 为 25,即图像中所有宏块 Qp 值为25。
Roi 区域 0 设置为绝对 Qp 模式, Qp 值为 10,索引为 0; Roi 区域 1 设置为相对Qp 模式, Qp 为-10,索引为 1。
区域 0 的 index 小于区域 1 的 index,所以在发生互相重叠的图像区域按高优先级的区域(区域 1) Qp 设置。区域 0 除了发生重叠的部分的Qp 值等于 10。区域 1 的 Qp 值为 25-10=15。
裁剪编码
裁剪编码,即 VENC 从图像中裁剪出一部分进行编码,用户可以设置裁剪的起始点X、 Y 和裁剪的宽度 width 和高度 height
函数调用关系
相关数据结构
typedef struct hiVENC_ATTR_H264_S
{
HI_U32 u32MaxPicWidth; /*maximum width of a picture to be encoded, in pixel*/
HI_U32 u32MaxPicHeight; /*maximum height of a picture to be encoded, in pixel*/
HI_U32 u32BufSize; /*stream buffer size*/
HI_U32 u32Profile; /*0: baseline; 1:MP; 2:HP; 3: SVC-T [0,3]; */
HI_BOOL bByFrame; /*get stream mode is slice mode or frame mode*/
HI_U32 u32PicWidth; /*width of a picture to be encoded, in pixel*/
HI_U32 u32PicHeight; /*height of a picture to be encoded, in pixel*/
HI_U32 u32BFrameNum; /* 0: not support B frame; >=1: number of B frames */
HI_U32 u32RefNum; /* 0: default; number of refrence frame*/
}VENC_ATTR_H264_S;
流程分析
首先选择码率控制模式,可选CBR、VBR、fixQP,选项放在enRcMode
中
接着三路码流分别进行通道属性配置,和Vpss绑定,
SAMPLE_COMM_VENC_Start
为通道属性设置、通道开启
此函数中,首先调用SAMPLE_COMM_SYS_GetPicSize
获取图像尺寸,即xy分辨率的值
然后进行vencstart中的第一步step 1: Create Venc Channel
其中判断了PAYLOAD_TYPE_E enType
,显然我们使用的是PT_H264,接着填充相关数据结构VENC_ATTR_H264_S stH264Attr
,再将这个数据结构放到正真用于编码配置的数据结构中
配置完playload和enType后,将最终的chn属性结构体写到对应chn号中HI_MPI_VENC_CreateChn
第一步创建完通道之后进入第二步,step 2: Start Recv Venc Pictures,HI_MPI_VENC_StartRecvPic
通过传入通道号接收对应通道中的图片
配置好通道属性,并打开通道后,就需要将Venc中的通道和Vpss中的组和通道绑定,SAMPLE_COMM_VENC_BindVpss
,配置好绑定的源通道和目标组、通道后,调用MPI中的HI_MPI_SYS_Bind
进行绑定
为什么在配置通道属性-stVencChnAttr.stVeAttr.stAttrH264e
时要定义一个stH264Attr
再将后者内存拷贝过去?
代码规范,为了方便阅读一行最多120字符,CPU性能够的情况下可以不在乎这一次内存拷贝
为什么复杂的VENC代码非常简单?
复杂的东西封装度高,不需要使用者做什么操作
标签:编码,码率,Qp,Video,3518E,VENC,图像,海思,通道 来源: https://blog.csdn.net/qq_28258885/article/details/118889738