【网络通信 -- WebRTC】FlexFec 基本知识点总结概述

【网络通信 -- WebRTC】FlexFec 基本知识点总结概述

【1】FlexFec 的保护方案

假设存在一组源数据包(D × L),其序列号从 1 开始运行到 D × L

  • 一维非交错行 FEC(1-D Non-interleaved Row FEC) : 一种连续的源数据包进行保护的方案,可用于恢复按行分组的源数据包中一个丢失的数据包
    • 每 L 个连续的源数据包通过 "异或" 计算生成一个修复数据包,最终可生成 D 个修复数据包  

 

  • 一维交错列 FEC(1-D Interleaved Column FEC) : 一种对交错的源数据包进行操作的保护方案,可用于恢复按列分组的源数据包中一个丢失的数据包
    • 对序列号间隔 L 的一组源数据包进行 "异或" 计算生成一个修复数据包,最终可生成 L 个修复数据包

 

  • 二维 FEC(2-D FEC) : 融合行和列的保护方案
    • 同时对 D × L 个源数据包进行上述两种操作以生成对应的修复数据包

说明 : 在对应分组的源数据包中仅存在一个数据包丢失时,可以对丢失的数据包进行恢复处理,换言之若对应分组的源数据包的丢包数量大于 1 则恢复处理会失败

【2】FlexFec 保护失败的场景

  • 一维非交错行 FEC(1-D Non-interleaved Row FEC)

在同一行的分组的源数据包中出现两个以上的丢包则恢复失败

  • 一维交错列 FEC(1-D Interleaved Column FEC)

在同一列分组的源数据包中出现两个以上的丢包则恢复失败

  • 二维 FEC(2-D FEC)

至少存在两个按行分组的源数据包/FEC数据包丢包两个以上,并且丢失的数据包在列维度上是对齐的,则恢复失败

至少存在两个按列分组的源数据包/FEC数据包丢包两个以上,并且丢失的数据包在行维度上是对齐的,则恢复失败

【3】FlexFec 数据包格式

【3.1】FlexFec 数据包 -- 整体构成

FlexFec 数据包的整体构成如下图,包含 RTP 数据包头 + RTP 数据包载荷(FEC 数据包头 + 修复载荷)

【3.2】FlexFec 数据包 -- FEC 数据包头

  • R,F : 用于决定 FlexFec 数据包头的格式
  • Padding(P) bit : 表示数据包是否包含可选的填充字节
  • Extension(X) bit : 表述数据包是否包含头部扩展
  • CSRC Count(CC) 4 bit : CSRC 列表中元素个数
  • Marker(M) bit : 标志位,对当前载荷无效,发送者应设置为 0,接收者可以忽视
  • PT recovery : 载荷类型

【3.2.1】弹性 FEC 掩码标识源数据包 -- R = 0,F = 0

  • length recovery (16 bits) : 恢复数据包的长度,该长度包括除了固定 12 字节的 RTP 头之外的长度
  • TS recovery (32 bits) : 恢复数据包时间戳
  • CSRC_i (32 bits) [包含于 RTP 头中] : 描述该 FEC 数据包保护的源数据包的 SSRC 信息,若该 FEC 数据包保护多个 SSRC,则将会存在多个 SN base 以及 Mask
  • SN base_i (16 bits) : 由该 FEC 数据包保护的对应 SSRC 的一系列源数据包的最小序列号
  • Mask : 掩码,标识由该 FEC 保护的数据包,若第 j 位置 1 表示保护序列号为 SN base_i + j 的源数据包
  • k : 若 k = 1 表示后面跟随其他掩码,k = 0 表示最后一个掩码
  • Repair Payload : 根据固定 12 字节的 RTP 头之后的数据计算得到

