Hi3518EV200进行H264编码时对VENC的基本设置

2024-04-27 09:08

本文主要是介绍Hi3518EV200进行H264编码时对VENC的基本设置,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

〇、文档说明

本文性质为个人学习笔记。
由于项目需要,基于Hi3518EV200平台进行H264编码,在此过程中涉及到对VENC的控制和理解,记录以备忘。
另外,如果您在学习hi3518编码h264的过程中有疑惑,希望我的博文可以帮到您:
1.Hi3518EV200实现H264视频采集的源码及流程详解(不依赖SAMPLE库)
2.从零开始进行Hi3518_SDK安装、环境搭建和Linux内核编译,并生成可供烧写的uImage
期待如今的我和未来的你,一起进步!

一、VENC(Video Encoder,视频编码模块)

VENC的相关内容,无论是网上还是手册中都已经介绍的非常详细了,但是对于一个学习的人而言,应当考虑的是如何将这些东西转化为自己的理解,而理解的最好过程就是用自己的语言讲出来。
VENC的学习,先从了解它的作用开始。下文描述、举例、现象等均在Hi3518EV200平台进行,MPP[Hi3518EV200_MPP_V1.0.4.0 B050 Release]
视频流从sensor到输出是这样的:
VI(sensor-ISP-ViDev0-Chn[0]/Ext_Chn[1-16])–VPSS(Group-Chn[(在线)0/(离线)0-31]/Ext_Chn[4-11])–VENC(Chn[0-15],Payload[H264/H265/JPEG],RC[CBR/VBR/AVBR/FIXQP])–输出
上面这个流程涵盖了几乎所有基本配置内容,其中通道数的限制都是基于手册查找。VENC在整个编码过程中可以干的事情有:关于通道有效荷载的编码协议选择、编码码率控制。我们所有针对VENC的设置都是围绕这两方面进行。

二、VENC设置步骤

VENC部分需要完成的设置一共有三项:
1.1选择要编码的编码方式,照着该编码方式配置相应结构体;
1.2按照所选择的编码方式的不同,配置与其对应的码流控制参数结构体;
2.按照上述的配置创建VENC通道;
3.启动通道的图像接收并绑定前级模块。

    VENC_CHN VencChn=0;                 //选择VENC通道号——0PAYLOAD_TYPE_E enPayLoad=PT_H264;   //选择编码方式——H264,更换编码要同时更换后面的设置参数VENC_CHN_ATTR_S stVencChnAttr;      //VENC通道属性参数结构体VENC_ATTR_H264_S stH264Attr;        //H264属性参数结构体VENC_ATTR_H264_CBR_S stH264Cbr;     //H264-CBR码率控制参数结构体SIZE_S stPicSize;                   //图像尺寸信息变量stPicSize.u32Width=1920;            //设置图像宽度stPicSize.u32Height=1080;           //设置图像高度HI_U32 u32Profile=0;                //0: baseline; 1:MP; 2:HP;3:Svc_t//--1--创建VENC通道stVencChnAttr.stVeAttr.enType=enPayLoad;if(enPayLoad==PT_H264)//在编码为H264的时候执行,换编码方式在此处{stH264Attr.u32MaxPicWidth=stPicSize.u32Width;  //设置最大图像宽度stH264Attr.u32MaxPicHeight=stPicSize.u32Height;//设置最大图像高度stH264Attr.u32PicWidth=stPicSize.u32Width;     //设置图像宽度stH264Attr.u32PicHeight=stPicSize.u32Height;   //设置图像高度stH264Attr.u32BufSize=stPicSize.u32Width * stPicSize.u32Height;//流缓冲器大小stH264Attr.u32Profile=u32Profile;              /*0: baseline; 1:MP; 2:HP;  3:svc_t */stH264Attr.bByFrame=HI_TRUE;                   //获取流模式是切片模式还是帧模式?stH264Attr.u32BFrameNum=0;                     //0: 不支持B帧; >=1:B帧的数量stH264Attr.u32RefNum=1;                        //0: 默认; >=0:参考帧数量memcpy(&stVencChnAttr.stVeAttr.stAttrH264e, &stH264Attr, sizeof(VENC_ATTR_H264_S));//选择编码码率控制方式——CBR{stVencChnAttr.stRcAttr.enRcMode=VENC_RC_MODE_H264CBR;stH264Cbr.u32Gop         =30;//图像组:I帧间间隔stH264Cbr.u32StatTime    =1; //码率统计时间stH264Cbr.u32SrcFrmRate  =30;//输入(VI)帧率stH264Cbr.fr32DstFrmRate =30;//输出帧率//下面的定义需要根据传感器分辨率修改stH264Cbr.u32BitRate=1024*2;stH264Cbr.u32FluctuateLevel=0;//平均比特率memcpy(&stVencChnAttr.stRcAttr.stAttrH264Cbr, &stH264Cbr, sizeof(VENC_ATTR_H264_CBR_S));}}s32Ret=HI_MPI_VENC_CreateChn(VencChn, &stVencChnAttr);//创建VENC通道//--2--启动接收VENC图像s32Ret=HI_MPI_VENC_StartRecvPic(VencChn);//--3--绑定VPSS和VENCMPP_CHN_S stSrcChn;  //源通道设备参数结构体MPP_CHN_S stDestChn; //目的通道设备参数结构体stSrcChn.enModId=HI_ID_VPSS;stSrcChn.s32DevId=0; //选择VPSS组号——0stSrcChn.s32ChnId=0; //选择VPSS通道号——0stDestChn.enModId=HI_ID_VENC;stDestChn.s32DevId=0;stDestChn.s32ChnId=0;//选择VENC通道号——0s32Ret=HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);//绑定源通道和目的通道

