diff options
Diffstat (limited to 'dom/media/webrtc/jsapi/PeerConnectionCtx.h')
-rw-r--r-- | dom/media/webrtc/jsapi/PeerConnectionCtx.h | 194 |
1 files changed, 194 insertions, 0 deletions
diff --git a/dom/media/webrtc/jsapi/PeerConnectionCtx.h b/dom/media/webrtc/jsapi/PeerConnectionCtx.h new file mode 100644 index 0000000000..fdd81f6406 --- /dev/null +++ b/dom/media/webrtc/jsapi/PeerConnectionCtx.h @@ -0,0 +1,194 @@ +/* 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 peerconnectionctx_h___h__ +#define peerconnectionctx_h___h__ + +#include <map> +#include <string> + +#include "WebrtcGlobalChild.h" +#include "api/field_trials_view.h" +#include "api/scoped_refptr.h" +#include "call/audio_state.h" +#include "MediaTransportHandler.h" // Mostly for IceLogPromise +#include "mozIGeckoMediaPluginService.h" +#include "mozilla/Attributes.h" +#include "mozilla/StaticPtr.h" +#include "nsIRunnable.h" +#include "PeerConnectionImpl.h" + +namespace webrtc { +class AudioDecoderFactory; + +// Used for testing in mediapipeline_unittest.cpp, MockCall.h +class NoTrialsConfig : public FieldTrialsView { + public: + NoTrialsConfig() = default; + std::string Lookup(absl::string_view key) const override { + // Upstream added a new default field trial string for + // CongestionWindow, that we don't want. In + // third_party/libwebrtc/rtc_base/experiments/rate_control_settings.cc + // they set kCongestionWindowDefaultFieldTrialString to + // "QueueSize:350,MinBitrate:30000,DropFrame:true". With QueueSize + // set, GoogCcNetworkController::UpdateCongestionWindowSize is + // called. Because negative values are calculated in + // feedback_rtt, an assert fires when calculating data_window in + // GoogCcNetworkController::UpdateCongestionWindowSize. We probably + // need to figure out why we're calculating negative feedback_rtt. + // See Bug 1780620. + if ("WebRTC-CongestionWindow" == key) { + return std::string("MinBitrate:30000,DropFrame:true"); + } + return std::string(); + } +}; +} // namespace webrtc + +namespace mozilla { +class PeerConnectionCtxObserver; + +namespace dom { +class WebrtcGlobalInformation; +} + +/** + * Refcounted class containing state shared across all PeerConnections and all + * Call instances. Managed by PeerConnectionCtx, and kept around while there are + * registered peer connections. + */ +class SharedWebrtcState { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWebrtcState) + + SharedWebrtcState(RefPtr<AbstractThread> aCallWorkerThread, + webrtc::AudioState::Config&& aAudioStateConfig, + RefPtr<webrtc::AudioDecoderFactory> aAudioDecoderFactory, + UniquePtr<webrtc::FieldTrialsView> aTrials); + + // A global Call worker thread shared between all Call instances. Implements + // AbstractThread for running tasks that call into a Call instance through its + // webrtc::TaskQueue member, and for using AbstractThread-specific higher + // order constructs like StateMirroring. + const RefPtr<AbstractThread> mCallWorkerThread; + + // AudioState config containing dummy implementations of the audio stack, + // since we use our own audio stack instead. Shared across all Call instances. + const webrtc::AudioState::Config mAudioStateConfig; + + // AudioDecoderFactory instance shared between calls, to limit the number of + // instances in large calls. + const RefPtr<webrtc::AudioDecoderFactory> mAudioDecoderFactory; + + // Trials instance shared between calls, to limit the number of instances in + // large calls. + const UniquePtr<webrtc::FieldTrialsView> mTrials; + + private: + virtual ~SharedWebrtcState(); +}; + +// A class to hold some of the singleton objects we need: +// * The global PeerConnectionImpl table and its associated lock. +// * Stats report objects for PCs that are gone +// * GMP related state +// * Upstream webrtc state shared across all Calls (processing thread) +class PeerConnectionCtx { + public: + static nsresult InitializeGlobal(); + static PeerConnectionCtx* GetInstance(); + static bool isActive(); + static void Destroy(); + + bool isReady() { + // If mGMPService is not set, we aren't using GMP. + if (mGMPService) { + return mGMPReady; + } + return true; + } + + void queueJSEPOperation(nsIRunnable* aJSEPOperation); + void onGMPReady(); + + bool gmpHasH264(); + + static void UpdateNetworkState(bool online); + + RefPtr<MediaTransportHandler> GetTransportHandler() const { + return mTransportHandler; + } + + SharedWebrtcState* GetSharedWebrtcState() const; + + void RemovePeerConnection(const std::string& aKey); + void AddPeerConnection(const std::string& aKey, + PeerConnectionImpl* aPeerConnection); + PeerConnectionImpl* GetPeerConnection(const std::string& aKey) const; + template <typename Function> + void ForEachPeerConnection(Function&& aFunction) const { + MOZ_ASSERT(NS_IsMainThread()); + for (const auto& pair : mPeerConnections) { + aFunction(pair.second); + } + } + + void ClearClosedStats(); + + private: + std::map<const std::string, PeerConnectionImpl*> mPeerConnections; + + PeerConnectionCtx() + : mGMPReady(false), + mTransportHandler( + MediaTransportHandler::Create(GetMainThreadSerialEventTarget())) {} + + // This is a singleton, so don't copy construct it, etc. + PeerConnectionCtx(const PeerConnectionCtx& other) = delete; + void operator=(const PeerConnectionCtx& other) = delete; + virtual ~PeerConnectionCtx() = default; + + nsresult Initialize(); + nsresult StartTelemetryTimer(); + void StopTelemetryTimer(); + nsresult Cleanup(); + + void initGMP(); + + static void EverySecondTelemetryCallback_m(nsITimer* timer, void*); + + nsCOMPtr<nsITimer> mTelemetryTimer; + + private: + void DeliverStats(UniquePtr<dom::RTCStatsReportInternal>&& aReport); + + std::map<nsString, UniquePtr<dom::RTCStatsReportInternal>> mLastReports; + // We cannot form offers/answers properly until the Gecko Media Plugin stuff + // has been initted, which is a complicated mess of thread dispatches, + // including sync dispatches to main. So, we need to be able to queue up + // offer creation (or SetRemote, when we're the answerer) until all of this is + // ready to go, since blocking on this init is just begging for deadlock. + nsCOMPtr<mozIGeckoMediaPluginService> mGMPService; + bool mGMPReady; + nsTArray<nsCOMPtr<nsIRunnable>> mQueuedJSEPOperations; + + // Not initted, just for ICE logging stuff + RefPtr<MediaTransportHandler> mTransportHandler; + + // State used by libwebrtc that needs to be shared across all PeerConnections + // and all Call instances. Set while there is at least one peer connection + // registered. CallWrappers can hold a ref to this object to be sure members + // are alive long enough. + RefPtr<SharedWebrtcState> mSharedWebrtcState; + + static PeerConnectionCtx* gInstance; + + public: + static mozilla::StaticRefPtr<mozilla::PeerConnectionCtxObserver> + gPeerConnectionCtxObserver; +}; + +} // namespace mozilla + +#endif |