openh264 SVC 时域分层原理介绍

news2024/11/24 10:36:04

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;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

hugo-magic主题使用教程(一)

前提条件 以下教程以windows10为例操作终端使用git bash魔法上网的前提下 下载hugo https://github.com/gohugoio/hugo/releases/download/v0.127.0/hugo_extended_0.127.0_windows-amd64.zip解压到任意目录,然后将目录添加到系统环境变量 如图 (windows)打开cmd 输入 hugo …

windows系统,家庭自用NAS。本地局域网 Docker安装nextcloud

windows系统&#xff0c;家庭自用NAS。本地局域网 Docker安装nextcloud 1、docker安装 太简单了&#xff0c;直接去搜一搜。 docker-compose 相关命令 docker-compose down docker compose up -d2、还是使用老的 在你需要挂载的目录下&#xff0c;新建一个文件&#xff0c;…

2023年13个最适合销售电子书的WordPress主题

欢迎来到我们用于销售电子书和其他数字/可下载产品&#xff08;软件、应用程序、图标集、主题等&#xff09;的最佳WordPress主题的完整集合。 这些主题有内置的支付网关&#xff0c;可以通过 PayPal、信用卡等处理安全支付。&#xff08;易于配置&#xff01;&#xff09; 最…

我主编的电子技术实验手册(07)——串联电路

本专栏是笔者主编教材&#xff08;图0所示&#xff09;的电子版&#xff0c;依托简易的元器件和仪表安排了30多个实验&#xff0c;主要面向经费不太充足的中高职院校。每个实验都安排了必不可少的【预习知识】&#xff0c;精心设计的【实验步骤】&#xff0c;全面丰富的【思考习…

海外仓系统如何让海外仓受益,WMS海外仓系统使用指南

随着跨境电商业务的快速发展&#xff0c;海外仓面临着需要更加高速运转的巨大挑战。 当海外仓出现因为手动作业导致效率低下&#xff0c;成本不断飙升或者出现库存管理问题的时候&#xff0c;意味着是时候引入一套合适的海外仓管理系统了。 对于寻求海外仓业务流程优化的企业…

2024年大数据领域的主流分布式计算框架有哪些

Apache Spark 适用场景 以批处理闻名&#xff0c;有专门用于机器学习的相关类库进行复杂的计算&#xff0c;有SparkSQL可以进行简单的交互式查询&#xff0c;也可以使用DataSet&#xff0c;RDD&#xff0c;DataFrame进行复杂的ETL操作。 关键词 处理数据量大批计算微批计算…

MATLAB中与直方图有关函数的关系

histogram Histogram plot画直方图 histcounts 直方图 bin 计数 histcounts是histogram的主要计算函数。 discretize 将数据划分为 bin 或类别 histogram2 画二元直方图 histcounts2 二元直方图 bin 计数 hist和histc过时了。替换不建议使用的 hist 和 histc 实例 hist → \r…

ByteTrack

1. 论文中伪代码表示的流程图 2. 简要版 此图源自&#xff1a; ByteTrack多目标跟踪原理&#xff0c;白老师人工智能学堂 3. 详细版 根据ByteTrack-CPP-ncnn代码的数据流画的较为详细的流程图&#xff1a; 4. ByteTrack-CPP-ncnn的UML类图 Reference ByteTrack多目标跟踪原…

[FFmpeg学习]windows环境sdl播放音频试验

参考资料&#xff1a; FFmpeg和SDL2播放mp4_sdl 播放mp4 声音-CSDN博客 SimplePlayer/SimplePlayer.c at master David1840/SimplePlayer GitHub 在前面的学习中&#xff0c;通过获得的AVFrame进行了播放画面&#xff0c; [FFmpeg学习]初级的SDL播放mp4测试-CSDN博客 播放…

npm安装不了解决办法

