webrtc-m79-peerconnection_client-收集 relay candidate_03

///
  接收 TurnAllocateRequest 响应 (第二次)

 这里直接到达和第一次处理 TurnAllocateRequest 响应不同的地方 //

bool StunRequestManager::CheckResponse(StunMessage* msg) 
===>
request->OnResponse(msg);  

void TurnAllocateRequest::OnResponse(StunMessage* response) {
  RTC_LOG(LS_INFO) << port_->ToString()
                   << ": TURN allocate requested successfully, id="
                   << rtc::hex_encode(id())
                   << ", code=0"  // Makes logging easier to parse.
                      ", rtt="
                   << Elapsed();

  // Check mandatory attributes as indicated in RFC5766, Section 6.3.
  const StunAddressAttribute* mapped_attr =
      response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
  if (!mapped_attr) {
    RTC_LOG(LS_WARNING) << port_->ToString()
                        << ": Missing STUN_ATTR_XOR_MAPPED_ADDRESS "
                           "attribute in allocate success response";
    return;
  }
  // Using XOR-Mapped-Address for stun.
  port_->OnStunAddress(mapped_attr->GetAddress()); /// TurnPort::OnStunAddress

  const StunAddressAttribute* relayed_attr =
      response->GetAddress(STUN_ATTR_XOR_RELAYED_ADDRESS);
  if (!relayed_attr) {
    RTC_LOG(LS_WARNING) << port_->ToString()
                        << ": Missing STUN_ATTR_XOR_RELAYED_ADDRESS "
                           "attribute in allocate success response";
    return;
  }

  const StunUInt32Attribute* lifetime_attr =
      response->GetUInt32(STUN_ATTR_TURN_LIFETIME);
  if (!lifetime_attr) {
    RTC_LOG(LS_WARNING) << port_->ToString()
                        << ": Missing STUN_ATTR_TURN_LIFETIME attribute in "
                           "allocate success response";
    return;
  }
  // Notify the port the allocate succeeded, and schedule a refresh request.
  port_->OnAllocateSuccess(relayed_attr->GetAddress(),
                           mapped_attr->GetAddress()); /// TurnPort::OnAllocateSuccess
  port_->ScheduleRefresh(lifetime_attr->value()); /// TurnPort::ScheduleRefresh
}


void TurnPort::OnAllocateSuccess(const rtc::SocketAddress& address,
                                 const rtc::SocketAddress& stun_address) {
  state_ = STATE_READY;

  rtc::SocketAddress related_address = stun_address;

  // For relayed candidate, Base is the candidate itself.
  AddAddress(address,          // Candidate address.
             address,          // Base address.
             related_address,  // Related address.
             UDP_PROTOCOL_NAME,
             ProtoToString(server_address_.proto),  // The first hop protocol.
             "",  // TCP canddiate type, empty for turn candidates.
             RELAY_PORT_TYPE, GetRelayPreference(server_address_.proto),
             server_priority_, ReconstructedServerUrl(false /* use_hostname */),
             true); /// 注意注意注意,这里 is_final 传递的是 true /
}


void Port::AddAddress(const rtc::SocketAddress& address,
                      const rtc::SocketAddress& base_address,
                      const rtc::SocketAddress& related_address,
                      const std::string& protocol,
                      const std::string& relay_protocol,
                      const std::string& tcptype,
                      const std::string& type,
                      uint32_t type_preference,
                      uint32_t relay_preference,
                      const std::string& url,
                      bool is_final) { // 这里 is_final 传递的是 true /
  if (protocol == TCP_PROTOCOL_NAME && type == LOCAL_PORT_TYPE) {
    RTC_DCHECK(!tcptype.empty());
  }

  std::string foundation =
      ComputeFoundation(type, protocol, relay_protocol, base_address);
  Candidate c(component_, protocol, address, 0U, username_fragment(), password_,  // 创建 candidate 
              type, generation_, foundation, network_->id(), network_cost_);
  c.set_priority(
      c.GetPriority(type_preference, network_->preference(), relay_preference));
  c.set_relay_protocol(relay_protocol);
  c.set_tcptype(tcptype);
  c.set_network_name(network_->name());
  c.set_network_type(network_->type());
  c.set_url(url);
  c.set_related_address(related_address);

  bool pending = MaybeObfuscateAddress(&c, type, is_final);

  if (!pending) {
    FinishAddingAddress(c, is_final); // 这里 is_final 传递的是 true /
  }
}


