webrtc中的rtcp处理

≯℡__Kan透↙ 提交于 2019-11-30 12:32:07

 

在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;

  }
}

 

 

 

 

 

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!