1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include "call/call.h"
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <string.h>
14*d9f75844SAndroid Build Coastguard Worker
15*d9f75844SAndroid Build Coastguard Worker #include <algorithm>
16*d9f75844SAndroid Build Coastguard Worker #include <atomic>
17*d9f75844SAndroid Build Coastguard Worker #include <map>
18*d9f75844SAndroid Build Coastguard Worker #include <memory>
19*d9f75844SAndroid Build Coastguard Worker #include <set>
20*d9f75844SAndroid Build Coastguard Worker #include <utility>
21*d9f75844SAndroid Build Coastguard Worker #include <vector>
22*d9f75844SAndroid Build Coastguard Worker
23*d9f75844SAndroid Build Coastguard Worker #include "absl/functional/bind_front.h"
24*d9f75844SAndroid Build Coastguard Worker #include "absl/strings/string_view.h"
25*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
26*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_event_log/rtc_event_log.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h"
28*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/pending_task_safety_flag.h"
29*d9f75844SAndroid Build Coastguard Worker #include "api/transport/network_control.h"
30*d9f75844SAndroid Build Coastguard Worker #include "audio/audio_receive_stream.h"
31*d9f75844SAndroid Build Coastguard Worker #include "audio/audio_send_stream.h"
32*d9f75844SAndroid Build Coastguard Worker #include "audio/audio_state.h"
33*d9f75844SAndroid Build Coastguard Worker #include "call/adaptation/broadcast_resource_listener.h"
34*d9f75844SAndroid Build Coastguard Worker #include "call/bitrate_allocator.h"
35*d9f75844SAndroid Build Coastguard Worker #include "call/flexfec_receive_stream_impl.h"
36*d9f75844SAndroid Build Coastguard Worker #include "call/receive_time_calculator.h"
37*d9f75844SAndroid Build Coastguard Worker #include "call/rtp_stream_receiver_controller.h"
38*d9f75844SAndroid Build Coastguard Worker #include "call/rtp_transport_controller_send.h"
39*d9f75844SAndroid Build Coastguard Worker #include "call/rtp_transport_controller_send_factory.h"
40*d9f75844SAndroid Build Coastguard Worker #include "call/version.h"
41*d9f75844SAndroid Build Coastguard Worker #include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
42*d9f75844SAndroid Build Coastguard Worker #include "logging/rtc_event_log/events/rtc_event_rtcp_packet_incoming.h"
43*d9f75844SAndroid Build Coastguard Worker #include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
44*d9f75844SAndroid Build Coastguard Worker #include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
45*d9f75844SAndroid Build Coastguard Worker #include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
46*d9f75844SAndroid Build Coastguard Worker #include "logging/rtc_event_log/rtc_stream_config.h"
47*d9f75844SAndroid Build Coastguard Worker #include "modules/congestion_controller/include/receive_side_congestion_controller.h"
48*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/include/flexfec_receiver.h"
49*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
50*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/byte_io.h"
51*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_packet_received.h"
52*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_util.h"
53*d9f75844SAndroid Build Coastguard Worker #include "modules/video_coding/fec_controller_default.h"
54*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
55*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/logging.h"
56*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/strings/string_builder.h"
57*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/system/no_unique_address.h"
58*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_utils/repeating_task.h"
59*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h"
60*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/time_utils.h"
61*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/trace_event.h"
62*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/clock.h"
63*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/cpu_info.h"
64*d9f75844SAndroid Build Coastguard Worker #include "system_wrappers/include/metrics.h"
65*d9f75844SAndroid Build Coastguard Worker #include "video/call_stats2.h"
66*d9f75844SAndroid Build Coastguard Worker #include "video/send_delay_stats.h"
67*d9f75844SAndroid Build Coastguard Worker #include "video/stats_counter.h"
68*d9f75844SAndroid Build Coastguard Worker #include "video/video_receive_stream2.h"
69*d9f75844SAndroid Build Coastguard Worker #include "video/video_send_stream.h"
70*d9f75844SAndroid Build Coastguard Worker
71*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
72*d9f75844SAndroid Build Coastguard Worker
73*d9f75844SAndroid Build Coastguard Worker namespace {
SendPeriodicFeedback(const std::vector<RtpExtension> & extensions)74*d9f75844SAndroid Build Coastguard Worker bool SendPeriodicFeedback(const std::vector<RtpExtension>& extensions) {
75*d9f75844SAndroid Build Coastguard Worker for (const auto& extension : extensions) {
76*d9f75844SAndroid Build Coastguard Worker if (extension.uri == RtpExtension::kTransportSequenceNumberV2Uri)
77*d9f75844SAndroid Build Coastguard Worker return false;
78*d9f75844SAndroid Build Coastguard Worker }
79*d9f75844SAndroid Build Coastguard Worker return true;
80*d9f75844SAndroid Build Coastguard Worker }
81*d9f75844SAndroid Build Coastguard Worker
HasTransportSequenceNumber(const RtpHeaderExtensionMap & map)82*d9f75844SAndroid Build Coastguard Worker bool HasTransportSequenceNumber(const RtpHeaderExtensionMap& map) {
83*d9f75844SAndroid Build Coastguard Worker return map.IsRegistered(kRtpExtensionTransportSequenceNumber) ||
84*d9f75844SAndroid Build Coastguard Worker map.IsRegistered(kRtpExtensionTransportSequenceNumber02);
85*d9f75844SAndroid Build Coastguard Worker }
86*d9f75844SAndroid Build Coastguard Worker
UseSendSideBwe(const ReceiveStreamInterface * stream)87*d9f75844SAndroid Build Coastguard Worker bool UseSendSideBwe(const ReceiveStreamInterface* stream) {
88*d9f75844SAndroid Build Coastguard Worker return stream->transport_cc() &&
89*d9f75844SAndroid Build Coastguard Worker HasTransportSequenceNumber(stream->GetRtpExtensionMap());
90*d9f75844SAndroid Build Coastguard Worker }
91*d9f75844SAndroid Build Coastguard Worker
FindKeyByValue(const std::map<int,int> & m,int v)92*d9f75844SAndroid Build Coastguard Worker const int* FindKeyByValue(const std::map<int, int>& m, int v) {
93*d9f75844SAndroid Build Coastguard Worker for (const auto& kv : m) {
94*d9f75844SAndroid Build Coastguard Worker if (kv.second == v)
95*d9f75844SAndroid Build Coastguard Worker return &kv.first;
96*d9f75844SAndroid Build Coastguard Worker }
97*d9f75844SAndroid Build Coastguard Worker return nullptr;
98*d9f75844SAndroid Build Coastguard Worker }
99*d9f75844SAndroid Build Coastguard Worker
CreateRtcLogStreamConfig(const VideoReceiveStreamInterface::Config & config)100*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtclog::StreamConfig> CreateRtcLogStreamConfig(
101*d9f75844SAndroid Build Coastguard Worker const VideoReceiveStreamInterface::Config& config) {
102*d9f75844SAndroid Build Coastguard Worker auto rtclog_config = std::make_unique<rtclog::StreamConfig>();
103*d9f75844SAndroid Build Coastguard Worker rtclog_config->remote_ssrc = config.rtp.remote_ssrc;
104*d9f75844SAndroid Build Coastguard Worker rtclog_config->local_ssrc = config.rtp.local_ssrc;
105*d9f75844SAndroid Build Coastguard Worker rtclog_config->rtx_ssrc = config.rtp.rtx_ssrc;
106*d9f75844SAndroid Build Coastguard Worker rtclog_config->rtcp_mode = config.rtp.rtcp_mode;
107*d9f75844SAndroid Build Coastguard Worker rtclog_config->rtp_extensions = config.rtp.extensions;
108*d9f75844SAndroid Build Coastguard Worker
109*d9f75844SAndroid Build Coastguard Worker for (const auto& d : config.decoders) {
110*d9f75844SAndroid Build Coastguard Worker const int* search =
111*d9f75844SAndroid Build Coastguard Worker FindKeyByValue(config.rtp.rtx_associated_payload_types, d.payload_type);
112*d9f75844SAndroid Build Coastguard Worker rtclog_config->codecs.emplace_back(d.video_format.name, d.payload_type,
113*d9f75844SAndroid Build Coastguard Worker search ? *search : 0);
114*d9f75844SAndroid Build Coastguard Worker }
115*d9f75844SAndroid Build Coastguard Worker return rtclog_config;
116*d9f75844SAndroid Build Coastguard Worker }
117*d9f75844SAndroid Build Coastguard Worker
CreateRtcLogStreamConfig(const VideoSendStream::Config & config,size_t ssrc_index)118*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtclog::StreamConfig> CreateRtcLogStreamConfig(
119*d9f75844SAndroid Build Coastguard Worker const VideoSendStream::Config& config,
120*d9f75844SAndroid Build Coastguard Worker size_t ssrc_index) {
121*d9f75844SAndroid Build Coastguard Worker auto rtclog_config = std::make_unique<rtclog::StreamConfig>();
122*d9f75844SAndroid Build Coastguard Worker rtclog_config->local_ssrc = config.rtp.ssrcs[ssrc_index];
123*d9f75844SAndroid Build Coastguard Worker if (ssrc_index < config.rtp.rtx.ssrcs.size()) {
124*d9f75844SAndroid Build Coastguard Worker rtclog_config->rtx_ssrc = config.rtp.rtx.ssrcs[ssrc_index];
125*d9f75844SAndroid Build Coastguard Worker }
126*d9f75844SAndroid Build Coastguard Worker rtclog_config->rtcp_mode = config.rtp.rtcp_mode;
127*d9f75844SAndroid Build Coastguard Worker rtclog_config->rtp_extensions = config.rtp.extensions;
128*d9f75844SAndroid Build Coastguard Worker
129*d9f75844SAndroid Build Coastguard Worker rtclog_config->codecs.emplace_back(config.rtp.payload_name,
130*d9f75844SAndroid Build Coastguard Worker config.rtp.payload_type,
131*d9f75844SAndroid Build Coastguard Worker config.rtp.rtx.payload_type);
132*d9f75844SAndroid Build Coastguard Worker return rtclog_config;
133*d9f75844SAndroid Build Coastguard Worker }
134*d9f75844SAndroid Build Coastguard Worker
CreateRtcLogStreamConfig(const AudioReceiveStreamInterface::Config & config)135*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<rtclog::StreamConfig> CreateRtcLogStreamConfig(
136*d9f75844SAndroid Build Coastguard Worker const AudioReceiveStreamInterface::Config& config) {
137*d9f75844SAndroid Build Coastguard Worker auto rtclog_config = std::make_unique<rtclog::StreamConfig>();
138*d9f75844SAndroid Build Coastguard Worker rtclog_config->remote_ssrc = config.rtp.remote_ssrc;
139*d9f75844SAndroid Build Coastguard Worker rtclog_config->local_ssrc = config.rtp.local_ssrc;
140*d9f75844SAndroid Build Coastguard Worker rtclog_config->rtp_extensions = config.rtp.extensions;
141*d9f75844SAndroid Build Coastguard Worker return rtclog_config;
142*d9f75844SAndroid Build Coastguard Worker }
143*d9f75844SAndroid Build Coastguard Worker
GetCurrentTaskQueueOrThread()144*d9f75844SAndroid Build Coastguard Worker TaskQueueBase* GetCurrentTaskQueueOrThread() {
145*d9f75844SAndroid Build Coastguard Worker TaskQueueBase* current = TaskQueueBase::Current();
146*d9f75844SAndroid Build Coastguard Worker if (!current)
147*d9f75844SAndroid Build Coastguard Worker current = rtc::ThreadManager::Instance()->CurrentThread();
148*d9f75844SAndroid Build Coastguard Worker return current;
149*d9f75844SAndroid Build Coastguard Worker }
150*d9f75844SAndroid Build Coastguard Worker
151*d9f75844SAndroid Build Coastguard Worker } // namespace
152*d9f75844SAndroid Build Coastguard Worker
153*d9f75844SAndroid Build Coastguard Worker namespace internal {
154*d9f75844SAndroid Build Coastguard Worker
155*d9f75844SAndroid Build Coastguard Worker // Wraps an injected resource in a BroadcastResourceListener and handles adding
156*d9f75844SAndroid Build Coastguard Worker // and removing adapter resources to individual VideoSendStreams.
157*d9f75844SAndroid Build Coastguard Worker class ResourceVideoSendStreamForwarder {
158*d9f75844SAndroid Build Coastguard Worker public:
ResourceVideoSendStreamForwarder(rtc::scoped_refptr<webrtc::Resource> resource)159*d9f75844SAndroid Build Coastguard Worker ResourceVideoSendStreamForwarder(
160*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<webrtc::Resource> resource)
161*d9f75844SAndroid Build Coastguard Worker : broadcast_resource_listener_(resource) {
162*d9f75844SAndroid Build Coastguard Worker broadcast_resource_listener_.StartListening();
163*d9f75844SAndroid Build Coastguard Worker }
~ResourceVideoSendStreamForwarder()164*d9f75844SAndroid Build Coastguard Worker ~ResourceVideoSendStreamForwarder() {
165*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(adapter_resources_.empty());
166*d9f75844SAndroid Build Coastguard Worker broadcast_resource_listener_.StopListening();
167*d9f75844SAndroid Build Coastguard Worker }
168*d9f75844SAndroid Build Coastguard Worker
Resource() const169*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<webrtc::Resource> Resource() const {
170*d9f75844SAndroid Build Coastguard Worker return broadcast_resource_listener_.SourceResource();
171*d9f75844SAndroid Build Coastguard Worker }
172*d9f75844SAndroid Build Coastguard Worker
OnCreateVideoSendStream(VideoSendStream * video_send_stream)173*d9f75844SAndroid Build Coastguard Worker void OnCreateVideoSendStream(VideoSendStream* video_send_stream) {
174*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(adapter_resources_.find(video_send_stream) ==
175*d9f75844SAndroid Build Coastguard Worker adapter_resources_.end());
176*d9f75844SAndroid Build Coastguard Worker auto adapter_resource =
177*d9f75844SAndroid Build Coastguard Worker broadcast_resource_listener_.CreateAdapterResource();
178*d9f75844SAndroid Build Coastguard Worker video_send_stream->AddAdaptationResource(adapter_resource);
179*d9f75844SAndroid Build Coastguard Worker adapter_resources_.insert(
180*d9f75844SAndroid Build Coastguard Worker std::make_pair(video_send_stream, adapter_resource));
181*d9f75844SAndroid Build Coastguard Worker }
182*d9f75844SAndroid Build Coastguard Worker
OnDestroyVideoSendStream(VideoSendStream * video_send_stream)183*d9f75844SAndroid Build Coastguard Worker void OnDestroyVideoSendStream(VideoSendStream* video_send_stream) {
184*d9f75844SAndroid Build Coastguard Worker auto it = adapter_resources_.find(video_send_stream);
185*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(it != adapter_resources_.end());
186*d9f75844SAndroid Build Coastguard Worker broadcast_resource_listener_.RemoveAdapterResource(it->second);
187*d9f75844SAndroid Build Coastguard Worker adapter_resources_.erase(it);
188*d9f75844SAndroid Build Coastguard Worker }
189*d9f75844SAndroid Build Coastguard Worker
190*d9f75844SAndroid Build Coastguard Worker private:
191*d9f75844SAndroid Build Coastguard Worker BroadcastResourceListener broadcast_resource_listener_;
192*d9f75844SAndroid Build Coastguard Worker std::map<VideoSendStream*, rtc::scoped_refptr<webrtc::Resource>>
193*d9f75844SAndroid Build Coastguard Worker adapter_resources_;
194*d9f75844SAndroid Build Coastguard Worker };
195*d9f75844SAndroid Build Coastguard Worker
196*d9f75844SAndroid Build Coastguard Worker class Call final : public webrtc::Call,
197*d9f75844SAndroid Build Coastguard Worker public PacketReceiver,
198*d9f75844SAndroid Build Coastguard Worker public RecoveredPacketReceiver,
199*d9f75844SAndroid Build Coastguard Worker public TargetTransferRateObserver,
200*d9f75844SAndroid Build Coastguard Worker public BitrateAllocator::LimitObserver {
201*d9f75844SAndroid Build Coastguard Worker public:
202*d9f75844SAndroid Build Coastguard Worker Call(Clock* clock,
203*d9f75844SAndroid Build Coastguard Worker const Call::Config& config,
204*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<RtpTransportControllerSendInterface> transport_send,
205*d9f75844SAndroid Build Coastguard Worker TaskQueueFactory* task_queue_factory);
206*d9f75844SAndroid Build Coastguard Worker ~Call() override;
207*d9f75844SAndroid Build Coastguard Worker
208*d9f75844SAndroid Build Coastguard Worker Call(const Call&) = delete;
209*d9f75844SAndroid Build Coastguard Worker Call& operator=(const Call&) = delete;
210*d9f75844SAndroid Build Coastguard Worker
211*d9f75844SAndroid Build Coastguard Worker // Implements webrtc::Call.
212*d9f75844SAndroid Build Coastguard Worker PacketReceiver* Receiver() override;
213*d9f75844SAndroid Build Coastguard Worker
214*d9f75844SAndroid Build Coastguard Worker webrtc::AudioSendStream* CreateAudioSendStream(
215*d9f75844SAndroid Build Coastguard Worker const webrtc::AudioSendStream::Config& config) override;
216*d9f75844SAndroid Build Coastguard Worker void DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) override;
217*d9f75844SAndroid Build Coastguard Worker
218*d9f75844SAndroid Build Coastguard Worker webrtc::AudioReceiveStreamInterface* CreateAudioReceiveStream(
219*d9f75844SAndroid Build Coastguard Worker const webrtc::AudioReceiveStreamInterface::Config& config) override;
220*d9f75844SAndroid Build Coastguard Worker void DestroyAudioReceiveStream(
221*d9f75844SAndroid Build Coastguard Worker webrtc::AudioReceiveStreamInterface* receive_stream) override;
222*d9f75844SAndroid Build Coastguard Worker
223*d9f75844SAndroid Build Coastguard Worker webrtc::VideoSendStream* CreateVideoSendStream(
224*d9f75844SAndroid Build Coastguard Worker webrtc::VideoSendStream::Config config,
225*d9f75844SAndroid Build Coastguard Worker VideoEncoderConfig encoder_config) override;
226*d9f75844SAndroid Build Coastguard Worker webrtc::VideoSendStream* CreateVideoSendStream(
227*d9f75844SAndroid Build Coastguard Worker webrtc::VideoSendStream::Config config,
228*d9f75844SAndroid Build Coastguard Worker VideoEncoderConfig encoder_config,
229*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<FecController> fec_controller) override;
230*d9f75844SAndroid Build Coastguard Worker void DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) override;
231*d9f75844SAndroid Build Coastguard Worker
232*d9f75844SAndroid Build Coastguard Worker webrtc::VideoReceiveStreamInterface* CreateVideoReceiveStream(
233*d9f75844SAndroid Build Coastguard Worker webrtc::VideoReceiveStreamInterface::Config configuration) override;
234*d9f75844SAndroid Build Coastguard Worker void DestroyVideoReceiveStream(
235*d9f75844SAndroid Build Coastguard Worker webrtc::VideoReceiveStreamInterface* receive_stream) override;
236*d9f75844SAndroid Build Coastguard Worker
237*d9f75844SAndroid Build Coastguard Worker FlexfecReceiveStream* CreateFlexfecReceiveStream(
238*d9f75844SAndroid Build Coastguard Worker const FlexfecReceiveStream::Config config) override;
239*d9f75844SAndroid Build Coastguard Worker void DestroyFlexfecReceiveStream(
240*d9f75844SAndroid Build Coastguard Worker FlexfecReceiveStream* receive_stream) override;
241*d9f75844SAndroid Build Coastguard Worker
242*d9f75844SAndroid Build Coastguard Worker void AddAdaptationResource(rtc::scoped_refptr<Resource> resource) override;
243*d9f75844SAndroid Build Coastguard Worker
244*d9f75844SAndroid Build Coastguard Worker RtpTransportControllerSendInterface* GetTransportControllerSend() override;
245*d9f75844SAndroid Build Coastguard Worker
246*d9f75844SAndroid Build Coastguard Worker Stats GetStats() const override;
247*d9f75844SAndroid Build Coastguard Worker
248*d9f75844SAndroid Build Coastguard Worker const FieldTrialsView& trials() const override;
249*d9f75844SAndroid Build Coastguard Worker
250*d9f75844SAndroid Build Coastguard Worker TaskQueueBase* network_thread() const override;
251*d9f75844SAndroid Build Coastguard Worker TaskQueueBase* worker_thread() const override;
252*d9f75844SAndroid Build Coastguard Worker
253*d9f75844SAndroid Build Coastguard Worker // Implements PacketReceiver.
254*d9f75844SAndroid Build Coastguard Worker DeliveryStatus DeliverPacket(MediaType media_type,
255*d9f75844SAndroid Build Coastguard Worker rtc::CopyOnWriteBuffer packet,
256*d9f75844SAndroid Build Coastguard Worker int64_t packet_time_us) override;
257*d9f75844SAndroid Build Coastguard Worker
258*d9f75844SAndroid Build Coastguard Worker // Implements RecoveredPacketReceiver.
259*d9f75844SAndroid Build Coastguard Worker void OnRecoveredPacket(const uint8_t* packet, size_t length) override;
260*d9f75844SAndroid Build Coastguard Worker
261*d9f75844SAndroid Build Coastguard Worker void SignalChannelNetworkState(MediaType media, NetworkState state) override;
262*d9f75844SAndroid Build Coastguard Worker
263*d9f75844SAndroid Build Coastguard Worker void OnAudioTransportOverheadChanged(
264*d9f75844SAndroid Build Coastguard Worker int transport_overhead_per_packet) override;
265*d9f75844SAndroid Build Coastguard Worker
266*d9f75844SAndroid Build Coastguard Worker void OnLocalSsrcUpdated(webrtc::AudioReceiveStreamInterface& stream,
267*d9f75844SAndroid Build Coastguard Worker uint32_t local_ssrc) override;
268*d9f75844SAndroid Build Coastguard Worker void OnLocalSsrcUpdated(VideoReceiveStreamInterface& stream,
269*d9f75844SAndroid Build Coastguard Worker uint32_t local_ssrc) override;
270*d9f75844SAndroid Build Coastguard Worker void OnLocalSsrcUpdated(FlexfecReceiveStream& stream,
271*d9f75844SAndroid Build Coastguard Worker uint32_t local_ssrc) override;
272*d9f75844SAndroid Build Coastguard Worker
273*d9f75844SAndroid Build Coastguard Worker void OnUpdateSyncGroup(webrtc::AudioReceiveStreamInterface& stream,
274*d9f75844SAndroid Build Coastguard Worker absl::string_view sync_group) override;
275*d9f75844SAndroid Build Coastguard Worker
276*d9f75844SAndroid Build Coastguard Worker void OnSentPacket(const rtc::SentPacket& sent_packet) override;
277*d9f75844SAndroid Build Coastguard Worker
278*d9f75844SAndroid Build Coastguard Worker // Implements TargetTransferRateObserver,
279*d9f75844SAndroid Build Coastguard Worker void OnTargetTransferRate(TargetTransferRate msg) override;
280*d9f75844SAndroid Build Coastguard Worker void OnStartRateUpdate(DataRate start_rate) override;
281*d9f75844SAndroid Build Coastguard Worker
282*d9f75844SAndroid Build Coastguard Worker // Implements BitrateAllocator::LimitObserver.
283*d9f75844SAndroid Build Coastguard Worker void OnAllocationLimitsChanged(BitrateAllocationLimits limits) override;
284*d9f75844SAndroid Build Coastguard Worker
285*d9f75844SAndroid Build Coastguard Worker void SetClientBitratePreferences(const BitrateSettings& preferences) override;
286*d9f75844SAndroid Build Coastguard Worker
287*d9f75844SAndroid Build Coastguard Worker private:
288*d9f75844SAndroid Build Coastguard Worker // Thread-compatible class that collects received packet stats and exposes
289*d9f75844SAndroid Build Coastguard Worker // them as UMA histograms on destruction.
290*d9f75844SAndroid Build Coastguard Worker class ReceiveStats {
291*d9f75844SAndroid Build Coastguard Worker public:
292*d9f75844SAndroid Build Coastguard Worker explicit ReceiveStats(Clock* clock);
293*d9f75844SAndroid Build Coastguard Worker ~ReceiveStats();
294*d9f75844SAndroid Build Coastguard Worker
295*d9f75844SAndroid Build Coastguard Worker void AddReceivedRtcpBytes(int bytes);
296*d9f75844SAndroid Build Coastguard Worker void AddReceivedAudioBytes(int bytes, webrtc::Timestamp arrival_time);
297*d9f75844SAndroid Build Coastguard Worker void AddReceivedVideoBytes(int bytes, webrtc::Timestamp arrival_time);
298*d9f75844SAndroid Build Coastguard Worker
299*d9f75844SAndroid Build Coastguard Worker private:
300*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
301*d9f75844SAndroid Build Coastguard Worker RateCounter received_bytes_per_second_counter_
302*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(sequence_checker_);
303*d9f75844SAndroid Build Coastguard Worker RateCounter received_audio_bytes_per_second_counter_
304*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(sequence_checker_);
305*d9f75844SAndroid Build Coastguard Worker RateCounter received_video_bytes_per_second_counter_
306*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(sequence_checker_);
307*d9f75844SAndroid Build Coastguard Worker RateCounter received_rtcp_bytes_per_second_counter_
308*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(sequence_checker_);
309*d9f75844SAndroid Build Coastguard Worker absl::optional<Timestamp> first_received_rtp_audio_timestamp_
310*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(sequence_checker_);
311*d9f75844SAndroid Build Coastguard Worker absl::optional<Timestamp> last_received_rtp_audio_timestamp_
312*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(sequence_checker_);
313*d9f75844SAndroid Build Coastguard Worker absl::optional<Timestamp> first_received_rtp_video_timestamp_
314*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(sequence_checker_);
315*d9f75844SAndroid Build Coastguard Worker absl::optional<Timestamp> last_received_rtp_video_timestamp_
316*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(sequence_checker_);
317*d9f75844SAndroid Build Coastguard Worker };
318*d9f75844SAndroid Build Coastguard Worker
319*d9f75844SAndroid Build Coastguard Worker // Thread-compatible class that collects sent packet stats and exposes
320*d9f75844SAndroid Build Coastguard Worker // them as UMA histograms on destruction, provided SetFirstPacketTime was
321*d9f75844SAndroid Build Coastguard Worker // called with a non-empty packet timestamp before the destructor.
322*d9f75844SAndroid Build Coastguard Worker class SendStats {
323*d9f75844SAndroid Build Coastguard Worker public:
324*d9f75844SAndroid Build Coastguard Worker explicit SendStats(Clock* clock);
325*d9f75844SAndroid Build Coastguard Worker ~SendStats();
326*d9f75844SAndroid Build Coastguard Worker
327*d9f75844SAndroid Build Coastguard Worker void SetFirstPacketTime(absl::optional<Timestamp> first_sent_packet_time);
328*d9f75844SAndroid Build Coastguard Worker void PauseSendAndPacerBitrateCounters();
329*d9f75844SAndroid Build Coastguard Worker void AddTargetBitrateSample(uint32_t target_bitrate_bps);
330*d9f75844SAndroid Build Coastguard Worker void SetMinAllocatableRate(BitrateAllocationLimits limits);
331*d9f75844SAndroid Build Coastguard Worker
332*d9f75844SAndroid Build Coastguard Worker private:
333*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS SequenceChecker destructor_sequence_checker_;
334*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS SequenceChecker sequence_checker_;
335*d9f75844SAndroid Build Coastguard Worker Clock* const clock_ RTC_GUARDED_BY(destructor_sequence_checker_);
336*d9f75844SAndroid Build Coastguard Worker AvgCounter estimated_send_bitrate_kbps_counter_
337*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(sequence_checker_);
338*d9f75844SAndroid Build Coastguard Worker AvgCounter pacer_bitrate_kbps_counter_ RTC_GUARDED_BY(sequence_checker_);
RTC_GUARDED_BY(sequence_checker_)339*d9f75844SAndroid Build Coastguard Worker uint32_t min_allocated_send_bitrate_bps_ RTC_GUARDED_BY(sequence_checker_){
340*d9f75844SAndroid Build Coastguard Worker 0};
341*d9f75844SAndroid Build Coastguard Worker absl::optional<Timestamp> first_sent_packet_time_
342*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(destructor_sequence_checker_);
343*d9f75844SAndroid Build Coastguard Worker };
344*d9f75844SAndroid Build Coastguard Worker
345*d9f75844SAndroid Build Coastguard Worker void DeliverRtcp(MediaType media_type, rtc::CopyOnWriteBuffer packet)
346*d9f75844SAndroid Build Coastguard Worker RTC_RUN_ON(network_thread_);
347*d9f75844SAndroid Build Coastguard Worker DeliveryStatus DeliverRtp(MediaType media_type,
348*d9f75844SAndroid Build Coastguard Worker rtc::CopyOnWriteBuffer packet,
349*d9f75844SAndroid Build Coastguard Worker int64_t packet_time_us) RTC_RUN_ON(worker_thread_);
350*d9f75844SAndroid Build Coastguard Worker
351*d9f75844SAndroid Build Coastguard Worker AudioReceiveStreamImpl* FindAudioStreamForSyncGroup(
352*d9f75844SAndroid Build Coastguard Worker absl::string_view sync_group) RTC_RUN_ON(worker_thread_);
353*d9f75844SAndroid Build Coastguard Worker void ConfigureSync(absl::string_view sync_group) RTC_RUN_ON(worker_thread_);
354*d9f75844SAndroid Build Coastguard Worker
355*d9f75844SAndroid Build Coastguard Worker void NotifyBweOfReceivedPacket(const RtpPacketReceived& packet,
356*d9f75844SAndroid Build Coastguard Worker MediaType media_type,
357*d9f75844SAndroid Build Coastguard Worker bool use_send_side_bwe)
358*d9f75844SAndroid Build Coastguard Worker RTC_RUN_ON(worker_thread_);
359*d9f75844SAndroid Build Coastguard Worker
360*d9f75844SAndroid Build Coastguard Worker bool IdentifyReceivedPacket(RtpPacketReceived& packet,
361*d9f75844SAndroid Build Coastguard Worker bool* use_send_side_bwe = nullptr);
362*d9f75844SAndroid Build Coastguard Worker bool RegisterReceiveStream(uint32_t ssrc, ReceiveStreamInterface* stream);
363*d9f75844SAndroid Build Coastguard Worker bool UnregisterReceiveStream(uint32_t ssrc);
364*d9f75844SAndroid Build Coastguard Worker
365*d9f75844SAndroid Build Coastguard Worker void UpdateAggregateNetworkState();
366*d9f75844SAndroid Build Coastguard Worker
367*d9f75844SAndroid Build Coastguard Worker // Ensure that necessary process threads are started, and any required
368*d9f75844SAndroid Build Coastguard Worker // callbacks have been registered.
369*d9f75844SAndroid Build Coastguard Worker void EnsureStarted() RTC_RUN_ON(worker_thread_);
370*d9f75844SAndroid Build Coastguard Worker
371*d9f75844SAndroid Build Coastguard Worker Clock* const clock_;
372*d9f75844SAndroid Build Coastguard Worker TaskQueueFactory* const task_queue_factory_;
373*d9f75844SAndroid Build Coastguard Worker TaskQueueBase* const worker_thread_;
374*d9f75844SAndroid Build Coastguard Worker TaskQueueBase* const network_thread_;
375*d9f75844SAndroid Build Coastguard Worker const std::unique_ptr<DecodeSynchronizer> decode_sync_;
376*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS SequenceChecker send_transport_sequence_checker_;
377*d9f75844SAndroid Build Coastguard Worker
378*d9f75844SAndroid Build Coastguard Worker const int num_cpu_cores_;
379*d9f75844SAndroid Build Coastguard Worker const std::unique_ptr<CallStats> call_stats_;
380*d9f75844SAndroid Build Coastguard Worker const std::unique_ptr<BitrateAllocator> bitrate_allocator_;
381*d9f75844SAndroid Build Coastguard Worker const Call::Config config_ RTC_GUARDED_BY(worker_thread_);
382*d9f75844SAndroid Build Coastguard Worker // Maps to config_.trials, can be used from any thread via `trials()`.
383*d9f75844SAndroid Build Coastguard Worker const FieldTrialsView& trials_;
384*d9f75844SAndroid Build Coastguard Worker
385*d9f75844SAndroid Build Coastguard Worker NetworkState audio_network_state_ RTC_GUARDED_BY(worker_thread_);
386*d9f75844SAndroid Build Coastguard Worker NetworkState video_network_state_ RTC_GUARDED_BY(worker_thread_);
387*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Move aggregate_network_up_ over to the
388*d9f75844SAndroid Build Coastguard Worker // network thread.
389*d9f75844SAndroid Build Coastguard Worker bool aggregate_network_up_ RTC_GUARDED_BY(worker_thread_);
390*d9f75844SAndroid Build Coastguard Worker
391*d9f75844SAndroid Build Coastguard Worker // Schedules nack periodic processing on behalf of all streams.
392*d9f75844SAndroid Build Coastguard Worker NackPeriodicProcessor nack_periodic_processor_;
393*d9f75844SAndroid Build Coastguard Worker
394*d9f75844SAndroid Build Coastguard Worker // Audio, Video, and FlexFEC receive streams are owned by the client that
395*d9f75844SAndroid Build Coastguard Worker // creates them.
396*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Move audio_receive_streams_,
397*d9f75844SAndroid Build Coastguard Worker // video_receive_streams_ over to the network thread.
398*d9f75844SAndroid Build Coastguard Worker std::set<AudioReceiveStreamImpl*> audio_receive_streams_
399*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(worker_thread_);
400*d9f75844SAndroid Build Coastguard Worker std::set<VideoReceiveStream2*> video_receive_streams_
401*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(worker_thread_);
402*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/7135, bugs.webrtc.org/9719): Should eventually be
403*d9f75844SAndroid Build Coastguard Worker // injected at creation, with a single object in the bundled case.
404*d9f75844SAndroid Build Coastguard Worker RtpStreamReceiverController audio_receiver_controller_
405*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(worker_thread_);
406*d9f75844SAndroid Build Coastguard Worker RtpStreamReceiverController video_receiver_controller_
407*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(worker_thread_);
408*d9f75844SAndroid Build Coastguard Worker
409*d9f75844SAndroid Build Coastguard Worker // This extra map is used for receive processing which is
410*d9f75844SAndroid Build Coastguard Worker // independent of media type.
411*d9f75844SAndroid Build Coastguard Worker
412*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS SequenceChecker receive_11993_checker_;
413*d9f75844SAndroid Build Coastguard Worker
414*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Move receive_rtp_config_ over to the
415*d9f75844SAndroid Build Coastguard Worker // network thread.
416*d9f75844SAndroid Build Coastguard Worker std::map<uint32_t, ReceiveStreamInterface*> receive_rtp_config_
417*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(&receive_11993_checker_);
418*d9f75844SAndroid Build Coastguard Worker
419*d9f75844SAndroid Build Coastguard Worker // Audio and Video send streams are owned by the client that creates them.
420*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): `audio_send_ssrcs_` and `video_send_ssrcs_`
421*d9f75844SAndroid Build Coastguard Worker // should be accessed on the network thread.
422*d9f75844SAndroid Build Coastguard Worker std::map<uint32_t, AudioSendStream*> audio_send_ssrcs_
423*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(worker_thread_);
424*d9f75844SAndroid Build Coastguard Worker std::map<uint32_t, VideoSendStream*> video_send_ssrcs_
425*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(worker_thread_);
426*d9f75844SAndroid Build Coastguard Worker std::set<VideoSendStream*> video_send_streams_ RTC_GUARDED_BY(worker_thread_);
427*d9f75844SAndroid Build Coastguard Worker // True if `video_send_streams_` is empty, false if not. The atomic variable
428*d9f75844SAndroid Build Coastguard Worker // is used to decide UMA send statistics behavior and enables avoiding a
429*d9f75844SAndroid Build Coastguard Worker // PostTask().
430*d9f75844SAndroid Build Coastguard Worker std::atomic<bool> video_send_streams_empty_{true};
431*d9f75844SAndroid Build Coastguard Worker
432*d9f75844SAndroid Build Coastguard Worker // Each forwarder wraps an adaptation resource that was added to the call.
433*d9f75844SAndroid Build Coastguard Worker std::vector<std::unique_ptr<ResourceVideoSendStreamForwarder>>
434*d9f75844SAndroid Build Coastguard Worker adaptation_resource_forwarders_ RTC_GUARDED_BY(worker_thread_);
435*d9f75844SAndroid Build Coastguard Worker
436*d9f75844SAndroid Build Coastguard Worker using RtpStateMap = std::map<uint32_t, RtpState>;
437*d9f75844SAndroid Build Coastguard Worker RtpStateMap suspended_audio_send_ssrcs_ RTC_GUARDED_BY(worker_thread_);
438*d9f75844SAndroid Build Coastguard Worker RtpStateMap suspended_video_send_ssrcs_ RTC_GUARDED_BY(worker_thread_);
439*d9f75844SAndroid Build Coastguard Worker
440*d9f75844SAndroid Build Coastguard Worker using RtpPayloadStateMap = std::map<uint32_t, RtpPayloadState>;
441*d9f75844SAndroid Build Coastguard Worker RtpPayloadStateMap suspended_video_payload_states_
442*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(worker_thread_);
443*d9f75844SAndroid Build Coastguard Worker
444*d9f75844SAndroid Build Coastguard Worker webrtc::RtcEventLog* const event_log_;
445*d9f75844SAndroid Build Coastguard Worker
446*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993) ready to move stats access to the network
447*d9f75844SAndroid Build Coastguard Worker // thread.
448*d9f75844SAndroid Build Coastguard Worker ReceiveStats receive_stats_ RTC_GUARDED_BY(worker_thread_);
449*d9f75844SAndroid Build Coastguard Worker SendStats send_stats_ RTC_GUARDED_BY(send_transport_sequence_checker_);
450*d9f75844SAndroid Build Coastguard Worker // `last_bandwidth_bps_` and `configured_max_padding_bitrate_bps_` being
451*d9f75844SAndroid Build Coastguard Worker // atomic avoids a PostTask. The variables are used for stats gathering.
452*d9f75844SAndroid Build Coastguard Worker std::atomic<uint32_t> last_bandwidth_bps_{0};
453*d9f75844SAndroid Build Coastguard Worker std::atomic<uint32_t> configured_max_padding_bitrate_bps_{0};
454*d9f75844SAndroid Build Coastguard Worker
455*d9f75844SAndroid Build Coastguard Worker ReceiveSideCongestionController receive_side_cc_;
456*d9f75844SAndroid Build Coastguard Worker RepeatingTaskHandle receive_side_cc_periodic_task_;
457*d9f75844SAndroid Build Coastguard Worker
458*d9f75844SAndroid Build Coastguard Worker const std::unique_ptr<ReceiveTimeCalculator> receive_time_calculator_;
459*d9f75844SAndroid Build Coastguard Worker
460*d9f75844SAndroid Build Coastguard Worker const std::unique_ptr<SendDelayStats> video_send_delay_stats_;
461*d9f75844SAndroid Build Coastguard Worker const Timestamp start_of_call_;
462*d9f75844SAndroid Build Coastguard Worker
463*d9f75844SAndroid Build Coastguard Worker // Note that `task_safety_` needs to be at a greater scope than the task queue
464*d9f75844SAndroid Build Coastguard Worker // owned by `transport_send_` since calls might arrive on the network thread
465*d9f75844SAndroid Build Coastguard Worker // while Call is being deleted and the task queue is being torn down.
466*d9f75844SAndroid Build Coastguard Worker const ScopedTaskSafety task_safety_;
467*d9f75844SAndroid Build Coastguard Worker
468*d9f75844SAndroid Build Coastguard Worker // Caches transport_send_.get(), to avoid racing with destructor.
469*d9f75844SAndroid Build Coastguard Worker // Note that this is declared before transport_send_ to ensure that it is not
470*d9f75844SAndroid Build Coastguard Worker // invalidated until no more tasks can be running on the transport_send_ task
471*d9f75844SAndroid Build Coastguard Worker // queue.
472*d9f75844SAndroid Build Coastguard Worker // For more details on the background of this member variable, see:
473*d9f75844SAndroid Build Coastguard Worker // https://webrtc-review.googlesource.com/c/src/+/63023/9/call/call.cc
474*d9f75844SAndroid Build Coastguard Worker // https://bugs.chromium.org/p/chromium/issues/detail?id=992640
475*d9f75844SAndroid Build Coastguard Worker RtpTransportControllerSendInterface* const transport_send_ptr_
476*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(send_transport_sequence_checker_);
477*d9f75844SAndroid Build Coastguard Worker // Declared last since it will issue callbacks from a task queue. Declaring it
478*d9f75844SAndroid Build Coastguard Worker // last ensures that it is destroyed first and any running tasks are finished.
479*d9f75844SAndroid Build Coastguard Worker const std::unique_ptr<RtpTransportControllerSendInterface> transport_send_;
480*d9f75844SAndroid Build Coastguard Worker
481*d9f75844SAndroid Build Coastguard Worker bool is_started_ RTC_GUARDED_BY(worker_thread_) = false;
482*d9f75844SAndroid Build Coastguard Worker
483*d9f75844SAndroid Build Coastguard Worker // Sequence checker for outgoing network traffic. Could be the network thread.
484*d9f75844SAndroid Build Coastguard Worker // Could also be a pacer owned thread or TQ such as the TaskQueuePacedSender.
485*d9f75844SAndroid Build Coastguard Worker RTC_NO_UNIQUE_ADDRESS SequenceChecker sent_packet_sequence_checker_;
486*d9f75844SAndroid Build Coastguard Worker absl::optional<rtc::SentPacket> last_sent_packet_
487*d9f75844SAndroid Build Coastguard Worker RTC_GUARDED_BY(sent_packet_sequence_checker_);
488*d9f75844SAndroid Build Coastguard Worker };
489*d9f75844SAndroid Build Coastguard Worker } // namespace internal
490*d9f75844SAndroid Build Coastguard Worker
ToString(int64_t time_ms) const491*d9f75844SAndroid Build Coastguard Worker std::string Call::Stats::ToString(int64_t time_ms) const {
492*d9f75844SAndroid Build Coastguard Worker char buf[1024];
493*d9f75844SAndroid Build Coastguard Worker rtc::SimpleStringBuilder ss(buf);
494*d9f75844SAndroid Build Coastguard Worker ss << "Call stats: " << time_ms << ", {";
495*d9f75844SAndroid Build Coastguard Worker ss << "send_bw_bps: " << send_bandwidth_bps << ", ";
496*d9f75844SAndroid Build Coastguard Worker ss << "recv_bw_bps: " << recv_bandwidth_bps << ", ";
497*d9f75844SAndroid Build Coastguard Worker ss << "max_pad_bps: " << max_padding_bitrate_bps << ", ";
498*d9f75844SAndroid Build Coastguard Worker ss << "pacer_delay_ms: " << pacer_delay_ms << ", ";
499*d9f75844SAndroid Build Coastguard Worker ss << "rtt_ms: " << rtt_ms;
500*d9f75844SAndroid Build Coastguard Worker ss << '}';
501*d9f75844SAndroid Build Coastguard Worker return ss.str();
502*d9f75844SAndroid Build Coastguard Worker }
503*d9f75844SAndroid Build Coastguard Worker
Create(const Call::Config & config)504*d9f75844SAndroid Build Coastguard Worker Call* Call::Create(const Call::Config& config) {
505*d9f75844SAndroid Build Coastguard Worker Clock* clock = Clock::GetRealTimeClock();
506*d9f75844SAndroid Build Coastguard Worker return Create(config, clock,
507*d9f75844SAndroid Build Coastguard Worker RtpTransportControllerSendFactory().Create(
508*d9f75844SAndroid Build Coastguard Worker config.ExtractTransportConfig(), clock));
509*d9f75844SAndroid Build Coastguard Worker }
510*d9f75844SAndroid Build Coastguard Worker
Create(const Call::Config & config,Clock * clock,std::unique_ptr<RtpTransportControllerSendInterface> transportControllerSend)511*d9f75844SAndroid Build Coastguard Worker Call* Call::Create(const Call::Config& config,
512*d9f75844SAndroid Build Coastguard Worker Clock* clock,
513*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<RtpTransportControllerSendInterface>
514*d9f75844SAndroid Build Coastguard Worker transportControllerSend) {
515*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(config.task_queue_factory);
516*d9f75844SAndroid Build Coastguard Worker return new internal::Call(clock, config, std::move(transportControllerSend),
517*d9f75844SAndroid Build Coastguard Worker config.task_queue_factory);
518*d9f75844SAndroid Build Coastguard Worker }
519*d9f75844SAndroid Build Coastguard Worker
520*d9f75844SAndroid Build Coastguard Worker // This method here to avoid subclasses has to implement this method.
521*d9f75844SAndroid Build Coastguard Worker // Call perf test will use Internal::Call::CreateVideoSendStream() to inject
522*d9f75844SAndroid Build Coastguard Worker // FecController.
CreateVideoSendStream(VideoSendStream::Config config,VideoEncoderConfig encoder_config,std::unique_ptr<FecController> fec_controller)523*d9f75844SAndroid Build Coastguard Worker VideoSendStream* Call::CreateVideoSendStream(
524*d9f75844SAndroid Build Coastguard Worker VideoSendStream::Config config,
525*d9f75844SAndroid Build Coastguard Worker VideoEncoderConfig encoder_config,
526*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<FecController> fec_controller) {
527*d9f75844SAndroid Build Coastguard Worker return nullptr;
528*d9f75844SAndroid Build Coastguard Worker }
529*d9f75844SAndroid Build Coastguard Worker
530*d9f75844SAndroid Build Coastguard Worker namespace internal {
531*d9f75844SAndroid Build Coastguard Worker
ReceiveStats(Clock * clock)532*d9f75844SAndroid Build Coastguard Worker Call::ReceiveStats::ReceiveStats(Clock* clock)
533*d9f75844SAndroid Build Coastguard Worker : received_bytes_per_second_counter_(clock, nullptr, false),
534*d9f75844SAndroid Build Coastguard Worker received_audio_bytes_per_second_counter_(clock, nullptr, false),
535*d9f75844SAndroid Build Coastguard Worker received_video_bytes_per_second_counter_(clock, nullptr, false),
536*d9f75844SAndroid Build Coastguard Worker received_rtcp_bytes_per_second_counter_(clock, nullptr, false) {
537*d9f75844SAndroid Build Coastguard Worker sequence_checker_.Detach();
538*d9f75844SAndroid Build Coastguard Worker }
539*d9f75844SAndroid Build Coastguard Worker
AddReceivedRtcpBytes(int bytes)540*d9f75844SAndroid Build Coastguard Worker void Call::ReceiveStats::AddReceivedRtcpBytes(int bytes) {
541*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_);
542*d9f75844SAndroid Build Coastguard Worker if (received_bytes_per_second_counter_.HasSample()) {
543*d9f75844SAndroid Build Coastguard Worker // First RTP packet has been received.
544*d9f75844SAndroid Build Coastguard Worker received_bytes_per_second_counter_.Add(static_cast<int>(bytes));
545*d9f75844SAndroid Build Coastguard Worker received_rtcp_bytes_per_second_counter_.Add(static_cast<int>(bytes));
546*d9f75844SAndroid Build Coastguard Worker }
547*d9f75844SAndroid Build Coastguard Worker }
548*d9f75844SAndroid Build Coastguard Worker
AddReceivedAudioBytes(int bytes,webrtc::Timestamp arrival_time)549*d9f75844SAndroid Build Coastguard Worker void Call::ReceiveStats::AddReceivedAudioBytes(int bytes,
550*d9f75844SAndroid Build Coastguard Worker webrtc::Timestamp arrival_time) {
551*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_);
552*d9f75844SAndroid Build Coastguard Worker received_bytes_per_second_counter_.Add(bytes);
553*d9f75844SAndroid Build Coastguard Worker received_audio_bytes_per_second_counter_.Add(bytes);
554*d9f75844SAndroid Build Coastguard Worker if (!first_received_rtp_audio_timestamp_)
555*d9f75844SAndroid Build Coastguard Worker first_received_rtp_audio_timestamp_ = arrival_time;
556*d9f75844SAndroid Build Coastguard Worker last_received_rtp_audio_timestamp_ = arrival_time;
557*d9f75844SAndroid Build Coastguard Worker }
558*d9f75844SAndroid Build Coastguard Worker
AddReceivedVideoBytes(int bytes,webrtc::Timestamp arrival_time)559*d9f75844SAndroid Build Coastguard Worker void Call::ReceiveStats::AddReceivedVideoBytes(int bytes,
560*d9f75844SAndroid Build Coastguard Worker webrtc::Timestamp arrival_time) {
561*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_);
562*d9f75844SAndroid Build Coastguard Worker received_bytes_per_second_counter_.Add(bytes);
563*d9f75844SAndroid Build Coastguard Worker received_video_bytes_per_second_counter_.Add(bytes);
564*d9f75844SAndroid Build Coastguard Worker if (!first_received_rtp_video_timestamp_)
565*d9f75844SAndroid Build Coastguard Worker first_received_rtp_video_timestamp_ = arrival_time;
566*d9f75844SAndroid Build Coastguard Worker last_received_rtp_video_timestamp_ = arrival_time;
567*d9f75844SAndroid Build Coastguard Worker }
568*d9f75844SAndroid Build Coastguard Worker
~ReceiveStats()569*d9f75844SAndroid Build Coastguard Worker Call::ReceiveStats::~ReceiveStats() {
570*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_);
571*d9f75844SAndroid Build Coastguard Worker if (first_received_rtp_audio_timestamp_) {
572*d9f75844SAndroid Build Coastguard Worker RTC_HISTOGRAM_COUNTS_100000(
573*d9f75844SAndroid Build Coastguard Worker "WebRTC.Call.TimeReceivingAudioRtpPacketsInSeconds",
574*d9f75844SAndroid Build Coastguard Worker (*last_received_rtp_audio_timestamp_ -
575*d9f75844SAndroid Build Coastguard Worker *first_received_rtp_audio_timestamp_)
576*d9f75844SAndroid Build Coastguard Worker .seconds());
577*d9f75844SAndroid Build Coastguard Worker }
578*d9f75844SAndroid Build Coastguard Worker if (first_received_rtp_video_timestamp_) {
579*d9f75844SAndroid Build Coastguard Worker RTC_HISTOGRAM_COUNTS_100000(
580*d9f75844SAndroid Build Coastguard Worker "WebRTC.Call.TimeReceivingVideoRtpPacketsInSeconds",
581*d9f75844SAndroid Build Coastguard Worker (*last_received_rtp_video_timestamp_ -
582*d9f75844SAndroid Build Coastguard Worker *first_received_rtp_video_timestamp_)
583*d9f75844SAndroid Build Coastguard Worker .seconds());
584*d9f75844SAndroid Build Coastguard Worker }
585*d9f75844SAndroid Build Coastguard Worker const int kMinRequiredPeriodicSamples = 5;
586*d9f75844SAndroid Build Coastguard Worker AggregatedStats video_bytes_per_sec =
587*d9f75844SAndroid Build Coastguard Worker received_video_bytes_per_second_counter_.GetStats();
588*d9f75844SAndroid Build Coastguard Worker if (video_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
589*d9f75844SAndroid Build Coastguard Worker RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.VideoBitrateReceivedInKbps",
590*d9f75844SAndroid Build Coastguard Worker video_bytes_per_sec.average * 8 / 1000);
591*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "WebRTC.Call.VideoBitrateReceivedInBps, "
592*d9f75844SAndroid Build Coastguard Worker << video_bytes_per_sec.ToStringWithMultiplier(8);
593*d9f75844SAndroid Build Coastguard Worker }
594*d9f75844SAndroid Build Coastguard Worker AggregatedStats audio_bytes_per_sec =
595*d9f75844SAndroid Build Coastguard Worker received_audio_bytes_per_second_counter_.GetStats();
596*d9f75844SAndroid Build Coastguard Worker if (audio_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
597*d9f75844SAndroid Build Coastguard Worker RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.AudioBitrateReceivedInKbps",
598*d9f75844SAndroid Build Coastguard Worker audio_bytes_per_sec.average * 8 / 1000);
599*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "WebRTC.Call.AudioBitrateReceivedInBps, "
600*d9f75844SAndroid Build Coastguard Worker << audio_bytes_per_sec.ToStringWithMultiplier(8);
601*d9f75844SAndroid Build Coastguard Worker }
602*d9f75844SAndroid Build Coastguard Worker AggregatedStats rtcp_bytes_per_sec =
603*d9f75844SAndroid Build Coastguard Worker received_rtcp_bytes_per_second_counter_.GetStats();
604*d9f75844SAndroid Build Coastguard Worker if (rtcp_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
605*d9f75844SAndroid Build Coastguard Worker RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.RtcpBitrateReceivedInBps",
606*d9f75844SAndroid Build Coastguard Worker rtcp_bytes_per_sec.average * 8);
607*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "WebRTC.Call.RtcpBitrateReceivedInBps, "
608*d9f75844SAndroid Build Coastguard Worker << rtcp_bytes_per_sec.ToStringWithMultiplier(8);
609*d9f75844SAndroid Build Coastguard Worker }
610*d9f75844SAndroid Build Coastguard Worker AggregatedStats recv_bytes_per_sec =
611*d9f75844SAndroid Build Coastguard Worker received_bytes_per_second_counter_.GetStats();
612*d9f75844SAndroid Build Coastguard Worker if (recv_bytes_per_sec.num_samples > kMinRequiredPeriodicSamples) {
613*d9f75844SAndroid Build Coastguard Worker RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.BitrateReceivedInKbps",
614*d9f75844SAndroid Build Coastguard Worker recv_bytes_per_sec.average * 8 / 1000);
615*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "WebRTC.Call.BitrateReceivedInBps, "
616*d9f75844SAndroid Build Coastguard Worker << recv_bytes_per_sec.ToStringWithMultiplier(8);
617*d9f75844SAndroid Build Coastguard Worker }
618*d9f75844SAndroid Build Coastguard Worker }
619*d9f75844SAndroid Build Coastguard Worker
SendStats(Clock * clock)620*d9f75844SAndroid Build Coastguard Worker Call::SendStats::SendStats(Clock* clock)
621*d9f75844SAndroid Build Coastguard Worker : clock_(clock),
622*d9f75844SAndroid Build Coastguard Worker estimated_send_bitrate_kbps_counter_(clock, nullptr, true),
623*d9f75844SAndroid Build Coastguard Worker pacer_bitrate_kbps_counter_(clock, nullptr, true) {
624*d9f75844SAndroid Build Coastguard Worker destructor_sequence_checker_.Detach();
625*d9f75844SAndroid Build Coastguard Worker sequence_checker_.Detach();
626*d9f75844SAndroid Build Coastguard Worker }
627*d9f75844SAndroid Build Coastguard Worker
~SendStats()628*d9f75844SAndroid Build Coastguard Worker Call::SendStats::~SendStats() {
629*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&destructor_sequence_checker_);
630*d9f75844SAndroid Build Coastguard Worker if (!first_sent_packet_time_)
631*d9f75844SAndroid Build Coastguard Worker return;
632*d9f75844SAndroid Build Coastguard Worker
633*d9f75844SAndroid Build Coastguard Worker TimeDelta elapsed = clock_->CurrentTime() - *first_sent_packet_time_;
634*d9f75844SAndroid Build Coastguard Worker if (elapsed.seconds() < metrics::kMinRunTimeInSeconds)
635*d9f75844SAndroid Build Coastguard Worker return;
636*d9f75844SAndroid Build Coastguard Worker
637*d9f75844SAndroid Build Coastguard Worker const int kMinRequiredPeriodicSamples = 5;
638*d9f75844SAndroid Build Coastguard Worker AggregatedStats send_bitrate_stats =
639*d9f75844SAndroid Build Coastguard Worker estimated_send_bitrate_kbps_counter_.ProcessAndGetStats();
640*d9f75844SAndroid Build Coastguard Worker if (send_bitrate_stats.num_samples > kMinRequiredPeriodicSamples) {
641*d9f75844SAndroid Build Coastguard Worker RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.EstimatedSendBitrateInKbps",
642*d9f75844SAndroid Build Coastguard Worker send_bitrate_stats.average);
643*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "WebRTC.Call.EstimatedSendBitrateInKbps, "
644*d9f75844SAndroid Build Coastguard Worker << send_bitrate_stats.ToString();
645*d9f75844SAndroid Build Coastguard Worker }
646*d9f75844SAndroid Build Coastguard Worker AggregatedStats pacer_bitrate_stats =
647*d9f75844SAndroid Build Coastguard Worker pacer_bitrate_kbps_counter_.ProcessAndGetStats();
648*d9f75844SAndroid Build Coastguard Worker if (pacer_bitrate_stats.num_samples > kMinRequiredPeriodicSamples) {
649*d9f75844SAndroid Build Coastguard Worker RTC_HISTOGRAM_COUNTS_100000("WebRTC.Call.PacerBitrateInKbps",
650*d9f75844SAndroid Build Coastguard Worker pacer_bitrate_stats.average);
651*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "WebRTC.Call.PacerBitrateInKbps, "
652*d9f75844SAndroid Build Coastguard Worker << pacer_bitrate_stats.ToString();
653*d9f75844SAndroid Build Coastguard Worker }
654*d9f75844SAndroid Build Coastguard Worker }
655*d9f75844SAndroid Build Coastguard Worker
SetFirstPacketTime(absl::optional<Timestamp> first_sent_packet_time)656*d9f75844SAndroid Build Coastguard Worker void Call::SendStats::SetFirstPacketTime(
657*d9f75844SAndroid Build Coastguard Worker absl::optional<Timestamp> first_sent_packet_time) {
658*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&destructor_sequence_checker_);
659*d9f75844SAndroid Build Coastguard Worker first_sent_packet_time_ = first_sent_packet_time;
660*d9f75844SAndroid Build Coastguard Worker }
661*d9f75844SAndroid Build Coastguard Worker
PauseSendAndPacerBitrateCounters()662*d9f75844SAndroid Build Coastguard Worker void Call::SendStats::PauseSendAndPacerBitrateCounters() {
663*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_);
664*d9f75844SAndroid Build Coastguard Worker estimated_send_bitrate_kbps_counter_.ProcessAndPause();
665*d9f75844SAndroid Build Coastguard Worker pacer_bitrate_kbps_counter_.ProcessAndPause();
666*d9f75844SAndroid Build Coastguard Worker }
667*d9f75844SAndroid Build Coastguard Worker
AddTargetBitrateSample(uint32_t target_bitrate_bps)668*d9f75844SAndroid Build Coastguard Worker void Call::SendStats::AddTargetBitrateSample(uint32_t target_bitrate_bps) {
669*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_);
670*d9f75844SAndroid Build Coastguard Worker estimated_send_bitrate_kbps_counter_.Add(target_bitrate_bps / 1000);
671*d9f75844SAndroid Build Coastguard Worker // Pacer bitrate may be higher than bitrate estimate if enforcing min
672*d9f75844SAndroid Build Coastguard Worker // bitrate.
673*d9f75844SAndroid Build Coastguard Worker uint32_t pacer_bitrate_bps =
674*d9f75844SAndroid Build Coastguard Worker std::max(target_bitrate_bps, min_allocated_send_bitrate_bps_);
675*d9f75844SAndroid Build Coastguard Worker pacer_bitrate_kbps_counter_.Add(pacer_bitrate_bps / 1000);
676*d9f75844SAndroid Build Coastguard Worker }
677*d9f75844SAndroid Build Coastguard Worker
SetMinAllocatableRate(BitrateAllocationLimits limits)678*d9f75844SAndroid Build Coastguard Worker void Call::SendStats::SetMinAllocatableRate(BitrateAllocationLimits limits) {
679*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sequence_checker_);
680*d9f75844SAndroid Build Coastguard Worker min_allocated_send_bitrate_bps_ = limits.min_allocatable_rate.bps();
681*d9f75844SAndroid Build Coastguard Worker }
682*d9f75844SAndroid Build Coastguard Worker
Call(Clock * clock,const Call::Config & config,std::unique_ptr<RtpTransportControllerSendInterface> transport_send,TaskQueueFactory * task_queue_factory)683*d9f75844SAndroid Build Coastguard Worker Call::Call(Clock* clock,
684*d9f75844SAndroid Build Coastguard Worker const Call::Config& config,
685*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<RtpTransportControllerSendInterface> transport_send,
686*d9f75844SAndroid Build Coastguard Worker TaskQueueFactory* task_queue_factory)
687*d9f75844SAndroid Build Coastguard Worker : clock_(clock),
688*d9f75844SAndroid Build Coastguard Worker task_queue_factory_(task_queue_factory),
689*d9f75844SAndroid Build Coastguard Worker worker_thread_(GetCurrentTaskQueueOrThread()),
690*d9f75844SAndroid Build Coastguard Worker // If `network_task_queue_` was set to nullptr, network related calls
691*d9f75844SAndroid Build Coastguard Worker // must be made on `worker_thread_` (i.e. they're one and the same).
692*d9f75844SAndroid Build Coastguard Worker network_thread_(config.network_task_queue_ ? config.network_task_queue_
693*d9f75844SAndroid Build Coastguard Worker : worker_thread_),
694*d9f75844SAndroid Build Coastguard Worker decode_sync_(config.metronome
695*d9f75844SAndroid Build Coastguard Worker ? std::make_unique<DecodeSynchronizer>(clock_,
696*d9f75844SAndroid Build Coastguard Worker config.metronome,
697*d9f75844SAndroid Build Coastguard Worker worker_thread_)
698*d9f75844SAndroid Build Coastguard Worker : nullptr),
699*d9f75844SAndroid Build Coastguard Worker num_cpu_cores_(CpuInfo::DetectNumberOfCores()),
700*d9f75844SAndroid Build Coastguard Worker call_stats_(new CallStats(clock_, worker_thread_)),
701*d9f75844SAndroid Build Coastguard Worker bitrate_allocator_(new BitrateAllocator(this)),
702*d9f75844SAndroid Build Coastguard Worker config_(config),
703*d9f75844SAndroid Build Coastguard Worker trials_(*config.trials),
704*d9f75844SAndroid Build Coastguard Worker audio_network_state_(kNetworkDown),
705*d9f75844SAndroid Build Coastguard Worker video_network_state_(kNetworkDown),
706*d9f75844SAndroid Build Coastguard Worker aggregate_network_up_(false),
707*d9f75844SAndroid Build Coastguard Worker event_log_(config.event_log),
708*d9f75844SAndroid Build Coastguard Worker receive_stats_(clock_),
709*d9f75844SAndroid Build Coastguard Worker send_stats_(clock_),
710*d9f75844SAndroid Build Coastguard Worker receive_side_cc_(clock,
711*d9f75844SAndroid Build Coastguard Worker absl::bind_front(&PacketRouter::SendCombinedRtcpPacket,
712*d9f75844SAndroid Build Coastguard Worker transport_send->packet_router()),
713*d9f75844SAndroid Build Coastguard Worker absl::bind_front(&PacketRouter::SendRemb,
714*d9f75844SAndroid Build Coastguard Worker transport_send->packet_router()),
715*d9f75844SAndroid Build Coastguard Worker /*network_state_estimator=*/nullptr),
716*d9f75844SAndroid Build Coastguard Worker receive_time_calculator_(
717*d9f75844SAndroid Build Coastguard Worker ReceiveTimeCalculator::CreateFromFieldTrial(*config.trials)),
718*d9f75844SAndroid Build Coastguard Worker video_send_delay_stats_(new SendDelayStats(clock_)),
719*d9f75844SAndroid Build Coastguard Worker start_of_call_(clock_->CurrentTime()),
720*d9f75844SAndroid Build Coastguard Worker transport_send_ptr_(transport_send.get()),
721*d9f75844SAndroid Build Coastguard Worker transport_send_(std::move(transport_send)) {
722*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(config.event_log != nullptr);
723*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(config.trials != nullptr);
724*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(network_thread_);
725*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(worker_thread_->IsCurrent());
726*d9f75844SAndroid Build Coastguard Worker
727*d9f75844SAndroid Build Coastguard Worker receive_11993_checker_.Detach();
728*d9f75844SAndroid Build Coastguard Worker send_transport_sequence_checker_.Detach();
729*d9f75844SAndroid Build Coastguard Worker sent_packet_sequence_checker_.Detach();
730*d9f75844SAndroid Build Coastguard Worker
731*d9f75844SAndroid Build Coastguard Worker // Do not remove this call; it is here to convince the compiler that the
732*d9f75844SAndroid Build Coastguard Worker // WebRTC source timestamp string needs to be in the final binary.
733*d9f75844SAndroid Build Coastguard Worker LoadWebRTCVersionInRegister();
734*d9f75844SAndroid Build Coastguard Worker
735*d9f75844SAndroid Build Coastguard Worker call_stats_->RegisterStatsObserver(&receive_side_cc_);
736*d9f75844SAndroid Build Coastguard Worker
737*d9f75844SAndroid Build Coastguard Worker ReceiveSideCongestionController* receive_side_cc = &receive_side_cc_;
738*d9f75844SAndroid Build Coastguard Worker receive_side_cc_periodic_task_ = RepeatingTaskHandle::Start(
739*d9f75844SAndroid Build Coastguard Worker worker_thread_,
740*d9f75844SAndroid Build Coastguard Worker [receive_side_cc] { return receive_side_cc->MaybeProcess(); },
741*d9f75844SAndroid Build Coastguard Worker TaskQueueBase::DelayPrecision::kLow, clock_);
742*d9f75844SAndroid Build Coastguard Worker }
743*d9f75844SAndroid Build Coastguard Worker
~Call()744*d9f75844SAndroid Build Coastguard Worker Call::~Call() {
745*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
746*d9f75844SAndroid Build Coastguard Worker
747*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(audio_send_ssrcs_.empty());
748*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(video_send_ssrcs_.empty());
749*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(video_send_streams_.empty());
750*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(audio_receive_streams_.empty());
751*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(video_receive_streams_.empty());
752*d9f75844SAndroid Build Coastguard Worker
753*d9f75844SAndroid Build Coastguard Worker receive_side_cc_periodic_task_.Stop();
754*d9f75844SAndroid Build Coastguard Worker call_stats_->DeregisterStatsObserver(&receive_side_cc_);
755*d9f75844SAndroid Build Coastguard Worker send_stats_.SetFirstPacketTime(transport_send_->GetFirstPacketTime());
756*d9f75844SAndroid Build Coastguard Worker
757*d9f75844SAndroid Build Coastguard Worker RTC_HISTOGRAM_COUNTS_100000(
758*d9f75844SAndroid Build Coastguard Worker "WebRTC.Call.LifetimeInSeconds",
759*d9f75844SAndroid Build Coastguard Worker (clock_->CurrentTime() - start_of_call_).seconds());
760*d9f75844SAndroid Build Coastguard Worker }
761*d9f75844SAndroid Build Coastguard Worker
EnsureStarted()762*d9f75844SAndroid Build Coastguard Worker void Call::EnsureStarted() {
763*d9f75844SAndroid Build Coastguard Worker if (is_started_) {
764*d9f75844SAndroid Build Coastguard Worker return;
765*d9f75844SAndroid Build Coastguard Worker }
766*d9f75844SAndroid Build Coastguard Worker is_started_ = true;
767*d9f75844SAndroid Build Coastguard Worker
768*d9f75844SAndroid Build Coastguard Worker call_stats_->EnsureStarted();
769*d9f75844SAndroid Build Coastguard Worker
770*d9f75844SAndroid Build Coastguard Worker // This call seems to kick off a number of things, so probably better left
771*d9f75844SAndroid Build Coastguard Worker // off being kicked off on request rather than in the ctor.
772*d9f75844SAndroid Build Coastguard Worker transport_send_->RegisterTargetTransferRateObserver(this);
773*d9f75844SAndroid Build Coastguard Worker
774*d9f75844SAndroid Build Coastguard Worker transport_send_->EnsureStarted();
775*d9f75844SAndroid Build Coastguard Worker }
776*d9f75844SAndroid Build Coastguard Worker
SetClientBitratePreferences(const BitrateSettings & preferences)777*d9f75844SAndroid Build Coastguard Worker void Call::SetClientBitratePreferences(const BitrateSettings& preferences) {
778*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
779*d9f75844SAndroid Build Coastguard Worker GetTransportControllerSend()->SetClientBitratePreferences(preferences);
780*d9f75844SAndroid Build Coastguard Worker }
781*d9f75844SAndroid Build Coastguard Worker
Receiver()782*d9f75844SAndroid Build Coastguard Worker PacketReceiver* Call::Receiver() {
783*d9f75844SAndroid Build Coastguard Worker return this;
784*d9f75844SAndroid Build Coastguard Worker }
785*d9f75844SAndroid Build Coastguard Worker
CreateAudioSendStream(const webrtc::AudioSendStream::Config & config)786*d9f75844SAndroid Build Coastguard Worker webrtc::AudioSendStream* Call::CreateAudioSendStream(
787*d9f75844SAndroid Build Coastguard Worker const webrtc::AudioSendStream::Config& config) {
788*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::CreateAudioSendStream");
789*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
790*d9f75844SAndroid Build Coastguard Worker
791*d9f75844SAndroid Build Coastguard Worker EnsureStarted();
792*d9f75844SAndroid Build Coastguard Worker
793*d9f75844SAndroid Build Coastguard Worker // Stream config is logged in AudioSendStream::ConfigureStream, as it may
794*d9f75844SAndroid Build Coastguard Worker // change during the stream's lifetime.
795*d9f75844SAndroid Build Coastguard Worker absl::optional<RtpState> suspended_rtp_state;
796*d9f75844SAndroid Build Coastguard Worker {
797*d9f75844SAndroid Build Coastguard Worker const auto& iter = suspended_audio_send_ssrcs_.find(config.rtp.ssrc);
798*d9f75844SAndroid Build Coastguard Worker if (iter != suspended_audio_send_ssrcs_.end()) {
799*d9f75844SAndroid Build Coastguard Worker suspended_rtp_state.emplace(iter->second);
800*d9f75844SAndroid Build Coastguard Worker }
801*d9f75844SAndroid Build Coastguard Worker }
802*d9f75844SAndroid Build Coastguard Worker
803*d9f75844SAndroid Build Coastguard Worker AudioSendStream* send_stream = new AudioSendStream(
804*d9f75844SAndroid Build Coastguard Worker clock_, config, config_.audio_state, task_queue_factory_,
805*d9f75844SAndroid Build Coastguard Worker transport_send_.get(), bitrate_allocator_.get(), event_log_,
806*d9f75844SAndroid Build Coastguard Worker call_stats_->AsRtcpRttStats(), suspended_rtp_state, trials());
807*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(audio_send_ssrcs_.find(config.rtp.ssrc) ==
808*d9f75844SAndroid Build Coastguard Worker audio_send_ssrcs_.end());
809*d9f75844SAndroid Build Coastguard Worker audio_send_ssrcs_[config.rtp.ssrc] = send_stream;
810*d9f75844SAndroid Build Coastguard Worker
811*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): call AssociateSendStream and
812*d9f75844SAndroid Build Coastguard Worker // UpdateAggregateNetworkState asynchronously on the network thread.
813*d9f75844SAndroid Build Coastguard Worker for (AudioReceiveStreamImpl* stream : audio_receive_streams_) {
814*d9f75844SAndroid Build Coastguard Worker if (stream->local_ssrc() == config.rtp.ssrc) {
815*d9f75844SAndroid Build Coastguard Worker stream->AssociateSendStream(send_stream);
816*d9f75844SAndroid Build Coastguard Worker }
817*d9f75844SAndroid Build Coastguard Worker }
818*d9f75844SAndroid Build Coastguard Worker
819*d9f75844SAndroid Build Coastguard Worker UpdateAggregateNetworkState();
820*d9f75844SAndroid Build Coastguard Worker
821*d9f75844SAndroid Build Coastguard Worker return send_stream;
822*d9f75844SAndroid Build Coastguard Worker }
823*d9f75844SAndroid Build Coastguard Worker
DestroyAudioSendStream(webrtc::AudioSendStream * send_stream)824*d9f75844SAndroid Build Coastguard Worker void Call::DestroyAudioSendStream(webrtc::AudioSendStream* send_stream) {
825*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::DestroyAudioSendStream");
826*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
827*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(send_stream != nullptr);
828*d9f75844SAndroid Build Coastguard Worker
829*d9f75844SAndroid Build Coastguard Worker send_stream->Stop();
830*d9f75844SAndroid Build Coastguard Worker
831*d9f75844SAndroid Build Coastguard Worker const uint32_t ssrc = send_stream->GetConfig().rtp.ssrc;
832*d9f75844SAndroid Build Coastguard Worker webrtc::internal::AudioSendStream* audio_send_stream =
833*d9f75844SAndroid Build Coastguard Worker static_cast<webrtc::internal::AudioSendStream*>(send_stream);
834*d9f75844SAndroid Build Coastguard Worker suspended_audio_send_ssrcs_[ssrc] = audio_send_stream->GetRtpState();
835*d9f75844SAndroid Build Coastguard Worker
836*d9f75844SAndroid Build Coastguard Worker size_t num_deleted = audio_send_ssrcs_.erase(ssrc);
837*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_EQ(1, num_deleted);
838*d9f75844SAndroid Build Coastguard Worker
839*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): call AssociateSendStream and
840*d9f75844SAndroid Build Coastguard Worker // UpdateAggregateNetworkState asynchronously on the network thread.
841*d9f75844SAndroid Build Coastguard Worker for (AudioReceiveStreamImpl* stream : audio_receive_streams_) {
842*d9f75844SAndroid Build Coastguard Worker if (stream->local_ssrc() == ssrc) {
843*d9f75844SAndroid Build Coastguard Worker stream->AssociateSendStream(nullptr);
844*d9f75844SAndroid Build Coastguard Worker }
845*d9f75844SAndroid Build Coastguard Worker }
846*d9f75844SAndroid Build Coastguard Worker
847*d9f75844SAndroid Build Coastguard Worker UpdateAggregateNetworkState();
848*d9f75844SAndroid Build Coastguard Worker
849*d9f75844SAndroid Build Coastguard Worker delete send_stream;
850*d9f75844SAndroid Build Coastguard Worker }
851*d9f75844SAndroid Build Coastguard Worker
CreateAudioReceiveStream(const webrtc::AudioReceiveStreamInterface::Config & config)852*d9f75844SAndroid Build Coastguard Worker webrtc::AudioReceiveStreamInterface* Call::CreateAudioReceiveStream(
853*d9f75844SAndroid Build Coastguard Worker const webrtc::AudioReceiveStreamInterface::Config& config) {
854*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::CreateAudioReceiveStream");
855*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
856*d9f75844SAndroid Build Coastguard Worker EnsureStarted();
857*d9f75844SAndroid Build Coastguard Worker event_log_->Log(std::make_unique<RtcEventAudioReceiveStreamConfig>(
858*d9f75844SAndroid Build Coastguard Worker CreateRtcLogStreamConfig(config)));
859*d9f75844SAndroid Build Coastguard Worker
860*d9f75844SAndroid Build Coastguard Worker AudioReceiveStreamImpl* receive_stream = new AudioReceiveStreamImpl(
861*d9f75844SAndroid Build Coastguard Worker clock_, transport_send_->packet_router(), config_.neteq_factory, config,
862*d9f75844SAndroid Build Coastguard Worker config_.audio_state, event_log_);
863*d9f75844SAndroid Build Coastguard Worker audio_receive_streams_.insert(receive_stream);
864*d9f75844SAndroid Build Coastguard Worker
865*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Make the registration on the network thread
866*d9f75844SAndroid Build Coastguard Worker // (asynchronously). The registration and `audio_receiver_controller_` need
867*d9f75844SAndroid Build Coastguard Worker // to live on the network thread.
868*d9f75844SAndroid Build Coastguard Worker receive_stream->RegisterWithTransport(&audio_receiver_controller_);
869*d9f75844SAndroid Build Coastguard Worker
870*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Update the below on the network thread.
871*d9f75844SAndroid Build Coastguard Worker // We could possibly set up the audio_receiver_controller_ association up
872*d9f75844SAndroid Build Coastguard Worker // as part of the async setup.
873*d9f75844SAndroid Build Coastguard Worker RegisterReceiveStream(config.rtp.remote_ssrc, receive_stream);
874*d9f75844SAndroid Build Coastguard Worker
875*d9f75844SAndroid Build Coastguard Worker ConfigureSync(config.sync_group);
876*d9f75844SAndroid Build Coastguard Worker
877*d9f75844SAndroid Build Coastguard Worker auto it = audio_send_ssrcs_.find(config.rtp.local_ssrc);
878*d9f75844SAndroid Build Coastguard Worker if (it != audio_send_ssrcs_.end()) {
879*d9f75844SAndroid Build Coastguard Worker receive_stream->AssociateSendStream(it->second);
880*d9f75844SAndroid Build Coastguard Worker }
881*d9f75844SAndroid Build Coastguard Worker
882*d9f75844SAndroid Build Coastguard Worker UpdateAggregateNetworkState();
883*d9f75844SAndroid Build Coastguard Worker return receive_stream;
884*d9f75844SAndroid Build Coastguard Worker }
885*d9f75844SAndroid Build Coastguard Worker
DestroyAudioReceiveStream(webrtc::AudioReceiveStreamInterface * receive_stream)886*d9f75844SAndroid Build Coastguard Worker void Call::DestroyAudioReceiveStream(
887*d9f75844SAndroid Build Coastguard Worker webrtc::AudioReceiveStreamInterface* receive_stream) {
888*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::DestroyAudioReceiveStream");
889*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
890*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(receive_stream != nullptr);
891*d9f75844SAndroid Build Coastguard Worker webrtc::AudioReceiveStreamImpl* audio_receive_stream =
892*d9f75844SAndroid Build Coastguard Worker static_cast<webrtc::AudioReceiveStreamImpl*>(receive_stream);
893*d9f75844SAndroid Build Coastguard Worker
894*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Access the map, rtp config, call ConfigureSync
895*d9f75844SAndroid Build Coastguard Worker // and UpdateAggregateNetworkState on the network thread. The call to
896*d9f75844SAndroid Build Coastguard Worker // `UnregisterFromTransport` should also happen on the network thread.
897*d9f75844SAndroid Build Coastguard Worker audio_receive_stream->UnregisterFromTransport();
898*d9f75844SAndroid Build Coastguard Worker
899*d9f75844SAndroid Build Coastguard Worker uint32_t ssrc = audio_receive_stream->remote_ssrc();
900*d9f75844SAndroid Build Coastguard Worker receive_side_cc_.RemoveStream(ssrc);
901*d9f75844SAndroid Build Coastguard Worker
902*d9f75844SAndroid Build Coastguard Worker audio_receive_streams_.erase(audio_receive_stream);
903*d9f75844SAndroid Build Coastguard Worker
904*d9f75844SAndroid Build Coastguard Worker // After calling erase(), call ConfigureSync. This will clear associated
905*d9f75844SAndroid Build Coastguard Worker // video streams or associate them with a different audio stream if one exists
906*d9f75844SAndroid Build Coastguard Worker // for this sync_group.
907*d9f75844SAndroid Build Coastguard Worker ConfigureSync(audio_receive_stream->sync_group());
908*d9f75844SAndroid Build Coastguard Worker
909*d9f75844SAndroid Build Coastguard Worker UnregisterReceiveStream(ssrc);
910*d9f75844SAndroid Build Coastguard Worker
911*d9f75844SAndroid Build Coastguard Worker UpdateAggregateNetworkState();
912*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Consider if deleting `audio_receive_stream`
913*d9f75844SAndroid Build Coastguard Worker // on the network thread would be better or if we'd need to tear down the
914*d9f75844SAndroid Build Coastguard Worker // state in two phases.
915*d9f75844SAndroid Build Coastguard Worker delete audio_receive_stream;
916*d9f75844SAndroid Build Coastguard Worker }
917*d9f75844SAndroid Build Coastguard Worker
918*d9f75844SAndroid Build Coastguard Worker // This method can be used for Call tests with external fec controller factory.
CreateVideoSendStream(webrtc::VideoSendStream::Config config,VideoEncoderConfig encoder_config,std::unique_ptr<FecController> fec_controller)919*d9f75844SAndroid Build Coastguard Worker webrtc::VideoSendStream* Call::CreateVideoSendStream(
920*d9f75844SAndroid Build Coastguard Worker webrtc::VideoSendStream::Config config,
921*d9f75844SAndroid Build Coastguard Worker VideoEncoderConfig encoder_config,
922*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<FecController> fec_controller) {
923*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::CreateVideoSendStream");
924*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
925*d9f75844SAndroid Build Coastguard Worker
926*d9f75844SAndroid Build Coastguard Worker EnsureStarted();
927*d9f75844SAndroid Build Coastguard Worker
928*d9f75844SAndroid Build Coastguard Worker video_send_delay_stats_->AddSsrcs(config);
929*d9f75844SAndroid Build Coastguard Worker for (size_t ssrc_index = 0; ssrc_index < config.rtp.ssrcs.size();
930*d9f75844SAndroid Build Coastguard Worker ++ssrc_index) {
931*d9f75844SAndroid Build Coastguard Worker event_log_->Log(std::make_unique<RtcEventVideoSendStreamConfig>(
932*d9f75844SAndroid Build Coastguard Worker CreateRtcLogStreamConfig(config, ssrc_index)));
933*d9f75844SAndroid Build Coastguard Worker }
934*d9f75844SAndroid Build Coastguard Worker
935*d9f75844SAndroid Build Coastguard Worker // TODO(mflodman): Base the start bitrate on a current bandwidth estimate, if
936*d9f75844SAndroid Build Coastguard Worker // the call has already started.
937*d9f75844SAndroid Build Coastguard Worker // Copy ssrcs from `config` since `config` is moved.
938*d9f75844SAndroid Build Coastguard Worker std::vector<uint32_t> ssrcs = config.rtp.ssrcs;
939*d9f75844SAndroid Build Coastguard Worker
940*d9f75844SAndroid Build Coastguard Worker VideoSendStream* send_stream = new VideoSendStream(
941*d9f75844SAndroid Build Coastguard Worker clock_, num_cpu_cores_, task_queue_factory_, network_thread_,
942*d9f75844SAndroid Build Coastguard Worker call_stats_->AsRtcpRttStats(), transport_send_.get(),
943*d9f75844SAndroid Build Coastguard Worker bitrate_allocator_.get(), video_send_delay_stats_.get(), event_log_,
944*d9f75844SAndroid Build Coastguard Worker std::move(config), std::move(encoder_config), suspended_video_send_ssrcs_,
945*d9f75844SAndroid Build Coastguard Worker suspended_video_payload_states_, std::move(fec_controller),
946*d9f75844SAndroid Build Coastguard Worker *config_.trials);
947*d9f75844SAndroid Build Coastguard Worker
948*d9f75844SAndroid Build Coastguard Worker for (uint32_t ssrc : ssrcs) {
949*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(video_send_ssrcs_.find(ssrc) == video_send_ssrcs_.end());
950*d9f75844SAndroid Build Coastguard Worker video_send_ssrcs_[ssrc] = send_stream;
951*d9f75844SAndroid Build Coastguard Worker }
952*d9f75844SAndroid Build Coastguard Worker video_send_streams_.insert(send_stream);
953*d9f75844SAndroid Build Coastguard Worker video_send_streams_empty_.store(false, std::memory_order_relaxed);
954*d9f75844SAndroid Build Coastguard Worker
955*d9f75844SAndroid Build Coastguard Worker // Forward resources that were previously added to the call to the new stream.
956*d9f75844SAndroid Build Coastguard Worker for (const auto& resource_forwarder : adaptation_resource_forwarders_) {
957*d9f75844SAndroid Build Coastguard Worker resource_forwarder->OnCreateVideoSendStream(send_stream);
958*d9f75844SAndroid Build Coastguard Worker }
959*d9f75844SAndroid Build Coastguard Worker
960*d9f75844SAndroid Build Coastguard Worker UpdateAggregateNetworkState();
961*d9f75844SAndroid Build Coastguard Worker
962*d9f75844SAndroid Build Coastguard Worker return send_stream;
963*d9f75844SAndroid Build Coastguard Worker }
964*d9f75844SAndroid Build Coastguard Worker
CreateVideoSendStream(webrtc::VideoSendStream::Config config,VideoEncoderConfig encoder_config)965*d9f75844SAndroid Build Coastguard Worker webrtc::VideoSendStream* Call::CreateVideoSendStream(
966*d9f75844SAndroid Build Coastguard Worker webrtc::VideoSendStream::Config config,
967*d9f75844SAndroid Build Coastguard Worker VideoEncoderConfig encoder_config) {
968*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
969*d9f75844SAndroid Build Coastguard Worker if (config_.fec_controller_factory) {
970*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO) << "External FEC Controller will be used.";
971*d9f75844SAndroid Build Coastguard Worker }
972*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<FecController> fec_controller =
973*d9f75844SAndroid Build Coastguard Worker config_.fec_controller_factory
974*d9f75844SAndroid Build Coastguard Worker ? config_.fec_controller_factory->CreateFecController()
975*d9f75844SAndroid Build Coastguard Worker : std::make_unique<FecControllerDefault>(clock_);
976*d9f75844SAndroid Build Coastguard Worker return CreateVideoSendStream(std::move(config), std::move(encoder_config),
977*d9f75844SAndroid Build Coastguard Worker std::move(fec_controller));
978*d9f75844SAndroid Build Coastguard Worker }
979*d9f75844SAndroid Build Coastguard Worker
DestroyVideoSendStream(webrtc::VideoSendStream * send_stream)980*d9f75844SAndroid Build Coastguard Worker void Call::DestroyVideoSendStream(webrtc::VideoSendStream* send_stream) {
981*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::DestroyVideoSendStream");
982*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(send_stream != nullptr);
983*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
984*d9f75844SAndroid Build Coastguard Worker
985*d9f75844SAndroid Build Coastguard Worker VideoSendStream* send_stream_impl =
986*d9f75844SAndroid Build Coastguard Worker static_cast<VideoSendStream*>(send_stream);
987*d9f75844SAndroid Build Coastguard Worker
988*d9f75844SAndroid Build Coastguard Worker auto it = video_send_ssrcs_.begin();
989*d9f75844SAndroid Build Coastguard Worker while (it != video_send_ssrcs_.end()) {
990*d9f75844SAndroid Build Coastguard Worker if (it->second == static_cast<VideoSendStream*>(send_stream)) {
991*d9f75844SAndroid Build Coastguard Worker send_stream_impl = it->second;
992*d9f75844SAndroid Build Coastguard Worker video_send_ssrcs_.erase(it++);
993*d9f75844SAndroid Build Coastguard Worker } else {
994*d9f75844SAndroid Build Coastguard Worker ++it;
995*d9f75844SAndroid Build Coastguard Worker }
996*d9f75844SAndroid Build Coastguard Worker }
997*d9f75844SAndroid Build Coastguard Worker
998*d9f75844SAndroid Build Coastguard Worker // Stop forwarding resources to the stream being destroyed.
999*d9f75844SAndroid Build Coastguard Worker for (const auto& resource_forwarder : adaptation_resource_forwarders_) {
1000*d9f75844SAndroid Build Coastguard Worker resource_forwarder->OnDestroyVideoSendStream(send_stream_impl);
1001*d9f75844SAndroid Build Coastguard Worker }
1002*d9f75844SAndroid Build Coastguard Worker video_send_streams_.erase(send_stream_impl);
1003*d9f75844SAndroid Build Coastguard Worker if (video_send_streams_.empty())
1004*d9f75844SAndroid Build Coastguard Worker video_send_streams_empty_.store(true, std::memory_order_relaxed);
1005*d9f75844SAndroid Build Coastguard Worker
1006*d9f75844SAndroid Build Coastguard Worker VideoSendStream::RtpStateMap rtp_states;
1007*d9f75844SAndroid Build Coastguard Worker VideoSendStream::RtpPayloadStateMap rtp_payload_states;
1008*d9f75844SAndroid Build Coastguard Worker send_stream_impl->StopPermanentlyAndGetRtpStates(&rtp_states,
1009*d9f75844SAndroid Build Coastguard Worker &rtp_payload_states);
1010*d9f75844SAndroid Build Coastguard Worker for (const auto& kv : rtp_states) {
1011*d9f75844SAndroid Build Coastguard Worker suspended_video_send_ssrcs_[kv.first] = kv.second;
1012*d9f75844SAndroid Build Coastguard Worker }
1013*d9f75844SAndroid Build Coastguard Worker for (const auto& kv : rtp_payload_states) {
1014*d9f75844SAndroid Build Coastguard Worker suspended_video_payload_states_[kv.first] = kv.second;
1015*d9f75844SAndroid Build Coastguard Worker }
1016*d9f75844SAndroid Build Coastguard Worker
1017*d9f75844SAndroid Build Coastguard Worker UpdateAggregateNetworkState();
1018*d9f75844SAndroid Build Coastguard Worker // TODO(tommi): consider deleting on the same thread as runs
1019*d9f75844SAndroid Build Coastguard Worker // StopPermanentlyAndGetRtpStates.
1020*d9f75844SAndroid Build Coastguard Worker delete send_stream_impl;
1021*d9f75844SAndroid Build Coastguard Worker }
1022*d9f75844SAndroid Build Coastguard Worker
CreateVideoReceiveStream(webrtc::VideoReceiveStreamInterface::Config configuration)1023*d9f75844SAndroid Build Coastguard Worker webrtc::VideoReceiveStreamInterface* Call::CreateVideoReceiveStream(
1024*d9f75844SAndroid Build Coastguard Worker webrtc::VideoReceiveStreamInterface::Config configuration) {
1025*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::CreateVideoReceiveStream");
1026*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1027*d9f75844SAndroid Build Coastguard Worker
1028*d9f75844SAndroid Build Coastguard Worker receive_side_cc_.SetSendPeriodicFeedback(
1029*d9f75844SAndroid Build Coastguard Worker SendPeriodicFeedback(configuration.rtp.extensions));
1030*d9f75844SAndroid Build Coastguard Worker
1031*d9f75844SAndroid Build Coastguard Worker EnsureStarted();
1032*d9f75844SAndroid Build Coastguard Worker
1033*d9f75844SAndroid Build Coastguard Worker event_log_->Log(std::make_unique<RtcEventVideoReceiveStreamConfig>(
1034*d9f75844SAndroid Build Coastguard Worker CreateRtcLogStreamConfig(configuration)));
1035*d9f75844SAndroid Build Coastguard Worker
1036*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Move the registration between `receive_stream`
1037*d9f75844SAndroid Build Coastguard Worker // and `video_receiver_controller_` out of VideoReceiveStream2 construction
1038*d9f75844SAndroid Build Coastguard Worker // and set it up asynchronously on the network thread (the registration and
1039*d9f75844SAndroid Build Coastguard Worker // `video_receiver_controller_` need to live on the network thread).
1040*d9f75844SAndroid Build Coastguard Worker // TODO(crbug.com/1381982): Re-enable decode synchronizer once the Chromium
1041*d9f75844SAndroid Build Coastguard Worker // API has adapted to the new Metronome interface.
1042*d9f75844SAndroid Build Coastguard Worker VideoReceiveStream2* receive_stream = new VideoReceiveStream2(
1043*d9f75844SAndroid Build Coastguard Worker task_queue_factory_, this, num_cpu_cores_,
1044*d9f75844SAndroid Build Coastguard Worker transport_send_->packet_router(), std::move(configuration),
1045*d9f75844SAndroid Build Coastguard Worker call_stats_.get(), clock_, std::make_unique<VCMTiming>(clock_, trials()),
1046*d9f75844SAndroid Build Coastguard Worker &nack_periodic_processor_, decode_sync_.get(), event_log_);
1047*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Set this up asynchronously on the network
1048*d9f75844SAndroid Build Coastguard Worker // thread.
1049*d9f75844SAndroid Build Coastguard Worker receive_stream->RegisterWithTransport(&video_receiver_controller_);
1050*d9f75844SAndroid Build Coastguard Worker
1051*d9f75844SAndroid Build Coastguard Worker if (receive_stream->rtx_ssrc()) {
1052*d9f75844SAndroid Build Coastguard Worker // We record identical config for the rtx stream as for the main
1053*d9f75844SAndroid Build Coastguard Worker // stream. Since the transport_send_cc negotiation is per payload
1054*d9f75844SAndroid Build Coastguard Worker // type, we may get an incorrect value for the rtx stream, but
1055*d9f75844SAndroid Build Coastguard Worker // that is unlikely to matter in practice.
1056*d9f75844SAndroid Build Coastguard Worker RegisterReceiveStream(receive_stream->rtx_ssrc(), receive_stream);
1057*d9f75844SAndroid Build Coastguard Worker }
1058*d9f75844SAndroid Build Coastguard Worker RegisterReceiveStream(receive_stream->remote_ssrc(), receive_stream);
1059*d9f75844SAndroid Build Coastguard Worker video_receive_streams_.insert(receive_stream);
1060*d9f75844SAndroid Build Coastguard Worker
1061*d9f75844SAndroid Build Coastguard Worker ConfigureSync(receive_stream->sync_group());
1062*d9f75844SAndroid Build Coastguard Worker
1063*d9f75844SAndroid Build Coastguard Worker receive_stream->SignalNetworkState(video_network_state_);
1064*d9f75844SAndroid Build Coastguard Worker UpdateAggregateNetworkState();
1065*d9f75844SAndroid Build Coastguard Worker return receive_stream;
1066*d9f75844SAndroid Build Coastguard Worker }
1067*d9f75844SAndroid Build Coastguard Worker
DestroyVideoReceiveStream(webrtc::VideoReceiveStreamInterface * receive_stream)1068*d9f75844SAndroid Build Coastguard Worker void Call::DestroyVideoReceiveStream(
1069*d9f75844SAndroid Build Coastguard Worker webrtc::VideoReceiveStreamInterface* receive_stream) {
1070*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::DestroyVideoReceiveStream");
1071*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1072*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(receive_stream != nullptr);
1073*d9f75844SAndroid Build Coastguard Worker VideoReceiveStream2* receive_stream_impl =
1074*d9f75844SAndroid Build Coastguard Worker static_cast<VideoReceiveStream2*>(receive_stream);
1075*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Unregister on the network thread.
1076*d9f75844SAndroid Build Coastguard Worker receive_stream_impl->UnregisterFromTransport();
1077*d9f75844SAndroid Build Coastguard Worker
1078*d9f75844SAndroid Build Coastguard Worker // Remove all ssrcs pointing to a receive stream. As RTX retransmits on a
1079*d9f75844SAndroid Build Coastguard Worker // separate SSRC there can be either one or two.
1080*d9f75844SAndroid Build Coastguard Worker UnregisterReceiveStream(receive_stream_impl->remote_ssrc());
1081*d9f75844SAndroid Build Coastguard Worker
1082*d9f75844SAndroid Build Coastguard Worker if (receive_stream_impl->rtx_ssrc()) {
1083*d9f75844SAndroid Build Coastguard Worker UnregisterReceiveStream(receive_stream_impl->rtx_ssrc());
1084*d9f75844SAndroid Build Coastguard Worker }
1085*d9f75844SAndroid Build Coastguard Worker video_receive_streams_.erase(receive_stream_impl);
1086*d9f75844SAndroid Build Coastguard Worker ConfigureSync(receive_stream_impl->sync_group());
1087*d9f75844SAndroid Build Coastguard Worker
1088*d9f75844SAndroid Build Coastguard Worker receive_side_cc_.RemoveStream(receive_stream_impl->remote_ssrc());
1089*d9f75844SAndroid Build Coastguard Worker
1090*d9f75844SAndroid Build Coastguard Worker UpdateAggregateNetworkState();
1091*d9f75844SAndroid Build Coastguard Worker delete receive_stream_impl;
1092*d9f75844SAndroid Build Coastguard Worker }
1093*d9f75844SAndroid Build Coastguard Worker
CreateFlexfecReceiveStream(const FlexfecReceiveStream::Config config)1094*d9f75844SAndroid Build Coastguard Worker FlexfecReceiveStream* Call::CreateFlexfecReceiveStream(
1095*d9f75844SAndroid Build Coastguard Worker const FlexfecReceiveStream::Config config) {
1096*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::CreateFlexfecReceiveStream");
1097*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1098*d9f75844SAndroid Build Coastguard Worker
1099*d9f75844SAndroid Build Coastguard Worker // Unlike the video and audio receive streams, FlexfecReceiveStream implements
1100*d9f75844SAndroid Build Coastguard Worker // RtpPacketSinkInterface itself, and hence its constructor passes its `this`
1101*d9f75844SAndroid Build Coastguard Worker // pointer to video_receiver_controller_->CreateStream(). Calling the
1102*d9f75844SAndroid Build Coastguard Worker // constructor while on the worker thread ensures that we don't call
1103*d9f75844SAndroid Build Coastguard Worker // OnRtpPacket until the constructor is finished and the object is
1104*d9f75844SAndroid Build Coastguard Worker // in a valid state, since OnRtpPacket runs on the same thread.
1105*d9f75844SAndroid Build Coastguard Worker FlexfecReceiveStreamImpl* receive_stream = new FlexfecReceiveStreamImpl(
1106*d9f75844SAndroid Build Coastguard Worker clock_, std::move(config), this, call_stats_->AsRtcpRttStats());
1107*d9f75844SAndroid Build Coastguard Worker
1108*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Set this up asynchronously on the network
1109*d9f75844SAndroid Build Coastguard Worker // thread.
1110*d9f75844SAndroid Build Coastguard Worker receive_stream->RegisterWithTransport(&video_receiver_controller_);
1111*d9f75844SAndroid Build Coastguard Worker RegisterReceiveStream(receive_stream->remote_ssrc(), receive_stream);
1112*d9f75844SAndroid Build Coastguard Worker
1113*d9f75844SAndroid Build Coastguard Worker // TODO(brandtr): Store config in RtcEventLog here.
1114*d9f75844SAndroid Build Coastguard Worker
1115*d9f75844SAndroid Build Coastguard Worker return receive_stream;
1116*d9f75844SAndroid Build Coastguard Worker }
1117*d9f75844SAndroid Build Coastguard Worker
DestroyFlexfecReceiveStream(FlexfecReceiveStream * receive_stream)1118*d9f75844SAndroid Build Coastguard Worker void Call::DestroyFlexfecReceiveStream(FlexfecReceiveStream* receive_stream) {
1119*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::DestroyFlexfecReceiveStream");
1120*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1121*d9f75844SAndroid Build Coastguard Worker
1122*d9f75844SAndroid Build Coastguard Worker FlexfecReceiveStreamImpl* receive_stream_impl =
1123*d9f75844SAndroid Build Coastguard Worker static_cast<FlexfecReceiveStreamImpl*>(receive_stream);
1124*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Unregister on the network thread.
1125*d9f75844SAndroid Build Coastguard Worker receive_stream_impl->UnregisterFromTransport();
1126*d9f75844SAndroid Build Coastguard Worker
1127*d9f75844SAndroid Build Coastguard Worker auto ssrc = receive_stream_impl->remote_ssrc();
1128*d9f75844SAndroid Build Coastguard Worker UnregisterReceiveStream(ssrc);
1129*d9f75844SAndroid Build Coastguard Worker
1130*d9f75844SAndroid Build Coastguard Worker // Remove all SSRCs pointing to the FlexfecReceiveStreamImpl to be
1131*d9f75844SAndroid Build Coastguard Worker // destroyed.
1132*d9f75844SAndroid Build Coastguard Worker receive_side_cc_.RemoveStream(ssrc);
1133*d9f75844SAndroid Build Coastguard Worker
1134*d9f75844SAndroid Build Coastguard Worker delete receive_stream_impl;
1135*d9f75844SAndroid Build Coastguard Worker }
1136*d9f75844SAndroid Build Coastguard Worker
AddAdaptationResource(rtc::scoped_refptr<Resource> resource)1137*d9f75844SAndroid Build Coastguard Worker void Call::AddAdaptationResource(rtc::scoped_refptr<Resource> resource) {
1138*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1139*d9f75844SAndroid Build Coastguard Worker adaptation_resource_forwarders_.push_back(
1140*d9f75844SAndroid Build Coastguard Worker std::make_unique<ResourceVideoSendStreamForwarder>(resource));
1141*d9f75844SAndroid Build Coastguard Worker const auto& resource_forwarder = adaptation_resource_forwarders_.back();
1142*d9f75844SAndroid Build Coastguard Worker for (VideoSendStream* send_stream : video_send_streams_) {
1143*d9f75844SAndroid Build Coastguard Worker resource_forwarder->OnCreateVideoSendStream(send_stream);
1144*d9f75844SAndroid Build Coastguard Worker }
1145*d9f75844SAndroid Build Coastguard Worker }
1146*d9f75844SAndroid Build Coastguard Worker
GetTransportControllerSend()1147*d9f75844SAndroid Build Coastguard Worker RtpTransportControllerSendInterface* Call::GetTransportControllerSend() {
1148*d9f75844SAndroid Build Coastguard Worker return transport_send_.get();
1149*d9f75844SAndroid Build Coastguard Worker }
1150*d9f75844SAndroid Build Coastguard Worker
GetStats() const1151*d9f75844SAndroid Build Coastguard Worker Call::Stats Call::GetStats() const {
1152*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1153*d9f75844SAndroid Build Coastguard Worker
1154*d9f75844SAndroid Build Coastguard Worker Stats stats;
1155*d9f75844SAndroid Build Coastguard Worker // TODO(srte): It is unclear if we only want to report queues if network is
1156*d9f75844SAndroid Build Coastguard Worker // available.
1157*d9f75844SAndroid Build Coastguard Worker stats.pacer_delay_ms =
1158*d9f75844SAndroid Build Coastguard Worker aggregate_network_up_ ? transport_send_->GetPacerQueuingDelayMs() : 0;
1159*d9f75844SAndroid Build Coastguard Worker
1160*d9f75844SAndroid Build Coastguard Worker stats.rtt_ms = call_stats_->LastProcessedRtt();
1161*d9f75844SAndroid Build Coastguard Worker
1162*d9f75844SAndroid Build Coastguard Worker // Fetch available send/receive bitrates.
1163*d9f75844SAndroid Build Coastguard Worker stats.recv_bandwidth_bps = receive_side_cc_.LatestReceiveSideEstimate().bps();
1164*d9f75844SAndroid Build Coastguard Worker stats.send_bandwidth_bps =
1165*d9f75844SAndroid Build Coastguard Worker last_bandwidth_bps_.load(std::memory_order_relaxed);
1166*d9f75844SAndroid Build Coastguard Worker stats.max_padding_bitrate_bps =
1167*d9f75844SAndroid Build Coastguard Worker configured_max_padding_bitrate_bps_.load(std::memory_order_relaxed);
1168*d9f75844SAndroid Build Coastguard Worker
1169*d9f75844SAndroid Build Coastguard Worker return stats;
1170*d9f75844SAndroid Build Coastguard Worker }
1171*d9f75844SAndroid Build Coastguard Worker
trials() const1172*d9f75844SAndroid Build Coastguard Worker const FieldTrialsView& Call::trials() const {
1173*d9f75844SAndroid Build Coastguard Worker return trials_;
1174*d9f75844SAndroid Build Coastguard Worker }
1175*d9f75844SAndroid Build Coastguard Worker
network_thread() const1176*d9f75844SAndroid Build Coastguard Worker TaskQueueBase* Call::network_thread() const {
1177*d9f75844SAndroid Build Coastguard Worker return network_thread_;
1178*d9f75844SAndroid Build Coastguard Worker }
1179*d9f75844SAndroid Build Coastguard Worker
worker_thread() const1180*d9f75844SAndroid Build Coastguard Worker TaskQueueBase* Call::worker_thread() const {
1181*d9f75844SAndroid Build Coastguard Worker return worker_thread_;
1182*d9f75844SAndroid Build Coastguard Worker }
1183*d9f75844SAndroid Build Coastguard Worker
SignalChannelNetworkState(MediaType media,NetworkState state)1184*d9f75844SAndroid Build Coastguard Worker void Call::SignalChannelNetworkState(MediaType media, NetworkState state) {
1185*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
1186*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(media == MediaType::AUDIO || media == MediaType::VIDEO);
1187*d9f75844SAndroid Build Coastguard Worker
1188*d9f75844SAndroid Build Coastguard Worker auto closure = [this, media, state]() {
1189*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Move this over to the network thread.
1190*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1191*d9f75844SAndroid Build Coastguard Worker if (media == MediaType::AUDIO) {
1192*d9f75844SAndroid Build Coastguard Worker audio_network_state_ = state;
1193*d9f75844SAndroid Build Coastguard Worker } else {
1194*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_EQ(media, MediaType::VIDEO);
1195*d9f75844SAndroid Build Coastguard Worker video_network_state_ = state;
1196*d9f75844SAndroid Build Coastguard Worker }
1197*d9f75844SAndroid Build Coastguard Worker
1198*d9f75844SAndroid Build Coastguard Worker // TODO(tommi): Is it necessary to always do this, including if there
1199*d9f75844SAndroid Build Coastguard Worker // was no change in state?
1200*d9f75844SAndroid Build Coastguard Worker UpdateAggregateNetworkState();
1201*d9f75844SAndroid Build Coastguard Worker
1202*d9f75844SAndroid Build Coastguard Worker // TODO(tommi): Is it right to do this if media == AUDIO?
1203*d9f75844SAndroid Build Coastguard Worker for (VideoReceiveStream2* video_receive_stream : video_receive_streams_) {
1204*d9f75844SAndroid Build Coastguard Worker video_receive_stream->SignalNetworkState(video_network_state_);
1205*d9f75844SAndroid Build Coastguard Worker }
1206*d9f75844SAndroid Build Coastguard Worker };
1207*d9f75844SAndroid Build Coastguard Worker
1208*d9f75844SAndroid Build Coastguard Worker if (network_thread_ == worker_thread_) {
1209*d9f75844SAndroid Build Coastguard Worker closure();
1210*d9f75844SAndroid Build Coastguard Worker } else {
1211*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Remove workaround when we no longer need to
1212*d9f75844SAndroid Build Coastguard Worker // post to the worker thread.
1213*d9f75844SAndroid Build Coastguard Worker worker_thread_->PostTask(SafeTask(task_safety_.flag(), std::move(closure)));
1214*d9f75844SAndroid Build Coastguard Worker }
1215*d9f75844SAndroid Build Coastguard Worker }
1216*d9f75844SAndroid Build Coastguard Worker
OnAudioTransportOverheadChanged(int transport_overhead_per_packet)1217*d9f75844SAndroid Build Coastguard Worker void Call::OnAudioTransportOverheadChanged(int transport_overhead_per_packet) {
1218*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
1219*d9f75844SAndroid Build Coastguard Worker worker_thread_->PostTask(
1220*d9f75844SAndroid Build Coastguard Worker SafeTask(task_safety_.flag(), [this, transport_overhead_per_packet]() {
1221*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Move this over to the network thread.
1222*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1223*d9f75844SAndroid Build Coastguard Worker for (auto& kv : audio_send_ssrcs_) {
1224*d9f75844SAndroid Build Coastguard Worker kv.second->SetTransportOverhead(transport_overhead_per_packet);
1225*d9f75844SAndroid Build Coastguard Worker }
1226*d9f75844SAndroid Build Coastguard Worker }));
1227*d9f75844SAndroid Build Coastguard Worker }
1228*d9f75844SAndroid Build Coastguard Worker
UpdateAggregateNetworkState()1229*d9f75844SAndroid Build Coastguard Worker void Call::UpdateAggregateNetworkState() {
1230*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Move this over to the network thread.
1231*d9f75844SAndroid Build Coastguard Worker // RTC_DCHECK_RUN_ON(network_thread_);
1232*d9f75844SAndroid Build Coastguard Worker
1233*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1234*d9f75844SAndroid Build Coastguard Worker
1235*d9f75844SAndroid Build Coastguard Worker bool have_audio =
1236*d9f75844SAndroid Build Coastguard Worker !audio_send_ssrcs_.empty() || !audio_receive_streams_.empty();
1237*d9f75844SAndroid Build Coastguard Worker bool have_video =
1238*d9f75844SAndroid Build Coastguard Worker !video_send_ssrcs_.empty() || !video_receive_streams_.empty();
1239*d9f75844SAndroid Build Coastguard Worker
1240*d9f75844SAndroid Build Coastguard Worker bool aggregate_network_up =
1241*d9f75844SAndroid Build Coastguard Worker ((have_video && video_network_state_ == kNetworkUp) ||
1242*d9f75844SAndroid Build Coastguard Worker (have_audio && audio_network_state_ == kNetworkUp));
1243*d9f75844SAndroid Build Coastguard Worker
1244*d9f75844SAndroid Build Coastguard Worker if (aggregate_network_up != aggregate_network_up_) {
1245*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_INFO)
1246*d9f75844SAndroid Build Coastguard Worker << "UpdateAggregateNetworkState: aggregate_state change to "
1247*d9f75844SAndroid Build Coastguard Worker << (aggregate_network_up ? "up" : "down");
1248*d9f75844SAndroid Build Coastguard Worker } else {
1249*d9f75844SAndroid Build Coastguard Worker RTC_LOG(LS_VERBOSE)
1250*d9f75844SAndroid Build Coastguard Worker << "UpdateAggregateNetworkState: aggregate_state remains at "
1251*d9f75844SAndroid Build Coastguard Worker << (aggregate_network_up ? "up" : "down");
1252*d9f75844SAndroid Build Coastguard Worker }
1253*d9f75844SAndroid Build Coastguard Worker aggregate_network_up_ = aggregate_network_up;
1254*d9f75844SAndroid Build Coastguard Worker
1255*d9f75844SAndroid Build Coastguard Worker transport_send_->OnNetworkAvailability(aggregate_network_up);
1256*d9f75844SAndroid Build Coastguard Worker }
1257*d9f75844SAndroid Build Coastguard Worker
OnLocalSsrcUpdated(webrtc::AudioReceiveStreamInterface & stream,uint32_t local_ssrc)1258*d9f75844SAndroid Build Coastguard Worker void Call::OnLocalSsrcUpdated(webrtc::AudioReceiveStreamInterface& stream,
1259*d9f75844SAndroid Build Coastguard Worker uint32_t local_ssrc) {
1260*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1261*d9f75844SAndroid Build Coastguard Worker webrtc::AudioReceiveStreamImpl& receive_stream =
1262*d9f75844SAndroid Build Coastguard Worker static_cast<webrtc::AudioReceiveStreamImpl&>(stream);
1263*d9f75844SAndroid Build Coastguard Worker
1264*d9f75844SAndroid Build Coastguard Worker receive_stream.SetLocalSsrc(local_ssrc);
1265*d9f75844SAndroid Build Coastguard Worker auto it = audio_send_ssrcs_.find(local_ssrc);
1266*d9f75844SAndroid Build Coastguard Worker receive_stream.AssociateSendStream(it != audio_send_ssrcs_.end() ? it->second
1267*d9f75844SAndroid Build Coastguard Worker : nullptr);
1268*d9f75844SAndroid Build Coastguard Worker }
1269*d9f75844SAndroid Build Coastguard Worker
OnLocalSsrcUpdated(VideoReceiveStreamInterface & stream,uint32_t local_ssrc)1270*d9f75844SAndroid Build Coastguard Worker void Call::OnLocalSsrcUpdated(VideoReceiveStreamInterface& stream,
1271*d9f75844SAndroid Build Coastguard Worker uint32_t local_ssrc) {
1272*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1273*d9f75844SAndroid Build Coastguard Worker static_cast<VideoReceiveStream2&>(stream).SetLocalSsrc(local_ssrc);
1274*d9f75844SAndroid Build Coastguard Worker }
1275*d9f75844SAndroid Build Coastguard Worker
OnLocalSsrcUpdated(FlexfecReceiveStream & stream,uint32_t local_ssrc)1276*d9f75844SAndroid Build Coastguard Worker void Call::OnLocalSsrcUpdated(FlexfecReceiveStream& stream,
1277*d9f75844SAndroid Build Coastguard Worker uint32_t local_ssrc) {
1278*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1279*d9f75844SAndroid Build Coastguard Worker static_cast<FlexfecReceiveStreamImpl&>(stream).SetLocalSsrc(local_ssrc);
1280*d9f75844SAndroid Build Coastguard Worker }
1281*d9f75844SAndroid Build Coastguard Worker
OnUpdateSyncGroup(webrtc::AudioReceiveStreamInterface & stream,absl::string_view sync_group)1282*d9f75844SAndroid Build Coastguard Worker void Call::OnUpdateSyncGroup(webrtc::AudioReceiveStreamInterface& stream,
1283*d9f75844SAndroid Build Coastguard Worker absl::string_view sync_group) {
1284*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1285*d9f75844SAndroid Build Coastguard Worker webrtc::AudioReceiveStreamImpl& receive_stream =
1286*d9f75844SAndroid Build Coastguard Worker static_cast<webrtc::AudioReceiveStreamImpl&>(stream);
1287*d9f75844SAndroid Build Coastguard Worker receive_stream.SetSyncGroup(sync_group);
1288*d9f75844SAndroid Build Coastguard Worker ConfigureSync(sync_group);
1289*d9f75844SAndroid Build Coastguard Worker }
1290*d9f75844SAndroid Build Coastguard Worker
OnSentPacket(const rtc::SentPacket & sent_packet)1291*d9f75844SAndroid Build Coastguard Worker void Call::OnSentPacket(const rtc::SentPacket& sent_packet) {
1292*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&sent_packet_sequence_checker_);
1293*d9f75844SAndroid Build Coastguard Worker // When bundling is in effect, multiple senders may be sharing the same
1294*d9f75844SAndroid Build Coastguard Worker // transport. It means every |sent_packet| will be multiply notified from
1295*d9f75844SAndroid Build Coastguard Worker // different channels, WebRtcVoiceMediaChannel or WebRtcVideoChannel. Record
1296*d9f75844SAndroid Build Coastguard Worker // |last_sent_packet_| to deduplicate redundant notifications to downstream.
1297*d9f75844SAndroid Build Coastguard Worker // (https://crbug.com/webrtc/13437): Pass all packets without a |packet_id| to
1298*d9f75844SAndroid Build Coastguard Worker // downstream.
1299*d9f75844SAndroid Build Coastguard Worker if (last_sent_packet_.has_value() && last_sent_packet_->packet_id != -1 &&
1300*d9f75844SAndroid Build Coastguard Worker last_sent_packet_->packet_id == sent_packet.packet_id &&
1301*d9f75844SAndroid Build Coastguard Worker last_sent_packet_->send_time_ms == sent_packet.send_time_ms) {
1302*d9f75844SAndroid Build Coastguard Worker return;
1303*d9f75844SAndroid Build Coastguard Worker }
1304*d9f75844SAndroid Build Coastguard Worker last_sent_packet_ = sent_packet;
1305*d9f75844SAndroid Build Coastguard Worker
1306*d9f75844SAndroid Build Coastguard Worker // In production and with most tests, this method will be called on the
1307*d9f75844SAndroid Build Coastguard Worker // network thread. However some test classes such as DirectTransport don't
1308*d9f75844SAndroid Build Coastguard Worker // incorporate a network thread. This means that tests for RtpSenderEgress
1309*d9f75844SAndroid Build Coastguard Worker // and ModuleRtpRtcpImpl2 that use DirectTransport, will call this method
1310*d9f75844SAndroid Build Coastguard Worker // on a ProcessThread. This is alright as is since we forward the call to
1311*d9f75844SAndroid Build Coastguard Worker // implementations that either just do a PostTask or use locking.
1312*d9f75844SAndroid Build Coastguard Worker video_send_delay_stats_->OnSentPacket(sent_packet.packet_id,
1313*d9f75844SAndroid Build Coastguard Worker clock_->TimeInMilliseconds());
1314*d9f75844SAndroid Build Coastguard Worker transport_send_->OnSentPacket(sent_packet);
1315*d9f75844SAndroid Build Coastguard Worker }
1316*d9f75844SAndroid Build Coastguard Worker
OnStartRateUpdate(DataRate start_rate)1317*d9f75844SAndroid Build Coastguard Worker void Call::OnStartRateUpdate(DataRate start_rate) {
1318*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&send_transport_sequence_checker_);
1319*d9f75844SAndroid Build Coastguard Worker bitrate_allocator_->UpdateStartRate(start_rate.bps<uint32_t>());
1320*d9f75844SAndroid Build Coastguard Worker }
1321*d9f75844SAndroid Build Coastguard Worker
OnTargetTransferRate(TargetTransferRate msg)1322*d9f75844SAndroid Build Coastguard Worker void Call::OnTargetTransferRate(TargetTransferRate msg) {
1323*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&send_transport_sequence_checker_);
1324*d9f75844SAndroid Build Coastguard Worker
1325*d9f75844SAndroid Build Coastguard Worker uint32_t target_bitrate_bps = msg.target_rate.bps();
1326*d9f75844SAndroid Build Coastguard Worker // For controlling the rate of feedback messages.
1327*d9f75844SAndroid Build Coastguard Worker receive_side_cc_.OnBitrateChanged(target_bitrate_bps);
1328*d9f75844SAndroid Build Coastguard Worker bitrate_allocator_->OnNetworkEstimateChanged(msg);
1329*d9f75844SAndroid Build Coastguard Worker
1330*d9f75844SAndroid Build Coastguard Worker last_bandwidth_bps_.store(target_bitrate_bps, std::memory_order_relaxed);
1331*d9f75844SAndroid Build Coastguard Worker
1332*d9f75844SAndroid Build Coastguard Worker // Ignore updates if bitrate is zero (the aggregate network state is
1333*d9f75844SAndroid Build Coastguard Worker // down) or if we're not sending video.
1334*d9f75844SAndroid Build Coastguard Worker // Using `video_send_streams_empty_` is racy but as the caller can't
1335*d9f75844SAndroid Build Coastguard Worker // reasonably expect synchronize with changes in `video_send_streams_` (being
1336*d9f75844SAndroid Build Coastguard Worker // on `send_transport_sequence_checker`), we can avoid a PostTask this way.
1337*d9f75844SAndroid Build Coastguard Worker if (target_bitrate_bps == 0 ||
1338*d9f75844SAndroid Build Coastguard Worker video_send_streams_empty_.load(std::memory_order_relaxed)) {
1339*d9f75844SAndroid Build Coastguard Worker send_stats_.PauseSendAndPacerBitrateCounters();
1340*d9f75844SAndroid Build Coastguard Worker } else {
1341*d9f75844SAndroid Build Coastguard Worker send_stats_.AddTargetBitrateSample(target_bitrate_bps);
1342*d9f75844SAndroid Build Coastguard Worker }
1343*d9f75844SAndroid Build Coastguard Worker }
1344*d9f75844SAndroid Build Coastguard Worker
OnAllocationLimitsChanged(BitrateAllocationLimits limits)1345*d9f75844SAndroid Build Coastguard Worker void Call::OnAllocationLimitsChanged(BitrateAllocationLimits limits) {
1346*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&send_transport_sequence_checker_);
1347*d9f75844SAndroid Build Coastguard Worker
1348*d9f75844SAndroid Build Coastguard Worker transport_send_ptr_->SetAllocatedSendBitrateLimits(limits);
1349*d9f75844SAndroid Build Coastguard Worker send_stats_.SetMinAllocatableRate(limits);
1350*d9f75844SAndroid Build Coastguard Worker configured_max_padding_bitrate_bps_.store(limits.max_padding_rate.bps(),
1351*d9f75844SAndroid Build Coastguard Worker std::memory_order_relaxed);
1352*d9f75844SAndroid Build Coastguard Worker }
1353*d9f75844SAndroid Build Coastguard Worker
FindAudioStreamForSyncGroup(absl::string_view sync_group)1354*d9f75844SAndroid Build Coastguard Worker AudioReceiveStreamImpl* Call::FindAudioStreamForSyncGroup(
1355*d9f75844SAndroid Build Coastguard Worker absl::string_view sync_group) {
1356*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1357*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&receive_11993_checker_);
1358*d9f75844SAndroid Build Coastguard Worker if (!sync_group.empty()) {
1359*d9f75844SAndroid Build Coastguard Worker for (AudioReceiveStreamImpl* stream : audio_receive_streams_) {
1360*d9f75844SAndroid Build Coastguard Worker if (stream->sync_group() == sync_group)
1361*d9f75844SAndroid Build Coastguard Worker return stream;
1362*d9f75844SAndroid Build Coastguard Worker }
1363*d9f75844SAndroid Build Coastguard Worker }
1364*d9f75844SAndroid Build Coastguard Worker
1365*d9f75844SAndroid Build Coastguard Worker return nullptr;
1366*d9f75844SAndroid Build Coastguard Worker }
1367*d9f75844SAndroid Build Coastguard Worker
ConfigureSync(absl::string_view sync_group)1368*d9f75844SAndroid Build Coastguard Worker void Call::ConfigureSync(absl::string_view sync_group) {
1369*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Expect to be called on the network thread.
1370*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1371*d9f75844SAndroid Build Coastguard Worker // `audio_stream` may be nullptr when clearing the audio stream for a group.
1372*d9f75844SAndroid Build Coastguard Worker AudioReceiveStreamImpl* audio_stream =
1373*d9f75844SAndroid Build Coastguard Worker FindAudioStreamForSyncGroup(sync_group);
1374*d9f75844SAndroid Build Coastguard Worker
1375*d9f75844SAndroid Build Coastguard Worker size_t num_synced_streams = 0;
1376*d9f75844SAndroid Build Coastguard Worker for (VideoReceiveStream2* video_stream : video_receive_streams_) {
1377*d9f75844SAndroid Build Coastguard Worker if (video_stream->sync_group() != sync_group)
1378*d9f75844SAndroid Build Coastguard Worker continue;
1379*d9f75844SAndroid Build Coastguard Worker ++num_synced_streams;
1380*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/4762): Support synchronizing more than one A/V pair.
1381*d9f75844SAndroid Build Coastguard Worker // Attempting to sync more than one audio/video pair within the same sync
1382*d9f75844SAndroid Build Coastguard Worker // group is not supported in the current implementation.
1383*d9f75844SAndroid Build Coastguard Worker // Only sync the first A/V pair within this sync group.
1384*d9f75844SAndroid Build Coastguard Worker if (num_synced_streams == 1) {
1385*d9f75844SAndroid Build Coastguard Worker // sync_audio_stream may be null and that's ok.
1386*d9f75844SAndroid Build Coastguard Worker video_stream->SetSync(audio_stream);
1387*d9f75844SAndroid Build Coastguard Worker } else {
1388*d9f75844SAndroid Build Coastguard Worker video_stream->SetSync(nullptr);
1389*d9f75844SAndroid Build Coastguard Worker }
1390*d9f75844SAndroid Build Coastguard Worker }
1391*d9f75844SAndroid Build Coastguard Worker }
1392*d9f75844SAndroid Build Coastguard Worker
DeliverRtcp(MediaType media_type,rtc::CopyOnWriteBuffer packet)1393*d9f75844SAndroid Build Coastguard Worker void Call::DeliverRtcp(MediaType media_type, rtc::CopyOnWriteBuffer packet) {
1394*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
1395*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::DeliverRtcp");
1396*d9f75844SAndroid Build Coastguard Worker
1397*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): This DCHECK is here just to maintain the
1398*d9f75844SAndroid Build Coastguard Worker // invariant that currently the only call path to this function is via
1399*d9f75844SAndroid Build Coastguard Worker // `PeerConnection::InitializeRtcpCallback()`. DeliverRtp on the other hand
1400*d9f75844SAndroid Build Coastguard Worker // gets called via the channel classes and
1401*d9f75844SAndroid Build Coastguard Worker // WebRtc[Audio|Video]Channel's `OnPacketReceived`. We'll remove the
1402*d9f75844SAndroid Build Coastguard Worker // PeerConnection involvement as well as
1403*d9f75844SAndroid Build Coastguard Worker // `JsepTransportController::OnRtcpPacketReceived_n` and `rtcp_handler`
1404*d9f75844SAndroid Build Coastguard Worker // and make sure that the flow of packets is consistent from the
1405*d9f75844SAndroid Build Coastguard Worker // `RtpTransport` class, via the *Channel and *Engine classes and into Call.
1406*d9f75844SAndroid Build Coastguard Worker // This way we'll also know more about the context of the packet.
1407*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_EQ(media_type, MediaType::ANY);
1408*d9f75844SAndroid Build Coastguard Worker
1409*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): This should execute directly on the network
1410*d9f75844SAndroid Build Coastguard Worker // thread.
1411*d9f75844SAndroid Build Coastguard Worker worker_thread_->PostTask(
1412*d9f75844SAndroid Build Coastguard Worker SafeTask(task_safety_.flag(), [this, packet = std::move(packet)]() {
1413*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1414*d9f75844SAndroid Build Coastguard Worker
1415*d9f75844SAndroid Build Coastguard Worker receive_stats_.AddReceivedRtcpBytes(static_cast<int>(packet.size()));
1416*d9f75844SAndroid Build Coastguard Worker bool rtcp_delivered = false;
1417*d9f75844SAndroid Build Coastguard Worker for (VideoReceiveStream2* stream : video_receive_streams_) {
1418*d9f75844SAndroid Build Coastguard Worker if (stream->DeliverRtcp(packet.cdata(), packet.size()))
1419*d9f75844SAndroid Build Coastguard Worker rtcp_delivered = true;
1420*d9f75844SAndroid Build Coastguard Worker }
1421*d9f75844SAndroid Build Coastguard Worker
1422*d9f75844SAndroid Build Coastguard Worker for (AudioReceiveStreamImpl* stream : audio_receive_streams_) {
1423*d9f75844SAndroid Build Coastguard Worker stream->DeliverRtcp(packet.cdata(), packet.size());
1424*d9f75844SAndroid Build Coastguard Worker rtcp_delivered = true;
1425*d9f75844SAndroid Build Coastguard Worker }
1426*d9f75844SAndroid Build Coastguard Worker
1427*d9f75844SAndroid Build Coastguard Worker for (VideoSendStream* stream : video_send_streams_) {
1428*d9f75844SAndroid Build Coastguard Worker stream->DeliverRtcp(packet.cdata(), packet.size());
1429*d9f75844SAndroid Build Coastguard Worker rtcp_delivered = true;
1430*d9f75844SAndroid Build Coastguard Worker }
1431*d9f75844SAndroid Build Coastguard Worker
1432*d9f75844SAndroid Build Coastguard Worker for (auto& kv : audio_send_ssrcs_) {
1433*d9f75844SAndroid Build Coastguard Worker kv.second->DeliverRtcp(packet.cdata(), packet.size());
1434*d9f75844SAndroid Build Coastguard Worker rtcp_delivered = true;
1435*d9f75844SAndroid Build Coastguard Worker }
1436*d9f75844SAndroid Build Coastguard Worker
1437*d9f75844SAndroid Build Coastguard Worker if (rtcp_delivered) {
1438*d9f75844SAndroid Build Coastguard Worker event_log_->Log(std::make_unique<RtcEventRtcpPacketIncoming>(
1439*d9f75844SAndroid Build Coastguard Worker rtc::MakeArrayView(packet.cdata(), packet.size())));
1440*d9f75844SAndroid Build Coastguard Worker }
1441*d9f75844SAndroid Build Coastguard Worker }));
1442*d9f75844SAndroid Build Coastguard Worker }
1443*d9f75844SAndroid Build Coastguard Worker
DeliverRtp(MediaType media_type,rtc::CopyOnWriteBuffer packet,int64_t packet_time_us)1444*d9f75844SAndroid Build Coastguard Worker PacketReceiver::DeliveryStatus Call::DeliverRtp(MediaType media_type,
1445*d9f75844SAndroid Build Coastguard Worker rtc::CopyOnWriteBuffer packet,
1446*d9f75844SAndroid Build Coastguard Worker int64_t packet_time_us) {
1447*d9f75844SAndroid Build Coastguard Worker TRACE_EVENT0("webrtc", "Call::DeliverRtp");
1448*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_NE(media_type, MediaType::ANY);
1449*d9f75844SAndroid Build Coastguard Worker
1450*d9f75844SAndroid Build Coastguard Worker RtpPacketReceived parsed_packet;
1451*d9f75844SAndroid Build Coastguard Worker if (!parsed_packet.Parse(std::move(packet)))
1452*d9f75844SAndroid Build Coastguard Worker return DELIVERY_PACKET_ERROR;
1453*d9f75844SAndroid Build Coastguard Worker
1454*d9f75844SAndroid Build Coastguard Worker if (packet_time_us != -1) {
1455*d9f75844SAndroid Build Coastguard Worker if (receive_time_calculator_) {
1456*d9f75844SAndroid Build Coastguard Worker // Repair packet_time_us for clock resets by comparing a new read of
1457*d9f75844SAndroid Build Coastguard Worker // the same clock (TimeUTCMicros) to a monotonic clock reading.
1458*d9f75844SAndroid Build Coastguard Worker packet_time_us = receive_time_calculator_->ReconcileReceiveTimes(
1459*d9f75844SAndroid Build Coastguard Worker packet_time_us, rtc::TimeUTCMicros(), clock_->TimeInMicroseconds());
1460*d9f75844SAndroid Build Coastguard Worker }
1461*d9f75844SAndroid Build Coastguard Worker parsed_packet.set_arrival_time(Timestamp::Micros(packet_time_us));
1462*d9f75844SAndroid Build Coastguard Worker } else {
1463*d9f75844SAndroid Build Coastguard Worker parsed_packet.set_arrival_time(clock_->CurrentTime());
1464*d9f75844SAndroid Build Coastguard Worker }
1465*d9f75844SAndroid Build Coastguard Worker
1466*d9f75844SAndroid Build Coastguard Worker // We might get RTP keep-alive packets in accordance with RFC6263 section 4.6.
1467*d9f75844SAndroid Build Coastguard Worker // These are empty (zero length payload) RTP packets with an unsignaled
1468*d9f75844SAndroid Build Coastguard Worker // payload type.
1469*d9f75844SAndroid Build Coastguard Worker const bool is_keep_alive_packet = parsed_packet.payload_size() == 0;
1470*d9f75844SAndroid Build Coastguard Worker
1471*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(media_type == MediaType::AUDIO || media_type == MediaType::VIDEO ||
1472*d9f75844SAndroid Build Coastguard Worker is_keep_alive_packet);
1473*d9f75844SAndroid Build Coastguard Worker
1474*d9f75844SAndroid Build Coastguard Worker bool use_send_side_bwe = false;
1475*d9f75844SAndroid Build Coastguard Worker if (!IdentifyReceivedPacket(parsed_packet, &use_send_side_bwe))
1476*d9f75844SAndroid Build Coastguard Worker return DELIVERY_UNKNOWN_SSRC;
1477*d9f75844SAndroid Build Coastguard Worker
1478*d9f75844SAndroid Build Coastguard Worker NotifyBweOfReceivedPacket(parsed_packet, media_type, use_send_side_bwe);
1479*d9f75844SAndroid Build Coastguard Worker
1480*d9f75844SAndroid Build Coastguard Worker // RateCounters expect input parameter as int, save it as int,
1481*d9f75844SAndroid Build Coastguard Worker // instead of converting each time it is passed to RateCounter::Add below.
1482*d9f75844SAndroid Build Coastguard Worker int length = static_cast<int>(parsed_packet.size());
1483*d9f75844SAndroid Build Coastguard Worker if (media_type == MediaType::AUDIO) {
1484*d9f75844SAndroid Build Coastguard Worker if (audio_receiver_controller_.OnRtpPacket(parsed_packet)) {
1485*d9f75844SAndroid Build Coastguard Worker receive_stats_.AddReceivedAudioBytes(length,
1486*d9f75844SAndroid Build Coastguard Worker parsed_packet.arrival_time());
1487*d9f75844SAndroid Build Coastguard Worker event_log_->Log(
1488*d9f75844SAndroid Build Coastguard Worker std::make_unique<RtcEventRtpPacketIncoming>(parsed_packet));
1489*d9f75844SAndroid Build Coastguard Worker return DELIVERY_OK;
1490*d9f75844SAndroid Build Coastguard Worker }
1491*d9f75844SAndroid Build Coastguard Worker } else if (media_type == MediaType::VIDEO) {
1492*d9f75844SAndroid Build Coastguard Worker parsed_packet.set_payload_type_frequency(kVideoPayloadTypeFrequency);
1493*d9f75844SAndroid Build Coastguard Worker if (video_receiver_controller_.OnRtpPacket(parsed_packet)) {
1494*d9f75844SAndroid Build Coastguard Worker receive_stats_.AddReceivedVideoBytes(length,
1495*d9f75844SAndroid Build Coastguard Worker parsed_packet.arrival_time());
1496*d9f75844SAndroid Build Coastguard Worker event_log_->Log(
1497*d9f75844SAndroid Build Coastguard Worker std::make_unique<RtcEventRtpPacketIncoming>(parsed_packet));
1498*d9f75844SAndroid Build Coastguard Worker return DELIVERY_OK;
1499*d9f75844SAndroid Build Coastguard Worker }
1500*d9f75844SAndroid Build Coastguard Worker }
1501*d9f75844SAndroid Build Coastguard Worker return DELIVERY_UNKNOWN_SSRC;
1502*d9f75844SAndroid Build Coastguard Worker }
1503*d9f75844SAndroid Build Coastguard Worker
DeliverPacket(MediaType media_type,rtc::CopyOnWriteBuffer packet,int64_t packet_time_us)1504*d9f75844SAndroid Build Coastguard Worker PacketReceiver::DeliveryStatus Call::DeliverPacket(
1505*d9f75844SAndroid Build Coastguard Worker MediaType media_type,
1506*d9f75844SAndroid Build Coastguard Worker rtc::CopyOnWriteBuffer packet,
1507*d9f75844SAndroid Build Coastguard Worker int64_t packet_time_us) {
1508*d9f75844SAndroid Build Coastguard Worker if (IsRtcpPacket(packet)) {
1509*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(network_thread_);
1510*d9f75844SAndroid Build Coastguard Worker DeliverRtcp(media_type, std::move(packet));
1511*d9f75844SAndroid Build Coastguard Worker return DELIVERY_OK;
1512*d9f75844SAndroid Build Coastguard Worker }
1513*d9f75844SAndroid Build Coastguard Worker
1514*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1515*d9f75844SAndroid Build Coastguard Worker return DeliverRtp(media_type, std::move(packet), packet_time_us);
1516*d9f75844SAndroid Build Coastguard Worker }
1517*d9f75844SAndroid Build Coastguard Worker
OnRecoveredPacket(const uint8_t * packet,size_t length)1518*d9f75844SAndroid Build Coastguard Worker void Call::OnRecoveredPacket(const uint8_t* packet, size_t length) {
1519*d9f75844SAndroid Build Coastguard Worker // TODO(bugs.webrtc.org/11993): Expect to be called on the network thread.
1520*d9f75844SAndroid Build Coastguard Worker // This method is called synchronously via `OnRtpPacket()` (see DeliverRtp)
1521*d9f75844SAndroid Build Coastguard Worker // on the same thread.
1522*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1523*d9f75844SAndroid Build Coastguard Worker RtpPacketReceived parsed_packet;
1524*d9f75844SAndroid Build Coastguard Worker if (!parsed_packet.Parse(packet, length))
1525*d9f75844SAndroid Build Coastguard Worker return;
1526*d9f75844SAndroid Build Coastguard Worker
1527*d9f75844SAndroid Build Coastguard Worker parsed_packet.set_recovered(true);
1528*d9f75844SAndroid Build Coastguard Worker
1529*d9f75844SAndroid Build Coastguard Worker if (!IdentifyReceivedPacket(parsed_packet))
1530*d9f75844SAndroid Build Coastguard Worker return;
1531*d9f75844SAndroid Build Coastguard Worker
1532*d9f75844SAndroid Build Coastguard Worker // TODO(brandtr): Update here when we support protecting audio packets too.
1533*d9f75844SAndroid Build Coastguard Worker parsed_packet.set_payload_type_frequency(kVideoPayloadTypeFrequency);
1534*d9f75844SAndroid Build Coastguard Worker video_receiver_controller_.OnRtpPacket(parsed_packet);
1535*d9f75844SAndroid Build Coastguard Worker }
1536*d9f75844SAndroid Build Coastguard Worker
NotifyBweOfReceivedPacket(const RtpPacketReceived & packet,MediaType media_type,bool use_send_side_bwe)1537*d9f75844SAndroid Build Coastguard Worker void Call::NotifyBweOfReceivedPacket(const RtpPacketReceived& packet,
1538*d9f75844SAndroid Build Coastguard Worker MediaType media_type,
1539*d9f75844SAndroid Build Coastguard Worker bool use_send_side_bwe) {
1540*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(worker_thread_);
1541*d9f75844SAndroid Build Coastguard Worker RTPHeader header;
1542*d9f75844SAndroid Build Coastguard Worker packet.GetHeader(&header);
1543*d9f75844SAndroid Build Coastguard Worker
1544*d9f75844SAndroid Build Coastguard Worker ReceivedPacket packet_msg;
1545*d9f75844SAndroid Build Coastguard Worker packet_msg.size = DataSize::Bytes(packet.payload_size());
1546*d9f75844SAndroid Build Coastguard Worker packet_msg.receive_time = packet.arrival_time();
1547*d9f75844SAndroid Build Coastguard Worker if (header.extension.hasAbsoluteSendTime) {
1548*d9f75844SAndroid Build Coastguard Worker packet_msg.send_time = header.extension.GetAbsoluteSendTimestamp();
1549*d9f75844SAndroid Build Coastguard Worker }
1550*d9f75844SAndroid Build Coastguard Worker transport_send_->OnReceivedPacket(packet_msg);
1551*d9f75844SAndroid Build Coastguard Worker
1552*d9f75844SAndroid Build Coastguard Worker if (!use_send_side_bwe && header.extension.hasTransportSequenceNumber) {
1553*d9f75844SAndroid Build Coastguard Worker // Inconsistent configuration of send side BWE. Do nothing.
1554*d9f75844SAndroid Build Coastguard Worker return;
1555*d9f75844SAndroid Build Coastguard Worker }
1556*d9f75844SAndroid Build Coastguard Worker // For audio, we only support send side BWE.
1557*d9f75844SAndroid Build Coastguard Worker if (media_type == MediaType::VIDEO ||
1558*d9f75844SAndroid Build Coastguard Worker (use_send_side_bwe && header.extension.hasTransportSequenceNumber)) {
1559*d9f75844SAndroid Build Coastguard Worker receive_side_cc_.OnReceivedPacket(
1560*d9f75844SAndroid Build Coastguard Worker packet.arrival_time().ms(),
1561*d9f75844SAndroid Build Coastguard Worker packet.payload_size() + packet.padding_size(), header);
1562*d9f75844SAndroid Build Coastguard Worker }
1563*d9f75844SAndroid Build Coastguard Worker }
1564*d9f75844SAndroid Build Coastguard Worker
IdentifyReceivedPacket(RtpPacketReceived & packet,bool * use_send_side_bwe)1565*d9f75844SAndroid Build Coastguard Worker bool Call::IdentifyReceivedPacket(RtpPacketReceived& packet,
1566*d9f75844SAndroid Build Coastguard Worker bool* use_send_side_bwe /*= nullptr*/) {
1567*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&receive_11993_checker_);
1568*d9f75844SAndroid Build Coastguard Worker auto it = receive_rtp_config_.find(packet.Ssrc());
1569*d9f75844SAndroid Build Coastguard Worker if (it == receive_rtp_config_.end()) {
1570*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_WARNING) << "receive_rtp_config_ lookup failed for ssrc "
1571*d9f75844SAndroid Build Coastguard Worker << packet.Ssrc();
1572*d9f75844SAndroid Build Coastguard Worker return false;
1573*d9f75844SAndroid Build Coastguard Worker }
1574*d9f75844SAndroid Build Coastguard Worker
1575*d9f75844SAndroid Build Coastguard Worker packet.IdentifyExtensions(it->second->GetRtpExtensionMap());
1576*d9f75844SAndroid Build Coastguard Worker
1577*d9f75844SAndroid Build Coastguard Worker if (use_send_side_bwe) {
1578*d9f75844SAndroid Build Coastguard Worker *use_send_side_bwe = UseSendSideBwe(it->second);
1579*d9f75844SAndroid Build Coastguard Worker }
1580*d9f75844SAndroid Build Coastguard Worker
1581*d9f75844SAndroid Build Coastguard Worker return true;
1582*d9f75844SAndroid Build Coastguard Worker }
1583*d9f75844SAndroid Build Coastguard Worker
RegisterReceiveStream(uint32_t ssrc,ReceiveStreamInterface * stream)1584*d9f75844SAndroid Build Coastguard Worker bool Call::RegisterReceiveStream(uint32_t ssrc,
1585*d9f75844SAndroid Build Coastguard Worker ReceiveStreamInterface* stream) {
1586*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&receive_11993_checker_);
1587*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK(stream);
1588*d9f75844SAndroid Build Coastguard Worker auto inserted = receive_rtp_config_.emplace(ssrc, stream);
1589*d9f75844SAndroid Build Coastguard Worker if (!inserted.second) {
1590*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_WARNING) << "ssrc already registered: " << ssrc;
1591*d9f75844SAndroid Build Coastguard Worker }
1592*d9f75844SAndroid Build Coastguard Worker return inserted.second;
1593*d9f75844SAndroid Build Coastguard Worker }
1594*d9f75844SAndroid Build Coastguard Worker
UnregisterReceiveStream(uint32_t ssrc)1595*d9f75844SAndroid Build Coastguard Worker bool Call::UnregisterReceiveStream(uint32_t ssrc) {
1596*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_RUN_ON(&receive_11993_checker_);
1597*d9f75844SAndroid Build Coastguard Worker size_t erased = receive_rtp_config_.erase(ssrc);
1598*d9f75844SAndroid Build Coastguard Worker if (!erased) {
1599*d9f75844SAndroid Build Coastguard Worker RTC_DLOG(LS_WARNING) << "ssrc wasn't registered: " << ssrc;
1600*d9f75844SAndroid Build Coastguard Worker }
1601*d9f75844SAndroid Build Coastguard Worker return erased != 0u;
1602*d9f75844SAndroid Build Coastguard Worker }
1603*d9f75844SAndroid Build Coastguard Worker
1604*d9f75844SAndroid Build Coastguard Worker } // namespace internal
1605*d9f75844SAndroid Build Coastguard Worker
1606*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
1607