openh264 SVC 时域分层原理介绍

openh264

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

SVC编码

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

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

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

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

openh264 SVC时域分层编码原理

代码流程

在这里插入图片描述

原理

  1. 定义二维数组g_kuiTemporalIdListTable,是 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;

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

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

相关文章

外链是否会增加流量?

外链确实可以间接地帮助增加网站流量&#xff0c;不过要了解的是这不是直接影响&#xff0c;首先&#xff0c;外链主要是提升你的网站在搜索引擎中的整体权重。简单地说&#xff0c;当你的网站被很多其他的网站通过dofollow链接指向时&#xff0c;搜索引擎会认为你的网站内容质…

如何完美解决 Xshell 使用 SSH 连接 Linux 服务器报错:找不到匹配的 host key 算法

&#x1f6e0;️ 如何完美解决 Xshell 使用 SSH 连接 Linux 服务器报错&#xff1a;找不到匹配的 host key 算法 摘要&#xff1a; 本文将带领大家深入学习如何解决 Xshell 使用 SSH 连接 Linux 服务器时报错“找不到匹配的 host key 算法”的问题。通过详细的操作步骤和代码案…

有什么可以创建ai聊天的软件?5个软件帮助你快速创建ai聊天

有什么可以创建ai聊天的软件&#xff1f;5个软件帮助你快速创建ai聊天 AI聊天软件是一种利用人工智能技术构建的聊天机器人系统&#xff0c;它能够模拟人类的对话方式&#xff0c;回答用户提出的问题或者进行对话。这类软件在各个领域都有广泛的应用&#xff0c;可以用于客户服…

从Instance classifier重新思考多实例学习

弱监督的WSI分类通常被形式化为多实例学习&#xff08;MIL&#xff09;问题&#xff0c;其中每张slide都被视为一个bag&#xff0c;从中切出的patch被视为实例。现有的方法要么通过伪标记训练实例分类器&#xff0c;要么通过注意力机制将实例特征聚合为bag特征&#xff0c;然后…

Shopee虾皮API:获取商家店铺商品列表

一、平台介绍 Shopee&#xff0c;作为东南亚及中国台湾地区领先的电商平台&#xff0c;为卖家提供了一个便捷、高效的销售渠道。作为卖家&#xff0c;能够将自己的商品展示在Shopee平台上&#xff0c;并通过平台的流量和工具&#xff0c;将商品销售给更多的潜在买家。 为了帮…

Elasticsearch-使用Logstash同步Mysql

1.安装logstash es服务器版本必须和logstash版本一致 7.9.2 在/usr/local/src/下新建logstash文件夹&#xff0c;解压 下载logstash后查看是否安装成功&#xff0c;在logstash的bin目录下输入指令&#xff1a; ./logstash -e input { stdin { } } output { stdout {} }2.my…

Java项目:基于SSM框架实现的汽车养护保养管理系统【ssm+B/S架构+源码+数据库+开题+毕业论文+任务书】

一、项目简介 本项目是一套基于SSM框架实现的汽车养护保养管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

【Java05】Java中的多维数组

从数组底层运行机制上看&#xff0c;Java没有多维数组一说。所谓多维数组&#xff0c;是说一个引用变量指向的元素也是引用变量。 例如&#xff0c;type[] arrayName是个指向type类型元素的数组。倘若type也是数组引用变量&#xff0c;比如int[]&#xff0c;那么这个数组就可以…

警惕!ELSEVIER旗下1本双1区TOP被On Hold !请大家谨慎投稿

【SciencePub学术】又1本&#xff01;双1区TOP刊被On Hold &#xff01;官方现在对期刊质量的管控越来越严格了&#xff0c;被标记为On Hold后的期刊中&#xff0c;大部分的命运也是被WOS数据库剔除&#xff01;所以请大家谨慎投稿&#xff01; 《Information Sciences》作为一…

Spring Security+Spring Boot实现登录认证以及权限认证

基本概念 “Authentication(认证)”是spring security框架中最重要的功能之一&#xff0c;所谓认证&#xff0c;就是对当前访问系统的用户给予一个合法的身份标识&#xff0c;用户只有通过认证才可以进入系统&#xff0c;在物理世界里&#xff0c;有点类似于“拿工卡刷门禁”的…

