基础知识

音频的 NACK 机制在 WebRTC 中默认是关闭的.

rtcp feedbacknack开启就可以了

WebRTC 的音频数据传输中,尽管对低延时有着很高的要求,但也实现了 NACK,以用于一些音质比延迟更重要的场景。

重传数据包的记录功能, 记录那些需要重传

nack_tracker.cc

在 WebRTC 里,NetEQ 的 webrtc::NackTracker 用来跟踪和记录可能需要请求重传的数据包。

typedef std::map<uint16_t, NackElement, NackListCompare> NackList;
//NackList记录了丢包的序列号和每个包的播放时间和timestamp

struct NackElement {

NackElement()

int64_t time_to_play_ms; //此数据包解码的估计剩余时间(毫秒)

uint32_t estimated_timestamp;//关于丢失数据包的时间戳的猜测

bool is_missing; //判定是丢包还是,延迟了

};

小于最新收到的, 才可能是丢包

更新最后接收到的包NackTracker::UpdateLastReceivedPacket

  • 从 NACK 列表中移除对应数据包序列号的记录
  • 如果新收到的数据包的序列号比收到的最近的数据包的序列号小, 收到了丢包; 否则更新NACK 列表
  • 计算收到的最近的数据包到这次收到的数据包之间还没有收到的数据包的个数,并据此计算丢包率;
  • 更新NACK 列表
  • 更新记录收到的最近的数据包的序列号和 timestamp;
  • 执行 NACK 列表大小限制。

更新最近一次解码成功, NackTracker::UpdateLastDecodedPacket

接收端寻找时机发送 NACK 消息

WebRTC 在每次收到音频数据包,并把它送进 NetEQ 之后,就会立即去获取 NACK 列表

ChannelReceive::OnReceivedPayloadData

webrtc::voe::ChannelReceive::OnReceivedPayloadData()

NackTracker::GetNackList

ModuleRtpRtcpImpl::SendNack

  //5 + RTT * 1.5.  来区别NACK下次时间

接收端开启音频 NACK

webrtc::internal::AudioReceiveStream 对象创建时,有个配置项 config.rtp.nack.rtp_history_ms 用于控制是否开启 NACK。

config.rtp.nack.rtp_history_ms 的值大于 0 时,开启 NACK,否则不开启。

config.rtp.nack.rtp_history_ms 的值根据 WebRtcVoiceEngine 的 recv_nack_enabled_ 配置计算得到,而这个配置则来自于 codec spec 的 nack_enabled,codec spec 的配置来自于接收和发送的两方协调的 codec 配置的 SDP 消息

FeedbackParam(kRtcpFbParamNack, kParamValueEmpty));

发送端缓存

webrtc::RtpPacketHistory //发送的时候存储在该对象

发送端接收并处理 RTCP NACK 反馈包

webrtc::RTCPReceiver::IncomingPacket
webrtc::ModuleRtpRtcpImpl2::IncomingRtcpPacket
webrtc::voe::ChannelSend::ReceivedRTCPPacket(unsigned char const*, unsigned long)
webrtc::internal::AudioSendStream::DeliverRtcp(unsigned char const*, unsigned long)
webrtc::internal::Call::DeliverRtcp(webrtc::MediaType, rtc::CopyOnWriteBuffer):



蓝色箭头和红色方框中的这些逻辑是 NACK 数据包处理过程中,不同于一般采集、编码及发送流程的地方。

