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/call/rtp_transport_controller_receive.h" |
| 16 |
| 17 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" |
| 18 |
| 19 namespace webrtc { |
| 20 |
| 21 class RtpTransportControllerReceive |
| 22 : public RtpTransportControllerReceiveInterface { |
| 23 public: |
| 24 RtpTransportControllerReceive(RtpPacketObserverInterface* observer); |
| 25 |
| 26 // ImplementRtpTransportControllerReceiveInterface |
| 27 bool AddReceiver(uint32_t ssrc, |
| 28 MediaType media_type, |
| 29 const Config& config, |
| 30 RtpPacketReceiverInterface* receiver) override; |
| 31 bool RemoveReceiver(const RtpPacketReceiverInterface* receiver) override; |
| 32 |
| 33 bool AddSink(uint32_t ssrc, |
| 34 MediaType media_type, |
| 35 RtpPacketSinkInterface* sink) override; |
| 36 bool RemoveSink(const RtpPacketSinkInterface* sink) override; |
| 37 |
| 38 #if 0 |
| 39 bool RegisterPayload(uint8_t payload_type, MediaType media_type, |
| 40 RtpPacketReceiverInterface *receiver) override; |
| 41 #endif |
| 42 PacketReceiver::DeliveryStatus OnRtpPacket( |
| 43 MediaType media_type, |
| 44 int64_t arrival_time_ms, |
| 45 rtc::ArrayView<const uint8_t> packet) override; |
| 46 |
| 47 ~RtpTransportControllerReceive() override; |
| 48 |
| 49 private: |
| 50 struct Stream { |
| 51 MediaType media_type = MediaType::ANY; |
| 52 Config config; |
| 53 RtpPacketReceiverInterface* receiver = nullptr; |
| 54 std::vector<RtpPacketSinkInterface*> auxillary_sinks; |
| 55 |
| 56 Stream(MediaType media_type, |
| 57 Config config, |
| 58 RtpPacketReceiverInterface* receiver) |
| 59 : media_type(media_type), config(config), receiver(receiver) {} |
| 60 }; |
| 61 |
| 62 Stream* LookupStream(uint32_t ssrc, MediaType media_type); |
| 63 |
| 64 // Indexed by ssrc. We could use a map indexed by pairs (media_type, ssrc), |
| 65 // except that we want special handling of MediaType:ANY specially. |
| 66 std::multimap<uint32_t, Stream> streams_; |
| 67 RtpPacketObserverInterface* observer_; |
| 68 }; |
| 69 |
| 70 RtpTransportControllerReceive::RtpTransportControllerReceive( |
| 71 RtpPacketObserverInterface* observer) |
| 72 : observer_(observer) {} |
| 73 |
| 74 RtpTransportControllerReceive::~RtpTransportControllerReceive() { |
| 75 RTC_DCHECK(streams_.empty()); |
| 76 } |
| 77 |
| 78 RtpTransportControllerReceive::Stream* |
| 79 RtpTransportControllerReceive::LookupStream(uint32_t ssrc, |
| 80 MediaType media_type) { |
| 81 auto range = streams_.equal_range(ssrc); |
| 82 for (auto it = range.first; it != range.second; ++it) { |
| 83 if (media_type == MediaType::ANY || media_type == it->second.media_type) |
| 84 return &it->second; |
| 85 } |
| 86 return nullptr; |
| 87 } |
| 88 |
| 89 bool RtpTransportControllerReceive::AddReceiver( |
| 90 uint32_t ssrc, |
| 91 MediaType media_type, |
| 92 const Config& config, |
| 93 RtpPacketReceiverInterface* receiver) { |
| 94 if (LookupStream(ssrc, media_type)) { |
| 95 return false; |
| 96 } |
| 97 streams_.insert( |
| 98 std::pair<uint32_t, Stream>(ssrc, Stream(media_type, config, receiver))); |
| 99 return true; |
| 100 } |
| 101 |
| 102 bool RtpTransportControllerReceive::RemoveReceiver( |
| 103 const RtpPacketReceiverInterface* receiver) { |
| 104 for (auto it = streams_.begin(); it != streams_.end(); ++it) { |
| 105 if (it->second.receiver == receiver) { |
| 106 streams_.erase(it); |
| 107 return true; |
| 108 } |
| 109 } |
| 110 return false; |
| 111 } |
| 112 |
| 113 bool RtpTransportControllerReceive::AddSink(uint32_t ssrc, |
| 114 MediaType media_type, |
| 115 RtpPacketSinkInterface* sink) { |
| 116 Stream* stream = LookupStream(ssrc, media_type); |
| 117 if (stream) { |
| 118 stream->auxillary_sinks.push_back(sink); |
| 119 return true; |
| 120 } |
| 121 return false; |
| 122 } |
| 123 |
| 124 bool RtpTransportControllerReceive::RemoveSink( |
| 125 const RtpPacketSinkInterface* sink) { |
| 126 bool found = false; |
| 127 for (auto it : streams_) { |
| 128 auto sinks_end = it.second.auxillary_sinks.end(); |
| 129 auto sinks_it = |
| 130 std::remove(it.second.auxillary_sinks.begin(), sinks_end, sink); |
| 131 if (sinks_it != sinks_end) { |
| 132 it.second.auxillary_sinks.erase(sinks_it, sinks_end); |
| 133 found = true; |
| 134 } |
| 135 } |
| 136 return found; |
| 137 } |
| 138 |
| 139 PacketReceiver::DeliveryStatus RtpTransportControllerReceive::OnRtpPacket( |
| 140 MediaType media_type, |
| 141 int64_t arrival_time_ms, |
| 142 rtc::ArrayView<const uint8_t> raw_packet) { |
| 143 RtpPacketReceived parsed_packet; |
| 144 if (!parsed_packet.Parse(raw_packet.data(), raw_packet.size())) |
| 145 return PacketReceiver::DELIVERY_PACKET_ERROR; |
| 146 parsed_packet.set_arrival_time_ms(arrival_time_ms); |
| 147 |
| 148 Stream* stream = LookupStream(parsed_packet.Ssrc(), media_type); |
| 149 if (!stream) { |
| 150 // TODO(nisse): Lookup payload, for unsignalled streams. |
| 151 return PacketReceiver::DELIVERY_UNKNOWN_SSRC; |
| 152 } |
| 153 if (!stream->receiver->OnRtpPacketReceive(&parsed_packet)) |
| 154 return PacketReceiver::DELIVERY_PACKET_ERROR; |
| 155 for (auto it : stream->auxillary_sinks) { |
| 156 it->OnRtpPacket(parsed_packet); |
| 157 } |
| 158 if (observer_) |
| 159 observer_->OnRtpPacket(media_type, stream->config, parsed_packet); |
| 160 return PacketReceiver::DELIVERY_OK; |
| 161 } |
| 162 |
| 163 // static |
| 164 std::unique_ptr<RtpTransportControllerReceiveInterface> |
| 165 RtpTransportControllerReceiveInterface::Create( |
| 166 RtpPacketObserverInterface* observer) { |
| 167 return std::unique_ptr<RtpTransportControllerReceiveInterface>( |
| 168 new RtpTransportControllerReceive(observer)); |
| 169 } |
| 170 |
| 171 } // namespace webrtc |
OLD | NEW |