三、相关设置项说明

1.VENC的图像缩放

参考《HiMPP IPC V2.0 媒体处理软件开发参考》(下文称“手册”)521页,通道接收到图像之后,比较图像尺寸和编码通道尺寸:如果输入图像比编码通道尺寸大,VENC将按照编码通道尺寸大小,调用VGS对源图像进行缩小,然后对缩小之后的图像进行编码。如果输入图像比编码通道尺寸小,VENC丢弃源图像。VENC不支持放大输入图像编码。如果输入图像与编码通道尺寸相当,VENC直接接受源图像,进行编码。
也就是说,VENC模块只支持原比例编码或者缩小,但不支持放大,如果设置的编码宽高大于输入图像的宽高,则会产生错误
VENC输出的图像宽高在stH264Attr.u32PicWidth和stH264Attr.u32PicHeight两个变量进行设置。
对于编码器宽高取值的限制在手册535页:
编码器属性最大宽高,通道宽高必须满足如下约束:
− MaxPicWidth∈[MIN_WIDTH, MAX_WIDTH]
− MaxPicHeight∈[MIN_HEIGHT, MAX_HEIGHT]
− PicWidth∈[MIN_WIDTH, MAX_WIDTH]
− PicHeight∈[MIN_HEIGHT, MAX_HEIGHT]
− 最大宽高,通道宽高必须是MIN_ALIGN的整数倍。
其中MIN_WIDTH,MAX_WIDTH,MIN_HEIGHT,MAX_HEIGHT,MIN_ALIGN分别表示编码通道支持的最小宽度,最大宽度,最小高度,最大高度,最小对齐单元(像素)。
芯片相关编码通道差异
另外,在手册774也中对宽高的属性也做了说明:
编码器属性中除通道宽高(u32PicWidth和u32PicHeight)外都是静态属性,一旦创建编码通道成功,静态属性不支持被修改,除非该通道被销毁,重新创建。
这说明在通道建立成功后,可以在程序运行过程中动态地修改编码宽、高

2.VENC帧率控制

