接收方定时把所有未收到的包序号通过反馈报文通知到发送方进行重传。

相对 ARQ带来的改进:减少的反馈包的频率和带宽占用,同时也能比较及时地通知发送方进行丢包重传。

NACK 报文的定义在 [rfc4585] 文档中定义。

RTCP 的反馈报文包头定义如下,FMT 和 PT 决定了该报文的类型,FCI 则是该类型报文的具体负载:

version (V): 2 bits 该字段标识RTP版本。当前版本是2

padding (P): 1 bit 如果设置,则填充位指示数据包包含末尾的其他填充八位位组不属于控制信息,但包含在长度字段中。

Feedback message type (FMT): 5 bits 此字段标识FB消息的类型,并且为相对于类型(传输层,有效负载特定的或应用层的反馈)。每个值 三种反馈类型在各自的部分中定义下面。

Payload type (PT): 8 bits 这是RTCP数据包类型,将数据包标识为RTCP FB消息. IANA定义了两个值:

Length: 16 bits 此数据包的长度(以32位字为单位)减去1,包括标头和任何填充。这符合定义RTCP发送方和接收方报告中使用的长度字段。

SSRC of packet sender: 32 bits 此消息的发起者的同步源标识符包。

SSRC of media source: 32 bits 媒体源的同步源标识符。

协议规定的 NACK 反馈报文的 PT= 205,FMT=1,FCI 的格式如下(可以附带多个 FCI,通过 header 的 length 字段来标示其长度):

这里的设计比较巧妙,它可以一次性携带多个连续的数据包的丢包情况:

Packet ID (PID): 16 bits PID字段用于指定丢失的数据包。PID字段表示丢失数据包的RTP序列号。

bitmask of following lost packets (BLP): 16 bits BLP允许报告紧跟在PID指示的RTP数据包之后16个RTP数据包中任何一个的丢失情况。如果接收方将位掩码的位i设置为1, 表示编号为(PID + i)的RTP数据包丢失。 否则,将位i设置为0。

NACK数据抓包

下面为RTCP数据包,红色方框内就为NACK数据。

使用wireshark解析如下:

通过丢失的RTP数据包序列号计算 PID 和 BLP

static void check_for_seq_number_gap_immediate(RtpSession *session, rtp_header_t *rtp) {uint16_t pid;uint16_t i;/*don't check anything before first packet delivered*/if (session->flags & RTP_SESSION_FIRST_PACKET_DELIVERED&& RTP_SEQ_IS_STRICTLY_GREATER_THAN(rtp->seq_number, session->rtp.rcv_last_seq + 1)&& RTP_SEQ_IS_STRICTLY_GREATER_THAN(rtp->seq_number, session->rtp.snd_last_nack + 1)) {uint16_t first_missed_seq = session->rtp.rcv_last_seq + 1;uint16_t diff;if (first_missed_seq <= session->rtp.snd_last_nack) {first_missed_seq = session->rtp.snd_last_nack + 1;}diff = rtp->seq_number - first_missed_seq;pid = first_missed_seq;for (i = 0; i <= (diff / 16); i++) {uint16_t seq;uint16_t blp = 0;for (seq = pid + 1; (seq < rtp->seq_number) && ((seq - pid) < 16); seq++) {blp |= (1 << (seq - pid - 1));}if (session->rtp.congdetect != NULL && session->rtp.congdetect->state == CongestionStateDetected) {/** Do not send NACK in IMMEDIATE_NACK mode in congestion, because the retransmission by the other party of the missing packets* will necessarily increase or at least sustain the congestion.* Furthermore, due to the congestion, the retransmitted packets have very few chance to arrive in time.*/ortp_message("Immediate NACK not sent because of congestion.");return;}rtp_session_send_rtcp_fb_generic_nack(session, pid, blp);pid = seq;}}if (RTP_SEQ_IS_STRICTLY_GREATER_THAN(rtp->seq_number, session->rtp.snd_last_nack)) {/* We update the last_nack since we received this packet we don't need a nack for it */session->rtp.snd_last_nack = rtp->seq_number;}
}

根据 PID 和 BLP 获取丢失的RTP数据包序列号

static void generic_nack_received(const OrtpEventData *evd, OrtpNackContext *ctx) {if (rtcp_is_RTPFB(evd->packet) && rtcp_RTPFB_get_type(evd->packet) == RTCP_RTPFB_NACK) {RtpTransport *rtpt = NULL;rtcp_fb_generic_nack_fci_t *fci;uint16_t pid, blp, seq;mblk_t *lost_msg;/* get RTP transport from session */rtp_session_get_transports(ctx->session, &rtpt, NULL);fci = rtcp_RTPFB_generic_nack_get_fci(evd->packet);pid = rtcp_fb_generic_nack_fci_get_pid(fci);blp = rtcp_fb_generic_nack_fci_get_blp(fci);bctbx_mutex_lock(&ctx->sent_packets_mutex);lost_msg = find_packet_with_sequence_number(&ctx->sent_packets, pid);if (lost_msg != NULL) {meta_rtp_transport_modifier_inject_packet_to_send(rtpt, ctx->rtp_modifier, lost_msg, 0);ortp_message("OrtpNackContext [%p]: Resending missing packet with seq=%hu", ctx, pid);} else {ortp_warning("OrtpNackContext [%p]: Cannot find missing packet with seq=%hu", ctx, pid);}++pid;for (seq = blp; seq != 0; seq >>= 1, ++pid) {if (seq & 1) {lost_msg = find_packet_with_sequence_number(&ctx->sent_packets, pid);if (lost_msg != NULL) {meta_rtp_transport_modifier_inject_packet_to_send(rtpt, ctx->rtp_modifier, lost_msg, 0);ortp_message("OrtpNackContext [%p]: Resending missing packet with seq=%hu", ctx, pid);} else {ortp_warning("OrtpNackContext [%p]: Cannot find missing packet with seq=%hu", ctx, pid);}}}bctbx_mutex_unlock(&ctx->sent_packets_mutex);}
}

