RV1126画面质量三:QP调节

news2025/1/26 14:32:21

一.什么是 QP 调节?
        QP 参数调节,指的是量化参数调节。它主要是来调节图像的细节,最终达到调节画面质量的作用。QP 值和比特率成反比QP值越小画面质量越高;反之 QP 值越大,画面质量越低。而且随着视频源复杂度,这种反比的关系会更加明显。QP 调节是改变画面质量最常用的手段之一。

        QP调节H264和H265画面最常用的一个手段。

二.QP 调节的基本概念:
        QP 调节一般由 QStep、MinQp、MaxQp 这三个参数进行调节。下面我们来看看,这三个参数的作用。下面这个是QP值和QStep对应的一个关键值。假设我的Qset是1,QP值就是4,在开发的时候,一个是直接调Qset就可以了

        前面说了QP值越小,画面越好,反之画面越差。 因为QP值和QStep对应的一个关键值。所以我们通过调Qset来设置QP值。

2.2. minqp 最小量化步长(调节禁止画面)
        设置最小量化器,限制最好的图像质量(重点在静止画面比如建筑,植物......),当 QP 达到这个值的时候,数值不会变。这就会使得在静止场景下,码率到达一定数量后不会进行调整。minqp 越小,静止时候码率越大,质量越好,建议值[8,20]。简单说就是解决禁止画面的异常,比如呼吸效应。这个值是经验值来的,是经过多调试才能得出一个比较不错的值,8是最好,但是有代价就是码率比较大。20画面质量也还行,但是码效率小。感根据实际情况取舍。如果我填8,这个植物是没有任何呼吸效应和马赛克情况。

        比如下面这写球员站着的球员用minqp 最小量化步长,因为画面相对禁止。

2.3. maxqp 最大量化步长(调节运动画面)

        设置最大量化器,最大 QP 值,限制最差的画面(重点在运动的时候),在运动画面把宏块和马赛克去掉,maxQp 越小,2同样道理,当运动情况下到达一定码率后就不会调整。建议值[20,50],一样要多试。

        比如踢球,因为是运动的,就要调maxqp

        QSet调整体画面,minQp调禁止的画面,maxqp调运动画面。

        QP调节的有一个数据结构体rvVENC_RC_PARAM_S数据结构

         u32ThrdI、u32ThrdP:分别衡量 I 帧、P 帧宏块复杂的一组阈值。这组阈值是从小到大依次排序,每个阈值的取值是[0,255]。这组阈值主要用于宏块级别的码率控制,并根据图像复杂程度对每个宏块进行 QP 调节。这部分大部分也用在 CBR 上面。
u32ThrdI 默认值:[0,0,0,0,3,3,5,5,8,8,8,15,15,20,25,25]
u32ThrdP 默认值:[0,0,0,0,3,3,5,5,8,8,8,15,15,20,25,25]
注意:u32ThrdI、u32ThrdP 在一般情况下不需要设置        

        下面解析一下:

        我们知道每一帧都是一张图片,图片又是是一个一个像素点组成,16X16的像素点,为一个宏快,u32ThrdI、u32ThrdP是对这些宏块调节,可以说是微观调节,但是用处不大,不如整体调节

        u32RowQpDeltaI: 基于行的宏块级别码率控制,每一行的宏块的起始 QP 相对于 I 帧的 QP 波动幅度值,主要用在 CBR 控制模式。对于码率波动比较严格的场景下,可以通过调节这个参数使得码率控制更加精确。在高码率时,该值推荐为 0;中码率时推荐该值为 0 或 1;低码率时推荐 该值为 2~5。

        意思是每一个小宏块的QP 相对于 I 帧的 QP 波动幅度值,宏块的QP  - I 帧的 QP = 码率的幅度


        u32RowQpDeltaP: 基于行的宏块级别码率控制,每一行的宏块的起始 QP 相对于 P 帧的 QP 波动幅度值,主要用在 CBR 控制模式。对于码率波动比较严格的场景下,可以通过调节这个参数使得码率控制更加精确。在高码率时,该值推荐为 0;中码率时推荐该值为 0 或 1;低码率时推荐 该值为 2~5。 

        意思是每一个小宏块的QP 相对于 I 帧的 QP 波动幅度值,宏块的QP  - I 帧的 QP = 码率的幅度

       

        下面的表格就是来解释哪些范围是高码率,中码率,低码率 

        s32FirstFrameStartQp:第一帧 QP 值,默认-1。-1 代表的是第一帧的起始 QP 由编码器内部进行计算。若是其他值,则由用户指定该合法值为第一帧起始 QP。 

