openh264 SVC 时域分层原理介绍

devtools/2024/10/18 5:47:45/

h264>openh264_0">h264>openh264

OpenH264是一个开源的H.264编码器,由Cisco公司开发并贡献给开源社区。它支持包括SVC(Scalable Video Coding)在内的多种编码特性,适用于实时应用场景,比如WebRTC。OpenH264项目在GitHub上是公开的,任何人都可以访问和使用它的源代码。

SVC_2">SVC编码

SVC(Scalable Video Coding,可伸缩视频编码)是一种先进的视频编码技术,它允许视频流被分割成多个层级,每个层级可以独立解码,并且可以根据网络带宽和解码能力提供不同质量的视频。这种技术特别适用于视频会议、视频监控和流媒体服务等场景,其中用户的网络条件和设备能力可能有很大差异。
SVC技术通过分层编码,实现了视频质量分辨率帧率的可扩展性。

  • 其中帧率可扩展即时域分层编码,允许根据网络带宽能力实现不同的帧率变化;在网络带宽较低时,接收端可以只解码基本层帧率的视频,而在带宽较高时,可以解码更多的帧以获得更流畅的视频效。

SVC技术的关键优势在于其灵活性和适应性。通过一次编码过程,可以生成多个可解码的子码流,适应不同的网络条件和终端设备。例如,在视频会议中,可以根据每个参与者的网络带宽动态调整发送的视频质量,确保所有人都能获得尽可能好的观看体验。

SVC技术的应用可以有效解决传统视频编码中的一些问题,如多次编码的需求和转码过程中的计算复杂度及性能损失。它通过提供一种编码后的视频码流,使得可以根据不同的网络环境和终端需求灵活地传输和解码视频,从而优化了视频的传输效率和用户体验。

h264>openh264_SVC_10">h264>openh264 SVC时域分层编码原理

代码流程

在这里插入图片描述

原理

  1. 定义二维数组g_kuiTemporalIdListTable,是 h264>openh264 实现时域分层的精髓部分,如下定义,分别对应 uiGopSize=1、2、3、4,表示时域分层 1、2、3、4 层;
    • 当uiGopSize = 1 时,表示时域分层为 1 层,即所有帧都是 0 0 0 0 层;
    • 当uiGopSize = 2 时,表示时域分层为 2 层,即帧序层是 0 1 0 1 层;
    • 当uiGopSize = 3 时,表示时域分层为 3 层,即帧序层是 0 2 1 2 0 2 1 2 层;
    • 当uiGopSize = 4 时,表示时域分层为 4 层,即帧序层是 0 3 2 3 1 3 2 3 层;
const uint8_t   g_kuiTemporalIdListTable[MAX_TEMPORAL_LEVEL][MAX_GOP_SIZE + 1] = {{0, 0, 0, 0, 0, 0, 0, 0,0},  // uiGopSize = 1{0, 1, 0, 0, 0, 0, 0, 0,0},  // uiGopSize = 2{0, 2, 1, 2, 0, 0, 0, 0,0},  // uiGopSize = 4{0, 3, 2, 3, 1, 3, 2, 3,0}  //uiGopSize = 8
};
  1. ParamTranscode函数中通过输入参数iTemporalLayerNum计算得到uiGopSize;
    • 其中iTemporalLayerNum的取值范围 1、2、3、4;
    • 因此通过计算uiGopSize的取值为 、2、4、8;
//代码有删减
iTemporalLayerNum = (int8_t)WELS_CLIP3 (pCodingParam.iTemporalLayerNum, 1,MAX_TEMPORAL_LEVEL); // number of temporal layer specified
uiGopSize           = 1 << (iTemporalLayerNum - 1); // Override GOP size based temporal layer
  1. 定义WELS_LOG2函数通过输入uiGopSize 计算iDecStages;
