1 /*
2 * Copyright 2017 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 "call/call_factory.h"
12
13 #include <stdio.h>
14
15 #include <memory>
16 #include <string>
17
18 #include "absl/types/optional.h"
19 #include "api/test/simulated_network.h"
20 #include "call/call.h"
21 #include "call/degraded_call.h"
22 #include "rtc_base/checks.h"
23 #include "system_wrappers/include/field_trial.h"
24
25 namespace webrtc {
26 namespace {
ParseConfigParam(std::string exp_name,int * field)27 bool ParseConfigParam(std::string exp_name, int* field) {
28 std::string group = field_trial::FindFullName(exp_name);
29 if (group.empty())
30 return false;
31
32 return (sscanf(group.c_str(), "%d", field) == 1);
33 }
34
ParseDegradationConfig(bool send)35 absl::optional<webrtc::BuiltInNetworkBehaviorConfig> ParseDegradationConfig(
36 bool send) {
37 std::string exp_prefix = "WebRTCFakeNetwork";
38 if (send) {
39 exp_prefix += "Send";
40 } else {
41 exp_prefix += "Receive";
42 }
43
44 webrtc::BuiltInNetworkBehaviorConfig config;
45 bool configured = false;
46 configured |=
47 ParseConfigParam(exp_prefix + "DelayMs", &config.queue_delay_ms);
48 configured |= ParseConfigParam(exp_prefix + "DelayStdDevMs",
49 &config.delay_standard_deviation_ms);
50 int queue_length = 0;
51 if (ParseConfigParam(exp_prefix + "QueueLength", &queue_length)) {
52 RTC_CHECK_GE(queue_length, 0);
53 config.queue_length_packets = queue_length;
54 configured = true;
55 }
56 configured |=
57 ParseConfigParam(exp_prefix + "CapacityKbps", &config.link_capacity_kbps);
58 configured |=
59 ParseConfigParam(exp_prefix + "LossPercent", &config.loss_percent);
60 int allow_reordering = 0;
61 if (ParseConfigParam(exp_prefix + "AllowReordering", &allow_reordering)) {
62 config.allow_reordering = true;
63 configured = true;
64 }
65 configured |= ParseConfigParam(exp_prefix + "AvgBurstLossLength",
66 &config.avg_burst_loss_length);
67 return configured
68 ? absl::optional<webrtc::BuiltInNetworkBehaviorConfig>(config)
69 : absl::nullopt;
70 }
71 } // namespace
72
CallFactory()73 CallFactory::CallFactory() {
74 call_thread_.Detach();
75 }
76
CreateCall(const Call::Config & config)77 Call* CallFactory::CreateCall(const Call::Config& config) {
78 RTC_DCHECK_RUN_ON(&call_thread_);
79 absl::optional<webrtc::BuiltInNetworkBehaviorConfig> send_degradation_config =
80 ParseDegradationConfig(true);
81 absl::optional<webrtc::BuiltInNetworkBehaviorConfig>
82 receive_degradation_config = ParseDegradationConfig(false);
83
84 if (send_degradation_config || receive_degradation_config) {
85 return new DegradedCall(std::unique_ptr<Call>(Call::Create(config)),
86 send_degradation_config, receive_degradation_config,
87 config.task_queue_factory);
88 }
89
90 if (!module_thread_) {
91 module_thread_ = SharedModuleThread::Create(
92 ProcessThread::Create("SharedModThread"), [this]() {
93 RTC_DCHECK_RUN_ON(&call_thread_);
94 module_thread_ = nullptr;
95 });
96 }
97
98 return Call::Create(config, module_thread_);
99 }
100
CreateCallFactory()101 std::unique_ptr<CallFactoryInterface> CreateCallFactory() {
102 return std::unique_ptr<CallFactoryInterface>(new CallFactory());
103 }
104
105 } // namespace webrtc
106