npm安装不了解决办法 这个错误是一个权限问题&#xff0c;导致 npm 无法在 D:\nodejs\node_modules 目录中创建必要的文件和文件夹。以下是一些解决方法&#xff1a; 1. 以管理员身份运行命令提示符 确保你以管理员身份运行命令提示符&#xff0c;然后再次尝试运行命令&#…

【计算机毕业设计】基于Springboot的毕业生实习与就业管理系统【源码+lw+部署文档】

包含论文源码的压缩包较大&#xff0c;请私信或者加我的绿色小软件获取 免责声明&#xff1a;资料部分来源于合法的互联网渠道收集和整理&#xff0c;部分自己学习积累成果&#xff0c;供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者…

JVM-GC-什么是垃圾

JVM-GC-什么是垃圾 前言 所谓垃圾其实是指&#xff0c;内存中没用的数据&#xff1b;没有任何引用指向这块内存&#xff0c;或者没有任何指针指向这块内存。没有的数据应该被清除&#xff0c;垃圾的处理其实是内存管理问题。 JVM虽然不直接遵循冯诺依曼计算机体系架构&#…

【深度学习】解析Vision Transformer (ViT): 从基础到实现与训练

之前介绍&#xff1a; https://qq742971636.blog.csdn.net/article/details/132061304 文章目录 背景实现代码示例解释 训练数据准备模型定义训练和评估总结 Vision Transformer&#xff08;ViT&#xff09;是一种基于transformer架构的视觉模型&#xff0c;它最初是由谷歌研究…

Java阻塞队列:ArrayBlockingQueue

Java阻塞队列&#xff1a;ArrayBlockingQueue ArrayBlockingQueue是Java中的一个阻塞队列&#xff08;Blocking Queue&#xff09;实现&#xff0c;它是线程安全的&#xff0c;并且基于数组实现。ArrayBlockingQueue常用于生产者-消费者模型&#xff0c;在这种模型中&#xff…

移动硬盘打不开怎么办?原因解析!

移动硬盘是一种方便携带、快速传输大量数据的存储设备。但有时我们会遇到这样的问题&#xff1a;插上电脑后&#xff0c;移动硬盘无法打开&#xff0c;出现各种错误提示。这时候我们该怎么办呢&#xff1f; 以下是一些可能导致移动硬盘打不开的原因及解决方法&#xff1a; 1.硬…

47.PyCharm P版突然无法启动

目录 1.启动cmd.exe&#xff0c;进到pycharm\bin目录&#xff0c;启动.\pycharm.bat&#xff0c;如果正常&#xff0c;就像下面这个样子&#xff0c;如果不正常&#xff0c;则会报错&#xff0c; 2.用记事本打开pycharm.bat文件&#xff0c;加上以下代码后 今晨&#xff0c;无…

llama3-70B体验

NVIDIA LLAMA3-70B大模型体验地址&#xff1a; NVIDIA NIM | llama3-70b 问题几个关于宇宙的问题&#xff0c;答案挺有意思的&#xff0c;很有启发性&#xff0c;记录一下&#xff1a; 问题1&#xff1a;既然相对论认为时间是相对的&#xff0c;为何却说宇宙寿命有137亿年&a…

股指期货功能

其金融期货的本质&#xff0c;决定了股指期货具有以下几方面特点&#xff1a; &#xff08;1&#xff09;交割方式为现金交割&#xff1b; &#xff08;2&#xff09;股指期货的持有成本较低&#xff1b; &#xff08;3&#xff09;股指期货的保证金率较低&#xff0c;杠杆性…

【尚庭公寓SpringBoot + Vue 项目实战】图片上传(十)

【尚庭公寓SpringBoot Vue 项目实战】图片上传&#xff08;十&#xff09; 文章目录 【尚庭公寓SpringBoot Vue 项目实战】图片上传&#xff08;十&#xff09;1、图片上传流程2、图片上传接口查看3、代码开发3.1、配置Minio Client3.2、开发上传图片接口 4、异常处理 1、图片…