void Port::FinishAddingAddress(const Candidate& c, bool is_final) {
  candidates_.push_back(c);
  SignalCandidateReady(this, c); / BasicPortAllocatorSession::OnCandidateReady 具体参考下面分析 
  /// 注意这里的 this 是 Port 的指针,而实际上指向的是 TurnPort (收集 relay candidate 使用的就是 TurnPort)
    /// 这里触发调用 BasicPortAllocatorSession::OnCandidateReady , 此函数内部又触发  SignalPortReady(this, port);
    /// 从而再次引发槽函数 P2PTransportChannel::OnPortReady 的调用,执行 ports_.push_back(port) ,从而将指向 TurnPort 的 Port 
    /// 指针保存到 ports_ ,所以在 P2PTransportChannel::CreateConnection 中调用 port->CreateConnection 创建 connection 时
     会调用 UDPPort::CreateConnection 或者 TurnPort::CreateConnection 
  PostAddAddress(is_final);
}

//
///  UDPPort::OnSentPacket   /
//
void UDPPort::OnSentPacket(rtc::AsyncPacketSocket* socket,
                           const rtc::SentPacket& sent_packet) {
  PortInterface::SignalSentPacket(sent_packet); / 这个信号在哪里绑定的?绑定到哪一个槽里呢? 见 P2PTransportChannel::OnPortReady
}  经过下面的分析这里就会调用到 P2PTransportChannel::OnSentPacket (具体见下部的 P2PTransportChannel::OnPortReady )


                                                class Port : public PortInterface,
                                                             public rtc::MessageHandlerAutoCleanup,
                                                             public sigslot::has_slots<>   
                                                             
                                                class UDPPort : public Port

什么时候会调用 P2PTransportChannel::OnPortReady ?? 
在 BasicPortAllocatorSession::OnCandidateReady 中发送这个信号 SignalPortReady , 就会调用到 P2PTransportChannel::OnPortReady
这个绑定关系是在 P2PTransportChannel::AddAllocatorSession 中确定的,具体见前面分析

                                                // A new port is available, attempt to make connections for it
                                                void P2PTransportChannel::OnPortReady(PortAllocatorSession* session,
                                                                                      PortInterface* port) {  这里的 port 实际上就是 Port 的指针
                                                  RTC_DCHECK_RUN_ON(network_thread_); / 这个 Port 的指针具体可以指向 UDPPort 和 TurnPort 
                                                
                                                  // Set in-effect options on the new port
                                                  for (OptionMap::const_iterator it = options_.begin(); it != options_.end();
                                                       ++it) {
                                                    int val = port->SetOption(it->first, it->second);
                                                    if (val < 0) {
                                                      // Errors are frequent, so use LS_INFO. bugs.webrtc.org/9221
                                                      RTC_LOG(LS_INFO) << port->ToString() << ": SetOption(" << it->first
                                                                       << ", " << it->second
                                                                       << ") failed: " << port->GetError();
                                                    }
                                                  }
                                                
                                                  // Remember the ports and candidates, and signal that candidates are ready.
                                                  // The session will handle this, and send an initiate/accept/modify message
                                                  // if one is pending.
                                                
                                                  port->SetIceRole(ice_role_);
                                                  port->SetIceTiebreaker(tiebreaker_);
                                                  ports_.push_back(port); // 将收集的 candidate 的 port 保存下来,后面会使用,比如: P2PTransportChannel::CreateConnections
                                                  port->SignalUnknownAddress.connect(this,
                                                                                     &P2PTransportChannel::OnUnknownAddress);
                                                  port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed);
                                                
                                                  port->SignalRoleConflict.connect(this, &P2PTransportChannel::OnRoleConflict);
                                                  port->SignalSentPacket.connect(this, &P2PTransportChannel::OnSentPacket); / 就是在这里对 Port 的 SignalSentPacket 事件进行了绑定 //
                                                
                                                  // Attempt to create a connection from this new port to all of the remote
                                                  // candidates that we were given so far.
                                                
                                                  std::vector<RemoteCandidate>::iterator iter;
                                                  for (iter = remote_candidates_.begin(); iter != remote_candidates_.end();
                                                       ++iter) {
                                                    CreateConnection(port, *iter, iter->origin_port());
                                                  }
                                                
                                                  SortConnectionsAndUpdateState(  连通性检测
                                                      IceControllerEvent::NEW_CONNECTION_FROM_LOCAL_CANDIDATE);
                                                }