RTCP 协议的 NACK 报文相关推荐

  1. 从WebRtc学习RTCP协议

    文章目录 RTCP支持的消息类型 RTCP协议头 WebRTC的反馈报文 RTPFB支持的报文类型: PSFB支持的报文类型: 参考 RTCP是RTP的控制协议. 那么RTCP能对RTP做哪些控制呢? ...

  2. rtp协议详解/rtcp协议详解

    1.简介 目前,在IP网络中实现实时语音.视频通信和应用已经成为网络应用的一个主流技术和发展方向,本文详细介绍IP协议族中用于实时语音.视频数据传输的标准协议RTP( Real-time Transp ...

  3. RTP与RTCP协议介绍

    本文转自:http://blog.51cto.com/zhangjunhd/25481 1.流媒体( Streaming Media) 1.1流媒体概念 流媒体技术是网络技术和多媒体技术发展到一定阶段 ...

  4. RTP/RTCP协议详解

    1.简介 目前,在IP网络中实现实时语音.视频通信和应用已经成为网络应用的一个主流技术和发展方向,本文详细介绍IP协议族中用于实时语音.视频数据传输的标准协议RTP( Real-time Transp ...

  5. RTSP/RTP/RTCP协议的区别

    1. RTSP(Real-Time Streaming Protocol):实时流协议,它的出现是由于流媒体服务器的引入而出现的. 如上图所示,上图反映出的是常用地观看视频的过程.在浏览器中输入视频的 ...

  6. 国标28181:什么是RTP协议与RTCP协议

    前言 流媒体指的是在网络中使用流技术传输的连续时基媒体,其特点是在播放前不需要下载整个文件,而是采用边下边播的方式,它是视频会议.IP电话等应用场合的技术基础.RTP是进行实时流媒体传输的标准协议和关 ...

  7. RTSP/RTP/RTCP协议流程及分析

    RTSP(实时流协议) RTSP中使用会话概念代替连接,由于它本身不与传输层绑定,因此RTSP会话在传输层支持TCP与UDP协议发送请求.RTSP客户机和服务器都可以发出请求,本身并不携带传输的媒体数 ...

  8. 音视频传输-之RTP/RTCP协议

    前言 RTP/RTCP协议设计用来传输音视频数据,对应的RFC文档为:RFC3550,对应的中文版RFC3550中文版 RTP被定义为在一对一或者一对多的传输情况下工作,其目的是为了提供时间信息和实现 ...

  9. FFmpeg入门详解之86:RTP/RTCP协议讲解

    RTP RTP:(Real-time Transport Protocol) 是用于Internet上针对多媒体数据流的一种传输层协议.RTP 协议和 RTP 控制协议 RTCP 一起使用,而且它是建 ...

  10. FFmpeg入门详解之112:RTP/RTCP协议讲解

    RTP RTP:(Real-time Transport Protocol) 是用于Internet上针对多媒体数据流的一种传输层协议.RTP 协议和 RTP 控制协议 RTCP 一起使用,而且它是建 ...

最新文章

  1. 使用 NetCoreBeauty 优化 .NET CORE 独立部署目录结构
  2. SSM 整合 3:一个 Spring 入门程序带你来了解什么是控制反转(IoC)/依赖注入(DI)!
  3. 作者:张金芳(1970-),男,中国科学院软件研究所副研究员
  4. 昔日的 HTC 与三星,今日的苹果:寒冬过后手机厂商才会明白的潜规则
  5. Java获取浏览器请求头(User-Agent),分析浏览器信息,系统信息的几种办法
  6. 给计算机系统打补丁,为什么我的电脑需要打补丁?
  7. vsftpd配置文件详细讲解
  8. android win7共享文件夹,win7系统共享文件夹如何用手机看电脑里面的电影
  9. Python 使用正则进行过滤字母、数字及特殊字符
  10. 三星android文件传输,最好的三星Galaxy S8管理器:如何将文件传输到三星Galaxy S8...
  11. 基于HTTP可供浏览器调用的本地打印程序
  12. python24点计算器_24点计算器Python脚本
  13. 亚米社区app v1.1.6
  14. 【小家java】一个例子让就能你彻底理解Java的Future模式,Future类的设计思想
  15. php内存不够,php内存不足怎么办
  16. 程序员除了会CRUD之外,还应该知道什么叫CQRS!
  17. js数组遍历方法总结
  18. PS美工教程:制作真实水面倒影效果详细步骤
  19. 计数器的计数长度的概要
  20. openerp 索引

热门文章

  1. 微博分享sdk4.0 中遇到的坑以及解决办法汇总
  2. Hdu-5769 Substring (SA后缀数组)
  3. NFT游戏开发NFT游戏平台模板搭建NFT平台定制开发MOBOX:NFT Farmer游戏开发
  4. 我孩子的毛毯教会了我关于技术和古希腊人的知识
  5. 保持初心,不负韶华||回顾2021,展望2022
  6. HTML期末学生大作业 响应式动漫网页作业 html+css+javascript (1)
  7. Composition API使用记录
  8. 人在烟火间(外两章)
  9. 惠斯通电桥称重传感器检测原理
  10. rpm -qa的意思详解