目录
2.1 VENC_ATTR_S结构体(编码器基础属性结构体)
2.2 VENC_RC_ATTR_S结构体(编码码率控制属性结构体)
2.3:VENC_GOP_ATTR_S结构体(编码器GOP属性结构体)。
一。VENC模块的介绍
1.1. VENC模块概述
VENC(Video ENCoder)是RV1126芯片中专门用于视频编码的硬件模块,它通过硬件加速实现高效的视频编码,大大降低了CPU的负担。
1.2. 支持的编码格式
| 编码格式 | 特点 | 应用场景 |
|---|---|---|
| H.264 | 高效率视频编码,压缩比高 | 视频监控、网络直播、视频会议(最常用) |
| H.265 | 比H.264压缩效率高40%,节省带宽 | 4K/8K超高清视频、存储受限场景 |
| MJPEG | 运动JPEG,每帧独立压缩 | 医疗影像、工业检测、低速运动场景 |
| JPEG | 静态图像压缩 | 拍照、截图、封面生成 |
1.3. VENC模块的主要特性
编码性能
-
支持多路同时编码(如:2路1080p@30fps)
-
支持不同的分辨率同时输出
-
低延迟编码
二。VENC结构体定义
/* the attribute of the venc chnl*/
typedef struct rkVENC_CHN_ATTR_S {
VENC_ATTR_S stVencAttr; // 编码器基础属性结构体 the attribute of video encoder
VENC_RC_ATTR_S stRcAttr; // 编码码率控制属性结构体 the attribute of rate ctrl
VENC_GOP_ATTR_S stGopAttr; // 编码器GOP属性结构体 the attribute of gop
} VENC_CHN_ATTR_S;
VENC_CHN_ATTRS主要包含三个结构体:
- VENC_ATTR_S结构体(编码器基础属性结构体)
- VENC_RC_ATTR_S结构体(编码码率控制属性结构体)
- VENC_GOP_ATTR_S结构体(编码器GOP属性结构体)。
2.1 VENC_ATTR_S结构体(编码器基础属性结构体)
-
stVencAttr- 编码器基础属性-
包含编码器类型、分辨率、像素格式等基本信息
-
通常包括:
-
编码格式(H.264/H.265/JPEG等)
-
图像宽度和高度
-
输入图像格式
-
编码配置文件等
-
-
/* the attribute of the Venc*/
typedef struct rkVENC_ATTR_S {
CODEC_TYPE_E enType; // 编码器协议类型 RW; the type of encodec
IMAGE_TYPE_E imageType; // 输入图像类型,通常来说venc的imageType和vi的imageType是一致的 the type of input image
RK_U32 u32VirWidth; // stride width, same to buffer_width, must greater than
// width, often set vir_width=(width+15)&(~15)
RK_U32 u32VirHeight; // stride height, same to buffer_height, must greater
// than height, often set vir_height=(height+15)&(~15)
RK_U32 u32Profile; // RW;
// H.264: 66: baseline; 77:MP; 100:HP;
// H.265: default:Main;
// Jpege/MJpege: default:Baseline
RK_BOOL bByFrame; // RW; Range:[0,1];
// get stream mode is slice mode or frame mode
RK_U32 u32PicWidth; // 编码图像宽度
RK_U32 u32PicHeight; // 编码图像高度
VENC_ROTATION_E enRotation;
union {
VENC_ATTR_H264_S stAttrH264e; // attributes of H264e
VENC_ATTR_H265_S stAttrH265e; // attributes of H265e
VENC_ATTR_MJPEG_S stAttrMjpege; // attributes of Mjpeg
VENC_ATTR_JPEG_S stAttrJpege; // attributes of jpeg
};
} VENC_ATTR_S;
成员变量详解
enType- 编码器协议类型
指定使用的编码格式
例如:
RK_VIDEO_ID_AVC(H.264),RK_VIDEO_ID_HEVC(H.265),RK_VIDEO_ID_MJPEG,RK_VIDEO_ID_JPEGtypedef enum rk_CODEC_TYPE_E { RK_CODEC_TYPE_NONE = -1, // Audio RK_CODEC_TYPE_AAC, RK_CODEC_TYPE_MP2, RK_CODEC_TYPE_VORBIS, RK_CODEC_TYPE_G711A, RK_CODEC_TYPE_G711U, RK_CODEC_TYPE_G726, // Video RK_CODEC_TYPE_H264, RK_CODEC_TYPE_H265, RK_CODEC_TYPE_JPEG, RK_CODEC_TYPE_MJPEG, RK_CODEC_TYPE_NB } CODEC_TYPE_E;
imageType- 输入图像类型
编码器输入的图像格式
通常与VI(视频输入)模块的输出格式一致
例如:
IMAGE_TYPE_NV12,IMAGE_TYPE_NV16,IMAGE_TYPE_YUV420Ptypedef enum rk_IMAGE_TYPE_E { IMAGE_TYPE_UNKNOW = 0, IMAGE_TYPE_GRAY8, IMAGE_TYPE_GRAY16, IMAGE_TYPE_YUV420P, IMAGE_TYPE_NV12, IMAGE_TYPE_NV21, IMAGE_TYPE_YV12, IMAGE_TYPE_FBC2, IMAGE_TYPE_FBC0, IMAGE_TYPE_YUV422P, IMAGE_TYPE_NV16, IMAGE_TYPE_NV61, IMAGE_TYPE_YV16, IMAGE_TYPE_YUYV422, IMAGE_TYPE_UYVY422, IMAGE_TYPE_RGB332, IMAGE_TYPE_RGB565, IMAGE_TYPE_BGR565, IMAGE_TYPE_RGB888, IMAGE_TYPE_BGR888, IMAGE_TYPE_ARGB8888, IMAGE_TYPE_ABGR8888, IMAGE_TYPE_JPEG, IMAGE_TYPE_BUTT } IMAGE_TYPE_E;
u32VirWidth- 虚拟宽度(步长宽度)
内存中对齐的宽度,必须大于等于实际图像宽度
通常按16字节对齐:
vir_width = (width + 15) & (~15)
u32VirHeight- 虚拟高度(步长高度)
内存中对齐的高度,必须大于等于实际图像高度
通常按16字节对齐:
vir_height = (height + 15) & (~15)
u32Profile- 编码配置文件
H.264: 66-Baseline, 77-Main Profile, 100-High Profile
H.265: Main Profile (默认)
JPEG/MJPEG: Baseline (默认)
bByFrame- 获取流模式
RK_TRUE: 按帧获取编码数据
RK_FALSE: 按片获取编码数据
u32PicWidth- 编码图像实际宽度
u32PicHeight- 编码图像实际高度
enRotation- 旋转设置
图像旋转角度:0°, 90°, 180°, 270°
联合体 - 具体编码格式属性
stAttrH264e: H.264编码特定属性
stAttrH265e: H.265编码特定属性
stAttrMjpege: MJPEG编码特定属性
stAttrJpege: JPEG编码特定属性
2.2 VENC_RC_ATTR_S结构体(编码码率控制属性结构体)
VENC_RC_ATTR_S 定义了视频编码的码率控制相关参数,支持多种码率控制模式和编码格式。
/* the attribute of rc*/
typedef struct rkVENC_RC_ATTR_S {
/* RW; the type of rc*/
VENC_RC_MODE_E enRcMode;
union {
VENC_H264_CBR_S stH264Cbr;
VENC_H264_VBR_S stH264Vbr;
VENC_H264_AVBR_S stH264Avbr;
VENC_MJPEG_CBR_S stMjpegCbr;
VENC_MJPEG_VBR_S stMjpegVbr;
VENC_H265_CBR_S stH265Cbr;
VENC_H265_VBR_S stH265Vbr;
VENC_H265_AVBR_S stH265Avbr;
};
} VENC_RC_ATTR_S;
成员变量详解
enRcMode- 码率控制模式
指定使用的码率控制算法类型
常见模式:
VENC_RC_MODE_H264CBR/VENC_RC_MODE_H265CBR- 恒定码率
VENC_RC_MODE_H264VBR/VENC_RC_MODE_H265VBR- 可变码率
VENC_RC_MODE_H264AVBR/VENC_RC_MODE_H265AVBR- 自适应可变码率MJPEG对应的码率控制模式
联合体 - 具体码率控制参数
根据enRcMode和编码类型选择对应的结构体:H.264编码:
stH264Cbr- H.264恒定码率控制参数
stH264Vbr- H.264可变码率控制参数
stH264Avbr- H.264自适应可变码率控制参数H.265编码:
stH265Cbr- H.265恒定码率控制参数
stH265Vbr- H.265可变码率控制参数
stH265Avbr- H.265自适应可变码率控制参数MJPEG编码:
stMjpegCbr- MJPEG恒定码率控制参数
stMjpegVbr- MJPEG可变码率控制参数
2.3:VENC_GOP_ATTR_S结构体(编码器GOP属性结构体)。
VENC_GOP_ATTR_S 定义了视频编码的GOP相关参数,控制帧类型分布和QP调整。
/* the attribute of the gop*/
typedef struct rkVENC_GOP_ATTR_S {
VENC_GOP_MODE_E enGopMode;
RK_U32 u32GopSize;
RK_S32 s32IPQpDelta;
RK_U32 u32BgInterval;
RK_S32 s32ViQpDelta;
} VENC_GOP_ATTR_S;
成员变量详解
enGopMode- GOP模式
指定GOP的结构模式
常见模式:
VENC_GOPMODE_NORMAL- 常规GOP模式
VENC_GOPMODE_B- 包含B帧的GOP模式
VENC_GOPMODE_SMARTP- 智能P帧模式
VENC_GOPMODE_DUALP- 双P帧模式
u32GopSize- GOP大小
两个I帧之间的间隔(帧数)
例如:30表示每30帧有一个I帧
影响编码效率和随机访问能力
s32IPQpDelta- I帧与P帧的QP差值
I帧相对于P帧的QP偏移量
通常为负值,表示I帧使用更小的QP(更好的质量)
例如:-5 表示I帧的QP比P帧小5
u32BgInterval- 背景帧间隔
背景参考帧的更新间隔
用于长期参考帧管理
s32ViQpDelta- 视觉感知QP差值
基于视觉感知的QP调整值
用于人眼敏感区域的QP优化
2.4:配置实例
VENC_CHN_ATTR_S venc_chn_attr;
//****** VENC Attr Set ************************//
venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;
venc_chn_attr.stVencAttr.u32PicWidth = 1920;
venc_chn_attr.stVencAttr.u32PicHeight = 1080;
venc_chn_attr.stVencAttr.u32VirWidth = 1920;
venc_chn_attr.stVencAttr.u32VirHeight = 1080;
venc_chn_attr.stVencAttr.u32Profile = 66;
venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12;
venc_chn_attr.stVencAttr.enRotation = VENC_ROTATION_0;
//********* VENC RCMODE Set *******************//
venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 25;
//25/1 NUM/DEN == FrameRate
venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1; //
venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 25;
venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;
venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 25;
venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = 8388608; //1M
ret = RK_MPI_VENC_CreateChn(VENC_CHN, &venc_chn_attr);
基础编码属性:
编码格式:H.264
分辨率:1920×1080
像素格式:NV12
Profile:66(Baseline)
无旋转
码率控制配置:
模式:H.264 CBR(恒定码率)
GOP大小:25帧
帧率:25fps
码率:8,388,608 bps(实际约8.4Mbps)
常见的码率和计算发送
1 Kb = 1024 bit
1 KB = 1024 Byte
1 Mb = 1024 Kb
1 MB = 1024 KB
1 Byte = 8 bit
1 MB = 8Mb
1 Mb = 0.125 MB
1M = 1024字节 = 1024 b
1b = 8bit1024 * 1024 * 8 = 8388608
更多的细节我就不展开了,大家可以看看源码
三。VENC 创建API接口
RK_S32 RK_MPI_VENC_CreateChn(VENC_CHN VeChn, const VENC_CHN_ATTR_S *pstAttr);
参数说明
VENC_CHN VeChn- 编码通道号
指定要创建的编码通道编号
通常定义为:
#define VENC_CHN 0
const VENC_CHN_ATTR_S *pstAttr- 编码通道属性指针
传入前面配置好的编码通道属性结构体
包含编码器基础属性、码率控制属性、GOP属性等
返回值
RK_SUCCESS(0): 创建成功其他值: 创建失败,返回错误码
四。实战:多线程获取VENC的H264码流数据
4.1 RV1126模块采并进行VENC编码的流程

VI模块相关介绍和初始化在下面连接中,大家可以去问问
https://blog.youkuaiyun.com/ALIANG2000/article/details/154024292?spm=1011.2124.3001.6209
https://blog.youkuaiyun.com/ALIANG2000/article/details/154024292?spm=1011.2124.3001.6209VENC模块初始化在 2.4 配置实例中有配置
4.2绑定函数
RK媒体处理系统中绑定两个模块通道的关键函数
ret = RK_MPI_SYS_Bind(&vi_chn_s, &venc_chn_s);
参数说明
pstSrcChn- 源通道
数据流的来源通道
这里是指VI(视频输入)通道
pstDestChn- 目标通道
数据流的目的地通道
这里是指VENC(视频编码)通道
返回值
RK_SUCCESS(0): 绑定成功其他值: 绑定失败,返回错误码
MPP_CHN_S vi_chn_s;
vi_chn_s.enModId = RK_ID_VI;
vi_chn_s.s32ChnId = CAMERA_CHN;
MPP_CHN_S venc_chn_s;
venc_chn_s.enModId = RK_ID_VENC;
venc_chn_s.s32ChnId = VENC_CHN;
ret = RK_MPI_SYS_Bind(&vi_chn_s, &venc_chn_s);
4.3 创建多线程读取VENC数据
pthread_t pid;
pthread_create(&pid, NULL, get_h264_venc_thread, NULL);
while (1)
{
sleep(1);
}
void * get_h264_venc_thread(void * args)
{
pthread_detach(pthread_self());
FILE * h264_file = fopen("test_camera.h264", "w+");
MEDIA_BUFFER mb;
while (1)
{
mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, VENC_CHN, -1);
if(!mb)
{
printf("Get Venc Mb Break.....\n");
break;
}
printf("Get H264 One Frame.......\n");
fwrite(RK_MPI_MB_GetPtr(mb),RK_MPI_MB_GetSize(mb),1, h264_file);
RK_MPI_MB_ReleaseBuffer(mb);
}
return NULL;
}
读取VENS数据具体流程和RGA流程基本一致:
创建h264文件,用于保存读取到的数据
定义 MEDIA_BUFFER mb 结构体,用于临时存储从VI中读取到数据
将mb的数据写入h264文件中
释放mb内存空间
4.4 关闭VI,VENC,和解绑
RK_MPI_VI_DisableChn(CAMERA_ID, CAMERA_CHN);
RK_MPI_VENC_DestroyChn(VENC_CHN);
RK_MPI_SYS_UnBind(&vi_chn_s, &venc_chn_s);
五。调试记录
5.1 .第一次调试

