当前位置: 首页 > news >正文

一个外国人做汉字网站网站建设做得好的公司

一个外国人做汉字网站,网站建设做得好的公司,平面设计网上培训,网页设计与制作的原则流媒体学习之路(WebRTC)——音频NackTracker优化思路#xff08;8#xff09; —— 我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost目标#xff1a;可以让大家熟悉各类Qos能力、带宽估计能力#xff0c;提供每个环节关键参数调节接口并实…流媒体学习之路(WebRTC)——音频NackTracker优化思路8 —— 我正在的github给大家开发一个用于做实验的项目 —— github.com/qw225967/Bifrost目标可以让大家熟悉各类Qos能力、带宽估计能力提供每个环节关键参数调节接口并实现一个json全配置提供全面的可视化算法观察能力。欢迎大家使用 ——文章目录 流媒体学习之路(WebRTC)——音频NackTracker优化思路8一、NackTracker逻辑分析1.1 设计思路1.2 代码 二、优化思路三、测试四、总结 在讲具体内容之前插一句嘴从GCC分析3开始我们将针对GCC的实现细节去分析它设计的原理让我们理解这些类存在的意义不再带大家去串具体的流程了。 一、NackTracker逻辑分析 1.1 设计思路 NackTracker是WebRTC根据NetEq逻辑设计的Nack逻辑相比于视频的重传音频考虑的问题相对更多一些。本文的音频NackTracker逻辑来源于WebRTC105版本 // // The NackTracker class keeps track of the lost packets, an estimate of // time-to-play for each packet is also given. // // Every time a packet is pushed into NetEq, LastReceivedPacket() has to be // called to update the NACK list. // // Every time 10ms audio is pulled from NetEq LastDecodedPacket() should be // called, and time-to-play is updated at that moment. // // If packet N is received, any packet prior to N which has not arrived is // considered lost, and should be labeled as missing (the size of // the list might be limited and older packet eliminated from the list). // // The NackTracker class has to know about the sample rate of the packets to // compute time-to-play. So sample rate should be set as soon as the first // packet is received. If there is a change in the receive codec (sender changes // codec) then NackTracker should be reset. This is because NetEQ would flush // its buffer and re-transmission is meaning less for old packet. Therefore, in // that case, after reset the sampling rate has to be updated. // // Thread Safety // // Please note that this class in not thread safe. The class must be protected // if different APIs are called from different threads. //上面是NackTracker注释的设计思路意思是   1.统计丢失的数据包并给出每个数据包播放的估计时间   2.每次数据进入NetEq时都会调用 LastReceivedPacket() 更新 NackList   3.每次从NetEq队列提取10ms的音频都需要调用LastDecodedPacket()更新播放时间记录   4.如果接收到数据包N则在N之前尚未到达的任何数据包都被视为丢失并应标记为“丢失”列表的大小可能受到限制旧的数据包将从列表中删除——这里记录的默认值是500。   5.NackTracker类必须知道数据包的采样率才能计算播放时间。因此一旦接收到第一个数据包就应该设置采样率。如果接收编解码器发生变化发送方更改编解码器则应重置NackTracker。这是因为NetEQ会清空其缓冲区而重新传输对旧数据包来说意义不大。因此在这种情况下在重置之后必须更新采样率。 1.2 代码 void NackTracker::UpdateLastReceivedPacket(uint16_t sequence_number,uint32_t timestamp) {// Just record the value of sequence number and timestamp if this is the// first packet.// 记录第一个数据包接收信息if (!any_rtp_received_) {sequence_num_last_received_rtp_ sequence_number;timestamp_last_received_rtp_ timestamp;any_rtp_received_ true;// If no packet is decoded, to have a reasonable estimate of time-to-play// use the given values.if (!any_rtp_decoded_) {sequence_num_last_decoded_rtp_ sequence_number;timestamp_last_decoded_rtp_ timestamp;}return;}// 序号已接到直接返回if (sequence_number sequence_num_last_received_rtp_)return;// Received RTP should not be in the list.nack_list_.erase(sequence_number);// If this is an old sequence number, no more action is required, return.// 如果是旧数据直接返回if (IsNewerSequenceNumber(sequence_num_last_received_rtp_, sequence_number))return;// 更新丢包率估计UpdatePacketLossRate(sequence_number - sequence_num_last_received_rtp_ - 1);// 更新nack列表UpdateList(sequence_number, timestamp);sequence_num_last_received_rtp_ sequence_number;timestamp_last_received_rtp_ timestamp;// 尝试清除队列到当前最大限制LimitNackListSize(); }// 这里的逻辑是个指数滤波器 // 指数滤波器是个低通滤波器主要是削弱高频信号 // y(k) a * y(k-1) (1-a) * x(k) // a就是下面的alpha_q30这个值在0-1之间通常是0.8 ~ 0.99这里配置给出0.996 void NackTracker::UpdatePacketLossRate(int packets_lost) {// 计算alpha值用默认值换算后1069446856const uint64_t alpha_q30 (1 30) * config_.packet_loss_forget_factor;// Exponential filter.// 进行指数滤波留下丢包的低通值packet_loss_rate_ (alpha_q30 * packet_loss_rate_) 30;for (int i 0; i packets_lost; i) {packet_loss_rate_ ((alpha_q30 * packet_loss_rate_) 30) ((1 30) - alpha_q30);} }// 这个函数根据最新的包序号更新丢包值 void NackTracker::UpdateList(uint16_t sequence_number_current_received_rtp,uint32_t timestamp_current_received_rtp) {// 序号连续直接返回if (!IsNewerSequenceNumber(sequence_number_current_received_rtp,sequence_num_last_received_rtp_ 1)) {return;}RTC_DCHECK(!any_rtp_decoded_ ||IsNewerSequenceNumber(sequence_number_current_received_rtp,sequence_num_last_decoded_rtp_));// 更新采样的包周期absl::optionalint samples_per_packet GetSamplesPerPacket(sequence_number_current_received_rtp, timestamp_current_received_rtp);if (!samples_per_packet) {return;}// 更新丢包到nacklistfor (uint16_t n sequence_num_last_received_rtp_ 1;IsNewerSequenceNumber(sequence_number_current_received_rtp, n); n) {uint32_t timestamp EstimateTimestamp(n, *samples_per_packet);NackElement nack_element(TimeToPlay(timestamp), timestamp);nack_list_.insert(nack_list_.end(), std::make_pair(n, nack_element));} }// 需要根据采样率估计出每个包的周期 absl::optionalint NackTracker::GetSamplesPerPacket(uint16_t sequence_number_current_received_rtp,uint32_t timestamp_current_received_rtp) const {uint32_t timestamp_increase timestamp_current_received_rtp - timestamp_last_received_rtp_;uint16_t sequence_num_increase sequence_number_current_received_rtp - sequence_num_last_received_rtp_;int samples_per_packet timestamp_increase / sequence_num_increase;if (samples_per_packet 0 ||samples_per_packet kMaxPacketSizeMs * sample_rate_khz_) {// Not a valid samples per packet.return absl::nullopt;}return samples_per_packet; }// 根据周期计算时间戳 uint32_t NackTracker::EstimateTimestamp(uint16_t sequence_num,int samples_per_packet) {uint16_t sequence_num_diff sequence_num - sequence_num_last_received_rtp_;return sequence_num_diff * samples_per_packet timestamp_last_received_rtp_; }// 根据最大包限制清除包 void NackTracker::LimitNackListSize() {uint16_t limit sequence_num_last_received_rtp_ -static_castuint16_t(max_nack_list_size_) - 1;nack_list_.erase(nack_list_.begin(), nack_list_.upper_bound(limit)); }上述逻辑中有几个点需要思考一下   1.为什么使用指数滤波器对丢包率进行低通滤波   2.为什么Nack队列需要记录时间戳信息 答首先packet_loss_rate_是用于做最大等待时间估计的这个最大等待时间估计用于判断是否需要请求重传的判断。 // We dont erase elements with time-to-play shorter than round-trip-time. std::vectoruint16_t NackTracker::GetNackList(int64_t round_trip_time_ms) {RTC_DCHECK_GE(round_trip_time_ms, 0);std::vectoruint16_t sequence_numbers;// rtt异常兜底if (round_trip_time_ms 0) {if (config_.require_valid_rtt) {return sequence_numbers;} else {round_trip_time_ms config_.default_rtt_ms;}}// 丢包率异常大于1直接返回if (packet_loss_rate_ static_castuint32_t(config_.max_loss_rate * (1 30))) {return sequence_numbers;}// The estimated packet loss is between 0 and 1, so we need to multiply by 100// here.// 根据丢包率计算最大等待时间int max_wait_ms 100.0 * config_.ms_per_loss_percent * packet_loss_rate_ / (1 30);// 重传包放入队列for (NackList::const_iterator it nack_list_.begin(); it ! nack_list_.end();it) {// 计算当前时间戳和丢包时间戳的差值int64_t time_since_packet_ms (timestamp_last_received_rtp_ - it-second.estimated_timestamp) /sample_rate_khz_;// 丢包数据播放时间超过rtt || 接到数据的差值 rtt 小于最大等待时间 则进行重传请求if (it-second.time_to_play_ms round_trip_time_ms ||time_since_packet_ms round_trip_time_ms max_wait_ms)sequence_numbers.push_back(it-first);}// 配置开启仅进行单次Nack请求则清除队列if (config_.never_nack_multiple_times) {nack_list_.clear();}return sequence_numbers; }从上述的代码中可以看到音频的重传限制主要有两个   1.播放时间大于rtt——代表这个重传是有意义的这个数据请求重传能在一个rtt重传回来则可以赶上播放不增加延迟   2.等待时间rtt 小于最大等待时间——最大等待时间的计算 // 每次丢包增加等待的时长ms_per_loss_percent 20 // 计算alpha衰减因子packet_loss_forget_factor 0.996 // 假设有7个丢包那么根据上述运算逻辑int ms_per_loss_percent 20;uint32_t packet_loss_rate_ 0;double packet_loss_forget_factor 0.996;const uint64_t alpha_q30 (1 30) * packet_loss_forget_factor;packet_loss_rate_ (alpha_q30 * packet_loss_rate_) 30;for (int i 0; i 7; i) {packet_loss_rate_ ((alpha_q30 * packet_loss_rate_) 30) ((1 30) - alpha_q30);}int max_wait_ms 100.0 * ms_per_loss_percent * packet_loss_rate_ / (1 30);// 那么 max_wait_ms 计算得到为 55ms。随着丢包个数的增加最大等待时间也会增长。下面画了一张最大等待时间和每次计算丢包个数的曲线图 上面的图显示随着丢包数不断增加等待的时间增长也变得缓慢即使把连续丢包数增加到199个这个连续丢包指的是每次接到的数据跳了199个在现实的网络环境中随机丢包基本不可能出现这种情况除非完全堵死也只是增加到了1099ms。因此音频的nack相比视频来说更注重实时性因为很多时候丢一两个包整体的沟通也不会有太大的影响。 二、优化思路 在实时传输中我们需要根据应用的场景进行针对性调整。例如我们常常看到导弹的引导画面会出现各种花屏的情况在这种实时性要求较高体验要求低的战场场景下那么多重传并没有意义。相反在延迟较大的CDN直播场景下实时要求低质量要求高的情况下重传来保证整体的质量就更有必要。因此我们可以思考一下在我们各自的使用场景中是否需要提高Nack重传的效率。   基于上面的理解我们对NackTracker进行分析 接收RTP 发送Nack 限制发送Nack的位置就是我们可以做手脚的地方   1.调整播放时间和RTT的比想速度变快就把RTT变为 RTT/2 或者 RTT/4想速度变慢就把RTT变为2RTT 或者 3RTT   2.在增加重传速度时也可以适当的调长最大等待时间。     可以增加每多一个丢包等待的时间也可以调整平滑值来增大丢包率的平滑值。 struct Config {Config();// The exponential decay factor used to estimate the packet loss rate.// 这个值会影响丢包率的平滑值double packet_loss_forget_factor 0.996;// How many additional ms we are willing to wait (at most) for nacked// packets for each additional percentage of packet loss.// 这个值是每多一个丢包多等待的时间值int ms_per_loss_percent 20;// If true, never nack packets more than once.// 这个值影响是否第二次重传bool never_nack_multiple_times false;// Only nack if the RTT is valid.// 这个值代表只有在RTT生效时发送Nackbool require_valid_rtt false;// Default RTT to use unless require_valid_rtt is set.// 默认RTT值int default_rtt_ms 100;// Do not nack if the loss rate is above this value.// 最大丢包率限制double max_loss_rate 1.0;};三、测试 本次测试中间通过了进行过上行Nack调整的Mediasoup服务器。在原先的测试中我们发现当上行存在小丢包下行大延迟的网络环境中音频会产生很大的丢包相比我们调整过的Nack视频确没有任何丢包产生于是我们进行了以下调整使音频与视频效果对其   1.调整重传限制为待播放时间差 大于 rtt/2 就进行重传   2.调整等待时间为 2倍的最大等待根据计算在延迟600ms时大部分音频的重传都超过了最大等待时间。 进行测试 环境视频表现音频表现码率增加上行 15%丢包下行 600ms延迟几乎没有丢包偶现卡顿几乎没有丢包无明显丢字约23%下行30%丢包下行100ms延迟几乎没有丢包偶现卡顿几乎没有丢包无明显丢字约34% 四、总结 音频NackTracker的逻辑与视频NackRequest有相似的地方但是相比多了播放时间以及丢包的等待估计因此限制更多。在同样的模拟环境下原NackTracker的逻辑丢包明显。这与音频的特点有关音频可以合理的丢弃数据并不会明显的影响听感但是视频少一个数据就无法组成完整的图像。因此WebRTC为了保证实时性增加了播放时间对比以及丢包参考如果想要保证Nack的效果与视频一致那么也需要调整一下它的频率和最大限制。但这不意味着效果更好因为测试发现它的带宽消耗相对高了不少因此我们需要结合场景考虑。
http://www.ho-use.cn/article/10813894.html

