/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef AUDIO_SESSION_H_ #define AUDIO_SESSION_H_ #include "mozilla/Attributes.h" #include "mozilla/ReentrantMonitor.h" #include "mozilla/RWLock.h" #include "mozilla/StateMirroring.h" #include "mozilla/TimeStamp.h" #include "MediaConduitInterface.h" #include "common/MediaEngineWrapper.h" /** * This file hosts several structures identifying different aspects of a RTP * Session. */ namespace mozilla { struct DtmfEvent; /** * Concrete class for Audio session. Hooks up * - media-source and target to external transport */ class WebrtcAudioConduit : public AudioSessionConduit, public webrtc::RtcpEventObserver { public: Maybe ActiveSendPayloadType() const override; Maybe ActiveRecvPayloadType() const override; void OnRtpReceived(webrtc::RtpPacketReceived&& aPacket, webrtc::RTPHeader&& aHeader); void OnRtcpReceived(MediaPacket&& aPacket); void OnRtcpBye() override; void OnRtcpTimeout() override; void SetTransportActive(bool aActive) override; MediaEventSourceExc& SenderRtpSendEvent() override { return mSenderRtpSendEvent; } MediaEventSourceExc& SenderRtcpSendEvent() override { return mSenderRtcpSendEvent; } MediaEventSourceExc& ReceiverRtcpSendEvent() override { return mReceiverRtcpSendEvent; } void ConnectReceiverRtpEvent( MediaEventSourceExc& aEvent) override { mReceiverRtpEventListener = aEvent.Connect(mCallThread, this, &WebrtcAudioConduit::OnRtpReceived); } void ConnectReceiverRtcpEvent( MediaEventSourceExc& aEvent) override { mReceiverRtcpEventListener = aEvent.Connect(mCallThread, this, &WebrtcAudioConduit::OnRtcpReceived); } void ConnectSenderRtcpEvent( MediaEventSourceExc& aEvent) override { mSenderRtcpEventListener = aEvent.Connect(mCallThread, this, &WebrtcAudioConduit::OnRtcpReceived); } Maybe RtpSendBaseSeqFor(uint32_t aSsrc) const override; const dom::RTCStatsTimestampMaker& GetTimestampMaker() const override; void StopTransmitting(); void StartTransmitting(); void StopReceiving(); void StartReceiving(); /** * Function to deliver externally captured audio sample for encoding and * transport * @param frame [in]: AudioFrame in upstream's format for forwarding to the * send stream. Ownership is passed along. * NOTE: ConfigureSendMediaCodec() SHOULD be called before this function can * be invoked. This ensures the inserted audio-samples can be transmitted by * the conduit. */ MediaConduitErrorCode SendAudioFrame( std::unique_ptr frame) override; /** * Function to grab a decoded audio-sample from the media engine for * rendering / playout of length 10 milliseconds. * * @param samplingFreqHz [in]: Frequency of the sampling for playback in * Hertz (16000, 32000,..) * @param frame [in/out]: Pointer to an AudioFrame to which audio data will be * copied * NOTE: This function should be invoked every 10 milliseconds for the best * performance * NOTE: ConfigureRecvMediaCodec() SHOULD be called before this function can * be invoked * This ensures the decoded samples are ready for reading and playout is * enabled. */ MediaConduitErrorCode GetAudioFrame(int32_t samplingFreqHz, webrtc::AudioFrame* frame) override; bool SendRtp(const uint8_t* aData, size_t aLength, const webrtc::PacketOptions& aOptions) override; bool SendSenderRtcp(const uint8_t* aData, size_t aLength) override; bool SendReceiverRtcp(const uint8_t* aData, size_t aLength) override; bool HasCodecPluginID(uint64_t aPluginID) const override { return false; } void SetJitterBufferTarget(DOMHighResTimeStamp aTargetMs) override; void DeliverPacket(rtc::CopyOnWriteBuffer packet, PacketType type) override; RefPtr Shutdown() override; WebrtcAudioConduit(RefPtr aCall, nsCOMPtr aStsThread); virtual ~WebrtcAudioConduit(); // Call thread. void InitControl(AudioConduitControlInterface* aControl) override; // Handle a DTMF event from mControl.mOnDtmfEventListener. void OnDtmfEvent(const DtmfEvent& aEvent); // Called when a parameter in mControl has changed. Call thread. void OnControlConfigChange(); Ssrcs GetLocalSSRCs() const override; Maybe GetRemoteSSRC() const override; void DisableSsrcChanges() override { MOZ_ASSERT(mCallThread->IsOnCurrentThread()); mAllowSsrcChange = false; } private: /** * Override the remote ssrc configured on mRecvStreamConfig. * * Recreates and restarts the recv stream if needed. The overriden value is * overwritten the next time the mControl.mRemoteSsrc mirror changes value. * * Call thread only. */ bool OverrideRemoteSSRC(uint32_t aSsrc); public: void UnsetRemoteSSRC(uint32_t aSsrc) override {} Maybe GetReceiverStats() const override; Maybe GetSenderStats() const override; Maybe GetCallStats() const override; bool IsSamplingFreqSupported(int freq) const override; MediaEventSource& RtcpByeEvent() override { return mRtcpByeEvent; } MediaEventSource& RtcpTimeoutEvent() override { return mRtcpTimeoutEvent; } MediaEventSource& RtpPacketEvent() override { return mRtpPacketEvent; } std::vector GetUpstreamRtpSources() const override; private: WebrtcAudioConduit(const WebrtcAudioConduit& other) = delete; void operator=(const WebrtcAudioConduit& other) = delete; // Generate block size in sample length for a given sampling frequency unsigned int GetNum10msSamplesForFrequency(int samplingFreqHz) const; // Checks the codec to be applied static MediaConduitErrorCode ValidateCodecConfig( const AudioCodecConfig& codecInfo, bool send); /** * Of all extensions in aExtensions, returns a list of supported extensions. */ static RtpExtList FilterExtensions( MediaSessionConduitLocalDirection aDirection, const RtpExtList& aExtensions); static webrtc::SdpAudioFormat CodecConfigToLibwebrtcFormat( const AudioCodecConfig& aConfig); void CreateSendStream(); void DeleteSendStream(); void CreateRecvStream(); void DeleteRecvStream(); // Are SSRC changes without signaling allowed or not. // Call thread only. bool mAllowSsrcChange = true; // Const so can be accessed on any thread. Most methods are called on the Call // thread. const RefPtr mCall; // Set up in the ctor and then not touched. Called through by the streams on // any thread. WebrtcSendTransport mSendTransport; WebrtcReceiveTransport mRecvTransport; // Accessed only on the Call thread. webrtc::AudioReceiveStreamInterface::Config mRecvStreamConfig; // Written only on the Call thread. Guarded by mLock, except for reads on the // Call thread. webrtc::AudioReceiveStreamInterface* mRecvStream; // Accessed only on the Call thread. webrtc::AudioSendStream::Config mSendStreamConfig; // Written only on the Call thread. Guarded by mLock, except for reads on the // Call thread. webrtc::AudioSendStream* mSendStream; // If true => mSendStream started and not stopped // Written only on the Call thread. Atomic mSendStreamRunning; // If true => mRecvStream started and not stopped // Written only on the Call thread. Atomic mRecvStreamRunning; // Accessed only on the Call thread. bool mDtmfEnabled; mutable RWLock mLock MOZ_UNANNOTATED; // Call worker thread. All access to mCall->Call() happens here. const RefPtr mCallThread; // Socket transport service thread. Any thread. const nsCOMPtr mStsThread; // Target jitter buffer to be applied to the receive stream in milliseconds. uint16_t mJitterBufferTargetMs = 0; struct Control { // Mirrors and events that map to AudioConduitControlInterface for control. // Call thread only. Mirror mReceiving; Mirror mTransmitting; Mirror mLocalSsrcs; Mirror mLocalCname; Mirror mMid; Mirror mRemoteSsrc; Mirror mSyncGroup; Mirror mLocalRecvRtpExtensions; Mirror mLocalSendRtpExtensions; Mirror> mSendCodec; Mirror> mRecvCodecs; MediaEventListener mOnDtmfEventListener; // For caching mRemoteSsrc, since another caller may change the remote ssrc // in the stream config directly. Ssrc mConfiguredRemoteSsrc = 0; // For tracking changes to mSendCodec. Maybe mConfiguredSendCodec; // For tracking changes to mRecvCodecs. std::vector mConfiguredRecvCodecs; Control() = delete; explicit Control(const RefPtr& aCallThread); } mControl; // WatchManager allowing Mirrors to trigger functions that will update the // webrtc.org configuration. WatchManager mWatchManager; // Accessed from mStsThread. Last successfully polled RTT Maybe mRttSec; // Call thread only. ssrc -> base_seq std::map mRtpSendBaseSeqs; // libwebrtc network thread only. ssrc -> base_seq. // To track changes needed to mRtpSendBaseSeqs. std::map mRtpSendBaseSeqs_n; // Thread safe Atomic mTransportActive = Atomic(false); MediaEventProducer mRtcpByeEvent; MediaEventProducer mRtcpTimeoutEvent; MediaEventProducer mRtpPacketEvent; MediaEventProducerExc mSenderRtpSendEvent; MediaEventProducerExc mSenderRtcpSendEvent; MediaEventProducerExc mReceiverRtcpSendEvent; // Assigned and revoked on mStsThread. Listeners for receiving packets. MediaEventListener mSenderRtcpEventListener; // Rtp-transmitting pipeline MediaEventListener mReceiverRtcpEventListener; // Rtp-receiving pipeline MediaEventListener mReceiverRtpEventListener; // Rtp-receiving pipeline }; } // namespace mozilla #endif