【3.2.2】固定 FEC 行/列(L/D)标识源数据包 -- R = 0,F = 1

  • length recovery (16 bits) : 恢复数据包的长度,该长度包括除了固定 12 字节的 RTP 头之外的长度
  • TS recovery (32 bits) : 恢复数据包时间戳
  • CSRC_i (32 bits) [包含于 RTP 头中] : 描述该 FEC 数据包保护的源数据包的 SSRC 信息,若该 FEC 数据包保护多个 SSRC,则将会存在多个 SN base 以及 Mask
  • SN base_i (16 bits) : 由该 FEC 数据包保护的对应 SSRC 的一系列源数据包的最小序列号
  • L/D 取值说明
    • L = 0,D = 0 : 保留
    • L > 0,D = 0 : 行 FEC 不跟随列 FEC (1D)
      • 每行保护的源数据包 SN,SN + 1,...,SN + (L - 1)
    • L > 0,D = 1 : 行 FEC 跟随列 FEC (2D)
      • 每行保护的源数据包 SN,SN + 1,...,SN + (L - 1)
      • 每列保护的源数据包 SN,SN + L,...,SN + (D - 1) * L
    • 当行 FEC 数据包发送完毕再发送列 FEC 数据包
      • L > 0,D > 1 : 列 FEC 数据包重复 D 次
      • 每列保护的源数据包 SN,SN + L,...,SN + (D - 1) * L

 注意 : 上图中的描述有些不太理解,D=1时应该不会存在按列保护的源数据包吧

【4】FlexFec 的 SDP 协商

【4.1】SDP 信令交互基本要求

  • 决定是否发送一个/多个 RTP 流
  • 决定是否发送一个/多个修复 RTP 流
  • 明确源流与修复流 SSRC 的关联关系
  • 明确 SSRC 与源流的关系
  • 明确修复数据包与源流的关系
  • 确保使用纠错包恢复特定 SSRC 相关的源数据

【4.2】SDP 交互示例

下图为 FlexFec SDP 交互的示例

表明存在一个视频流(ssrc:1234)以及一个 FlexFec 流(ssrc:2345),源流与修复流通过不同的 ssrc 复用,修复窗口设置为 200ms

【5】FlexFec 保护与恢复流程概述

【5.1】构造修复数据包一般流程概述

  • FEC 位串的生成过程
    • 对由该特定纠错包保护的一系列独立的源数据包的位串进行异或计算,获得对应的 FEC 包头以及有效载荷信息
    • 对生成的 FEC 包头以及有效载荷信息的位串进行奇偶校验

  • 每个源数据包的位串的组成结构
    • 16 bit : RTP 数据包头的前 16 bit
    • 16 bit : 无符号网络字节序,描述源数据包长度 - 12 字节(RTP 数据包头的固定长度)
    • 32 bit : 描述 RTP 数据包头的时间戳
    • 其他 : 固定 12 字节 RTP 数据包头之后的所有字节

  • 根据 FEC 位串生成 FEC 数据包头以及载荷的过程
    • FEC Header 2 bit : 根据格式选择适当的 R/F 的值,FEC 位串 2 bit 跳过
    • FEC Header P recovery field : FEC 位串 1 bit
    • FEC Header X recovery field : FEC 位串 1 bit
    • FEC Header CC recovery field : FEC 位串 4 bit
    • FEC Header M recovery field : FEC 位串 1 bit
    • FEC Header PT recovery field : FEC 位串 7 bit
    • FEC Header length recovery field : FEC 位串 16 bit
    • FEC Header TS recovery field : FEC 位串 32 bit
    • FEC Header SN base_i field : 由当前 FEC 数据包保护的对应 SSRC 的一系列源数据包中的最小序列号
    • FEC Header Mask 或者 L/D field : 根据 FEC 头部相关配置变量以及 FEC 与对应 SSRC 的源数据包保护关系设置
    • FEC 载荷 : FEC 位串剩余部分(包含源数据包除了 12 字节固定 RTP 数据包头的数据)

注意 : 若源数据包系列中的数据包长度不等,则短的数据包通过在末尾填充字节 0 的方式与最长的数据包补齐

