Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 1 | /* |
| 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 | #ifndef AUDIO_CHANNEL_SEND_H_ |
| 12 | #define AUDIO_CHANNEL_SEND_H_ |
| 13 | |
| 14 | #include <map> |
| 15 | #include <memory> |
| 16 | #include <string> |
| 17 | #include <vector> |
| 18 | |
| 19 | #include "api/audio/audio_frame.h" |
| 20 | #include "api/audio_codecs/audio_encoder.h" |
| 21 | #include "api/call/transport.h" |
Benjamin Wright | bfb444c | 2018-10-15 10:20:24 -0700 | [diff] [blame] | 22 | #include "api/crypto/cryptooptions.h" |
Niels Möller | 7d76a31 | 2018-10-26 12:57:07 +0200 | [diff] [blame] | 23 | #include "api/media_transport_interface.h" |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 24 | #include "common_types.h" // NOLINT(build/include) |
| 25 | #include "modules/audio_coding/include/audio_coding_module.h" |
| 26 | #include "modules/audio_processing/rms_level.h" |
| 27 | #include "modules/rtp_rtcp/include/rtp_rtcp.h" |
| 28 | #include "rtc_base/criticalsection.h" |
| 29 | #include "rtc_base/task_queue.h" |
| 30 | #include "rtc_base/thread_checker.h" |
| 31 | |
| 32 | // TODO(solenberg, nisse): This file contains a few NOLINT marks, to silence |
| 33 | // warnings about use of unsigned short, and non-const reference arguments. |
| 34 | // These need cleanup, in a separate cl. |
| 35 | |
| 36 | namespace rtc { |
| 37 | class TimestampWrapAroundHandler; |
| 38 | } |
| 39 | |
| 40 | namespace webrtc { |
| 41 | |
Benjamin Wright | 84583f6 | 2018-10-04 14:22:34 -0700 | [diff] [blame] | 42 | class FrameEncryptorInterface; |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 43 | class PacketRouter; |
| 44 | class ProcessThread; |
| 45 | class RateLimiter; |
| 46 | class RtcEventLog; |
| 47 | class RtpRtcp; |
| 48 | class RtpTransportControllerSendInterface; |
| 49 | |
| 50 | struct SenderInfo; |
| 51 | |
| 52 | struct CallSendStatistics { |
| 53 | int64_t rttMs; |
| 54 | size_t bytesSent; |
| 55 | int packetsSent; |
| 56 | }; |
| 57 | |
| 58 | // See section 6.4.2 in http://www.ietf.org/rfc/rfc3550.txt for details. |
| 59 | struct ReportBlock { |
| 60 | uint32_t sender_SSRC; // SSRC of sender |
| 61 | uint32_t source_SSRC; |
| 62 | uint8_t fraction_lost; |
| 63 | int32_t cumulative_num_packets_lost; |
| 64 | uint32_t extended_highest_sequence_number; |
| 65 | uint32_t interarrival_jitter; |
| 66 | uint32_t last_SR_timestamp; |
| 67 | uint32_t delay_since_last_SR; |
| 68 | }; |
| 69 | |
| 70 | namespace voe { |
| 71 | |
| 72 | class RtpPacketSenderProxy; |
| 73 | class TransportFeedbackProxy; |
| 74 | class TransportSequenceNumberProxy; |
| 75 | class VoERtcpObserver; |
| 76 | |
| 77 | // Helper class to simplify locking scheme for members that are accessed from |
| 78 | // multiple threads. |
| 79 | // Example: a member can be set on thread T1 and read by an internal audio |
| 80 | // thread T2. Accessing the member via this class ensures that we are |
| 81 | // safe and also avoid TSan v2 warnings. |
| 82 | class ChannelSendState { |
| 83 | public: |
| 84 | struct State { |
| 85 | bool sending = false; |
| 86 | }; |
| 87 | |
| 88 | ChannelSendState() {} |
| 89 | virtual ~ChannelSendState() {} |
| 90 | |
| 91 | void Reset() { |
| 92 | rtc::CritScope lock(&lock_); |
| 93 | state_ = State(); |
| 94 | } |
| 95 | |
| 96 | State Get() const { |
| 97 | rtc::CritScope lock(&lock_); |
| 98 | return state_; |
| 99 | } |
| 100 | |
| 101 | void SetSending(bool enable) { |
| 102 | rtc::CritScope lock(&lock_); |
| 103 | state_.sending = enable; |
| 104 | } |
| 105 | |
| 106 | private: |
| 107 | rtc::CriticalSection lock_; |
| 108 | State state_; |
| 109 | }; |
| 110 | |
| 111 | class ChannelSend |
| 112 | : public Transport, |
| 113 | public AudioPacketizationCallback, // receive encoded packets from the |
| 114 | // ACM |
| 115 | public OverheadObserver { |
| 116 | public: |
| 117 | // TODO(nisse): Make OnUplinkPacketLossRate public, and delete friend |
| 118 | // declaration. |
| 119 | friend class VoERtcpObserver; |
| 120 | |
| 121 | ChannelSend(rtc::TaskQueue* encoder_queue, |
| 122 | ProcessThread* module_process_thread, |
Niels Möller | 7d76a31 | 2018-10-26 12:57:07 +0200 | [diff] [blame] | 123 | MediaTransportInterface* media_transport, |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 124 | RtcpRttStats* rtcp_rtt_stats, |
Benjamin Wright | 84583f6 | 2018-10-04 14:22:34 -0700 | [diff] [blame] | 125 | RtcEventLog* rtc_event_log, |
Benjamin Wright | bfb444c | 2018-10-15 10:20:24 -0700 | [diff] [blame] | 126 | FrameEncryptorInterface* frame_encryptor, |
Johannes Kron | 9190b82 | 2018-10-29 11:22:05 +0100 | [diff] [blame] | 127 | const webrtc::CryptoOptions& crypto_options, |
Jiawei Ou | 5571812 | 2018-11-09 13:17:39 -0800 | [diff] [blame] | 128 | bool extmap_allow_mixed, |
| 129 | int rtcp_report_interval_ms); |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 130 | |
| 131 | virtual ~ChannelSend(); |
| 132 | |
| 133 | // Send using this encoder, with this payload type. |
| 134 | bool SetEncoder(int payload_type, std::unique_ptr<AudioEncoder> encoder); |
| 135 | void ModifyEncoder( |
| 136 | rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)> modifier); |
| 137 | |
| 138 | // API methods |
| 139 | |
Niels Möller | 2681523 | 2018-11-16 09:32:40 +0100 | [diff] [blame] | 140 | void StartSend(); |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 141 | void StopSend(); |
| 142 | |
| 143 | // Codecs |
| 144 | void SetBitRate(int bitrate_bps, int64_t probing_interval_ms); |
Sebastian Jansson | 359d60a | 2018-10-25 16:22:02 +0200 | [diff] [blame] | 145 | int GetBitRate() const; |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 146 | |
| 147 | // Network |
| 148 | void RegisterTransport(Transport* transport); |
Niels Möller | 2681523 | 2018-11-16 09:32:40 +0100 | [diff] [blame] | 149 | |
| 150 | bool ReceivedRTCPPacket(const uint8_t* data, size_t length); |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 151 | |
| 152 | // Muting, Volume and Level. |
| 153 | void SetInputMute(bool enable); |
| 154 | |
| 155 | // Stats. |
| 156 | ANAStats GetANAStatistics() const; |
| 157 | |
| 158 | // Used by AudioSendStream. |
| 159 | RtpRtcp* GetRtpRtcp() const; |
| 160 | |
| 161 | // DTMF. |
Niels Möller | 2681523 | 2018-11-16 09:32:40 +0100 | [diff] [blame] | 162 | bool SendTelephoneEventOutband(int event, int duration_ms); |
| 163 | bool SetSendTelephoneEventPayloadType(int payload_type, |
| 164 | int payload_frequency); |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 165 | |
| 166 | // RTP+RTCP |
Niels Möller | 2681523 | 2018-11-16 09:32:40 +0100 | [diff] [blame] | 167 | void SetLocalSSRC(uint32_t ssrc); |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 168 | |
| 169 | void SetMid(const std::string& mid, int extension_id); |
Johannes Kron | 9190b82 | 2018-10-29 11:22:05 +0100 | [diff] [blame] | 170 | void SetExtmapAllowMixed(bool extmap_allow_mixed); |
Niels Möller | 2681523 | 2018-11-16 09:32:40 +0100 | [diff] [blame] | 171 | void SetSendAudioLevelIndicationStatus(bool enable, int id); |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 172 | void EnableSendTransportSequenceNumber(int id); |
| 173 | |
| 174 | void RegisterSenderCongestionControlObjects( |
| 175 | RtpTransportControllerSendInterface* transport, |
| 176 | RtcpBandwidthObserver* bandwidth_observer); |
| 177 | void ResetSenderCongestionControlObjects(); |
Niels Möller | 2681523 | 2018-11-16 09:32:40 +0100 | [diff] [blame] | 178 | void SetRTCP_CNAME(absl::string_view c_name); |
| 179 | std::vector<ReportBlock> GetRemoteRTCPReportBlocks() const; |
| 180 | CallSendStatistics GetRTCPStatistics() const; |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 181 | void SetNACKStatus(bool enable, int maxNumberOfPackets); |
| 182 | |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 183 | // ProcessAndEncodeAudio() posts a task on the shared encoder task queue, |
| 184 | // which in turn calls (on the queue) ProcessAndEncodeAudioOnTaskQueue() where |
| 185 | // the actual processing of the audio takes place. The processing mainly |
| 186 | // consists of encoding and preparing the result for sending by adding it to a |
| 187 | // send queue. |
| 188 | // The main reason for using a task queue here is to release the native, |
| 189 | // OS-specific, audio capture thread as soon as possible to ensure that it |
| 190 | // can go back to sleep and be prepared to deliver an new captured audio |
| 191 | // packet. |
| 192 | void ProcessAndEncodeAudio(std::unique_ptr<AudioFrame> audio_frame); |
| 193 | |
Niels Möller | 2681523 | 2018-11-16 09:32:40 +0100 | [diff] [blame] | 194 | public: |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 195 | void SetTransportOverhead(size_t transport_overhead_per_packet); |
| 196 | |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 197 | // The existence of this function alongside OnUplinkPacketLossRate is |
| 198 | // a compromise. We want the encoder to be agnostic of the PLR source, but |
| 199 | // we also don't want it to receive conflicting information from TWCC and |
| 200 | // from RTCP-XR. |
| 201 | void OnTwccBasedUplinkPacketLossRate(float packet_loss_rate); |
| 202 | |
| 203 | void OnRecoverableUplinkPacketLossRate(float recoverable_packet_loss_rate); |
| 204 | |
| 205 | int64_t GetRTT() const; |
| 206 | |
Benjamin Wright | 84583f6 | 2018-10-04 14:22:34 -0700 | [diff] [blame] | 207 | // E2EE Custom Audio Frame Encryption |
Benjamin Wright | 78410ad | 2018-10-25 09:52:57 -0700 | [diff] [blame] | 208 | void SetFrameEncryptor( |
| 209 | rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor); |
Benjamin Wright | 84583f6 | 2018-10-04 14:22:34 -0700 | [diff] [blame] | 210 | |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 211 | private: |
| 212 | class ProcessAndEncodeAudioTask; |
| 213 | |
Niels Möller | 2681523 | 2018-11-16 09:32:40 +0100 | [diff] [blame] | 214 | // From AudioPacketizationCallback in the ACM |
| 215 | int32_t SendData(FrameType frameType, |
| 216 | uint8_t payloadType, |
| 217 | uint32_t timeStamp, |
| 218 | const uint8_t* payloadData, |
| 219 | size_t payloadSize, |
| 220 | const RTPFragmentationHeader* fragmentation) override; |
| 221 | |
| 222 | // From Transport (called by the RTP/RTCP module) |
| 223 | bool SendRtp(const uint8_t* data, |
| 224 | size_t len, |
| 225 | const PacketOptions& packet_options) override; |
| 226 | bool SendRtcp(const uint8_t* data, size_t len) override; |
| 227 | |
Niels Möller | 2681523 | 2018-11-16 09:32:40 +0100 | [diff] [blame] | 228 | bool Sending() const { return channel_state_.Get().sending; } |
| 229 | |
| 230 | // From OverheadObserver in the RTP/RTCP module |
| 231 | void OnOverheadChanged(size_t overhead_bytes_per_packet) override; |
| 232 | |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 233 | void OnUplinkPacketLossRate(float packet_loss_rate); |
| 234 | bool InputMute() const; |
| 235 | |
| 236 | int ResendPackets(const uint16_t* sequence_numbers, int length); |
| 237 | |
Niels Möller | 2681523 | 2018-11-16 09:32:40 +0100 | [diff] [blame] | 238 | int SetSendRtpHeaderExtension(bool enable, RTPExtensionType type, int id); |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 239 | |
| 240 | void UpdateOverheadForEncoder() |
| 241 | RTC_EXCLUSIVE_LOCKS_REQUIRED(overhead_per_packet_lock_); |
| 242 | |
| 243 | int GetRtpTimestampRateHz() const; |
| 244 | |
Niels Möller | 7d76a31 | 2018-10-26 12:57:07 +0200 | [diff] [blame] | 245 | int32_t SendRtpAudio(FrameType frameType, |
| 246 | uint8_t payloadType, |
| 247 | uint32_t timeStamp, |
| 248 | rtc::ArrayView<const uint8_t> payload, |
| 249 | const RTPFragmentationHeader* fragmentation); |
| 250 | |
| 251 | int32_t SendMediaTransportAudio(FrameType frameType, |
| 252 | uint8_t payloadType, |
| 253 | uint32_t timeStamp, |
| 254 | rtc::ArrayView<const uint8_t> payload, |
| 255 | const RTPFragmentationHeader* fragmentation); |
| 256 | |
| 257 | // Return media transport or nullptr if using RTP. |
| 258 | MediaTransportInterface* media_transport() { return media_transport_; } |
| 259 | |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 260 | // Called on the encoder task queue when a new input audio frame is ready |
| 261 | // for encoding. |
| 262 | void ProcessAndEncodeAudioOnTaskQueue(AudioFrame* audio_input); |
| 263 | |
| 264 | rtc::CriticalSection _callbackCritSect; |
| 265 | rtc::CriticalSection volume_settings_critsect_; |
| 266 | |
| 267 | ChannelSendState channel_state_; |
| 268 | |
| 269 | RtcEventLog* const event_log_; |
| 270 | |
| 271 | std::unique_ptr<RtpRtcp> _rtpRtcpModule; |
| 272 | |
| 273 | std::unique_ptr<AudioCodingModule> audio_coding_; |
| 274 | uint32_t _timeStamp RTC_GUARDED_BY(encoder_queue_); |
| 275 | |
| 276 | uint16_t send_sequence_number_; |
| 277 | |
| 278 | // uses |
| 279 | ProcessThread* _moduleProcessThreadPtr; |
| 280 | Transport* _transportPtr; // WebRtc socket or external transport |
| 281 | RmsLevel rms_level_ RTC_GUARDED_BY(encoder_queue_); |
| 282 | bool input_mute_ RTC_GUARDED_BY(volume_settings_critsect_); |
| 283 | bool previous_frame_muted_ RTC_GUARDED_BY(encoder_queue_); |
| 284 | // VoeRTP_RTCP |
| 285 | // TODO(henrika): can today be accessed on the main thread and on the |
| 286 | // task queue; hence potential race. |
| 287 | bool _includeAudioLevelIndication; |
| 288 | size_t transport_overhead_per_packet_ |
| 289 | RTC_GUARDED_BY(overhead_per_packet_lock_); |
| 290 | size_t rtp_overhead_per_packet_ RTC_GUARDED_BY(overhead_per_packet_lock_); |
| 291 | rtc::CriticalSection overhead_per_packet_lock_; |
| 292 | // RtcpBandwidthObserver |
| 293 | std::unique_ptr<VoERtcpObserver> rtcp_observer_; |
| 294 | |
| 295 | PacketRouter* packet_router_ = nullptr; |
| 296 | std::unique_ptr<TransportFeedbackProxy> feedback_observer_proxy_; |
| 297 | std::unique_ptr<TransportSequenceNumberProxy> seq_num_allocator_proxy_; |
| 298 | std::unique_ptr<RtpPacketSenderProxy> rtp_packet_sender_proxy_; |
| 299 | std::unique_ptr<RateLimiter> retransmission_rate_limiter_; |
| 300 | |
| 301 | rtc::ThreadChecker construction_thread_; |
| 302 | |
| 303 | const bool use_twcc_plr_for_ana_; |
| 304 | |
| 305 | rtc::CriticalSection encoder_queue_lock_; |
| 306 | bool encoder_queue_is_active_ RTC_GUARDED_BY(encoder_queue_lock_) = false; |
| 307 | rtc::TaskQueue* encoder_queue_ = nullptr; |
Benjamin Wright | 84583f6 | 2018-10-04 14:22:34 -0700 | [diff] [blame] | 308 | |
Niels Möller | 7d76a31 | 2018-10-26 12:57:07 +0200 | [diff] [blame] | 309 | MediaTransportInterface* const media_transport_; |
| 310 | int media_transport_sequence_number_ RTC_GUARDED_BY(encoder_queue_) = 0; |
| 311 | |
| 312 | rtc::CriticalSection media_transport_lock_; |
| 313 | // Currently set by SetLocalSSRC. |
| 314 | uint64_t media_transport_channel_id_ RTC_GUARDED_BY(&media_transport_lock_) = |
| 315 | 0; |
| 316 | // Cache payload type and sampling frequency from most recent call to |
| 317 | // SetEncoder. Needed to set MediaTransportEncodedAudioFrame metadata, and |
| 318 | // invalidate on encoder change. |
| 319 | int media_transport_payload_type_ RTC_GUARDED_BY(&media_transport_lock_); |
| 320 | int media_transport_sampling_frequency_ |
| 321 | RTC_GUARDED_BY(&media_transport_lock_); |
| 322 | |
Benjamin Wright | 84583f6 | 2018-10-04 14:22:34 -0700 | [diff] [blame] | 323 | // E2EE Audio Frame Encryption |
Benjamin Wright | 78410ad | 2018-10-25 09:52:57 -0700 | [diff] [blame] | 324 | rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor_; |
Benjamin Wright | bfb444c | 2018-10-15 10:20:24 -0700 | [diff] [blame] | 325 | // E2EE Frame Encryption Options |
| 326 | webrtc::CryptoOptions crypto_options_; |
Piotr (Peter) Slatala | 1eebec9 | 2018-11-16 09:03:35 -0800 | [diff] [blame^] | 327 | |
| 328 | rtc::CriticalSection bitrate_crit_section_; |
| 329 | int configured_bitrate_bps_ RTC_GUARDED_BY(bitrate_crit_section_) = 0; |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 330 | }; |
| 331 | |
| 332 | } // namespace voe |
| 333 | } // namespace webrtc |
| 334 | |
| 335 | #endif // AUDIO_CHANNEL_SEND_H_ |