openh264 编码器源码分析:AnalyzePictureComplexity 函数

介绍

  1. 文件位置:
    • openh264/codec/processing/src/complexityanalysis/ComplexityAnalysis.cpp
  2. 功能:
    • 作为CWelsPreProcess类中一个方法,用来分析当前图像与参考图像之间的复杂度关系,以便编码策略。
  3. 原型:
void CWelsPreProcess::AnalyzePictureComplexity (sWelsEncCtx* pCtx, SPicture* pCurPicture, SPicture* pRefPicture,
    const int32_t kiDependencyId, const bool bCalculateBGD)
  1. 参数:
    • sWelsEncCtx* pCtx:指向sWelsEncCtx结构的指针,这通常是一个上下文结构,包含了编码过程中所需的状态信息。
    • SPicture* pCurPicture:指向当前待编码图片的指针。
    • SPicture* pRefPicture:指向参考图片的指针,用于与当前图片进行比较。
    • const int32_t kiDependencyId:一个整数常量,表示依赖层的ID,可能用于确定当前图片所属的编码层。
    • const bool bCalculateBGD:一个布尔值常量,指示是否需要计算背景差分(Background Difference)。

函数关系图

在这里插入图片描述

原理

桌面图像

  1. process 函数
  • 如果是IDR帧或参考图像为空,则调用GomComplexityAnalysisIntra函数执行内部复杂度分析;
  • 如果滚动标志为假或滚动偏移量在X和Y方向上都为0,则调用GomComplexityAnalysisInter函数执行无滚动的交互复杂度分析;
  • 调用GomComplexityAnalysisInter函数执行有滚动的交互复杂度分析;
  1. GomComplexityAnalysisIntra函数
  • 变量初始化;
  • 嵌套循环分析每个宏块;
    - 检查是否有可用的垂直或水平参考宏块,如果有,则使用相应的预测函数m_pIntraFunc和SAD计算函数m_pSadFunc来计算SAD值iBlockSadH、iBlockSadV;
    • 如果垂直或水平参考宏块存在,则累加中iBlockSadH、iBlockSadV的最小值到iGomSad中;
      • 如果当前宏块是一行中的最后一个宏块,或者已经到达了宏块组的底部,将iGomSad的值存储到类成员变量m_ComplexityAnalysisParam.pGomComplexity中,并更新帧复杂度m_ComplexityAnalysisParam.iFrameComplexity;
      • 更新索引iIdx,将变量iGomSad置 0,为下一个宏块组的复杂度值做准备;
      • 在处理完一行的所有宏块后,更新指针pPtrY到下一行的开始位置;
  • 更新类成员变量m_ComplexityAnalysisParam.iGomNumInFrame,表示帧中宏块组的数量;
  1. GomComplexityAnalysisInter函数
  • 变量初始化;
  • 嵌套 for 循环分析每个宏块;
    • 首先调用m_pSadFunc函数计算当前块的SAD值iInterSad;
    • 如果bScrollFlag为真,并且当前块的SAD值不为0,且滚动偏移量在有效范围内,则调用m_pSadFunc函数计算考虑滚动后的SAD值iScrollSad,并取两者的较小值作为当前块的SAD值iInterSad;
    • 如果当前宏块不是第一行或第一列的宏块,使用类成员预测函数m_pIntraFuncm_pSadFunc计算水平和垂直预测的SAD值iBlockSadH、iBlockSadV;
    • 选择iBlockSadH、iBlockSadV、iInterSad中最小值最为总体 SAD 值iGomSad;
    • 果当前宏块是一行中的最后一个宏块,或者已经到达了宏块组的底部,将iGomSad的值存储到类成员变量m_ComplexityAnalysisParam.pGomComplexity中,并更新帧复杂度m_ComplexityAnalysisParam.iFrameComplexity;
    • 更新索引iIdx,将变量iGomSad置 0,为下一个宏块组的复杂度值做准备;
    • 在处理完一行的所有宏块后,更新指针pPtrY到下一行的开始位置;
  • 更新类成员变量m_ComplexityAnalysisParam.iGomNumInFrame,表示帧中宏块组的数量;
  1. m_pSadFunc函数
  • 指向WelsSampleSad16x16_c函数
  1. m_pIntraFunc[0]函数
  • 指向WelsI16x16LumaPredV_c函数
  1. m_pIntraFunc[1]函数
  • 指向WelsI16x16LumaPredH_c函数

