这篇文章是对webrtc 中Nack包发送机制的梳理,主要包括三个部分:
第一部分,介绍RTCP包中,Nack包的规范。
第二部分,介绍在WEBRTC中,Nack发送机制的数据流程图。
第三部分,介绍在WEBRTC中,Nack处理的一些关键的代码。

一:RTCP Nack报文解析

    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|V=2|P|   FMT   |       PT      |          length               |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                  SSRC of packet sender                        |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|                  SSRC of media source                         |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+:            Feedback Control Information (FCI)                 ::              Feedback message type (FMT): 5 bits0:    unassigned1:    Generic NACK2-30: unassigned31:   reserved for future expansion of the identifier number spacePayload type (PT): 8 bitsThis is the RTCP packet type that identifies the packet as beingan RTCP FB message.  Two values are defined by the IANA:Name   | Value | Brief Description----------+-------+------------------------------------RTPFB  |  205  | Transport layer FB messagePSFB   |  206  | Payload-specific FB messagessrc packet sender: 构造发送当前消息包的端的SSRCssrc source:  NACK消息部分,也是SSRC值,在此可称为媒体源标识符The Feedback Control Information (FCI) field has the following Syntax0                   1                   2                   30 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|            PID                |             BLP               |+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

参考链接:rfc4585

  • 如果是一个NACK message

    • PT=RTPFB

    • FMT=1

    • 丢包为10,20,30,40,50。用3个int可以表示清楚,用rfc 4585的通用协议表示如下

        Real-time Transport Control Protocol (Generic RTP Feedback): NACK: 2 frames lost: NACK: 2 frames lost: NACK: 1 frames lost10.. .... = Version: RFC 1889 Version (2)..0. .... = Padding: False...0 0001 = RTCP Feedback message type (FMT): Generic negative acknowledgement (NACK) (1)Packet type: Generic RTP Feedback (205)Length: 5 (24 bytes)Sender SSRC: 0x00123456 (1193046)Media source SSRC: 0x00c0ffed (12648429)RTCP Transport Feedback NACK PID: 10RTCP Transport Feedback NACK BLP: 0x0200 (Frames 20 lost)RTCP Transport Feedback NACK PID: 30RTCP Transport Feedback NACK BLP: 0x0200 (Frames 40 lost)RTCP Transport Feedback NACK PID: 50RTCP Transport Feedback NACK BLP: 0x0000 (No additional frames lost)
      

      PID为10,表示sequence为10的包,BLP的第10位为1,表示10之后第10个包,即sequence num为20的包,所以一个int可以表示17个连续包的丢包情况。

二:Nack包发送流程图

三:Nack在webrtc中的计算