在数据结果里面,这三个才是重点,实际开发的时候也是调这个

  1. stParamH264:主要是调节 H264 的 QP 参数
  2. stParamH265:主要是调节 H265 的 QP 参数
  3. stParamMjpeg:主要是调节 Mjpeg 的 QP 参数

stParamH264:主要是调节 H264 的 QP 参数:

  1. u32StepQp: QP 的 STEP 步长,STEP 步长去调节 QP 值,要想画面最好直接填1
  2. u32MaxQp:QP 的最大值调节非I帧的,对运动画面进行限制,若忽视码率则建议 51;若对质量讲究,则建议设置[20,51]。
  3. u32MinQp:QP 的最小值,希望在静止画面的时候节省码率,取值范围[0,48]。VBR 建议设置为[24,32],CBR 建议设置[10,20]
  4. u32MaxIQp: I 帧的 QP 最大值,取值范围[8,51],图像运动的时候节省码率,默认和 u32MaxQP 的值是一致。
  5. u32MinIQp: I 帧的 QP 最小值,取值范围[0,48],图像静止或小运动的时候节省码率,默认和 u32MinIQp 是一致。

u32MaxQp和u32MinQp还是基于I帧P帧B帧直接整体调整,u32RowQpDeltaI和u32RowQpDeltaP:基于宏块调整。宏块调整的效果远远低于整体调整

stParamH265:主要是调节 H265 的 QP 参数:和264差不多

  1. u32StepQp: QP 的 STEP 步长
  2. u32MaxQp:QP 的最大值,对运动画面进行限制,若忽视码率则建议 51;若对质量讲究,则建议设置[40,51]。取值范围[8,51]。
  3. u32MinQp:QP 的最小值,希望在静止画面的时候节省码率,取值范围[0,48]。VBR 建议设置为[24,32],CBR 建议设置[10,20]
  4. u32MaxIQp: I 帧的 QP 最大值,取值范围[8,51],图像运动的时候节省码率,默认和 u32MaxQP 的值是一致。
  5. u32MinIQp: I 帧的 QP 最小值,取值范围[0,48],图像静止或小运动的时候节省码率,默认和 u32MinIQp 是一致。

编码 :

#include <stdio.h>
#include "rkmedia_config.h"

void * collect_venc_thread(void * args)
{
   pthread_detach(pthread_self());
   MEDIA_BUFFER mb;
   FILE * h264_file = fopen("./test_output_smart.h264", "w+");

   while (1)
   {
       mb = RK_MPI_SYS_GetMediaBuffer(RK_ID_VENC, 0 , -1);
       if(!mb)
       {
           printf("Get Venc Buffer Break....\n");
           break;
       }

       printf("mmmmmm\n");
       fwrite(RK_MPI_MB_GetPtr(mb), RK_MPI_MB_GetSize(mb), 1, h264_file);
       RK_MPI_MB_ReleaseBuffer(mb);
   }
   return NULL;
}

