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