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

相关文章

Redis 基本数据类型和使用详解

《Redis基本数据类型和使用详解》String是Redis最基本的数据类型,一个键对应一个值,它的功能十分强大,可以存储字符串、整数、浮点数等多种数据格式,本文给大家介绍Redis基本数据类型和... 目录一、Redis 入门介绍二、Redis 的五大基本数据类型2.1 String 类型2.2 Hash

Java Instrumentation从概念到基本用法详解

《JavaInstrumentation从概念到基本用法详解》JavaInstrumentation是java.lang.instrument包提供的API,允许开发者在类被JVM加载时对其进行修改... 目录一、什么是 Java Instrumentation主要用途二、核心概念1. Java Agent

Java实现为PDF设置背景色和背景图片

《Java实现为PDF设置背景色和背景图片》在日常的文档处理中,PDF格式因其稳定性和跨平台兼容性而广受欢迎,本文将深入探讨如何利用Spire.PDFforJava库,以简洁高效的方式为你的PDF文档... 目录库介绍与安装步骤Java 给 PDF 设置背景颜色Java 给 PDF 设置背景图片总结在日常的

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

Python动态处理文件编码的完整指南

《Python动态处理文件编码的完整指南》在Python文件处理的高级应用中,我们经常会遇到需要动态处理文件编码的场景,本文将深入探讨Python中动态处理文件编码的技术,有需要的小伙伴可以了解下... 目录引言一、理解python的文件编码体系1.1 Python的IO层次结构1.2 编码问题的常见场景二

Python进行word模板内容替换的实现示例

《Python进行word模板内容替换的实现示例》本文介绍了使用Python自动化处理Word模板文档的常用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友... 目录技术背景与需求场景核心工具库介绍1.获取你的word模板内容2.正常文本内容的替换3.表格内容的

python库pydantic数据验证和设置管理库的用途

《python库pydantic数据验证和设置管理库的用途》pydantic是一个用于数据验证和设置管理的Python库,它主要利用Python类型注解来定义数据模型的结构和验证规则,本文给大家介绍p... 目录主要特点和用途:Field数值验证参数总结pydantic 是一个让你能够 confidentl

Git进行版本控制的实战指南

《Git进行版本控制的实战指南》Git是一种分布式版本控制系统,广泛应用于软件开发中,它可以记录和管理项目的历史修改,并支持多人协作开发,通过Git,开发者可以轻松地跟踪代码变更、合并分支、回退版本等... 目录一、Git核心概念解析二、环境搭建与配置1. 安装Git(Windows示例)2. 基础配置(必

Kotlin 协程之Channel的概念和基本使用详解

《Kotlin协程之Channel的概念和基本使用详解》文章介绍协程在复杂场景中使用Channel进行数据传递与控制,涵盖创建参数、缓冲策略、操作方式及异常处理,适用于持续数据流、多协程协作等,需注... 目录前言launch / async 适合的场景Channel 的概念和基本使用概念Channel 的

Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧

《Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧》本文将通过实际代码示例,深入讲解Python函数的基本用法、返回值特性、全局变量修改以及异常处理技巧,感兴趣的朋友跟随小编一起看看... 目录一、python函数定义与调用1.1 基本函数定义1.2 函数调用二、函数返回值详解2.1 有返