summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/libwebrtcglue/AudioConduit.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /dom/media/webrtc/libwebrtcglue/AudioConduit.h
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/media/webrtc/libwebrtcglue/AudioConduit.h')
-rw-r--r--dom/media/webrtc/libwebrtcglue/AudioConduit.h315
1 files changed, 315 insertions, 0 deletions
diff --git a/dom/media/webrtc/libwebrtcglue/AudioConduit.h b/dom/media/webrtc/libwebrtcglue/AudioConduit.h
new file mode 100644
index 0000000000..630b22b297
--- /dev/null
+++ b/dom/media/webrtc/libwebrtcglue/AudioConduit.h
@@ -0,0 +1,315 @@
+/* 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<int> ActiveSendPayloadType() const override;
+ Maybe<int> ActiveRecvPayloadType() const override;
+
+ void OnRtpReceived(MediaPacket&& aPacket, webrtc::RTPHeader&& aHeader);
+ void OnRtcpReceived(MediaPacket&& aPacket);
+
+ void OnRtcpBye() override;
+ void OnRtcpTimeout() override;
+
+ void SetTransportActive(bool aActive) override {
+ mTransportActive = aActive;
+ if (!aActive) {
+ mReceiverRtpEventListener.DisconnectIfExists();
+ mReceiverRtcpEventListener.DisconnectIfExists();
+ mSenderRtcpEventListener.DisconnectIfExists();
+ }
+ }
+ MediaEventSourceExc<MediaPacket>& SenderRtpSendEvent() override {
+ return mSenderRtpSendEvent;
+ }
+ MediaEventSourceExc<MediaPacket>& SenderRtcpSendEvent() override {
+ return mSenderRtcpSendEvent;
+ }
+ MediaEventSourceExc<MediaPacket>& ReceiverRtcpSendEvent() override {
+ return mReceiverRtcpSendEvent;
+ }
+ void ConnectReceiverRtpEvent(
+ MediaEventSourceExc<MediaPacket, webrtc::RTPHeader>& aEvent) override {
+ // Hold a strong-ref to `this` for safety, since we'll be disconnecting
+ // off-target.
+ mReceiverRtpEventListener = aEvent.Connect(
+ mCallThread, [this, self = RefPtr<WebrtcAudioConduit>(this)](
+ MediaPacket aPacket, webrtc::RTPHeader aHeader) {
+ OnRtpReceived(std::move(aPacket), std::move(aHeader));
+ });
+ }
+ void ConnectReceiverRtcpEvent(
+ MediaEventSourceExc<MediaPacket>& aEvent) override {
+ // Hold a strong-ref to `this` for safety, since we'll be disconnecting
+ // off-target.
+ mReceiverRtcpEventListener = aEvent.Connect(
+ mCallThread,
+ [this, self = RefPtr<WebrtcAudioConduit>(this)](MediaPacket aPacket) {
+ OnRtcpReceived(std::move(aPacket));
+ });
+ }
+ void ConnectSenderRtcpEvent(
+ MediaEventSourceExc<MediaPacket>& aEvent) override {
+ // Hold a strong-ref to `this` for safety, since we'll be disconnecting
+ // off-target.
+ mSenderRtcpEventListener = aEvent.Connect(
+ mCallThread,
+ [this, self = RefPtr<WebrtcAudioConduit>(this)](MediaPacket aPacket) {
+ OnRtcpReceived(std::move(aPacket));
+ });
+ }
+
+ 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 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;
+ }
+
+ 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;
+
+ 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;
+ 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;
+
+ 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;
+
+ // Thread safe
+ Atomic<bool> mTransportActive = Atomic<bool>(false);
+ MediaEventProducer<void> mRtcpByeEvent;
+ MediaEventProducer<void> mRtcpTimeoutEvent;
+ MediaEventProducerExc<MediaPacket> mSenderRtpSendEvent;
+ MediaEventProducerExc<MediaPacket> mSenderRtcpSendEvent;
+ MediaEventProducerExc<MediaPacket> 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