摄像镜头图像

  1. process 函数
  • iComplexityAnalysisMode等于FRAME_SAD时,调用AnalyzeFrameComplexityViaSad函数分析图像复杂度;
  • iComplexityAnalysisMode等于GOM_SAD时,调用AnalyzeGomComplexityViaSad函数分析图像复杂度;
  • iComplexityAnalysisMode等于GOM_VAR时,调用AnalyzeGomComplexityViaVar函数分析图像复杂度;
  1. AnalyzeFrameComplexityViaSad函数
  • 将pCalcResult赋值给pVaaCalcResults;
  • 将pVaaCalcResults中的iFrameSad赋值给m_sComplexityAnalysisParam.iFrameComplexity,作为当前帧的复杂度;
  • 如果iCalcBgd,即有背景检测,则调用GetFrameSadExcludeBackground函数计算复杂度,赋值给m_sComplexityAnalysisParam.iFrameComplexity,作为当前帧的复杂度;
  • GetFrameSadExcludeBackground函数:这个函数的目的是计算帧的SAD值,但在计算时排除了背景区域的宏块,这有助于更准确地评估帧中实际的前景复杂度。
    • 初始化变量,计算宏块组iMbNumInGom和宏块数iGomMbNum;
    • m_sComplexityAnalysisParam.pCalcResult赋值给pVaaCalcResults;
    • 双层嵌套 for 循环遍历所有宏块,
      • 如果宏块不是背景宏块,增加对应宏块组的前景宏块数量,并累加该宏块的四个8x8块的SAD值到uiFrameSad;
    • 返回 uiFrameSad值;
  1. AnalyzeGomComplexityViaSad函数
  • 初始化变量,计算宏块组iMbNumInGom和宏块数iGomMbNum;
  • 调用InitGomSadFunc函数初始化SAD计算函数(m_pfGomSad),并为每个GOB分配一个SAD变量(uiGomSad)
  • 嵌套双层循环处理每个宏块,
    • 对当前GOB的每一行进行循环,计算SAD;
    • 调用m_pfGomSad函数来累加当前宏块的SAD值uiGomSad;
    • 将计算得到的SAD值uiGomSad存储到pGomComplexity数组中;
    • 更新整个帧的SAD值(uiFrameSad);
  • 将帧的SAD值uiFrameSad存储在m_sComplexityAnalysisParam结构体中。
  1. AnalyzeGomComplexityViaVar函数
  • 初始化变量,计算宏块组iMbNumInGom和宏块数iGomMbNum;
  • 初始化样本和平方和变量(uiSampleSum和uiSquareSum);
  • 双层嵌套循环遍历每一个宏块;
    • 对当前GOB的每一行进行循环,累加样本和uiSampleSum和平方和uiSquareSum;
    • 计算宏块组方差,将结果存到pGomComplexity中;
    • 累加pGomComplexity到帧的 SAD 值uiFrameSad;
  • 将帧的SAD值uiFrameSad存储在m_sComplexityAnalysisParam结构体中。

源码

  • 略。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

01背包问题(模板)

一、题目描述 描述 你有一个背包,最多能容纳的体积是V。 现在有n个物品,第i个物品的体积为vi,价值为wi。 (1)求这个背包至多能装多大价值的物品? (2)若背包恰好装满,求至多能装多大价…

XMind软件下载-详细安装教程视频

​简介 XMind是一款实用的思维导图软件,简单易用、美观、功能强大,拥有高效的可视化思维模式,具备可扩展、跨平台、稳定性和性能,真正帮助用户提高生产率,促进有效沟通及协作。中文官方网站:http://www.x…

Oracle最终会扼杀MySQL?(译)

原文网站:https://www.percona.com/blog/is-oracle-finally-killing-mysql/ 作者:Peter Zaitsev 自从Oracle收购了MySQL后,很多人怀疑Oracle对开源MySQL的善意,这篇percona的文章深入分析了Oracle已经和将要对MySQL采取的措施&a…

【C++】——继承(详解)

一 继承的定义和概念 1.1 继承的定义 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保 持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类,被继承的称为基类…

【多元统计】期末复习必备!按题型分类

一,简答题 二,证明题 三,计算题

推荐一款WPF绘图插件OxyPlot

开始 使用 NuGet 包管理器添加对 OxyPlot 的引用(如果要使用预发布包,请参阅下面的详细信息)向用户界面添加PlotView在代码中创建一个PlotModel绑定到你的属性PlotModelModelPlotView 例子 您可以在代码存储库的文件夹中找到示例。/Source/Ex…

9 - 上升的温度(高频 SQL 50 题基础版)

9 - 上升的温度 -- 找出与之前(昨天的)日期相比温度更高的所有日期的 id -- DATEDIFF(2007-12-31,2007-12-30); # 1 -- DATEDIFF(2010-12-30,2010-12-31); # -1select w1.id from Weather w1, Weather w2 wheredatediff(w1.recordDate,w2.recordDat…

【MySQL】表的基本增删查改(结合案例)

文章目录 1.前言2.插入数据(Create)2.1案例2.2单行数据全列插入2.3多行数据指定列插入2.4插入否则更新2.5替换 3. 读取数据(Retireve)3.1案例3.2全列查询3.3指定列查询3.4查询字段为表达式3.5为查询结果起别名3.6去重3.7where条件3.7.1案例 3.8排序3.9筛…

初识 AQS

