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, |
| 127 | const webrtc::CryptoOptions& crypto_options); |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 128 | |
| 129 | virtual ~ChannelSend(); |
| 130 | |
| 131 | // Send using this encoder, with this payload type. |
| 132 | bool SetEncoder(int payload_type, std::unique_ptr<AudioEncoder> encoder); |
| 133 | void ModifyEncoder( |
| 134 | rtc::FunctionView<void(std::unique_ptr<AudioEncoder>*)> modifier); |
| 135 | |
| 136 | // API methods |
| 137 | |
| 138 | // VoEBase |
| 139 | int32_t StartSend(); |
| 140 | void StopSend(); |
| 141 | |
| 142 | // Codecs |
| 143 | void SetBitRate(int bitrate_bps, int64_t probing_interval_ms); |
Sebastian Jansson | 359d60a | 2018-10-25 16:22:02 +0200 | [diff] [blame] | 144 | int GetBitRate() const; |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 145 | bool EnableAudioNetworkAdaptor(const std::string& config_string); |
| 146 | void DisableAudioNetworkAdaptor(); |
| 147 | |
| 148 | // TODO(nisse): Modifies decoder, but not used? |
| 149 | void SetReceiverFrameLengthRange(int min_frame_length_ms, |
| 150 | int max_frame_length_ms); |
| 151 | |
| 152 | // Network |
| 153 | void RegisterTransport(Transport* transport); |
| 154 | // TODO(nisse, solenberg): Delete when VoENetwork is deleted. |
| 155 | int32_t ReceivedRTCPPacket(const uint8_t* data, size_t length); |
| 156 | |
| 157 | // Muting, Volume and Level. |
| 158 | void SetInputMute(bool enable); |
| 159 | |
| 160 | // Stats. |
| 161 | ANAStats GetANAStatistics() const; |
| 162 | |
| 163 | // Used by AudioSendStream. |
| 164 | RtpRtcp* GetRtpRtcp() const; |
| 165 | |
| 166 | // DTMF. |
| 167 | int SendTelephoneEventOutband(int event, int duration_ms); |
| 168 | int SetSendTelephoneEventPayloadType(int payload_type, int payload_frequency); |
| 169 | |
| 170 | // RTP+RTCP |
| 171 | int SetLocalSSRC(unsigned int ssrc); |
| 172 | |
| 173 | void SetMid(const std::string& mid, int extension_id); |
| 174 | int SetSendAudioLevelIndicationStatus(bool enable, unsigned char id); |
| 175 | void EnableSendTransportSequenceNumber(int id); |
| 176 | |
| 177 | void RegisterSenderCongestionControlObjects( |
| 178 | RtpTransportControllerSendInterface* transport, |
| 179 | RtcpBandwidthObserver* bandwidth_observer); |
| 180 | void ResetSenderCongestionControlObjects(); |
| 181 | void SetRTCPStatus(bool enable); |
| 182 | int SetRTCP_CNAME(const char cName[256]); |
| 183 | int GetRemoteRTCPReportBlocks(std::vector<ReportBlock>* report_blocks); |
| 184 | int GetRTPStatistics(CallSendStatistics& stats); // NOLINT |
| 185 | void SetNACKStatus(bool enable, int maxNumberOfPackets); |
| 186 | |
| 187 | // From AudioPacketizationCallback in the ACM |
| 188 | int32_t SendData(FrameType frameType, |
| 189 | uint8_t payloadType, |
| 190 | uint32_t timeStamp, |
| 191 | const uint8_t* payloadData, |
| 192 | size_t payloadSize, |
| 193 | const RTPFragmentationHeader* fragmentation) override; |
| 194 | |
| 195 | // From Transport (called by the RTP/RTCP module) |
| 196 | bool SendRtp(const uint8_t* data, |
| 197 | size_t len, |
| 198 | const PacketOptions& packet_options) override; |
| 199 | bool SendRtcp(const uint8_t* data, size_t len) override; |
| 200 | |
| 201 | int PreferredSampleRate() const; |
| 202 | |
| 203 | bool Sending() const { return channel_state_.Get().sending; } |
| 204 | RtpRtcp* RtpRtcpModulePtr() const { return _rtpRtcpModule.get(); } |
| 205 | |
| 206 | // ProcessAndEncodeAudio() posts a task on the shared encoder task queue, |
| 207 | // which in turn calls (on the queue) ProcessAndEncodeAudioOnTaskQueue() where |
| 208 | // the actual processing of the audio takes place. The processing mainly |
| 209 | // consists of encoding and preparing the result for sending by adding it to a |
| 210 | // send queue. |
| 211 | // The main reason for using a task queue here is to release the native, |
| 212 | // OS-specific, audio capture thread as soon as possible to ensure that it |
| 213 | // can go back to sleep and be prepared to deliver an new captured audio |
| 214 | // packet. |
| 215 | void ProcessAndEncodeAudio(std::unique_ptr<AudioFrame> audio_frame); |
| 216 | |
| 217 | void SetTransportOverhead(size_t transport_overhead_per_packet); |
| 218 | |
| 219 | // From OverheadObserver in the RTP/RTCP module |
| 220 | void OnOverheadChanged(size_t overhead_bytes_per_packet) override; |
| 221 | |
| 222 | // The existence of this function alongside OnUplinkPacketLossRate is |
| 223 | // a compromise. We want the encoder to be agnostic of the PLR source, but |
| 224 | // we also don't want it to receive conflicting information from TWCC and |
| 225 | // from RTCP-XR. |
| 226 | void OnTwccBasedUplinkPacketLossRate(float packet_loss_rate); |
| 227 | |
| 228 | void OnRecoverableUplinkPacketLossRate(float recoverable_packet_loss_rate); |
| 229 | |
| 230 | int64_t GetRTT() const; |
| 231 | |
Benjamin Wright | 84583f6 | 2018-10-04 14:22:34 -0700 | [diff] [blame] | 232 | // E2EE Custom Audio Frame Encryption |
Benjamin Wright | 78410ad | 2018-10-25 09:52:57 -0700 | [diff] [blame] | 233 | void SetFrameEncryptor( |
| 234 | rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor); |
Benjamin Wright | 84583f6 | 2018-10-04 14:22:34 -0700 | [diff] [blame] | 235 | |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 236 | private: |
| 237 | class ProcessAndEncodeAudioTask; |
| 238 | |
| 239 | void Init(); |
| 240 | void Terminate(); |
| 241 | |
| 242 | void OnUplinkPacketLossRate(float packet_loss_rate); |
| 243 | bool InputMute() const; |
| 244 | |
| 245 | int ResendPackets(const uint16_t* sequence_numbers, int length); |
| 246 | |
| 247 | int SetSendRtpHeaderExtension(bool enable, |
| 248 | RTPExtensionType type, |
| 249 | unsigned char id); |
| 250 | |
| 251 | void UpdateOverheadForEncoder() |
| 252 | RTC_EXCLUSIVE_LOCKS_REQUIRED(overhead_per_packet_lock_); |
| 253 | |
| 254 | int GetRtpTimestampRateHz() const; |
| 255 | |
Niels Möller | 7d76a31 | 2018-10-26 12:57:07 +0200 | [diff] [blame^] | 256 | int32_t SendRtpAudio(FrameType frameType, |
| 257 | uint8_t payloadType, |
| 258 | uint32_t timeStamp, |
| 259 | rtc::ArrayView<const uint8_t> payload, |
| 260 | const RTPFragmentationHeader* fragmentation); |
| 261 | |
| 262 | int32_t SendMediaTransportAudio(FrameType frameType, |
| 263 | uint8_t payloadType, |
| 264 | uint32_t timeStamp, |
| 265 | rtc::ArrayView<const uint8_t> payload, |
| 266 | const RTPFragmentationHeader* fragmentation); |
| 267 | |
| 268 | // Return media transport or nullptr if using RTP. |
| 269 | MediaTransportInterface* media_transport() { return media_transport_; } |
| 270 | |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 271 | // Called on the encoder task queue when a new input audio frame is ready |
| 272 | // for encoding. |
| 273 | void ProcessAndEncodeAudioOnTaskQueue(AudioFrame* audio_input); |
| 274 | |
| 275 | rtc::CriticalSection _callbackCritSect; |
| 276 | rtc::CriticalSection volume_settings_critsect_; |
| 277 | |
| 278 | ChannelSendState channel_state_; |
| 279 | |
| 280 | RtcEventLog* const event_log_; |
| 281 | |
| 282 | std::unique_ptr<RtpRtcp> _rtpRtcpModule; |
| 283 | |
| 284 | std::unique_ptr<AudioCodingModule> audio_coding_; |
| 285 | uint32_t _timeStamp RTC_GUARDED_BY(encoder_queue_); |
| 286 | |
| 287 | uint16_t send_sequence_number_; |
| 288 | |
| 289 | // uses |
| 290 | ProcessThread* _moduleProcessThreadPtr; |
| 291 | Transport* _transportPtr; // WebRtc socket or external transport |
| 292 | RmsLevel rms_level_ RTC_GUARDED_BY(encoder_queue_); |
| 293 | bool input_mute_ RTC_GUARDED_BY(volume_settings_critsect_); |
| 294 | bool previous_frame_muted_ RTC_GUARDED_BY(encoder_queue_); |
| 295 | // VoeRTP_RTCP |
| 296 | // TODO(henrika): can today be accessed on the main thread and on the |
| 297 | // task queue; hence potential race. |
| 298 | bool _includeAudioLevelIndication; |
| 299 | size_t transport_overhead_per_packet_ |
| 300 | RTC_GUARDED_BY(overhead_per_packet_lock_); |
| 301 | size_t rtp_overhead_per_packet_ RTC_GUARDED_BY(overhead_per_packet_lock_); |
| 302 | rtc::CriticalSection overhead_per_packet_lock_; |
| 303 | // RtcpBandwidthObserver |
| 304 | std::unique_ptr<VoERtcpObserver> rtcp_observer_; |
| 305 | |
| 306 | PacketRouter* packet_router_ = nullptr; |
| 307 | std::unique_ptr<TransportFeedbackProxy> feedback_observer_proxy_; |
| 308 | std::unique_ptr<TransportSequenceNumberProxy> seq_num_allocator_proxy_; |
| 309 | std::unique_ptr<RtpPacketSenderProxy> rtp_packet_sender_proxy_; |
| 310 | std::unique_ptr<RateLimiter> retransmission_rate_limiter_; |
| 311 | |
| 312 | rtc::ThreadChecker construction_thread_; |
| 313 | |
| 314 | const bool use_twcc_plr_for_ana_; |
| 315 | |
| 316 | rtc::CriticalSection encoder_queue_lock_; |
| 317 | bool encoder_queue_is_active_ RTC_GUARDED_BY(encoder_queue_lock_) = false; |
| 318 | rtc::TaskQueue* encoder_queue_ = nullptr; |
Benjamin Wright | 84583f6 | 2018-10-04 14:22:34 -0700 | [diff] [blame] | 319 | |
Niels Möller | 7d76a31 | 2018-10-26 12:57:07 +0200 | [diff] [blame^] | 320 | MediaTransportInterface* const media_transport_; |
| 321 | int media_transport_sequence_number_ RTC_GUARDED_BY(encoder_queue_) = 0; |
| 322 | |
| 323 | rtc::CriticalSection media_transport_lock_; |
| 324 | // Currently set by SetLocalSSRC. |
| 325 | uint64_t media_transport_channel_id_ RTC_GUARDED_BY(&media_transport_lock_) = |
| 326 | 0; |
| 327 | // Cache payload type and sampling frequency from most recent call to |
| 328 | // SetEncoder. Needed to set MediaTransportEncodedAudioFrame metadata, and |
| 329 | // invalidate on encoder change. |
| 330 | int media_transport_payload_type_ RTC_GUARDED_BY(&media_transport_lock_); |
| 331 | int media_transport_sampling_frequency_ |
| 332 | RTC_GUARDED_BY(&media_transport_lock_); |
| 333 | |
Benjamin Wright | 84583f6 | 2018-10-04 14:22:34 -0700 | [diff] [blame] | 334 | // E2EE Audio Frame Encryption |
Benjamin Wright | 78410ad | 2018-10-25 09:52:57 -0700 | [diff] [blame] | 335 | rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor_; |
Benjamin Wright | bfb444c | 2018-10-15 10:20:24 -0700 | [diff] [blame] | 336 | // E2EE Frame Encryption Options |
| 337 | webrtc::CryptoOptions crypto_options_; |
Sebastian Jansson | 359d60a | 2018-10-25 16:22:02 +0200 | [diff] [blame] | 338 | int configured_bitrate_bps_ = 0; |
Niels Möller | 530ead4 | 2018-10-04 14:28:39 +0200 | [diff] [blame] | 339 | }; |
| 340 | |
| 341 | } // namespace voe |
| 342 | } // namespace webrtc |
| 343 | |
| 344 | #endif // AUDIO_CHANNEL_SEND_H_ |