VideoStream接收端的处理

  • 添加Nack 包到nack_list_中去

       void NackModule::AddPacketsToNack(uint16_t seq_num_start,uint16_t seq_num_end) {// Remove old packets.auto it = nack_list_.lower_bound(seq_num_end - kMaxPacketAge);nack_list_.erase(nack_list_.begin(), it);// If the nack list is too large, remove packets from the nack list until// the latest first packet of a keyframe. If the list is still too large,// clear it and request a keyframe.uint16_t num_new_nacks = ForwardDiff(seq_num_start, seq_num_end);if (nack_list_.size() + num_new_nacks > kMaxNackPackets) {while (RemovePacketsUntilKeyFrame() &&nack_list_.size() + num_new_nacks > kMaxNackPackets) {}if (nack_list_.size() + num_new_nacks > kMaxNackPackets) {nack_list_.clear();LOG(LS_WARNING) << "NACK list full, clearing NACK"" list and requesting keyframe.";keyframe_request_sender_->RequestKeyFrame();return;}}//在Start 和 End之间的RTP包,就是需要发Nack的包。for (uint16_t seq_num = seq_num_start; seq_num != seq_num_end; ++seq_num) {NackInfo nack_info(seq_num, seq_num + WaitNumberOfPackets(0.5));RTC_DCHECK(nack_list_.find(seq_num) == nack_list_.end());nack_list_[seq_num] = nack_info;}}
    
  • 根据不同的kSeqNumOnly, kTimeOnly模式,来选择需要重发的包

      std::vector<uint16_t> NackModule::GetNackBatch(NackFilterOptions options) {bool consider_seq_num = options != kTimeOnly;bool consider_timestamp = options != kSeqNumOnly;int64_t now_ms = clock_->TimeInMilliseconds();std::vector<uint16_t> nack_batch;auto it = nack_list_.begin();while (it != nack_list_.end()) {if (consider_seq_num && it->second.sent_at_time == -1 &&AheadOrAt(newest_seq_num_, it->second.send_at_seq_num)) {nack_batch.emplace_back(it->second.seq_num);++it->second.retries;it->second.sent_at_time = now_ms;if (it->second.retries >= kMaxNackRetries) {LOG(LS_VERBOSE) << "Sequence number " << it->second.seq_num<< " removed from NACK list due to max retries."<< " newest_seq_num " << newest_seq_num_<< " it->second.send_at_seq_num " << it->second.send_at_seq_num;it = nack_list_.erase(it);} else {++it;}continue;}if (consider_timestamp && it->second.sent_at_time + rtt_ms_ <= now_ms) {nack_batch.emplace_back(it->second.seq_num);++it->second.retries;it->second.sent_at_time = now_ms;if (it->second.retries >= kMaxNackRetries) {LOG(LS_VERBOSE) << "Sequence number " << it->second.seq_num<< " removed from NACK list due to max retries."<< " rtt_ms " << rtt_ms_;it = nack_list_.erase(it);} else {++it;}continue;}++it;}return nack_batch;}
    

VideoSendStream端的处理

  • 收到OnReceivedNack事件

      int32_t RTPSender::ReSendPacket(uint16_t packet_id, int64_t min_resend_time) {// 根据RTT,去从队列里找到还能发送的RTP包std::unique_ptr<RtpPacketToSend> packet =packet_history_.GetPacketAndSetSendTime(packet_id, min_resend_time, true);if (!packet) {// Packet not found.LOG(LS_VERBOSE) << "ResendPacket packet not found "<< " pktid " << packet_id<< " min_resend_time " << min_resend_time;return 0;}。。。。。。if (paced_sender_) {// Convert from TickTime to Clock since capture_time_ms is based on// TickTime.int64_t corrected_capture_tims_ms =packet->capture_time_ms() + clock_delta_ms_;// 添加到Pace Sender里去发送    paced_sender_->InsertPacket(RtpPacketSender::kNormalPriority,packet->Ssrc(), packet->SequenceNumber(),corrected_capture_tims_ms,packet->payload_size(), true);。。。。。。
    

WEBRTC浅析(五)视频Nack包的发送判断逻辑以及数据流相关推荐

  1. 10没有基于策略的qos_WebRTC QoS | NACK 格式与发送策略

    本文是 WebRTC QoS 第 1 篇 导读 10.20.100.1000.10000 策略 1,10 次 策略 2,20 毫秒 策略 3,100 毫秒 策略 4,1000 个(丢失包数量) 策略 ...

  2. WebRTC 教程五:WebRTC搭建视频聊天室

    这篇文章主要介绍了 WebRTC 聊天室的整体演示,以及 WebRTC 视频聊天的功能设计,代码逻辑以及整体演示. 目录 WebRTC 聊天室:总体演示 WebRTC 视频聊天: 设计 WebRTC ...

  3. android webrtc学习五(webrtc视频数据传递和切换摄像头问题处理)

    android webrtc学习五(webrtc视频数据传递和切换摄像头问题处理) Android webrtc摄像头流程分析 1.打开摄像头 2.获取流数据 摄像头切换 问题场景:在使用华为手机(忘 ...

  4. 使用WebRTC搭建前端视频聊天室——数据通道篇

    转自 使用WebRTC搭建前端视频聊天室--数据通道篇 在两个浏览器中,为聊天.游戏.或是文件传输等需求发送信息是十分复杂的.通常情况下,我们需要建立一台服务器来转发数据,当然规模比较大的情况下,会扩 ...

  5. WebRTC 系列之视频辅流

    导读:近几年,实时音视频领域越来越热,业界很多音视频引擎都是基于 WebRTC 进行实现的.本文主要介绍 WebRTC 在视频辅流上的需求背景以及相关技术实现. 文|陶金亮 网易云信资深客户端开发工程 ...

  6. 使用WebRTC搭建前端视频聊天室——点对点通信篇

    转载自:使用WebRTC搭建前端视频聊天室--点对点通信篇 WebRTC给我们带来了浏览器中的视频.音频聊天体验.但个人认为,它最实用的特性莫过于DataChannel--在浏览器之间建立一个点对点的 ...

  7. 【复】基于 WebRTC 的音视频在线监考模块的设计与实现(上)

    文章目录 前言 什么是 WebRTC? WebRTC 架构 WebRTC 通讯内容 WebRTC 通讯协议 WebRTC 连接建立过程 后记 前言 最近在做关于考试系统的项目,其中有一项需求分析是要做 ...

  8. 使用WebRTC搭建前端视频聊天室——信令篇

    转载自:使用WebRTC搭建前端视频聊天室--信令篇 建议看这篇之前先看一下使用WebRTC搭建前端视频聊天室--入门篇 如果需要搭建实例的话可以参照SkyRTC-demo:github地址 其中使用 ...

  9. 基于WebRTC实现音视频及数据通信

    文章目录 前言 一.WebRTC的组成? 二.信令交换的方式 三.会话描述 四.客户端应用 1.HTML 2.JavaScript 五.效果演示 六.项目地址 总结 前言 刚写了篇基于WebRTC使用 ...

  10. 智能会议系统(10)---WebRtc在H5视频聊天

    基于WebRtc在H5视频聊天.视频教学.视频会议.视频直播.白板互动低延时方案 随移动互联应用加快,4G,5G网络上马,低延时网络视频应改越来越走近生活,在教学,会议,在线医疗,招聘交友及时视频要求 ...

最新文章

  1. Java Web开发中文乱码问题
  2. 智能合约重构社会契约 (1)李嘉图合约
  3. STL中的priority_queue(优先队列)
  4. 直播预告 | TCCI追问研讨会第二期:双向脑机接口如何实现?
  5. CAS服务下单点登录(服务端与客户端)
  6. 初谈逻辑读、物理读、预读
  7. LibreOffice、OpenOffice 漏洞可导致黑客欺骗已签名文档
  8. NettyMina (转)
  9. 谷歌地图网页版_安卓版谷歌地图新增专用的街景图层
  10. IOS人脸识别开发入门教程--人脸检测篇
  11. 优维EasyOps,打造新一代运维新方式
  12. MyBatis 的基本工作原理
  13. Hive —— Design and Architecture
  14. Excel如何将多个工作簿合并到一个工作簿中
  15. 2022-2028全球与中国智能家居安全市场现状及未来发展趋势
  16. 李彦宏:没有妻子就没有百度
  17. tag untag pvid 理解
  18. 肖邦圆舞曲14首 个人赏析
  19. 收集各种文章资料的URL 不断更新
  20. 安卓c语言assets,Android Studio神器之Vector Asset

热门文章

  1. HTML5+CSS期末大作业:明星主页介绍(7页) 简约个人网页制作 大学生个人网页设计模板 学生个人博客网页成品 简单个人网站作品下载 静态HTML CSS个人网页作业源代码
  2. 小程序页面跳转的几种方式
  3. python求残差_在python中如何计算点过程的残差
  4. 关于androidstudio获取shal的总结
  5. shal+php,学习笔记---PHP中几种加密算法(MD5,shal,base64_encode等)
  6. codeforces 558 D Guess Your Way Out! II
  7. DNS域名详细解析过程(最全面,看这一篇就够)
  8. 利用FFmpeg合并音频和视频
  9. PushMall推贴共享电商十二月更新计划
  10. python邮箱格式验证_学会使用正则表达式——验证邮箱地址格式