openh264 帧间预测编码原理:WelsMdP16x16函数

openh264 帧间预测编码

  • 帧间预测编码是视频压缩技术中的关键方法之一,它主要用于减少视频序列中时间维度上的冗余。这种编码方式依赖于视频帧之间的空间相关性,通过预测和补偿来减少数据量,从而实现高效的视频压缩。帧间预测编码广泛应用于各种视频编码标准,包括H.264/AVC、H.265/HEVC、VP9和AV1等。通过减少时间冗余,帧间预测编码显著提高了视频数据的压缩率,同时保持了视频质量。
  • 关于 openh264 帧间预测编码整体过程可以参考:openh264 帧间预测编码过程源码分析。

WelsMdP16x16函数介绍

  1. 功能:实现了对16x16宏块的运动估计(Motion Estimation, ME)和运动补偿(Motion Compensation, MC),并得到 P16x16 块的代价 cost;
  2. 参数
  • pFunc: SWelsFuncPtrList* 类型的指针,指向一个函数指针列表,包含编码过程中使用的各种函数。
  • pCurLayer: SDqLayer* 类型的指针,指向当前处理的解码队列层(Decoding Queue Layer),包含当前宏块的编码和解码信息。
  • pWelsMd: SWelsMD* 类型的指针,指向运动检测(Motion Detection)相关的上下文信息,包括运动估计和补偿的数据结构。
  • pSlice: SSlice* 类型的指针,指向当前处理的切片(Slice)信息,切片是视频帧中的一个逻辑分段,包含一系列的宏块。
  • pCurMb: SMB* 类型的指针,指向当前正在处理的宏块。
  1. 返回值:SWelsME* pMe16x16中代价uiSatdCost;
  2. 函数关系图
    在这里插入图片描述

WelsMdP16x16函数原理

  • 通过 pMbCache = &pSlice->sMbCacheInfo; 获取当前切片的宏块缓存信息;
  • pMe16x16 指向用于16x16块运动估计的结构体,它被初始化为 pWelsMd->sMe.sMe16x16;
  • uiNeighborAvail 存储了当前宏块邻居(左侧、顶部)的存在性信息;
  • kiMbWidth 和 kiMbHeight 分别获取编码图像的宏块宽度和高度;
  • InitMe 函数用于初始化运动估计过程,包括编码宏块、参考宏块、屏幕块特征存储等信息;
  • pMe16x16->uSadPredISatd.uiSadPred 设置为 pWelsMd->iSadPredMb,这是预测的SAD值;
  • MV候选列表初始化:
    • pSlice->uiMvcNum 重置为0,表示MV候选列表的开始;
    • pMe16x16->sMvBase 作为基础MV添加到候选列表;
  • 空间MV预测:
    • 如果当前宏块的左侧或上方有邻居宏块,它们各自的16x16 MV被添加到候选列表。
  • 时间MV预测:
    • 如果参考帧是P切片,并且当前宏块在图像的右侧或下方有宏块,这些宏块的MV也被添加到候选列表,并根据 pSlice->sScaleShift 进行缩放。
  • MV预测:
    • PredMv 函数用于根据MV候选列表预测当前宏块的MV。
  • 执行运动搜索:
    • pFunc->pfMotionSearch[0] 调用指定的运动搜索算法来找到最佳MV,指向WelsMotionEstimateSearch函数完成运动估计搜索过程;
  • 更新宏块MV:
    • pCurMb->sP16x16Mv 和解码图像的MV列表 pCurLayer->pDecPic->sMvList 被更新为找到的最佳MV。
  • 返回SATD成本:
    • 函数返回 pMe16x16->uiSatdCost,这是与最佳MV相关的SATD(Sum of Absolute Transformed Differences)成本。

WelsMdP16x16函数源码

