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

函数关系

在这里插入图片描述

  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. 源码:略

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

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

相关文章

三星公布尖端芯片进展 | 百能云芯

三星电子在本周三举办的年度晶圆制造盛会上&#xff0c;揭开了未来多项技术革新的神秘面纱&#xff0c;并宣布其晶圆制造业务将整合全球领先的记忆芯片、晶圆制造及封装服务&#xff0c;为AI芯片客户提供一站式服务&#xff0c;以加速其生产进程。 三星强调&#xff0c;客户仅需…

万元补贴助力开源项目!「GitCode 开源摘星计划」已开启

当我们谈到开源项目运作的痛点&#xff0c;都在谈什么&#xff1f;找不到对项目感兴趣的开发者&#xff0c;始终是几个人维护…代码托管平台上开源项目众多&#xff0c;得不到有力的流量支持&#xff0c;项目被淹没在茫茫列表里…社区运营要专人来做&#xff0c;成本太高… 这…

【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 …

vue/react/js 常用的原生获取当前页面的url网址的相关方法

目录 第一章 场景 第二章 总结 第一章 场景 最近实现需求时遇到这么一种情况&#xff1a; 本地url —— 线上url —— 需求&#xff1a;需要将token清除掉 注意事项&#xff1a;token不是#/后面的参数&#xff0c;说明并不是我们前端返回的&#xff0c;vue路由的方法使用不…

python的a[:2]、a[:] 和a [::] 的区别

一、a[:2] 数据准备 import numpy as np X np.array([[0,1],[2,3],[4,5],[6,7],[8,9],[10,11],[12,13],[14,15],[16,17],[18,19]]) print(X)形成矩阵 print (“X[: 2]:”, X[: 2]) ### :表示索引 0至1行&#xff1b; 二、a[:]和a [::] 在 Python 中&#xff0c;[:] 和 [::…

Vue30-自定义指令:对象式

一、需求&#xff1a;创建fbind指定 要用js代码实现自动获取焦点的功能&#xff01; 二、实现 2-1、步骤一&#xff1a;绑定元素 2-2、步骤二&#xff1a;input元素获取焦点 此时&#xff0c;页面初始化的时候&#xff0c;input元素并没有获取焦点&#xff0c;点击按钮&…

CobaltStrike权限传递MSF

一、测试环境 操作系统&#xff1a; 1.VMware17 2.kali 6.1.0-kali5-amd64 3.Win10x64 软件&#xff1a; 1.cs4.0 2.metasploit v6.3.4-dev 二、测试思路 1.cs是一款渗透测试工具&#xff0c;但没有漏洞利用的模块&#xff0c;我们可以在拿到目标主机的权限后&#xff0c;将…

mtk低压充电关机充电关机动画显示

lk下充电&#xff1a; 在启动时读取电压小于BATTERY_LOWVOL_THRESOLD便会到lk循环充电&#xff0c;这里的BATTERY_LOWVOL_THRESOLD是3.45v 1、mtk_battery.c&#xff1a; 通过fg计算电池充电电流&#xff0c;电池温度等2、mtk_charger_intf.c&#xff1a; 在mtk_charger_init…

React 中的 Lanes

React 中有一个 Lane 的概念&#xff0c;Lane 就像高速路上的不同车道&#xff0c;具有不同优先级&#xff0c;在 React Lane 通过一个 32 位的二进制数来表示。越小优先级别越高&#xff0c;SyncLane 级别最高。用二进制存储的方式&#xff0c;可以通过逻辑操作快速判断 Lane …

App UI 风格展现非凡创意

App UI 风格展现非凡创意

Sqoop学习详细介绍!!

一、Sqoop介绍 Sqoop是一款开源的工具&#xff0c;主要用于在Hadoop(HDFS/Hive/HBase)与传统的数据库(mysql、postgresql...)间进行数据的传递&#xff0c;可以将一个关系型数据库&#xff08;例如 &#xff1a; MySQL ,Oracle ,Postgres等&#xff09;中的数据导进到Hadoop的H…

160. 相交链表 (Swift版本)

题目描述 最简单直接的解法 遍历 headA 的所有节点, 看 headB 中是否有相交的节点 /*** Definition for singly-linked list.* public class ListNode {* public var val: Int* public var next: ListNode?* public init(_ val: Int) {* self.val val*…

vs2019 c++20规范 STL 库中头文件 <atomic> 源码注释及探讨几个知识点

&#xff08;1 探讨一&#xff09; 模板类 atomic 的继承关系与数据结构如下&#xff1a; (2 探讨二 ) 可见 atomic 的 fetch_xx 函数&#xff0c;返回的都是 atomic 中存储的旧值。测试如下&#xff1a; 谢谢

MySQL千万级数据从190秒优化到1秒全过程

文章目录 一、性能问题的分析1. 问题背景2. 查询分析二、优化思路1. 添加索引2. 分区表3. 优化查询4. 查询缓存三、具体优化步骤1. 添加复合索引2. 对表进行分区3. 启用查询缓存4. 优化查询四、总结🎉欢迎来到Java学习路线专栏~探索Java中的静态变量与实例变量 ☆* o(≧▽≦)…

2024年【北京市安全员-B证】模拟考试题及北京市安全员-B证操作证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 北京市安全员-B证模拟考试题考前必练&#xff01;安全生产模拟考试一点通每个月更新北京市安全员-B证操作证考试题目及答案&#xff01;多做几遍&#xff0c;其实通过北京市安全员-B证在线考试很简单。 1、【多选题】…

文案提取小帮手轻松将视频为转文字!而且不限时长

作为一个自媒体的资深用户总在一个一个的敲字真的太慢了&#xff0c;而且很多创作者都知道追热点是和时间赛跑。如果你嫌弃自己手抄效率太低&#xff0c;看视频又嫌时间太长。 今天叫教你一个可以将视频转文字的工具&#xff0c; 这个工具就叫文案提取小帮手&#xff0c;而且…

Golang的channel

目录 基本使用 channel 数据结构 阻塞的协程队列 协程节点 构建 channel 写流程 读流程 非阻塞与阻塞 closechan(关闭) 基本使用 创建无缓存 channel c : make(chan int) //创建无缓冲的通道 cc : make(chan int,0) //创建无缓冲的通道 c 创建有缓存 channel c : m…

2024年大数据、区块链与物联网国际会议(ICBDBLT 2024)

2024 International Conference on Big Data, Blockchain, and Internet of Things 【1】大会信息 会议简称&#xff1a;ICBDBLT 2024 大会地点&#xff1a;中国青岛 审稿通知&#xff1a;投稿后2-3日内通知 会议官网&#xff1a;www.icbdblt.com 【2】会议简介 即将召开的…

定档6.20,创邻科技图数据库先锋版发布会来了!

6月20日 14:00 &#xff0c;创邻科技将重磅召开 2024 Galaxybase银河图数据库先锋版发布会&#xff0c;戳此预约&#xff01; 书于竹帛&#xff0c;镂于金石&#xff0c;琢于盘盂。历史长河中&#xff0c;数据通过不同形态承载着人类文明&#xff0c;人们在数千年中始终保持着…

智能制造前沿:ARMxy工控机在机器人控制中

机器人控制系统正逐步成为现代制造业的核心引擎。在这个过程中&#xff0c;ARMxy工业计算机以其独特的优势&#xff0c;成为了驱动这一变革的关键力量。本文将以自动化装配线机器人为例&#xff0c;探讨ARMxy如何通过其低功耗、高性能特性&#xff0c;以及高度灵活性的设计&…