从零开始精通RTSP之传输H265视频流

概述

        在上一篇文章中,我们详细介绍了使用RTP传输H264视频流的打包方法。接下来,我们继续介绍RTP传输H265视频流的打包方法。H265,正式名称为高效视频编码,英文全称为High Efficiency Video Coding(HEVC),是国际电信联盟视频编码专家组和国际标准化组织/国际电工委员会动态图像专家组共同开发的下一代视频编码标准。作为H264/MPEG-4 AVC的继任者,H265旨在提供更高的视频压缩效率,能够在保持相同视频质量的前提下大幅度减少视频文件的大小,或者在相同的比特率下提供显著提升的图像质量。当使用RTP传输H265视频流时,也需要遵循一定的打包和传输规则。

 

H265 NALU

        H265 NALU是H265编码视频流的基本数据单元,用于承载编码后的视频数据,并提供网络传输的抽象。NALU的设计旨在使视频编码与底层网络传输协议分离,使得H265编码的视频内容能够适应各种网络环境和应用需求。

        每个NALU都以一个固定长度的NAL Unit Header开始,NAL Unit Header占用两个字节,通常包含以下几个字段。

        Forbidden Zero Bit (F): 占1位,这一位必须为0。如果为1,则表示语法错误,整个NALU将被丢弃。

        NALU Type (Type): 占6位,定义了NALU所携带数据的类型。总共有64种可能的类型(范围是0-63),其中0-31是VCL(视频编码层)NAL单元,用于携带编码的视频数据;而32-63是非VCL NAL单元,用于携带控制信息或元数据。不同的NALU Type对应着不同的编码数据或控制信息,比如:P帧和B帧为1,IDR帧为19,VPS(Video Parameter Set)为32,SPS(Sequence Parameter Set)为33,PPS(Picture Parameter Set)为34,SEI(Supplemental Enhancement Information)为39等。

        LayerId: 占6位,用于表示NAL所在的Access Unit所属的层,是为了HEVC的继续扩展而设置的。在当前的HEVC标准中,这个字段通常被设置为0,但在未来的扩展中可能会用到。

        TID: 占3位,用于指定NAL单元的时间标识符,一般取值为1。它帮助解码器确定NAL单元在视频流中的时间位置,从而正确解码和播放视频。

        紧跟在NAL Unit Header之后的是NAL Unit Payload,包含了编码视频流的核心数据和辅助信息,是视频解码和播放的基础。在实际的网络传输和存储中,NALU通常还需要进一步封装成以下格式中的一种。

        Annex B格式:在Annex B格式中,每个NALU之前添加一个Start Code Prefix,可以是0x000001或0x00000001,用于标识NALU的起始位置。相邻NALU之间,以此方式明确分隔。

        AVCC (Advanced Video Coding Container) 格式:AVCC格式常见于MP4容器中,NALU不再使用Start Code Prefix,而是通过Length字段来标识每个NALU的长度。SPS和PPS等参数以NALU形式封装,并在MP4文件的hvcC盒(Box)中以字节串的形式存储。

 

封装方法

        H265 NALU在封装到 RTP包中时,需要遵循一定的规则和流程,以确保数据能够被正确地传输、接收和解码。根据NALU的大小和传输需求,可以选择以下三种常见的封装方法。

        1、单NALU封装。对于小型的NALU,(比如:P帧、B帧),可以直接将整个NALU放入一个RTP包的Payload中,无需额外处理。此时,RTP包的结构如下。

+-----------------------------+
| RTP Header (12 Byte)        |
| NALU Header (2 Byte)        |
| NALU Data ...               |
+-----------------------------+

        2、FU-A分包。对于大型NALU(比如:某些关键帧),如果其大小超过了RTP包的最大有效载荷MTU,可以使用Fragmentation Unit A方式进行分片。原始NALU会被拆分成多个片段,每个片段作为一个独立的RTP包发送。此时,RTP包的结构如下。

+-----------------------------+
| RTP Header (12 Byte)        |
| FU Indicator (2 Byte)       |
| FU Header (1 Byte)          |
| Fragmented NALU Data ...    |
+-----------------------------+

        可以看到,FU-A分包在12个字节的RTP Header后,有三个字节的分包头,分别为:FU Indicator和FU Header。

        FU Indicator占用两个字节,由以下部分组成。

        F (1 bit): 禁止位,与NALU Header的F位一致。

        Type (6 bits): 分包类型,二进制固定为110001(对应十进制的49),表示FU-A类型。

        LayerId (6 bits): 与NALU Header的LayerId一致。

        TID (3 bits): 与NALU Header的TID一致。

        FU Header占用一个字节,由以下部分组成。

        S (1 bit): 分包起始位。如果该FU是原始NALU的第一个片段,S设为1。否则,设为0。

        E (1 bit): 分包结束位。如果该FU是原始NALU的最后一个片段,E设为1。否则,设为0。

        Type (6 bits): 原始NALU类型,与NALU Header的Type一致,用于在重组时恢复原始NALU Header。

        3、STAP-A聚合

        对于多个小尺寸NALU,如果它们具有相近的解码时间戳,且合并后总尺寸仍小于MTU,可以使用Single-Time Aggregation Packet A方式将多个NALU合并到一个RTP包中。此时,RTP包的结构如下。