相关文章:

  • 微网站开发需要多少费用深圳企业宣传片制作
  • 邯郸网站建设的企业外贸网站建设视频
  • 在门户网站建设上的讲话临平做网站
  • 大连个人网站建设wordpress文章导入公众号
  • 天津网站建设基本流程加强网站信息内容建设管理
  • 优秀的网页设计网站app大全视频app大全
  • 怎么制作网站设计wordpress 文章新窗口
  • 什么是企业营销型网站做防护信息的网站
  • jquery在网站开发实例运用建网站网站
  • 深圳市宝安区建设局网站搜索引擎优化是什么工作
  • 怎样把建好的网站上传到互联网营销型网站的付费推广渠道
  • 建设银行的官方网站电话小公司管理软件
  • 空气源热泵热水器网站建设网站建设多少钱一年
  • 陕西建设网网站集群专业网站搭建运营
  • 美食网站建设的时间进度表南京做网站公司地点
  • 郑州网站优化工资网站建设易网宣
  • 交流做病理切片的网站哪个网站可以接任务做兼职
  • 如何设计网站首页导航专业行业网站开发报价
  • 制作网站能挣钱jsp网站 值班
  • 怎么做优惠网站建筑模拟3正版下载
  • 城乡建设厅建筑特种作业证书查询seo外链专员工作要求
  • 湛江宇锋网站建设linux网站如何做ip解析
  • 湖南建设银行官网网站首页vue开发视频网站
  • 公司起名吉祥字大全seo怎么优化方案
  • 做网站需要加班吗300平方别墅装修大约多少钱
  • 怎么关闭网站安全检测wordpress外贸网站模板
  • 网站建设的投资预算怎么写广告制作开票大类是什么
  • 法治网站的建设整改措施wordpress 医疗
  • 学院网站建设北滘做网站
  • 邯郸wap网站建设费用网页设计的发展