一、什么是 AQS AQS是一个用来构建锁和同步器的框架。JUC 的同步器底层都是用了 AQS,例如ReentrantLock,Semaphore,CountDownLatch,CyclicBarrier,ReentrantReadWriteLock。 二、前置知识 在了解 AQS之前&#xff0c…

C++ 01 之 hello world

c01helloworld.cpp #include <iostream>using namespace std;int main() {cout << "hello world" << endl;return 0; } #include<iostream>; 预编译指令&#xff0c;引入头文件iostream.using namespace std; 使用标准命名空间cout <&l…

LW-DETR:实时目标检测的Transformer, Apache-2.0 开源可商用,论文实验超 YOLOv8

LW-DETR&#xff1a;实时目标检测的Transformer&#xff0c; Apache-2.0 开源可商用&#xff0c;论文实验超 YOLOv8 LW-DETR 架构实例化高效训练高效推理 目的与解法拆解ViT编码器和DETR解码器多级特征图聚合变形交叉注意力窗口注意力和全局注意力 论文&#xff1a;https://arx…

1124. 表现良好的最长时间段 (python) 前缀和 分类讨论 最大长度 力扣 面试题

给你一份工作时间表 hours&#xff0c;上面记录着某一位员工每天的工作小时数。 我们认为当员工一天中的工作小时数大于 8 小时的时候&#xff0c;那么这一天就是「劳累的一天」。 所谓「表现良好的时间段」&#xff0c;意味在这段时间内&#xff0c;「劳累的天数」是严格 大…

什么是 URL 过滤?是如何保障浏览体验的?

互联网是一个无边无际的空间&#xff0c;几乎包含了你能想象到的一切。不幸的是&#xff0c;这意味着也存在着从不合适到非常危险的网站。这就是 URL 过滤可以发挥作用的地方。 一、URL 过滤的含义 我们希望您已经熟悉 URL&#xff08;统一资源定位器&#xff09;&#xff0c;…

在韩国遇到阿姨叫“아줌마”还是“이모”?都不如称呼好!柯桥学韩语来银泰附近基础教学通俗易懂

认识母音 母音&#xff0c;又叫元音&#xff0c;共21个&#xff0c;包含10个基本母音和11复合母音&#xff08;又称双元音&#xff09;。 10个基本母音&#xff1a;ㅏ(a)、ㅑ(ya)、ㅓ(eo)、ㅕ(yeo)、ㅗ(o)、ㅛ(yo)、ㅜ(u)、ㅠ(yu)、ㅡ(eu)、ㅣ(i) 11个复合母音&#xff1a;ㅐ(a…

【ETAS CP AUTOSAR基础软件】BswM模块详解

文章包含了AUTOSAR基础软件&#xff08;BSW&#xff09;中BswM模块相关的内容详解。本文从AUTOSAR规范解析&#xff0c;ISOLAR-AB配置以及模块相关代码分析三个维度来帮读者清晰的认识和了解BswM这一基础软件模块。文中涉及的SOLAR-AB配置以及模块相关代码都是依托于ETAS提供的…

pdf添加书签的软件,分享3个实用的软件!

在数字化阅读日益盛行的今天&#xff0c;PDF文件已成为我们工作、学习和生活中不可或缺的一部分。然而&#xff0c;面对海量的PDF文件&#xff0c;如何高效地进行管理和阅读&#xff0c;成为了许多人关注的焦点。其中&#xff0c;添加书签功能作为提高PDF文件阅读体验的重要工具…

数据结构01 栈及其相关应用

栈是一种线性数据结构&#xff0c;栈的特征是数据的插入和删除只能通过一端来实现&#xff0c;这一端称为“栈顶”&#xff0c;相应的另一端称为“栈底”。 栈及其特点 用一个简单的例子来说&#xff0c;栈就像一个放乒乓球的圆筒&#xff0c;底部是封住的&#xff0c;如果你想…

c++线性关系求值

目的 线性关系是最简单的关系,但也是编程当中最常用的一种关系,很多行业,都用。 可以说,其是准确的,有时利用了正比例的关系,其具有预测性,检验其它数据是否正确,应用实在太多了。 生活中太多的东西可以认为成线性的,比如:年龄越大,经验越丰富,这也是线性关系,因…

揭秘湖北工程类助理工程师证书:纸质版 vs 电子版,哪个更靠谱

"揭秘湖北工程类助理工程师证书&#xff1a;纸质版 vs 电子版&#xff0c;哪个更靠谱&#xff1f;" 2024年湖北工程类助理工程师证书纸质版VS电子版 很多人会疑惑不是从2021年底就发布相关文件&#xff0c;湖北初级、中级、高级职称进入电子版证书时代&#xff0c;为…

分组聚集查询-GROUP BY子句

一、GROUP BY子句位置 SELECT 【ALL|DISTINCT】<目标列表达式1>【,<目标列表达式2>,...】 FROM <表名或视图名1>【&#xff0c;<表名或视图名2>&#xff0c;...】 【WHERE <元组选择条件表达式>】 【GROUP BY <属性列名1>【&#xff0…