void P2PTransportChannel::OnSentPacket(const rtc::SentPacket& sent_packet) {
  RTC_DCHECK_RUN_ON(network_thread_);

  SignalSentPacket(this, sent_packet); / 此信号来自 PacketTransportInternal ,经过下面的分析实际上是会触发 DtlsTransport::OnSentPacket /
}
                                                                                                // P2PTransportChannel 的继承关系
                                                                                                class RTC_EXPORT IceTransportInternal : public rtc::PacketTransportInternal
                                                                                                class RTC_EXPORT P2PTransportChannel : public IceTransportInternal
                                                                
                                                                
                                                                                                JsepTransportController::MaybeCreateJsepTransport 中调用 如下内容:
                                                                                                ====> 
                                                                                                          rtc::scoped_refptr<webrtc::IceTransportInterface> ice =
                                                                                                              CreateIceTransport(content_info.name, /*rtcp=*/false); / 返回的是包裹了 cricket::P2PTransportChannel 的 DefaultIceTransport 实例对象
                                                                                                          RTC_DCHECK(ice);  ice->internal() 返回的就是 DefaultIceTransport 包裹的 cricket::P2PTransportChannel 指针
                                                                                                        
                                                                                                          std::unique_ptr<cricket::DtlsTransportInternal> rtp_dtls_transport =  CreateDtlsTransport返回的是 cricket::DtlsTransport
                                                                                                              CreateDtlsTransport(content_info, ice->internal()); /// ice->internal() 返回的就是 DefaultIceTransport 包裹的 cricket::P2PTransportChannel 指针
                                                                
                                                                
                                                                                            
                                                                                            std::unique_ptr<cricket::DtlsTransportInternal>
                                                                                            JsepTransportController::CreateDtlsTransport(
                                                                                                const cricket::ContentInfo& content_info,
                                                                                                cricket::IceTransportInternal* ice) {
                                                                                              RTC_DCHECK(network_thread_->IsCurrent());
                                                                                            
                                                                                              std::unique_ptr<cricket::DtlsTransportInternal> dtls;
                                                                                            
                                                                                              if (config_.dtls_transport_factory) {
                                                                                                dtls = config_.dtls_transport_factory->CreateDtlsTransport(
                                                                                                    ice, config_.crypto_options);
                                                                                              } else {
                                                                                                dtls = std::make_unique<cricket::DtlsTransport>(ice, config_.crypto_options,
                                                                                                                                                config_.event_log); / 将 ice 也就是 cricket::P2PTransportChannel 传递到 DtlsTransport 中的成变 ice_transport_
                                                                                              }
                                                                                            
                                                                                              RTC_DCHECK(dtls); /// dtls->ice_transport() 返回的就是 创建 DtlsTransport 时传递进去的参数 ice 
                                                                                              dtls->SetSslMaxProtocolVersion(config_.ssl_max_version);
                                                                                              dtls->ice_transport()->SetIceRole(ice_role_);
                                                                                              dtls->ice_transport()->SetIceTiebreaker(ice_tiebreaker_);
                                                                                              dtls->ice_transport()->SetIceConfig(ice_config_);
                                                                                              if (certificate_) {
                                                                                                bool set_cert_success = dtls->SetLocalCertificate(certificate_);
                                                                                                RTC_DCHECK(set_cert_success);
                                                                                              }
                                                                                            
                                                                                              // Connect to signals offered by the DTLS and ICE transport.
                                                                                              dtls->SignalWritableState.connect(
                                                                                                  this, &JsepTransportController::OnTransportWritableState_n);
                                                                                              dtls->SignalReceivingState.connect(
                                                                                                  this, &JsepTransportController::OnTransportReceivingState_n);
                                                                                              dtls->SignalDtlsHandshakeError.connect(
                                                                                                  this, &JsepTransportController::OnDtlsHandshakeError);
                                                                                              dtls->ice_transport()->SignalGatheringState.connect(
                                                                                                  this, &JsepTransportController::OnTransportGatheringState_n);
                                                                                              dtls->ice_transport()->SignalCandidateGathered.connect(  在这里设置了 cricket::P2PTransportChannel SignalCandidateGathered 信号的槽函数
                                                                                                  this, &JsepTransportController::OnTransportCandidateGathered_n);
                                                                                              dtls->ice_transport()->SignalCandidateError.connect(
                                                                                                  this, &JsepTransportController::OnTransportCandidateError_n);
                                                                                              dtls->ice_transport()->SignalCandidatesRemoved.connect(
                                                                                                  this, &JsepTransportController::OnTransportCandidatesRemoved_n);
                                                                                              dtls->ice_transport()->SignalRoleConflict.connect(
                                                                                                  this, &JsepTransportController::OnTransportRoleConflict_n);
                                                                                              dtls->ice_transport()->SignalStateChanged.connect(
                                                                                                  this, &JsepTransportController::OnTransportStateChanged_n);
                                                                                              dtls->ice_transport()->SignalIceTransportStateChanged.connect(
                                                                                                  this, &JsepTransportController::OnTransportStateChanged_n);
                                                                                              dtls->ice_transport()->SignalCandidatePairChanged.connect(
                                                                                                  this, &JsepTransportController::OnTransportCandidatePairChanged_n);
                                                                                              return dtls;
                                                                                            }
                                                                
                                                                
                                                                
                                                                                                DtlsTransport::DtlsTransport(IceTransportInternal* ice_transport,
                                                                                                                             const webrtc::CryptoOptions& crypto_options,
                                                                                                                             webrtc::RtcEventLog* event_log)
                                                                                                    : transport_name_(ice_transport->transport_name()),
                                                                                                      component_(ice_transport->component()),
                                                                                                      ice_transport_(ice_transport), / ice_transport 实际上就是 cricket::P2PTransportChannel
                                                                                                      downward_(NULL),
                                                                                                      srtp_ciphers_(crypto_options.GetSupportedDtlsSrtpCryptoSuites()),
                                                                                                      ssl_max_version_(rtc::SSL_PROTOCOL_DTLS_12),
                                                                                                      crypto_options_(crypto_options),
                                                                                                      event_log_(event_log) {
                                                                                                  RTC_DCHECK(ice_transport_);
                                                                                                  ConnectToIceTransport(); // 
                                                                                                }
                                                                
                                                                
                                                                
                                                                                                    void DtlsTransport::ConnectToIceTransport() {
                                                                                                      RTC_DCHECK(ice_transport_); / ice_transport_ 实际上就是 cricket::P2PTransportChannel
                                                                                                      ice_transport_->SignalWritableState.connect(this,
                                                                                                                                                  &DtlsTransport::OnWritableState);
                                                                                                      ice_transport_->SignalReadPacket.connect(this, &DtlsTransport::OnReadPacket);
                                                                                                      ice_transport_->SignalSentPacket.connect(this, &DtlsTransport::OnSentPacket); // 就是在这里设置了 cricket::P2PTransportChannel 的 信号-槽 函数
                                                                                                      ice_transport_->SignalReadyToSend.connect(this,
                                                                                                                                                &DtlsTransport::OnReadyToSend); 在这里设置了 cricket::P2PTransportChannel 的 SignalReadyToSend 信号-槽 函数 
                                                                                                      ice_transport_->SignalReceivingState.connect(
                                                                                                          this, &DtlsTransport::OnReceivingState);
                                                                                                      ice_transport_->SignalNetworkRouteChanged.connect(
                                                                                                          this, &DtlsTransport::OnNetworkRouteChanged);
                                                                                                    }

 这里的 DtlsTransport 是 circket::DtlsTransport , 下面的 circket:: 是自己加上的,方便自己的理解
