webrtc QOS方法一(NACK实现)

article/2025/10/6 16:31:29

        一:概述

       NACK则在接收端检测到数据丢包后,发送NACK报文到发送端;发送端根据NACK报文中的序列号,在发送缓冲区找到对应的数据包,重新发送到接收端。NACK需要发送端发送缓冲区的支持,RFC5104[2]定义NACK数据包的格式。

        1 NACK框架

1.1 NACK介绍

        与NACK对应的是ACK,ACK是到达通知技术。以TCP为例,他可靠因为接收方在收到数据后会给发送方返回一个“已收到数据”的消息(ACK),告诉发送方“我已经收到了”,确保消息的可靠。

        NACK也是一种通知技术,只是触发通知的条件刚好的ACK相反,在未收到消息时,通知发送方“我未收到消息”,即通知未达。

        在rfc4585协议中定义可重传未到达数据的类型有二种:

        1 RTPFB:rtp报文丢失重传。

        2 PSFB:指定净荷重传,指定净荷重传里面又分如下三种:

        1) PLI(Picture Loss Indication)视频帧丢失重传。

        2)SLI(Slice Loss Indication)slice丢失重转。

         3)RPSI(Reference Picture Selection Indication)参考帧丢失重传。 

        在创建视频连接的SDP协议里面,会协商以上述哪种类型进行NACK重转。以webrtc为例,会协商两种NACK,一个rtp报文丢包重传的nack(nack后面不带参数,默认RTPFB)、PLI 视频帧丢失重传的nack。

        

      二、定义

class NackStructor {public:uint32_t version :2;      //协议版本号(2bit)uint32_t padding :1;      //是否有填充(1bit)可理解为是否有其他跟随或补充信息在消息中                                                                 uint32_t fmt :5;          //(5bit)在不同消息中叫法不同,也叫blockcount或RC,此处指格式 //format,在NACK消息中此值为1,之所以同时具有fmt和packettype//是因为某些消息存在多级类型,比如当前的NACK消息属于Feedback//类型。因此fmt=1(Feedback).uint32_t packettype :8;   //包类型(8bit),NACK消息类型值为205,Feedback子类型                                           uint32_t length :16;      //(16bit)消息长度                                             uint32_t ssrc;            //构造发送当前消息包的端的SSRC,若本端是此NACK包的发送者,此//SSRC值就是本端的SSRC值(源标识符)uint32_t ssrcsource;      //NACK消息部分,也是SSRC值,在此可称为媒体源标识符,用来指明//此消息要反鐀谁的情况。比如我是接收端,我知道发送端的音频流//(SSRC:1234)给我发来的数据包有丢包,我要反鐀对方音频流的//情况,那这个地方就应该填写1234(对方音频流SSRC)。uint32_t pid:16;          //packet id(sequence number)详见下面PID-BLP图                                           uint32_t blp:16;
};

         在一个消息的一个公用头后面的NACK块部分可以有多个,每个NACK块可以反馈1个流(SSRC)的情况。当然 //1个NACK块中的blp部分也可以有多个。

         1.3 NACK通信过程

         NACK作为RTP层反馈参数,和Video Codec联系在一起。WebRTC在初始化阶段,创建call会话时,会收集本端支持的所有Video Codec,NACK作为Codec的属性被一起收集。在接下来的SDP协商过程中,NACK属性被协商到Offer/Answer中。

        webRTC在评估到收发端之间RTT延迟比较小的时候会采用NACK来进行丢包补偿,NACK是一个请求重发过程,其流程如下图所示。这个过程有一个问题是在网络抖动和丢包很厉害的情况下有可能造成同一时刻收到很多NACK的重传请求,发送端瞬间把这些重传请求放入pacer中进行重发,这样pacer的延迟会增大,而且pace的参考码率会随着pace queue的延迟控制变的很大而出现间歇性网络风暴。WebRTC在处理NACK重传时设计了一个重传码率控制器,其设计原理是通过统计单位时间窗口周期中发送的字节数据来限流,如果这个时间窗内发送的数据的码率大于estimator评估的码率,不进行当前NACK请求的重传,等待下一个NACK。

        

        1.4 WebRTC NACK算法实现

        新的WebRTC的NACK算法构建NACKList的方式不同。

         1)call启动,并接收rtp包;

        2 )rtp包头部解析,并转发给具体的编码格式解析具体编解码参数信息;

        3) vi_channel 开启线程,jitterbuffer对数据包进行处理、数据帧获取、数据包插入,数据包重排等操作;jitterbuffer进行插包处理,同时进行NACKList构建;

        每次进行插包处理时,都将接收到数据包序列号和之前已经保存的最新序列号latest_received_sequence_number进行比对:如果不是新的数据包,则从missing_sequence_numbers中剔除;如果是新的数据包,则进行NACK构建,以上次保存的序列号+1为起始值,以新收到的序列号为结束,将之间的序列号先缓存到missing_sequence_numbers中;

        插入该序列号完成后,需要判断当前missing_sequence_numbers是否过大、是否收到的序列号是否太旧,并进行NACKList过大、序列号过久等处理;完成NACKList瘦身;

        判断并更新当前序列号为latest_received_sequence_number;

        这样每次接受到一个数据包,都可以形成一个较小的NACK List;

        4) vi_channel开启重传线程,jitterbuffer进行NACK获取,得到NACKlist通过rtcp反馈给发送端,进行数据包重发;

        5)这时只需要从missing_sequence_numbers中获取当前的NACK列表即可,可以保证是最新的NACK请求列表。

