fake_network_interface.h (7253B)
1 /* 2 * Copyright (c) 2004 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 #ifndef MEDIA_BASE_FAKE_NETWORK_INTERFACE_H_ 12 #define MEDIA_BASE_FAKE_NETWORK_INTERFACE_H_ 13 14 #include <cstddef> 15 #include <cstdint> 16 #include <map> 17 #include <set> 18 #include <utility> 19 #include <vector> 20 21 #include "api/task_queue/pending_task_safety_flag.h" 22 #include "api/task_queue/task_queue_base.h" 23 #include "api/units/timestamp.h" 24 #include "media/base/media_channel.h" 25 #include "modules/rtp_rtcp/source/rtp_packet_received.h" 26 #include "modules/rtp_rtcp/source/rtp_util.h" 27 #include "rtc_base/async_packet_socket.h" 28 #include "rtc_base/byte_order.h" 29 #include "rtc_base/checks.h" 30 #include "rtc_base/copy_on_write_buffer.h" 31 #include "rtc_base/dscp.h" 32 #include "rtc_base/logging.h" 33 #include "rtc_base/socket.h" 34 #include "rtc_base/synchronization/mutex.h" 35 #include "rtc_base/thread.h" 36 #include "rtc_base/thread_annotations.h" 37 #include "rtc_base/time_utils.h" 38 39 namespace webrtc { 40 41 // Fake NetworkInterface that sends/receives RTP/RTCP packets. 42 class FakeNetworkInterface : public MediaChannelNetworkInterface { 43 public: 44 FakeNetworkInterface() 45 : thread_(Thread::Current()), 46 dest_(NULL), 47 conf_(false), 48 sendbuf_size_(-1), 49 recvbuf_size_(-1), 50 dscp_(DSCP_NO_CHANGE) {} 51 52 void SetDestination(MediaReceiveChannelInterface* dest) { dest_ = dest; } 53 54 // Conference mode is a mode where instead of simply forwarding the packets, 55 // the transport will send multiple copies of the packet with the specified 56 // SSRCs. This allows us to simulate receiving media from multiple sources. 57 void SetConferenceMode(bool conf, const std::vector<uint32_t>& ssrcs) 58 RTC_LOCKS_EXCLUDED(mutex_) { 59 MutexLock lock(&mutex_); 60 conf_ = conf; 61 conf_sent_ssrcs_ = ssrcs; 62 } 63 64 int NumRtpBytes() RTC_LOCKS_EXCLUDED(mutex_) { 65 MutexLock lock(&mutex_); 66 int bytes = 0; 67 for (size_t i = 0; i < rtp_packets_.size(); ++i) { 68 bytes += static_cast<int>(rtp_packets_[i].size()); 69 } 70 return bytes; 71 } 72 73 int NumRtpBytes(uint32_t ssrc) RTC_LOCKS_EXCLUDED(mutex_) { 74 MutexLock lock(&mutex_); 75 int bytes = 0; 76 GetNumRtpBytesAndPackets(ssrc, &bytes, NULL); 77 return bytes; 78 } 79 80 int NumRtpPackets() RTC_LOCKS_EXCLUDED(mutex_) { 81 MutexLock lock(&mutex_); 82 return static_cast<int>(rtp_packets_.size()); 83 } 84 85 int NumRtpPackets(uint32_t ssrc) RTC_LOCKS_EXCLUDED(mutex_) { 86 MutexLock lock(&mutex_); 87 int packets = 0; 88 GetNumRtpBytesAndPackets(ssrc, NULL, &packets); 89 return packets; 90 } 91 92 int NumSentSsrcs() RTC_LOCKS_EXCLUDED(mutex_) { 93 MutexLock lock(&mutex_); 94 return static_cast<int>(sent_ssrcs_.size()); 95 } 96 97 CopyOnWriteBuffer GetRtpPacket(int index) RTC_LOCKS_EXCLUDED(mutex_) { 98 MutexLock lock(&mutex_); 99 if (index >= static_cast<int>(rtp_packets_.size())) { 100 return {}; 101 } 102 return rtp_packets_[index]; 103 } 104 105 int NumRtcpPackets() RTC_LOCKS_EXCLUDED(mutex_) { 106 MutexLock lock(&mutex_); 107 return static_cast<int>(rtcp_packets_.size()); 108 } 109 110 // Note: callers are responsible for deleting the returned buffer. 111 const CopyOnWriteBuffer* GetRtcpPacket(int index) RTC_LOCKS_EXCLUDED(mutex_) { 112 MutexLock lock(&mutex_); 113 if (index >= static_cast<int>(rtcp_packets_.size())) { 114 return NULL; 115 } 116 return new CopyOnWriteBuffer(rtcp_packets_[index]); 117 } 118 119 int sendbuf_size() const { return sendbuf_size_; } 120 int recvbuf_size() const { return recvbuf_size_; } 121 DiffServCodePoint dscp() const { return dscp_; } 122 AsyncSocketPacketOptions options() const { return options_; } 123 124 protected: 125 virtual bool SendPacket(CopyOnWriteBuffer* packet, 126 const AsyncSocketPacketOptions& options) 127 RTC_LOCKS_EXCLUDED(mutex_) { 128 if (!IsRtpPacket(*packet)) { 129 return false; 130 } 131 132 MutexLock lock(&mutex_); 133 sent_ssrcs_[ParseRtpSsrc(*packet)]++; 134 options_ = options; 135 136 rtp_packets_.push_back(*packet); 137 if (conf_) { 138 for (size_t i = 0; i < conf_sent_ssrcs_.size(); ++i) { 139 SetRtpSsrc(conf_sent_ssrcs_[i], *packet); 140 PostPacket(*packet); 141 } 142 } else { 143 PostPacket(*packet); 144 } 145 return true; 146 } 147 148 virtual bool SendRtcp(CopyOnWriteBuffer* packet, 149 const AsyncSocketPacketOptions& options) 150 RTC_LOCKS_EXCLUDED(mutex_) { 151 MutexLock lock(&mutex_); 152 rtcp_packets_.push_back(*packet); 153 options_ = options; 154 if (!conf_) { 155 // don't worry about RTCP in conf mode for now 156 RTC_LOG(LS_VERBOSE) << "Dropping RTCP packet, they are not handled by " 157 "MediaChannel anymore."; 158 } 159 return true; 160 } 161 162 virtual int SetOption(SocketType /* type */, Socket::Option opt, int option) { 163 if (opt == Socket::OPT_SNDBUF) { 164 sendbuf_size_ = option; 165 } else if (opt == Socket::OPT_RCVBUF) { 166 recvbuf_size_ = option; 167 } else if (opt == Socket::OPT_DSCP) { 168 dscp_ = static_cast<DiffServCodePoint>(option); 169 } 170 return 0; 171 } 172 173 void PostPacket(CopyOnWriteBuffer packet) { 174 thread_->PostTask(SafeTask(safety_.flag(), [this, packet = std::move( 175 packet)]() mutable { 176 if (dest_) { 177 RtpPacketReceived parsed_packet; 178 if (parsed_packet.Parse(packet)) { 179 parsed_packet.set_arrival_time(Timestamp::Micros(TimeMicros())); 180 dest_->OnPacketReceived(std::move(parsed_packet)); 181 } else { 182 RTC_DCHECK_NOTREACHED(); 183 } 184 } 185 })); 186 } 187 188 private: 189 void SetRtpSsrc(uint32_t ssrc, CopyOnWriteBuffer& buffer) { 190 RTC_CHECK_GE(buffer.size(), 12); 191 SetBE32(buffer.MutableData() + 8, ssrc); 192 } 193 194 void GetNumRtpBytesAndPackets(uint32_t ssrc, int* bytes, int* packets) { 195 if (bytes) { 196 *bytes = 0; 197 } 198 if (packets) { 199 *packets = 0; 200 } 201 for (size_t i = 0; i < rtp_packets_.size(); ++i) { 202 if (ssrc == ParseRtpSsrc(rtp_packets_[i])) { 203 if (bytes) { 204 *bytes += static_cast<int>(rtp_packets_[i].size()); 205 } 206 if (packets) { 207 ++(*packets); 208 } 209 } 210 } 211 } 212 213 TaskQueueBase* thread_; 214 MediaReceiveChannelInterface* dest_; 215 bool conf_; 216 // The ssrcs used in sending out packets in conference mode. 217 std::vector<uint32_t> conf_sent_ssrcs_; 218 // Map to track counts of packets that have been sent per ssrc. 219 // This includes packets that are dropped. 220 std::map<uint32_t, uint32_t> sent_ssrcs_; 221 // Map to track packet-number that needs to be dropped per ssrc. 222 std::map<uint32_t, std::set<uint32_t> > drop_map_; 223 Mutex mutex_; 224 std::vector<CopyOnWriteBuffer> rtp_packets_; 225 std::vector<CopyOnWriteBuffer> rtcp_packets_; 226 int sendbuf_size_; 227 int recvbuf_size_; 228 DiffServCodePoint dscp_; 229 // Options of the most recently sent packet. 230 AsyncSocketPacketOptions options_; 231 ScopedTaskSafety safety_; 232 }; 233 234 } // namespace webrtc 235 236 237 #endif // MEDIA_BASE_FAKE_NETWORK_INTERFACE_H_