blob: 353fe4c7167e4f24aa91a442557d8952bd489779 [file] [log] [blame]
Erik Språng09708512018-03-14 15:16:50 +01001/*
2 * Copyright (c) 2018 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 <utility>
12
13#include "call/degraded_call.h"
14
Karl Wiberg918f50c2018-07-05 11:40:33 +020015#include "absl/memory/memory.h"
Erik Språng09708512018-03-14 15:16:50 +010016
17namespace webrtc {
18DegradedCall::DegradedCall(
19 std::unique_ptr<Call> call,
Artem Titov75e36472018-10-08 12:28:56 +020020 absl::optional<BuiltInNetworkBehaviorConfig> send_config,
21 absl::optional<BuiltInNetworkBehaviorConfig> receive_config)
Erik Språng09708512018-03-14 15:16:50 +010022 : clock_(Clock::GetRealTimeClock()),
23 call_(std::move(call)),
24 send_config_(send_config),
25 send_process_thread_(
26 send_config_ ? ProcessThread::Create("DegradedSendThread") : nullptr),
27 num_send_streams_(0),
28 receive_config_(receive_config) {
29 if (receive_config_) {
Artem Titov3229d652018-08-17 13:00:54 +020030 auto network = absl::make_unique<SimulatedNetwork>(*receive_config_);
31 receive_simulated_network_ = network.get();
Erik Språng09708512018-03-14 15:16:50 +010032 receive_pipe_ =
Artem Titov3229d652018-08-17 13:00:54 +020033 absl::make_unique<webrtc::FakeNetworkPipe>(clock_, std::move(network));
Erik Språng09708512018-03-14 15:16:50 +010034 receive_pipe_->SetReceiver(call_->Receiver());
35 }
36 if (send_process_thread_) {
37 send_process_thread_->Start();
38 }
39}
40
41DegradedCall::~DegradedCall() {
42 if (send_pipe_) {
43 send_process_thread_->DeRegisterModule(send_pipe_.get());
44 }
45 if (send_process_thread_) {
46 send_process_thread_->Stop();
47 }
48}
49
50AudioSendStream* DegradedCall::CreateAudioSendStream(
51 const AudioSendStream::Config& config) {
52 return call_->CreateAudioSendStream(config);
53}
54
55void DegradedCall::DestroyAudioSendStream(AudioSendStream* send_stream) {
56 call_->DestroyAudioSendStream(send_stream);
57}
58
59AudioReceiveStream* DegradedCall::CreateAudioReceiveStream(
60 const AudioReceiveStream::Config& config) {
61 return call_->CreateAudioReceiveStream(config);
62}
63
64void DegradedCall::DestroyAudioReceiveStream(
65 AudioReceiveStream* receive_stream) {
66 call_->DestroyAudioReceiveStream(receive_stream);
67}
68
69VideoSendStream* DegradedCall::CreateVideoSendStream(
70 VideoSendStream::Config config,
71 VideoEncoderConfig encoder_config) {
72 if (send_config_ && !send_pipe_) {
Artem Titov3229d652018-08-17 13:00:54 +020073 auto network = absl::make_unique<SimulatedNetwork>(*send_config_);
74 send_simulated_network_ = network.get();
75 send_pipe_ = absl::make_unique<FakeNetworkPipe>(clock_, std::move(network),
Karl Wiberg918f50c2018-07-05 11:40:33 +020076 config.send_transport);
Erik Språng09708512018-03-14 15:16:50 +010077 config.send_transport = this;
78 send_process_thread_->RegisterModule(send_pipe_.get(), RTC_FROM_HERE);
79 }
80 ++num_send_streams_;
81 return call_->CreateVideoSendStream(std::move(config),
82 std::move(encoder_config));
83}
84
85VideoSendStream* DegradedCall::CreateVideoSendStream(
86 VideoSendStream::Config config,
87 VideoEncoderConfig encoder_config,
88 std::unique_ptr<FecController> fec_controller) {
89 if (send_config_ && !send_pipe_) {
Artem Titov3229d652018-08-17 13:00:54 +020090 auto network = absl::make_unique<SimulatedNetwork>(*send_config_);
91 send_simulated_network_ = network.get();
92 send_pipe_ = absl::make_unique<FakeNetworkPipe>(clock_, std::move(network),
Karl Wiberg918f50c2018-07-05 11:40:33 +020093 config.send_transport);
Erik Språng09708512018-03-14 15:16:50 +010094 config.send_transport = this;
95 send_process_thread_->RegisterModule(send_pipe_.get(), RTC_FROM_HERE);
96 }
97 ++num_send_streams_;
98 return call_->CreateVideoSendStream(
99 std::move(config), std::move(encoder_config), std::move(fec_controller));
100}
101
102void DegradedCall::DestroyVideoSendStream(VideoSendStream* send_stream) {
Erik Språngeef09fc2018-03-16 10:47:16 +0100103 call_->DestroyVideoSendStream(send_stream);
Erik Språng09708512018-03-14 15:16:50 +0100104 if (send_pipe_ && num_send_streams_ > 0) {
105 --num_send_streams_;
106 if (num_send_streams_ == 0) {
107 send_process_thread_->DeRegisterModule(send_pipe_.get());
108 send_pipe_.reset();
109 }
110 }
Erik Språng09708512018-03-14 15:16:50 +0100111}
112
113VideoReceiveStream* DegradedCall::CreateVideoReceiveStream(
114 VideoReceiveStream::Config configuration) {
115 return call_->CreateVideoReceiveStream(std::move(configuration));
116}
117
118void DegradedCall::DestroyVideoReceiveStream(
119 VideoReceiveStream* receive_stream) {
120 call_->DestroyVideoReceiveStream(receive_stream);
121}
122
123FlexfecReceiveStream* DegradedCall::CreateFlexfecReceiveStream(
124 const FlexfecReceiveStream::Config& config) {
125 return call_->CreateFlexfecReceiveStream(config);
126}
127
128void DegradedCall::DestroyFlexfecReceiveStream(
129 FlexfecReceiveStream* receive_stream) {
130 call_->DestroyFlexfecReceiveStream(receive_stream);
131}
132
133PacketReceiver* DegradedCall::Receiver() {
134 if (receive_config_) {
135 return this;
136 }
137 return call_->Receiver();
138}
139
140RtpTransportControllerSendInterface*
141DegradedCall::GetTransportControllerSend() {
142 return call_->GetTransportControllerSend();
143}
144
145Call::Stats DegradedCall::GetStats() const {
146 return call_->GetStats();
147}
148
149void DegradedCall::SetBitrateAllocationStrategy(
150 std::unique_ptr<rtc::BitrateAllocationStrategy>
151 bitrate_allocation_strategy) {
152 call_->SetBitrateAllocationStrategy(std::move(bitrate_allocation_strategy));
153}
154
155void DegradedCall::SignalChannelNetworkState(MediaType media,
156 NetworkState state) {
157 call_->SignalChannelNetworkState(media, state);
158}
159
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200160void DegradedCall::OnAudioTransportOverheadChanged(
Erik Språng09708512018-03-14 15:16:50 +0100161 int transport_overhead_per_packet) {
Stefan Holmer64be7fa2018-10-04 15:21:55 +0200162 call_->OnAudioTransportOverheadChanged(transport_overhead_per_packet);
Erik Språng09708512018-03-14 15:16:50 +0100163}
164
165void DegradedCall::OnSentPacket(const rtc::SentPacket& sent_packet) {
166 if (send_config_) {
167 // If we have a degraded send-transport, we have already notified call
168 // about the supposed network send time. Discard the actual network send
169 // time in order to properly fool the BWE.
170 return;
171 }
172 call_->OnSentPacket(sent_packet);
173}
174
175bool DegradedCall::SendRtp(const uint8_t* packet,
176 size_t length,
177 const PacketOptions& options) {
178 // A call here comes from the RTP stack (probably pacer). We intercept it and
179 // put it in the fake network pipe instead, but report to Call that is has
180 // been sent, so that the bandwidth estimator sees the delay we add.
181 send_pipe_->SendRtp(packet, length, options);
182 if (options.packet_id != -1) {
Sebastian Jansson156d11d2018-09-28 17:21:34 +0200183 rtc::SentPacket sent_packet;
184 sent_packet.packet_id = options.packet_id;
185 sent_packet.send_time_ms = clock_->TimeInMilliseconds();
186 sent_packet.info.packet_size_bytes = length;
187 sent_packet.info.packet_type = rtc::PacketType::kData;
188 call_->OnSentPacket(sent_packet);
Erik Språng09708512018-03-14 15:16:50 +0100189 }
190 return true;
191}
192
193bool DegradedCall::SendRtcp(const uint8_t* packet, size_t length) {
194 send_pipe_->SendRtcp(packet, length);
195 return true;
196}
197
198PacketReceiver::DeliveryStatus DegradedCall::DeliverPacket(
199 MediaType media_type,
200 rtc::CopyOnWriteBuffer packet,
Niels Möller70082872018-08-07 11:03:12 +0200201 int64_t packet_time_us) {
202 PacketReceiver::DeliveryStatus status = receive_pipe_->DeliverPacket(
203 media_type, std::move(packet), packet_time_us);
Erik Språng09708512018-03-14 15:16:50 +0100204 // This is not optimal, but there are many places where there are thread
205 // checks that fail if we're not using the worker thread call into this
206 // method. If we want to fix this we probably need a task queue to do handover
207 // of all overriden methods, which feels like overikill for the current use
208 // case.
209 // By just having this thread call out via the Process() method we work around
210 // that, with the tradeoff that a non-zero delay may become a little larger
211 // than anticipated at very low packet rates.
212 receive_pipe_->Process();
213 return status;
214}
215
216} // namespace webrtc