【达梦数据库】typeorm+node.js+达梦数据库返回自增列值

1.配置环境&#xff0c;下载依赖包 typeorm init --name test22 --database mysql typeorm-dm&#xff0c;uuid,typeorm2,修改连接信息 修改src/ data-source.ts 文件 连接dm&#xff0c;可参考刚刚安装typeorm-dm 模块中的 README.md 3.修改自增信息 /* 修改前*/PrimaryGen…

HarmonyOS之自选股App

支持在 鸿蒙、安卓、苹果设备上运行。 1.界面效果展示 2.数据存储 数据存储采用的是官方的 ohos.data.relationalStore.relationalStore stock_code表用来存储A股市场5000多家公司的股票代码和名称等信息 const TAB_STOCK_CODE "stock_code" const CREATE_TABL…

思科配置:vlan、两个交换机、两个路由器、四台主机

一、如图配置 各设备ip地址、接口、vlan如图所示。 二、配置各主机ip、子网掩码、默认网关 PC0 PC8 PC1 PC9 PC2 PC10 PC3 PC11 三、配置Switch0 &#xff08;期间报错为拼写错误&#xff09; MySwitch0> MySwitch0>en MySwitch0#conf t Enter configuration co…

《珊瑚岛》是一款什么类型的游戏 苹果电脑如何玩到《珊瑚岛》

在众多电子游戏中&#xff0c;有些游戏因其独特的游戏体验和丰富的内容而脱颖而出&#xff0c;《珊瑚岛》便是其中之一。在游戏中你将离开宝京前往珊瑚岛&#xff0c;种植农作物、饲养动物、和岛民成为朋友。您不仅可以振兴该岛小镇&#xff0c;还可以保护和修复周围的珊瑚礁。…

2毛钱的SOT23-5封装单运放LMV321支持轨到轨输出

前言&#xff1a; 运放比三极管放大电路更简洁、PCB占用空间小&#xff0c;该LMV321单价较低&#xff0c;且支持轨到轨&#xff0c;TI的单价约0.4元&#xff0c;国产有多家半导体厂商有替代产品&#xff0c;追求性价比的可以选择国产LMV321&#xff0c;参考价格约0.2元。在多数…

市场情绪周期2024-6-17(补涨回头潮视角验证)

竞价隔夜单 看长江通信&#xff0c;38亿涨到40亿又回落&#xff0c;那么周末最大的利好消息加持下&#xff0c;隔夜单不及预期&#xff0c;金溢科技 更是如此&#xff1b;空间板华闻集团8天7板&#xff0c;连扳5板&#xff0c;一字跌停&#xff0c;它也是有车联网的&#xff0c…

visual studio下载安装

1、下载网址&#xff1a;下载 Visual Studio Tools - 免费安装 Windows、Mac、Linux 选择下载“社区” 2、下载好之后&#xff0c;安装在非系统盘上&#xff0c;在下面这个界面上&#xff0c;大家可以把自己需要的都勾选上&#xff0c;然后更改安装地址 安装完即可

嵌入式技术学习——c51——串口

一、串口介绍。 串口是一个 通讯接口。成本低&#xff0c;容易使用&#xff0c;通信线路简单&#xff0c;可实现两个设备的相互通信 单片机的串口可以实现单片机于单片机&#xff0c;单片机与电脑&#xff0c;单片机与其他模块相互通信。 51单片机内部自带UART&#xff0c;通…

16.RedHat认证-Ansible自动化运维(中)

16.RedHat认证-Ansible自动化运维(中) 部署Ansible Ansible的Inventory文件 Inventory文件定义了ansible管理的主机&#xff0c;说白了就是Inventory文件中的内容是记录被管理的主机。 Inventory文件分为两种&#xff0c;一种是静态的Inventory文件&#xff0c;一种是动态的…

mcms-5.2.8环境部署

1 数据库 1.1 新建数据库 1.2 导入数据表 2 tomcat配置 2.1 在IDEA中tomcat环境并配置 首先添加tomcat服务器并配置 配置Artifacts&#xff08;这里配置不正确的话&#xff0c;在运行时会报错&#xff1a;Error during artifact deployment. See server log for details.&am…