Source code
Revision control
Copy as Markdown
Other Tools
/* 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,
#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"
/**
* 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<int> ActiveSendPayloadType() const override;
Maybe<int> ActiveRecvPayloadType() const override;
void OnRtpReceived(webrtc::RtpPacketReceived&& aPacket,
webrtc::RTPHeader&& aHeader);
void OnRtcpBye() override;
void OnRtcpTimeout() override;
void SetTransportActive(bool aActive) override;
MediaEventSourceExc<MediaPacket>& SenderRtpSendEvent() override {
return mSenderRtpSendEvent;
}
MediaEventSourceExc<MediaPacket>& SenderRtcpSendEvent() override {
return mSenderRtcpSendEvent;
}
MediaEventSourceExc<MediaPacket>& ReceiverRtcpSendEvent() override {
return mReceiverRtcpSendEvent;
}
void ConnectReceiverRtpEvent(
MediaEventSourceExc<webrtc::RtpPacketReceived, webrtc::RTPHeader>& aEvent)
override {
mReceiverRtpEventListener =
aEvent.Connect(mCallThread, this, &WebrtcAudioConduit::OnRtpReceived);
}
Maybe<uint16_t> 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<webrtc::AudioFrame> 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<GenericPromise> Shutdown() override;
WebrtcAudioConduit(RefPtr<WebrtcCallWrapper> aCall,
nsCOMPtr<nsISerialEventTarget> 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<Ssrc> 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<webrtc::AudioReceiveStreamInterface::Stats> GetReceiverStats()
const override;
Maybe<webrtc::AudioSendStream::Stats> GetSenderStats() const override;
Maybe<webrtc::CallBasicStats> GetCallStats() const override;
bool IsSamplingFreqSupported(int freq) const override;
MediaEventSource<void>& RtcpByeEvent() override { return mRtcpByeEvent; }
MediaEventSource<void>& RtcpTimeoutEvent() override {
return mRtcpTimeoutEvent;
}
MediaEventSource<void>& RtpPacketEvent() override { return mRtpPacketEvent; }
std::vector<webrtc::RtpSource> 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<WebrtcCallWrapper> 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<bool> mSendStreamRunning;
// If true => mRecvStream started and not stopped
// Written only on the Call thread.
Atomic<bool> 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<AbstractThread> mCallThread;
// Socket transport service thread. Any thread.
const nsCOMPtr<nsISerialEventTarget> 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<bool> mReceiving;
Mirror<bool> mTransmitting;
Mirror<Ssrcs> mLocalSsrcs;
Mirror<std::string> mLocalCname;
Mirror<std::string> mMid;
Mirror<Ssrc> mRemoteSsrc;
Mirror<std::string> mSyncGroup;
Mirror<RtpExtList> mLocalRecvRtpExtensions;
Mirror<RtpExtList> mLocalSendRtpExtensions;
Mirror<Maybe<AudioCodecConfig>> mSendCodec;
Mirror<std::vector<AudioCodecConfig>> mRecvCodecs;
Mirror<RefPtr<FrameTransformerProxy>> mFrameTransformerProxySend;
Mirror<RefPtr<FrameTransformerProxy>> mFrameTransformerProxyRecv;
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<AudioCodecConfig> mConfiguredSendCodec;
// For tracking changes to mRecvCodecs.
std::vector<AudioCodecConfig> mConfiguredRecvCodecs;
// For change tracking. Callthread only.
RefPtr<FrameTransformerProxy> mConfiguredFrameTransformerProxySend;
RefPtr<FrameTransformerProxy> mConfiguredFrameTransformerProxyRecv;
Control() = delete;
explicit Control(const RefPtr<AbstractThread>& aCallThread);
} mControl;
// WatchManager allowing Mirrors to trigger functions that will update the
// webrtc.org configuration.
WatchManager<WebrtcAudioConduit> mWatchManager;
// Accessed from mStsThread. Last successfully polled RTT
Maybe<DOMHighResTimeStamp> mRttSec;
// Call thread only. ssrc -> base_seq
std::map<uint32_t, uint16_t> mRtpSendBaseSeqs;
// libwebrtc network thread only. ssrc -> base_seq.
// To track changes needed to mRtpSendBaseSeqs.
std::map<uint32_t, uint16_t> mRtpSendBaseSeqs_n;
// Written only on the main thread. Guarded by mLock, except for
// reads on the main thread.
std::vector<webrtc::RtpSource> mRtpSources;
// Thread safe
Atomic<bool> mTransportActive = Atomic<bool>(false);
MediaEventProducer<void> mRtcpByeEvent;
MediaEventProducer<void> mRtcpTimeoutEvent;
MediaEventProducer<void> mRtpPacketEvent;
MediaEventProducerExc<MediaPacket> mSenderRtpSendEvent;
MediaEventProducerExc<MediaPacket> mSenderRtcpSendEvent;
MediaEventProducerExc<MediaPacket> mReceiverRtcpSendEvent;
// Assigned and revoked on mStsThread. Listeners for receiving packets.
MediaEventListener mReceiverRtpEventListener; // Rtp-receiving pipeline
};
} // namespace mozilla
#endif