openh264 帧内预测编码过程源码分析

news2025/1/10 4:18:07

函数关系

在这里插入图片描述

  1. 说明:
    可以看到完成帧内预测编码的核心函数就是 WelsMdI16x16WelsMdI4x4WelsMdI4x4Fast WelsMdIntraChroma 四个函数。

原理

WelsMdI16x16函数

  1. 功能:针对16x16像素块的帧内模式决策
  2. 过程
  • 局部变量申明;
  • 根据宏块的领域宏块情况计算得出iOffset;
  • iAvailCount 和 kpAvailMode 用于获取当前宏块可用的帧内预测模式数量和预测模式列表;
  • 如果iAvailCount大于 3,且提供 pfIntra16x16Combined3函数;
    • 则调用pfIntra16x16Combined3函数来获取最佳模式iBestMode和成本iBestCost;
    • 从kpAvailMode[3]中确定当前模式iCurMode,表明考虑 第四种模式;
    • 调用pfGetLumaI16x16Pred函数,根据当前模式编号 iCurMode 生成预测块,并将结果存储在 pDst 中;
    • pfMdCost[BLOCK_16x16] 函数计算当前预测块 pDst 和编码图像 pEnc 之间的成本iCurCost;
    • iCurCost小于iBestCost,
      • 将iCurMode和iCurCost确定最佳模式iBestMode和成本iBestCost;
    • 否则,
      • 则调用pfGetLumaI16x16Pred函数使用最佳模式iBestMode重新生成预测块,并存储在 pDst 中;
    • iIdx 被设置为1,最佳成本 iBestCost 被加上量化参数 iLambda,作为总开销;
  • 否则
    • iBestMode 被初始化为第一个可用模式,即 kpAvailMode[0];
    • for 循环遍历所有可用的模式iAvailCount;
      • 在每次循环迭代中,iCurMode 被设置为当前考虑的模式编号iCurMode;
      • 调用 pfGetLumaI16x16Pred[iCurMode] 函数,根据当前模式编号 iCurMode 生成预测块;
      • 使用 pfMdCost[BLOCK_16x16] 函数计算当前预测块 pDst 和编码图像 pEnc 之间的成本iCurCost;
      • iCurCost 加上量化参数 iLambda 与当前模式编号的编码长度(使用 BsSizeUE 函数和 g_kiMapModeI16x16 数组计算)的乘积;
      • 如果 iCurCost小于 iBestCost;
        • 更新iBestMode、iBestCost、iIdx、pDst;iIdx 通过异或操作 ^ 0x01 来切换,这在每次找到更好的模式时都会发生;
        • iIdx用来指向预测块pPredI16x16;
    • 更新缓存SMbCache中pMemPredChroma、pMemPredLuma、uiLumaI16x16Mode;
    • 返回 最佳代价iBestCost。
  1. 原理图
    在这里插入图片描述
  2. 说明
  • pfGetLumaI16x16Pred函数指针根据不同的模式指向不同的函数,具体在WelsInitIntraPredFuncs函数中定义。
  • pfMdCost函数指针根据 fastmode 模式指向pfSampleSadpfSampleSatd函数指针,而且根据不同预测模式指向不同的函数实现,具体在WelsInitSampleSadFunc函数中定义。
  1. 源码:
int32_t WelsMdI16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SMbCache* pMbCache, int32_t iLambda) {
  const int8_t*  kpAvailMode;
  int32_t iAvailCount;
  int32_t iIdx = 0;
  uint8_t* pPredI16x16[2] = {pMbCache->pMemPredMb, pMbCache->pMemPredMb + 256};
  uint8_t* pDst       = pPredI16x16[0];
  uint8_t* pDec       = pMbCache->SPicData.pCsMb[0];
  uint8_t* pEnc       = pMbCache->SPicData.pEncMb[0];
  int32_t iLineSizeDec = pCurDqLayer->iCsStride[0];
  int32_t iLineSizeEnc = pCurDqLayer->iEncStride[0];
  int32_t i, iCurCost, iCurMode, iBestMode, iBestCost = INT_MAX;

  int32_t iOffset = pMbCache->uiNeighborIntra & 0x07;
  iAvailCount = g_kiIntra16AvaliMode[iOffset][4];
  kpAvailMode = g_kiIntra16AvaliMode[iOffset];
  if (iAvailCount > 3 && pFunc->sSampleDealingFuncs.pfIntra16x16Combined3) {
    iBestCost = pFunc->sSampleDealingFuncs.pfIntra16x16Combined3 (pDec, iLineSizeDec, pEnc, iLineSizeEnc, &iBestMode,
                iLambda, pDst/*temp*/);
    iCurMode = kpAvailMode[3];
    pFunc->pfGetLumaI16x16Pred[iCurMode] (pDst, pDec, iLineSizeDec);
    iCurCost = pFunc->sSampleDealingFuncs.pfMdCost[BLOCK_16x16] (pDst, 16, pEnc, iLineSizeEnc) + iLambda * 4 ;
    if (iCurCost < iBestCost) {
      iBestMode = iCurMode;
      iBestCost = iCurCost;
    } else {
      pFunc->pfGetLumaI16x16Pred[iBestMode] (pDst, pDec, iLineSizeDec);
    }
    iIdx = 1;
    iBestCost += iLambda;
  } else {
    iBestMode = kpAvailMode[0];
    for (i = 0; i < iAvailCount; ++ i) {
      iCurMode = kpAvailMode[i];

      assert (iCurMode >= 0 && iCurMode < 7);

      pFunc->pfGetLumaI16x16Pred[iCurMode] (pDst, pDec, iLineSizeDec);
      iCurCost = pFunc->sSampleDealingFuncs.pfMdCost[BLOCK_16x16] (pDst, 16, pEnc, iLineSizeEnc);
      iCurCost += iLambda * (BsSizeUE (g_kiMapModeI16x16[iCurMode]));
      if (iCurCost < iBestCost) {
        iBestMode = iCurMode;
        iBestCost = iCurCost;
        iIdx = iIdx ^ 0x01;
        pDst = pPredI16x16[iIdx];
      }
    }
  }
  pMbCache->pMemPredChroma = pPredI16x16[iIdx];

  pMbCache->pMemPredLuma = pPredI16x16[iIdx ^ 0x01];
  pMbCache->uiLumaI16x16Mode  = iBestMode;
  return iBestCost;
}

