openh264 帧内预测编码原理:WelsMdIntraChroma 函数

2024-06-15 20:44

本文主要是介绍openh264 帧内预测编码原理:WelsMdIntraChroma 函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

帧内色度预测编码

  • 帧内预测的目的是利用图像中相邻像素的亮度和色度值之间的接近性来进行压缩。在H.264中,帧内预测包括亮度和色度的预测。色度预测模式通常是基于亮度预测模式来确定的,因为色度分量通常具有更高的空间冗余度。色度预测模式的选择可以基于亮度预测模式,并且可能包括DC模式、垂直模式、水平模式等。
  • 在OpenH264中,帧内色度预测编码的过程涉及到几个核心函数,如 WelsMdIntraChroma 函数,它负责色度像素块的帧内模式决策。色度的预测模式与亮度16x16块的预测模式相似,有7种模式可供选择。在编码过程中,会根据可用的参考像素和预测模式列表来选择最佳模式,以最小化编码成本。

函数介绍

  1. 函数说明:类似 I16x16决策过程,色度的预测模式跟 I16x16 块一样,具体可以参考:openh264 帧内预测编码过程源码分析。
  2. 函数功能:针对色度像素块的帧内模式决策
  3. 函数原型
int32_t WelsMdIntraChroma (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SMbCache* pMbCache, int32_t iLambda)
  1. 函数参数
  • pFunc: 指向函数指针列表的指针,包含用于编码的各种函数。
  • pCurDqLayer: 指向当前解码层的指针。
  • pMbCache: 指向宏块缓存的指针,包含编码过程中使用的缓存数据。
  • iLambda: 一个用于调整成本计算的权重值。

函数关系图

在这里插入图片描述

函数原理

  1. 内部实现详细过程
  • 局部变量初始化;
  • 根据宏块的领域宏块情况计算得出iOffset;
  • iAvailCount 和 kpAvailMode 用于获取当前宏块可用的帧内预测模式数量和预测模式列表;
  • 如果iAvailCount大于 3,且提供 pfIntra16x16Combined3函数,
    • 调用pfIntra16x16Combined3函数计算出最佳代价iBestCost和色度最佳模式iBestMode;
    • 基于当前预测模式iCurMode调用pfGetChromaPred函数分别预测两个色度 Cb、Cr的预测块;
    • 调用pfMdCost函数计算两个色度的代价相加,并加上iLambda * 4,作为当前模式下的代价iCurCost;
    • 如果 iCurCost 小于 iBestCost,
      • 则更新最佳模式iBestMode和最佳代价iBestCost;
    • 否则,
      • 基于最佳模式iBestMode,重新调用pfGetChromaPred函数分别预测两个色度的预测块;
    • 累加iLambda到最佳代价iBestCost;
  • 否则,
    • for 循环每个模式,
      • 基于当前预测模式iCurMode调用pfGetChromaPred函数分别预测两个色度 Cb、Cr的预测块;
      • 调用pfMdCost函数计算两个色度的代价相加,并加上加上量化参数 iLambda 与当前模式编号的编码长度(使用 BsSizeUE 函数和 g_kiMapModeI16x16 数组计算)的乘积,作为当前模式下的代价iCurCost;
      • 如果 iCurCost 小于 iBestCost,
        • 则更新最佳模式iBestMode和最佳代价iBestCost;
  • 返回最佳代价iBestCost。
  1. 函数原理流程图
    在这里插入图片描述

源码


