henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 1 | /* |
kjellander | 1afca73 | 2016-02-07 20:46:45 -0800 | [diff] [blame^] | 2 | * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 3 | * |
kjellander | 1afca73 | 2016-02-07 20:46:45 -0800 | [diff] [blame^] | 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. |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 9 | */ |
| 10 | |
kjellander | a96e2d7 | 2016-02-04 23:52:28 -0800 | [diff] [blame] | 11 | #ifndef WEBRTC_MEDIA_BASE_FAKENETWORKINTERFACE_H_ |
| 12 | #define WEBRTC_MEDIA_BASE_FAKENETWORKINTERFACE_H_ |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 13 | |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 14 | #include <map> |
buildbot@webrtc.org | a09a999 | 2014-08-13 17:26:08 +0000 | [diff] [blame] | 15 | #include <vector> |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 16 | |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 17 | #include "webrtc/base/buffer.h" |
| 18 | #include "webrtc/base/byteorder.h" |
| 19 | #include "webrtc/base/criticalsection.h" |
| 20 | #include "webrtc/base/dscp.h" |
| 21 | #include "webrtc/base/messagehandler.h" |
| 22 | #include "webrtc/base/messagequeue.h" |
| 23 | #include "webrtc/base/thread.h" |
kjellander | a96e2d7 | 2016-02-04 23:52:28 -0800 | [diff] [blame] | 24 | #include "webrtc/media/base/mediachannel.h" |
| 25 | #include "webrtc/media/base/rtputils.h" |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 26 | |
| 27 | namespace cricket { |
| 28 | |
| 29 | // Fake NetworkInterface that sends/receives RTP/RTCP packets. |
| 30 | class FakeNetworkInterface : public MediaChannel::NetworkInterface, |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 31 | public rtc::MessageHandler { |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 32 | public: |
| 33 | FakeNetworkInterface() |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 34 | : thread_(rtc::Thread::Current()), |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 35 | dest_(NULL), |
| 36 | conf_(false), |
| 37 | sendbuf_size_(-1), |
wu@webrtc.org | de30501 | 2013-10-31 15:40:38 +0000 | [diff] [blame] | 38 | recvbuf_size_(-1), |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 39 | dscp_(rtc::DSCP_NO_CHANGE) { |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 40 | } |
| 41 | |
| 42 | void SetDestination(MediaChannel* dest) { dest_ = dest; } |
| 43 | |
| 44 | // Conference mode is a mode where instead of simply forwarding the packets, |
| 45 | // the transport will send multiple copies of the packet with the specified |
| 46 | // SSRCs. This allows us to simulate receiving media from multiple sources. |
Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 47 | void SetConferenceMode(bool conf, const std::vector<uint32_t>& ssrcs) { |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 48 | rtc::CritScope cs(&crit_); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 49 | conf_ = conf; |
| 50 | conf_sent_ssrcs_ = ssrcs; |
| 51 | } |
| 52 | |
| 53 | int NumRtpBytes() { |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 54 | rtc::CritScope cs(&crit_); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 55 | int bytes = 0; |
| 56 | for (size_t i = 0; i < rtp_packets_.size(); ++i) { |
kwiberg@webrtc.org | eebcab5 | 2015-03-24 09:19:06 +0000 | [diff] [blame] | 57 | bytes += static_cast<int>(rtp_packets_[i].size()); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 58 | } |
| 59 | return bytes; |
| 60 | } |
| 61 | |
Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 62 | int NumRtpBytes(uint32_t ssrc) { |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 63 | rtc::CritScope cs(&crit_); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 64 | int bytes = 0; |
| 65 | GetNumRtpBytesAndPackets(ssrc, &bytes, NULL); |
| 66 | return bytes; |
| 67 | } |
| 68 | |
| 69 | int NumRtpPackets() { |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 70 | rtc::CritScope cs(&crit_); |
henrike@webrtc.org | 28654cb | 2013-07-22 21:07:49 +0000 | [diff] [blame] | 71 | return static_cast<int>(rtp_packets_.size()); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 72 | } |
| 73 | |
Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 74 | int NumRtpPackets(uint32_t ssrc) { |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 75 | rtc::CritScope cs(&crit_); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 76 | int packets = 0; |
| 77 | GetNumRtpBytesAndPackets(ssrc, NULL, &packets); |
| 78 | return packets; |
| 79 | } |
| 80 | |
| 81 | int NumSentSsrcs() { |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 82 | rtc::CritScope cs(&crit_); |
henrike@webrtc.org | 28654cb | 2013-07-22 21:07:49 +0000 | [diff] [blame] | 83 | return static_cast<int>(sent_ssrcs_.size()); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 84 | } |
| 85 | |
| 86 | // Note: callers are responsible for deleting the returned buffer. |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 87 | const rtc::Buffer* GetRtpPacket(int index) { |
| 88 | rtc::CritScope cs(&crit_); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 89 | if (index >= NumRtpPackets()) { |
| 90 | return NULL; |
| 91 | } |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 92 | return new rtc::Buffer(rtp_packets_[index]); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 93 | } |
| 94 | |
| 95 | int NumRtcpPackets() { |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 96 | rtc::CritScope cs(&crit_); |
henrike@webrtc.org | 28654cb | 2013-07-22 21:07:49 +0000 | [diff] [blame] | 97 | return static_cast<int>(rtcp_packets_.size()); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 98 | } |
| 99 | |
| 100 | // Note: callers are responsible for deleting the returned buffer. |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 101 | const rtc::Buffer* GetRtcpPacket(int index) { |
| 102 | rtc::CritScope cs(&crit_); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 103 | if (index >= NumRtcpPackets()) { |
| 104 | return NULL; |
| 105 | } |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 106 | return new rtc::Buffer(rtcp_packets_[index]); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 107 | } |
| 108 | |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 109 | int sendbuf_size() const { return sendbuf_size_; } |
| 110 | int recvbuf_size() const { return recvbuf_size_; } |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 111 | rtc::DiffServCodePoint dscp() const { return dscp_; } |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 112 | |
| 113 | protected: |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 114 | virtual bool SendPacket(rtc::Buffer* packet, |
stefan | c1aeaf0 | 2015-10-15 07:26:07 -0700 | [diff] [blame] | 115 | const rtc::PacketOptions& options) { |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 116 | rtc::CritScope cs(&crit_); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 117 | |
Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 118 | uint32_t cur_ssrc = 0; |
kwiberg@webrtc.org | eebcab5 | 2015-03-24 09:19:06 +0000 | [diff] [blame] | 119 | if (!GetRtpSsrc(packet->data(), packet->size(), &cur_ssrc)) { |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 120 | return false; |
| 121 | } |
| 122 | sent_ssrcs_[cur_ssrc]++; |
| 123 | |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 124 | rtp_packets_.push_back(*packet); |
| 125 | if (conf_) { |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 126 | rtc::Buffer buffer_copy(*packet); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 127 | for (size_t i = 0; i < conf_sent_ssrcs_.size(); ++i) { |
kwiberg@webrtc.org | eebcab5 | 2015-03-24 09:19:06 +0000 | [diff] [blame] | 128 | if (!SetRtpSsrc(buffer_copy.data(), buffer_copy.size(), |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 129 | conf_sent_ssrcs_[i])) { |
| 130 | return false; |
| 131 | } |
| 132 | PostMessage(ST_RTP, buffer_copy); |
| 133 | } |
| 134 | } else { |
| 135 | PostMessage(ST_RTP, *packet); |
| 136 | } |
| 137 | return true; |
| 138 | } |
| 139 | |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 140 | virtual bool SendRtcp(rtc::Buffer* packet, |
stefan | c1aeaf0 | 2015-10-15 07:26:07 -0700 | [diff] [blame] | 141 | const rtc::PacketOptions& options) { |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 142 | rtc::CritScope cs(&crit_); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 143 | rtcp_packets_.push_back(*packet); |
| 144 | if (!conf_) { |
| 145 | // don't worry about RTCP in conf mode for now |
| 146 | PostMessage(ST_RTCP, *packet); |
| 147 | } |
| 148 | return true; |
| 149 | } |
| 150 | |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 151 | virtual int SetOption(SocketType type, rtc::Socket::Option opt, |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 152 | int option) { |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 153 | if (opt == rtc::Socket::OPT_SNDBUF) { |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 154 | sendbuf_size_ = option; |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 155 | } else if (opt == rtc::Socket::OPT_RCVBUF) { |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 156 | recvbuf_size_ = option; |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 157 | } else if (opt == rtc::Socket::OPT_DSCP) { |
| 158 | dscp_ = static_cast<rtc::DiffServCodePoint>(option); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 159 | } |
| 160 | return 0; |
| 161 | } |
| 162 | |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 163 | void PostMessage(int id, const rtc::Buffer& packet) { |
| 164 | thread_->Post(this, id, rtc::WrapMessageData(packet)); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 165 | } |
| 166 | |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 167 | virtual void OnMessage(rtc::Message* msg) { |
| 168 | rtc::TypedMessageData<rtc::Buffer>* msg_data = |
| 169 | static_cast<rtc::TypedMessageData<rtc::Buffer>*>( |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 170 | msg->pdata); |
| 171 | if (dest_) { |
| 172 | if (msg->message_id == ST_RTP) { |
wu@webrtc.org | a989080 | 2013-12-13 00:21:03 +0000 | [diff] [blame] | 173 | dest_->OnPacketReceived(&msg_data->data(), |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 174 | rtc::CreatePacketTime(0)); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 175 | } else { |
wu@webrtc.org | a989080 | 2013-12-13 00:21:03 +0000 | [diff] [blame] | 176 | dest_->OnRtcpReceived(&msg_data->data(), |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 177 | rtc::CreatePacketTime(0)); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 178 | } |
| 179 | } |
| 180 | delete msg_data; |
| 181 | } |
| 182 | |
| 183 | private: |
Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 184 | void GetNumRtpBytesAndPackets(uint32_t ssrc, int* bytes, int* packets) { |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 185 | if (bytes) { |
| 186 | *bytes = 0; |
| 187 | } |
| 188 | if (packets) { |
| 189 | *packets = 0; |
| 190 | } |
Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 191 | uint32_t cur_ssrc = 0; |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 192 | for (size_t i = 0; i < rtp_packets_.size(); ++i) { |
kwiberg@webrtc.org | eebcab5 | 2015-03-24 09:19:06 +0000 | [diff] [blame] | 193 | if (!GetRtpSsrc(rtp_packets_[i].data(), rtp_packets_[i].size(), |
| 194 | &cur_ssrc)) { |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 195 | return; |
| 196 | } |
| 197 | if (ssrc == cur_ssrc) { |
| 198 | if (bytes) { |
kwiberg@webrtc.org | eebcab5 | 2015-03-24 09:19:06 +0000 | [diff] [blame] | 199 | *bytes += static_cast<int>(rtp_packets_[i].size()); |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 200 | } |
| 201 | if (packets) { |
| 202 | ++(*packets); |
| 203 | } |
| 204 | } |
| 205 | } |
| 206 | } |
| 207 | |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 208 | rtc::Thread* thread_; |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 209 | MediaChannel* dest_; |
| 210 | bool conf_; |
| 211 | // The ssrcs used in sending out packets in conference mode. |
Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 212 | std::vector<uint32_t> conf_sent_ssrcs_; |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 213 | // Map to track counts of packets that have been sent per ssrc. |
| 214 | // This includes packets that are dropped. |
Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 215 | std::map<uint32_t, uint32_t> sent_ssrcs_; |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 216 | // Map to track packet-number that needs to be dropped per ssrc. |
Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 217 | std::map<uint32_t, std::set<uint32_t> > drop_map_; |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 218 | rtc::CriticalSection crit_; |
| 219 | std::vector<rtc::Buffer> rtp_packets_; |
| 220 | std::vector<rtc::Buffer> rtcp_packets_; |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 221 | int sendbuf_size_; |
| 222 | int recvbuf_size_; |
buildbot@webrtc.org | d4e598d | 2014-07-29 17:36:52 +0000 | [diff] [blame] | 223 | rtc::DiffServCodePoint dscp_; |
henrike@webrtc.org | 28e2075 | 2013-07-10 00:45:36 +0000 | [diff] [blame] | 224 | }; |
| 225 | |
| 226 | } // namespace cricket |
| 227 | |
kjellander | a96e2d7 | 2016-02-04 23:52:28 -0800 | [diff] [blame] | 228 | #endif // WEBRTC_MEDIA_BASE_FAKENETWORKINTERFACE_H_ |