三、实现

        webrtc支持RTPFB和PLI FB两种重传方式。

1 RTPFB实现

        RTPFB在JB里面实现。通过RTP报文的序列号和时间戳,判断是否出现丢包异常。参考NackTracker类实现。

-->PlatformThread::StartThread
->PlatformThread::Run
->ProcessThreadImpl::Run
->ProcessThreadImpl::Process
->PacedSender::Process
->PacedSender::SendPacket
->PacketRouter::TimeToSendPacket
->ModuleRtpRtcpImpl::TimeToSendPacket
->RTPSender::TimeToSendPacket
->RtpPacketHistory::GetPacketAndSetSendTime
->RtpPacketHistory::GetPacket
        接收端有两种方式驱动方式NACK

1)收包驱动 

         DeliverPacket
->DeliverRtp
->RtpStreamReceiverController::OnRtpPacket
->RtpDemuxer::OnRtpPacket
->RtpVideoStreamReceiver::OnRtpPacket
->RtpVideoStreamReceiver::ReceivePacket
->RtpReceiverImpl::IncomingRtpPacket
->RTPReceiverVideo::ParseRtpPacket
->RtpVideoStreamReceiver::OnReceivedPayloadData
->NackModule::OnReceivedPacket
->VideoReceiveStream::SendNack
->RtpVideoStreamReceiver::RequestPacketRetransmit
->ModuleRtpRtcpImpl::SendNack

2)定时驱动

        NackModule::Process

2 PLI FB实现 

        PLI FB在webrtc里面实现的是请求关键帧。当连续出现解码失败,或者长期没有解码输入,就通过RTCP报文发送请求IDR帧命令。参考VideoReceiveStream::Decode、RequestKeyFrame这两个函数实现。

        


http://chatgpt.dhexx.cn/article/kHm3hxPd.shtml

相关文章

认识网络通信中的 ACK、NACK 和 REX

ACK、NACK、 REX在面试或者网络通信的时候,我们可能经常听到和遇到。今天就来详细介绍一下ACK、NACK、 REX。 认识ACK、NACK、 REX ACK:Acknowledgement,它是一种正向反馈,接收方收到数据后回复消息告知发送方。NACK&#xff1a…

WebRTC之NACK、RTX 在什么时机判断丢包发送NACK请求和RTX丢包重传

WebRTC之NACK、RTX 在什么时机判断丢包发送NACK请求和RTX丢包重传 WebRTC之NACK、RTX 在什么时机判断丢包发送NACK请求和RTX丢包重传 WebRTC之NACK、RTX 在什么时机判断丢包发送NACK请求和RTX丢包重传前言一、NACK与RTX的作用1、NACK/RTX的工作机制的流程图2、NACK/RTX涉及到的…

WebRTC 的音频弱网对抗之 NACK

本文梳理 WebRTC 的音频弱网对抗中的 NACK 机制的实现。音频的 NACK 机制在 WebRTC 中默认是关闭的,本文会介绍开启 NACK 机制的方法。 在网络数据传输中,NACK (NAK,negative acknowledgment,not acknowledged) 是数据接收端主动…

流媒体弱网优化之路(NACK)——纯NACK方案的优化探索

流媒体弱网优化之路(NACK)——纯NACK方案的优化探索 —— 我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost目标:可以让大家熟悉各类Qos能力、带宽估计能力,提供每个环节关键参数调节接口并实现一个json全配置&#xff…

WebRTC源码分析 nack详解

1、Nack过程 1.1 nack是什么 丢包重传(NACK)是抵抗网络错误的重要手段。NACK在接收端检测到数据丢包后,发送NACK报文到发送端;发送端根据NACK报文中的序列号,在发送缓冲区找到对应的数据包,重新发送到接收端。NACK需要发送端&am…

谈谈网络通信中的 ACK、NACK 和 REX

目录 名词解释 问题 1: 接收方如何判断数据包是否丢失? 问题 2:发送方如何确认数据包已经丢失? 问题 3:重传超时的计算规则? 问题 4:发送方的数据包要缓存多久? 问题 5&#x…