【5.2】重构源数据包一般流程概述

  • 关联源数据包与纠错数据包一般流程概述
    • 使用掩码关联
      • 1. FEC 数据包头部前两个 bit 必须为 R = 0,F = 0
      • 2. 若掩码中第 i 个 bit 位为 1 则表示序列号为 N + i 的源数据包被该 FEC 纠错数据包保护,其中 N 为基准序列号(标识在 FEC 头部对应字段中)
    • 使用 L/D
      • 1. FEC 数据包头部前两个 bit 必须为 R = 0,F = 1
      • 2. 给定 FEC 纠错包 P* 其对应的源数据包判定方式如下(SN 基准的序列号)
        • 若 D <= 1 则源数据包对应行,SN,SN + 1,...,SN + (L - 1)
        • 若 D > 1 则源数据包对应列,SN,SN + L,...,SN + (D - 1) * L

  • 恢复 RTP 头部
    • 给定集合 T 则恢复其中丢失的数据包头部(数据包序列号为 SEQNUM) 一般过程概述
      • 1. 给定集合 T 中所有收到的每个源数据包生成 80 bit 的位串(RTP 数据包头 : 64 bit + lengthMinus12 : 16 bit 无符号网络字节序),记为 RTP_Head_Bit_String_i
      • 2. 给定集合 T 中的纠错数据包取其 FEC 数据包头的前 80 bit,记为 FEC_Head_Bit_String
      • 3. 计算恢复的位串,Recovery_Head_Bit_String (针对 RTP_Head_Bit_String_i 以及 FEC_Head_Bit_String 进行异或计算)
      • 4. 创建新的数据包 RTP_Recovery 包含 12 字节 RTP 数据包头,不含载荷
      • 5. RTP_Recovery 2 bit : 设置为 2,Recovery_Head_Bit_String 2 bit 跳过
      • 6. RTP_Recovery P : Recovery_Head_Bit_String 1 bit
      • 7. RTP_Recovery X : Recovery_Head_Bit_String 1 bit
      • 8. RTP_Recovery CC : Recovery_Head_Bit_String 4 bit
      • 9. RTP_Recovery M : Recovery_Head_Bit_String 1 bit
      • 10. RTP_Recovery PT : Recovery_Head_Bit_String 7 
      • 11. RTP_Recovery SN : SEQNUM
      • 12. Y : Recovery_Head_Bit_String 16 bit,转换为主机字节序,标识 RTP_Recovery 的长度 - 12
      • 13. RTP_Recovery TS : Recovery_Head_Bit_String 32 bit
      • 14. RTP_Recovery SSRC : 丢失的 RTP 数据包的 SSRC

说明 : 标红部分的文字说明有些不清楚,结合 webrtc 源码分析总结如下

  • 1. 给定集合 T 中的纠错数据包取其 FEC 数据包头部前 96 bit (RTP 数据包头固定长度 12 字节) 为 FEC_Head_Bit_String
    • 其中
      • FEC_Head_Bit_String(bit16 : bit31) 为 FEC Header length recovery field,该数据段之后需要被 SEQNUM 覆盖
      • FEC_Head_Bit_String(bit64 : bit95) 该数据段之后需要被 SSRC 覆盖
  • 2. 给定集合 T 中所有收到的每个源数据包,RTP_Head_Bit_String_i 为 RTP 数据包头(64 bit),lengthMinus12_i 为每个源数据包大小 - 12
  • 3. FEC_Head_Bit_String(bit0 : bit15) 与 RTP_Head_Bit_String_i(bit0 : bit15) 做异或运算以恢复前 16 个 bit
  • 4. FEC_Head_Bit_String(bit16 : bit31) 与 lengthMinus12_i 做异或运算以恢复丢失数据包的大小(减去 12 个字节),记为 Y
  • 5. FEC_Head_Bit_String(bit32 : bit63) 与 RTP_Head_Bit_String_i(bit32 : bit63) 做异或运算以恢复时间戳

  • 恢复 RTP 载荷(此处载荷标识除了 RTP 数据包头 12 字节之后的所有数据)
    • 给定集合 T 则恢复其中丢失的数据包头部(数据包序列号为 SEQNUM) 一般过程概述
      • 1. 分配 Y 字节大小的空间
      • 2. 给定集合 T 中所有收到的每个源数据包,从第 13 字节开始,长度为 Y,组成位串 RTP_PayLoad_Bit_String_i
      • 注意 : 若根据源数据包生成的位串长度小于 Y 则通过在末尾补充 0 的方式将长度补充到 Y
      • 3. 给定集合 T 中纠错数据包,获取 FEC 数据包头之后,长度为 Y,组成位串 FEC_PayLoad_Bit_String
      • 4. 计算恢复的位串,Recovery_PayLoad_Bit_String (针对 RTP_PayLoad_Bit_String_i 以及 FEC_PayLoad_Bit_String 进行异或计算)
      • 5. 将 Recovery_PayLoad_Bit_String 设置到 RTP_Recovery 中

  • 针对二维 FEC 保护的迭代解码算法
    • 一般过程概述
      • 1. num_recovered_until_this_iteration = 0
      • 2. num_recovered_so_far = 0
      • 3. 尽可能根据非交错 FEC 恢复丢失的数据包并记录 num_recovered_so_far = 当前已经恢复的数据包
      • 4. 尽可能根据交错 FEC 恢复丢失的数据包并记录 num_recovered_so_far = 当前已经恢复的数据包
      • 5. 若 num_recovered_so_far > num_recovered_until_this_iteration 则 num_recovered_until_this_iteration = num_recovered_so_far,执行步骤 3 否则执行完毕