int main()
{
    RK_U32 u32Width = 1920;
    RK_U32 u32Height = 1080;
    RK_CHAR *pDeviceName = "rkispp_scale0";
    RK_CHAR *pOutPath = NULL;
    RK_CHAR *pIqfilesPath = NULL;
    CODEC_TYPE_E enCodecType = RK_CODEC_TYPE_H264;
    RK_CHAR *pCodecName = "H264";
    RK_S32 s32CamId = 0;
    RK_U32 u32BufCnt = 3;

    rk_aiq_working_mode_t hdr_mode = RK_AIQ_WORKING_MODE_NORMAL;
    SAMPLE_COMM_ISP_Init(hdr_mode, RK_FALSE);
    SAMPLE_COMM_ISP_Run();
    SAMPLE_COMM_ISP_SetFrameRate(30);

    int ret;
    RK_MPI_SYS_Init();
    VI_CHN_ATTR_S vi_chn_attr;
    vi_chn_attr.pcVideoNode = pDeviceName;
    vi_chn_attr.u32BufCnt = u32BufCnt;
    vi_chn_attr.u32Width = u32Width;
    vi_chn_attr.u32Height = u32Height;
    vi_chn_attr.enPixFmt = IMAGE_TYPE_NV12;
    vi_chn_attr.enBufType = VI_CHN_BUF_TYPE_MMAP;
    vi_chn_attr.enWorkMode = VI_WORK_MODE_NORMAL;
    ret = RK_MPI_VI_SetChnAttr(s32CamId, 1, &vi_chn_attr);
    ret |= RK_MPI_VI_EnableChn(s32CamId, 1);
    if (ret)
    {
        printf("ERROR: create VI[0] error! ret=%d\n", ret);
        return 0;
    }

    VENC_CHN_ATTR_S venc_chn_attr;
    memset(&venc_chn_attr, 0, sizeof(venc_chn_attr));
    venc_chn_attr.stVencAttr.enType = RK_CODEC_TYPE_H264;
    venc_chn_attr.stRcAttr.enRcMode = VENC_RC_MODE_H264CBR;
    venc_chn_attr.stRcAttr.stH264Cbr.u32Gop = 30 * 4;
    venc_chn_attr.stRcAttr.stH264Cbr.u32BitRate = u32Width * u32Height;
    // frame rate: in 30/1, out 30/1.
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateDen = 1;
    venc_chn_attr.stRcAttr.stH264Cbr.fr32DstFrameRateNum = 30;
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateDen = 1;
    venc_chn_attr.stRcAttr.stH264Cbr.u32SrcFrameRateNum = 30;
    venc_chn_attr.stVencAttr.imageType = IMAGE_TYPE_NV12;
    venc_chn_attr.stVencAttr.u32PicWidth = u32Width;
    venc_chn_attr.stVencAttr.u32PicHeight = u32Height;
    venc_chn_attr.stVencAttr.u32VirWidth = u32Width;
    venc_chn_attr.stVencAttr.u32VirHeight = u32Height;
    venc_chn_attr.stVencAttr.u32Profile = 77;
    ret = RK_MPI_VENC_CreateChn(0, &venc_chn_attr);
    if (ret)
    {
        printf("ERROR: create VENC[0] error! ret=%d\n", ret);
        return 0;
    }

    RK_U32 u32StepQp = 1; //因为是一个整形,我们尽量填整型
    RK_U32 u32MaxQp = 24; //这个只能说一个经验值,可能24还会一点点马赛克的情况,只能说多调试
    RK_U32 u32MinQp = 10; //禁止的时候我们把画面质量提高,10是比较高的了
    RK_U32 u32MaxIQp = 24; 
    RK_U32 u32MinIQp = 10;
    VENC_RC_PARAM_S venc_rc_param;

    venc_rc_param.u32RowQpDeltaI = 1; //因为是中码率所以填1
    venc_rc_param.u32RowQpDeltaP = 1; //因为是中码率所以填1
    venc_rc_param.s32FirstFrameStartQp = -1; //默认-1
    //把值设置进去
    venc_rc_param.stParamH264.u32StepQp = u32StepQp;
    venc_rc_param.stParamH264.u32MaxQp = u32MaxQp;
    venc_rc_param.stParamH264.u32MinQp = u32MinQp;
    venc_rc_param.stParamH264.u32MinIQp = u32MinIQp;
    venc_rc_param.stParamH264.u32MaxIQp = u32MaxIQp;
    ret = RK_MPI_VENC_SetRcParam(0, &venc_rc_param);
    if (ret != 0)
    {
        printf("venc_params failed....\n");
    }
    else
    {
        printf("venc_params success....\n");
    }


    MPP_CHN_S stSrcChn;
    stSrcChn.enModId = RK_ID_VI;
    stSrcChn.s32DevId = 0;
    stSrcChn.s32ChnId = 1;
    
    MPP_CHN_S stDestChn;
    stDestChn.enModId = RK_ID_VENC;
    stDestChn.s32DevId = 0;
    stDestChn.s32ChnId = 0;
    ret = RK_MPI_SYS_Bind(&stSrcChn, &stDestChn);
    if (ret)
    {
        printf("ERROR: Bind VI[0] and VENC[0] error! ret=%d\n", ret);
        return 0;
    }

    pthread_t pid;
    ret = pthread_create(&pid, NULL, collect_venc_thread, NULL);
    if(ret != 0)
    {
        printf("Create Venc Thread Failed....\n");
    }

    while (1)
    {
       sleep(20);
    }
    

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2281830.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

渐变颜色怎么调?

渐变颜色的调整是设计中非常重要的一部分,尤其是在创建具有视觉吸引力和深度感的设计作品时。以下是一些在不同设计软件中调整渐变颜色的详细步骤和技巧: 一、Adobe Photoshop 1. 创建渐变 打开渐变工具: 选择工具栏中的“渐变工具”&#x…

Arduino基础入门学习——OLED显示屏的基本使用

Arduino基础入门学习——OLED显示屏的基本使用 一、前言二、准备工作三、基本使用1. OLED显示基本字符 (数字英文基本标点符号)2. OLED显示汉字3. 显示图片 四、 结束语 一、前言 在我们的日常开发中,一般有这么几种方式对数据进行展示&#…

jQuery阶段总结(二维表+思维导图)

引言 经过23天的学习,期间有期末考试,有放假等插曲。本来应该在学校里学习,但是特殊原因,让回家了。但是在家学习的过程,虽然在学,很让我感觉到不一样。但是效果始终还是差点的,本来17、18号左右…

无公网IP 外网访问媒体服务器 Emby

Emby 是一款多媒体服务器软件,用户可以在 Emby 创建自己的个人多媒体娱乐中心,并且可以跨多个设备访问自己的媒体库。它允许用户管理传输自己的媒体内容,比如电影、电视节目、音乐和照片等。 本文将详细的介绍如何利用 Docker 在本地部署 Emb…

PAT甲级-1022 Digital Libiary

题目 题目大意 一个图书有图书id,书名,作者,关键字,出版商,出版时间6个信息。现要查询图书的ID,1对应通过书名查询,2对应作者,3对应关键字(不需要完全一致,包…

OpenCV:在图像中添加高斯噪声、胡椒噪声

目录 在图像中添加高斯噪声 高斯噪声的特性 添加高斯噪声的实现 给图像添加胡椒噪声 实现胡椒噪声的步骤 相关阅读 OpenCV:图像处理中的低通滤波-CSDN博客 OpenCV:高通滤波之索贝尔、沙尔和拉普拉斯-CSDN博客 OpenCV:图像滤波、卷积与…

二叉树的存储(下)c++

链式存储 我们可以创建两个数组L[N]、r[N]&#xff0c;分别存储i 号结点的左右孩子的编号&#xff0c;这样就可以通过数组下标实现链式访问。 本质上还是孩子表示法&#xff0c;存储的是左右孩子的信息 #include <iostream>using namespace std;const int N 1e6 10; …

回归预测 | MATLAB基于TCN-BiGRU时间卷积神经网络结合双向门控循环单元多输入单输出回归预测

效果一览 基本介绍 回归预测 | MATLAB基于TCN-BiGRU时间卷积神经网络结合双向门控循环单元多输入单输出回归预测 一、引言 1.1、研究背景及意义 在当今数据驱动的时代&#xff0c;时间序列预测已成为金融、气象、工业控制等多个领域的关键技术。随着人工智能和机器学习技术的…

如何获取小程序的code在uniapp开发中

如何获取小程序的code在uniapp开发中&#xff0c;也就是本地环境&#xff0c;微信开发者工具中获取code&#xff0c;这里的操作是页面一进入就获取code登录&#xff0c;没有登录页面的交互&#xff0c;所以写在了APP.vue中&#xff0c;也就是小程序一打开就获取用户的code APP.…

BGP边界网关协议(Border Gateway Protocol)路由聚合详解

一、路由聚合 1、意义 在大规模的网络中&#xff0c;BGP路由表十分庞大&#xff0c;给设备造成了很大的负担&#xff0c;同时使发生路由振荡的几率也大大增加&#xff0c;影响网络的稳定性。 路由聚合是将多条路由合并的机制&#xff0c;它通过只向对等体发送聚合后的路由而…

《用DOTS解决实际需求》集锦

去年作者发布了一篇《DOTS-ECS系列课程》&#xff0c;深受同学们的好评&#xff01;前期课程是基于0.51版本录制的&#xff0c;DOTS升级至1.0版本后&#xff0c;同学们纷纷希望能使用DOTS 1.0版本录制实战课程。 今年作者带着DOTS 1.0版本的实战课程回来啦&#xff01;&#x…

pycharm 运行远程环境问题 Error:Failed to prepare environment.

问题排查 拿到更详细的报错信息&#xff1a; Help > Diagnostic Tools > Debug Log Settings section: 添加下面的配置 com.intellij.execution.configurations.GeneralCommandLine 重显报错&#xff0c;我这里是再次运行代码打开 Help | Collect Logs and Diagnosti…

11、性能测试及监控Nginx动静分离配置

1、Jconsole使用 1、win cmd窗口输入jconsole打开工具 选择需要监控的应用程序&#xff0c;点击连接即可进行监控 2、jvisualvm监控工具 1、cmd控制台输入jvisualvm打开工具 运行&#xff1a;正在运行的 休眠&#xff1a;sleep 等待&#xff1a;wait 驻留&#xff1a;线…

流行的开源高性能数据同步工具 - Apache SeaTunnel 整体架构运行原理

概述 背景 数据集成在现代企业的数据治理和决策支持中扮演着至关重要的角色。随着数据源的多样化和数据量的迅速增长&#xff0c;企业需要具备强大的数据集成能力来高效地处理和分析数据。SeaTunnel通过其高度可扩展和灵活的架构&#xff0c;帮助企业快速实现多源数据的采集、…

【Address Overfitting】解决过拟合的三种方法

目录 1. 收集更多数据实践方法&#xff1a;适用场景&#xff1a;优缺点&#xff1a; 2. 特征选择方法介绍&#xff1a;实践示例&#xff1a;适用场景&#xff1a;优缺点&#xff1a; 3. 正则化&#xff08;Regularization&#xff09;正则化类型&#xff1a;实践示例&#xff1…

机器人SLAM建图与自主导航

前言 这篇文章我开始和大家一起探讨机器人SLAM建图与自主导航 &#xff0c;在前面的内容中&#xff0c;我们介绍了差速轮式机器人的概念及应用&#xff0c;谈到了使用Gazebo平台搭建仿真环境的教程&#xff0c;主要是利用gmapping slam算法&#xff0c;生成一张二维的仿真环境…

士的宁(strychnine)的生物合成-文献精读104

Biosynthesis of strychnine 士的宁&#xff08;strychnine&#xff09; 又名 番木鳖碱 的生物合成 摘要 士的宁&#xff08;番木鳖碱&#xff09;是一种天然产物&#xff0c;通过分离、结构阐明和合成努力&#xff0c;塑造了有机化学领域。目前&#xff0c;士的宁因其强大的…

Moretl FileSync增量文件采集工具

永久免费: <下载> <使用说明> 我们希望Moretl FileSync是一款通用性很好的文件日志采集工具,解决工厂环境下,通过共享目录采集文件,SMB协议存在的安全性,兼容性的问题. 同时,我们发现工厂设备日志一般为增量,为方便MES,QMS等后端系统直接使用数据,我们推出了增量采…

设计模式的艺术-中介者模式

行为型模式的名称、定义、学习难度和使用频率如下表所示&#xff1a; 1.如何理解中介者模式 如果在一个系统中对象之间存在多对多的相互关系&#xff0c;可以将对象之间的一些交互行为从各个对象中分离出来&#xff0c;并集中封装在一个中介者对象中&#xff0c;由该中介者进行…

win32汇编环境,函数的编写与调用、传值或返回值等

;运行效果 ;win32汇编环境,函数的编写与调用、传值或返回值等 ;函数在被调用的时候&#xff0c;如果此函数实体在前面&#xff0c;可以不用声明。如果实体在后面&#xff0c;则需要先声明。类似于下面的DlgProc函数&#xff0c;因为它的实体在后面&#xff0c;所以需要在调用之…