费马定理_高数_1元微积分

定理 设 f(x) 在 x0 点处满足:1、可导 2、取得极值,则有 f ’ (x0)0 证明 不妨假设 f(x) 在点 x0 处取得极大值,则存在 x0 的邻域 U( x0 ),对任意的 x属于U( x0 ),都有 根据导数定义与极限的保号性有 又 f(x) 在点…

老猿Python博客文章目录索引

本目录提供老猿Python所有相关博文的一级目录汇总,带星号的为付费专栏: 一、专栏列表 本部分为老猿所有专栏的列表,每个专栏都有该专栏置顶的博文目录: Python基础教程目录PyQt入门学习* 使用PyQt开发图形界面Python应用PyQtmo…

(组合数+快速幂+lucas+费马小引理)acwing 887. 求组合数 III

887. 求组合数 III 题目链接https://www.acwing.com/problem/content/889/ 题目&#xff1a; 思路&#xff1a; #include<iostream> #include<cstdio> using namespace std; typedef long long LL; int n; int qmi(LL a,int k,int p){int res1;while(k){if(k&…

(组合数 +快速幂+逆元+费马小引理)acwing 886. 求组合数 II

886. 求组合数 II 题目链接https://www.acwing.com/problem/content/888/ 题目&#xff1a; 思路&#xff1a; #include<iostream> #include<cstdio> using namespace std; typedef long long LL; const int mod1e97;//mod为质数 int a,b,n; int fact[100010],…

Leetcode-数学费马平方和定理-633. 平方数之和

题目633. 平方数之和&#xff1a; 题解&#xff1a; 1&#xff0c;暴力枚举sqrt class Solution { public:bool judgeSquareSum(int c) {if(c < 2 ){return true;}for(long a 0; a*a < c; a){double b sqrt(c - a * a);if((int)b b){return true;}}return false;} …

费马定理、罗尔中值定理、零点存在定理、拉格朗日中值定理、

介值定理 介值定理如果AB,则开区间&#xff08;a,b&#xff09;内可能取不到端点值A,B 即介值定理如果C不等于端点值&#xff0c;那么 ξ ξ ξ可以是属于开区间&#xff0c;如果C等于端点值&#xff0c;那么 ξ ξ ξ必须属于闭区间。 零点存在定理 假设函数f(x)在闭区间[a,…

费马引理的证明

设 f(x)在 ξ处最大&#xff0c;故不论Δx是正或负&#xff0c;总有 设 &#xff0c; 则 。 故由极限的保号性有 &#xff08;1&#xff09; 而当 时&#xff0c; &#xff0c; 故 &#xff08;2&#xff09; 由(1)&#xff0c;(2)两式及 存在知&#xff0c;必有 设 f(x)在 ξ处…

费马引理

转载于:https://www.cnblogs.com/fuhang/p/7976329.html

高等数学——微分中值定理

本文始发于个人公众号&#xff1a;TechFlow&#xff0c;原创不易&#xff0c;求个关注 今天和大家回顾一下高数当中的微分中值定理&#xff0c;据说是很多高数公式的基础。由于本人才疏学浅&#xff0c;所以对于这点没有太深的认识。但是提出中值定理的几个数学家倒是如雷贯耳&…

(机器学习、人工智能数学基础:高等数学篇)第三章:微分中值定理:第一节:微分中值定理

文章目录 一&#xff1a;费马引理二&#xff1a;罗尔定理三&#xff1a;拉格朗日中值定理四&#xff1a;柯西中值定理五&#xff1a;泰勒公式&#xff08;1&#xff09;泰勒公式&#xff08;2&#xff09;常见泰勒展开式 一&#xff1a;费马引理 费马引理&#xff1a;如果函数…

高等数学(总结1-导数的几个定理)

1&#xff09;费马引理&#xff1a; 证明的关键&#xff1a;如果在x0处可导&#xff0c;则在x0处的左导数等于右导数等于导数。 意义&#xff1a;显然(x0&#xff0c;f(x0))是f(x)在x0邻域内的一个极值点&#xff0c;推广&#xff1a;f(x)的极值点&#xff08;驻点&#x…

人工智能数学基础:费马引理、罗尔定理、拉格朗日微分中值定理、柯西中值定理

一、费马&#xff08;Fermat&#xff09;引理 费马&#xff08;Fermat&#xff09;引理&#xff1a;设函数f(x)在点x0的某邻域U(x0)内有定义&#xff0c;并且在x0处可导&#xff0c;如果对任意的x∈U(x0)&#xff0c;有f(x)≤f(x0)(或f(x)≥f(xo))&#xff0c;那么f’(x0)0。 …