参考致谢
本博客为博主的学习实践总结,并参考了众多博主的博文,在此表示感谢,博主若有不足之处,请批评指正。

【1】RFC8627

【2】webrtc QOS方法二.3(flexfec rfc8627简介) 

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

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

相关文章

Linux内存管理--smaps内存

一、内存的两个概念 了解smaps内存之前要先搞清楚Linux内存管理中的虚拟内存&#xff08;Virtual Memory&#xff09;和驻留内存&#xff08;Resident Memory&#xff09;两个概念。 1、虚拟内存 首先需要强调的是虚拟内存不同于物理内存&#xff0c;虽然两者都包含内存字眼…

微信会员卡开发流程

功能需求&#xff1a; 通过微信第三方平台创建的模板小程序&#xff0c;想要实现用户在小程序支付一定金额后领取会员卡&#xff0c;领取会员卡后可给用户下发一定数量的优惠券&#xff0c;并且实现用户在小程序消费享受商品折扣。 开发流程&#xff1a; 一、了解微信的3个平…

Java高级: 反射

目录 反射反射概述反射获取类的字节码反射获取类的构造器反射获取构造器的作用反射获取成员变量&使用反射获取成员方法反射获取成员方法的作用 反射的应用案例 接下来我们学习的反射、动态代理、注解等知识点&#xff0c;在以后开发中极少用到&#xff0c;这些技术都是以后…

【动态规划刷题 14】最长递增子序列 摆动序列

673. 最长递增子序列的个数 链接: 673. 最长递增子序列的个数 给定一个未排序的整数数组 nums &#xff0c; 返回最长递增子序列的个数 。 注意 这个数列必须是 严格 递增的。 示例 1: 输入: [1,3,5,4,7] 输出: 2 解释: 有两个最长递增子序列&#xff0c;分别是 [1, 3, 4,…

[Qt]基础数据类型和信号槽

文章目录 1. Qt基本结构1.1 Qt本有项目1.1.1 项目文件&#xff08;.pro&#xff09;1.1.2 main.cpp1.1.3 mainwindow.ui1.1.4 mainwindow.h1.1.5 mainwindow.cpp 1.2 Qt中的窗口类1.2.1基础窗口类1.2.2 窗口的显示 1.3 内存回收 2. Qt中的基础数据类型2.1 基础类型2.2 log输出2…

Linux上防火墙操作

开放关闭防火墙 查看防火墙状态的命令&#xff1a;systemctl status firewalld 或者 firewall-cmd --state 暂时关闭防火墙的命令&#xff1a;systemctl stop firewalld 暂时开启防火墙的命令&#xff1a;systemctl start firewalld 永久关闭防火墙(禁用开机自启)下次启动&a…

内网穿透——Windows搭建服务器

文章目录 1.前言2. Emby网站搭建2.1. Emby下载和安装2.2 Emby网页测试 3. 本地网页发布3.1 注册并安装cpolar内网穿透3.2 Cpolar云端设置3.3 Cpolar内网穿透本地设置 4.公网访问测试5.结语 1.前言 在现代五花八门的网络应用场景中&#xff0c;观看视频绝对是主力应用场景之一&…

使用redis+lua通过原子减解决超卖问题【示例】

系列文章目录 一、SpringBoot连接MySQL数据库实例【tk.mybatis连接mysql数据库】 二、SpringBoot连接Redis与Redisson【代码】 三、SpringBoot整合WebSocket【代码】 四、使用redislua通过原子减解决超卖问题【示例】 五、SpringBoot整合Elasticsearch【代码示例】 文章目录 系…

【JavaScript内置对象】Date对象,从零开始

【JavaScript内置对象】Date对象&#xff0c;从零开始 时间的表示方式 时间表示的基本概念 最初&#xff0c;人们是通过观察太阳的位置来决定时间的&#xff0c;但是这种方式有一个最大的弊端就是不同区域位置大家使用的时间是不一致的。 相互之间没有办法通过一个统一的时间…

