blob: 184ea4145899127908ab6d047530874a1ee7cc3e [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
Niels Möller7d76a312018-10-26 12:57:07 +020055MediaTransportEncodedAudioFrame::FrameType
Niels Möller87e2d782019-03-07 10:18:23 +010056MediaTransportFrameTypeForWebrtcFrameType(webrtc::AudioFrameType frame_type) {
Niels Möller7d76a312018-10-26 12:57:07 +020057 switch (frame_type) {
Niels Möllerc936cb62019-03-19 14:10:16 +010058 case AudioFrameType::kAudioFrameSpeech:
Niels Möller7d76a312018-10-26 12:57:07 +020059 return MediaTransportEncodedAudioFrame::FrameType::kSpeech;
60 break;
61
Niels Möllerc936cb62019-03-19 14:10:16 +010062 case AudioFrameType::kAudioFrameCN:
Niels Möller7d76a312018-10-26 12:57:07 +020063 return MediaTransportEncodedAudioFrame::FrameType::
64 kDiscontinuousTransmission;
65 break;
66
67 default:
Niels Möllerc936cb62019-03-19 14:10:16 +010068 RTC_CHECK(false) << "Unexpected frame type="
69 << static_cast<int>(frame_type);
Niels Möller7d76a312018-10-26 12:57:07 +020070 break;
71 }
72}
73
Niels Möllerdced9f62018-11-19 10:27:07 +010074class RtpPacketSenderProxy;
75class TransportFeedbackProxy;
76class TransportSequenceNumberProxy;
77class VoERtcpObserver;
78
Benjamin Wright17b050f2019-03-13 17:35:46 -070079class ChannelSend : public ChannelSendInterface,
80 public AudioPacketizationCallback, // receive encoded
81 // packets from the ACM
82 public TargetTransferRateObserver {
Niels Möllerdced9f62018-11-19 10:27:07 +010083 public:
84 // TODO(nisse): Make OnUplinkPacketLossRate public, and delete friend
85 // declaration.
86 friend class VoERtcpObserver;
87
Sebastian Jansson977b3352019-03-04 17:43:34 +010088 ChannelSend(Clock* clock,
Sebastian Jansson44dd9f22019-03-08 14:50:30 +010089 TaskQueueFactory* task_queue_factory,
Niels Möllerdced9f62018-11-19 10:27:07 +010090 ProcessThread* module_process_thread,
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070091 const MediaTransportConfig& media_transport_config,
Anton Sukhanov626015d2019-02-04 15:16:06 -080092 OverheadObserver* overhead_observer,
Niels Möllere9771992018-11-26 10:55:07 +010093 Transport* rtp_transport,
Niels Möllerdced9f62018-11-19 10:27:07 +010094 RtcpRttStats* rtcp_rtt_stats,
95 RtcEventLog* rtc_event_log,
96 FrameEncryptorInterface* frame_encryptor,
97 const webrtc::CryptoOptions& crypto_options,
98 bool extmap_allow_mixed,
Erik Språng4c2c4122019-07-11 15:20:15 +020099 int rtcp_report_interval_ms,
100 uint32_t ssrc);
Niels Möllerdced9f62018-11-19 10:27:07 +0100101
102 ~ChannelSend() override;
103
104 // Send using this encoder, with this payload type.
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100105 void SetEncoder(int payload_type,
Niels Möllerdced9f62018-11-19 10:27:07 +0100106 std::unique_ptr<AudioEncoder> encoder) override;
107 void ModifyEncoder(rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)>
108 modifier) override;
Sebastian Jansson14a7cf92019-02-13 15:11:42 +0100109 void CallEncoder(rtc::FunctionView<void(AudioEncoder*)> modifier) override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100110
111 // API methods
Niels Möllerdced9f62018-11-19 10:27:07 +0100112 void StartSend() override;
113 void StopSend() override;
114
115 // Codecs
Sebastian Jansson254d8692018-11-21 19:19:00 +0100116 void OnBitrateAllocation(BitrateAllocationUpdate update) override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100117 int GetBitrate() const override;
118
119 // Network
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100120 void ReceivedRTCPPacket(const uint8_t* data, size_t length) override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100121
122 // Muting, Volume and Level.
123 void SetInputMute(bool enable) override;
124
125 // Stats.
126 ANAStats GetANAStatistics() const override;
127
128 // Used by AudioSendStream.
129 RtpRtcp* GetRtpRtcp() const override;
130
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100131 void RegisterCngPayloadType(int payload_type, int payload_frequency) override;
132
Niels Möllerdced9f62018-11-19 10:27:07 +0100133 // DTMF.
134 bool SendTelephoneEventOutband(int event, int duration_ms) override;
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100135 void SetSendTelephoneEventPayloadType(int payload_type,
Niels Möllerdced9f62018-11-19 10:27:07 +0100136 int payload_frequency) override;
137
138 // RTP+RTCP
Amit Hilbuch77938e62018-12-21 09:23:38 -0800139 void SetRid(const std::string& rid,
140 int extension_id,
141 int repaired_extension_id) override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100142 void SetMid(const std::string& mid, int extension_id) override;
143 void SetExtmapAllowMixed(bool extmap_allow_mixed) override;
144 void SetSendAudioLevelIndicationStatus(bool enable, int id) override;
145 void EnableSendTransportSequenceNumber(int id) override;
146
147 void RegisterSenderCongestionControlObjects(
148 RtpTransportControllerSendInterface* transport,
149 RtcpBandwidthObserver* bandwidth_observer) override;
150 void ResetSenderCongestionControlObjects() override;
151 void SetRTCP_CNAME(absl::string_view c_name) override;
152 std::vector<ReportBlock> GetRemoteRTCPReportBlocks() const override;
153 CallSendStatistics GetRTCPStatistics() const override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100154
155 // ProcessAndEncodeAudio() posts a task on the shared encoder task queue,
156 // which in turn calls (on the queue) ProcessAndEncodeAudioOnTaskQueue() where
157 // the actual processing of the audio takes place. The processing mainly
158 // consists of encoding and preparing the result for sending by adding it to a
159 // send queue.
160 // The main reason for using a task queue here is to release the native,
161 // OS-specific, audio capture thread as soon as possible to ensure that it
162 // can go back to sleep and be prepared to deliver an new captured audio
163 // packet.
164 void ProcessAndEncodeAudio(std::unique_ptr<AudioFrame> audio_frame) override;
165
Niels Möllerdced9f62018-11-19 10:27:07 +0100166 int64_t GetRTT() const override;
167
168 // E2EE Custom Audio Frame Encryption
169 void SetFrameEncryptor(
170 rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) override;
171
172 private:
Niels Möllerdced9f62018-11-19 10:27:07 +0100173 // From AudioPacketizationCallback in the ACM
Niels Möller87e2d782019-03-07 10:18:23 +0100174 int32_t SendData(AudioFrameType frameType,
Niels Möllerdced9f62018-11-19 10:27:07 +0100175 uint8_t payloadType,
176 uint32_t timeStamp,
177 const uint8_t* payloadData,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200178 size_t payloadSize) override;
Niels Möllerdced9f62018-11-19 10:27:07 +0100179
Niels Möllerdced9f62018-11-19 10:27:07 +0100180 void OnUplinkPacketLossRate(float packet_loss_rate);
181 bool InputMute() const;
182
Sebastian Janssonf39c8152019-10-14 17:32:21 +0200183 void SetSendRtpHeaderExtension(bool enable, absl::string_view uri, int id);
Niels Möllerdced9f62018-11-19 10:27:07 +0100184
Niels Möller87e2d782019-03-07 10:18:23 +0100185 int32_t SendRtpAudio(AudioFrameType frameType,
Niels Möllerdced9f62018-11-19 10:27:07 +0100186 uint8_t payloadType,
187 uint32_t timeStamp,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200188 rtc::ArrayView<const uint8_t> payload)
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100189 RTC_RUN_ON(encoder_queue_);
Niels Möllerdced9f62018-11-19 10:27:07 +0100190
Niels Möller87e2d782019-03-07 10:18:23 +0100191 int32_t SendMediaTransportAudio(AudioFrameType frameType,
Niels Möllerdced9f62018-11-19 10:27:07 +0100192 uint8_t payloadType,
193 uint32_t timeStamp,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200194 rtc::ArrayView<const uint8_t> payload)
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100195 RTC_RUN_ON(encoder_queue_);
Niels Möllerdced9f62018-11-19 10:27:07 +0100196
197 // Return media transport or nullptr if using RTP.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700198 MediaTransportInterface* media_transport() {
199 return media_transport_config_.media_transport;
200 }
Niels Möllerdced9f62018-11-19 10:27:07 +0100201
Niels Möllerdced9f62018-11-19 10:27:07 +0100202 void OnReceivedRtt(int64_t rtt_ms);
203
204 void OnTargetTransferRate(TargetTransferRate) override;
205
206 // Thread checkers document and lock usage of some methods on voe::Channel to
207 // specific threads we know about. The goal is to eventually split up
208 // voe::Channel into parts with single-threaded semantics, and thereby reduce
209 // the need for locks.
210 rtc::ThreadChecker worker_thread_checker_;
211 rtc::ThreadChecker module_process_thread_checker_;
212 // Methods accessed from audio and video threads are checked for sequential-
213 // only access. We don't necessarily own and control these threads, so thread
214 // checkers cannot be used. E.g. Chromium may transfer "ownership" from one
215 // audio thread to another, but access is still sequential.
216 rtc::RaceChecker audio_thread_race_checker_;
217
Niels Möllerdced9f62018-11-19 10:27:07 +0100218 rtc::CriticalSection volume_settings_critsect_;
219
Niels Möller26e88b02018-11-19 15:08:13 +0100220 bool sending_ RTC_GUARDED_BY(&worker_thread_checker_) = false;
Niels Möllerdced9f62018-11-19 10:27:07 +0100221
222 RtcEventLog* const event_log_;
223
224 std::unique_ptr<RtpRtcp> _rtpRtcpModule;
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100225 std::unique_ptr<RTPSenderAudio> rtp_sender_audio_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100226
227 std::unique_ptr<AudioCodingModule> audio_coding_;
228 uint32_t _timeStamp RTC_GUARDED_BY(encoder_queue_);
229
Niels Möllerdced9f62018-11-19 10:27:07 +0100230 // uses
Niels Möller985a1f32018-11-19 16:08:42 +0100231 ProcessThread* const _moduleProcessThreadPtr;
Niels Möllerdced9f62018-11-19 10:27:07 +0100232 RmsLevel rms_level_ RTC_GUARDED_BY(encoder_queue_);
233 bool input_mute_ RTC_GUARDED_BY(volume_settings_critsect_);
234 bool previous_frame_muted_ RTC_GUARDED_BY(encoder_queue_);
235 // VoeRTP_RTCP
236 // TODO(henrika): can today be accessed on the main thread and on the
237 // task queue; hence potential race.
238 bool _includeAudioLevelIndication;
Anton Sukhanov626015d2019-02-04 15:16:06 -0800239
Niels Möllerdced9f62018-11-19 10:27:07 +0100240 // RtcpBandwidthObserver
Niels Möller985a1f32018-11-19 16:08:42 +0100241 const std::unique_ptr<VoERtcpObserver> rtcp_observer_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100242
Niels Möller985a1f32018-11-19 16:08:42 +0100243 PacketRouter* packet_router_ RTC_GUARDED_BY(&worker_thread_checker_) =
244 nullptr;
245 const std::unique_ptr<TransportFeedbackProxy> feedback_observer_proxy_;
Erik Språng59b86542019-06-23 18:24:46 +0200246 const std::unique_ptr<RtpPacketSenderProxy> rtp_packet_pacer_proxy_;
Niels Möller985a1f32018-11-19 16:08:42 +0100247 const std::unique_ptr<RateLimiter> retransmission_rate_limiter_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100248
249 rtc::ThreadChecker construction_thread_;
250
Niels Möllerdced9f62018-11-19 10:27:07 +0100251
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100252 bool encoder_queue_is_active_ RTC_GUARDED_BY(encoder_queue_) = false;
Niels Möllerdced9f62018-11-19 10:27:07 +0100253
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700254 MediaTransportConfig media_transport_config_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100255 int media_transport_sequence_number_ RTC_GUARDED_BY(encoder_queue_) = 0;
256
257 rtc::CriticalSection media_transport_lock_;
Erik Språng70efdde2019-08-21 13:36:20 +0200258 // Currently set to local SSRC at construction.
Niels Möllerdced9f62018-11-19 10:27:07 +0100259 uint64_t media_transport_channel_id_ RTC_GUARDED_BY(&media_transport_lock_) =
260 0;
261 // Cache payload type and sampling frequency from most recent call to
262 // SetEncoder. Needed to set MediaTransportEncodedAudioFrame metadata, and
263 // invalidate on encoder change.
264 int media_transport_payload_type_ RTC_GUARDED_BY(&media_transport_lock_);
265 int media_transport_sampling_frequency_
266 RTC_GUARDED_BY(&media_transport_lock_);
267
268 // E2EE Audio Frame Encryption
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100269 rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor_
270 RTC_GUARDED_BY(encoder_queue_);
Niels Möllerdced9f62018-11-19 10:27:07 +0100271 // E2EE Frame Encryption Options
Niels Möller985a1f32018-11-19 16:08:42 +0100272 const webrtc::CryptoOptions crypto_options_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100273
274 rtc::CriticalSection bitrate_crit_section_;
275 int configured_bitrate_bps_ RTC_GUARDED_BY(bitrate_crit_section_) = 0;
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100276
277 // Defined last to ensure that there are no running tasks when the other
278 // members are destroyed.
279 rtc::TaskQueue encoder_queue_;
Niels Möllerdced9f62018-11-19 10:27:07 +0100280};
Niels Möller530ead42018-10-04 14:28:39 +0200281
282const int kTelephoneEventAttenuationdB = 10;
283
284class TransportFeedbackProxy : public TransportFeedbackObserver {
285 public:
286 TransportFeedbackProxy() : feedback_observer_(nullptr) {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200287 pacer_thread_.Detach();
288 network_thread_.Detach();
Niels Möller530ead42018-10-04 14:28:39 +0200289 }
290
291 void SetTransportFeedbackObserver(
292 TransportFeedbackObserver* feedback_observer) {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200293 RTC_DCHECK(thread_checker_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +0200294 rtc::CritScope lock(&crit_);
295 feedback_observer_ = feedback_observer;
296 }
297
298 // Implements TransportFeedbackObserver.
Erik Språng30a276b2019-04-23 12:00:11 +0200299 void OnAddPacket(const RtpPacketSendInfo& packet_info) override {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200300 RTC_DCHECK(pacer_thread_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +0200301 rtc::CritScope lock(&crit_);
302 if (feedback_observer_)
Erik Språng30a276b2019-04-23 12:00:11 +0200303 feedback_observer_->OnAddPacket(packet_info);
Niels Möller530ead42018-10-04 14:28:39 +0200304 }
305
306 void OnTransportFeedback(const rtcp::TransportFeedback& feedback) override {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200307 RTC_DCHECK(network_thread_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +0200308 rtc::CritScope lock(&crit_);
309 if (feedback_observer_)
310 feedback_observer_->OnTransportFeedback(feedback);
311 }
312
313 private:
314 rtc::CriticalSection crit_;
315 rtc::ThreadChecker thread_checker_;
316 rtc::ThreadChecker pacer_thread_;
317 rtc::ThreadChecker network_thread_;
318 TransportFeedbackObserver* feedback_observer_ RTC_GUARDED_BY(&crit_);
319};
320
Erik Språngaa59eca2019-07-24 14:52:55 +0200321class RtpPacketSenderProxy : public RtpPacketSender {
Niels Möller530ead42018-10-04 14:28:39 +0200322 public:
Erik Språng59b86542019-06-23 18:24:46 +0200323 RtpPacketSenderProxy() : rtp_packet_pacer_(nullptr) {}
Niels Möller530ead42018-10-04 14:28:39 +0200324
Erik Språngaa59eca2019-07-24 14:52:55 +0200325 void SetPacketPacer(RtpPacketSender* rtp_packet_pacer) {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200326 RTC_DCHECK(thread_checker_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +0200327 rtc::CritScope lock(&crit_);
Erik Språng59b86542019-06-23 18:24:46 +0200328 rtp_packet_pacer_ = rtp_packet_pacer;
329 }
330
Erik Språngea55b082019-10-02 14:57:46 +0200331 void EnqueuePackets(
332 std::vector<std::unique_ptr<RtpPacketToSend>> packets) override {
Erik Språng59b86542019-06-23 18:24:46 +0200333 rtc::CritScope lock(&crit_);
Erik Språngea55b082019-10-02 14:57:46 +0200334 rtp_packet_pacer_->EnqueuePackets(std::move(packets));
Niels Möller530ead42018-10-04 14:28:39 +0200335 }
336
Niels Möller530ead42018-10-04 14:28:39 +0200337 private:
338 rtc::ThreadChecker thread_checker_;
339 rtc::CriticalSection crit_;
Erik Språngaa59eca2019-07-24 14:52:55 +0200340 RtpPacketSender* rtp_packet_pacer_ RTC_GUARDED_BY(&crit_);
Niels Möller530ead42018-10-04 14:28:39 +0200341};
342
343class VoERtcpObserver : public RtcpBandwidthObserver {
344 public:
345 explicit VoERtcpObserver(ChannelSend* owner)
346 : owner_(owner), bandwidth_observer_(nullptr) {}
Mirko Bonadeife055c12019-01-29 22:53:28 +0100347 ~VoERtcpObserver() override {}
Niels Möller530ead42018-10-04 14:28:39 +0200348
349 void SetBandwidthObserver(RtcpBandwidthObserver* bandwidth_observer) {
350 rtc::CritScope lock(&crit_);
351 bandwidth_observer_ = bandwidth_observer;
352 }
353
354 void OnReceivedEstimatedBitrate(uint32_t bitrate) override {
355 rtc::CritScope lock(&crit_);
356 if (bandwidth_observer_) {
357 bandwidth_observer_->OnReceivedEstimatedBitrate(bitrate);
358 }
359 }
360
361 void OnReceivedRtcpReceiverReport(const ReportBlockList& report_blocks,
362 int64_t rtt,
363 int64_t now_ms) override {
364 {
365 rtc::CritScope lock(&crit_);
366 if (bandwidth_observer_) {
367 bandwidth_observer_->OnReceivedRtcpReceiverReport(report_blocks, rtt,
368 now_ms);
369 }
370 }
371 // TODO(mflodman): Do we need to aggregate reports here or can we jut send
372 // what we get? I.e. do we ever get multiple reports bundled into one RTCP
373 // report for VoiceEngine?
374 if (report_blocks.empty())
375 return;
376
377 int fraction_lost_aggregate = 0;
378 int total_number_of_packets = 0;
379
380 // If receiving multiple report blocks, calculate the weighted average based
381 // on the number of packets a report refers to.
382 for (ReportBlockList::const_iterator block_it = report_blocks.begin();
383 block_it != report_blocks.end(); ++block_it) {
384 // Find the previous extended high sequence number for this remote SSRC,
385 // to calculate the number of RTP packets this report refers to. Ignore if
386 // we haven't seen this SSRC before.
387 std::map<uint32_t, uint32_t>::iterator seq_num_it =
388 extended_max_sequence_number_.find(block_it->source_ssrc);
389 int number_of_packets = 0;
390 if (seq_num_it != extended_max_sequence_number_.end()) {
391 number_of_packets =
392 block_it->extended_highest_sequence_number - seq_num_it->second;
393 }
394 fraction_lost_aggregate += number_of_packets * block_it->fraction_lost;
395 total_number_of_packets += number_of_packets;
396
397 extended_max_sequence_number_[block_it->source_ssrc] =
398 block_it->extended_highest_sequence_number;
399 }
400 int weighted_fraction_lost = 0;
401 if (total_number_of_packets > 0) {
402 weighted_fraction_lost =
403 (fraction_lost_aggregate + total_number_of_packets / 2) /
404 total_number_of_packets;
405 }
406 owner_->OnUplinkPacketLossRate(weighted_fraction_lost / 255.0f);
407 }
408
409 private:
410 ChannelSend* owner_;
411 // Maps remote side ssrc to extended highest sequence number received.
412 std::map<uint32_t, uint32_t> extended_max_sequence_number_;
413 rtc::CriticalSection crit_;
414 RtcpBandwidthObserver* bandwidth_observer_ RTC_GUARDED_BY(crit_);
415};
416
Niels Möller87e2d782019-03-07 10:18:23 +0100417int32_t ChannelSend::SendData(AudioFrameType frameType,
Niels Möller530ead42018-10-04 14:28:39 +0200418 uint8_t payloadType,
419 uint32_t timeStamp,
420 const uint8_t* payloadData,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200421 size_t payloadSize) {
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100422 RTC_DCHECK_RUN_ON(&encoder_queue_);
Niels Möller7d76a312018-10-26 12:57:07 +0200423 rtc::ArrayView<const uint8_t> payload(payloadData, payloadSize);
424
425 if (media_transport() != nullptr) {
Niels Möllerc936cb62019-03-19 14:10:16 +0100426 if (frameType == AudioFrameType::kEmptyFrame) {
Piotr (Peter) Slatala3cdd4d52019-02-28 07:10:56 -0800427 // TODO(bugs.webrtc.org/9719): Media transport Send doesn't support
428 // sending empty frames.
429 return 0;
430 }
431
Niels Möllerc35b6e62019-04-25 16:31:18 +0200432 return SendMediaTransportAudio(frameType, payloadType, timeStamp, payload);
Niels Möller7d76a312018-10-26 12:57:07 +0200433 } else {
Niels Möllerc35b6e62019-04-25 16:31:18 +0200434 return SendRtpAudio(frameType, payloadType, timeStamp, payload);
Niels Möller7d76a312018-10-26 12:57:07 +0200435 }
436}
437
Niels Möller87e2d782019-03-07 10:18:23 +0100438int32_t ChannelSend::SendRtpAudio(AudioFrameType frameType,
Niels Möller7d76a312018-10-26 12:57:07 +0200439 uint8_t payloadType,
440 uint32_t timeStamp,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200441 rtc::ArrayView<const uint8_t> payload) {
Niels Möller530ead42018-10-04 14:28:39 +0200442 if (_includeAudioLevelIndication) {
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100443 // Store current audio level in the RTP sender.
Niels Möller530ead42018-10-04 14:28:39 +0200444 // The level will be used in combination with voice-activity state
445 // (frameType) to add an RTP header extension
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100446 rtp_sender_audio_->SetAudioLevel(rms_level_.Average());
Niels Möller530ead42018-10-04 14:28:39 +0200447 }
448
Benjamin Wright84583f62018-10-04 14:22:34 -0700449 // E2EE Custom Audio Frame Encryption (This is optional).
450 // Keep this buffer around for the lifetime of the send call.
451 rtc::Buffer encrypted_audio_payload;
Minyue Li9ab520e2019-05-28 13:27:40 +0200452 // We don't invoke encryptor if payload is empty, which means we are to send
453 // DTMF, or the encoder entered DTX.
454 // TODO(minyue): see whether DTMF packets should be encrypted or not. In
455 // current implementation, they are not.
Minyue Lif48bca72019-06-20 23:37:02 +0200456 if (!payload.empty()) {
457 if (frame_encryptor_ != nullptr) {
458 // TODO(benwright@webrtc.org) - Allocate enough to always encrypt inline.
459 // Allocate a buffer to hold the maximum possible encrypted payload.
460 size_t max_ciphertext_size = frame_encryptor_->GetMaxCiphertextByteSize(
461 cricket::MEDIA_TYPE_AUDIO, payload.size());
462 encrypted_audio_payload.SetSize(max_ciphertext_size);
Benjamin Wright84583f62018-10-04 14:22:34 -0700463
Minyue Lif48bca72019-06-20 23:37:02 +0200464 // Encrypt the audio payload into the buffer.
465 size_t bytes_written = 0;
466 int encrypt_status = frame_encryptor_->Encrypt(
467 cricket::MEDIA_TYPE_AUDIO, _rtpRtcpModule->SSRC(),
468 /*additional_data=*/nullptr, payload, encrypted_audio_payload,
469 &bytes_written);
470 if (encrypt_status != 0) {
471 RTC_DLOG(LS_ERROR)
472 << "Channel::SendData() failed encrypt audio payload: "
473 << encrypt_status;
474 return -1;
475 }
476 // Resize the buffer to the exact number of bytes actually used.
477 encrypted_audio_payload.SetSize(bytes_written);
478 // Rewrite the payloadData and size to the new encrypted payload.
479 payload = encrypted_audio_payload;
480 } else if (crypto_options_.sframe.require_frame_encryption) {
481 RTC_DLOG(LS_ERROR) << "Channel::SendData() failed sending audio payload: "
482 << "A frame encryptor is required but one is not set.";
Benjamin Wright84583f62018-10-04 14:22:34 -0700483 return -1;
484 }
Benjamin Wright84583f62018-10-04 14:22:34 -0700485 }
486
Niels Möller530ead42018-10-04 14:28:39 +0200487 // Push data from ACM to RTP/RTCP-module to deliver audio frame for
488 // packetization.
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100489 if (!_rtpRtcpModule->OnSendingRtpFrame(timeStamp,
490 // Leaving the time when this frame was
491 // received from the capture device as
492 // undefined for voice for now.
493 -1, payloadType,
494 /*force_sender_report=*/false)) {
495 return false;
496 }
497
498 // RTCPSender has it's own copy of the timestamp offset, added in
499 // RTCPSender::BuildSR, hence we must not add the in the offset for the above
500 // call.
501 // TODO(nisse): Delete RTCPSender:timestamp_offset_, and see if we can confine
502 // knowledge of the offset to a single place.
503 const uint32_t rtp_timestamp = timeStamp + _rtpRtcpModule->StartTimestamp();
Niels Möller530ead42018-10-04 14:28:39 +0200504 // This call will trigger Transport::SendPacket() from the RTP/RTCP module.
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100505 if (!rtp_sender_audio_->SendAudio(frameType, payloadType, rtp_timestamp,
506 payload.data(), payload.size())) {
Niels Möller530ead42018-10-04 14:28:39 +0200507 RTC_DLOG(LS_ERROR)
508 << "ChannelSend::SendData() failed to send data to RTP/RTCP module";
509 return -1;
510 }
511
512 return 0;
513}
514
Niels Möller7d76a312018-10-26 12:57:07 +0200515int32_t ChannelSend::SendMediaTransportAudio(
Niels Möller87e2d782019-03-07 10:18:23 +0100516 AudioFrameType frameType,
Niels Möller7d76a312018-10-26 12:57:07 +0200517 uint8_t payloadType,
518 uint32_t timeStamp,
Niels Möllerc35b6e62019-04-25 16:31:18 +0200519 rtc::ArrayView<const uint8_t> payload) {
Niels Möller7d76a312018-10-26 12:57:07 +0200520 // TODO(nisse): Use null _transportPtr for MediaTransport.
521 // RTC_DCHECK(_transportPtr == nullptr);
522 uint64_t channel_id;
523 int sampling_rate_hz;
524 {
525 rtc::CritScope cs(&media_transport_lock_);
526 if (media_transport_payload_type_ != payloadType) {
527 // Payload type is being changed, media_transport_sampling_frequency_,
528 // no longer current.
529 return -1;
530 }
531 sampling_rate_hz = media_transport_sampling_frequency_;
532 channel_id = media_transport_channel_id_;
533 }
Mirko Bonadei1c546052019-02-04 14:50:38 +0100534 MediaTransportEncodedAudioFrame frame(
Niels Möller7d76a312018-10-26 12:57:07 +0200535 /*sampling_rate_hz=*/sampling_rate_hz,
536
537 // TODO(nisse): Timestamp and sample index are the same for all supported
538 // audio codecs except G722. Refactor audio coding module to only use
539 // sample index, and leave translation to RTP time, when needed, for
540 // RTP-specific code.
541 /*starting_sample_index=*/timeStamp,
542
543 // Sample count isn't conveniently available from the AudioCodingModule,
544 // and needs some refactoring to wire up in a good way. For now, left as
545 // zero.
Benjamin Wright17b050f2019-03-13 17:35:46 -0700546 /*samples_per_channel=*/0,
Niels Möller7d76a312018-10-26 12:57:07 +0200547
548 /*sequence_number=*/media_transport_sequence_number_,
549 MediaTransportFrameTypeForWebrtcFrameType(frameType), payloadType,
550 std::vector<uint8_t>(payload.begin(), payload.end()));
551
552 // TODO(nisse): Introduce a MediaTransportSender object bound to a specific
553 // channel id.
554 RTCError rtc_error =
555 media_transport()->SendAudioFrame(channel_id, std::move(frame));
556
557 if (!rtc_error.ok()) {
558 RTC_LOG(LS_ERROR) << "Failed to send frame, rtc_error="
559 << ToString(rtc_error.type()) << ", "
560 << rtc_error.message();
561 return -1;
562 }
563
564 ++media_transport_sequence_number_;
565
566 return 0;
567}
568
Sebastian Jansson977b3352019-03-04 17:43:34 +0100569ChannelSend::ChannelSend(Clock* clock,
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100570 TaskQueueFactory* task_queue_factory,
Niels Möller530ead42018-10-04 14:28:39 +0200571 ProcessThread* module_process_thread,
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700572 const MediaTransportConfig& media_transport_config,
Anton Sukhanov626015d2019-02-04 15:16:06 -0800573 OverheadObserver* overhead_observer,
Niels Möllere9771992018-11-26 10:55:07 +0100574 Transport* rtp_transport,
Niels Möller530ead42018-10-04 14:28:39 +0200575 RtcpRttStats* rtcp_rtt_stats,
Benjamin Wright84583f62018-10-04 14:22:34 -0700576 RtcEventLog* rtc_event_log,
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700577 FrameEncryptorInterface* frame_encryptor,
Johannes Kron9190b822018-10-29 11:22:05 +0100578 const webrtc::CryptoOptions& crypto_options,
Jiawei Ou55718122018-11-09 13:17:39 -0800579 bool extmap_allow_mixed,
Erik Språng4c2c4122019-07-11 15:20:15 +0200580 int rtcp_report_interval_ms,
581 uint32_t ssrc)
Niels Möller530ead42018-10-04 14:28:39 +0200582 : event_log_(rtc_event_log),
583 _timeStamp(0), // This is just an offset, RTP module will add it's own
584 // random offset
Niels Möller530ead42018-10-04 14:28:39 +0200585 _moduleProcessThreadPtr(module_process_thread),
Niels Möller530ead42018-10-04 14:28:39 +0200586 input_mute_(false),
587 previous_frame_muted_(false),
588 _includeAudioLevelIndication(false),
Niels Möller530ead42018-10-04 14:28:39 +0200589 rtcp_observer_(new VoERtcpObserver(this)),
590 feedback_observer_proxy_(new TransportFeedbackProxy()),
Erik Språng59b86542019-06-23 18:24:46 +0200591 rtp_packet_pacer_proxy_(new RtpPacketSenderProxy()),
Sebastian Jansson977b3352019-03-04 17:43:34 +0100592 retransmission_rate_limiter_(
593 new RateLimiter(clock, kMaxRetransmissionWindowMs)),
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700594 media_transport_config_(media_transport_config),
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700595 frame_encryptor_(frame_encryptor),
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100596 crypto_options_(crypto_options),
597 encoder_queue_(task_queue_factory->CreateTaskQueue(
598 "AudioEncoder",
599 TaskQueueFactory::Priority::NORMAL)) {
Niels Möller530ead42018-10-04 14:28:39 +0200600 RTC_DCHECK(module_process_thread);
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200601 module_process_thread_checker_.Detach();
Niels Möllerdced9f62018-11-19 10:27:07 +0100602
Niels Möller530ead42018-10-04 14:28:39 +0200603 audio_coding_.reset(AudioCodingModule::Create(AudioCodingModule::Config()));
604
605 RtpRtcp::Configuration configuration;
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800606
607 // We gradually remove codepaths that depend on RTP when using media
608 // transport. All of this logic should be moved to the future
609 // RTPMediaTransport. In this case it means that overhead and bandwidth
610 // observers should not be called when using media transport.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700611 if (!media_transport_config.media_transport) {
Anton Sukhanov626015d2019-02-04 15:16:06 -0800612 configuration.overhead_observer = overhead_observer;
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800613 configuration.bandwidth_callback = rtcp_observer_.get();
614 configuration.transport_feedback_callback = feedback_observer_proxy_.get();
615 }
616
Sebastian Jansson977b3352019-03-04 17:43:34 +0100617 configuration.clock = clock;
Niels Möller530ead42018-10-04 14:28:39 +0200618 configuration.audio = true;
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100619 configuration.clock = Clock::GetRealTimeClock();
Fredrik Solenberg3d2ed192018-12-18 09:18:33 +0100620 configuration.outgoing_transport = rtp_transport;
Niels Möller530ead42018-10-04 14:28:39 +0200621
Erik Språng59b86542019-06-23 18:24:46 +0200622 configuration.paced_sender = rtp_packet_pacer_proxy_.get();
Niels Möller530ead42018-10-04 14:28:39 +0200623
624 configuration.event_log = event_log_;
625 configuration.rtt_stats = rtcp_rtt_stats;
626 configuration.retransmission_rate_limiter =
627 retransmission_rate_limiter_.get();
Johannes Kron9190b822018-10-29 11:22:05 +0100628 configuration.extmap_allow_mixed = extmap_allow_mixed;
Jiawei Ou8b5d9d82018-11-15 16:44:37 -0800629 configuration.rtcp_report_interval_ms = rtcp_report_interval_ms;
Niels Möller530ead42018-10-04 14:28:39 +0200630
Erik Språng54d5d2c2019-08-20 17:22:36 +0200631 configuration.local_media_ssrc = ssrc;
Erik Språng70efdde2019-08-21 13:36:20 +0200632 if (media_transport_config_.media_transport) {
633 rtc::CritScope cs(&media_transport_lock_);
634 media_transport_channel_id_ = ssrc;
635 }
Erik Språng4c2c4122019-07-11 15:20:15 +0200636
Danil Chapovalovc44f6cc2019-03-06 11:31:09 +0100637 _rtpRtcpModule = RtpRtcp::Create(configuration);
Niels Möller530ead42018-10-04 14:28:39 +0200638 _rtpRtcpModule->SetSendingMediaStatus(false);
Niels Möller530ead42018-10-04 14:28:39 +0200639
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200640 rtp_sender_audio_ = std::make_unique<RTPSenderAudio>(
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100641 configuration.clock, _rtpRtcpModule->RtpSender());
642
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800643 // We want to invoke the 'TargetRateObserver' and |OnOverheadChanged|
644 // callbacks after the audio_coding_ is fully initialized.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700645 if (media_transport_config.media_transport) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800646 RTC_DLOG(LS_INFO) << "Setting media_transport_ rate observers.";
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700647 media_transport_config.media_transport->AddTargetTransferRateObserver(this);
648 media_transport_config.media_transport->SetAudioOverheadObserver(
649 overhead_observer);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800650 } else {
651 RTC_DLOG(LS_INFO) << "Not setting media_transport_ rate observers.";
652 }
653
Niels Möller530ead42018-10-04 14:28:39 +0200654 _moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get(), RTC_FROM_HERE);
655
Niels Möller530ead42018-10-04 14:28:39 +0200656 // Ensure that RTCP is enabled by default for the created channel.
Niels Möller530ead42018-10-04 14:28:39 +0200657 _rtpRtcpModule->SetRTCPStatus(RtcpMode::kCompound);
658
Fredrik Solenbergeb134842018-11-19 14:13:15 +0100659 int error = audio_coding_->RegisterTransportCallback(this);
Niels Möller530ead42018-10-04 14:28:39 +0200660 RTC_DCHECK_EQ(0, error);
661}
662
Fredrik Solenberg645a3af2018-11-16 12:51:15 +0100663ChannelSend::~ChannelSend() {
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200664 RTC_DCHECK(construction_thread_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +0200665
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700666 if (media_transport_config_.media_transport) {
667 media_transport_config_.media_transport->RemoveTargetTransferRateObserver(
668 this);
669 media_transport_config_.media_transport->SetAudioOverheadObserver(nullptr);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800670 }
671
Niels Möller530ead42018-10-04 14:28:39 +0200672 StopSend();
Niels Möller530ead42018-10-04 14:28:39 +0200673 int error = audio_coding_->RegisterTransportCallback(NULL);
674 RTC_DCHECK_EQ(0, error);
675
Niels Möller530ead42018-10-04 14:28:39 +0200676 if (_moduleProcessThreadPtr)
677 _moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get());
Niels Möller530ead42018-10-04 14:28:39 +0200678}
679
Niels Möller26815232018-11-16 09:32:40 +0100680void ChannelSend::StartSend() {
Niels Möller26e88b02018-11-19 15:08:13 +0100681 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Fredrik Solenbergeb134842018-11-19 14:13:15 +0100682 RTC_DCHECK(!sending_);
683 sending_ = true;
Niels Möller530ead42018-10-04 14:28:39 +0200684
Niels Möller530ead42018-10-04 14:28:39 +0200685 _rtpRtcpModule->SetSendingMediaStatus(true);
Niels Möller26815232018-11-16 09:32:40 +0100686 int ret = _rtpRtcpModule->SetSendingStatus(true);
687 RTC_DCHECK_EQ(0, ret);
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100688 // It is now OK to start processing on the encoder task queue.
689 encoder_queue_.PostTask([this] {
690 RTC_DCHECK_RUN_ON(&encoder_queue_);
Niels Möller530ead42018-10-04 14:28:39 +0200691 encoder_queue_is_active_ = true;
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100692 });
Niels Möller530ead42018-10-04 14:28:39 +0200693}
694
695void ChannelSend::StopSend() {
Niels Möller26e88b02018-11-19 15:08:13 +0100696 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Fredrik Solenbergeb134842018-11-19 14:13:15 +0100697 if (!sending_) {
Niels Möller530ead42018-10-04 14:28:39 +0200698 return;
699 }
Fredrik Solenbergeb134842018-11-19 14:13:15 +0100700 sending_ = false;
Niels Möller530ead42018-10-04 14:28:39 +0200701
Niels Möllerc572ff32018-11-07 08:43:50 +0100702 rtc::Event flush;
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100703 encoder_queue_.PostTask([this, &flush]() {
704 RTC_DCHECK_RUN_ON(&encoder_queue_);
Niels Möller530ead42018-10-04 14:28:39 +0200705 encoder_queue_is_active_ = false;
Sebastian Jansson44dd9f22019-03-08 14:50:30 +0100706 flush.Set();
707 });
Niels Möller530ead42018-10-04 14:28:39 +0200708 flush.Wait(rtc::Event::kForever);
709
Niels Möller530ead42018-10-04 14:28:39 +0200710 // Reset sending SSRC and sequence number and triggers direct transmission
711 // of RTCP BYE
712 if (_rtpRtcpModule->SetSendingStatus(false) == -1) {
713 RTC_DLOG(LS_ERROR) << "StartSend() RTP/RTCP failed to stop sending";
714 }
715 _rtpRtcpModule->SetSendingMediaStatus(false);
716}
717
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100718void ChannelSend::SetEncoder(int payload_type,
Niels Möller530ead42018-10-04 14:28:39 +0200719 std::unique_ptr<AudioEncoder> encoder) {
Niels Möller26e88b02018-11-19 15:08:13 +0100720 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200721 RTC_DCHECK_GE(payload_type, 0);
722 RTC_DCHECK_LE(payload_type, 127);
Niels Möller530ead42018-10-04 14:28:39 +0200723
724 // The RTP/RTCP module needs to know the RTP timestamp rate (i.e. clockrate)
725 // as well as some other things, so we collect this info and send it along.
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100726 _rtpRtcpModule->RegisterSendPayloadFrequency(payload_type,
727 encoder->RtpTimestampRateHz());
728 rtp_sender_audio_->RegisterAudioPayload("audio", payload_type,
729 encoder->RtpTimestampRateHz(),
730 encoder->NumChannels(), 0);
Niels Möller530ead42018-10-04 14:28:39 +0200731
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700732 if (media_transport_config_.media_transport) {
Niels Möller7d76a312018-10-26 12:57:07 +0200733 rtc::CritScope cs(&media_transport_lock_);
734 media_transport_payload_type_ = payload_type;
735 // TODO(nisse): Currently broken for G722, since timestamps passed through
736 // encoder use RTP clock rather than sample count, and they differ for G722.
737 media_transport_sampling_frequency_ = encoder->RtpTimestampRateHz();
738 }
Niels Möller530ead42018-10-04 14:28:39 +0200739 audio_coding_->SetEncoder(std::move(encoder));
Niels Möller530ead42018-10-04 14:28:39 +0200740}
741
742void ChannelSend::ModifyEncoder(
743 rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)> modifier) {
Anton Sukhanov626015d2019-02-04 15:16:06 -0800744 // This method can be called on the worker thread, module process thread
745 // or network thread. Audio coding is thread safe, so we do not need to
746 // enforce the calling thread.
Niels Möller530ead42018-10-04 14:28:39 +0200747 audio_coding_->ModifyEncoder(modifier);
748}
749
Sebastian Jansson14a7cf92019-02-13 15:11:42 +0100750void ChannelSend::CallEncoder(rtc::FunctionView<void(AudioEncoder*)> modifier) {
751 ModifyEncoder([modifier](std::unique_ptr<AudioEncoder>* encoder_ptr) {
752 if (*encoder_ptr) {
753 modifier(encoder_ptr->get());
754 } else {
755 RTC_DLOG(LS_WARNING) << "Trying to call unset encoder.";
756 }
757 });
758}
759
Sebastian Jansson254d8692018-11-21 19:19:00 +0100760void ChannelSend::OnBitrateAllocation(BitrateAllocationUpdate update) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100761 // This method can be called on the worker thread, module process thread
762 // or on a TaskQueue via VideoSendStreamImpl::OnEncoderConfigurationChanged.
763 // TODO(solenberg): Figure out a good way to check this or enforce calling
764 // rules.
Sebastian Janssonc01367d2019-04-08 15:20:44 +0200765 // RTC_DCHECK(worker_thread_checker_.IsCurrent() ||
766 // module_process_thread_checker_.IsCurrent());
Piotr (Peter) Slatala1eebec92018-11-16 09:03:35 -0800767 rtc::CritScope lock(&bitrate_crit_section_);
Niels Möllerdced9f62018-11-19 10:27:07 +0100768
Sebastian Jansson14a7cf92019-02-13 15:11:42 +0100769 CallEncoder([&](AudioEncoder* encoder) {
770 encoder->OnReceivedUplinkAllocation(update);
Niels Möller530ead42018-10-04 14:28:39 +0200771 });
Sebastian Jansson254d8692018-11-21 19:19:00 +0100772 retransmission_rate_limiter_->SetMaxRate(update.target_bitrate.bps());
773 configured_bitrate_bps_ = update.target_bitrate.bps();
Sebastian Jansson359d60a2018-10-25 16:22:02 +0200774}
775
Niels Möllerdced9f62018-11-19 10:27:07 +0100776int ChannelSend::GetBitrate() const {
Piotr (Peter) Slatala1eebec92018-11-16 09:03:35 -0800777 rtc::CritScope lock(&bitrate_crit_section_);
Sebastian Jansson359d60a2018-10-25 16:22:02 +0200778 return configured_bitrate_bps_;
Niels Möller530ead42018-10-04 14:28:39 +0200779}
780
Niels Möller530ead42018-10-04 14:28:39 +0200781void ChannelSend::OnUplinkPacketLossRate(float packet_loss_rate) {
Sebastian Jansson14a7cf92019-02-13 15:11:42 +0100782 CallEncoder([&](AudioEncoder* encoder) {
783 encoder->OnReceivedUplinkPacketLossFraction(packet_loss_rate);
Niels Möller530ead42018-10-04 14:28:39 +0200784 });
785}
786
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100787void ChannelSend::ReceivedRTCPPacket(const uint8_t* data, size_t length) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100788 // May be called on either worker thread or network thread.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -0700789 if (media_transport_config_.media_transport) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800790 // Ignore RTCP packets while media transport is used.
791 // Those packets should not arrive, but we are seeing occasional packets.
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100792 return;
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800793 }
794
Niels Möller530ead42018-10-04 14:28:39 +0200795 // Deliver RTCP packet to RTP/RTCP module for parsing
796 _rtpRtcpModule->IncomingRtcpPacket(data, length);
797
798 int64_t rtt = GetRTT();
799 if (rtt == 0) {
800 // Waiting for valid RTT.
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100801 return;
Niels Möller530ead42018-10-04 14:28:39 +0200802 }
803
804 int64_t nack_window_ms = rtt;
805 if (nack_window_ms < kMinRetransmissionWindowMs) {
806 nack_window_ms = kMinRetransmissionWindowMs;
807 } else if (nack_window_ms > kMaxRetransmissionWindowMs) {
808 nack_window_ms = kMaxRetransmissionWindowMs;
809 }
810 retransmission_rate_limiter_->SetWindowSize(nack_window_ms);
811
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -0800812 OnReceivedRtt(rtt);
Niels Möller530ead42018-10-04 14:28:39 +0200813}
814
815void ChannelSend::SetInputMute(bool enable) {
Niels Möller26e88b02018-11-19 15:08:13 +0100816 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200817 rtc::CritScope cs(&volume_settings_critsect_);
818 input_mute_ = enable;
819}
820
821bool ChannelSend::InputMute() const {
822 rtc::CritScope cs(&volume_settings_critsect_);
823 return input_mute_;
824}
825
Niels Möller26815232018-11-16 09:32:40 +0100826bool ChannelSend::SendTelephoneEventOutband(int event, int duration_ms) {
Niels Möller26e88b02018-11-19 15:08:13 +0100827 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200828 RTC_DCHECK_LE(0, event);
829 RTC_DCHECK_GE(255, event);
830 RTC_DCHECK_LE(0, duration_ms);
831 RTC_DCHECK_GE(65535, duration_ms);
Fredrik Solenbergeb134842018-11-19 14:13:15 +0100832 if (!sending_) {
Niels Möller26815232018-11-16 09:32:40 +0100833 return false;
Niels Möller530ead42018-10-04 14:28:39 +0200834 }
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100835 if (rtp_sender_audio_->SendTelephoneEvent(
Niels Möller530ead42018-10-04 14:28:39 +0200836 event, duration_ms, kTelephoneEventAttenuationdB) != 0) {
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100837 RTC_DLOG(LS_ERROR) << "SendTelephoneEvent() failed to send event";
Niels Möller26815232018-11-16 09:32:40 +0100838 return false;
Niels Möller530ead42018-10-04 14:28:39 +0200839 }
Niels Möller26815232018-11-16 09:32:40 +0100840 return true;
Niels Möller530ead42018-10-04 14:28:39 +0200841}
842
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100843void ChannelSend::RegisterCngPayloadType(int payload_type,
844 int payload_frequency) {
845 _rtpRtcpModule->RegisterSendPayloadFrequency(payload_type, payload_frequency);
846 rtp_sender_audio_->RegisterAudioPayload("CN", payload_type, payload_frequency,
847 1, 0);
848}
849
Niels Möller8fb1a6a2019-03-05 14:29:42 +0100850void ChannelSend::SetSendTelephoneEventPayloadType(int payload_type,
Niels Möller26815232018-11-16 09:32:40 +0100851 int payload_frequency) {
Niels Möller26e88b02018-11-19 15:08:13 +0100852 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200853 RTC_DCHECK_LE(0, payload_type);
854 RTC_DCHECK_GE(127, payload_type);
Niels Mölleree5ccbc2019-03-06 16:47:29 +0100855 _rtpRtcpModule->RegisterSendPayloadFrequency(payload_type, payload_frequency);
856 rtp_sender_audio_->RegisterAudioPayload("telephone-event", payload_type,
857 payload_frequency, 0, 0);
Niels Möller530ead42018-10-04 14:28:39 +0200858}
859
Amit Hilbuch77938e62018-12-21 09:23:38 -0800860void ChannelSend::SetRid(const std::string& rid,
861 int extension_id,
862 int repaired_extension_id) {
863 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
864 if (extension_id != 0) {
Sebastian Janssonf39c8152019-10-14 17:32:21 +0200865 SetSendRtpHeaderExtension(!rid.empty(), RtpStreamId::kUri, extension_id);
Amit Hilbuch77938e62018-12-21 09:23:38 -0800866 }
867 if (repaired_extension_id != 0) {
Sebastian Janssonf39c8152019-10-14 17:32:21 +0200868 SetSendRtpHeaderExtension(!rid.empty(), RtpStreamId::kUri,
869 repaired_extension_id);
Amit Hilbuch77938e62018-12-21 09:23:38 -0800870 }
871 _rtpRtcpModule->SetRid(rid);
872}
873
Niels Möller530ead42018-10-04 14:28:39 +0200874void ChannelSend::SetMid(const std::string& mid, int extension_id) {
Niels Möller26e88b02018-11-19 15:08:13 +0100875 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Sebastian Janssonf39c8152019-10-14 17:32:21 +0200876 SetSendRtpHeaderExtension(true, RtpMid::kUri, extension_id);
Niels Möller530ead42018-10-04 14:28:39 +0200877 _rtpRtcpModule->SetMid(mid);
878}
879
Johannes Kron9190b822018-10-29 11:22:05 +0100880void ChannelSend::SetExtmapAllowMixed(bool extmap_allow_mixed) {
Niels Möller26e88b02018-11-19 15:08:13 +0100881 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Johannes Kron9190b822018-10-29 11:22:05 +0100882 _rtpRtcpModule->SetExtmapAllowMixed(extmap_allow_mixed);
883}
884
Niels Möller26815232018-11-16 09:32:40 +0100885void ChannelSend::SetSendAudioLevelIndicationStatus(bool enable, int id) {
Niels Möller26e88b02018-11-19 15:08:13 +0100886 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200887 _includeAudioLevelIndication = enable;
Sebastian Janssonf39c8152019-10-14 17:32:21 +0200888 SetSendRtpHeaderExtension(enable, AudioLevel::kUri, id);
Niels Möller530ead42018-10-04 14:28:39 +0200889}
890
891void ChannelSend::EnableSendTransportSequenceNumber(int id) {
Niels Möller26e88b02018-11-19 15:08:13 +0100892 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Sebastian Janssonf39c8152019-10-14 17:32:21 +0200893 SetSendRtpHeaderExtension(true, TransportSequenceNumber::kUri, id);
Niels Möller530ead42018-10-04 14:28:39 +0200894}
895
896void ChannelSend::RegisterSenderCongestionControlObjects(
897 RtpTransportControllerSendInterface* transport,
898 RtcpBandwidthObserver* bandwidth_observer) {
Niels Möller26e88b02018-11-19 15:08:13 +0100899 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Erik Språngaa59eca2019-07-24 14:52:55 +0200900 RtpPacketSender* rtp_packet_pacer = transport->packet_sender();
Niels Möller530ead42018-10-04 14:28:39 +0200901 TransportFeedbackObserver* transport_feedback_observer =
902 transport->transport_feedback_observer();
903 PacketRouter* packet_router = transport->packet_router();
904
Erik Språng59b86542019-06-23 18:24:46 +0200905 RTC_DCHECK(rtp_packet_pacer);
Niels Möller530ead42018-10-04 14:28:39 +0200906 RTC_DCHECK(transport_feedback_observer);
907 RTC_DCHECK(packet_router);
908 RTC_DCHECK(!packet_router_);
909 rtcp_observer_->SetBandwidthObserver(bandwidth_observer);
910 feedback_observer_proxy_->SetTransportFeedbackObserver(
911 transport_feedback_observer);
Erik Språng59b86542019-06-23 18:24:46 +0200912 rtp_packet_pacer_proxy_->SetPacketPacer(rtp_packet_pacer);
Niels Möller530ead42018-10-04 14:28:39 +0200913 _rtpRtcpModule->SetStorePacketsStatus(true, 600);
914 constexpr bool remb_candidate = false;
915 packet_router->AddSendRtpModule(_rtpRtcpModule.get(), remb_candidate);
916 packet_router_ = packet_router;
917}
918
919void ChannelSend::ResetSenderCongestionControlObjects() {
Niels Möller26e88b02018-11-19 15:08:13 +0100920 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200921 RTC_DCHECK(packet_router_);
922 _rtpRtcpModule->SetStorePacketsStatus(false, 600);
923 rtcp_observer_->SetBandwidthObserver(nullptr);
924 feedback_observer_proxy_->SetTransportFeedbackObserver(nullptr);
Niels Möller530ead42018-10-04 14:28:39 +0200925 packet_router_->RemoveSendRtpModule(_rtpRtcpModule.get());
926 packet_router_ = nullptr;
Erik Språng59b86542019-06-23 18:24:46 +0200927 rtp_packet_pacer_proxy_->SetPacketPacer(nullptr);
Niels Möller530ead42018-10-04 14:28:39 +0200928}
929
Niels Möller26815232018-11-16 09:32:40 +0100930void ChannelSend::SetRTCP_CNAME(absl::string_view c_name) {
Niels Möller26e88b02018-11-19 15:08:13 +0100931 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller26815232018-11-16 09:32:40 +0100932 // Note: SetCNAME() accepts a c string of length at most 255.
933 const std::string c_name_limited(c_name.substr(0, 255));
934 int ret = _rtpRtcpModule->SetCNAME(c_name_limited.c_str()) != 0;
935 RTC_DCHECK_EQ(0, ret) << "SetRTCP_CNAME() failed to set RTCP CNAME";
Niels Möller530ead42018-10-04 14:28:39 +0200936}
937
Niels Möller26815232018-11-16 09:32:40 +0100938std::vector<ReportBlock> ChannelSend::GetRemoteRTCPReportBlocks() const {
Niels Möller26e88b02018-11-19 15:08:13 +0100939 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +0200940 // Get the report blocks from the latest received RTCP Sender or Receiver
941 // Report. Each element in the vector contains the sender's SSRC and a
942 // report block according to RFC 3550.
943 std::vector<RTCPReportBlock> rtcp_report_blocks;
Niels Möller530ead42018-10-04 14:28:39 +0200944
Niels Möller26815232018-11-16 09:32:40 +0100945 int ret = _rtpRtcpModule->RemoteRTCPStat(&rtcp_report_blocks);
946 RTC_DCHECK_EQ(0, ret);
947
948 std::vector<ReportBlock> report_blocks;
Niels Möller530ead42018-10-04 14:28:39 +0200949
950 std::vector<RTCPReportBlock>::const_iterator it = rtcp_report_blocks.begin();
951 for (; it != rtcp_report_blocks.end(); ++it) {
952 ReportBlock report_block;
953 report_block.sender_SSRC = it->sender_ssrc;
954 report_block.source_SSRC = it->source_ssrc;
955 report_block.fraction_lost = it->fraction_lost;
956 report_block.cumulative_num_packets_lost = it->packets_lost;
957 report_block.extended_highest_sequence_number =
958 it->extended_highest_sequence_number;
959 report_block.interarrival_jitter = it->jitter;
960 report_block.last_SR_timestamp = it->last_sender_report_timestamp;
961 report_block.delay_since_last_SR = it->delay_since_last_sender_report;
Niels Möller26815232018-11-16 09:32:40 +0100962 report_blocks.push_back(report_block);
Niels Möller530ead42018-10-04 14:28:39 +0200963 }
Niels Möller26815232018-11-16 09:32:40 +0100964 return report_blocks;
Niels Möller530ead42018-10-04 14:28:39 +0200965}
966
Niels Möller26815232018-11-16 09:32:40 +0100967CallSendStatistics ChannelSend::GetRTCPStatistics() const {
Niels Möller26e88b02018-11-19 15:08:13 +0100968 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller26815232018-11-16 09:32:40 +0100969 CallSendStatistics stats = {0};
Niels Möller530ead42018-10-04 14:28:39 +0200970 stats.rttMs = GetRTT();
971
Henrik Boströmcf96e0f2019-04-17 13:51:53 +0200972 StreamDataCounters rtp_stats;
973 StreamDataCounters rtx_stats;
974 _rtpRtcpModule->GetSendStreamDataCounters(&rtp_stats, &rtx_stats);
Niels Möllerac0a4cb2019-10-09 15:01:33 +0200975 stats.payload_bytes_sent =
976 rtp_stats.transmitted.payload_bytes + rtx_stats.transmitted.payload_bytes;
977 stats.header_and_padding_bytes_sent =
978 rtp_stats.transmitted.padding_bytes + rtp_stats.transmitted.header_bytes +
979 rtx_stats.transmitted.padding_bytes + rtx_stats.transmitted.header_bytes;
980
Henrik Boströmcf96e0f2019-04-17 13:51:53 +0200981 // TODO(https://crbug.com/webrtc/10555): RTX retransmissions should show up in
982 // separate outbound-rtp stream objects.
983 stats.retransmitted_bytes_sent = rtp_stats.retransmitted.payload_bytes;
984 stats.packetsSent =
985 rtp_stats.transmitted.packets + rtx_stats.transmitted.packets;
986 stats.retransmitted_packets_sent = rtp_stats.retransmitted.packets;
Henrik Boström6e436d12019-05-27 12:19:33 +0200987 stats.report_block_datas = _rtpRtcpModule->GetLatestReportBlockData();
Niels Möller530ead42018-10-04 14:28:39 +0200988
Niels Möller26815232018-11-16 09:32:40 +0100989 return stats;
Niels Möller530ead42018-10-04 14:28:39 +0200990}
991
Niels Möller530ead42018-10-04 14:28:39 +0200992void ChannelSend::ProcessAndEncodeAudio(
993 std::unique_ptr<AudioFrame> audio_frame) {
Niels Möllerdced9f62018-11-19 10:27:07 +0100994 RTC_DCHECK_RUNS_SERIALIZED(&audio_thread_race_checker_);
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +0200995 RTC_DCHECK_GT(audio_frame->samples_per_channel_, 0);
996 RTC_DCHECK_LE(audio_frame->num_channels_, 8);
997
Niels Möller530ead42018-10-04 14:28:39 +0200998 // Profile time between when the audio frame is added to the task queue and
999 // when the task is actually executed.
1000 audio_frame->UpdateProfileTimeStamp();
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001001 encoder_queue_.PostTask(
1002 [this, audio_frame = std::move(audio_frame)]() mutable {
1003 RTC_DCHECK_RUN_ON(&encoder_queue_);
1004 if (!encoder_queue_is_active_) {
1005 return;
1006 }
1007 // Measure time between when the audio frame is added to the task queue
1008 // and when the task is actually executed. Goal is to keep track of
1009 // unwanted extra latency added by the task queue.
1010 RTC_HISTOGRAM_COUNTS_10000("WebRTC.Audio.EncodingTaskQueueLatencyMs",
1011 audio_frame->ElapsedProfileTimeMs());
Niels Möller530ead42018-10-04 14:28:39 +02001012
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001013 bool is_muted = InputMute();
1014 AudioFrameOperations::Mute(audio_frame.get(), previous_frame_muted_,
1015 is_muted);
Niels Möller530ead42018-10-04 14:28:39 +02001016
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001017 if (_includeAudioLevelIndication) {
1018 size_t length =
1019 audio_frame->samples_per_channel_ * audio_frame->num_channels_;
1020 RTC_CHECK_LE(length, AudioFrame::kMaxDataSizeBytes);
1021 if (is_muted && previous_frame_muted_) {
1022 rms_level_.AnalyzeMuted(length);
1023 } else {
1024 rms_level_.Analyze(
1025 rtc::ArrayView<const int16_t>(audio_frame->data(), length));
1026 }
1027 }
1028 previous_frame_muted_ = is_muted;
Niels Möller530ead42018-10-04 14:28:39 +02001029
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001030 // Add 10ms of raw (PCM) audio data to the encoder @ 32kHz.
Niels Möller530ead42018-10-04 14:28:39 +02001031
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001032 // The ACM resamples internally.
1033 audio_frame->timestamp_ = _timeStamp;
1034 // This call will trigger AudioPacketizationCallback::SendData if
1035 // encoding is done and payload is ready for packetization and
1036 // transmission. Otherwise, it will return without invoking the
1037 // callback.
1038 if (audio_coding_->Add10MsData(*audio_frame) < 0) {
1039 RTC_DLOG(LS_ERROR) << "ACM::Add10MsData() failed.";
1040 return;
1041 }
Niels Möller530ead42018-10-04 14:28:39 +02001042
Sebastian Janssonee5ec9a2019-09-17 20:34:03 +02001043 _timeStamp += static_cast<uint32_t>(audio_frame->samples_per_channel_);
1044 });
Niels Möller530ead42018-10-04 14:28:39 +02001045}
1046
Niels Möller530ead42018-10-04 14:28:39 +02001047ANAStats ChannelSend::GetANAStatistics() const {
Niels Möller26e88b02018-11-19 15:08:13 +01001048 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Niels Möller530ead42018-10-04 14:28:39 +02001049 return audio_coding_->GetANAStats();
1050}
1051
1052RtpRtcp* ChannelSend::GetRtpRtcp() const {
Sebastian Janssonc01367d2019-04-08 15:20:44 +02001053 RTC_DCHECK(module_process_thread_checker_.IsCurrent());
Niels Möller530ead42018-10-04 14:28:39 +02001054 return _rtpRtcpModule.get();
1055}
1056
Sebastian Janssonf39c8152019-10-14 17:32:21 +02001057void ChannelSend::SetSendRtpHeaderExtension(bool enable,
1058 absl::string_view uri,
1059 int id) {
1060 _rtpRtcpModule->DeregisterSendRtpHeaderExtension(uri);
Niels Möller530ead42018-10-04 14:28:39 +02001061 if (enable) {
Sebastian Janssonf39c8152019-10-14 17:32:21 +02001062 _rtpRtcpModule->RegisterRtpHeaderExtension(uri, id);
Niels Möller530ead42018-10-04 14:28:39 +02001063 }
Niels Möller530ead42018-10-04 14:28:39 +02001064}
1065
Niels Möller530ead42018-10-04 14:28:39 +02001066int64_t ChannelSend::GetRTT() const {
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001067 if (media_transport_config_.media_transport) {
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -08001068 // GetRTT is generally used in the RTCP codepath, where media transport is
1069 // not present and so it shouldn't be needed. But it's also invoked in
1070 // 'GetStats' method, and for now returning media transport RTT here gives
1071 // us "free" rtt stats for media transport.
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001072 auto target_rate =
1073 media_transport_config_.media_transport->GetLatestTargetTransferRate();
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -08001074 if (target_rate.has_value()) {
1075 return target_rate.value().network_estimate.round_trip_time.ms();
1076 }
1077
1078 return 0;
1079 }
Niels Möller530ead42018-10-04 14:28:39 +02001080 std::vector<RTCPReportBlock> report_blocks;
1081 _rtpRtcpModule->RemoteRTCPStat(&report_blocks);
1082
1083 if (report_blocks.empty()) {
1084 return 0;
1085 }
1086
1087 int64_t rtt = 0;
1088 int64_t avg_rtt = 0;
1089 int64_t max_rtt = 0;
1090 int64_t min_rtt = 0;
1091 // We don't know in advance the remote ssrc used by the other end's receiver
1092 // reports, so use the SSRC of the first report block for calculating the RTT.
1093 if (_rtpRtcpModule->RTT(report_blocks[0].sender_ssrc, &rtt, &avg_rtt,
1094 &min_rtt, &max_rtt) != 0) {
1095 return 0;
1096 }
1097 return rtt;
1098}
1099
Benjamin Wright78410ad2018-10-25 09:52:57 -07001100void ChannelSend::SetFrameEncryptor(
1101 rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) {
Niels Möller26e88b02018-11-19 15:08:13 +01001102 RTC_DCHECK_RUN_ON(&worker_thread_checker_);
Sebastian Jansson44dd9f22019-03-08 14:50:30 +01001103 encoder_queue_.PostTask([this, frame_encryptor]() mutable {
1104 RTC_DCHECK_RUN_ON(&encoder_queue_);
Sebastian Jansson7949f212019-03-05 13:41:48 +00001105 frame_encryptor_ = std::move(frame_encryptor);
Sebastian Jansson44dd9f22019-03-08 14:50:30 +01001106 });
Benjamin Wright84583f62018-10-04 14:22:34 -07001107}
1108
Anton Sukhanov626015d2019-02-04 15:16:06 -08001109// TODO(sukhanov): Consider moving TargetTransferRate observer to
1110// AudioSendStream. Since AudioSendStream owns encoder and configures ANA, it
1111// makes sense to consolidate all rate (and overhead) calculation there.
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -08001112void ChannelSend::OnTargetTransferRate(TargetTransferRate rate) {
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001113 RTC_DCHECK(media_transport_config_.media_transport);
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -08001114 OnReceivedRtt(rate.network_estimate.round_trip_time.ms());
1115}
1116
1117void ChannelSend::OnReceivedRtt(int64_t rtt_ms) {
1118 // Invoke audio encoders OnReceivedRtt().
Sebastian Jansson14a7cf92019-02-13 15:11:42 +01001119 CallEncoder(
1120 [rtt_ms](AudioEncoder* encoder) { encoder->OnReceivedRtt(rtt_ms); });
Piotr (Peter) Slatala179a3922018-11-16 09:57:58 -08001121}
1122
Niels Möllerdced9f62018-11-19 10:27:07 +01001123} // namespace
1124
1125std::unique_ptr<ChannelSendInterface> CreateChannelSend(
Sebastian Jansson977b3352019-03-04 17:43:34 +01001126 Clock* clock,
Sebastian Jansson44dd9f22019-03-08 14:50:30 +01001127 TaskQueueFactory* task_queue_factory,
Niels Möllerdced9f62018-11-19 10:27:07 +01001128 ProcessThread* module_process_thread,
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001129 const MediaTransportConfig& media_transport_config,
Anton Sukhanov626015d2019-02-04 15:16:06 -08001130 OverheadObserver* overhead_observer,
Niels Möllere9771992018-11-26 10:55:07 +01001131 Transport* rtp_transport,
Niels Möllerdced9f62018-11-19 10:27:07 +01001132 RtcpRttStats* rtcp_rtt_stats,
1133 RtcEventLog* rtc_event_log,
1134 FrameEncryptorInterface* frame_encryptor,
1135 const webrtc::CryptoOptions& crypto_options,
1136 bool extmap_allow_mixed,
Erik Språng4c2c4122019-07-11 15:20:15 +02001137 int rtcp_report_interval_ms,
1138 uint32_t ssrc) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001139 return std::make_unique<ChannelSend>(
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001140 clock, task_queue_factory, module_process_thread, media_transport_config,
Sebastian Jansson977b3352019-03-04 17:43:34 +01001141 overhead_observer, rtp_transport, rtcp_rtt_stats, rtc_event_log,
1142 frame_encryptor, crypto_options, extmap_allow_mixed,
Erik Språng4c2c4122019-07-11 15:20:15 +02001143 rtcp_report_interval_ms, ssrc);
Niels Möllerdced9f62018-11-19 10:27:07 +01001144}
1145
Niels Möller530ead42018-10-04 14:28:39 +02001146} // namespace voe
1147} // namespace webrtc