static inline int32_t WELS_LOG2 (uint32_t v) {int32_t r = 0;while (v >>= 1) {++r;}return r;}
  1. DetermineTemporalSettings函数中实现将g_kuiTemporalIdListTable转换到uiCodingIdx2TemporalId一维数组中;
    • 使用WELS_LOG2函数来计算GOP大小的对数,根据uiGopSize确定时域分层数;
    • 定义pTemporalIdList指针,指向表g_kuiTemporalIdListTable;
    • 遍历uiGopSize中,确定pTemporalIdList中帧的时域层级kiTemporalId;
    • 根据kiTemporalId计算出每个空域层中的uiCodingIdx2TemporalId中的时域层级别标志,即对应g_kuiTemporalIdListTable中数字号;
  /*!* \brief  determined key coding tables for temporal scalability, uiProfileIdc etc for each spatial layer settings* \param  SWelsSvcCodingParam, and carried with known GOP size, max, input and output frame rate of each spatial* \return NONE (should ensure valid parameter before this procedure)*/int32_t DetermineTemporalSettings() {const int32_t iDecStages = WELS_LOG2 (uiGopSize); // (int8_t)GetLogFactor(1.0f, 1.0f * pcfg->uiGopSize);  //log2(uiGopSize)const uint8_t* pTemporalIdList = &g_kuiTemporalIdListTable[iDecStages][0];SSpatialLayerInternal* pDlp    = &sDependencyLayers[0];SSpatialLayerConfig* pSpatialLayer = &sSpatialLayers[0];int8_t i = 0;while (i < iSpatialLayerNum) {const uint32_t kuiLogFactorInOutRate = GetLogFactor (pDlp->fOutputFrameRate, pDlp->fInputFrameRate);const uint32_t kuiLogFactorMaxInRate = GetLogFactor (pDlp->fInputFrameRate, fMaxFrameRate);if (UINT_MAX == kuiLogFactorInOutRate || UINT_MAX == kuiLogFactorMaxInRate) {return ENC_RETURN_INVALIDINPUT;}int32_t iNotCodedMask = 0;int8_t iMaxTemporalId = 0;memset (pDlp->uiCodingIdx2TemporalId, INVALID_TEMPORAL_ID, sizeof (pDlp->uiCodingIdx2TemporalId));iNotCodedMask = (1 << (kuiLogFactorInOutRate + kuiLogFactorMaxInRate)) - 1;for (uint32_t uiFrameIdx = 0; uiFrameIdx <= uiGopSize; ++ uiFrameIdx) {if (0 == (uiFrameIdx & iNotCodedMask)) {const int8_t kiTemporalId = pTemporalIdList[uiFrameIdx];pDlp->uiCodingIdx2TemporalId[uiFrameIdx] = kiTemporalId;if (kiTemporalId > iMaxTemporalId) {iMaxTemporalId = kiTemporalId;}}}pDlp->iHighestTemporalId   = iMaxTemporalId;pDlp->iTemporalResolution  = kuiLogFactorMaxInRate + kuiLogFactorInOutRate;pDlp->iDecompositionStages = iDecStages - kuiLogFactorMaxInRate - kuiLogFactorInOutRate;if (pDlp->iDecompositionStages < 0) {return ENC_RETURN_INVALIDINPUT;}++ pDlp;++ pSpatialLayer;++ i;}iDecompStages = (int8_t)iDecStages;return ENC_RETURN_SUCCESS;}
  1. 之后根据时域分层 ID,进行参考帧管理和帧重要性管理操作。
    //代码有删减if (iCurTid == 0 || pCtx->eSliceType == I_SLICE)eNalRefIdc = NRI_PRI_HIGHEST;else if (iCurTid == iDecompositionStages)eNalRefIdc = NRI_PRI_LOWEST;else if (1 + iCurTid == iDecompositionStages)eNalRefIdc = NRI_PRI_LOW;else // more details for other temporal layers?eNalRefIdc = NRI_PRI_HIGHEST;pCtx->eNalType = eNalType;pCtx->eNalPriority = eNalRefIdc;

http://www.ppmy.cn/devtools/48259.html

相关文章

Python私教张大鹏 Vue3整合AntDesignVue之AutoComplete 自动完成

何时使用 需要一个输入框而不是选择器。需要输入建议/辅助提示。 和 Select 的区别 AutoComplete 是一个带提示的文本输入框&#xff0c;用户可以自由输入&#xff0c;关键词是辅助输入。Select 是在限定的可选项中进行选择&#xff0c;关键词是选择。 基本使用 基本使用。…

[数据分享第二弹]降水、植被、土壤等生态相关数据分享

数据是GIS的重要组成部分&#xff0c;也是我们进行研究分析的基础。在日常工作中&#xff0c;我们时常因数据问题而犯难&#xff0c;今天就来继续做一波相关数据分享。 1.世界土壤数据库&#xff08;HWSD&#xff09;全球土壤数据 世界协调土壤数据库 2.0 版 &#xff08;HWS…

python3的基本语法: import 与 from...import

一. 简介 前面几篇文章学习了 python3的基本语法&#xff0c;文章如下&#xff1a; python3的基本语法说明一-CSDN博客 python3的基本语法说明二-CSDN博客 python3的基本语法说明三-CSDN博客 本文继续学习 python3 的基本语法。 二. python3的基本语法&#xff1a;impor…

CPT204 Advanced OO Programming(2)

W5 Lists_stacks_queues_priority queues  To explore the relationship between interfaces and classes in the Java Collections Framework hierarchy.  To use the common methods defined in the Collectioninterface for operating collections.  To use…

mac环境基于llama3和metaGPT自动开发2048游戏

1.准备虚拟环境 conda create -n metagpt python3.9 && conda activate metagpt 2.安装metagpt pip install --upgrade metagpt 3.初始化配置文件 metagpt --init-config 4. 安装llama3 5. 修改配置文件 6.让metegpt自动开发2048游戏 7.经过多轮迭代&#xff0c;最终…

WPF国际化的最佳实践

WPF国际化的最佳实践 1.创建项目资源文件 如果你的项目没有Properties文件夹和Resources.resx文件&#xff0c;可以通过右键项目-资源-常规-添加创建或打开程序集资源 2.添加国际化字符串 打开Resources.resx文件&#xff0c;添加需要翻译的文本字符&#xff0c;并将访问修…

找不到vcruntime140_1.dll无法继续执行的原因解析及解决方法

在现代的信息化社会中&#xff0c;电脑已经成为我们生活和工作中不可或缺的工具之一。然而&#xff0c;在使用过程中&#xff0c;我们可能会遇到一些问题&#xff0c;其中之一就是电脑缺失vcruntime140_1.dll文件。那么&#xff0c;这个问题到底是怎么回事呢&#xff1f;小编将…

Transformer动画讲解:注意力计算Q、K、V

暑期实习基本结束了&#xff0c;校招即将开启。 不同以往的是&#xff0c;当前职场环境已不再是那个双向奔赴时代了。求职者在变多&#xff0c;HC 在变少&#xff0c;岗位要求还更高了。提前准备才是完全之策。 最近&#xff0c;我们又陆续整理了很多大厂的面试题&#xff0c…