int32_t WelsMdIntraChroma (SWelsFuncPtrList* pFunc, SDqLayer* pCurDqLayer, SMbCache* pMbCache, int32_t iLambda) {const int8_t* kpAvailMode;int32_t iAvailCount = 0;int32_t iChmaIdx = 0;uint8_t* pPredIntraChma[2]    = {pMbCache->pMemPredChroma, pMbCache->pMemPredChroma + 128};uint8_t* pDstChma             = pPredIntraChma[0];uint8_t* pEncCb               = pMbCache->SPicData.pEncMb[1];uint8_t* pEncCr               = pMbCache->SPicData.pEncMb[2];uint8_t* pDecCb               = pMbCache->SPicData.pCsMb[1];//pMbCache->SPicData.pDecMb[1];uint8_t* pDecCr               = pMbCache->SPicData.pCsMb[2];//pMbCache->SPicData.pDecMb[2];const int32_t kiLineSizeEnc   = pCurDqLayer->iEncStride[1];const int32_t kiLineSizeDec   = pCurDqLayer->iCsStride[1];//pMbCache->SPicData.i_stride_dec[1];int32_t i, iCurMode, iCurCost, iBestMode, iBestCost = INT_MAX;int32_t iOffset = pMbCache->uiNeighborIntra & 0x07;iAvailCount = g_kiIntraChromaAvailMode[iOffset][4];kpAvailMode = g_kiIntraChromaAvailMode[iOffset];if (iAvailCount > 3 && pFunc->sSampleDealingFuncs.pfIntra8x8Combined3) {iBestCost = pFunc->sSampleDealingFuncs.pfIntra8x8Combined3 (pDecCb, kiLineSizeDec, pEncCb, kiLineSizeEnc, &iBestMode,iLambda, pDstChma, pDecCr, pEncCr);iCurMode = kpAvailMode[3];pFunc->pfGetChromaPred[iCurMode] (pDstChma, pDecCb, kiLineSizeDec); //CbpFunc->pfGetChromaPred[iCurMode] (pDstChma + 64, pDecCr, kiLineSizeDec); //CriCurCost = pFunc->sSampleDealingFuncs.pfMdCost[BLOCK_8x8] (pDstChma, 8, pEncCb, kiLineSizeEnc) +pFunc->sSampleDealingFuncs.pfMdCost[BLOCK_8x8] (pDstChma + 64, 8, pEncCr, kiLineSizeEnc) +iLambda * 4;if (iCurCost < iBestCost) {iBestMode = iCurMode;iBestCost = iCurCost;} else {pFunc->pfGetChromaPred[iBestMode] (pDstChma, pDecCb, kiLineSizeDec); //CbpFunc->pfGetChromaPred[iBestMode] (pDstChma + 64, pDecCr, kiLineSizeDec); //Cr}iBestCost += iLambda;iChmaIdx = 1;} else {iBestMode = kpAvailMode[0];for (i = 0; i < iAvailCount; ++ i) {iCurMode = kpAvailMode[i];assert (iCurMode >= 0 && iCurMode < 7);// pDstCb = &pMbCache->mem_pred_intra_cb[iCurMode<<6];// pDstCr = &pMbCache->mem_pred_intra_cr[iCurMode<<6];pFunc->pfGetChromaPred[iCurMode] (pDstChma, pDecCb, kiLineSizeDec); //CbiCurCost = pFunc->sSampleDealingFuncs.pfMdCost[BLOCK_8x8] (pDstChma, 8, pEncCb, kiLineSizeEnc);pFunc->pfGetChromaPred[iCurMode] (pDstChma + 64, pDecCr, kiLineSizeDec); //CriCurCost += pFunc->sSampleDealingFuncs.pfMdCost[BLOCK_8x8] (pDstChma + 64, 8, pEncCr, kiLineSizeEnc) +iLambda * BsSizeUE (g_kiMapModeIntraChroma[iCurMode]);if (iCurCost < iBestCost) {iBestMode = iCurMode;iBestCost = iCurCost;iChmaIdx = iChmaIdx ^ 0x01;pDstChma = pPredIntraChma[iChmaIdx];}}}pMbCache->pBestPredIntraChroma = pPredIntraChma[iChmaIdx ^ 0x01];pMbCache->uiChmaI8x8Mode = iBestMode;return iBestCost;
}

这篇关于openh264 帧内预测编码原理:WelsMdIntraChroma 函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1064525

相关文章

Spring @Scheduled注解及工作原理

《Spring@Scheduled注解及工作原理》Spring的@Scheduled注解用于标记定时任务,无需额外库,需配置@EnableScheduling,设置fixedRate、fixedDe... 目录1.@Scheduled注解定义2.配置 @Scheduled2.1 开启定时任务支持2.2 创建

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

Python中help()和dir()函数的使用

《Python中help()和dir()函数的使用》我们经常需要查看某个对象(如模块、类、函数等)的属性和方法,Python提供了两个内置函数help()和dir(),它们可以帮助我们快速了解代... 目录1. 引言2. help() 函数2.1 作用2.2 使用方法2.3 示例(1) 查看内置函数的帮助(

Python中使用uv创建环境及原理举例详解

《Python中使用uv创建环境及原理举例详解》uv是Astral团队开发的高性能Python工具,整合包管理、虚拟环境、Python版本控制等功能,:本文主要介绍Python中使用uv创建环境及... 目录一、uv工具简介核心特点:二、安装uv1. 通过pip安装2. 通过脚本安装验证安装:配置镜像源(可

C++ 函数 strftime 和时间格式示例详解

《C++函数strftime和时间格式示例详解》strftime是C/C++标准库中用于格式化日期和时间的函数,定义在ctime头文件中,它将tm结构体中的时间信息转换为指定格式的字符串,是处理... 目录C++ 函数 strftipythonme 详解一、函数原型二、功能描述三、格式字符串说明四、返回值五

Mysql的主从同步/复制的原理分析

《Mysql的主从同步/复制的原理分析》:本文主要介绍Mysql的主从同步/复制的原理分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录为什么要主从同步?mysql主从同步架构有哪些?Mysql主从复制的原理/整体流程级联复制架构为什么好?Mysql主从复制注意

Nacos注册中心和配置中心的底层原理全面解读

《Nacos注册中心和配置中心的底层原理全面解读》:本文主要介绍Nacos注册中心和配置中心的底层原理的全面解读,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录临时实例和永久实例为什么 Nacos 要将服务实例分为临时实例和永久实例?1.x 版本和2.x版本的区别

Python中bisect_left 函数实现高效插入与有序列表管理

《Python中bisect_left函数实现高效插入与有序列表管理》Python的bisect_left函数通过二分查找高效定位有序列表插入位置,与bisect_right的区别在于处理重复元素时... 目录一、bisect_left 基本介绍1.1 函数定义1.2 核心功能二、bisect_left 与

java中BigDecimal里面的subtract函数介绍及实现方法

《java中BigDecimal里面的subtract函数介绍及实现方法》在Java中实现减法操作需要根据数据类型选择不同方法,主要分为数值型减法和字符串减法两种场景,本文给大家介绍java中BigD... 目录Java中BigDecimal里面的subtract函数的意思?一、数值型减法(高精度计算)1.

C++/类与对象/默认成员函数@构造函数的用法

《C++/类与对象/默认成员函数@构造函数的用法》:本文主要介绍C++/类与对象/默认成员函数@构造函数的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录名词概念默认成员函数构造函数概念函数特征显示构造函数隐式构造函数总结名词概念默认构造函数:不用传参就可以