// class circket::DtlsTransportInternal : public rtc::PacketTransportInternal
// class circket::DtlsTransport : public circket::DtlsTransportInternal
// 下面的 SignalSentPacket 来自 circket::DtlsTransport 的父类 rtc::PacketTransportInternal


void DtlsTransport::OnSentPacket(rtc::PacketTransportInternal* transport,
                                 const rtc::SentPacket& sent_packet) {
  RTC_DCHECK_RUN_ON(&thread_checker_);
  SignalSentPacket(this, sent_packet); / DtlsTransport 中的 SignalSentPacket 是在哪里绑定的呢? 具体见下面分析
} /// 分析结果就是链接到了槽 RtpTransport::OnSentPacket 中


                                                                                                //
                                                                                                ///  DtlsTransport 中的 SignalSentPacket 信号绑定分析 
                                                                                                //
                                                                                                JsepTransportController::MaybeCreateJsepTransport
                                                                                                ===>
                                                                                                  rtc::scoped_refptr<webrtc::IceTransportInterface> ice =
                                                                                                      CreateIceTransport(content_info.name, /*rtcp=*/false); / 返回的是包裹了 cricket::P2PTransportChannel 的 DefaultIceTransport 实例对象
                                                                                                  RTC_DCHECK(ice); /// ice->internal() 返回的就是 DefaultIceTransport 包裹的 cricket::P2PTransportChannel 指针
                                                                                                
                                                                                                  std::unique_ptr<cricket::DtlsTransportInternal> rtp_dtls_transport =
                                                                                                      CreateDtlsTransport(content_info, ice->internal()); / 这里返回的是 cricket::DtlsTransport
                                                                                                      
                                                                                                  if (config_.disable_encryption) { /// config_.disable_encryption 默认为 false 所以这里不会创建 不加密 的 rtp transport
                                                                                                    RTC_LOG(LS_INFO)
                                                                                                        << "Creating UnencryptedRtpTransport, becayse encryption is disabled.";
                                                                                                    unencrypted_rtp_transport = CreateUnencryptedRtpTransport( / 返回 webrtc::RtpTransport
                                                                                                        content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get()); / 这里将 rtp_dtls_transport 传递进去,也就是将 cricket::DtlsTransport 传递进去
                                                                                                  } else if (!content_desc->cryptos().empty()) { /// class webrtc::SrtpTransport : public webrtc::RtpTransport , 而 class webrtc::RtpTransport : public webrtc::RtpTransportInternal
                                                                                                    sdes_transport = CreateSdesTransport(  返回 webrtc::SrtpTransport
                                                                                                        content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get());
                                                                                                    RTC_LOG(LS_INFO) << "Creating SdesTransport.";
                                                                                                  } else {  class webrtc::DtlsSrtpTransport : public webrtc::SrtpTransport
                                                                                                    RTC_LOG(LS_INFO) << "Creating DtlsSrtpTransport.";
                                                                                                    dtls_srtp_transport = CreateDtlsSrtpTransport( / 返回 webrtc::DtlsSrtpTransport
                                                                                                        content_info.name, rtp_dtls_transport.get(), rtcp_dtls_transport.get());
                                                                                                  }
                                                                                                  
                                                                                                // class circket::DtlsTransport  的继承关系
                                                                                                // class circket::DtlsTransportInternal : public rtc::PacketTransportInternal
                                                                                                // class circket::DtlsTransport : public circket::DtlsTransportInternal
                                                                                                
                                                                                                std::unique_ptr<webrtc::RtpTransport>
                                                                                                JsepTransportController::CreateUnencryptedRtpTransport(
                                                                                                    const std::string& transport_name,
                                                                                                    rtc::PacketTransportInternal* rtp_packet_transport, // 这里传递进来的实际上是 cricket::DtlsTransport
                                                                                                    rtc::PacketTransportInternal* rtcp_packet_transport) {
                                                                                                  RTC_DCHECK(network_thread_->IsCurrent());
                                                                                                  auto unencrypted_rtp_transport =
                                                                                                      std::make_unique<RtpTransport>(rtcp_packet_transport == nullptr); // class webrtc::RtpTransport : public webrtc::RtpTransportInternal 
                                                                                                  unencrypted_rtp_transport->SetRtpPacketTransport(rtp_packet_transport);  rtp_packet_transport 就是 cricket::DtlsTransport 的指针
                                                                                                  if (rtcp_packet_transport) {
                                                                                                    unencrypted_rtp_transport->SetRtcpPacketTransport(rtcp_packet_transport);
                                                                                                  }
                                                                                                  return unencrypted_rtp_transport;
                                                                                                }
                                                                                                
                                                                                                
                                                                                                void RtpTransport::SetRtpPacketTransport(
                                                                                                    rtc::PacketTransportInternal* new_packet_transport) { / 这里传递进来的 new_packet_transport 实际上是 cricket::DtlsTransport
                                                                                                  if (new_packet_transport == rtp_packet_transport_) {
                                                                                                    return;
                                                                                                  }
                                                                                                  if (rtp_packet_transport_) { / 这里传递进来的 new_packet_transport 实际上是 cricket::DtlsTransport
                                                                                                    rtp_packet_transport_->SignalReadyToSend.disconnect(this);
                                                                                                    rtp_packet_transport_->SignalReadPacket.disconnect(this);
                                                                                                    rtp_packet_transport_->SignalNetworkRouteChanged.disconnect(this);
                                                                                                    rtp_packet_transport_->SignalWritableState.disconnect(this);
                                                                                                    rtp_packet_transport_->SignalSentPacket.disconnect(this);
                                                                                                    // Reset the network route of the old transport.
                                                                                                    SignalNetworkRouteChanged(absl::optional<rtc::NetworkRoute>()); /// SignalNetworkRouteChanged 来自 RtpTransport 的父类 webrtc::RtpTransportInternal
                                                                                                  }
                                                                                                  if (new_packet_transport) {
                                                                                                    new_packet_transport->SignalReadyToSend.connect(  就是在这里设置了 cricket::DtlsTransport 的 SignalReadyToSend 信号的槽函数: RtpTransport::OnReadyToSend
                                                                                                        this, &RtpTransport::OnReadyToSend);
                                                                                                    new_packet_transport->SignalReadPacket.connect(this,
                                                                                                                                                   &RtpTransport::OnReadPacket);
                                                                                                    new_packet_transport->SignalNetworkRouteChanged.connect(
                                                                                                        this, &RtpTransport::OnNetworkRouteChanged);
                                                                                                    new_packet_transport->SignalWritableState.connect(
                                                                                                        this, &RtpTransport::OnWritableState);
                                                                                                    new_packet_transport->SignalSentPacket.connect(this,
                                                                                                                                                   &RtpTransport::OnSentPacket); / 就是在这里设置的  cricket::DtlsTransport 的 SignalSentPacket 信号绑定关系
                                                                                                    // Set the network route for the new transport.
                                                                                                    SignalNetworkRouteChanged(new_packet_transport->network_route()); /// SignalNetworkRouteChanged 来自 RtpTransport 的父类 webrtc::RtpTransportInternal
                                                                                                  }
                                                                                                
                                                                                                  rtp_packet_transport_ = new_packet_transport;
                                                                                                  // Assumes the transport is ready to send if it is writable. If we are wrong,
                                                                                                  // ready to send will be updated the next time we try to send.
                                                                                                  SetReadyToSend(false,
                                                                                                                 rtp_packet_transport_ && rtp_packet_transport_->writable());
                                                                                                }


