当前位置: 首页 > news >正文

Hi3518E官方录像例程源码流程分析(五)

文章目录

  • Venc理论部分
  • 阶段五 开始视频流编码
    • SAMPLE_COMM_VENC_Start()
      • s32Ret = SAMPLE_COMM_SYS_GetPicSize(enNorm, enSize, &stPicSize);
      • 创造Venc channal
  • 码率控制
    • CBR
    • FIXQP
    • VBR
      • HI_MPI_VENC_CreateChn
      • HI_MPI_VENC_StartRecvPic
    • SAMPLE_COMM_VENC_BindVpss 绑定VPsschn0 到Vencchn0
      • HI_MPI_SYS_Bind()

源码地址 + 文档资料 – 提取码: chmr

本专栏分析的是mpp\venc\sample\sample_venc.c

Venc理论部分

在这里插入图片描述
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 支持 Semi-planar YUV 4:2:0 或 Semi-planar YUV 4:2:2。另外,Hi3518EV200 能够支持单分量输入(只存在 Y 分量)。通道模块接收外部原始图像数据,而不关心图像数据是来自哪个外部模块。

通道接收到图像之后,比较图像尺寸和编码通道尺寸:

  • 如果输入图像比编码通道尺寸大,VENC 将按照编码通道尺寸大小,调用 VGS 对源图像进行缩小,然后对缩小之后的图像进行编码。
  • 如果输入图像比编码通道尺寸小,VENC 丢弃源图像。VENC 不支持放大输入图像编码。
  • 如果输入图像与编码通道尺寸相当,VENC 直接接受源图像,进行编码。

在这里插入图片描述

编码通道作为基本容器,保存编码通道的多种用户设置和管理编码通道的多种内部资源。编码通道完成图像转化为码流的功能,具体由码率控制器和编码器协同完成。这里的编码器指的是狭义上的编码器,只完成编码功能。码率控制器提供了对编码参数的控制和调整,从而对输出码率进行控制。