机器学习基础之《分类算法(6)—决策树》

一、决策树 1、认识决策树 决策树思想的来源非常朴素&#xff0c;程序设计中的条件分支结构就是if-else结构&#xff0c;最早的决策树就是利用这类结构分割数据的一种分类学习方法 2、一个对话的例子 想一想这个女生为什么把年龄放在最上面判断&#xff01;&#xff01;&…

Java时间复杂度和空间复杂度(详解)

目录 1.复杂度分析 2.时间复杂度 大O的渐进表示法 3.空间复杂度 1.复杂度分析 当我们设计一个算法时&#xff0c;怎样衡量其好坏&#xff1f; 算法在编写为可执行程序后&#xff0c;运行时需要耗费时间资源和空间&#xff08;内存&#xff09;资源。因此&#xff0c;衡量一…

java复习-线程的同步和死锁

线程的同步和死锁 同步问题引出 当多个线程访问同一资源时&#xff0c;会出现不同步问题。比如当票贩子A&#xff08;线程A&#xff09;已经通过了“判断”&#xff0c;但由于网络延迟&#xff0c;暂未修改票数的间隔时间内&#xff0c;票贩子B&#xff08;线程B&#xff09;…

SpringBoot-线程池ThreadPoolExecutor异步处理(包含拆分集合工具类)

ThreadPoolExecutor VS ThreadPoolTaskExecutor ThreadPoolTaskExecutor是对ThreadPoolExecutor进行了封装处理。 配置文件application.yml # 异步线程配置 自定义使用参数 async:executor:thread:core_pool_size: 10max_pool_size: 100 # 配置最大线程数queue_capacity: …

【css面试题】 实现一个盒子的水平竖直居中对齐效果

面试题里有时还会强调 子盒子宽高是否已知&#xff0c;要注意一下 尝试一&#xff1a;给父盒子设置padding 或者子盒子设置margin <style>.father{width: 300px;height: 200px;overflow: hidden; /* 放坑爹现象&#xff0c;不信你删了试试 */background-color: #db7b7b…

61、SpringBoot -----跨域资源的设置----局部设置和全局设置

★ 跨域资源共享的意义 ▲ 在前后端分离的开发架构中&#xff0c;前端应用和后端应用往往是彻底隔离的&#xff0c;二者不在同一个应用服务器内、甚至不再同一台物理节点上。 因此前端应用和后端应用就不在同一个域里。▲ 在这种架构下&#xff0c;前端应用可能采用前端框架&a…

【驱动开发】实现三盏灯的控制,编写应用程序测试

head.h #ifndef __HEAD_H__ #define __HEAD_H__//LED1:PE10 //LED2:PF10 //LED3:PE8#define LED_RCC 0X50000A28 //使能GPIO#define LED_MODER 0X50006000 //设置输出模式 #define LED_ODR 0X50006014 //设置输出高低电平#define LED2_MODER 0X50007000 …

JVM调优的GC日志观察解读

如果各项参数设置合理&#xff0c;系统没有超时日志出现&#xff0c;GC 频率不高&#xff0c;GC 耗时不高&#xff0c;那么没有必要进行 GC 优化 如果 GC 时间超过 1-3 秒&#xff0c;或者频繁 GC&#xff0c;则必须优化。 一、参数解读 Jvm 调优典型参数设置; -Xms: 堆内存的…

VMware vCenter 从6.7跨版本升级至7.0U3N

本文尝试使用 vCenter Server Appliance 管理界面 (VAMI) 进行对vCenter Server Appliance7应用进行小版本升级&#xff0c;从6.7.0.47000升级到7.0.3.01600&#xff08;7.0U3N&#xff09;。 一、升级前的准备工作 1、检查当前运行环境&#xff08;当前为6.7.0.47000&#x…

【办公自动化】用Python批量从上市公司年报中获取主要业务信息

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

软件测试行业已经卷到什么程度了?

近几个月经常听到IT行业的人员吐槽找工作难的事情&#xff0c;特别是找软件测试工作相比前几年难了很多&#xff0c;以前只要简历一挂网上&#xff0c;每天会接到好多个面试邀请电话&#xff0c;甚至两三天或者一周内就能把工作找好&#xff0c;而现在把简历投了个遍&#xff0…