news 2026/4/7 1:59:15

Linux_16:GOP参数调节

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux_16:GOP参数调节

1.RV1126GOP模式的分类

在RV1126中GOP模式,一般分为三大类,分别是普通GOP模式智能SMARTPGOP模式TSVCGOP模式。这三种不同的GOP模式,分别对应不同的视频场景。下面我们来一一介绍这三种GOP模式的特点。

1.普通GOP模式

普通GOP模式是最常见的GOP模式,它的特点就是两个I帧间隔固定的GOPSIZE,而GOPSIZE里面都是P帧或者B帧。比方说上图,GOPSIZE=5,相当于每隔5个P帧或者B帧插入一个I帧;普通的GOP模式通常适用于普通场景,比方说视频场景比较单一,没有那种运动画面、静止画面频繁切换的场景。

2.智能编码SMARTPGOP模式

在SMART的GOP模式下,会分成两种I帧,一种是普通的I另外一种是虚拟I普通的I帧主要是检测画面的静止区域,当检测到视频里面有静止画面的时候,编码器会利用长参考帧大幅度降低码率,静止画面降低码率能够有效防止画面的呼吸效应出现。

而在运动区域,则利用短参考帧进行运动估计,并插入Virtual I(虚拟I帧就是SMARTP)。在插入虚拟I帧的时候,可以最大拉长I帧间隔让它其提高在运动场景下的码率能够得到足够的提高,画面质量能够得到很好的改善;SMARTP模式常使用在静止画面和运动画面经常切换的场景,尤其是体育赛事

3.多层时域参考模型

多层时域指的是编码层可以划分为多个层级,RV1126提供了RK_MPI_MB_GetTsvcLevel获取层数,并通过层数来定制码流。举个例子,TSVC技术可以将一个普通的H264码流分割成不同的帧率、分辨率和视频质量的层数。一般而言,TSVC技术会根据目前的编码的网络情况把视频码流分割成一个基础层和多个视频增强层,基础层为开发者提供最基本的视频质量、帧率和分辨率。基础层可以作为一个独立的层进行解码,而增强层的信息则依赖于基础层进行解码;总体来说,解码端接受的增强层数量越大,解码的视频质量就会越好。TSVC模式主要运用在网络环境不好的情况,如弱网环境、或者移动场景下比较多。

2.RV1126中设置GOP模式的结构体和API

1.RV1126GOP属性结构体

上图就是RV1126设置GOP属性的结构体,下面我们来分别介绍它的成员变量:

1.enGopMode

编码GOP类型的设置,RV1126中分别提供了三种GOP类型的设置,分别是:VENC_GOPMODE_NORMALP(普通GOP模式)VENC_GOPMODE_SMARTP(智能SMARTP模式)VENC_GOPMODE_TSVC(多层时域参考模型)

2. u32GopSize编码GOP的长度大小,在普通的GOP模式下这个值就是I帧关键帧间隔。在SMARTP模式下,它是短期参考帧的间隔

3. s32IPQpDeltaI帧相对于P帧的差值,这个值主要是调节I帧过大或者呼吸效应的场景,默认值为6, 取值范围是[-10, 30]

4. u32BgInterval长期参考帧的间隔, 主要运用在SMARTP模式下, 普通GOP模式不起作用。一般而言,长参考帧是短参考帧的整数倍

5. s32ViQpDelta虚拟I帧相对于P帧的差值,这个值主要是调节虚拟I帧过大默认值为6,这个值主要使用在SMARTP模式下调节运动画面的场景,取值范围是[-10, 30]。

2.RV1126设置GOP属性的API

上面这个就是设置VENC GOP模式的API:

第一个传参数:VeChn编码通道号

第二个传参数:VENC_GOP_ATTR_S结构体指针

3.代码

同时获取SMARTP模式的VENC码流数据和普通GOP模式的VENC码流数据,并进行对比画质。

RV1126 VI采集摄像头数据并同时编码SMARTP模式和普通GOP模式的编码码流流程

RV1126利用多线程同时获取普通GOP的VENC码流数据和SMARTP的码流数据一般如上图,分为8个步骤:分别是VI模块初始化、普通GOP的VENC模块初始化、智能SMARTP_GOP的VENC模块初始化、VI绑定普通GOP的VENC编码器节点、设置GOP属性为SMARTP属性、VI绑定SMARTP_GOP的VENC编码器节点、创建多线程获取普通GOP的VENC码流数据并保存、创建多线程获取SMART_GOP的VENC码流数据并保存。

