| Index: webrtc/pc/channel.cc
 | 
| diff --git a/webrtc/pc/channel.cc b/webrtc/pc/channel.cc
 | 
| index a34e9434ebaf3afc66aa6cc1691424ffcc0cb0dc..3c438f63ef601df25b7507aa25e5092445581a89 100644
 | 
| --- a/webrtc/pc/channel.cc
 | 
| +++ b/webrtc/pc/channel.cc
 | 
| @@ -198,10 +198,14 @@ void BaseChannel::DisconnectTransportChannels_n() {
 | 
|    // Stop signals from transport channels, but keep them alive because
 | 
|    // media_channel may use them from a different thread.
 | 
|    if (rtp_dtls_transport_) {
 | 
| -    DisconnectFromTransport(rtp_dtls_transport_);
 | 
| +    DisconnectFromDtlsTransport(rtp_dtls_transport_);
 | 
| +  } else if (rtp_packet_transport_) {
 | 
| +    DisconnectFromPacketTransport(rtp_packet_transport_);
 | 
|    }
 | 
|    if (rtcp_dtls_transport_) {
 | 
| -    DisconnectFromTransport(rtcp_dtls_transport_);
 | 
| +    DisconnectFromDtlsTransport(rtcp_dtls_transport_);
 | 
| +  } else if (rtcp_packet_transport_) {
 | 
| +    DisconnectFromPacketTransport(rtcp_packet_transport_);
 | 
|    }
 | 
|  
 | 
|    // Clear pending read packets/messages.
 | 
| @@ -210,26 +214,33 @@ void BaseChannel::DisconnectTransportChannels_n() {
 | 
|  }
 | 
|  
 | 
|  bool BaseChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
 | 
| -                         DtlsTransportInternal* rtcp_dtls_transport) {
 | 
| +                         DtlsTransportInternal* rtcp_dtls_transport,
 | 
| +                         rtc::PacketTransportInterface* rtp_packet_transport,
 | 
| +                         rtc::PacketTransportInterface* rtcp_packet_transport) {
 | 
|    if (!network_thread_->Invoke<bool>(
 | 
|            RTC_FROM_HERE, Bind(&BaseChannel::InitNetwork_n, this,
 | 
| -                              rtp_dtls_transport, rtcp_dtls_transport))) {
 | 
| +                              rtp_dtls_transport, rtcp_dtls_transport,
 | 
| +                              rtp_packet_transport, rtcp_packet_transport))) {
 | 
|      return false;
 | 
|    }
 | 
| -
 | 
| -  // Both RTP and RTCP channels are set, we can call SetInterface on
 | 
| -  // media channel and it can set network options.
 | 
| -  RTC_DCHECK(worker_thread_->IsCurrent());
 | 
| +  // Both RTP and RTCP channels should be set, we can call SetInterface on
 | 
| +  // the media channel and it can set network options.
 | 
| +  RTC_DCHECK_RUN_ON(worker_thread_);
 | 
|    media_channel_->SetInterface(this);
 | 
|    return true;
 | 
|  }
 | 
|  
 | 