/ class webrtc::RtpTransport : public webrtc::RtpTransportInternal
/ webrtc::RtpTransport 中的信号 SignalSentPacket 实际上就是来自其父类 webrtc::RtpTransportInternal
/ JsepTransportController::CreateUnencryptedRtpTransport 中创建的 webrtc::RtpTransport

void RtpTransport::OnSentPacket(rtc::PacketTransportInternal* packet_transport, / 这里的 packet_transport 就是 cricket::DtlsTransport
                                const rtc::SentPacket& sent_packet) {
  RTC_DCHECK(packet_transport == rtp_packet_transport_ ||
             packet_transport == rtcp_packet_transport_);
  SignalSentPacket(sent_packet); // 这里又来了一个信号, 这个信号在哪里设置的?见下面分析, 这个地方有点绕的
}  / 提示: PeerConnection::CreateVoiceChannel PeerConnection::CreateVideoChannel PeerConnection::CreateDataChannel 中都会触发这个信号-槽的绑定关系 ,分析一个就行了
/// 实际上会触发 BaseChannel::SignalSentPacket_n


void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
  RTC_DCHECK_RUN_ON(network_thread());
  invoker_.AsyncInvoke<void>(RTC_FROM_HERE, worker_thread_,
                             [this, sent_packet] {
                               RTC_DCHECK_RUN_ON(worker_thread());
                               SignalSentPacket(sent_packet);  又来了。。。。。。 SignalSentPacket 就是来自 BaseChannel
                             });  PeerConnection::CreateVideoChannel 中在创建 ricket::VideoChannel 时就对 cricket::VideoChannel 进行了 SignalSentPacket 信号的绑定,
                                          将其绑定到了 PeerConnection::OnSentPacket_w 
}