WelsMdI4x4函数

  1. 功能:针对4x4像素块的帧内模式决策
  2. 过程:类似 I16x16,只不过预测模式更多,有 16 种模式;
  3. 源码:略

WelsMdI4x4Fast函数

  1. 功能:针对4x4像素块的帧内模式决策的快速实现逻辑
  2. 过程:类似 I16x16,只不过预测模式更多,有 16 中模式,但采用了快速算法;
  3. 源码:略

WelsMdIntraChroma函数

  1. 功能:针对色度像素块的帧内模式决策
  2. 过程:类似 I16x16决策过程,色度的预测模式跟 I16x16 块一样,有 7 种模式;
  3. 源码:略

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

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

相关文章

python如何终止程序运行

方法1&#xff1a;采用sys.exit(0)&#xff0c;正常终止程序&#xff0c;从图中可以看到&#xff0c;程序终止后shell运行不受影响。 方法2&#xff1a;采用os._exit(0)关闭整个shell&#xff0c;从图中看到&#xff0c;调用sys._exit(0)后整个shell都重启了&#xff08;RESTAR…

卡塔尔.巴林:海外媒体投放-宣发.发稿效果显著提高

引言 卡塔尔和巴林两国积极采取措施&#xff0c;通过海外媒体投放和宣发&#xff0c;将本国的商业新闻和相关信息传达给更广泛的受众。在这一过程中&#xff0c;卡塔尔新闻网、巴林商业新闻和摩纳哥新闻网等媒体起到了关键作用。通过投放新闻稿&#xff0c;这些国际化的媒体平…

UITableView之显示单组数据Demo

需求 UITableView实现显示单组数据。尝试设置不同行高度不同。 效果&#xff1a; 数据展示 实现 与之前分组显示数据的区别在于懒加载的数据模型不同。 &#xff08;1&#xff09;声明数据模型类 类的属性一定要和plist中数据的字段保持一致 interface CZhero : NSObject /…

idea在空工程中添加新模块并测试的步骤

ServicesTest是空的工程&#xff0c;没有pom文件。现在需要在ServicesTest目录下添加新模块作为新的工程&#xff0c;目的是写一下别的技术功能。 原先目录结构&#xff0c;ServicesTest是空的工程&#xff0c;没有pom文件。下面的几个模块是新的工程&#xff0c;相互独立。 1.…

数栈xAI:轻量化、专业化、模块化,四大功能革新 SQL 开发体验

在这个数据如潮的时代&#xff0c;SQL 已远远超越了简单的查询语言范畴&#xff0c;它已成为数据分析和决策制定的基石&#xff0c;成为撬动企业智慧决策的关键杠杆。SQL 的编写和执行效率直接关系到数据处理的速度和分析结果的深度&#xff0c;对企业洞察市场动态、优化业务流…

谁说Python GUI难?用pywebview打造现代化GUI界面

在Python的世界里&#xff0c;我们经常需要为程序添加一个图形用户界面&#xff08;GUI&#xff09;。传统上&#xff0c;Tkinter、PyQt或Kivy等库是常用的选择。但是&#xff0c;今天我们要介绍的是一个更简单、更现代的方法——pywebview。它让你可以使用HTML、CSS和JavaScri…

OpenCV查找图像中的轮廓并且展示

1、查找轮廓随机用不同的颜色画出 import cv2 import numpy as npdef get_contour_colors(num_contours):# 定义颜色表 (BGR 格式)colors [(255, 0, 0),(255, 50, 0),(255, 100, 0),(255, 150, 0),(255, 200, 0),(255, 255, 0),(200, 255, 0),(150, 255, 0),(100, 255, 0),(5…

