blob: 2a969ab1b491d9899bae212340cd878bcf41a683 [file] [log] [blame]
Niels Möller530ead42018-10-04 14:28:39 +02001/*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "audio/channel_send.h"
12
13#include <algorithm>
14#include <map>
15#include <memory>
16#include <string>
17#include <utility>
18#include <vector>
19
Niels Möller530ead42018-10-04 14:28:39 +020020#include "api/array_view.h"
Niels Möllerdced9f62018-11-19 10:27:07 +010021#include "api/call/transport.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "api/crypto/frame_encryptor_interface.h"
Danil Chapovalov83bbe912019-08-07 12:24:53 +020023#include "api/rtc_event_log/rtc_event_log.h"
Niels Möller530ead42018-10-04 14:28:39 +020024#include "audio/utility/audio_frame_operations.h"
25#include "call/rtp_transport_controller_send_interface.h"
26#include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
Niels Möller530ead42018-10-04 14:28:39 +020027#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
Niels Möllerdced9f62018-11-19 10:27:07 +010028#include "modules/audio_coding/include/audio_coding_module.h"
29#include "modules/audio_processing/rms_level.h"
Niels Möller530ead42018-10-04 14:28:39 +020030#include "modules/pacing/packet_router.h"
31#include "modules/utility/include/process_thread.h"
32#include "rtc_base/checks.h"
Yves Gerey2e00abc2018-10-05 15:39:24 +020033#include "rtc_base/event.h"
Niels Möller530ead42018-10-04 14:28:39 +020034#include "rtc_base/format_macros.h"
35#include "rtc_base/location.h"
36#include "rtc_base/logging.h"
Niels Möller26815232018-11-16 09:32:40 +010037#include "rtc_base/numerics/safe_conversions.h"
Niels Möllerdced9f62018-11-19 10:27:07 +010038#include "rtc_base/race_checker.h"
Niels Möller530ead42018-10-04 14:28:39 +020039#include "rtc_base/rate_limiter.h"
40#include "rtc_base/task_queue.h"
41#include "rtc_base/thread_checker.h"
Steve Anton10542f22019-01-11 09:11:00 -080042#include "rtc_base/time_utils.h"
Sebastian Jansson977b3352019-03-04 17:43:34 +010043#include "system_wrappers/include/clock.h"
Niels Möller530ead42018-10-04 14:28:39 +020044#include "system_wrappers/include/field_trial.h"
45#include "system_wrappers/include/metrics.h"
46
47namespace webrtc {
48namespace voe {
49
50namespace {
51
52constexpr int64_t kMaxRetransmissionWindowMs = 1000;
53constexpr int64_t kMinRetransmissionWindowMs = 30;
54
Bjorn A Mellemda4f0932019-07-30 08:34:03 -070055// Field trial which controls whether to report standard-compliant bytes
56// sent/received per stream. If enabled, padding and headers are not included
57// in bytes sent or received.
58constexpr char kUseStandardBytesStats[] = "WebRTC-UseStandardBytesStats";
59
Niels Möller7d76a312018-10-26 12:57:07 +020060MediaTransportEncodedAudioFrame::FrameType
Niels Möller87e2d782019-03-07 10:18:23 +010061MediaTransportFrameTypeForWebrtcFrameType(webrtc::AudioFrameType frame_type) {
Niels Möller7d76a312018-10-26 12:57:07 +020062 switch (frame_type) {
Niels Möllerc936cb62019-03-19 14:10:16 +010063 case AudioFrameType::kAudioFrameSpeech:
Niels Möller7d76a312018-10-26 12:57:07 +020064 return MediaTransportEncodedAudioFrame::FrameType::kSpeech;
65 break;
66
Niels Möllerc936cb62019-03-19 14:10:16 +010067 case AudioFrameType::kAudioFrameCN:
Niels Möller7d76a312018-10-26 12:57:07 +020068 return MediaTransportEncodedAudioFrame::FrameType::
69 kDiscontinuousTransmission;
70 break;
71
72 default:
Niels Möllerc936cb62019-03-19 14:10:16 +010073 RTC_CHECK(false) << "Unexpected frame type="
74 << static_cast<int>(frame_type);
Niels Möller7d76a312018-10-26 12:57:07 +020075 break;
76 }
77}
78
Niels Möllerdced9f62018-11-19 10:27:07 +010079class RtpPacketSenderProxy;
80class TransportFeedbackProxy;
81class TransportSequenceNumberProxy;
82class VoERtcpObserver;
83
Benjamin Wright17b050f2019-03-13 17:35:46 -070084class ChannelSend : public ChannelSendInterface,
85 public AudioPacketizationCallback, // receive encoded
86 // packets from the ACM
87 public TargetTransferRateObserver {
Niels Möllerdced9f62018-11-19 10:27:07 +010088 public:
89 // TODO(nisse): Make OnUplinkPacketLossRate public, and delete friend
90 // declaration.
91 friend class VoERtcpObserver;
92
Sebastian Jansson977b3352019-03-04 17:43:34 +010093 ChannelSend(Clock* clock,
Sebastian Jansson44dd9f22019-03-08 14:50:30 +010094 TaskQueueFactory* task_queue_factory,
Niels Möllerdced9f62018-11-19 10:27:07 +010095 ProcessThread* module_process_thread,
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070096 const MediaTransportConfig& media_transport_config,
Anton Sukhanov626015d2019-02-04 15:16:06 -080097 OverheadObserver* overhead_observer,
Niels Möllere9771992018-11-26 10:55:07 +010098 Transport* rtp_transport,
Niels Möllerdced9f62018-11-19 10:27:07 +010099 RtcpRttStats* rtcp_rtt_stats,
100 RtcEventLog* rtc_event_log,
101 FrameEncryptorInterface* frame_encryptor,
102 const webrtc::CryptoOptions& crypto_options,
103 bool extmap_allow_mixed,
Erik Språng4c2c4122019-07-11 15:20:15 +0200104 int rtcp_report_interval_ms,
105 uint32_t ssrc);
Niels Möllerdced9f62018-11-19 10:27:07 +0100106
107 ~ChannelSend() override;
108
109 // Send using this encoder, with this payload type.
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100110 void SetEncoder(int payload_type,
Niels Möllerdced9f62018-11-19 10:27:07 +0100111 std::unique_ptr<AudioEncoder> encoder) override;
112 void ModifyEncoder(rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)>
113 modifier) override;
Sebastian Jansson14a7cf92019-02-13 15:11:42 +0100114 void CallEncoder(rtc::FunctionView<void(AudioEncoder*)> modifier) override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100115
116 // API methods
Niels Möllerdced9f62018-11-19 10:27:07 +0100117 void StartSend() override;
118 void StopSend() override;
119
120 // Codecs
Sebastian Jansson254d8692018-11-21 19:19:00 +0100121 void OnBitrateAllocation(BitrateAllocationUpdate update) override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100122 int GetBitrate() const override;
123
124 // Network
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100125 void ReceivedRTCPPacket(const uint8_t* data, size_t length) override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100126
127 // Muting, Volume and Level.
128 void SetInputMute(bool enable) override;
129
130 // Stats.
131 ANAStats GetANAStatistics() const override;
132
133 // Used by AudioSendStream.
134 RtpRtcp* GetRtpRtcp() const override;
135
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100136 void RegisterCngPayloadType(int payload_type, int payload_frequency) override;
137
Niels Möllerdced9f62018-11-19 10:27:07 +0100138 // DTMF.
139 bool SendTelephoneEventOutband(int event, int duration_ms) override;
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100140 void SetSendTelephoneEventPayloadType(int payload_type,
Niels Möllerdced9f62018-11-19 10:27:07 +0100141 int payload_frequency) override;
142
143 // RTP+RTCP
Amit Hilbuch77938e62018-12-21 09:23:38 -0800144 void SetRid(const std::string& rid,
145 int extension_id,
146 int repaired_extension_id) override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100147 void SetMid(const std::string& mid, int extension_id) override;
148 void SetExtmapAllowMixed(bool extmap_allow_mixed) override;
149 void SetSendAudioLevelIndicationStatus(bool enable, int id) override;
150 void EnableSendTransportSequenceNumber(int id) override;
151
152 void RegisterSenderCongestionControlObjects(
153 RtpTransportControllerSendInterface* transport,
154 RtcpBandwidthObserver* bandwidth_observer) override;
155 void ResetSenderCongestionControlObjects() override;
156 void SetRTCP_CNAME(absl::string_view c_name) override;
157 std::vector<ReportBlock> GetRemoteRTCPReportBlocks() const override;
158 CallSendStatistics GetRTCPStatistics() const override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100159
160 // ProcessAndEncodeAudio() posts a task on the shared encoder task queue,
161 // which in turn calls (on the queue) ProcessAndEncodeAudioOnTaskQueue() where
162 // the actual processing of the audio takes place. The processing mainly
163 // consists of encoding and preparing the result for sending by adding it to a
164 // send queue.
165 // The main reason for using a task queue here is to release the native,
166 // OS-specific, audio capture thread as soon as possible to ensure that it
167 // can go back to sleep and be prepared to deliver an new captured audio
168 // packet.
169 void ProcessAndEncodeAudio(std::unique_ptr<AudioFrame> audio_frame) override;
170
Niels Möllerdced9f62018-11-19 10:27:07 +0100171 // The existence of this function alongside OnUplinkPacketLossRate is
172 // a compromise. We want the encoder to be agnostic of the PLR source, but
173 // we also don't want it to receive conflicting information from TWCC and
174 // from RTCP-XR.
175 void OnTwccBasedUplinkPacketLossRate(float packet_loss_rate) override;
176
177 void OnRecoverableUplinkPacketLossRate(
178 float recoverable_packet_loss_rate) override;
179
180 int64_t GetRTT() const override;
181
182 // E2EE Custom Audio Frame Encryption
183 void SetFrameEncryptor(
184 rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) override;
185
186 private:
Niels Möllerdced9f62018-11-19 10:27:07 +0100187 // From AudioPacketizationCallback in the ACM
Niels Möller87e2d782019-03-07 10:18:23 +0100188 int32_t SendData(AudioFrameType frameType,
Niels Möllerdced9f62018-11-19 10:27:07 +0100189 uint8_t payloadType,
190 uint32_t timeStamp,
191 const uint8_t* payloadData,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200192 size_t payloadSize) override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100193
Niels Möllerdced9f62018-11-19 10:27:07 +0100194 void OnUplinkPacketLossRate(float packet_loss_rate);
195 bool InputMute() const;
196
Niels Möllerdced9f62018-11-19 10:27:07 +0100197 int SetSendRtpHeaderExtension(bool enable, RTPExtensionType type, int id);
198
Niels Möller87e2d782019-03-07 10:18:23 +0100199 int32_t SendRtpAudio(AudioFrameType frameType,
Niels Möllerdced9f62018-11-19 10:27:07 +0100200 uint8_t payloadType,
201 uint32_t timeStamp,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200202 rtc::ArrayView<const uint8_t> payload)
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100203 RTC_RUN_ON(encoder_queue_);
Niels Möllerdced9f62018-11-19 10:27:07 +0100204
Niels Möller87e2d782019-03-07 10:18:23 +0100205 int32_t SendMediaTransportAudio(AudioFrameType frameType,
Niels Möllerdced9f62018-11-19 10:27:07 +0100206 uint8_t payloadType,
207 uint32_t timeStamp,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200208 rtc::ArrayView<const uint8_t> payload)
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100209 RTC_RUN_ON(encoder_queue_);
Niels Möllerdced9f62018-11-19 10:27:07 +0100210
211 // Return media transport or nullptr if using RTP.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700212 MediaTransportInterface* media_transport() {
213 return media_transport_config_.media_transport;
214 }
Niels Möllerdced9f62018-11-19 10:27:07 +0100215
Niels Möllerdced9f62018-11-19 10:27:07 +0100216 void OnReceivedRtt(int64_t rtt_ms);
217
218 void OnTargetTransferRate(TargetTransferRate) override;
219
220 // Thread checkers document and lock usage of some methods on voe::Channel to
221 // specific threads we know about. The goal is to eventually split up
222 // voe::Channel into parts with single-threaded semantics, and thereby reduce
223 // the need for locks.
224 rtc::ThreadChecker worker_thread_checker_;
225 rtc::ThreadChecker module_process_thread_checker_;
226 // Methods accessed from audio and video threads are checked for sequential-
227 // only access. We don't necessarily own and control these threads, so thread
228 // checkers cannot be used. E.g. Chromium may transfer "ownership" from one
229 // audio thread to another, but access is still sequential.
230 rtc::RaceChecker audio_thread_race_checker_;
231
Niels Möllerdced9f62018-11-19 10:27:07 +0100232 rtc::CriticalSection volume_settings_critsect_;
233
Niels Möller26e88b02018-11-19 15:08:13 +0100234 bool sending_ RTC_GUARDED_BY(&worker_thread_checker_) = false;
Niels Möllerdced9f62018-11-19 10:27:07 +0100235
236 RtcEventLog* const event_log_;
237
238 std::unique_ptr<RtpRtcp> _rtpRtcpModule;
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100239 std::unique_ptr<RTPSenderAudio> rtp_sender_audio_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100240
241 std::unique_ptr<AudioCodingModule> audio_coding_;
242 uint32_t _timeStamp RTC_GUARDED_BY(encoder_queue_);
243
Niels Möllerdced9f62018-11-19 10:27:07 +0100244 // uses
Niels Möller985a1f32018-11-19 16:08:42 +0100245 ProcessThread* const _moduleProcessThreadPtr;
Niels Möllerdced9f62018-11-19 10:27:07 +0100246 RmsLevel rms_level_ RTC_GUARDED_BY(encoder_queue_);
247 bool input_mute_ RTC_GUARDED_BY(volume_settings_critsect_);
248 bool previous_frame_muted_ RTC_GUARDED_BY(encoder_queue_);
249 // VoeRTP_RTCP
250 // TODO(henrika): can today be accessed on the main thread and on the
251 // task queue; hence potential race.
252 bool _includeAudioLevelIndication;
Anton Sukhanov626015d2019-02-04 15:16:06 -0800253
Niels Möllerdced9f62018-11-19 10:27:07 +0100254 // RtcpBandwidthObserver
Niels Möller985a1f32018-11-19 16:08:42 +0100255 const std::unique_ptr<VoERtcpObserver> rtcp_observer_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100256
Niels Möller985a1f32018-11-19 16:08:42 +0100257 PacketRouter* packet_router_ RTC_GUARDED_BY(&worker_thread_checker_) =
258 nullptr;
259 const std::unique_ptr<TransportFeedbackProxy> feedback_observer_proxy_;
Erik Språng59b86542019-06-23 18:24:46 +0200260 const std::unique_ptr<RtpPacketSenderProxy> rtp_packet_pacer_proxy_;
Niels Möller985a1f32018-11-19 16:08:42 +0100261 const std::unique_ptr<RateLimiter> retransmission_rate_limiter_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100262
263 rtc::ThreadChecker construction_thread_;
264
265 const bool use_twcc_plr_for_ana_;
Bjorn A Mellemda4f0932019-07-30 08:34:03 -0700266 const bool use_standard_bytes_stats_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100267
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100268 bool encoder_queue_is_active_ RTC_GUARDED_BY(encoder_queue_) = false;
Niels Möllerdced9f62018-11-19 10:27:07 +0100269
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700270 MediaTransportConfig media_transport_config_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100271 int media_transport_sequence_number_ RTC_GUARDED_BY(encoder_queue_) = 0;
272
273 rtc::CriticalSection media_transport_lock_;
Erik Språng70efdde2019-08-21 13:36:20 +0200274 // Currently set to local SSRC at construction.
Niels Möllerdced9f62018-11-19 10:27:07 +0100275 uint64_t media_transport_channel_id_ RTC_GUARDED_BY(&media_transport_lock_) =
276 0;
277 // Cache payload type and sampling frequency from most recent call to
278 // SetEncoder. Needed to set MediaTransportEncodedAudioFrame metadata, and
279 // invalidate on encoder change.
280 int media_transport_payload_type_ RTC_GUARDED_BY(&media_transport_lock_);
281 int media_transport_sampling_frequency_
282 RTC_GUARDED_BY(&media_transport_lock_);
283
284 // E2EE Audio Frame Encryption
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100285 rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor_
286 RTC_GUARDED_BY(encoder_queue_);
Niels Möllerdced9f62018-11-19 10:27:07 +0100287 // E2EE Frame Encryption Options
Niels Möller985a1f32018-11-19 16:08:42 +0100288 const webrtc::CryptoOptions crypto_options_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100289
290 rtc::CriticalSection bitrate_crit_section_;
291 int configured_bitrate_bps_ RTC_GUARDED_BY(bitrate_crit_section_) = 0;
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100292
293 // Defined last to ensure that there are no running tasks when the other
294 // members are destroyed.
295 rtc::TaskQueue encoder_queue_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100296};
Niels Möller530ead42018-10-04 14:28:39 +0200297
298const int kTelephoneEventAttenuationdB = 10;
299
300class TransportFeedbackProxy : public TransportFeedbackObserver {
301 public:
302 TransportFeedbackProxy() : feedback_observer_(nullptr) {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200303 pacer_thread_.Detach();
304 network_thread_.Detach();
Niels Möller530ead42018-10-04 14:28:39 +0200305 }
306
307 void SetTransportFeedbackObserver(
308 TransportFeedbackObserver* feedback_observer) {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200309 RTC_DCHECK(thread_checker_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +0200310 rtc::CritScope lock(&crit_);
311 feedback_observer_ = feedback_observer;
312 }
313
314 // Implements TransportFeedbackObserver.
Erik Språng30a276b2019-04-23 12:00:11 +0200315 void OnAddPacket(const RtpPacketSendInfo& packet_info) override {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200316 RTC_DCHECK(pacer_thread_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +0200317 rtc::CritScope lock(&crit_);
318 if (feedback_observer_)
Erik Språng30a276b2019-04-23 12:00:11 +0200319 feedback_observer_->OnAddPacket(packet_info);
Niels Möller530ead42018-10-04 14:28:39 +0200320 }
321
322 void OnTransportFeedback(const rtcp::TransportFeedback& feedback) override {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200323 RTC_DCHECK(network_thread_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +0200324 rtc::CritScope lock(&crit_);
325 if (feedback_observer_)
326 feedback_observer_->OnTransportFeedback(feedback);
327 }
328
329 private:
330 rtc::CriticalSection crit_;
331 rtc::ThreadChecker thread_checker_;
332 rtc::ThreadChecker pacer_thread_;
333 rtc::ThreadChecker network_thread_;
334 TransportFeedbackObserver* feedback_observer_ RTC_GUARDED_BY(&crit_);
335};
336
Erik Språngaa59eca2019-07-24 14:52:55 +0200337class RtpPacketSenderProxy : public RtpPacketSender {
Niels Möller530ead42018-10-04 14:28:39 +0200338 public:
Erik Språng59b86542019-06-23 18:24:46 +0200339 RtpPacketSenderProxy() : rtp_packet_pacer_(nullptr) {}
Niels Möller530ead42018-10-04 14:28:39 +0200340
Erik Språngaa59eca2019-07-24 14:52:55 +0200341 void SetPacketPacer(RtpPacketSender* rtp_packet_pacer) {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200342 RTC_DCHECK(thread_checker_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +0200343 rtc::CritScope lock(&crit_);
Erik Språng59b86542019-06-23 18:24:46 +0200344 rtp_packet_pacer_ = rtp_packet_pacer;
345 }
346
Erik Språngea55b082019-10-02 14:57:46 +0200347 void EnqueuePackets(
348 std::vector<std::unique_ptr<RtpPacketToSend>> packets) override {
Erik Språng59b86542019-06-23 18:24:46 +0200349 rtc::CritScope lock(&crit_);
Erik Språngea55b082019-10-02 14:57:46 +0200350 rtp_packet_pacer_->EnqueuePackets(std::move(packets));
Niels Möller530ead42018-10-04 14:28:39 +0200351 }
352
Niels Möller530ead42018-10-04 14:28:39 +0200353 private:
354 rtc::ThreadChecker thread_checker_;
355 rtc::CriticalSection crit_;
Erik Språngaa59eca2019-07-24 14:52:55 +0200356 RtpPacketSender* rtp_packet_pacer_ RTC_GUARDED_BY(&crit_);
Niels Möller530ead42018-10-04 14:28:39 +0200357};
358
359class VoERtcpObserver : public RtcpBandwidthObserver {
360 public:
361 explicit VoERtcpObserver(ChannelSend* owner)
362 : owner_(owner), bandwidth_observer_(nullptr) {}
Mirko Bonadeife055c12019-01-29 22:53:28 +0100363 ~VoERtcpObserver() override {}
Niels Möller530ead42018-10-04 14:28:39 +0200364
365 void SetBandwidthObserver(RtcpBandwidthObserver* bandwidth_observer) {
366 rtc::CritScope lock(&crit_);
367 bandwidth_observer_ = bandwidth_observer;
368 }
369
370 void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
371 rtc::CritScope lock(&crit_);
372 if (bandwidth_observer_) {
373 bandwidth_observer_->OnReceivedEstimatedBitrate(bitrate);
374 }
375 }
376
377 void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
378 int64_t rtt,
379 int64_t now_ms) override {
380 {
381 rtc::CritScope lock(&crit_);
382 if (bandwidth_observer_) {
383 bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, rtt,
384 now_ms);
385 }
386 }
387 // TODO(mflodman): Do we need to aggregate reports here or can we jut send
388 // what we get? I.e. do we ever get multiple reports bundled into one RTCP
389 // report for VoiceEngine?
390 if (report_blocks.empty())
391 return;
392
393 int fraction_lost_aggregate = 0;
394 int total_number_of_packets = 0;
395
396 // If receiving multiple report blocks, calculate the weighted average based
397 // on the number of packets a report refers to.
398 for (ReportBlockList::const_iterator block_it = report_blocks.begin();
399 block_it != report_blocks.end(); ++block_it) {
400 // Find the previous extended high sequence number for this remote SSRC,
401 // to calculate the number of RTP packets this report refers to. Ignore if
402 // we haven't seen this SSRC before.
403 std::map<uint32_t, uint32_t>::iterator seq_num_it =
404 extended_max_sequence_number_.find(block_it->source_ssrc);
405 int number_of_packets = 0;
406 if (seq_num_it != extended_max_sequence_number_.end()) {
407 number_of_packets =
408 block_it->extended_highest_sequence_number - seq_num_it->second;
409 }
410 fraction_lost_aggregate += number_of_packets * block_it->fraction_lost;
411 total_number_of_packets += number_of_packets;
412
413 extended_max_sequence_number_[block_it->source_ssrc] =
414 block_it->extended_highest_sequence_number;
415 }
416 int weighted_fraction_lost = 0;
417 if (total_number_of_packets > 0) {
418 weighted_fraction_lost =
419 (fraction_lost_aggregate + total_number_of_packets / 2) /
420 total_number_of_packets;
421 }
422 owner_->OnUplinkPacketLossRate(weighted_fraction_lost / 255.0f);
423 }
424
425 private:
426 ChannelSend* owner_;
427 // Maps remote side ssrc to extended highest sequence number received.
428 std::map<uint32_t, uint32_t> extended_max_sequence_number_;
429 rtc::CriticalSection crit_;
430 RtcpBandwidthObserver* bandwidth_observer_ RTC_GUARDED_BY(crit_);
431};
432
Niels Möller87e2d782019-03-07 10:18:23 +0100433int32_t ChannelSend::SendData(AudioFrameType frameType,
Niels Möller530ead42018-10-04 14:28:39 +0200434 uint8_t payloadType,
435 uint32_t timeStamp,
436 const uint8_t* payloadData,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200437 size_t payloadSize) {
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100438 RTC_DCHECK_RUN_ON(&encoder_queue_);
Niels Möller7d76a312018-10-26 12:57:07 +0200439 rtc::ArrayView<const uint8_t> payload(payloadData, payloadSize);
440
441 if (media_transport() != nullptr) {
Niels Möllerc936cb62019-03-19 14:10:16 +0100442 if (frameType == AudioFrameType::kEmptyFrame) {
Piotr (Peter) Slatala3cdd4d52019-02-28 07:10:56 -0800443 // TODO(bugs.webrtc.org/9719): Media transport Send doesn't support
444 // sending empty frames.
445 return 0;
446 }
447
Niels Möllerc35b6e62019-04-25 16:31:18 +0200448 return SendMediaTransportAudio(frameType, payloadType, timeStamp, payload);
Niels Möller7d76a312018-10-26 12:57:07 +0200449 } else {
Niels Möllerc35b6e62019-04-25 16:31:18 +0200450 return SendRtpAudio(frameType, payloadType, timeStamp, payload);
Niels Möller7d76a312018-10-26 12:57:07 +0200451 }
452}
453
Niels Möller87e2d782019-03-07 10:18:23 +0100454int32_t ChannelSend::SendRtpAudio(AudioFrameType frameType,
Niels Möller7d76a312018-10-26 12:57:07 +0200455 uint8_t payloadType,
456 uint32_t timeStamp,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200457 rtc::ArrayView<const uint8_t> payload) {
Niels Möller530ead42018-10-04 14:28:39 +0200458 if (_includeAudioLevelIndication) {
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100459 // Store current audio level in the RTP sender.
Niels Möller530ead42018-10-04 14:28:39 +0200460 // The level will be used in combination with voice-activity state
461 // (frameType) to add an RTP header extension
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100462 rtp_sender_audio_->SetAudioLevel(rms_level_.Average());
Niels Möller530ead42018-10-04 14:28:39 +0200463 }
464
Benjamin Wright84583f62018-10-04 14:22:34 -0700465 // E2EE Custom Audio Frame Encryption (This is optional).
466 // Keep this buffer around for the lifetime of the send call.
467 rtc::Buffer encrypted_audio_payload;
Minyue Li9ab520e2019-05-28 13:27:40 +0200468 // We don't invoke encryptor if payload is empty, which means we are to send
469 // DTMF, or the encoder entered DTX.
470 // TODO(minyue): see whether DTMF packets should be encrypted or not. In
471 // current implementation, they are not.
Minyue Lif48bca72019-06-20 23:37:02 +0200472 if (!payload.empty()) {
473 if (frame_encryptor_ != nullptr) {
474 // TODO(benwright@webrtc.org) - Allocate enough to always encrypt inline.
475 // Allocate a buffer to hold the maximum possible encrypted payload.
476 size_t max_ciphertext_size = frame_encryptor_->GetMaxCiphertextByteSize(
477 cricket::MEDIA_TYPE_AUDIO, payload.size());
478 encrypted_audio_payload.SetSize(max_ciphertext_size);
Benjamin Wright84583f62018-10-04 14:22:34 -0700479
Minyue Lif48bca72019-06-20 23:37:02 +0200480 // Encrypt the audio payload into the buffer.
481 size_t bytes_written = 0;
482 int encrypt_status = frame_encryptor_->Encrypt(
483 cricket::MEDIA_TYPE_AUDIO, _rtpRtcpModule->SSRC(),
484 /*additional_data=*/nullptr, payload, encrypted_audio_payload,
485 &bytes_written);
486 if (encrypt_status != 0) {
487 RTC_DLOG(LS_ERROR)
488 << "Channel::SendData() failed encrypt audio payload: "
489 << encrypt_status;
490 return -1;
491 }
492 // Resize the buffer to the exact number of bytes actually used.
493 encrypted_audio_payload.SetSize(bytes_written);
494 // Rewrite the payloadData and size to the new encrypted payload.
495 payload = encrypted_audio_payload;
496 } else if (crypto_options_.sframe.require_frame_encryption) {
497 RTC_DLOG(LS_ERROR) << "Channel::SendData() failed sending audio payload: "
498 << "A frame encryptor is required but one is not set.";
Benjamin Wright84583f62018-10-04 14:22:34 -0700499 return -1;
500 }
Benjamin Wright84583f62018-10-04 14:22:34 -0700501 }
502
Niels Möller530ead42018-10-04 14:28:39 +0200503 // Push data from ACM to RTP/RTCP-module to deliver audio frame for
504 // packetization.
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100505 if (!_rtpRtcpModule->OnSendingRtpFrame(timeStamp,
506 // Leaving the time when this frame was
507 // received from the capture device as
508 // undefined for voice for now.
509 -1, payloadType,
510 /*force_sender_report=*/false)) {
511 return false;
512 }
513
514 // RTCPSender has it's own copy of the timestamp offset, added in
515 // RTCPSender::BuildSR, hence we must not add the in the offset for the above
516 // call.
517 // TODO(nisse): Delete RTCPSender:timestamp_offset_, and see if we can confine
518 // knowledge of the offset to a single place.
519 const uint32_t rtp_timestamp = timeStamp + _rtpRtcpModule->StartTimestamp();
Niels Möller530ead42018-10-04 14:28:39 +0200520 // This call will trigger Transport::SendPacket() from the RTP/RTCP module.
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100521 if (!rtp_sender_audio_->SendAudio(frameType, payloadType, rtp_timestamp,
522 payload.data(), payload.size())) {
Niels Möller530ead42018-10-04 14:28:39 +0200523 RTC_DLOG(LS_ERROR)
524 << "ChannelSend::SendData() failed to send data to RTP/RTCP module";
525 return -1;
526 }
527
528 return 0;
529}
530
Niels Möller7d76a312018-10-26 12:57:07 +0200531int32_t ChannelSend::SendMediaTransportAudio(
Niels Möller87e2d782019-03-07 10:18:23 +0100532 AudioFrameType frameType,
Niels Möller7d76a312018-10-26 12:57:07 +0200533 uint8_t payloadType,
534 uint32_t timeStamp,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200535 rtc::ArrayView<const uint8_t> payload) {
Niels Möller7d76a312018-10-26 12:57:07 +0200536 // TODO(nisse): Use null _transportPtr for MediaTransport.
537 // RTC_DCHECK(_transportPtr == nullptr);
538 uint64_t channel_id;
539 int sampling_rate_hz;
540 {
541 rtc::CritScope cs(&media_transport_lock_);
542 if (media_transport_payload_type_ != payloadType) {
543 // Payload type is being changed, media_transport_sampling_frequency_,
544 // no longer current.
545 return -1;
546 }
547 sampling_rate_hz = media_transport_sampling_frequency_;
548 channel_id = media_transport_channel_id_;
549 }
Mirko Bonadei1c546052019-02-04 14:50:38 +0100550 MediaTransportEncodedAudioFrame frame(
Niels Möller7d76a312018-10-26 12:57:07 +0200551 /*sampling_rate_hz=*/sampling_rate_hz,
552
553 // TODO(nisse): Timestamp and sample index are the same for all supported
554 // audio codecs except G722. Refactor audio coding module to only use
555 // sample index, and leave translation to RTP time, when needed, for
556 // RTP-specific code.
557 /*starting_sample_index=*/timeStamp,
558
559 // Sample count isn't conveniently available from the AudioCodingModule,
560 // and needs some refactoring to wire up in a good way. For now, left as
561 // zero.
Benjamin Wright17b050f2019-03-13 17:35:46 -0700562 /*samples_per_channel=*/0,
Niels Möller7d76a312018-10-26 12:57:07 +0200563
564 /*sequence_number=*/media_transport_sequence_number_,
565 MediaTransportFrameTypeForWebrtcFrameType(frameType), payloadType,
566 std::vector<uint8_t>(payload.begin(), payload.end()));
567
568 // TODO(nisse): Introduce a MediaTransportSender object bound to a specific
569 // channel id.
570 RTCError rtc_error =
571 media_transport()->SendAudioFrame(channel_id, std::move(frame));
572
573 if (!rtc_error.ok()) {
574 RTC_LOG(LS_ERROR) << "Failed to send frame, rtc_error="
575 << ToString(rtc_error.type()) << ", "
576 << rtc_error.message();
577 return -1;
578 }
579
580 ++media_transport_sequence_number_;
581
582 return 0;
583}
584
Sebastian Jansson977b3352019-03-04 17:43:34 +0100585ChannelSend::ChannelSend(Clock* clock,
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100586 TaskQueueFactory* task_queue_factory,
Niels Möller530ead42018-10-04 14:28:39 +0200587 ProcessThread* module_process_thread,
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700588 const MediaTransportConfig& media_transport_config,
Anton Sukhanov626015d2019-02-04 15:16:06 -0800589 OverheadObserver* overhead_observer,
Niels Möllere9771992018-11-26 10:55:07 +0100590 Transport* rtp_transport,
Niels Möller530ead42018-10-04 14:28:39 +0200591 RtcpRttStats* rtcp_rtt_stats,
Benjamin Wright84583f62018-10-04 14:22:34 -0700592 RtcEventLog* rtc_event_log,
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700593 FrameEncryptorInterface* frame_encryptor,
Johannes Kron9190b822018-10-29 11:22:05 +0100594 const webrtc::CryptoOptions& crypto_options,
Jiawei Ou55718122018-11-09 13:17:39 -0800595 bool extmap_allow_mixed,
Erik Språng4c2c4122019-07-11 15:20:15 +0200596 int rtcp_report_interval_ms,
597 uint32_t ssrc)
Niels Möller530ead42018-10-04 14:28:39 +0200598 : event_log_(rtc_event_log),
599 _timeStamp(0), // This is just an offset, RTP module will add it's own
600 // random offset
Niels Möller530ead42018-10-04 14:28:39 +0200601 _moduleProcessThreadPtr(module_process_thread),
Niels Möller530ead42018-10-04 14:28:39 +0200602 input_mute_(false),
603 previous_frame_muted_(false),
604 _includeAudioLevelIndication(false),
Niels Möller530ead42018-10-04 14:28:39 +0200605 rtcp_observer_(new VoERtcpObserver(this)),
606 feedback_observer_proxy_(new TransportFeedbackProxy()),
Erik Språng59b86542019-06-23 18:24:46 +0200607 rtp_packet_pacer_proxy_(new RtpPacketSenderProxy()),
Sebastian Jansson977b3352019-03-04 17:43:34 +0100608 retransmission_rate_limiter_(
609 new RateLimiter(clock, kMaxRetransmissionWindowMs)),
Niels Möller530ead42018-10-04 14:28:39 +0200610 use_twcc_plr_for_ana_(
611 webrtc::field_trial::FindFullName("UseTwccPlrForAna") == "Enabled"),
Bjorn A Mellemda4f0932019-07-30 08:34:03 -0700612 use_standard_bytes_stats_(
613 webrtc::field_trial::IsEnabled(kUseStandardBytesStats)),
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700614 media_transport_config_(media_transport_config),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700615 frame_encryptor_(frame_encryptor),
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100616 crypto_options_(crypto_options),
617 encoder_queue_(task_queue_factory->CreateTaskQueue(
618 "AudioEncoder",
619 TaskQueueFactory::Priority::NORMAL)) {
Niels Möller530ead42018-10-04 14:28:39 +0200620 RTC_DCHECK(module_process_thread);
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200621 module_process_thread_checker_.Detach();
Niels Möllerdced9f62018-11-19 10:27:07 +0100622
Niels Möller530ead42018-10-04 14:28:39 +0200623 audio_coding_.reset(AudioCodingModule::Create(AudioCodingModule::Config()));
624
625 RtpRtcp::Configuration configuration;
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800626
627 // We gradually remove codepaths that depend on RTP when using media
628 // transport. All of this logic should be moved to the future
629 // RTPMediaTransport. In this case it means that overhead and bandwidth
630 // observers should not be called when using media transport.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700631 if (!media_transport_config.media_transport) {
Anton Sukhanov626015d2019-02-04 15:16:06 -0800632 configuration.overhead_observer = overhead_observer;
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800633 configuration.bandwidth_callback = rtcp_observer_.get();
634 configuration.transport_feedback_callback = feedback_observer_proxy_.get();
635 }
636
Sebastian Jansson977b3352019-03-04 17:43:34 +0100637 configuration.clock = clock;
Niels Möller530ead42018-10-04 14:28:39 +0200638 configuration.audio = true;
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100639 configuration.clock = Clock::GetRealTimeClock();
Fredrik Solenberg3d2ed192018-12-18 09:18:33 +0100640 configuration.outgoing_transport = rtp_transport;
Niels Möller530ead42018-10-04 14:28:39 +0200641
Erik Språng59b86542019-06-23 18:24:46 +0200642 configuration.paced_sender = rtp_packet_pacer_proxy_.get();
Niels Möller530ead42018-10-04 14:28:39 +0200643
644 configuration.event_log = event_log_;
645 configuration.rtt_stats = rtcp_rtt_stats;
646 configuration.retransmission_rate_limiter =
647 retransmission_rate_limiter_.get();
Johannes Kron9190b822018-10-29 11:22:05 +0100648 configuration.extmap_allow_mixed = extmap_allow_mixed;
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800649 configuration.rtcp_report_interval_ms = rtcp_report_interval_ms;
Niels Möller530ead42018-10-04 14:28:39 +0200650
Erik Språng54d5d2c2019-08-20 17:22:36 +0200651 configuration.local_media_ssrc = ssrc;
Erik Språng70efdde2019-08-21 13:36:20 +0200652 if (media_transport_config_.media_transport) {
653 rtc::CritScope cs(&media_transport_lock_);
654 media_transport_channel_id_ = ssrc;
655 }
Erik Språng4c2c4122019-07-11 15:20:15 +0200656
Danil Chapovalovc44f6cc2019-03-06 11:31:09 +0100657 _rtpRtcpModule = RtpRtcp::Create(configuration);
Niels Möller530ead42018-10-04 14:28:39 +0200658 _rtpRtcpModule->SetSendingMediaStatus(false);
Niels Möller530ead42018-10-04 14:28:39 +0200659
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200660 rtp_sender_audio_ = std::make_unique<RTPSenderAudio>(
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100661 configuration.clock, _rtpRtcpModule->RtpSender());
662
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800663 // We want to invoke the 'TargetRateObserver' and |OnOverheadChanged|
664 // callbacks after the audio_coding_ is fully initialized.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700665 if (media_transport_config.media_transport) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800666 RTC_DLOG(LS_INFO) << "Setting media_transport_ rate observers.";
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700667 media_transport_config.media_transport->AddTargetTransferRateObserver(this);
668 media_transport_config.media_transport->SetAudioOverheadObserver(
669 overhead_observer);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800670 } else {
671 RTC_DLOG(LS_INFO) << "Not setting media_transport_ rate observers.";
672 }
673
Niels Möller530ead42018-10-04 14:28:39 +0200674 _moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get(), RTC_FROM_HERE);
675
Niels Möller530ead42018-10-04 14:28:39 +0200676 // Ensure that RTCP is enabled by default for the created channel.
Niels Möller530ead42018-10-04 14:28:39 +0200677 _rtpRtcpModule->SetRTCPStatus(RtcpMode::kCompound);
678
Fredrik Solenbergeb134842018-11-19 14:13:15 +0100679 int error = audio_coding_->RegisterTransportCallback(this);
Niels Möller530ead42018-10-04 14:28:39 +0200680 RTC_DCHECK_EQ(0, error);
681}
682
Fredrik Solenberg645a3af2018-11-16 12:51:15 +0100683ChannelSend::~ChannelSend() {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200684 RTC_DCHECK(construction_thread_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +0200685
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700686 if (media_transport_config_.media_transport) {
687 media_transport_config_.media_transport->RemoveTargetTransferRateObserver(
688 this);
689 media_transport_config_.media_transport->SetAudioOverheadObserver(nullptr);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800690 }
691
Niels Möller530ead42018-10-04 14:28:39 +0200692 StopSend();
Niels Möller530ead42018-10-04 14:28:39 +0200693 int error = audio_coding_->RegisterTransportCallback(NULL);
694 RTC_DCHECK_EQ(0, error);
695
Niels Möller530ead42018-10-04 14:28:39 +0200696 if (_moduleProcessThreadPtr)
697 _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get());
Niels Möller530ead42018-10-04 14:28:39 +0200698}
699
Niels Möller26815232018-11-16 09:32:40 +0100700void ChannelSend::StartSend() {
Niels Möller26e88b02018-11-19 15:08:13 +0100701 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Fredrik Solenbergeb134842018-11-19 14:13:15 +0100702 RTC_DCHECK(!sending_);
703 sending_ = true;
Niels Möller530ead42018-10-04 14:28:39 +0200704
Niels Möller530ead42018-10-04 14:28:39 +0200705 _rtpRtcpModule->SetSendingMediaStatus(true);
Niels Möller26815232018-11-16 09:32:40 +0100706 int ret = _rtpRtcpModule->SetSendingStatus(true);
707 RTC_DCHECK_EQ(0, ret);
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100708 // It is now OK to start processing on the encoder task queue.
709 encoder_queue_.PostTask([this] {
710 RTC_DCHECK_RUN_ON(&encoder_queue_);
Niels Möller530ead42018-10-04 14:28:39 +0200711 encoder_queue_is_active_ = true;
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100712 });
Niels Möller530ead42018-10-04 14:28:39 +0200713}
714
715void ChannelSend::StopSend() {
Niels Möller26e88b02018-11-19 15:08:13 +0100716 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Fredrik Solenbergeb134842018-11-19 14:13:15 +0100717 if (!sending_) {
Niels Möller530ead42018-10-04 14:28:39 +0200718 return;
719 }
Fredrik Solenbergeb134842018-11-19 14:13:15 +0100720 sending_ = false;
Niels Möller530ead42018-10-04 14:28:39 +0200721
Niels Möllerc572ff32018-11-07 08:43:50 +0100722 rtc::Event flush;
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100723 encoder_queue_.PostTask([this, &flush]() {
724 RTC_DCHECK_RUN_ON(&encoder_queue_);
Niels Möller530ead42018-10-04 14:28:39 +0200725 encoder_queue_is_active_ = false;
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100726 flush.Set();
727 });
Niels Möller530ead42018-10-04 14:28:39 +0200728 flush.Wait(rtc::Event::kForever);
729
Niels Möller530ead42018-10-04 14:28:39 +0200730 // Reset sending SSRC and sequence number and triggers direct transmission
731 // of RTCP BYE
732 if (_rtpRtcpModule->SetSendingStatus(false) == -1) {
733 RTC_DLOG(LS_ERROR) << "StartSend() RTP/RTCP failed to stop sending";
734 }
735 _rtpRtcpModule->SetSendingMediaStatus(false);
736}
737
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100738void ChannelSend::SetEncoder(int payload_type,
Niels Möller530ead42018-10-04 14:28:39 +0200739 std::unique_ptr<AudioEncoder> encoder) {
Niels Möller26e88b02018-11-19 15:08:13 +0100740 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200741 RTC_DCHECK_GE(payload_type, 0);
742 RTC_DCHECK_LE(payload_type, 127);
Niels Möller530ead42018-10-04 14:28:39 +0200743
744 // The RTP/RTCP module needs to know the RTP timestamp rate (i.e. clockrate)
745 // as well as some other things, so we collect this info and send it along.
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100746 _rtpRtcpModule->RegisterSendPayloadFrequency(payload_type,
747 encoder->RtpTimestampRateHz());
748 rtp_sender_audio_->RegisterAudioPayload("audio", payload_type,
749 encoder->RtpTimestampRateHz(),
750 encoder->NumChannels(), 0);
Niels Möller530ead42018-10-04 14:28:39 +0200751
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700752 if (media_transport_config_.media_transport) {
Niels Möller7d76a312018-10-26 12:57:07 +0200753 rtc::CritScope cs(&media_transport_lock_);
754 media_transport_payload_type_ = payload_type;
755 // TODO(nisse): Currently broken for G722, since timestamps passed through
756 // encoder use RTP clock rather than sample count, and they differ for G722.
757 media_transport_sampling_frequency_ = encoder->RtpTimestampRateHz();
758 }
Niels Möller530ead42018-10-04 14:28:39 +0200759 audio_coding_->SetEncoder(std::move(encoder));
Niels Möller530ead42018-10-04 14:28:39 +0200760}
761
762void ChannelSend::ModifyEncoder(
763 rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)> modifier) {
Anton Sukhanov626015d2019-02-04 15:16:06 -0800764 // This method can be called on the worker thread, module process thread
765 // or network thread. Audio coding is thread safe, so we do not need to
766 // enforce the calling thread.
Niels Möller530ead42018-10-04 14:28:39 +0200767 audio_coding_->ModifyEncoder(modifier);
768}
769
Sebastian Jansson14a7cf92019-02-13 15:11:42 +0100770void ChannelSend::CallEncoder(rtc::FunctionView<void(AudioEncoder*)> modifier) {
771 ModifyEncoder([modifier](std::unique_ptr<AudioEncoder>* encoder_ptr) {
772 if (*encoder_ptr) {
773 modifier(encoder_ptr->get());
774 } else {
775 RTC_DLOG(LS_WARNING) << "Trying to call unset encoder.";
776 }
777 });
778}
779
Sebastian Jansson254d8692018-11-21 19:19:00 +0100780void ChannelSend::OnBitrateAllocation(BitrateAllocationUpdate update) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100781 // This method can be called on the worker thread, module process thread
782 // or on a TaskQueue via VideoSendStreamImpl::OnEncoderConfigurationChanged.
783 // TODO(solenberg): Figure out a good way to check this or enforce calling
784 // rules.
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200785 // RTC_DCHECK(worker_thread_checker_.IsCurrent() ||
786 // module_process_thread_checker_.IsCurrent());
Piotr (Peter) Slatala1eebec92018-11-16 09:03:35 -0800787 rtc::CritScope lock(&bitrate_crit_section_);
Niels Möllerdced9f62018-11-19 10:27:07 +0100788
Sebastian Jansson14a7cf92019-02-13 15:11:42 +0100789 CallEncoder([&](AudioEncoder* encoder) {
790 encoder->OnReceivedUplinkAllocation(update);
Niels Möller530ead42018-10-04 14:28:39 +0200791 });
Sebastian Jansson254d8692018-11-21 19:19:00 +0100792 retransmission_rate_limiter_->SetMaxRate(update.target_bitrate.bps());
793 configured_bitrate_bps_ = update.target_bitrate.bps();
Sebastian Jansson359d60a2018-10-25 16:22:02 +0200794}
795
Niels Möllerdced9f62018-11-19 10:27:07 +0100796int ChannelSend::GetBitrate() const {
Piotr (Peter) Slatala1eebec92018-11-16 09:03:35 -0800797 rtc::CritScope lock(&bitrate_crit_section_);
Sebastian Jansson359d60a2018-10-25 16:22:02 +0200798 return configured_bitrate_bps_;
Niels Möller530ead42018-10-04 14:28:39 +0200799}
800
801void ChannelSend::OnTwccBasedUplinkPacketLossRate(float packet_loss_rate) {
Niels Möller26e88b02018-11-19 15:08:13 +0100802 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200803 if (!use_twcc_plr_for_ana_)
804 return;
Sebastian Jansson14a7cf92019-02-13 15:11:42 +0100805 CallEncoder([&](AudioEncoder* encoder) {
806 encoder->OnReceivedUplinkPacketLossFraction(packet_loss_rate);
Niels Möller530ead42018-10-04 14:28:39 +0200807 });
808}
809
810void ChannelSend::OnRecoverableUplinkPacketLossRate(
811 float recoverable_packet_loss_rate) {
Niels Möller26e88b02018-11-19 15:08:13 +0100812 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Sebastian Jansson14a7cf92019-02-13 15:11:42 +0100813 CallEncoder([&](AudioEncoder* encoder) {
814 encoder->OnReceivedUplinkRecoverablePacketLossFraction(
815 recoverable_packet_loss_rate);
Niels Möller530ead42018-10-04 14:28:39 +0200816 });
817}
818
819void ChannelSend::OnUplinkPacketLossRate(float packet_loss_rate) {
820 if (use_twcc_plr_for_ana_)
821 return;
Sebastian Jansson14a7cf92019-02-13 15:11:42 +0100822 CallEncoder([&](AudioEncoder* encoder) {
823 encoder->OnReceivedUplinkPacketLossFraction(packet_loss_rate);
Niels Möller530ead42018-10-04 14:28:39 +0200824 });
825}
826
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100827void ChannelSend::ReceivedRTCPPacket(const uint8_t* data, size_t length) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100828 // May be called on either worker thread or network thread.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700829 if (media_transport_config_.media_transport) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800830 // Ignore RTCP packets while media transport is used.
831 // Those packets should not arrive, but we are seeing occasional packets.
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100832 return;
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800833 }
834
Niels Möller530ead42018-10-04 14:28:39 +0200835 // Deliver RTCP packet to RTP/RTCP module for parsing
836 _rtpRtcpModule->IncomingRtcpPacket(data, length);
837
838 int64_t rtt = GetRTT();
839 if (rtt == 0) {
840 // Waiting for valid RTT.
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100841 return;
Niels Möller530ead42018-10-04 14:28:39 +0200842 }
843
844 int64_t nack_window_ms = rtt;
845 if (nack_window_ms < kMinRetransmissionWindowMs) {
846 nack_window_ms = kMinRetransmissionWindowMs;
847 } else if (nack_window_ms > kMaxRetransmissionWindowMs) {
848 nack_window_ms = kMaxRetransmissionWindowMs;
849 }
850 retransmission_rate_limiter_->SetWindowSize(nack_window_ms);
851
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800852 OnReceivedRtt(rtt);
Niels Möller530ead42018-10-04 14:28:39 +0200853}
854
855void ChannelSend::SetInputMute(bool enable) {
Niels Möller26e88b02018-11-19 15:08:13 +0100856 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200857 rtc::CritScope cs(&volume_settings_critsect_);
858 input_mute_ = enable;
859}
860
861bool ChannelSend::InputMute() const {
862 rtc::CritScope cs(&volume_settings_critsect_);
863 return input_mute_;
864}
865
Niels Möller26815232018-11-16 09:32:40 +0100866bool ChannelSend::SendTelephoneEventOutband(int event, int duration_ms) {
Niels Möller26e88b02018-11-19 15:08:13 +0100867 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200868 RTC_DCHECK_LE(0, event);
869 RTC_DCHECK_GE(255, event);
870 RTC_DCHECK_LE(0, duration_ms);
871 RTC_DCHECK_GE(65535, duration_ms);
Fredrik Solenbergeb134842018-11-19 14:13:15 +0100872 if (!sending_) {
Niels Möller26815232018-11-16 09:32:40 +0100873 return false;
Niels Möller530ead42018-10-04 14:28:39 +0200874 }
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100875 if (rtp_sender_audio_->SendTelephoneEvent(
Niels Möller530ead42018-10-04 14:28:39 +0200876 event, duration_ms, kTelephoneEventAttenuationdB) != 0) {
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100877 RTC_DLOG(LS_ERROR) << "SendTelephoneEvent() failed to send event";
Niels Möller26815232018-11-16 09:32:40 +0100878 return false;
Niels Möller530ead42018-10-04 14:28:39 +0200879 }
Niels Möller26815232018-11-16 09:32:40 +0100880 return true;
Niels Möller530ead42018-10-04 14:28:39 +0200881}
882
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100883void ChannelSend::RegisterCngPayloadType(int payload_type,
884 int payload_frequency) {
885 _rtpRtcpModule->RegisterSendPayloadFrequency(payload_type, payload_frequency);
886 rtp_sender_audio_->RegisterAudioPayload("CN", payload_type, payload_frequency,
887 1, 0);
888}
889
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100890void ChannelSend::SetSendTelephoneEventPayloadType(int payload_type,
Niels Möller26815232018-11-16 09:32:40 +0100891 int payload_frequency) {
Niels Möller26e88b02018-11-19 15:08:13 +0100892 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200893 RTC_DCHECK_LE(0, payload_type);
894 RTC_DCHECK_GE(127, payload_type);
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100895 _rtpRtcpModule->RegisterSendPayloadFrequency(payload_type, payload_frequency);
896 rtp_sender_audio_->RegisterAudioPayload("telephone-event", payload_type,
897 payload_frequency, 0, 0);
Niels Möller530ead42018-10-04 14:28:39 +0200898}
899
Amit Hilbuch77938e62018-12-21 09:23:38 -0800900void ChannelSend::SetRid(const std::string& rid,
901 int extension_id,
902 int repaired_extension_id) {
903 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
904 if (extension_id != 0) {
905 int ret = SetSendRtpHeaderExtension(!rid.empty(), kRtpExtensionRtpStreamId,
906 extension_id);
907 RTC_DCHECK_EQ(0, ret);
908 }
909 if (repaired_extension_id != 0) {
910 int ret = SetSendRtpHeaderExtension(!rid.empty(), kRtpExtensionRtpStreamId,
911 repaired_extension_id);
912 RTC_DCHECK_EQ(0, ret);
913 }
914 _rtpRtcpModule->SetRid(rid);
915}
916
Niels Möller530ead42018-10-04 14:28:39 +0200917void ChannelSend::SetMid(const std::string& mid, int extension_id) {
Niels Möller26e88b02018-11-19 15:08:13 +0100918 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200919 int ret = SetSendRtpHeaderExtension(true, kRtpExtensionMid, extension_id);
920 RTC_DCHECK_EQ(0, ret);
921 _rtpRtcpModule->SetMid(mid);
922}
923
Johannes Kron9190b822018-10-29 11:22:05 +0100924void ChannelSend::SetExtmapAllowMixed(bool extmap_allow_mixed) {
Niels Möller26e88b02018-11-19 15:08:13 +0100925 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Johannes Kron9190b822018-10-29 11:22:05 +0100926 _rtpRtcpModule->SetExtmapAllowMixed(extmap_allow_mixed);
927}
928
Niels Möller26815232018-11-16 09:32:40 +0100929void ChannelSend::SetSendAudioLevelIndicationStatus(bool enable, int id) {
Niels Möller26e88b02018-11-19 15:08:13 +0100930 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200931 _includeAudioLevelIndication = enable;
Niels Möller26815232018-11-16 09:32:40 +0100932 int ret = SetSendRtpHeaderExtension(enable, kRtpExtensionAudioLevel, id);
933 RTC_DCHECK_EQ(0, ret);
Niels Möller530ead42018-10-04 14:28:39 +0200934}
935
936void ChannelSend::EnableSendTransportSequenceNumber(int id) {
Niels Möller26e88b02018-11-19 15:08:13 +0100937 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200938 int ret =
939 SetSendRtpHeaderExtension(true, kRtpExtensionTransportSequenceNumber, id);
940 RTC_DCHECK_EQ(0, ret);
941}
942
943void ChannelSend::RegisterSenderCongestionControlObjects(
944 RtpTransportControllerSendInterface* transport,
945 RtcpBandwidthObserver* bandwidth_observer) {
Niels Möller26e88b02018-11-19 15:08:13 +0100946 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Erik Språngaa59eca2019-07-24 14:52:55 +0200947 RtpPacketSender* rtp_packet_pacer = transport->packet_sender();
Niels Möller530ead42018-10-04 14:28:39 +0200948 TransportFeedbackObserver* transport_feedback_observer =
949 transport->transport_feedback_observer();
950 PacketRouter* packet_router = transport->packet_router();
951
Erik Språng59b86542019-06-23 18:24:46 +0200952 RTC_DCHECK(rtp_packet_pacer);
Niels Möller530ead42018-10-04 14:28:39 +0200953 RTC_DCHECK(transport_feedback_observer);
954 RTC_DCHECK(packet_router);
955 RTC_DCHECK(!packet_router_);
956 rtcp_observer_->SetBandwidthObserver(bandwidth_observer);
957 feedback_observer_proxy_->SetTransportFeedbackObserver(
958 transport_feedback_observer);
Erik Språng59b86542019-06-23 18:24:46 +0200959 rtp_packet_pacer_proxy_->SetPacketPacer(rtp_packet_pacer);
Niels Möller530ead42018-10-04 14:28:39 +0200960 _rtpRtcpModule->SetStorePacketsStatus(true, 600);
961 constexpr bool remb_candidate = false;
962 packet_router->AddSendRtpModule(_rtpRtcpModule.get(), remb_candidate);
963 packet_router_ = packet_router;
964}
965
966void ChannelSend::ResetSenderCongestionControlObjects() {
Niels Möller26e88b02018-11-19 15:08:13 +0100967 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200968 RTC_DCHECK(packet_router_);
969 _rtpRtcpModule->SetStorePacketsStatus(false, 600);
970 rtcp_observer_->SetBandwidthObserver(nullptr);
971 feedback_observer_proxy_->SetTransportFeedbackObserver(nullptr);
Niels Möller530ead42018-10-04 14:28:39 +0200972 packet_router_->RemoveSendRtpModule(_rtpRtcpModule.get());
973 packet_router_ = nullptr;
Erik Språng59b86542019-06-23 18:24:46 +0200974 rtp_packet_pacer_proxy_->SetPacketPacer(nullptr);
Niels Möller530ead42018-10-04 14:28:39 +0200975}
976
Niels Möller26815232018-11-16 09:32:40 +0100977void ChannelSend::SetRTCP_CNAME(absl::string_view c_name) {
Niels Möller26e88b02018-11-19 15:08:13 +0100978 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller26815232018-11-16 09:32:40 +0100979 // Note: SetCNAME() accepts a c string of length at most 255.
980 const std::string c_name_limited(c_name.substr(0, 255));
981 int ret = _rtpRtcpModule->SetCNAME(c_name_limited.c_str()) != 0;
982 RTC_DCHECK_EQ(0, ret) << "SetRTCP_CNAME() failed to set RTCP CNAME";
Niels Möller530ead42018-10-04 14:28:39 +0200983}
984
Niels Möller26815232018-11-16 09:32:40 +0100985std::vector<ReportBlock> ChannelSend::GetRemoteRTCPReportBlocks() const {
Niels Möller26e88b02018-11-19 15:08:13 +0100986 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200987 // Get the report blocks from the latest received RTCP Sender or Receiver
988 // Report. Each element in the vector contains the sender's SSRC and a
989 // report block according to RFC 3550.
990 std::vector<RTCPReportBlock> rtcp_report_blocks;
Niels Möller530ead42018-10-04 14:28:39 +0200991
Niels Möller26815232018-11-16 09:32:40 +0100992 int ret = _rtpRtcpModule->RemoteRTCPStat(&rtcp_report_blocks);
993 RTC_DCHECK_EQ(0, ret);
994
995 std::vector<ReportBlock> report_blocks;
Niels Möller530ead42018-10-04 14:28:39 +0200996
997 std::vector<RTCPReportBlock>::const_iterator it = rtcp_report_blocks.begin();
998 for (; it != rtcp_report_blocks.end(); ++it) {
999 ReportBlock report_block;
1000 report_block.sender_SSRC = it->sender_ssrc;
1001 report_block.source_SSRC = it->source_ssrc;
1002 report_block.fraction_lost = it->fraction_lost;
1003 report_block.cumulative_num_packets_lost = it->packets_lost;
1004 report_block.extended_highest_sequence_number =
1005 it->extended_highest_sequence_number;
1006 report_block.interarrival_jitter = it->jitter;
1007 report_block.last_SR_timestamp = it->last_sender_report_timestamp;
1008 report_block.delay_since_last_SR = it->delay_since_last_sender_report;
Niels Möller26815232018-11-16 09:32:40 +01001009 report_blocks.push_back(report_block);
Niels Möller530ead42018-10-04 14:28:39 +02001010 }
Niels Möller26815232018-11-16 09:32:40 +01001011 return report_blocks;
Niels Möller530ead42018-10-04 14:28:39 +02001012}
1013
Niels Möller26815232018-11-16 09:32:40 +01001014CallSendStatistics ChannelSend::GetRTCPStatistics() const {
Niels Möller26e88b02018-11-19 15:08:13 +01001015 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller26815232018-11-16 09:32:40 +01001016 CallSendStatistics stats = {0};
Niels Möller530ead42018-10-04 14:28:39 +02001017 stats.rttMs = GetRTT();
1018
Henrik Boströmcf96e0f2019-04-17 13:51:53 +02001019 StreamDataCounters rtp_stats;
1020 StreamDataCounters rtx_stats;
1021 _rtpRtcpModule->GetSendStreamDataCounters(&rtp_stats, &rtx_stats);
Bjorn A Mellemda4f0932019-07-30 08:34:03 -07001022 if (use_standard_bytes_stats_) {
1023 stats.bytesSent = rtp_stats.transmitted.payload_bytes +
1024 rtx_stats.transmitted.payload_bytes;
1025 } else {
1026 stats.bytesSent = rtp_stats.transmitted.payload_bytes +
1027 rtp_stats.transmitted.padding_bytes +
1028 rtp_stats.transmitted.header_bytes +
1029 rtx_stats.transmitted.payload_bytes +
1030 rtx_stats.transmitted.padding_bytes +
1031 rtx_stats.transmitted.header_bytes;
1032 }
Henrik Boströmcf96e0f2019-04-17 13:51:53 +02001033 // TODO(https://crbug.com/webrtc/10555): RTX retransmissions should show up in
1034 // separate outbound-rtp stream objects.
1035 stats.retransmitted_bytes_sent = rtp_stats.retransmitted.payload_bytes;
1036 stats.packetsSent =
1037 rtp_stats.transmitted.packets + rtx_stats.transmitted.packets;
1038 stats.retransmitted_packets_sent = rtp_stats.retransmitted.packets;
Henrik Boström6e436d12019-05-27 12:19:33 +02001039 stats.report_block_datas = _rtpRtcpModule->GetLatestReportBlockData();
Niels Möller530ead42018-10-04 14:28:39 +02001040
Niels Möller26815232018-11-16 09:32:40 +01001041 return stats;
Niels Möller530ead42018-10-04 14:28:39 +02001042}
1043
Niels Möller530ead42018-10-04 14:28:39 +02001044void ChannelSend::ProcessAndEncodeAudio(
1045 std::unique_ptr<AudioFrame> audio_frame) {
Niels Möllerdced9f62018-11-19 10:27:07 +01001046 RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_);
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001047 RTC_DCHECK_GT(audio_frame->samples_per_channel_, 0);
1048 RTC_DCHECK_LE(audio_frame->num_channels_, 8);
1049
Niels Möller530ead42018-10-04 14:28:39 +02001050 // Profile time between when the audio frame is added to the task queue and
1051 // when the task is actually executed.
1052 audio_frame->UpdateProfileTimeStamp();
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001053 encoder_queue_.PostTask(
1054 [this, audio_frame = std::move(audio_frame)]() mutable {
1055 RTC_DCHECK_RUN_ON(&encoder_queue_);
1056 if (!encoder_queue_is_active_) {
1057 return;
1058 }
1059 // Measure time between when the audio frame is added to the task queue
1060 // and when the task is actually executed. Goal is to keep track of
1061 // unwanted extra latency added by the task queue.
1062 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Audio.EncodingTaskQueueLatencyMs",
1063 audio_frame->ElapsedProfileTimeMs());
Niels Möller530ead42018-10-04 14:28:39 +02001064
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001065 bool is_muted = InputMute();
1066 AudioFrameOperations::Mute(audio_frame.get(), previous_frame_muted_,
1067 is_muted);
Niels Möller530ead42018-10-04 14:28:39 +02001068
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001069 if (_includeAudioLevelIndication) {
1070 size_t length =
1071 audio_frame->samples_per_channel_ * audio_frame->num_channels_;
1072 RTC_CHECK_LE(length, AudioFrame::kMaxDataSizeBytes);
1073 if (is_muted && previous_frame_muted_) {
1074 rms_level_.AnalyzeMuted(length);
1075 } else {
1076 rms_level_.Analyze(
1077 rtc::ArrayView<const int16_t>(audio_frame->data(), length));
1078 }
1079 }
1080 previous_frame_muted_ = is_muted;
Niels Möller530ead42018-10-04 14:28:39 +02001081
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001082 // Add 10ms of raw (PCM) audio data to the encoder @ 32kHz.
Niels Möller530ead42018-10-04 14:28:39 +02001083
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001084 // The ACM resamples internally.
1085 audio_frame->timestamp_ = _timeStamp;
1086 // This call will trigger AudioPacketizationCallback::SendData if
1087 // encoding is done and payload is ready for packetization and
1088 // transmission. Otherwise, it will return without invoking the
1089 // callback.
1090 if (audio_coding_->Add10MsData(*audio_frame) < 0) {
1091 RTC_DLOG(LS_ERROR) << "ACM::Add10MsData() failed.";
1092 return;
1093 }
Niels Möller530ead42018-10-04 14:28:39 +02001094
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001095 _timeStamp += static_cast<uint32_t>(audio_frame->samples_per_channel_);
1096 });
Niels Möller530ead42018-10-04 14:28:39 +02001097}
1098
Niels Möller530ead42018-10-04 14:28:39 +02001099ANAStats ChannelSend::GetANAStatistics() const {
Niels Möller26e88b02018-11-19 15:08:13 +01001100 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +02001101 return audio_coding_->GetANAStats();
1102}
1103
1104RtpRtcp* ChannelSend::GetRtpRtcp() const {
Sebastian Janssonc01367d2019-04-08 15:20:44 +02001105 RTC_DCHECK(module_process_thread_checker_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +02001106 return _rtpRtcpModule.get();
1107}
1108
1109int ChannelSend::SetSendRtpHeaderExtension(bool enable,
1110 RTPExtensionType type,
Niels Möller26815232018-11-16 09:32:40 +01001111 int id) {
Niels Möller530ead42018-10-04 14:28:39 +02001112 int error = 0;
1113 _rtpRtcpModule->DeregisterSendRtpHeaderExtension(type);
1114 if (enable) {
Niels Möller26815232018-11-16 09:32:40 +01001115 // TODO(nisse): RtpRtcp::RegisterSendRtpHeaderExtension to take an int
1116 // argument. Currently it wants an uint8_t.
1117 error = _rtpRtcpModule->RegisterSendRtpHeaderExtension(
1118 type, rtc::dchecked_cast<uint8_t>(id));
Niels Möller530ead42018-10-04 14:28:39 +02001119 }
1120 return error;
1121}
1122
Niels Möller530ead42018-10-04 14:28:39 +02001123int64_t ChannelSend::GetRTT() const {
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001124 if (media_transport_config_.media_transport) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -08001125 // GetRTT is generally used in the RTCP codepath, where media transport is
1126 // not present and so it shouldn't be needed. But it's also invoked in
1127 // 'GetStats' method, and for now returning media transport RTT here gives
1128 // us "free" rtt stats for media transport.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001129 auto target_rate =
1130 media_transport_config_.media_transport->GetLatestTargetTransferRate();
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -08001131 if (target_rate.has_value()) {
1132 return target_rate.value().network_estimate.round_trip_time.ms();
1133 }
1134
1135 return 0;
1136 }
Niels Möller530ead42018-10-04 14:28:39 +02001137 std::vector<RTCPReportBlock> report_blocks;
1138 _rtpRtcpModule->RemoteRTCPStat(&report_blocks);
1139
1140 if (report_blocks.empty()) {
1141 return 0;
1142 }
1143
1144 int64_t rtt = 0;
1145 int64_t avg_rtt = 0;
1146 int64_t max_rtt = 0;
1147 int64_t min_rtt = 0;
1148 // We don't know in advance the remote ssrc used by the other end's receiver
1149 // reports, so use the SSRC of the first report block for calculating the RTT.
1150 if (_rtpRtcpModule->RTT(report_blocks[0].sender_ssrc, &rtt, &avg_rtt,
1151 &min_rtt, &max_rtt) != 0) {
1152 return 0;
1153 }
1154 return rtt;
1155}
1156
Benjamin Wright78410ad2018-10-25 09:52:57 -07001157void ChannelSend::SetFrameEncryptor(
1158 rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) {
Niels Möller26e88b02018-11-19 15:08:13 +01001159 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Sebastian Jansson44dd9f22019-03-08 14:50:30 +01001160 encoder_queue_.PostTask([this, frame_encryptor]() mutable {
1161 RTC_DCHECK_RUN_ON(&encoder_queue_);
Sebastian Jansson7949f212019-03-05 13:41:48 +00001162 frame_encryptor_ = std::move(frame_encryptor);
Sebastian Jansson44dd9f22019-03-08 14:50:30 +01001163 });
Benjamin Wright84583f62018-10-04 14:22:34 -07001164}
1165
Anton Sukhanov626015d2019-02-04 15:16:06 -08001166// TODO(sukhanov): Consider moving TargetTransferRate observer to
1167// AudioSendStream. Since AudioSendStream owns encoder and configures ANA, it
1168// makes sense to consolidate all rate (and overhead) calculation there.
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -08001169void ChannelSend::OnTargetTransferRate(TargetTransferRate rate) {
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001170 RTC_DCHECK(media_transport_config_.media_transport);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -08001171 OnReceivedRtt(rate.network_estimate.round_trip_time.ms());
1172}
1173
1174void ChannelSend::OnReceivedRtt(int64_t rtt_ms) {
1175 // Invoke audio encoders OnReceivedRtt().
Sebastian Jansson14a7cf92019-02-13 15:11:42 +01001176 CallEncoder(
1177 [rtt_ms](AudioEncoder* encoder) { encoder->OnReceivedRtt(rtt_ms); });
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -08001178}
1179
Niels Möllerdced9f62018-11-19 10:27:07 +01001180} // namespace
1181
1182std::unique_ptr<ChannelSendInterface> CreateChannelSend(
Sebastian Jansson977b3352019-03-04 17:43:34 +01001183 Clock* clock,
Sebastian Jansson44dd9f22019-03-08 14:50:30 +01001184 TaskQueueFactory* task_queue_factory,
Niels Möllerdced9f62018-11-19 10:27:07 +01001185 ProcessThread* module_process_thread,
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001186 const MediaTransportConfig& media_transport_config,
Anton Sukhanov626015d2019-02-04 15:16:06 -08001187 OverheadObserver* overhead_observer,
Niels Möllere9771992018-11-26 10:55:07 +01001188 Transport* rtp_transport,
Niels Möllerdced9f62018-11-19 10:27:07 +01001189 RtcpRttStats* rtcp_rtt_stats,
1190 RtcEventLog* rtc_event_log,
1191 FrameEncryptorInterface* frame_encryptor,
1192 const webrtc::CryptoOptions& crypto_options,
1193 bool extmap_allow_mixed,
Erik Språng4c2c4122019-07-11 15:20:15 +02001194 int rtcp_report_interval_ms,
1195 uint32_t ssrc) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001196 return std::make_unique<ChannelSend>(
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001197 clock, task_queue_factory, module_process_thread, media_transport_config,
Sebastian Jansson977b3352019-03-04 17:43:34 +01001198 overhead_observer, rtp_transport, rtcp_rtt_stats, rtc_event_log,
1199 frame_encryptor, crypto_options, extmap_allow_mixed,
Erik Språng4c2c4122019-07-11 15:20:15 +02001200 rtcp_report_interval_ms, ssrc);
Niels Möllerdced9f62018-11-19 10:27:07 +01001201}
1202
Niels Möller530ead42018-10-04 14:28:39 +02001203} // namespace voe
1204} // namespace webrtc