+-----------------------------+
| RTP Header (12 Byte)        |
| STAP-A Header (2 Byte)      |
| NALU Payload1 Size (2 Byte) |
| NALU Payload1               |
| NALU Payload2 Size (2 Byte) |
| NALU Payload2               |
| ...                         |
+-----------------------------+

        STAP-A Header紧跟在RTP Header之后,占用两个字节(与NALU Header结构类似),用于标识这是一个STAP-A包,其Type值固定为48。在每个聚合的NALU前,会有一个长度字段(通常为2个字节),表明后续NALU数据的长度。所有聚合在STAP-A包中的NALU都共享相同的时间戳,这是STAP-A包的一个重要特征。

        注意:无论采用上面的哪种封装方法,NALU Data或NALU Payload中都不包括Annex B格式中的起始码(比如:0x000001或0x00000001),因为RTP包已经提供了足够的信息来标识NALU的边界。

 

FU-A分包及重组

        在服务端,FU-A分包的大致步骤如下。

        1、原NALU切割: 大型NALU被拆分成多个连续的片段。切割位置通常选择在NALU内部的编码块边界,以避免破坏编码结构。

        2、片段标识: 每个片段(FU)在RTP Payload中添加一个FU Header,用于标识该片段属于哪个原始NALU,以及其在原始NALU中的位置。

        3、独立传输: 每个FU作为一个独立的RTP包发送,每个RTP包的Payload仅包含一个FU。

        客户端接收到FU-A分包的RTP包后,根据RTP Header解析出Payload Type,确认为H265 FU-A数据后,按照以下步骤处理。

        1、FU分包头解析: 提取FU Indicator和FU Header中的信息。

        2、片段重组: 将收到的FU片段按照RTP包的Sequence Number顺序重新组合,将所有片段的Fragmented NALU Data拼接在一起。

        3、NALU还原: 在重组后的NALU数据前添加原始NALU Header(根据FU分包头中的信息恢复),形成完整的NALU结构。

        4、解码处理: 将还原后的完整NALU提交给H265解码器进行解码。

        使用FU-A封装方法进行分包和重组时,有以下几点需要特别注意。

        1、顺序传输: FU-A分包的RTP包必须严格按照分包顺序发送和接收,以确保正确重组。

        2、丢包处理: 如果中间某个FU片段丢失,可能导致原始NALU无法正确重组。接收端可以根据RTP包的序列号和确认机制检测丢包,并尝试通过重传请求(比如:RTCP的NACK)恢复丢失片段。

        3、时间戳同步: 所有FU片段共享同一个解码时间戳,确保解码时的正确同步。

 

 

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

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

相关文章

企业定制AI智能名片商城小程序:重塑营销场景,引领数字化营销新纪元

在数字化时代的浪潮中,多企业AI智能名片商城小程序以其独特的魅力和创新的功能,为消费者带来了前所未有的购物体验。它不仅是一个汇聚各类商品的购物平台,更是一个充满活力和创造力的社群生态。通过强化社群互动、鼓励用户生成内容以及引入积…

【RAG 博客】Haystack 中的 DiversityRanker 与 LostInMiddleRanker 用来增强 RAG pipelines

Blog:Enhancing RAG Pipelines in Haystack: Introducing DiversityRanker and LostInTheMiddleRanker ⭐⭐⭐⭐ 文章目录 Haystack 是什么1. DiversityRanker2. LostInTheMiddleRanker使用示例 这篇 blog 介绍了什么是 Haystack,以及如何在 Haystack 框…

加州大学欧文分校英语中级语法专项课程03:Tricky English Grammar 学习笔记

Tricky English Grammar Course Certificate Course Intro 本文是学习 https://www.coursera.org/learn/tricky-english-grammar?specializationintermediate-grammar 这门课的学习笔记 文章目录 Tricky English GrammarWeek 01: Nouns, Articles, and QuantifiersLearning …

WAAP动态安全解决方案

随着企业数字化进程不断加速,应用安全面临多重威胁,新型攻击方式层出不穷,常见的攻击形式包括Web应用攻击、DDoS攻击、API攻击、恶意爬虫攻击等。企业正面临严峻的安全防护挑战,需寻找一个可靠、全面的安全解决方案。在此情况下&a…

基于双层优化的电动汽车优化调度研究(附matlab程序)

基于双层优化的电动汽车优化调度研究 0.代码链接 基于双层优化的电动汽车优化调度研究(matlab程序)资源-CSDN文库 1.简述 关键词:双层优化 选址定容 输配协同 时空优化 参考文档:《考虑大规模电动汽车接入电网的双层优化调度策略_胡文平》…

