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