void PeerConnection::OnSentPacket_w(const rtc::SentPacket& sent_packet) {
  RTC_DCHECK_RUN_ON(worker_thread());
  RTC_DCHECK(call_);
  call_->OnSentPacket(sent_packet); / 至此终于没有信号了。。。。。。 在下面会分析 call 的创建以及使用,具体见下方的 “ PeerConnection 中的 call ”
}  这里的 call_ 实际上就是 internal::Call 具体见下面分析

                                                        /// internal::Call 的继承关系
                                                        class internal::Call final : public webrtc::Call,
                                                                           public PacketReceiver,
                                                                           public RecoveredPacketReceiver,
                                                                           public TargetTransferRateObserver,
                                                                           public BitrateAllocator::LimitObserver


void internal::Call::OnSentPacket(const rtc::SentPacket& sent_packet) {
  video_send_delay_stats_->OnSentPacket(sent_packet.packet_id,
                                        clock_->TimeInMilliseconds());
  transport_send_ptr_->OnSentPacket(sent_packet); / 这些地方就用到 internal::Call 里面详细的细节了
} /// transport_send_ptr_ 实际上就是 webrtc::RtpTransportControllerSend 指针, 具体见下面分析


void RtpTransportControllerSend::OnSentPacket(
    const rtc::SentPacket& sent_packet) {
  task_queue_.PostTask([this, sent_packet]() {
    RTC_DCHECK_RUN_ON(&task_queue_);
    absl::optional<SentPacket> packet_msg =
        transport_feedback_adapter_.ProcessSentPacket(sent_packet); /// 这里后面再进行分析
    pacer()->UpdateOutstandingData(
        transport_feedback_adapter_.GetOutstandingData()); // 这里后面再进行分析
    if (packet_msg && controller_)
      PostUpdates(controller_->OnSentPacket(*packet_msg));  这里后面再进行分析
  });
}


