OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. |
| 3 * |
| 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ |
| 10 |
| 11 #include <map> |
| 12 #include <utility> |
| 13 #include <vector> |
| 14 |
| 15 #include "webrtc/base/ptr_util.h" |
| 16 #include "webrtc/call/rtp_transport_controller_receive.h" |
| 17 #include "webrtc/modules/congestion_controller/include/receive_side_congestion_c
ontroller.h" |
| 18 #include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" |
| 19 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" |
| 20 |
| 21 namespace webrtc { |
| 22 namespace { |
| 23 |
| 24 class RtpTransportControllerReceive |
| 25 : public RtpTransportControllerReceiveInterface { |
| 26 public: |
| 27 RtpTransportControllerReceive( |
| 28 ReceiveSideCongestionController* receive_side_cc, |
| 29 bool enable_receive_side_bwe); |
| 30 |
| 31 ~RtpTransportControllerReceive() override; |
| 32 |
| 33 // ImplementRtpTransportControllerReceiveInterface |
| 34 void AddReceiver(uint32_t ssrc, |
| 35 const Config& config, |
| 36 RtpPacketReceiverInterface* receiver) override; |
| 37 void RemoveReceiver(const RtpPacketReceiverInterface* receiver) override; |
| 38 |
| 39 void AddSink(uint32_t ssrc, RtpPacketSinkInterface* sink) override; |
| 40 void RemoveSink(const RtpPacketSinkInterface* sink) override; |
| 41 |
| 42 PacketReceiver::DeliveryStatus OnRtpPacket( |
| 43 int64_t arrival_time_ms, |
| 44 rtc::ArrayView<const uint8_t> packet) override; |
| 45 |
| 46 private: |
| 47 struct Stream { |
| 48 Config config; |
| 49 RtpPacketReceiverInterface* receiver; |
| 50 std::vector<RtpPacketSinkInterface*> auxillary_sinks; |
| 51 |
| 52 Stream(Config config, RtpPacketReceiverInterface* receiver) |
| 53 : config(config), receiver(receiver) {} |
| 54 }; |
| 55 |
| 56 Stream* LookupStream(uint32_t ssrc); |
| 57 |
| 58 // Indexed by ssrc. |
| 59 std::map<uint32_t, Stream> streams_; |
| 60 ReceiveSideCongestionController* const receive_side_cc_; |
| 61 const bool enable_receive_side_bwe_; |
| 62 }; |
| 63 |
| 64 RtpTransportControllerReceive::RtpTransportControllerReceive( |
| 65 ReceiveSideCongestionController* receive_side_cc, |
| 66 bool enable_receive_side_bwe) |
| 67 : receive_side_cc_(receive_side_cc), |
| 68 enable_receive_side_bwe_(enable_receive_side_bwe) {} |
| 69 |
| 70 RtpTransportControllerReceive::~RtpTransportControllerReceive() { |
| 71 RTC_DCHECK(streams_.empty()); |
| 72 } |
| 73 |
| 74 RtpTransportControllerReceive::Stream* |
| 75 RtpTransportControllerReceive::LookupStream(uint32_t ssrc) { |
| 76 const auto it = streams_.find(ssrc); |
| 77 return (it != streams_.end()) ? &it->second : nullptr; |
| 78 } |
| 79 |
| 80 void RtpTransportControllerReceive::AddReceiver( |
| 81 uint32_t ssrc, |
| 82 const Config& config, |
| 83 RtpPacketReceiverInterface* receiver) { |
| 84 bool inserted = streams_.emplace(ssrc, Stream(config, receiver)).second; |
| 85 RTC_DCHECK(inserted); |
| 86 } |
| 87 |
| 88 void RtpTransportControllerReceive::RemoveReceiver( |
| 89 const RtpPacketReceiverInterface* receiver) { |
| 90 for (auto it = streams_.begin(); it != streams_.end();) { |
| 91 if (it->second.receiver == receiver) { |
| 92 receive_side_cc_ |
| 93 ->GetRemoteBitrateEstimator(it->second.config.use_send_side_bwe) |
| 94 ->RemoveStream(it->first); |
| 95 it = streams_.erase(it); |
| 96 } else { |
| 97 ++it; |
| 98 } |
| 99 } |
| 100 } |
| 101 |
| 102 void RtpTransportControllerReceive::AddSink(uint32_t ssrc, |
| 103 RtpPacketSinkInterface* sink) { |
| 104 Stream* stream = LookupStream(ssrc); |
| 105 // Can't DCHECK this, since flexfec tests create flexfec streams |
| 106 // without creating the streams they are protecting. |
| 107 if (!stream) { |
| 108 return; |
| 109 } |
| 110 stream->auxillary_sinks.push_back(sink); |
| 111 } |
| 112 |
| 113 void RtpTransportControllerReceive::RemoveSink( |
| 114 const RtpPacketSinkInterface* sink) { |
| 115 for (auto& it : streams_) { |
| 116 auto sinks_end = it.second.auxillary_sinks.end(); |
| 117 auto sinks_it = |
| 118 std::remove(it.second.auxillary_sinks.begin(), sinks_end, sink); |
| 119 it.second.auxillary_sinks.erase(sinks_it, sinks_end); |
| 120 } |
| 121 } |
| 122 |
| 123 PacketReceiver::DeliveryStatus RtpTransportControllerReceive::OnRtpPacket( |
| 124 int64_t arrival_time_ms, |
| 125 rtc::ArrayView<const uint8_t> raw_packet) { |
| 126 RtpPacketReceived parsed_packet; |
| 127 if (!parsed_packet.Parse(raw_packet)) { |
| 128 return PacketReceiver::DELIVERY_PACKET_ERROR; |
| 129 } |
| 130 parsed_packet.set_arrival_time_ms(arrival_time_ms); |
| 131 |
| 132 Stream* stream = LookupStream(parsed_packet.Ssrc()); |
| 133 if (!stream) { |
| 134 return PacketReceiver::DELIVERY_UNKNOWN_SSRC; |
| 135 } |
| 136 if (!stream->receiver->OnRtpPacketReceive(&parsed_packet)) { |
| 137 return PacketReceiver::DELIVERY_PACKET_ERROR; |
| 138 } |
| 139 for (auto* it : stream->auxillary_sinks) { |
| 140 it->OnRtpPacket(parsed_packet); |
| 141 } |
| 142 if (receive_side_cc_) { |
| 143 if (!stream->config.use_send_side_bwe && |
| 144 parsed_packet.HasExtension<TransportSequenceNumber>()) { |
| 145 // Inconsistent configuration of send side BWE. Do nothing. |
| 146 // TODO(nisse): Without this check, we may produce RTCP feedback |
| 147 // packets even when not negotiated. But it would be cleaner to |
| 148 // move the check down to RTCPSender::SendFeedbackPacket, which |
| 149 // would also help the PacketRouter to select an appropriate rtp |
| 150 // module in the case that some, but not all, have RTCP feedback |
| 151 // enabled. |
| 152 return PacketReceiver::DELIVERY_OK; |
| 153 } |
| 154 // Receive side bwe is not used for audio. |
| 155 if (enable_receive_side_bwe_ || |
| 156 (stream->config.use_send_side_bwe && |
| 157 parsed_packet.HasExtension<TransportSequenceNumber>())) { |
| 158 RTPHeader header; |
| 159 parsed_packet.GetHeader(&header); |
| 160 |
| 161 receive_side_cc_->OnReceivedPacket( |
| 162 parsed_packet.arrival_time_ms(), |
| 163 parsed_packet.payload_size() + parsed_packet.padding_size(), header); |
| 164 } |
| 165 } |
| 166 return PacketReceiver::DELIVERY_OK; |
| 167 } |
| 168 |
| 169 } // namespace |
| 170 |
| 171 // static |
| 172 std::unique_ptr<RtpTransportControllerReceiveInterface> |
| 173 RtpTransportControllerReceiveInterface::Create( |
| 174 ReceiveSideCongestionController* receive_side_cc, |
| 175 bool enable_receive_side_bwe) { |
| 176 return rtc::MakeUnique<RtpTransportControllerReceive>( |
| 177 receive_side_cc, enable_receive_side_bwe); |
| 178 } |
| 179 |
| 180 } // namespace webrtc |
OLD | NEW |