1 /* 2 * Copyright (c) 2020 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_VOIP_AUDIO_INGRESS_H_ 12 #define AUDIO_VOIP_AUDIO_INGRESS_H_ 13 14 #include <algorithm> 15 #include <atomic> 16 #include <map> 17 #include <memory> 18 #include <utility> 19 20 #include "api/array_view.h" 21 #include "api/audio/audio_mixer.h" 22 #include "api/rtp_headers.h" 23 #include "api/scoped_refptr.h" 24 #include "audio/audio_level.h" 25 #include "modules/audio_coding/acm2/acm_receiver.h" 26 #include "modules/audio_coding/include/audio_coding_module.h" 27 #include "modules/rtp_rtcp/include/receive_statistics.h" 28 #include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h" 29 #include "modules/rtp_rtcp/source/rtp_packet_received.h" 30 #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" 31 #include "rtc_base/synchronization/mutex.h" 32 #include "rtc_base/time_utils.h" 33 34 namespace webrtc { 35 36 // AudioIngress handles incoming RTP/RTCP packets from the remote 37 // media endpoint. Received RTP packets are injected into AcmReceiver and 38 // when audio output thread requests for audio samples to play through system 39 // output such as speaker device, AudioIngress provides the samples via its 40 // implementation on AudioMixer::Source interface. 41 // 42 // Note that this class is originally based on ChannelReceive in 43 // audio/channel_receive.cc with non-audio related logic trimmed as aimed for 44 // smaller footprint. 45 class AudioIngress : public AudioMixer::Source { 46 public: 47 AudioIngress(RtpRtcpInterface* rtp_rtcp, 48 Clock* clock, 49 ReceiveStatistics* receive_statistics, 50 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory); 51 ~AudioIngress() override; 52 53 // Start or stop receiving operation of AudioIngress. StartPlay()54 void StartPlay() { playing_ = true; } StopPlay()55 void StopPlay() { 56 playing_ = false; 57 output_audio_level_.ResetLevelFullRange(); 58 } 59 60 // Query the state of the AudioIngress. IsPlaying()61 bool IsPlaying() const { return playing_; } 62 63 // Set the decoder formats and payload type for AcmReceiver where the 64 // key type (int) of the map is the payload type of SdpAudioFormat. 65 void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs); 66 67 // APIs to handle received RTP/RTCP packets from caller. 68 void ReceivedRTPPacket(rtc::ArrayView<const uint8_t> rtp_packet); 69 void ReceivedRTCPPacket(rtc::ArrayView<const uint8_t> rtcp_packet); 70 71 // Retrieve highest speech output level in last 100 ms. Note that 72 // this isn't RMS but absolute raw audio level on int16_t sample unit. 73 // Therefore, the return value will vary between 0 ~ 0xFFFF. This type of 74 // value may be useful to be used for measuring active speaker gauge. GetSpeechOutputLevelFullRange()75 int GetSpeechOutputLevelFullRange() const { 76 return output_audio_level_.LevelFullRange(); 77 } 78 79 // Returns network round trip time (RTT) measued by RTCP exchange with 80 // remote media endpoint. RTT value -1 indicates that it's not initialized. 81 int64_t GetRoundTripTime(); 82 GetNetworkStatistics()83 NetworkStatistics GetNetworkStatistics() const { 84 NetworkStatistics stats; 85 acm_receiver_.GetNetworkStatistics(&stats); 86 return stats; 87 } GetDecodingStatistics()88 AudioDecodingCallStats GetDecodingStatistics() const { 89 AudioDecodingCallStats stats; 90 acm_receiver_.GetDecodingCallStatistics(&stats); 91 return stats; 92 } 93 94 // Implementation of AudioMixer::Source interface. 95 AudioMixer::Source::AudioFrameInfo GetAudioFrameWithInfo( 96 int sampling_rate, 97 AudioFrame* audio_frame) override; Ssrc()98 int Ssrc() const override { 99 return rtc::dchecked_cast<int>(remote_ssrc_.load()); 100 } PreferredSampleRate()101 int PreferredSampleRate() const override { 102 // If we haven't received any RTP packet from remote and thus 103 // last_packet_sampling_rate is not available then use NetEq's sampling 104 // rate as that would be what would be used for audio output sample. 105 return std::max(acm_receiver_.last_packet_sample_rate_hz().value_or(0), 106 acm_receiver_.last_output_sample_rate_hz()); 107 } 108 109 private: 110 // Indicates AudioIngress status as caller invokes Start/StopPlaying. 111 // If not playing, incoming RTP data processing is skipped, thus 112 // producing no data to output device. 113 std::atomic<bool> playing_; 114 115 // Currently active remote ssrc from remote media endpoint. 116 std::atomic<uint32_t> remote_ssrc_; 117 118 // The first rtp timestamp of the output audio frame that is used to 119 // calculate elasped time for subsequent audio frames. 120 std::atomic<int64_t> first_rtp_timestamp_; 121 122 // Synchronizaton is handled internally by ReceiveStatistics. 123 ReceiveStatistics* const rtp_receive_statistics_; 124 125 // Synchronizaton is handled internally by RtpRtcpInterface. 126 RtpRtcpInterface* const rtp_rtcp_; 127 128 // Synchronizaton is handled internally by acm2::AcmReceiver. 129 acm2::AcmReceiver acm_receiver_; 130 131 // Synchronizaton is handled internally by voe::AudioLevel. 132 voe::AudioLevel output_audio_level_; 133 134 Mutex lock_; 135 136 RemoteNtpTimeEstimator ntp_estimator_ RTC_GUARDED_BY(lock_); 137 138 // For receiving RTP statistics, this tracks the sampling rate value 139 // per payload type set when caller set via SetReceiveCodecs. 140 std::map<int, int> receive_codec_info_ RTC_GUARDED_BY(lock_); 141 142 rtc::TimestampWrapAroundHandler timestamp_wrap_handler_ RTC_GUARDED_BY(lock_); 143 }; 144 145 } // namespace webrtc 146 147 #endif // AUDIO_VOIP_AUDIO_INGRESS_H_ 148