int32_t WelsMdP16x16 (SWelsFuncPtrList* pFunc, SDqLayer* pCurLayer, SWelsMD* pWelsMd, SSlice* pSlice, SMB* pCurMb) {
  SMbCache* pMbCache = &pSlice->sMbCacheInfo;
  SWelsME* pMe16x16 = &pWelsMd->sMe.sMe16x16;
  uint32_t uiNeighborAvail = pCurMb->uiNeighborAvail;
  const int32_t kiMbWidth  = pCurLayer->iMbWidth;  // for assign once
  const int32_t kiMbHeight = pCurLayer->iMbHeight;
  InitMe (*pWelsMd, BLOCK_16x16, pMbCache->SPicData.pEncMb[0], pMbCache->SPicData.pRefMb[0],
          pCurLayer->pRefPic->pScreenBlockFeatureStorage,
          *pMe16x16);
  //not putting the line below into InitMe to avoid judging mode in InitMe
  pMe16x16->uSadPredISatd.uiSadPred = pWelsMd->iSadPredMb;

  pSlice->uiMvcNum = 0;
  pSlice->sMvc[pSlice->uiMvcNum++] = pMe16x16->sMvBase;
  //spatial motion vector predictors
  if (uiNeighborAvail & LEFT_MB_POS) { //left available
    pSlice->sMvc[pSlice->uiMvcNum++] = (pCurMb - 1)->sP16x16Mv;
  }
  if (uiNeighborAvail & TOP_MB_POS) { //top available
    pSlice->sMvc[pSlice->uiMvcNum++] = (pCurMb - kiMbWidth)->sP16x16Mv;
  }
  //temporal motion vector predictors
  if (pCurLayer->pRefPic->iPictureType == P_SLICE) {
    if (pCurMb->iMbX < kiMbWidth - 1) {
      SMVUnitXY sTempMv = pCurLayer->pRefPic->sMvList[pCurMb->iMbXY + 1];
      pSlice->sMvc[pSlice->uiMvcNum].iMvX = sTempMv.iMvX >> pSlice->sScaleShift;
      pSlice->sMvc[pSlice->uiMvcNum].iMvY = sTempMv.iMvY >> pSlice->sScaleShift;
      ++ pSlice->uiMvcNum;
    }
    if (pCurMb->iMbY < kiMbHeight - 1) {
      SMVUnitXY sTempMv = pCurLayer->pRefPic->sMvList[pCurMb->iMbXY + kiMbWidth];
      pSlice->sMvc[pSlice->uiMvcNum].iMvX = sTempMv.iMvX >> pSlice->sScaleShift;
      pSlice->sMvc[pSlice->uiMvcNum].iMvY = sTempMv.iMvY >> pSlice->sScaleShift;
      ++ pSlice->uiMvcNum;
    }
  }

  PredMv (&pMbCache->sMvComponents, 0, 4, 0, & (pMe16x16->sMvp));
  pFunc->pfMotionSearch[0] (pFunc, pCurLayer, pMe16x16, pSlice);

  pCurMb->sP16x16Mv = pMe16x16->sMv;
  pCurLayer->pDecPic->sMvList[pCurMb->iMbXY] = pMe16x16->sMv;

  return pMe16x16->uiSatdCost;
}

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

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

相关文章

短路是怎么形成的

1. 短路分为电源短路和用电器短路。 电源短路&#xff1a;电流不经过任何用电器&#xff0c;直接由正极经过导线流向负极&#xff0c;由于电源内阻很小&#xff0c;导致短路电流很大&#xff0c;特别容易烧坏电源。 用电器短路&#xff1a;也叫部分电路短路&#xff0c;即一根…

全国产城市轨道交通运营公安AI高清视频监控系统

方案简介 城市轨道交通运营公安高清视频监控系统解决方案针对运营部门和公安部门的安保需求&#xff0c;选用华维视讯的各类前端和视频编解码、控制产品&#xff0c;通过统一平台提供视频监控服务和智能应用&#xff0c;满足轨道交通运营业主客运组织和抢险指挥的需求&#xff…

【idea】解决springboot项目中遇到的问题

一、Maven报错Could not find artifact com.mysql:mysql-connector-j:pom:unknown in aliyunmaven解决及分析 报错 创建springboot项目&#xff0c;勾选数据库驱动&#xff0c;springboot版本为3&#xff0c;现在改成了2.7.2&#xff0c;Maven就发生了报错Could not find art…

从兼职到大神:新手必看的UE材质原理讲解

对于刚接触UE的同学来说&#xff0c;材质篇章往往是令人望而生畏的一大板块。但材质的一些基本原理其实并不难&#xff0c;只要稍作理解便可以轻松入门。接下来我们便分为材质类型和节点类型两个知识板块来介绍材质的相关内容。 材质类型 材质分类 金属&#xff1a;金属材质一…

【C语言】数组参数和指针参数详解

在写代码的时候难免要把【数组】或者【指针】传给函数&#xff0c;那函数的参数该如何设计呢&#xff1f; 1 一维数组传参 #include <stdio.h> void test(int arr[])//ok? {} void test(int arr[10])//ok? {} void test(int* arr)//ok? {} void test2(int* arr[20])…

单载波水声通信技术研究【附MATLAB代码】

文章来源&#xff1a;​微信公众号&#xff1a;EW Frontier 摘要 水下无线通信因其在海洋科研、国防、救援及资源开发等方面的关键作用而备受关注。声波作为水中信息传输的有效载体&#xff0c;推动了水声通信技术的发展&#xff0c;其中单载波调制技术由于其高频谱利用率、结…

Vue60-TodoList案例-全局事件总线

一、全局事件总线的适用场景 虽然全局事件总线使用于任意组件之间的通信&#xff0c;但是没有必要处处用它。 数据在哪里&#xff0c;操作数据的方法就在哪里&#xff01; 二、TodoList案例-全局事件总线 适用于全局总线的场景&#xff1a;Item和App&#xff08;爷孙关系&…

RFID期末复习 | 防碰撞算法 | 信源编码 | 差错控制 | 系统调制 | S50卡 | 无源标签 | 工作频率 | 自动识别