| -bool BaseChannel::InitNetwork_n(DtlsTransportInternal* rtp_dtls_transport,
 | 
| -                                DtlsTransportInternal* rtcp_dtls_transport) {
 | 
| +bool BaseChannel::InitNetwork_n(
 | 
| +    DtlsTransportInternal* rtp_dtls_transport,
 | 
| +    DtlsTransportInternal* rtcp_dtls_transport,
 | 
| +    rtc::PacketTransportInterface* rtp_packet_transport,
 | 
| +    rtc::PacketTransportInterface* rtcp_packet_transport) {
 | 
|    RTC_DCHECK(network_thread_->IsCurrent());
 | 
| -  SetTransports_n(rtp_dtls_transport, rtcp_dtls_transport);
 | 
| +  SetTransports_n(rtp_dtls_transport, rtcp_dtls_transport, rtp_packet_transport,
 | 
| +                  rtcp_packet_transport);
 | 
|  
 | 
| -  if (!SetDtlsSrtpCryptoSuites_n(rtp_dtls_transport_, false)) {
 | 
| +  if (rtp_dtls_transport_ &&
 | 
| +      !SetDtlsSrtpCryptoSuites_n(rtp_dtls_transport_, false)) {
 | 
|      return false;
 | 
|    }
 | 
|    if (rtcp_dtls_transport_ &&
 | 
| @@ -254,35 +265,56 @@ void BaseChannel::Deinit() {
 | 
|  
 | 
|  void BaseChannel::SetTransports(DtlsTransportInternal* rtp_dtls_transport,
 | 
|                                  DtlsTransportInternal* rtcp_dtls_transport) {
 | 
| -  network_thread_->Invoke<void>(RTC_FROM_HERE,
 | 
| -                                Bind(&BaseChannel::SetTransports_n, this,
 | 
| -                                     rtp_dtls_transport, rtcp_dtls_transport));
 | 
| +  network_thread_->Invoke<void>(
 | 
| +      RTC_FROM_HERE,
 | 
| +      Bind(&BaseChannel::SetTransports_n, this, rtp_dtls_transport,
 | 
| +           rtcp_dtls_transport, rtp_dtls_transport, rtcp_dtls_transport));
 | 
|  }
 | 
|  
 | 
| -void BaseChannel::SetTransports_n(DtlsTransportInternal* rtp_dtls_transport,
 | 
| -                                  DtlsTransportInternal* rtcp_dtls_transport) {
 | 
| +void BaseChannel::SetTransports(
 | 
| +    rtc::PacketTransportInterface* rtp_packet_transport,
 | 
| +    rtc::PacketTransportInterface* rtcp_packet_transport) {
 | 
| +  network_thread_->Invoke<void>(
 | 
| +      RTC_FROM_HERE, Bind(&BaseChannel::SetTransports_n, this, nullptr, nullptr,
 | 
| +                          rtp_packet_transport, rtcp_packet_transport));
 | 
| +}
 | 
| +
 | 
| +void BaseChannel::SetTransports_n(
 | 
| +    DtlsTransportInternal* rtp_dtls_transport,
 | 
| +    DtlsTransportInternal* rtcp_dtls_transport,
 | 
| +    rtc::PacketTransportInterface* rtp_packet_transport,
 | 
| +    rtc::PacketTransportInterface* rtcp_packet_transport) {
 | 
|    RTC_DCHECK(network_thread_->IsCurrent());
 | 
| -  if (!rtp_dtls_transport && !rtcp_dtls_transport) {
 | 
| -    LOG(LS_ERROR) << "Setting nullptr to RTP Transport and RTCP Transport.";
 | 
| -    return;
 | 
| +  // Validate some assertions about the input.
 | 
| +  RTC_DCHECK(rtp_packet_transport);
 | 
| +  RTC_DCHECK_EQ(NeedsRtcpTransport(), rtcp_packet_transport != nullptr);
 | 
| +  if (rtp_dtls_transport || rtcp_dtls_transport) {
 | 
| +    // DTLS/non-DTLS pointers should be to the same object.
 | 
| +    RTC_DCHECK(rtp_dtls_transport == rtp_packet_transport);
 | 
| +    RTC_DCHECK(rtcp_dtls_transport == rtcp_packet_transport);
 | 
| +    // Can't go from non-DTLS to DTLS.
 | 
| +    RTC_DCHECK(!rtp_packet_transport_ || rtp_dtls_transport_);
 | 
| +  } else {
 | 
| +    // Can't go from DTLS to non-DTLS.
 | 
| +    RTC_DCHECK(!rtp_dtls_transport_);
 | 
|    }
 | 
| -
 | 
| +  // Transport names should be the same.
 | 
|    if (rtp_dtls_transport && rtcp_dtls_transport) {
 | 
|      RTC_DCHECK(rtp_dtls_transport->transport_name() ==
 | 
|                 rtcp_dtls_transport->transport_name());
 | 
| -    RTC_DCHECK(NeedsRtcpTransport());
 | 
|    }
 | 
| -
 | 
| -  std::string transport_name = rtp_dtls_transport
 | 
| -                                   ? rtp_dtls_transport->transport_name()
 | 
| -                                   : rtcp_dtls_transport->transport_name();
 | 
| -  if (transport_name == transport_name_) {
 | 
| -    // Nothing to do if transport name isn't changing.
 | 
| +  std::string debug_name;
 | 
| +  if (rtp_dtls_transport) {
 | 
| +    transport_name_ = rtp_dtls_transport->transport_name();
 | 
| +    debug_name = transport_name_;
 | 
| +  } else {
 | 
| +    debug_name = rtp_packet_transport->debug_name();
 | 
| +  }
 | 
| +  if (rtp_packet_transport == rtp_packet_transport_) {
 | 
| +    // Nothing to do if transport isn't changing.
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| -  transport_name_ = transport_name;
 | 
| -
 | 
|    // When using DTLS-SRTP, we must reset the SrtpFilter every time the transport
 | 
|    // changes and wait until the DTLS handshake is complete to set the newly
 | 
|    // negotiated parameters.
 | 
| @@ -295,17 +327,15 @@ void BaseChannel::SetTransports_n(DtlsTransportInternal* rtp_dtls_transport,
 | 
|  
 | 
|    // If this BaseChannel doesn't require RTCP mux and we haven't fully
 | 
|    // negotiated RTCP mux, we need an RTCP transport.
 | 
| -  if (NeedsRtcpTransport()) {
 | 
| +  if (rtcp_packet_transport) {
 | 
|      LOG(LS_INFO) << "Setting RTCP Transport for " << content_name() << " on "
 | 
| -                 << transport_name << " transport " << rtcp_dtls_transport;
 | 
| -    SetTransport_n(true, rtcp_dtls_transport);
 | 
| -    RTC_DCHECK(rtcp_dtls_transport_);
 | 
| +                 << debug_name << " transport " << rtcp_packet_transport;
 | 
| +    SetTransport_n(true, rtcp_dtls_transport, rtcp_packet_transport);
 | 
|    }
 | 
|  
 | 
| -  LOG(LS_INFO) << "Setting non-RTCP Transport for " << content_name() << " on "
 | 
| -               << transport_name << " transport " << rtp_dtls_transport;
 | 
| -  SetTransport_n(false, rtp_dtls_transport);
 | 
| -  RTC_DCHECK(rtp_dtls_transport_);
 | 
| +  LOG(LS_INFO) << "Setting RTP Transport for " << content_name() << " on "
 | 
| +               << debug_name << " transport " << rtp_packet_transport;
 | 
| +  SetTransport_n(false, rtp_dtls_transport, rtp_packet_transport);
 | 
|  
 | 
|    // Update aggregate writable/ready-to-send state between RTP and RTCP upon
 | 
|    // setting new transport channels.
 | 
| @@ -320,44 +350,58 @@ void BaseChannel::SetTransports_n(DtlsTransportInternal* rtp_dtls_transport,
 | 
|    // BaseChannel could have resulted in an error), but even so, we'll just
 | 
|    // encounter the error again and update "ready to send" accordingly.
 | 
|    SetTransportChannelReadyToSend(
 | 
| -      false, rtp_dtls_transport_ && rtp_dtls_transport_->writable());
 | 
| +      false, rtp_packet_transport_ && rtp_packet_transport_->writable());
 | 
|    SetTransportChannelReadyToSend(
 | 
| -      true, rtcp_dtls_transport_ && rtcp_dtls_transport_->writable());
 | 
| +      true, rtcp_packet_transport_ && rtcp_packet_transport_->writable());
 | 
|  }
 | 
|  
 | 
| -void BaseChannel::SetTransport_n(bool rtcp,
 | 
| -                                 DtlsTransportInternal* new_transport) {
 | 
| +void BaseChannel::SetTransport_n(
 | 
| +    bool rtcp,
 | 
| +    DtlsTransportInternal* new_dtls_transport,
 | 
| +    rtc::PacketTransportInterface* new_packet_transport) {
 | 
|    RTC_DCHECK(network_thread_->IsCurrent());
 | 
| -  DtlsTransportInternal*& old_transport =
 | 
| +  DtlsTransportInternal*& old_dtls_transport =
 | 
|        rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_;
 | 
| +  rtc::PacketTransportInterface*& old_packet_transport =
 | 
| +      rtcp ? rtcp_packet_transport_ : rtp_packet_transport_;
 | 
|  
 | 
| -  if (!old_transport && !new_transport) {
 | 
| +  if (!old_packet_transport && !new_packet_transport) {
 | 
|      // Nothing to do.
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| -  RTC_DCHECK(old_transport != new_transport);
 | 
| -  if (old_transport) {
 | 
| -    DisconnectFromTransport(old_transport);
 | 
| +  RTC_DCHECK(old_packet_transport != new_packet_transport);
 | 
| +  if (old_dtls_transport) {
 | 
| +    DisconnectFromDtlsTransport(old_dtls_transport);
 | 
| +  } else if (old_packet_transport) {
 | 
| +    DisconnectFromPacketTransport(old_packet_transport);
 | 
|    }
 | 
|  
 | 
| -  old_transport = new_transport;
 | 
| +  old_packet_transport = new_packet_transport;
 | 
| +  old_dtls_transport = new_dtls_transport;
 | 
|  
 | 
| -  if (new_transport) {
 | 
| -    if (rtcp) {
 | 
| -      RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_filter_.IsActive()))
 | 
| -          << "Setting RTCP for DTLS/SRTP after SrtpFilter is active "
 | 
| -          << "should never happen.";
 | 
| -    }
 | 
| -    ConnectToTransport(new_transport);
 | 
| -    auto& socket_options = rtcp ? rtcp_socket_options_ : socket_options_;
 | 
| -    for (const auto& pair : socket_options) {
 | 
| -      new_transport->SetOption(pair.first, pair.second);
 | 
| -    }
 | 
| +  // If there's no new transport, we're done after disconnecting from old one.
 | 
| +  if (!new_packet_transport) {
 | 
| +    return;
 | 
| +  }
 | 
| +
 | 
| +  if (rtcp && new_dtls_transport) {
 | 
| +    RTC_CHECK(!(ShouldSetupDtlsSrtp_n() && srtp_filter_.IsActive()))
 | 
| +        << "Setting RTCP for DTLS/SRTP after SrtpFilter is active "
 | 
| +        << "should never happen.";
 | 
| +  }
 | 
| +  if (new_dtls_transport) {
 | 
| +    ConnectToDtlsTransport(new_dtls_transport);
 | 
| +  } else {
 | 
| +    ConnectToPacketTransport(new_packet_transport);
 | 
| +  }
 | 
| +  auto& socket_options = rtcp ? rtcp_socket_options_ : socket_options_;
 | 
| +  for (const auto& pair : socket_options) {
 | 
| +    new_packet_transport->SetOption(pair.first, pair.second);
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -void BaseChannel::ConnectToTransport(DtlsTransportInternal* transport) {
 | 
| +void BaseChannel::ConnectToDtlsTransport(DtlsTransportInternal* transport) {
 | 
|    RTC_DCHECK(network_thread_->IsCurrent());
 | 
|  
 | 
|    transport->SignalWritableState.connect(this, &BaseChannel::OnWritableState);
 | 
| @@ -369,7 +413,8 @@ void BaseChannel::ConnectToTransport(DtlsTransportInternal* transport) {
 | 
|        this, &BaseChannel::OnSelectedCandidatePairChanged);
 | 
|  }
 | 
|  
 | 
| -void BaseChannel::DisconnectFromTransport(DtlsTransportInternal* transport) {
 | 
| +void BaseChannel::DisconnectFromDtlsTransport(
 | 
| +    DtlsTransportInternal* transport) {
 | 
|    RTC_DCHECK(network_thread_->IsCurrent());
 | 
|    OnSelectedCandidatePairChanged(transport->ice_transport(), nullptr, -1,
 | 
|                                   false);
 | 
| @@ -383,6 +428,24 @@ void BaseChannel::DisconnectFromTransport(DtlsTransportInternal* transport) {
 | 
|        this);
 | 
|  }
 | 
|  
 | 
| +void BaseChannel::ConnectToPacketTransport(
 | 
| +    rtc::PacketTransportInterface* transport) {
 | 
| +  RTC_DCHECK_RUN_ON(network_thread_);
 | 
| +  transport->SignalWritableState.connect(this, &BaseChannel::OnWritableState);
 | 
| +  transport->SignalReadPacket.connect(this, &BaseChannel::OnPacketRead);
 | 
| +  transport->SignalReadyToSend.connect(this, &BaseChannel::OnReadyToSend);
 | 
| +  transport->SignalSentPacket.connect(this, &BaseChannel::SignalSentPacket_n);
 | 
| +}
 | 
| +
 | 
| +void BaseChannel::DisconnectFromPacketTransport(
 | 
| +    rtc::PacketTransportInterface* transport) {
 | 
| +  RTC_DCHECK_RUN_ON(network_thread_);
 | 
| +  transport->SignalWritableState.disconnect(this);
 | 
| +  transport->SignalReadPacket.disconnect(this);
 | 
| +  transport->SignalReadyToSend.disconnect(this);
 | 
| +  transport->SignalSentPacket.disconnect(this);
 | 
| +}
 | 
| +
 | 
|  bool BaseChannel::Enable(bool enable) {
 | 
|    worker_thread_->Invoke<void>(
 | 
|        RTC_FROM_HERE,
 | 
| @@ -450,6 +513,9 @@ void BaseChannel::StopConnectionMonitor() {
 | 
|  
 | 
|  bool BaseChannel::GetConnectionStats(ConnectionInfos* infos) {
 | 
|    RTC_DCHECK(network_thread_->IsCurrent());
 | 
| +  if (!rtp_dtls_transport_) {
 | 
| +    return false;
 | 
| +  }
 | 
|    return rtp_dtls_transport_->ice_transport()->GetStats(infos);
 | 
|  }
 | 
|  
 | 
| @@ -499,20 +565,20 @@ int BaseChannel::SetOption_n(SocketType type,
 | 
|                               rtc::Socket::Option opt,
 | 
|                               int value) {
 | 
|    RTC_DCHECK(network_thread_->IsCurrent());
 | 
| -  DtlsTransportInternal* transport = nullptr;
 | 
| +  rtc::PacketTransportInterface* transport = nullptr;
 | 
|    switch (type) {
 | 
|      case ST_RTP:
 | 
| -      transport = rtp_dtls_transport_;
 | 
| +      transport = rtp_packet_transport_;
 | 
|        socket_options_.push_back(
 | 
|            std::pair<rtc::Socket::Option, int>(opt, value));
 | 
|        break;
 | 
|      case ST_RTCP:
 | 
| -      transport = rtcp_dtls_transport_;
 | 
| +      transport = rtcp_packet_transport_;
 | 
|        rtcp_socket_options_.push_back(
 | 
|            std::pair<rtc::Socket::Option, int>(opt, value));
 | 
|        break;
 | 
|    }
 | 
| -  return transport ? transport->ice_transport()->SetOption(opt, value) : -1;
 | 
| +  return transport ? transport->SetOption(opt, value) : -1;
 | 
|  }
 | 
|  
 | 
|  bool BaseChannel::SetCryptoOptions(const rtc::CryptoOptions& crypto_options) {
 | 
| @@ -521,8 +587,8 @@ bool BaseChannel::SetCryptoOptions(const rtc::CryptoOptions& crypto_options) {
 | 
|  }
 | 
|  
 | 
|  void BaseChannel::OnWritableState(rtc::PacketTransportInterface* transport) {
 | 
| -  RTC_DCHECK(transport == rtp_dtls_transport_ ||
 | 
| -             transport == rtcp_dtls_transport_);
 | 
| +  RTC_DCHECK(transport == rtp_packet_transport_ ||
 | 
| +             transport == rtcp_packet_transport_);
 | 
|    RTC_DCHECK(network_thread_->IsCurrent());
 | 
|    UpdateWritableState_n();
 | 
|  }
 | 
| @@ -544,9 +610,9 @@ void BaseChannel::OnPacketRead(rtc::PacketTransportInterface* transport,
 | 
|  }
 | 
|  
 | 
|  void BaseChannel::OnReadyToSend(rtc::PacketTransportInterface* transport) {
 | 
| -  RTC_DCHECK(transport == rtp_dtls_transport_ ||
 | 
| -             transport == rtcp_dtls_transport_);
 | 
| -  SetTransportChannelReadyToSend(transport == rtcp_dtls_transport_, true);
 | 
| +  RTC_DCHECK(transport == rtp_packet_transport_ ||
 | 
| +             transport == rtcp_packet_transport_);
 | 
| +  SetTransportChannelReadyToSend(transport == rtcp_packet_transport_, true);
 | 
|  }
 | 
|  
 | 
|  void BaseChannel::OnDtlsState(DtlsTransportInternal* transport,
 | 
| @@ -570,8 +636,10 @@ void BaseChannel::OnSelectedCandidatePairChanged(
 | 
|      CandidatePairInterface* selected_candidate_pair,
 | 
|      int last_sent_packet_id,
 | 
|      bool ready_to_send) {
 | 
| -  RTC_DCHECK(ice_transport == rtp_dtls_transport_->ice_transport() ||
 | 
| -             ice_transport == rtcp_dtls_transport_->ice_transport());
 | 
| +  RTC_DCHECK((rtp_dtls_transport_ &&
 | 
| +              ice_transport == rtp_dtls_transport_->ice_transport()) ||
 | 
| +             (rtcp_dtls_transport_ &&
 | 
| +              ice_transport == rtcp_dtls_transport_->ice_transport()));
 | 
|    RTC_DCHECK(network_thread_->IsCurrent());
 | 
|    selected_candidate_pair_ = selected_candidate_pair;
 | 
|    std::string transport_name = ice_transport->transport_name();
 | 
| @@ -600,8 +668,8 @@ void BaseChannel::SetTransportChannelReadyToSend(bool rtcp, bool ready) {
 | 
|  
 | 
|    bool ready_to_send =
 | 
|        (rtp_ready_to_send_ &&
 | 
| -       // In the case of rtcp mux |rtcp_dtls_transport_| will be null.
 | 
| -       (rtcp_ready_to_send_ || !rtcp_dtls_transport_));
 | 
| +       // In the case of rtcp mux |rtcp_packet_transport_| will be null.
 | 
| +       (rtcp_ready_to_send_ || !rtcp_packet_transport_));
 | 
|  
 | 
|    invoker_.AsyncInvoke<void>(
 | 
|        RTC_FROM_HERE, worker_thread_,
 | 
| @@ -611,7 +679,7 @@ void BaseChannel::SetTransportChannelReadyToSend(bool rtcp, bool ready) {
 | 
|  bool BaseChannel::PacketIsRtcp(const rtc::PacketTransportInterface* transport,
 | 
|                                 const char* data,
 | 
|                                 size_t len) {
 | 
| -  return (transport == rtcp_dtls_transport_ ||
 | 
| +  return (transport == rtcp_packet_transport_ ||
 | 
|            rtcp_mux_filter_.DemuxRtcp(data, static_cast<int>(len)));
 | 
|  }
 | 
|  
 | 
| @@ -640,9 +708,9 @@ bool BaseChannel::SendPacket(bool rtcp,
 | 
|    // packet before doing anything. (We might get RTCP packets that we don't
 | 
|    // intend to send.) If we've negotiated RTCP mux, send RTCP over the RTP
 | 
|    // transport.
 | 
| -  DtlsTransportInternal* transport = (!rtcp || rtcp_mux_filter_.IsActive())
 | 
| -                                         ? rtp_dtls_transport_
 | 
| -                                         : rtcp_dtls_transport_;
 | 
| +  rtc::PacketTransportInterface* transport =
 | 
| +      (!rtcp || rtcp_mux_filter_.IsActive()) ? rtp_packet_transport_
 | 
| +                                             : rtcp_packet_transport_;
 | 
|    if (!transport || !transport->writable()) {
 | 
|      return false;
 | 
|    }
 | 
| @@ -891,8 +959,8 @@ void BaseChannel::DisableMedia_w() {
 | 
|  }
 | 
|  
 | 
|  void BaseChannel::UpdateWritableState_n() {
 | 
| -  if (rtp_dtls_transport_ && rtp_dtls_transport_->writable() &&
 | 
| -      (!rtcp_dtls_transport_ || rtcp_dtls_transport_->writable())) {
 | 
| +  if (rtp_packet_transport_ && rtp_packet_transport_->writable() &&
 | 
| +      (!rtcp_packet_transport_ || rtcp_packet_transport_->writable())) {
 | 
|      ChannelWritable_n();
 | 
|    } else {
 | 
|      ChannelNotWritable_n();
 | 
| @@ -959,7 +1027,7 @@ bool BaseChannel::SetupDtlsSrtp_n(bool rtcp) {
 | 
|  
 | 
|    DtlsTransportInternal* transport =
 | 
|        rtcp ? rtcp_dtls_transport_ : rtp_dtls_transport_;
 | 
| -
 | 
| +  RTC_DCHECK(transport);
 | 
|    RTC_DCHECK(transport->IsDtlsActive());
 | 
|  
 | 
|    int selected_crypto_suite;
 | 
| @@ -1110,7 +1178,7 @@ bool BaseChannel::SetRtpTransportParameters_n(
 | 
|  bool BaseChannel::CheckSrtpConfig_n(const std::vector<CryptoParams>& cryptos,
 | 
|                                      bool* dtls,
 | 
|                                      std::string* error_desc) {
 | 
| -  *dtls = rtp_dtls_transport_->IsDtlsActive();
 | 
| +  *dtls = rtp_dtls_transport_ && rtp_dtls_transport_->IsDtlsActive();
 | 
|    if (*dtls && !cryptos.empty()) {
 | 
|      SafeSetError("Cryptos must be empty when DTLS is active.", error_desc);
 | 
|      return false;
 | 
| @@ -1195,9 +1263,9 @@ bool BaseChannel::SetRtcpMux_n(bool enable,
 | 
|          LOG(LS_INFO) << "Enabling rtcp-mux for " << content_name()
 | 
|                       << " by destroying RTCP transport for "
 | 
|                       << transport_name();
 | 
| -        if (rtcp_dtls_transport()) {
 | 
| -          SetTransport_n(true, nullptr);
 | 
| -          SignalRtcpMuxFullyActive(rtp_dtls_transport()->transport_name());
 | 
| +        if (rtcp_packet_transport_) {
 | 
| +          SetTransport_n(true, nullptr, nullptr);
 | 
| +          SignalRtcpMuxFullyActive(transport_name_);
 | 
|          }
 | 
|          UpdateWritableState_n();
 | 
|          SetTransportChannelReadyToSend(true, false);
 | 
| @@ -1219,7 +1287,7 @@ bool BaseChannel::SetRtcpMux_n(bool enable,
 | 
|    // a final answer.
 | 
|    if (rtcp_mux_filter_.IsActive()) {
 | 
|      // If the RTP transport is already writable, then so are we.
 | 
| -    if (rtp_dtls_transport_->writable()) {
 | 
| +    if (rtp_packet_transport_->writable()) {
 | 
|        ChannelWritable_n();
 | 
|      }
 | 
|    }
 | 
| @@ -1479,11 +1547,6 @@ VoiceChannel::~VoiceChannel() {
 | 
|    Deinit();
 | 
|  }
 | 
|  
 | 
| -bool VoiceChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
 | 
| -                          DtlsTransportInternal* rtcp_dtls_transport) {
 | 
| -  return BaseChannel::Init_w(rtp_dtls_transport, rtcp_dtls_transport);
 | 
| -}
 | 
| -
 | 
|  bool VoiceChannel::SetAudioSend(uint32_t ssrc,
 | 
|                                  bool enable,
 | 
|                                  const AudioOptions* options,
 | 
| @@ -1881,11 +1944,6 @@ VideoChannel::VideoChannel(rtc::Thread* worker_thread,
 | 
|                    rtcp_mux_required,
 | 
|                    srtp_required) {}
 | 
|  
 | 
| -bool VideoChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
 | 
| -                          DtlsTransportInternal* rtcp_dtls_transport) {
 | 
| -  return BaseChannel::Init_w(rtp_dtls_transport, rtcp_dtls_transport);
 | 
| -}
 | 
| -
 | 
|  VideoChannel::~VideoChannel() {
 | 
|    TRACE_EVENT0("webrtc", "VideoChannel::~VideoChannel");
 | 
|    StopMediaMonitor();
 | 
| @@ -2151,9 +2209,13 @@ RtpDataChannel::~RtpDataChannel() {
 | 
|    Deinit();
 | 
|  }
 | 
|  
 | 
| -bool RtpDataChannel::Init_w(DtlsTransportInternal* rtp_dtls_transport,
 | 
| -                            DtlsTransportInternal* rtcp_dtls_transport) {
 | 
| -  if (!BaseChannel::Init_w(rtp_dtls_transport, rtcp_dtls_transport)) {
 | 
| +bool RtpDataChannel::Init_w(
 | 
| +    DtlsTransportInternal* rtp_dtls_transport,
 | 
| +    DtlsTransportInternal* rtcp_dtls_transport,
 | 
| +    rtc::PacketTransportInterface* rtp_packet_transport,
 | 
| +    rtc::PacketTransportInterface* rtcp_packet_transport) {
 | 
| +  if (!BaseChannel::Init_w(rtp_dtls_transport, rtcp_dtls_transport,
 | 
| +                           rtp_packet_transport, rtcp_packet_transport)) {
 | 
|      return false;
 | 
|    }
 | 
|    media_channel()->SignalDataReceived.connect(this,
 | 
| 
 |