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_CHANNEL_H_ 12 #define AUDIO_VOIP_AUDIO_CHANNEL_H_ 13 14 #include <map> 15 #include <memory> 16 #include <queue> 17 #include <utility> 18 19 #include "api/task_queue/task_queue_factory.h" 20 #include "api/voip/voip_base.h" 21 #include "api/voip/voip_statistics.h" 22 #include "audio/voip/audio_egress.h" 23 #include "audio/voip/audio_ingress.h" 24 #include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h" 25 #include "rtc_base/ref_count.h" 26 27 namespace webrtc { 28 29 // AudioChannel represents a single media session and provides APIs over 30 // AudioIngress and AudioEgress. Note that a single RTP stack is shared with 31 // these two classes as it has both sending and receiving capabilities. 32 class AudioChannel : public rtc::RefCountInterface { 33 public: 34 AudioChannel(Transport* transport, 35 uint32_t local_ssrc, 36 TaskQueueFactory* task_queue_factory, 37 AudioMixer* audio_mixer, 38 rtc::scoped_refptr<AudioDecoderFactory> decoder_factory); 39 ~AudioChannel() override; 40 41 // Set and get ChannelId that this audio channel belongs for debugging and 42 // logging purpose. SetId(ChannelId id)43 void SetId(ChannelId id) { id_ = id; } GetId()44 ChannelId GetId() const { return id_; } 45 46 // APIs to start/stop audio channel on each direction. 47 // StartSend/StartPlay returns false if encoder/decoders 48 // have not been set, respectively. 49 bool StartSend(); 50 void StopSend(); 51 bool StartPlay(); 52 void StopPlay(); 53 54 // APIs relayed to AudioEgress. IsSendingMedia()55 bool IsSendingMedia() const { return egress_->IsSending(); } GetAudioSender()56 AudioSender* GetAudioSender() { return egress_.get(); } SetEncoder(int payload_type,const SdpAudioFormat & encoder_format,std::unique_ptr<AudioEncoder> encoder)57 void SetEncoder(int payload_type, 58 const SdpAudioFormat& encoder_format, 59 std::unique_ptr<AudioEncoder> encoder) { 60 egress_->SetEncoder(payload_type, encoder_format, std::move(encoder)); 61 } GetEncoderFormat()62 absl::optional<SdpAudioFormat> GetEncoderFormat() const { 63 return egress_->GetEncoderFormat(); 64 } RegisterTelephoneEventType(int rtp_payload_type,int sample_rate_hz)65 void RegisterTelephoneEventType(int rtp_payload_type, int sample_rate_hz) { 66 egress_->RegisterTelephoneEventType(rtp_payload_type, sample_rate_hz); 67 } SendTelephoneEvent(int dtmf_event,int duration_ms)68 bool SendTelephoneEvent(int dtmf_event, int duration_ms) { 69 return egress_->SendTelephoneEvent(dtmf_event, duration_ms); 70 } SetMute(bool enable)71 void SetMute(bool enable) { egress_->SetMute(enable); } 72 73 // APIs relayed to AudioIngress. IsPlaying()74 bool IsPlaying() const { return ingress_->IsPlaying(); } ReceivedRTPPacket(rtc::ArrayView<const uint8_t> rtp_packet)75 void ReceivedRTPPacket(rtc::ArrayView<const uint8_t> rtp_packet) { 76 ingress_->ReceivedRTPPacket(rtp_packet); 77 } ReceivedRTCPPacket(rtc::ArrayView<const uint8_t> rtcp_packet)78 void ReceivedRTCPPacket(rtc::ArrayView<const uint8_t> rtcp_packet) { 79 ingress_->ReceivedRTCPPacket(rtcp_packet); 80 } SetReceiveCodecs(const std::map<int,SdpAudioFormat> & codecs)81 void SetReceiveCodecs(const std::map<int, SdpAudioFormat>& codecs) { 82 ingress_->SetReceiveCodecs(codecs); 83 } 84 IngressStatistics GetIngressStatistics(); 85 ChannelStatistics GetChannelStatistics(); 86 87 // See comments on the methods used from AudioEgress and AudioIngress. 88 // Conversion to double is following what is done in 89 // DoubleAudioLevelFromIntAudioLevel method in rtc_stats_collector.cc to be 90 // consistent. GetInputAudioLevel()91 double GetInputAudioLevel() const { 92 return egress_->GetInputAudioLevel() / 32767.0; 93 } GetInputTotalEnergy()94 double GetInputTotalEnergy() const { return egress_->GetInputTotalEnergy(); } GetInputTotalDuration()95 double GetInputTotalDuration() const { 96 return egress_->GetInputTotalDuration(); 97 } GetOutputAudioLevel()98 double GetOutputAudioLevel() const { 99 return ingress_->GetOutputAudioLevel() / 32767.0; 100 } GetOutputTotalEnergy()101 double GetOutputTotalEnergy() const { 102 return ingress_->GetOutputTotalEnergy(); 103 } GetOutputTotalDuration()104 double GetOutputTotalDuration() const { 105 return ingress_->GetOutputTotalDuration(); 106 } 107 108 // Internal API for testing purpose. SendRTCPReportForTesting(RTCPPacketType type)109 void SendRTCPReportForTesting(RTCPPacketType type) { 110 int32_t result = rtp_rtcp_->SendRTCP(type); 111 RTC_DCHECK(result == 0); 112 } 113 114 private: 115 // ChannelId that this audio channel belongs for logging purpose. 116 ChannelId id_; 117 118 // Synchronization is handled internally by AudioMixer. 119 AudioMixer* audio_mixer_; 120 121 // Listed in order for safe destruction of AudioChannel object. 122 // Synchronization for these are handled internally. 123 std::unique_ptr<ReceiveStatistics> receive_statistics_; 124 std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp_; 125 std::unique_ptr<AudioIngress> ingress_; 126 std::unique_ptr<AudioEgress> egress_; 127 }; 128 129 } // namespace webrtc 130 131 #endif // AUDIO_VOIP_AUDIO_CHANNEL_H_ 132