【 书生·浦语大模型实战营】学习笔记(六):Lagent AgentLego 智能体应用搭建

🎉AI学习星球推荐: GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系的学习资料,配有全面而有深度的专栏内容,包括不限于 前沿论文解读、…

Redis 实战之对象

Redis 实战 - 对象 对象的类型与编码类型编码和底层实现 字符串对象编码的转换字符串命令的实现 列表对象编码转换列表命令的实现 哈希对象编码转换哈希命令的实现 集合对象集合命令的实现 有序集合对象编码的转换有序集合命令的实现 类型检查与命令多态类型检查的实现多态命令…

嵌入式全栈开发学习笔记---C语言笔试复习大全7(编程题1~8)

目录 1、200~300之间能被3整除的数,5个一行输出; 2、求两个数的最大公约数、最小公倍数; 3、输入十个数,求出平均值; 4、通过编程实现,统计1~n有多少个9; 5、有1、2、3、4个数字&#xff0…

开源AI智能名片与B2B2C商城系统:打造私域流量的会员体系新篇章

在数字化浪潮的推动下,企业如何高效利用私域流量、构建强大的会员体系成为了市场竞争的关键。AI智能名片与B2B2C商城系统的结合,为企业提供了一个全新的解决方案。通过智能名片的个性化推荐和商城系统的精准营销,企业能够更有效地触达和沟通私…

ApiHug 官方站点

🤗 ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱,有温度,有质量,有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplacehttps://…

计算机等级考试2级(Python)知识点整理

计算机等级考试2级(Python)知识点整理 1.基础知识点(记忆、理解) 第1讲Python概述 01. 源代码 02. 目标代码 03. 编译和解释 04. 程序的基本编写方法 第2讲 Python语言基础(一) 01. 用缩进表示代码…

tomcat打开乱码修改端口

将UTF-8改成GBK 如果端口冲突,需要修改tomcat的端口

AJ-Report开源数据大屏 verification;swagger-ui RCE漏洞复现

0x01 产品简介 AJ-Report是一个完全开源的BI平台,酷炫大屏展示,能随时随地掌控业务动态,让每个决策都有数据支撑。多数据源支持,内置mysql、elasticsearch、kudu等多种驱动,支持自定义数据集省去数据接口开发,支持17+种大屏组件,不会开发,照着设计稿也可以制作大屏。三…

高级数据结构与算法习题(9)

一、判断题 1、Let S be the set of activities in Activity Selection Problem. Then the earliest finish activity am​ must be included in all the maximum-size subset of mutually compatible activities of S. T F 解析:F。设S是活动选择问题中的一…

每日OJ题_贪心算法二⑤_力扣870. 优势洗牌(田忌赛马)

目录 力扣870. 优势洗牌(田忌赛马) 解析代码 力扣870. 优势洗牌(田忌赛马) 870. 优势洗牌 难度 中等 给定两个长度相等的数组 nums1 和 nums2,nums1 相对于 nums2 的优势可以用满足 nums1[i] > nums2[i] 的索引…

EDA(一)Verilog

EDA(一)Verilog Verilog是一种用于电子系统设计自动化(EDA)的硬件描述语言(HDL),主要用于设计和模拟电子系统,特别是在集成电路(IC)和印刷电路板(…

使用OpenCV绘制两幅图验证DSC和IoU以及BCELoss的计算程序

1.创作灵感 很多小伙伴在玩深度学习模型的时候,需要计算Groudtruth和predict图的dsc、IOU以及BCELoss。这两个关键的指标的程序有很多种写法,今天使用OpenCV绘制两张已知分布的图像,计算其dsc、IOU以及BCELoss。 2、图像如图所示 在一个100100的区域内,红色框范围为预测…

访问jwt生成token404解决方法

背景: 1.在部署新的阿里云环境后发现调用jwt生成token的方法404,前端除了404,台不报任何错误 在本地好用,在老的阿里云环境好用, 2.缩短生成私钥的参数报错,以为私钥太长改了tomcat参数也无效&#xff0…

启动任何类型操作系统:不需要检索 ISO 文件 | 开源日报 No.243

netbootxyz/netboot.xyz Stars: 7.7k License: Apache-2.0 netboot.xyz 是一个方便的平台,可以不需要检索 ISO 文件就能启动任何类型操作系统或实用工具磁盘。它使用 iPXE 提供用户友好的 BIOS 菜单,让您轻松选择所需的操作系统以及特定版本或可引导标志…

华为云耀云服务器开放端口

博客主页:花果山~程序猿-CSDN博客 关注我一起学习,一起进步,一起探索编程的无限可能吧!让我们一起努力,一起成长! 目录 一.华为云控制台开放端口 寻找到安全组信息 2. 添加开放的端口信息 3. 检查是否成…
最新文章