VENC作为编码的模块,自然有能力决定编码产生的帧率大小,对帧率的设置在码率参数结构体中进行:
stH264Cbr.u32SrcFrmRate表示从前级模块(VI或VPSS)传来的视频图像的帧率,一般我们在设置VPSS模块的时候不开启它的帧率控制,例如芯片SAMPLE例程库中进行的那样,此时从VPSS模块传来的图像帧率就是VI模块输出的图像帧率。
VI模块的帧率设置分为两部分,一是sensor向ISP注册时传入的帧率参数,这个帧率是sensor支持的帧率,是不一定能任意修改的;二是VI物理通道设置的帧率控制,这个在SAMPLE库中也没有进行设置。所以我们不妨也按照这种方法进行,即对帧率的修改放在VENC模块上。
此时传给VENC模块的源帧率就是sensor支持得到的最大值,假设是30fps,我们只需要设置目的帧率stH264Cbr.fr32DstFrmRate变量即可完成帧率控制。
但是实际的情况要是都这么简单就好了。
按照手册951页的说法,我给翻译翻译,就是说VENC的帧率控制分为两种情况,分别为“增帧”或者“减帧/不控制”。
在增帧模式下,要设置的是u32SrcFrmRate成员,假设前级传来的帧率是30fps,我想要60fps,那就应该设置u32SrcFrmRate=60,fr32DstFrmRate=60;
在减帧或者不控制的情况下,源帧率要设置成产生时间参考的实际帧率,此时要区分在线模式或者离线模式,关于离线模式和在线模式的说明可以参考手册32页。这里如果我们在VI/VPSS前级模块没有进行任何帧率控制,那么u32SrcFrmRate就是VI的帧率(sensor帧率)。目的帧率fr32DstFrmRate的设置分为两种,一是目标帧率为整数,此时fr32DstFrmRate设置为整数即可,例如25帧(每秒25帧);二是目标帧率为分数,例如每两秒25帧(每秒25/2帧),则fr32DstFrmRate=(2<<16)+25。

3.GOP设置

声明: 本节参考了https://blog.csdn.net/xiaoyida11/article/details/52852398
GOP设置由u32Gop成员确定,其目的是定义视频编码帧中的I帧间间隔,如果设置编码码流帧配置模式为多包模式(参考手册527页),那么可以发现,I帧会分为4个小包,其中第四包为数据包。下图为设置GOP为30时的编码流情况:
gop=30rc(gop=30)
u32Gop成员即决定了I帧和I帧之间间隔包计数。顺便提一嘴,B帧的编码有前文程序中的stH264Attr.u32BFrameNum变量确定,参考例程,已经给关了。
如果希望I帧出现在每秒编码帧的首包,则应该将u32Gop设置为目的帧率。下图为设置u32Gop=fr32DstFrmRate=10的编码输出情况。
gop=10
暂时从项目中总结的就是这么多,以上。

四、阅读注意

1.在本记录中为了简便起见,删除了所有对函数返回值s32Ret的判断,在实际程序中应该对相应执行失败的函数做适当处理。
2.本文仅为个人学习记录,如直接套用或者言语不明造成经济损失等后果作者不承担责任,如需转载,请注明原作者及出处。
————2020-1-2 @燕卫博————

这篇关于Hi3518EV200进行H264编码时对VENC的基本设置的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/940088

相关文章

基本知识点

1、c++的输入加上ios::sync_with_stdio(false);  等价于 c的输入,读取速度会加快(但是在字符串的题里面和容易出现问题) 2、lower_bound()和upper_bound() iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素。 iterator upper_bou

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

【IPV6从入门到起飞】5-1 IPV6+Home Assistant(搭建基本环境)

【IPV6从入门到起飞】5-1 IPV6+Home Assistant #搭建基本环境 1 背景2 docker下载 hass3 创建容器4 浏览器访问 hass5 手机APP远程访问hass6 更多玩法 1 背景 既然电脑可以IPV6入站,手机流量可以访问IPV6网络的服务,为什么不在电脑搭建Home Assistant(hass),来控制你的设备呢?@智能家居 @万物互联

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return

C 语言的基本数据类型

C 语言的基本数据类型 注:本文面向 C 语言初学者,如果你是熟手,那就不用看了。 有人问我,char、short、int、long、float、double 等这些关键字到底是什么意思,如果说他们是数据类型的话,那么为啥有这么多数据类型呢? 如果写了一句: int a; 那么执行的时候在内存中会有什么变化呢? 橡皮泥大家都玩过吧,一般你买橡皮泥的时候,店家会赠送一些模板。 上

form表单提交编码的问题

浏览器在form提交后,会生成一个HTTP的头部信息"content-type",标准规定其形式为Content-type: application/x-www-form-urlencoded; charset=UTF-8        那么我们如果需要修改编码,不使用默认的,那么可以如下这样操作修改编码,来满足需求: hmtl代码:   <meta http-equiv="Conte

遮罩,在指定元素上进行遮罩

废话不多说,直接上代码: ps:依赖 jquer.js 1.首先,定义一个 Overlay.js  代码如下: /*遮罩 Overlay js 对象*/function Overlay(options){//{targetId:'',viewHtml:'',viewWidth:'',viewHeight:''}try{this.state=false;//遮罩状态 true 激活,f