#include <assert.h> #include <fcntl.h> #include <getopt.h> #include <pthread.h> #include <signal.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <time.h> #include <unistd.h> // #include "common/sample_common.h" #include "include/rkmedia/rkmedia_api.h" #define CAMERA_PATH "rkispp_scale0" #define PIPE_TD 0 #define VI_CHN 0 #define COMMON_GOP_CHN 0 #define SMART_GOP_CHN 1 void *get_common_gop_thread(void*args) { pthread_detach(pthread_self()); FILE* common_gop_file = fopen("test_common_gop.h264","w+"); MEDIA_BUFFER mb; while (1) { mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC,COMMON_GOP_CHN,-1); if(!mb) { printf("COMMON GOP RK_MPI_SYS_GetMediaBuffer Failed\n"); break; } printf("COMMON GOP RK_MPI_SYS_GetMediaBuffer Success\n"); fwrite(RK_MPI_MB_GetPtr(mb),RK_MPI_MB_GetSize(mb),1,common_gop_file); RK_MPI_MB_ReleaseBuffer(mb); } return NULL; } void *get_smart_gop_thread(void*args) { pthread_detach(pthread_self()); FILE* smart_gop_file = fopen("test_smart_gop.h264","w+"); MEDIA_BUFFER mb; while (1) { mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC,SMART_GOP_CHN,-1); if(!mb) { printf("SMART GOP RK_MPI_SYS_GetMediaBuffer Failed\n"); break; } printf("SMART GOP RK_MPI_SYS_GetMediaBuffer Success\n"); fwrite(RK_MPI_MB_GetPtr(mb),RK_MPI_MB_GetSize(mb),1,smart_gop_file); RK_MPI_MB_ReleaseBuffer(mb); } return NULL; } int main() { int ret; RK_MPI_SYS_Init(); VI_CHN_ATTR_S vi_chn_attr; vi_chn_attr.pcVideoNode = CAMERA_PATH; vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12; vi_chn_attr.u32Width = 1920; vi_chn_attr.u32Height = 1080; vi_chn_attr.enBufType = VI_CHN_BUF_TYPE_MMAP; vi_chn_attr.u32BufCnt = 3; vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL; ret = RK_MPI_VI_SetChnAttr(PIPE_TD,VI_CHN,&vi_chn_attr); if(ret) { printf("RK_MPI_VI_SetChnAttr Failed\n"); return 0; } else { printf("RK_MPI_VI_SetChnAttr Success\n"); } ret = RK_MPI_VI_EnableChn(PIPE_TD,VI_CHN); if(ret) { printf("RK_MPI_VI_EnableChn Failed\n"); return 0; } else { printf("RK_MPI_VI_EnableChn Success\n"); } VENC_CHN_ATTR_S commom_venc_chn_attr; commom_venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264; commom_venc_chn_attr.stVencAttr.bByFrame = RK_FALSE; commom_venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12; commom_venc_chn_attr.stVencAttr.enRotation = VENC_ROTATION_0; commom_venc_chn_attr.stVencAttr.u32PicWidth = 1920; commom_venc_chn_attr.stVencAttr.u32PicHeight = 1080; commom_venc_chn_attr.stVencAttr.u32Profile = 66; commom_venc_chn_attr.stVencAttr.u32VirWidth = 1920; commom_venc_chn_attr.stVencAttr.u32VirHeight = 1080; commom_venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR; commom_venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 25; commom_venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1; commom_venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 25; commom_venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1; commom_venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = 8388608; commom_venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 25; ret = RK_MPI_VENC_CreateChn(COMMON_GOP_CHN,&commom_venc_chn_attr); if(ret) { printf("COMMON RK_MPI_VENC_CreateChn Failed\n"); return 0; } else { printf("COMMON RK_MPI_VENC_CreateChn Success\n"); } VENC_CHN_ATTR_S smart_gop_chn_attr; smart_gop_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264; smart_gop_chn_attr.stVencAttr.bByFrame = RK_FALSE; smart_gop_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12; smart_gop_chn_attr.stVencAttr.enRotation = VENC_ROTATION_0; smart_gop_chn_attr.stVencAttr.u32PicWidth = 1920; smart_gop_chn_attr.stVencAttr.u32PicHeight = 1080; smart_gop_chn_attr.stVencAttr.u32Profile = 66; smart_gop_chn_attr.stVencAttr.u32VirWidth = 1920; smart_gop_chn_attr.stVencAttr.u32VirHeight = 1080; smart_gop_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR; smart_gop_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 25; smart_gop_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1; smart_gop_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 25; smart_gop_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1; smart_gop_chn_attr.stRcAttr.stH264Cbr.u32BitRate = 8388608; smart_gop_chn_attr.stRcAttr.stH264Cbr.u32Gop = 25; ret = RK_MPI_VENC_CreateChn(SMART_GOP_CHN,&smart_gop_chn_attr); if(ret) { printf("SMART GOP RK_MPI_VENC_CreateChn Failed\n"); return 0; } else { printf("SMART GOOP RK_MPI_VENC_CreateChn Success\n"); } rkVENC_GOP_ATTR_S smart_gop_attr; smart_gop_attr.enGopMode = VENC_GOPMODE_SMARTP; smart_gop_attr.u32GopSize = 25; smart_gop_attr.u32BgInterval = 25*5; smart_gop_attr.s32IPQpDelta = 6; smart_gop_attr.s32ViQpDelta = 6; RK_MPI_VENC_SetGopMode(SMART_GOP_CHN,&smart_gop_attr); MPP_CHN_S vi_chn_s; vi_chn_s.enModId = RK_ID_VI; vi_chn_s.s32ChnId = VI_CHN; MPP_CHN_S common_gop_chn_s; common_gop_chn_s.enModId = RK_ID_VENC; common_gop_chn_s.s32ChnId = COMMON_GOP_CHN; MPP_CHN_S smart_gop_chn_s; smart_gop_chn_s.enModId = RK_ID_VENC; smart_gop_chn_s.s32ChnId = SMART_GOP_CHN; ret = RK_MPI_SYS_Bind(&vi_chn_s,&common_gop_chn_s); if(ret) { printf("VI BIND COMMON GOP Failed\n"); return 0; } else { printf("VI BIND COMMON GOP Success\n"); } ret = RK_MPI_SYS_Bind(&vi_chn_s,&smart_gop_chn_s); if(ret) { printf("VI BIND SMART GOP Failed\n"); return 0; } else { printf("VI BIND SMART GOP Success\n"); } pthread_t common_pid,smart_pid; pthread_create(&common_pid,NULL,get_common_gop_thread,NULL); pthread_create(&smart_pid,NULL,get_smart_gop_thread,NULL); while(1) { sleep(2); } RK_MPI_SYS_UnBind(&vi_chn_s,&common_gop_chn_s); RK_MPI_SYS_UnBind(&vi_chn_s,&smart_gop_chn_s); RK_MPI_VENC_DestroyChn(COMMON_GOP_CHN); RK_MPI_VENC_DestroyChn(SMART_GOP_CHN); RK_MPI_VI_DisableChn(PIPE_TD,VI_CHN); return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/26 17:01:28

