DEPRECATED_NackModule::OnReceivedPacket

说明

OnReceivedPacket有两个函数
int OnReceivedPacket(uint16t seq_num, bool is_keyframe);
int OnReceivedPacket(uint16_t seq_num, bool is_keyframe, bool is_recovered);
前者调用了后者,第三个参数为false。
image.png
第一次进来需要初始化,然后第二个包进来就不需要初始化了。然后开始判断当前是否是上次处理前面的包,是则需要判断是否还在nack列表中,还在则需要删除。
image.png
如果是个新包,走下面的逻辑。
image.png
每个keyframe只有该keyframe第一个包,才会插入到keyframe_list中,其他位置的不插入。然后更新keyframe_list,只保存一万个值,将多出来的清理掉。接着往下走处理recoverd_list找回的包列表处理。
image.png
不是第一个包,不是一个重复的包,不是在newest_seq_num之前的包,也不是一个恢复的包,这时会跑到下面的逻辑。
image.png
AddPacketsToNack,将(newest_seq_num
+1,seqnum)范围的包插入到NackList nack_list
GetNackBatch拿到真正的丢包。

AddPacketsToNack

image.png
image.png

OnReceivedPacket源码

  1. int DEPRECATED_NackModule::OnReceivedPacket(uint16_t seq_num,
  2. bool is_keyframe,
  3. bool is_recovered) {
  4. MutexLock lock(&mutex_);
  5. // TODO(philipel): When the packet includes information whether it is
  6. // retransmitted or not, use that value instead. For
  7. // now set it to true, which will cause the reordering
  8. // statistics to never be updated.
  9. bool is_retransmitted = true;
  10. if (!initialized_) {
  11. newest_seq_num_ = seq_num;
  12. if (is_keyframe)
  13. keyframe_list_.insert(seq_num);
  14. initialized_ = true;
  15. return 0;
  16. }
  17. // Since the |newest_seq_num_| is a packet we have actually received we know
  18. // that packet has never been Nacked.
  19. if (seq_num == newest_seq_num_)
  20. return 0;
  21. if (AheadOf(newest_seq_num_, seq_num)) {
  22. // An out of order packet has been received.
  23. auto nack_list_it = nack_list_.find(seq_num);
  24. int nacks_sent_for_packet = 0;
  25. if (nack_list_it != nack_list_.end()) {
  26. nacks_sent_for_packet = nack_list_it->second.retries;
  27. nack_list_.erase(nack_list_it);
  28. }
  29. if (!is_retransmitted)
  30. UpdateReorderingStatistics(seq_num);
  31. return nacks_sent_for_packet;
  32. }
  33. // Keep track of new keyframes.
  34. if (is_keyframe)
  35. keyframe_list_.insert(seq_num);
  36. // And remove old ones so we don't accumulate keyframes.
  37. auto it = keyframe_list_.lower_bound(seq_num - kMaxPacketAge);
  38. if (it != keyframe_list_.begin())
  39. keyframe_list_.erase(keyframe_list_.begin(), it);
  40. if (is_recovered) {
  41. recovered_list_.insert(seq_num);
  42. // Remove old ones so we don't accumulate recovered packets.
  43. auto it = recovered_list_.lower_bound(seq_num - kMaxPacketAge);
  44. if (it != recovered_list_.begin())
  45. recovered_list_.erase(recovered_list_.begin(), it);
  46. // Do not send nack for packets recovered by FEC or RTX.
  47. return 0;
  48. }
  49. AddPacketsToNack(newest_seq_num_ + 1, seq_num);
  50. newest_seq_num_ = seq_num;
  51. // Are there any nacks that are waiting for this seq_num.
  52. std::vector<uint16_t> nack_batch = GetNackBatch(kSeqNumOnly);
  53. if (!nack_batch.empty()) {
  54. // This batch of NACKs is triggered externally; the initiator can
  55. // batch them with other feedback messages.
  56. nack_sender_->SendNack(nack_batch, /*buffering_allowed=*/true);
  57. }
  58. return 0;
  59. }