///  AllocationSequence::CreateStunPorts /


void AllocationSequence::CreateStunPorts() {
  if (IsFlagSet(PORTALLOCATOR_DISABLE_STUN)) {
    RTC_LOG(LS_VERBOSE) << "AllocationSequence: STUN ports disabled, skipping.";
    return;
  }

  if (IsFlagSet(PORTALLOCATOR_ENABLE_SHARED_SOCKET)) { // PeerConnection::InitializePortAllocator_n 中针对 allocator 设置了新的 flags_ , 见上面分析 ///
    return; // 此处会进入这个分支,也就是直接返回
  }

  if (!(config_ && !config_->StunServers().empty())) {
    RTC_LOG(LS_WARNING)
        << "AllocationSequence: No STUN server configured, skipping.";
    return;
  }

  std::unique_ptr<StunPort> port = StunPort::Create(
      session_->network_thread(), session_->socket_factory(), network_,
      session_->allocator()->min_port(), session_->allocator()->max_port(),
      session_->username(), session_->password(), config_->StunServers(),
      session_->allocator()->origin(),
      session_->allocator()->stun_candidate_keepalive_interval());
  if (port) {
    session_->AddAllocatedPort(port.release(), this, true); //
    // Since StunPort is not created using shared socket, |port| will not be
    // added to the dequeue.
  }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值