AgentCPM实战案例:如何生成高质量行业研究报告

AgentCPM实战案例&#xff1a;如何生成高质量行业研究报告 在信息爆炸的时代&#xff0c;撰写一份高质量的行业研究报告往往需要耗费大量时间——你需要收集数据、分析趋势、梳理逻辑、组织语言&#xff0c;整个过程既繁琐又考验专业功底。有没有一种工具&#xff0c;能够让你…

作者头像 李华
网站建设 2026/4/1 15:05:53

零基础教程:用软萌拆拆屋轻松制作专业级服装分解图

零基础教程&#xff1a;用软萌拆拆屋轻松制作专业级服装分解图 "让服饰像棉花糖一样展开&#xff0c;变出甜度超标的拆解图&#xff01;" 你是否曾经想过&#xff0c;一件漂亮的衣服如果拆开来看会是什么样子&#xff1f;每个部件如何组合&#xff1f;缝线走向如何&a…

作者头像 李华
网站建设 2026/3/24 22:13:52

编写老年人社交APP,根据老年人兴趣爱好,(下棋,跳舞,唱戏,散步),推荐同城老年人活动,老年大学,支持在线聊天视频通话,还能提醒,老年人吃药,体检,方便老年人生活。

1. 实际应用场景描述场景张大爷今年 68 岁&#xff0c;退休后喜欢下棋、跳舞、唱戏&#xff0c;也常和老朋友散步。他住在城市里&#xff0c;但身边同龄人分散&#xff0c;很难找到志同道合的朋友一起活动。此外&#xff0c;他需要按时吃药、定期体检&#xff0c;有时会忘记。子…

作者头像 李华
网站建设 2026/3/24 17:21:20

Linux Camera驱动开发(常见sensor驱动开发的误区)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】关于摄像头&#xff0c;大家都知道很有用&#xff0c;但是如何开发camera&#xff0c;大家并不是很清楚。或者说&#xff0c;大家都知道sensor开发很…

作者头像 李华
网站建设 2026/3/29 4:47:37

Streamlit+UNet双驱动:cv_unet_image-colorization交互界面开发与部署

StreamlitUNet双驱动&#xff1a;cv_unet_image-colorization交互界面开发与部署 1. 项目概述 你是否曾经翻出家里的老照片&#xff0c;看着那些黑白影像&#xff0c;想象它们如果有了颜色会是什么样子&#xff1f;现在&#xff0c;借助人工智能技术&#xff0c;这个想象可以…

作者头像 李华
网站建设 2026/4/4 23:04:30

AI销冠系统是什么?数字员工如何在数字化转型中提升企业效能?

数字员工在企业中能够有效优化业务流程&#xff0c;降低成本并提升整体效率。通过运用AI销冠系统&#xff0c;数字员工自动化处理大量重复性任务&#xff0c;如外呼客户和处理反馈。这种自动化不仅减轻了人力负担&#xff0c;而且使得企业能在短时间内完成更多工作。此外&#…

作者头像 李华