WebRTC 的音频弱网对抗之 NACK的更多相关文章

  1. 阿里云 RTC QoS 弱网对抗之 LTR 及其硬件解码支持

    LTR 弱网对抗由于需要解码器的反馈,因此用硬件解码器实现时需要做一些特殊处理.另外,一些硬件解码器对 LTR 的实现不是特别完善,会导致出现解码错误.本文为 QoS 弱网优化系列的第三篇,将为您详解 ...

  2. 网络QoS的平衡之道——音视频弱网对抗策略介绍

    作者:网易智企云信资深音视频引擎开发工程师 王兴鹤 随着AI和5G的到来,音视频应用将变得越来越广泛,人们对音视频的品质需求也越来越高,视频分辨率已经从高清发展为超高清.VR,视频帧率也已出现60fp ...

  3. 阿里云 RTC QoS 弱网对抗之变分辨率编码

    本文为 QoS 弱网优化系列的第二篇 作者|安基程.田伟峰 审校| 泰一 视频编码中的变分辨率问题及解决 变分辨率在弱网场景的实际应用中非常常见,网络状况不好的时候降低分辨率可以降低码率,减少块效应, ...

  4. 单独编译使用WebRTC的音频处理模块

    块,每块个点,(12*64=768采样)即AEC-PC仅能处理48ms的单声道16kHz延迟的数据,而 - 加载编译好的NS模块动态库 接下来只需要按照 此文 的描述在 android 的JAVA代码 ...

  5. 直播推流端弱网优化策略 | 直播 SDK 性能优化实践

    弱网优化的场景 网络直播行业经过一年多的快速发展,衍生出了各种各样的玩法.最早的网络直播是主播坐在 PC 前,安装好专业的直播设备(如摄像头和麦克风),然后才能开始直播.后来随着手机性能的提升和直播技 ...

  6. 弱网测试IOS

    IOS测弱网非常方便,在设置-开发者-NETWORK LINK CONDITIONER的Status 进入后可以看到IOS自带了100%LOSS.3G.WiFi等常见场景 可以点击图标i进行查看或编辑 ...

  7. 弱网测试Android

    弱网测试一般是指模拟在网络环境比较差的情况下,检测APP是否有异常,如崩溃,数据收发出现丢包的情况 一.首先需要控制网络,有两种方式其一使用网络损伤仪进行,其二采用软件方式.硬件采购费用太贵,因此使用 ...

  8. iOS如何监听弱网?

    场景: iOS中我们可能经常用到监听网络,不过大部分是监听网络的类型,即2G/3G/4G WIFI,是否连接网络,然而测试人员对APP进行测试时候经常会有一个弱网测试,即在弱网环境下对APP进行测试, ...

  9. APP弱网测试

    APP弱网测试   App弱网测试方法,常用工具有使用fiddler进行网络模拟,也可以使用Network Emulator Toolkit控制模拟网络,相对来说Network Emulator To ...

  10. Android弱网测试中关于网络检测的一些借鉴方法

    Android 平台下提供了一个android.net.ConnectivityManager类来监控当前的网络状态包括wifi.gprs.UMTS等.可以判断当前用户网络到底是WIFI还是移动网络, ...

随机推荐

  1. Commons-Collections反序列化

    Java反序列化漏洞 Commons Collections Apache Commons 是 Apache 软件基金会的项目.Commons Collections 包为 Java 标准的 Coll ...

  2. el-dialog中中使用echarts

    1.在dialog中使用open方法 <el-dialog :title="diaTitle" :visible.sync="dialogVisible" ...

  3. el-select 获取change点击index

    <el-select> <el-option v-for="(item, index) in optionlist" @click.native ="h ...

  4. JSP 与 Servlet 之间的联系,及其语法

    JSP 是什么 JSP 将 Java 代码和特定变动内容嵌入到静态的页面中,实现以静态页面为模板,动态生成其中的部分内容.JSP 文件在运行时会被其编译器转换成更原始的 Servlet 代码.JSP ...

  5. 基于Python的OpenGL 05 之坐标系统

    1. 引言 本文基于Python语言,描述OpenGL的坐标系统 前置知识可参考: 基于Python的OpenGL 04 之变换 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com) 笔者 ...

  6. [引擎开发] 深入GPU和渲染优化(基础篇)

    https://blog.csdn.net/ZJU_fish1996/article/details/109269448

  7. mysql转DM的日期函数转换

    背景: 项目要从mysql转换为DM数据库,发现很多日期函数在DM是不能用的. 所以大概总结下有哪些,以及转换思路. 正文: INTERVAL 表示日期间隔. 看做拼接符. DATE_ADD 表示日期 ...

  8. Source Insight 4.0 常用快捷键小记

    1. 括号配对高亮:"在前括号左侧,后括号左侧" 双击鼠标左键,可以选定匹配括号和其中内容(<>,(),L{R},[]之间) 高亮当前单词 : F8 语法窗口(隐藏/显 ...

  9. redis 集群配置(从0到1)

    1.关闭配置文件 appendonly yes改为no 2.到redis目录下拷贝redis.conf文件 cp ./redis.conf ./7001/ cp ./redis.conf ./7002 ...

  10. windows注册表的读

    1.打开 2.读取 //打开注册表 CString CDownDlg::GetPortCom(int nmber)//读取操作表,其类型为REG_SZ { CString ans; CString r ...