Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: webrtc/voice_engine/test/auto_test/fakes/conference_transport.cc

Issue 3008273002: Replace voe_conference_test. (Closed)
Patch Set: rebase Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2015 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 "webrtc/voice_engine/test/auto_test/fakes/conference_transport.h"
12
13 #include <string>
14
15 #include "webrtc/rtc_base/byteorder.h"
16 #include "webrtc/rtc_base/timeutils.h"
17 #include "webrtc/system_wrappers/include/sleep.h"
18 #include "webrtc/voice_engine/channel_proxy.h"
19 #include "webrtc/voice_engine/voice_engine_impl.h"
20
21 namespace webrtc {
22 namespace voetest {
23
24 namespace {
25
26 static const unsigned int kReflectorSsrc = 0x0000;
27 static const unsigned int kLocalSsrc = 0x0001;
28 static const unsigned int kFirstRemoteSsrc = 0x0002;
29 static const webrtc::CodecInst kCodecInst = {120, "opus", 48000, 960, 2, 64000};
30 static const int kAudioLevelHeaderId = 1;
31
32 static unsigned int ParseRtcpSsrc(const void* data, size_t len) {
33 const size_t ssrc_pos = 4;
34 unsigned int ssrc = 0;
35 if (len >= (ssrc_pos + sizeof(ssrc))) {
36 ssrc = rtc::GetBE32(static_cast<const char*>(data) + ssrc_pos);
37 }
38 return ssrc;
39 }
40
41 } // namespace
42
43 ConferenceTransport::ConferenceTransport()
44 : packet_event_(webrtc::EventWrapper::Create()),
45 thread_(Run, this, "ConferenceTransport"),
46 rtt_ms_(0),
47 stream_count_(0),
48 rtp_header_parser_(webrtc::RtpHeaderParser::Create()) {
49 rtp_header_parser_->
50 RegisterRtpHeaderExtension(webrtc::kRtpExtensionAudioLevel,
51 kAudioLevelHeaderId);
52
53 local_voe_ = webrtc::VoiceEngine::Create();
54 local_base_ = webrtc::VoEBase::GetInterface(local_voe_);
55 local_network_ = webrtc::VoENetwork::GetInterface(local_voe_);
56 local_rtp_rtcp_ = webrtc::VoERTP_RTCP::GetInterface(local_voe_);
57
58 local_apm_ = webrtc::AudioProcessing::Create();
59 local_base_->Init(nullptr, local_apm_.get(), nullptr);
60
61 // In principle, we can use one VoiceEngine to achieve the same goal. Well, in
62 // here, we use two engines to make it more like reality.
63 remote_voe_ = webrtc::VoiceEngine::Create();
64 remote_base_ = webrtc::VoEBase::GetInterface(remote_voe_);
65 remote_codec_ = webrtc::VoECodec::GetInterface(remote_voe_);
66 remote_network_ = webrtc::VoENetwork::GetInterface(remote_voe_);
67 remote_rtp_rtcp_ = webrtc::VoERTP_RTCP::GetInterface(remote_voe_);
68 remote_file_ = webrtc::VoEFile::GetInterface(remote_voe_);
69
70 remote_apm_ = webrtc::AudioProcessing::Create();
71 remote_base_->Init(nullptr, remote_apm_.get(), nullptr);
72
73 local_sender_ = local_base_->CreateChannel();
74 static_cast<webrtc::VoiceEngineImpl*>(local_voe_)
75 ->GetChannelProxy(local_sender_)
76 ->RegisterLegacyReceiveCodecs();
77 EXPECT_EQ(0, local_network_->RegisterExternalTransport(local_sender_, *this));
78 EXPECT_EQ(0, local_rtp_rtcp_->SetLocalSSRC(local_sender_, kLocalSsrc));
79 EXPECT_EQ(0, local_rtp_rtcp_->
80 SetSendAudioLevelIndicationStatus(local_sender_, true,
81 kAudioLevelHeaderId));
82 EXPECT_EQ(0, local_base_->StartSend(local_sender_));
83
84 reflector_ = remote_base_->CreateChannel();
85 static_cast<webrtc::VoiceEngineImpl*>(remote_voe_)
86 ->GetChannelProxy(reflector_)
87 ->RegisterLegacyReceiveCodecs();
88 EXPECT_EQ(0, remote_network_->RegisterExternalTransport(reflector_, *this));
89 EXPECT_EQ(0, remote_rtp_rtcp_->SetLocalSSRC(reflector_, kReflectorSsrc));
90
91 thread_.Start();
92 thread_.SetPriority(rtc::kHighPriority);
93 }
94
95 ConferenceTransport::~ConferenceTransport() {
96 // Must stop sending, otherwise DispatchPackets() cannot quit.
97 EXPECT_EQ(0, remote_network_->DeRegisterExternalTransport(reflector_));
98 EXPECT_EQ(0, local_network_->DeRegisterExternalTransport(local_sender_));
99
100 while (!streams_.empty()) {
101 auto stream = streams_.begin();
102 RemoveStream(stream->first);
103 }
104
105 thread_.Stop();
106
107 remote_file_->Release();
108 remote_rtp_rtcp_->Release();
109 remote_network_->Release();
110 remote_base_->Release();
111
112 local_rtp_rtcp_->Release();
113 local_network_->Release();
114 local_base_->Release();
115
116 EXPECT_TRUE(webrtc::VoiceEngine::Delete(remote_voe_));
117 EXPECT_TRUE(webrtc::VoiceEngine::Delete(local_voe_));
118 }
119
120 bool ConferenceTransport::SendRtp(const uint8_t* data,
121 size_t len,
122 const webrtc::PacketOptions& options) {
123 StorePacket(Packet::Rtp, data, len);
124 return true;
125 }
126
127 bool ConferenceTransport::SendRtcp(const uint8_t* data, size_t len) {
128 StorePacket(Packet::Rtcp, data, len);
129 return true;
130 }
131
132 int ConferenceTransport::GetReceiverChannelForSsrc(unsigned int sender_ssrc)
133 const {
134 rtc::CritScope lock(&stream_crit_);
135 auto it = streams_.find(sender_ssrc);
136 if (it != streams_.end()) {
137 return it->second.second;
138 }
139 return -1;
140 }
141
142 void ConferenceTransport::StorePacket(Packet::Type type,
143 const void* data,
144 size_t len) {
145 {
146 rtc::CritScope lock(&pq_crit_);
147 packet_queue_.push_back(Packet(type, data, len, rtc::TimeMillis()));
148 }
149 packet_event_->Set();
150 }
151
152 // This simulates the flow of RTP and RTCP packets. Complications like that
153 // a packet is first sent to the reflector, and then forwarded to the receiver
154 // are simplified, in this particular case, to a direct link between the sender
155 // and the receiver.
156 void ConferenceTransport::SendPacket(const Packet& packet) {
157 int destination = -1;
158
159 switch (packet.type_) {
160 case Packet::Rtp: {
161 webrtc::RTPHeader rtp_header;
162 rtp_header_parser_->Parse(packet.data_, packet.len_, &rtp_header);
163 if (rtp_header.ssrc == kLocalSsrc) {
164 remote_network_->ReceivedRTPPacket(reflector_, packet.data_,
165 packet.len_, webrtc::PacketTime());
166 } else {
167 if (loudest_filter_.ForwardThisPacket(rtp_header)) {
168 destination = GetReceiverChannelForSsrc(rtp_header.ssrc);
169 if (destination != -1) {
170 local_network_->ReceivedRTPPacket(destination, packet.data_,
171 packet.len_,
172 webrtc::PacketTime());
173 }
174 }
175 }
176 break;
177 }
178 case Packet::Rtcp: {
179 unsigned int sender_ssrc = ParseRtcpSsrc(packet.data_, packet.len_);
180 if (sender_ssrc == kLocalSsrc) {
181 remote_network_->ReceivedRTCPPacket(reflector_, packet.data_,
182 packet.len_);
183 } else if (sender_ssrc == kReflectorSsrc) {
184 local_network_->ReceivedRTCPPacket(local_sender_, packet.data_,
185 packet.len_);
186 } else {
187 destination = GetReceiverChannelForSsrc(sender_ssrc);
188 if (destination != -1) {
189 local_network_->ReceivedRTCPPacket(destination, packet.data_,
190 packet.len_);
191 }
192 }
193 break;
194 }
195 }
196 }
197
198 bool ConferenceTransport::DispatchPackets() {
199 switch (packet_event_->Wait(1000)) {
200 case webrtc::kEventSignaled:
201 break;
202 case webrtc::kEventTimeout:
203 return true;
204 case webrtc::kEventError:
205 ADD_FAILURE() << "kEventError encountered.";
206 return true;
207 }
208
209 while (true) {
210 Packet packet;
211 {
212 rtc::CritScope lock(&pq_crit_);
213 if (packet_queue_.empty())
214 break;
215 packet = packet_queue_.front();
216 packet_queue_.pop_front();
217 }
218
219 int32_t elapsed_time_ms = rtc::TimeSince(packet.send_time_ms_);
220 int32_t sleep_ms = rtt_ms_ / 2 - elapsed_time_ms;
221 if (sleep_ms > 0) {
222 // Every packet should be delayed by half of RTT.
223 webrtc::SleepMs(sleep_ms);
224 }
225
226 SendPacket(packet);
227 }
228 return true;
229 }
230
231 void ConferenceTransport::SetRtt(unsigned int rtt_ms) {
232 rtt_ms_ = rtt_ms;
233 }
234
235 unsigned int ConferenceTransport::AddStream(std::string file_name,
236 webrtc::FileFormats format) {
237 const int new_sender = remote_base_->CreateChannel();
238 static_cast<webrtc::VoiceEngineImpl*>(remote_voe_)
239 ->GetChannelProxy(new_sender)
240 ->RegisterLegacyReceiveCodecs();
241 EXPECT_EQ(0, remote_network_->RegisterExternalTransport(new_sender, *this));
242
243 const unsigned int remote_ssrc = kFirstRemoteSsrc + stream_count_++;
244 EXPECT_EQ(0, remote_rtp_rtcp_->SetLocalSSRC(new_sender, remote_ssrc));
245 EXPECT_EQ(0, remote_rtp_rtcp_->
246 SetSendAudioLevelIndicationStatus(new_sender, true, kAudioLevelHeaderId));
247
248 EXPECT_EQ(0, remote_codec_->SetSendCodec(new_sender, kCodecInst));
249 EXPECT_EQ(0, remote_base_->StartSend(new_sender));
250 EXPECT_EQ(0, remote_file_->StartPlayingFileAsMicrophone(
251 new_sender, file_name.c_str(), true, false, format, 1.0));
252
253 const int new_receiver = local_base_->CreateChannel();
254 static_cast<webrtc::VoiceEngineImpl*>(local_voe_)
255 ->GetChannelProxy(new_receiver)
256 ->RegisterLegacyReceiveCodecs();
257 EXPECT_EQ(0, local_base_->AssociateSendChannel(new_receiver, local_sender_));
258
259 EXPECT_EQ(0, local_network_->RegisterExternalTransport(new_receiver, *this));
260 // Receive channels have to have the same SSRC in order to send receiver
261 // reports with this SSRC.
262 EXPECT_EQ(0, local_rtp_rtcp_->SetLocalSSRC(new_receiver, kLocalSsrc));
263
264 {
265 rtc::CritScope lock(&stream_crit_);
266 streams_[remote_ssrc] = std::make_pair(new_sender, new_receiver);
267 }
268 return remote_ssrc; // remote ssrc used as stream id.
269 }
270
271 bool ConferenceTransport::RemoveStream(unsigned int id) {
272 rtc::CritScope lock(&stream_crit_);
273 auto it = streams_.find(id);
274 if (it == streams_.end()) {
275 return false;
276 }
277 EXPECT_EQ(0, remote_network_->
278 DeRegisterExternalTransport(it->second.second));
279 EXPECT_EQ(0, local_network_->
280 DeRegisterExternalTransport(it->second.first));
281 EXPECT_EQ(0, remote_base_->DeleteChannel(it->second.second));
282 EXPECT_EQ(0, local_base_->DeleteChannel(it->second.first));
283 streams_.erase(it);
284 return true;
285 }
286
287 bool ConferenceTransport::StartPlayout(unsigned int id) {
288 int dst = GetReceiverChannelForSsrc(id);
289 if (dst == -1) {
290 return false;
291 }
292 EXPECT_EQ(0, local_base_->StartPlayout(dst));
293 return true;
294 }
295
296 bool ConferenceTransport::GetReceiverStatistics(unsigned int id,
297 webrtc::CallStatistics* stats) {
298 int dst = GetReceiverChannelForSsrc(id);
299 if (dst == -1) {
300 return false;
301 }
302 EXPECT_EQ(0, local_rtp_rtcp_->GetRTCPStatistics(dst, *stats));
303 return true;
304 }
305
306 } // namespace voetest
307 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698