webrtc中的rtcp处理

 

在webrtc中,处理rtcp,目前的版本是在, rtcp_sender.h 和 rtcp_sender.cpp中实现;

 

当收到rtcp packet时,调用过程,主要是以下三个函数:

接收-》解析-》响应;

IncomingPacket -》{  ParseCompoundPacket -》 TriggerCallbacksFromRtcpPacket };

 

当然,还是实现了(根据rtcp)延时计算:

  // Get rtt.
  int32_t RTT(uint32_t remote_ssrc,
              int64_t* last_rtt_ms,
              int64_t* avg_rtt_ms,
              int64_t* min_rtt_ms,
              int64_t* max_rtt_ms) const;

 

 

void RTCPReceiver::IncomingPacket(const uint8_t* packet, size_t packet_size) {
  if (packet_size == 0) {
    RTC_LOG(LS_WARNING) << "Incoming empty RTCP packet";
    return;
  }


  PacketInformation packet_information;
  if (!ParseCompoundPacket(packet, packet + packet_size, &packet_information))
    return;
  TriggerCallbacksFromRtcpPacket(packet_information);

}

 

 

ParseCompoundPacket,是解析函数,直接看源码

 

 

说明一下这个响应函数:

RTCPReceiver::TriggerCallbacksFromRtcpPacket; 

这个函数,响应了,TMMBR and RTMB,NACK,和 Pli/Fir/Pli;

再说明一下 Pli/Fir/Pli:对关键帧的请求;

 

  if (rtcp_intra_frame_observer_) {
    RTC_DCHECK(!receiver_only_);
    if ((packet_information.packet_type_flags & kRtcpPli) ||
        (packet_information.packet_type_flags & kRtcpFir)) {
      if (packet_information.packet_type_flags & kRtcpPli) {
        RTC_LOG(LS_VERBOSE)
            << "Incoming PLI from SSRC " << packet_information.remote_ssrc;
      } else {
        RTC_LOG(LS_VERBOSE)
            << "Incoming FIR from SSRC " << packet_information.remote_ssrc;
      }
      rtcp_intra_frame_observer_->OnReceivedIntraFrameRequest(local_ssrc);
    }
  }

 

OnReceivedIntraFrameRequest函数会最后在本地产生一个相关的关键帧

 

 

 

再看一个函数:

响应Fir,然后设置packet_type_flags;

void RTCPReceiver::HandleFir(const CommonHeader& rtcp_block,
                             PacketInformation* packet_information) {
  rtcp::Fir fir;
  if (!fir.Parse(rtcp_block)) {
    ++num_skipped_packets_;
    return;
  }


  for (const rtcp::Fir::Request& fir_request : fir.requests()) {
    // Is it our sender that is requested to generate a new keyframe.
    if (main_ssrc_ != fir_request.ssrc)
      continue;


    ++packet_type_counter_.fir_packets;


    int64_t now_ms = clock_->TimeInMilliseconds();
    auto inserted = last_fir_.insert(std::make_pair(
        fir.sender_ssrc(), LastFirStatus(now_ms, fir_request.seq_nr)));
    if (!inserted.second) {  // There was already an entry.
      LastFirStatus* last_fir = &inserted.first->second;


      // Check if we have reported this FIRSequenceNumber before.
      if (fir_request.seq_nr == last_fir->sequence_number)
        continue;


      // Sanity: don't go crazy with the callbacks.
      if (now_ms - last_fir->request_ms < kRtcpMinFrameLengthMs)
        continue;


      last_fir->request_ms = now_ms;
      last_fir->sequence_number = fir_request.seq_nr;
    }

 

    // Received signal that we need to send a new key frame.

    packet_information->packet_type_flags |= kRtcpFir;

  }
}

 

 

 

 

 

 

 

发布了414 篇原创文章 · 获赞 210 · 访问量 248万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览