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