fake_network_interface.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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. #ifndef MEDIA_BASE_FAKE_NETWORK_INTERFACE_H_
  11. #define MEDIA_BASE_FAKE_NETWORK_INTERFACE_H_
  12. #include <map>
  13. #include <set>
  14. #include <vector>
  15. #include "media/base/media_channel.h"
  16. #include "media/base/rtp_utils.h"
  17. #include "rtc_base/byte_order.h"
  18. #include "rtc_base/copy_on_write_buffer.h"
  19. #include "rtc_base/dscp.h"
  20. #include "rtc_base/message_handler.h"
  21. #include "rtc_base/synchronization/mutex.h"
  22. #include "rtc_base/thread.h"
  23. namespace cricket {
  24. // Fake NetworkInterface that sends/receives RTP/RTCP packets.
  25. class FakeNetworkInterface : public MediaChannel::NetworkInterface,
  26. public rtc::MessageHandlerAutoCleanup {
  27. public:
  28. FakeNetworkInterface()
  29. : thread_(rtc::Thread::Current()),
  30. dest_(NULL),
  31. conf_(false),
  32. sendbuf_size_(-1),
  33. recvbuf_size_(-1),
  34. dscp_(rtc::DSCP_NO_CHANGE) {}
  35. void SetDestination(MediaChannel* dest) { dest_ = dest; }
  36. // Conference mode is a mode where instead of simply forwarding the packets,
  37. // the transport will send multiple copies of the packet with the specified
  38. // SSRCs. This allows us to simulate receiving media from multiple sources.
  39. void SetConferenceMode(bool conf, const std::vector<uint32_t>& ssrcs)
  40. RTC_LOCKS_EXCLUDED(mutex_) {
  41. webrtc::MutexLock lock(&mutex_);
  42. conf_ = conf;
  43. conf_sent_ssrcs_ = ssrcs;
  44. }
  45. int NumRtpBytes() RTC_LOCKS_EXCLUDED(mutex_) {
  46. webrtc::MutexLock lock(&mutex_);
  47. int bytes = 0;
  48. for (size_t i = 0; i < rtp_packets_.size(); ++i) {
  49. bytes += static_cast<int>(rtp_packets_[i].size());
  50. }
  51. return bytes;
  52. }
  53. int NumRtpBytes(uint32_t ssrc) RTC_LOCKS_EXCLUDED(mutex_) {
  54. webrtc::MutexLock lock(&mutex_);
  55. int bytes = 0;
  56. GetNumRtpBytesAndPackets(ssrc, &bytes, NULL);
  57. return bytes;
  58. }
  59. int NumRtpPackets() RTC_LOCKS_EXCLUDED(mutex_) {
  60. webrtc::MutexLock lock(&mutex_);
  61. return static_cast<int>(rtp_packets_.size());
  62. }
  63. int NumRtpPackets(uint32_t ssrc) RTC_LOCKS_EXCLUDED(mutex_) {
  64. webrtc::MutexLock lock(&mutex_);
  65. int packets = 0;
  66. GetNumRtpBytesAndPackets(ssrc, NULL, &packets);
  67. return packets;
  68. }
  69. int NumSentSsrcs() RTC_LOCKS_EXCLUDED(mutex_) {
  70. webrtc::MutexLock lock(&mutex_);
  71. return static_cast<int>(sent_ssrcs_.size());
  72. }
  73. // Note: callers are responsible for deleting the returned buffer.
  74. const rtc::CopyOnWriteBuffer* GetRtpPacket(int index)
  75. RTC_LOCKS_EXCLUDED(mutex_) {
  76. webrtc::MutexLock lock(&mutex_);
  77. if (index >= static_cast<int>(rtp_packets_.size())) {
  78. return NULL;
  79. }
  80. return new rtc::CopyOnWriteBuffer(rtp_packets_[index]);
  81. }
  82. int NumRtcpPackets() RTC_LOCKS_EXCLUDED(mutex_) {
  83. webrtc::MutexLock lock(&mutex_);
  84. return static_cast<int>(rtcp_packets_.size());
  85. }
  86. // Note: callers are responsible for deleting the returned buffer.
  87. const rtc::CopyOnWriteBuffer* GetRtcpPacket(int index)
  88. RTC_LOCKS_EXCLUDED(mutex_) {
  89. webrtc::MutexLock lock(&mutex_);
  90. if (index >= static_cast<int>(rtcp_packets_.size())) {
  91. return NULL;
  92. }
  93. return new rtc::CopyOnWriteBuffer(rtcp_packets_[index]);
  94. }
  95. int sendbuf_size() const { return sendbuf_size_; }
  96. int recvbuf_size() const { return recvbuf_size_; }
  97. rtc::DiffServCodePoint dscp() const { return dscp_; }
  98. rtc::PacketOptions options() const { return options_; }
  99. protected:
  100. virtual bool SendPacket(rtc::CopyOnWriteBuffer* packet,
  101. const rtc::PacketOptions& options)
  102. RTC_LOCKS_EXCLUDED(mutex_) {
  103. webrtc::MutexLock lock(&mutex_);
  104. uint32_t cur_ssrc = 0;
  105. if (!GetRtpSsrc(packet->data(), packet->size(), &cur_ssrc)) {
  106. return false;
  107. }
  108. sent_ssrcs_[cur_ssrc]++;
  109. options_ = options;
  110. rtp_packets_.push_back(*packet);
  111. if (conf_) {
  112. for (size_t i = 0; i < conf_sent_ssrcs_.size(); ++i) {
  113. if (!SetRtpSsrc(packet->data(), packet->size(), conf_sent_ssrcs_[i])) {
  114. return false;
  115. }
  116. PostMessage(ST_RTP, *packet);
  117. }
  118. } else {
  119. PostMessage(ST_RTP, *packet);
  120. }
  121. return true;
  122. }
  123. virtual bool SendRtcp(rtc::CopyOnWriteBuffer* packet,
  124. const rtc::PacketOptions& options)
  125. RTC_LOCKS_EXCLUDED(mutex_) {
  126. webrtc::MutexLock lock(&mutex_);
  127. rtcp_packets_.push_back(*packet);
  128. options_ = options;
  129. if (!conf_) {
  130. // don't worry about RTCP in conf mode for now
  131. PostMessage(ST_RTCP, *packet);
  132. }
  133. return true;
  134. }
  135. virtual int SetOption(SocketType type, rtc::Socket::Option opt, int option) {
  136. if (opt == rtc::Socket::OPT_SNDBUF) {
  137. sendbuf_size_ = option;
  138. } else if (opt == rtc::Socket::OPT_RCVBUF) {
  139. recvbuf_size_ = option;
  140. } else if (opt == rtc::Socket::OPT_DSCP) {
  141. dscp_ = static_cast<rtc::DiffServCodePoint>(option);
  142. }
  143. return 0;
  144. }
  145. void PostMessage(int id, const rtc::CopyOnWriteBuffer& packet) {
  146. thread_->Post(RTC_FROM_HERE, this, id, rtc::WrapMessageData(packet));
  147. }
  148. virtual void OnMessage(rtc::Message* msg) {
  149. rtc::TypedMessageData<rtc::CopyOnWriteBuffer>* msg_data =
  150. static_cast<rtc::TypedMessageData<rtc::CopyOnWriteBuffer>*>(msg->pdata);
  151. if (dest_) {
  152. if (msg->message_id == ST_RTP) {
  153. dest_->OnPacketReceived(msg_data->data(), rtc::TimeMicros());
  154. } else {
  155. RTC_LOG(LS_VERBOSE) << "Dropping RTCP packet, they not handled by "
  156. "MediaChannel anymore.";
  157. }
  158. }
  159. delete msg_data;
  160. }
  161. private:
  162. void GetNumRtpBytesAndPackets(uint32_t ssrc, int* bytes, int* packets) {
  163. if (bytes) {
  164. *bytes = 0;
  165. }
  166. if (packets) {
  167. *packets = 0;
  168. }
  169. uint32_t cur_ssrc = 0;
  170. for (size_t i = 0; i < rtp_packets_.size(); ++i) {
  171. if (!GetRtpSsrc(rtp_packets_[i].data(), rtp_packets_[i].size(),
  172. &cur_ssrc)) {
  173. return;
  174. }
  175. if (ssrc == cur_ssrc) {
  176. if (bytes) {
  177. *bytes += static_cast<int>(rtp_packets_[i].size());
  178. }
  179. if (packets) {
  180. ++(*packets);
  181. }
  182. }
  183. }
  184. }
  185. rtc::Thread* thread_;
  186. MediaChannel* dest_;
  187. bool conf_;
  188. // The ssrcs used in sending out packets in conference mode.
  189. std::vector<uint32_t> conf_sent_ssrcs_;
  190. // Map to track counts of packets that have been sent per ssrc.
  191. // This includes packets that are dropped.
  192. std::map<uint32_t, uint32_t> sent_ssrcs_;
  193. // Map to track packet-number that needs to be dropped per ssrc.
  194. std::map<uint32_t, std::set<uint32_t> > drop_map_;
  195. webrtc::Mutex mutex_;
  196. std::vector<rtc::CopyOnWriteBuffer> rtp_packets_;
  197. std::vector<rtc::CopyOnWriteBuffer> rtcp_packets_;
  198. int sendbuf_size_;
  199. int recvbuf_size_;
  200. rtc::DiffServCodePoint dscp_;
  201. // Options of the most recently sent packet.
  202. rtc::PacketOptions options_;
  203. };
  204. } // namespace cricket
  205. #endif // MEDIA_BASE_FAKE_NETWORK_INTERFACE_H_