2.6数据报与虚电路

数据报 当作为通信子网用户的端系统要发送一个报文时&#xff0c;在端系统中实现的高层协议先把报文拆成若干个带有序号的数据单元&#xff0c;并在网络层加上地址等控制信息后形成数据报分组(即网络层PDU)中间结点存储分组一段很短的时间&#xff0c;找到最佳的路由后&#x…

【StructueEngineering】Wind Load Combination Patterns风荷载组合模式

文章目录 Combination PatternsBasic Rules of Combinations组合的基本规律Specific Combination Patterns1. First 8 Combinations (1 to 8)2. Middle 8 Combinations (9 to 16)3. Last 8 Combinations (17 to 24) Summary of CombinationsKey Variables and Parameters with …

Base64编码方式的介绍及其编码解码

一、Base64是什么 Base64是一种用于将二进制数据编码为ASCII字符的编码方式&#xff0c;主要目的是为了能够在文本环境中传输和存储二进制数据。这种编码方式广泛应用于电子邮件、HTTP协议和其他需要传输或存储二进制数据的地方。 二、发明Base64编码的原因 Base64编码的发明解…

《转载》前苏联的三进制计算机Setun

1、苏联的三进制计算机概述 早在 1956 年&#xff0c;就需要创建一种可在大学和实验室中使用的实用数字计算机模型。为此&#xff0c;需要一种易于学习、可靠、廉价但同时高效、专为大规模使用而设计的小型计算机。 对这种机器的要求&#xff1a;运行速度必须等于每秒数百次操作…

破解发展难题 台山这家合作社以农业社会化服务助推乡村振兴

风吹稻田千层浪&#xff0c;眼下&#xff0c;台山四九镇的早稻长势喜人&#xff0c;沉甸甸的稻穗迎风而动&#xff0c;已进入破口抽穗的关键期&#xff0c;即将在6月底陆续迎来丰收。在台山市明华汇种养专业合作社管理的稻田里&#xff0c;合作社负责人梁明喜正仔细观察着稻苗的…

(代数:解一元二次方程)可以使用下面的公式求一元二次方程 ax2+bx+c0 的两个根:

(代数:解一元二次方程)可以使用下面的公式求一元二次方程 ax2bxc0 的两个根: b2-4ac 称作一元二次方程的判别式。如果它是正值,那么一元二次方程就有两个实数根。 如果它为 0&#xff0c;方程式就只有一个根。如果它是负值&#xff0c;方程式无实根。 编写程序&#xff0c;提示…

单点登录分析介绍

文章目录 1、单点登录解决方案1.1、后端保存登录状态1.2、token模式 2、user服务-登录接口2.1、UserController2.2、UserInfoServiceImpl2.3、载荷2.4、响应2.5、Redis Desktop Manager 1、单点登录解决方案 多个系统只有一个登录服务 1.1、后端保存登录状态 1.2、token模式 …

WordPress、Typecho 站点如何让 CloudFlare 缓存加速

众所周知 WordPress、Typecho 都是著名动态博客站点(一个最简单的判断依据就是都要依赖结合数据库),这类站点在 CDN 缓存上都有一个致命的缓存弊端就是动静态请求的区分,理论上要让 CDN 绕过所有的动态请求,缓存所有的静态请求,否则就会造成前端登录和非登录状态的混乱,…

聊聊分布式集群的基本概念

在当前主流的分布式架构中&#xff0c;各种各样的集群技术几乎成了任何想要提升系统稳定性和处理能力的团队的必备技能。虽然各种中间件和系统都有让人看似眼花缭乱的集群实现方案&#xff0c;但其背后仍然逃不过一些核心的技术概念&#xff0c;我会结合几个我比较熟悉的中间件…

java.nio.charset.UnmappableCharacterException

问题 java.lang.IllegalArgumentException: java.nio.charset.UnmappableCharacterException: Input length 1 解释为编码转换有问题 问题错在位置 非汉字存在 打包的时候就会报异常

怎么把wma格式转化为mp3格式?四种wma格式转成MP3格式的方法

怎么把wma格式转化为mp3格式&#xff1f;转换WMA格式音频文件为MP3格式是一个常见的需求&#xff0c;尤其是在我们希望在不同设备或平台上播放音频时。WMA格式虽然在Windows系统中较为常见&#xff0c;但在其他平台上的兼容性可能不如MP3格式。因此&#xff0c;将WMA转换为MP3是…

c#引用dll报错cs8370功能“本地函数特性“在c#7.3中不可用

cs8370:功能"本地函数特性"在c#7.3中不可用 解决方法&#xff1a; 代码放在form类里面

YOLOv5改进 | Head | 将yolov5的检测头替换为ASFF_Detect

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 在目标检测中&#xff0c;为了解决尺度变化的问题&#xff0c;通常采用金字塔特征表示。然而&#xff0c;对于基于特征金字塔的单次检测器来…