防碰撞算法 ALOHA算法 ALOHA算法是一种随机接入方法&#xff0c;其基本思想是采取标签先发言的方式&#xff0c;当标签进入读写器的识别区域内时就自动向读写器发送其自身的ID号&#xff0c;在标签发送数据的过程中&#xff0c;若有其他标签也在发送数据&#xff0c;将会发生…

深度神经网络——什么是降维?

引言 什么是降维&#xff1f; 降维是用于降低数据集维度的过程&#xff0c;采用许多特征并将它们表示为更少的特征。 例如&#xff0c;降维可用于将二十个特征的数据集减少到仅有几个特征。 降维通常用于无监督学习任务 降维是一个用于降低数据集维度的过程&#xff0c;采用许…

从0到1,揭秘AI产品经理的高薪秘诀,转型之路与实战资源全解析

前言 随着算法模型的日益精进、计算能力的显著提升以及海量数据的积累&#xff0c;人工智能领域正以前所未有的速度蓬勃发展。 在国家政策的积极推动、社会资本的强劲注入下&#xff0c;人工智能产业正处于技术快速进步的黄金时期&#xff0c;其影响力广泛渗透至教育智能化、…

dmhs同步因目的端表自增列报错解决方法

dmhs同步因目的端表自增列报错解决方法 1 dmhs copy 装载数据时报错 HY000 CODE:-27232 配置源端捕获器cpt 1 dmhs copy 装载数据时报错 HY000 CODE:-2723 ERR:Only if specified in the column list and SET IDENTITY INSERT is ON, then identity column could be assigned …

栈帧浅析,堆栈漏洞概述——【太原理工大学软件安全期末补充】

在上一篇文章中我说实验一不重要&#xff0c;确实没必要完全按照实验内容逐字逐句理解&#xff0c;但是这里我们补充一个知识点 栈帧&#xff08;Stack Frame&#xff09;是计算机程序执行过程中&#xff0c;调用栈&#xff08;Call Stack&#xff09;中的一个单元&#xff0c;…

存储文件夹下所有.cpp和.h的代码到对应的txt文件里

最近大半年刷了160多天的题&#xff0c;每次刷的时候都要新建一个VS文件&#xff0c;所以文件内存太大了&#xff0c;又舍不得删&#xff0c;就用ai整了一个脚本&#xff0c;可将当前路径下的所有文件里的.cpp和.h文件储存到相应名字的txt文件里&#xff0c;若文件夹下还有文件…

跟TED演讲学英文:A tale of mental illness -- from the inside by Elyn Saks

A tale of mental illness – from the inside Link: https://www.ted.com/talks/elyn_saks_a_tale_of_mental_illness_from_the_inside Speaker: Elyn Saks Date: June 2012 文章目录 A tale of mental illness -- from the insideIntroductionVocabularySummaryTranscriptA…

从零开始理解 XML 和 JSON 的区别

在这篇文章中&#xff0c;我们将深入探讨XML和JSON这两种数据格式的关键异同点&#xff0c;以便读者可以根据项目需求做出明智的技术选择。 了解XML XML&#xff08;Extensible Markup Language&#xff09;是一种用于数据定义的标记语言&#xff0c;最初由万维网联盟&#x…

uniapp使用伪元素实现气泡

uniapp使用伪元素实现气泡 背景实现思路代码实现尾巴 背景 气泡效果在开发中使用是非常常见的&#xff0c;使用场景有提示框&#xff0c;对话框等等&#xff0c;今天我们使用css来实现气泡效果。老规矩&#xff0c;先看下效果图&#xff1a; 实现思路 其实实现这个气泡框的…

Matplotlib(小案例)

1、3D表面形状的绘制 from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import numpy as np import matplotlib as mplfigplt.figure() axfig.add_subplot(111,projection3d)unp.linspace(0,2*np.pi,100) vnp.linspace(0,np.pi,100) x10*np.outer(n…

Kubernetes CSR 颁发的 MinIO Operator 证书

在当前的 Kubernetes 环境中&#xff0c;创建、管理和自动化 TLS 证书的标准方法是使用 kind: CertificateSigningRequest &#xff08;CSR&#xff09;资源。此原生 Kubernetes 资源提供了一种强大而高效的方式来处理集群中证书的整个生命周期。 通过利用 CSR 资源&#xff0…

【算法与设计】期末总结

文章目录 第一章 概述算法与程序时间复杂性求上界 第二章 递归与分治双递归函数——Ackerman函数分治策略大整数乘法两位两位四位x四位 三位x三位两位x六位 第三章 动态规划矩阵连乘基本要素最优子结构子问题重叠 备忘录 第四章 贪心算法活动安排问题基本要素贪心选择性质最优子…

DLS平台:惠誉全球经济展望——今年调增至2.6%,明年调减!

摘要 尽管全球货币政策逐渐转向宽松&#xff0c;惠誉国际评级&#xff08;Fitch Ratings&#xff09;在最新的《全球经济展望》中对2024年全球经济增长进行了上调。然而&#xff0c;由于美国经济增速放缓和其他因素的影响&#xff0c;2025年的全球经济增长预期则被下调。这篇文…