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;

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

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

相关文章

Docker部署常见应用之SFTP服务器

文章目录 简介Dockers部署单用户多用户用户信息加密使用SSH密钥认证 参考文章 简介 atmoz/sftp 是一个基于 Docker 的 SFTP 服务镜像&#xff0c;它使用 OpenSSH 来提供 SFTP 服务。这个镜像支持创建单个或多个用户的 SFTP 访问&#xff0c;并允许用户通过 SFTP 协议安全地共享…

Excel 多列组合内容循环展开

某表格 A 列是编号&#xff0c;其他列是用逗号分隔的意义不同的分类列 ABCDEFG1Assembly#ProductTypeUnit ConfigNominal CapacitySupply VoltageGenerationCase Construction23H1012290001CMD,P24,36FAA,B33H1012290002CMD,P48,60FA,BA,B43H1012290003CMD,P24,36B,C,D,EAA,B …

SSM母婴用品交流系统-计算机毕业设计源码05772

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 母婴用品交流系统&#xff0c;主要的模块包括查看首页、轮播图管理、通知公告管理、资源管理&#xff08;母婴资讯、资讯分类&#xff09;、交…

统计信号处理基础 习题解答10-17

题目&#xff1a; 在选择不含信息的或者不假设任何先验知识的先验PDF时,我们需要从数据中得到最大的信息量。在这种方式下,数据是了解未知参数的主要贡献者。利用习题10.15的结果,这种方法可以通过选择使I最大的来实现。对于例10.1的高斯先验PDF,该如何选择和2使得 是不含信息…

visual studio 2022使用全版本平台工具集

https://www.cnblogs.com/coolfan/p/15822057.html vs2022使用全版本平台工具集 关键词&#xff1a;visual studio 2022使用全版本平台工具集;vs2022使用vc60、vc6.0工具集;vs2022使用全部旧平台工具集 优点&#xff1a;用v60平台工具集编译出来的exe文件可以无依赖的运行在W…

流量卡怎么办理的攻略

一、确定需求 在办理流量卡之前&#xff0c;你需要明确自己的需求。根据不同的使用场景&#xff0c;你可能需要考虑以下几个方面&#xff1a; 月租费用&#xff1a;不同运营商提供的流量卡套餐价格各异&#xff0c;从低至19元到高达199元不等。 流量大小&#xff1a;从30GB到3…

【设计模式深度剖析】【8】【行为型】【备忘录模式】| 以后悔药为例加深理解

&#x1f448;️上一篇:观察者模式 设计模式-专栏&#x1f448;️ 文章目录 备忘录模式定义英文原话直译如何理解呢&#xff1f; 3个角色1. Memento&#xff08;备忘录&#xff09;2. Originator&#xff08;原发器&#xff09;3. Caretaker&#xff08;负责人&#xff09;类…

使用 Python 进行测试(1)测试基础

原文 总结 我们将从unittest开始&#xff0c;尽管它并不那么好用&#xff0c;但它是Python标准库中的测试工具。 使用unittest编写测试看起来像这样&#xff1a; import unittest# 需要测试的代码 def add(a, b):return a b# The tests class TestAddFunction(unittest.Test…

拦截器 之 用户登录判断

spring boot 拦截器的实现需要有两步&#xff1a; 自定义一个拦截器 package com.example.demo.common;import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; import org.springfra…

Golang——gRPC gateway网关

前言 etcd3 API全面升级为gRPC后&#xff0c;同时要提供REST API服务&#xff0c;维护两个版本的服务显然不大合理&#xff0c;所以gRPC-gateway诞生了。通过protobuf的自定义option实现了一个网关。服务端同时开启gRPC和HTTP服务&#xff0c;HTTP服务接收客户端请求后转换为gr…

SAP HANA1709~2023版本Fiori激活简介

SAP Fiori 是一个设计系统,使您能够创建具有消费者级别用户体验的业务应用,通过在任何设备上运行,可以在Ipad或者是手机端都可以随时随地的使用SAP,现在越来越多的公司都在使用Fiori系统,公司高层可以更直观的在移动端设备中查看各种数据。 本文主要说明HANA版本怎么激活F…

直流放大器

一&#xff0c;概念及存在问题 集成电路主要由半导体材料构成&#xff0c;其内部适合用二极管&#xff0c;三极管等类型的元器件制作&#xff0c;而不适用电容&#xff0c;电感和变压器&#xff0c;因此集成放大电路内部多个放大电路之间通常采用直接耦合。直接耦合电路除了可…

牛客热题:兑换零钱(一)

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 牛客热题&#xff1a;兑换零钱(一)题目链接方法一&am…

基于WPF技术的换热站智能监控系统03--实现左侧加载动画

1、左侧布局规划 左侧分5行&#xff0c;每行的高度通过height属性来指定&#xff0c;1.2*表示占1.2倍的宽度 2、创建用户控件 在WPF中想要进行个性化处理&#xff0c;主要可以通过三个方面来实现&#xff1a;控件模板&#xff08;控件模板、数据模板、数据容器模板&#xff09…

【Webpack】使用 Webpack 构建 Vue3+TS 项目

构建项目目录 tsc --init npm init -yshim.d.ts 文件是一个类型声明文件&#xff0c;用于告诉 TypeScript 编译器如何处理 Vue 的单文件组件&#xff08;SFC&#xff09;和其他自定义模块。为 Vue 的单文件组件和其他非 TypeScript 模块提供类型信息&#xff0c;以便在 TypeScr…

Web期末复习指南(2w字总结)

前言&#xff1a;本文旨在梳理Web技术常包含的内容&#xff0c;阅读完整篇文章后会对整体有个系统的认知&#xff0c;从前端的HTML到后端的MySql&#xff0c;对于大概试题中可能会涉及的地方都有所分析&#xff0c;通篇提供了许多代码案例&#xff0c;供读者更好的理解。对于一…

FPGA - 全局时钟资源

全局时钟资源是指FPGA内部为实现系统时钟到达FPGA内部各 CLB、IOB&#xff0c;以及BSRAM&#xff08;Block Select RAM&#xff0c;选择性BRAM&#xff09;等基本逻辑单元的延时和抖动最小化&#xff0c;采用全铜层工艺设计和实现的专用缓冲与驱动结构。 由于全局时钟资源的布线…

OpenGL3.3_C++_Windows(5)

变换 && 3D空间的2D图形 /\/\/\/\/\//\/\/\/\/\/\/\/\//\/\///\/\/\/\//\/\/\/\//\//\/\/\/\/\\/GLM库从0.9.9版本起&#xff0c;默认会将矩阵类型初始化为一个零矩阵&#xff08;所有元素均为0&#xff09;&#xff0c;而不是单位矩阵&#xff08;对角元素为1&#…

从踢足球到数字孪生

前言 贵州“村超”的火热现象是一个多方面因素共同作用的结果,它不仅是一场体育赛事,更是一个文化现象,反映了时代的精神和人民的情感诉求,同时也推动了乡村振兴和地区发展。足球的魅力是多方面的,它不仅仅是一项运动,更是一种全球性的文化现象。 简单规则下的无限变化:…

Java注解Annotation机制说明和基础使用(为什么Annotation直接促进了框架的繁荣发展?)

一、注解解决的问题【可忽略】 软件开发过程中&#xff0c;如何配置一直是一个重要的问题&#xff0c;对于一个框架&#xff0c;如果你不为它提供初始结构&#xff0c;它就无法理解你要做什么&#xff0c;自然无法工作。 1.问题&#xff1a;紧密贴合的代码和配置 在很久之前…