通过日志输出主要报错两个问题:
[RKMEDIA][SYS][Error]:invalid gop mode(352)!
[RKMEDIA][VENC][Error]:The resolution of the input buffer is wrong.
问题定位点:分辨率不匹配错误:
mpp[1732]: h264e_api_v2: MPP_ENC_SET_PREP_CFG w:h [1920:1020] stride [1920:1080] mpp[1732]: mpp_enc: send header for set cfg change input/format [RKMEDIA][VENC][Info]:MPP Encoder: w x h(1920[1920] x 1020[1080])
5.2 第二次调试:

忘记在线程的输出中加入换行符号
void *get_h264_venc_thread(void * args)
{
pthread_detach(pthread_self());//recall pthread
FILE * h264_file = fopen("test_camera.h264","w+");
MEDIA_BUFFER mb;
while(1)
{
mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC,VENC_CHN,-1);
if(!mb)
{
printf("get Venc Mb failed....\n");
break;
}
printf("Get H264 One Frame ....\n");//这里忘记加入\n
fwrite(RK_MPI_MB_GetPtr(mb),RK_MPI_MB_GetSize(mb),1,h264_file);
RK_MPI_MB_ReleaseBuffer(mb);//realease the memory;otherwise,it will cause a memory lea;
}
检查下是否生成 目标文件和目标文件的大小
![]()
一开始没有反应过来:采集的时间的稍微长一点
使用cmd 驱动ffplay显示采集的视频:

5.3 做h264和nv12的数据对比
5.3.1 运行RGA程序

问题:显示界面不对,而且时间短
可以看到已经生成了一个366.7M的nv12文件

看上去像是播放的分辨率不对
问题:RGA这个程序分辨率我修改成1280*720大小,但是在使用ffplay指令时设置成1920*1070导致读取数据错误
正确指令:
ffplay -f rawvideo -pix_fmt nv12 -video_size 1280x720 vi_rga_RGA_FLIP_V.nv12

![]()
5.3.2 运行VENC程序
需要杀死当前的进行,才可以运行,否则无法运行下次

发现已经生成了一个.h264文件,但是文件大小是空的
经过排查发现是.nv12空间过大,导致当前目录下的可用空间无了,无法写入数据导致的
删掉nv12程序,重新运行
![]()
直接使用这个指令 ffplay.exe test_camera.h264

5.3.3 总结:
RGA数据分辨率为1280*720,运行时长才8秒多,数据大小为309.9M
VENC数据分辨率为1980*1020,运行时长为32秒,数据大小才33M
1013

被折叠的 条评论
为什么被折叠?