阶段五 开始视频流编码

	if(s32ChnNum >= 1){VpssGrp = 0;VpssChn = 0;VencChn = 0;//bind VencChn0 to VpssChn0s32Ret = SAMPLE_COMM_VENC_Start(VencChn, enPayLoad[0],\gs_enNorm, enSize[0], enRcMode,u32Profile);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("Start Venc failed!\n");goto END_VENC_1080P_CLASSIC_5;}//bind VencChn0 to VpssChn0s32Ret = SAMPLE_COMM_VENC_BindVpss(VencChn, VpssGrp, VpssChn);if (HI_SUCCESS != s32Ret){SAMPLE_PRT("Start Venc failed!\n");goto END_VENC_1080P_CLASSIC_5;}}

SAMPLE_COMM_VENC_Start()

s32Ret = SAMPLE_COMM_SYS_GetPicSize(enNorm, enSize, &stPicSize);

首先是前面出现过很多次的GetPicSize,就不再哆嗦了

创造Venc channal

首先命中enType的H264

        case PT_H264:{stH264Attr.u32MaxPicWidth = stPicSize.u32Width;stH264Attr.u32MaxPicHeight = stPicSize.u32Height;stH264Attr.u32PicWidth = stPicSize.u32Width;/*the picture width*/stH264Attr.u32PicHeight = stPicSize.u32Height;/*the picture height*/stH264Attr.u32BufSize  = stPicSize.u32Width * stPicSize.u32Height;/*stream buffer size*/stH264Attr.u32Profile  = u32Profile;/*0: baseline; 1:MP; 2:HP;  3:svc_t */stH264Attr.bByFrame = HI_TRUE;/*get stream mode is slice mode or frame mode?*/stH264Attr.u32BFrameNum = 0;/* 0: not support B frame; >=1: number of B frames */stH264Attr.u32RefNum = 1;/* 0: default; number of refrence frame*/memcpy(&stVencChnAttr.stVeAttr.stAttrH264e, &stH264Attr, sizeof(VENC_ATTR_H264_S));if(SAMPLE_RC_CBR == enRcMode){stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;stH264Cbr.u32Gop            = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;stH264Cbr.u32StatTime       = 1; /* stream rate statics time(s) */stH264Cbr.u32SrcFrmRate      = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;/* input (vi) frame rate */stH264Cbr.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;/* target frame rate */switch (enSize){case PIC_QCIF:stH264Cbr.u32BitRate = 256; /* average bit rate */break;case PIC_QVGA:    /* 320 * 240 */case PIC_CIF: stH264Cbr.u32BitRate = 512;break;case PIC_D1:case PIC_VGA:	   /* 640 * 480 */stH264Cbr.u32BitRate = 1024*2;break;case PIC_HD720:   /* 1280 * 720 */stH264Cbr.u32BitRate = 1024*2;break;case PIC_HD1080:  /* 1920 * 1080 */stH264Cbr.u32BitRate = 1024*4;break;case PIC_5M:  /* 2592 * 1944 */stH264Cbr.u32BitRate = 1024*8;break;                       default :stH264Cbr.u32BitRate = 1024*4;break;}stH264Cbr.u32FluctuateLevel = 0; /* average bit rate */memcpy(&stVencChnAttr.stRcAttr.stAttrH264Cbr, &stH264Cbr, sizeof(VENC_ATTR_H264_CBR_S));}else if (SAMPLE_RC_FIXQP == enRcMode) {stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264FIXQP;stH264FixQp.u32Gop = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;stH264FixQp.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;stH264FixQp.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;stH264FixQp.u32IQp = 20;stH264FixQp.u32PQp = 23;memcpy(&stVencChnAttr.stRcAttr.stAttrH264FixQp, &stH264FixQp,sizeof(VENC_ATTR_H264_FIXQP_S));}else if (SAMPLE_RC_VBR == enRcMode) {stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264VBR;stH264Vbr.u32Gop = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;stH264Vbr.u32StatTime = 1;stH264Vbr.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;stH264Vbr.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;stH264Vbr.u32MinQp = 10;stH264Vbr.u32MaxQp = 40;switch (enSize){case PIC_HD720:   /* 1280 * 720 */stH264Vbr.u32MaxBitRate = 1024*3;break;default :stH264Vbr.u32MaxBitRate = 1024*4;break;}memcpy(&stVencChnAttr.stRcAttr.stAttrH264Vbr, &stH264Vbr, sizeof(VENC_ATTR_H264_VBR_S));}else{return HI_FAILURE;}}break;

首先是这两步

stH264Attr.u32MaxPicWidth  = stPicSize.u32Width;
stH264Attr.u32MaxPicHeight = stPicSize.u32Height;
stH264Attr.u32PicWidth     = stPicSize.u32Width;/*the picture width*/
stH264Attr.u32PicHeight    = stPicSize.u32Height;/*the picture height*/

通过上面资料可知

  • 如果输入图像比编码通道尺寸大,VENC 将按照编码通道尺寸大小,调用 VGS 对源图像进行缩小,然后对缩小之后的图像进行编码。
  • 如果输入图像比编码通道尺寸小,VENC 丢弃源图像。VENC 不支持放大输入图像编码。
  • 如果输入图像与编码通道尺寸相当,VENC 直接接受源图像,进行编码。

所以这里直接把图像尺寸大小给到编码通道,这样既不会丢弃源图像,也不会对图像进行缩小

码率控制

CBR

CBR(Constant Bit Rate)固定比特率。即在码率统计时间内保证编码码率平稳。码率稳定主要由两个量来评估,这两个量都可以由用户在创建编码通道时指定。

  • 码率统计时间 u32StatTime
    单位为秒(s),码率统计时间越长,每帧图像的码率波动对于码率调节的影响越弱,码率的调节会更缓慢,图像质量的波动会更轻微;码率统计时间越短,每帧图像的码率波动对于码率调节的影响越强,图像码率的调节会更灵敏,图像质量的波动会更剧烈。

  • 行级码率控制调节幅度 u32RowQpDelta
    行级码率控制调节幅度是一帧内行级调节的最大范围,其中行级以宏块行为单位。调节幅度越大,允许行级调整的 QP 范围越大,码率越平稳。对于图像复杂度分布不均匀的场景,行级码率控制调节幅度设置过大会带来图像质量不均匀。

stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
stH264Cbr.u32Gop                = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264Cbr.u32StatTime           = 1; /* stream rate statics time(s) */
stH264Cbr.u32SrcFrmRate         = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;/* input (vi) frame rate */
stH264Cbr.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;/* target frame rate */
case PIC_HD720:   /* 1280 * 720 */stH264Cbr.u32BitRate = 1024*2;

FIXQP

Fix Qp 固定 Qp 值。在码率统计时间内,编码图像所有宏块 Qp 值相同,采用用户设定
的图像 Qp 值,I 帧和 P 帧的 QP 值可以分别设置。

stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264FIXQP;
stH264FixQp.u32Gop = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264FixQp.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264FixQp.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264FixQp.u32IQp = 20;
stH264FixQp.u32PQp = 23;

VBR

VBR(Variable Bit Rate)可变比特率,即允许在码率统计时间内编码码率波动,从而保证编码图像质量平稳。以 H.264 编码为例,VENC 模块提供用户可设置 MaxQp,MinQp,MaxBitrate 和 ChangePos。MaxQp,MinQp 用于控制图像的质量范围, MaxBitrate 用于钳位码率统计时间内的最大编码码率,ChangePos 用于控制开始调整Qp 的码率基准线。当编码码率大于 MaxBitrateChangePos 时,图像 qp 会逐步向MaxQp 调整,如果图像 QP 达到 MaxQp,QP 会被钳位到最大值,MaxBitrate 的钳位效果失效,编码码率有可能会超出 MaxBitrate。当编码码率小于 MaxBitrateChangePos时,图像 QP 会逐步向 MinQp 调整,如果图像 QP 达到 MinQp,此时编码的码率已经达到最大值,而且图像质量最好。

stVencChnAttr.stRcAttr.enRcMode = VENC_RC_MODE_H264VBR;
stH264Vbr.u32Gop = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264Vbr.u32StatTime = 1;
stH264Vbr.u32SrcFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264Vbr.fr32DstFrmRate = (VIDEO_ENCODING_MODE_PAL== enNorm)?25:30;
stH264Vbr.u32MinQp = 10;
stH264Vbr.u32MaxQp = 40;

HI_MPI_VENC_CreateChn

通过上面设置好的参数创建Venc通道

HI_MPI_VENC_StartRecvPic

开始接收Venc图像

SAMPLE_COMM_VENC_BindVpss 绑定VPsschn0 到Vencchn0

VPsschn2 到Vencchn02的部分在if(s32ChnNum >= 2)

    HI_S32 s32Ret = HI_SUCCESS;MPP_CHN_S stSrcChn;MPP_CHN_S stDestChn;stSrcChn.enModId = HI_ID_VPSS;stSrcChn.s32DevId = VpssGrp;stSrcChn.s32ChnId = VpssChn;stDestChn.enModId = HI_ID_VENC;stDestChn.s32DevId = 0;stDestChn.s32ChnId = VeChn;s32Ret = HI_MPI_SYS_Bind(&stSrcChn, &stDestChn);if (s32Ret != HI_SUCCESS){SAMPLE_PRT("failed with %#x!\n", s32Ret);return HI_FAILURE;}

HI_MPI_SYS_Bind()

相关文章:

  • PNG透明免抠设计素材大全26000+
  • python异步协程async调用过程图解
  • HTTP 请求头的 key 不区分大小写。
  • FlinkUDF用户自定义函数深度剖析
  • 洛谷5318C语言题解
  • Linux CAN 驱动浅析
  • 私有知识库 Coco AI 实战(二):摄入 MongoDB 数据
  • 【问题解决】本机navicat连接云服务器mysql
  • 工作记录9
  • 【Pandas】pandas DataFrame mod
  • 【复盘】cpu飙升引发的连锁反应
  • JDK 7 Update 0 (64位) 详细Windows 安装指南
  • 每日一题(小白)模拟娱乐篇33
  • Java 拦截器完全指南:原理、实战与最佳实践
  • Chronos - 时间序列预测语言模型
  • Redis从入门到实战先导篇
  • Jsoup、Selenium 和 Playwright 的含义、作用和区别
  • 【C/S通信仿真】
  • 17.QT-Qt窗口-工具栏|状态栏|浮动窗口|设置停靠位置|设置浮动属性|设置移动属性|拉伸系数|添加控件(C++)
  • 软件黑盒与白盒测试详解
  • 魔都眼·上海车展④|奔驰宝马保时捷……全球豪车扎堆首秀
  • 广东省发展改革委原副主任、省能源局原局长吴道闻被开除公职
  • 过敏性鼻炎,不只是“打喷嚏”那么简单
  • 全红婵、李宁亮相中国航天日论坛,体育和航天这一次紧密相连
  • 股市劝服马斯克
  • 温氏股份一季度归母净利润20.01亿元,同比扭亏为盈