PeerConnectionCtx.h (6670B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef peerconnectionctx_h___h__ 6 #define peerconnectionctx_h___h__ 7 8 #include <map> 9 #include <string> 10 11 #include "MediaTransportHandler.h" // Mostly for IceLogPromise 12 #include "PeerConnectionImpl.h" 13 #include "api/field_trials_view.h" 14 #include "call/audio_state.h" 15 #include "mozIGeckoMediaPluginService.h" 16 #include "mozilla/StaticPrefs_media.h" 17 #include "mozilla/StaticPtr.h" 18 #include "nsIRunnable.h" 19 20 class WebrtcLogSinkHandle; 21 22 namespace webrtc { 23 class AudioDecoderFactory; 24 25 class MozTrialsConfig : public FieldTrialsView { 26 public: 27 MozTrialsConfig() = default; 28 std::string Lookup(absl::string_view key) const override { 29 // Upstream added a new default field trial string for 30 // CongestionWindow, that we don't want. In 31 // third_party/libwebrtc/rtc_base/experiments/rate_control_settings.cc 32 // they set kCongestionWindowDefaultFieldTrialString to 33 // "QueueSize:350,MinBitrate:30000,DropFrame:true". With QueueSize 34 // set, GoogCcNetworkController::UpdateCongestionWindowSize is 35 // called. Because negative values are calculated in 36 // feedback_rtt, an assert fires when calculating data_window in 37 // GoogCcNetworkController::UpdateCongestionWindowSize. We probably 38 // need to figure out why we're calculating negative feedback_rtt. 39 // See Bug 1780620. 40 if ("WebRTC-CongestionWindow" == key) { 41 return std::string("MinBitrate:30000,DropFrame:true"); 42 } 43 if ("WebRTC-VP9-SvcForSimulcast" == key) { 44 return mozilla::StaticPrefs::media_webrtc_simulcast_vp9_enabled() 45 ? "Enabled" 46 : "Disabled"; 47 } 48 return std::string(); 49 } 50 }; 51 } // namespace webrtc 52 53 namespace mozilla { 54 class PeerConnectionCtxObserver; 55 56 namespace dom { 57 class WebrtcGlobalInformation; 58 } 59 60 /** 61 * Refcounted class containing state shared across all PeerConnections and all 62 * Call instances. Managed by PeerConnectionCtx, and kept around while there are 63 * registered peer connections. 64 */ 65 class SharedWebrtcState { 66 public: 67 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedWebrtcState) 68 69 SharedWebrtcState(RefPtr<AbstractThread> aCallWorkerThread, 70 webrtc::AudioState::Config&& aAudioStateConfig, 71 RefPtr<webrtc::AudioDecoderFactory> aAudioDecoderFactory, 72 UniquePtr<webrtc::FieldTrialsView> aTrials); 73 74 // A global Call worker thread shared between all Call instances. Implements 75 // AbstractThread for running tasks that call into a Call instance through its 76 // webrtc::TaskQueue member, and for using AbstractThread-specific higher 77 // order constructs like StateMirroring. 78 const RefPtr<AbstractThread> mCallWorkerThread; 79 80 // AudioState config containing dummy implementations of the audio stack, 81 // since we use our own audio stack instead. Shared across all Call instances. 82 const webrtc::AudioState::Config mAudioStateConfig; 83 84 // AudioDecoderFactory instance shared between calls, to limit the number of 85 // instances in large calls. 86 const RefPtr<webrtc::AudioDecoderFactory> mAudioDecoderFactory; 87 88 // Trials instance shared between calls, to limit the number of instances in 89 // large calls. 90 const UniquePtr<webrtc::FieldTrialsView> mTrials; 91 92 private: 93 virtual ~SharedWebrtcState(); 94 }; 95 96 // A class to hold some of the singleton objects we need: 97 // * The global PeerConnectionImpl table and its associated lock. 98 // * Stats report objects for PCs that are gone 99 // * GMP related state 100 // * Upstream webrtc state shared across all Calls (processing thread) 101 class PeerConnectionCtx { 102 public: 103 static nsresult InitializeGlobal(); 104 static PeerConnectionCtx* GetInstance(); 105 static bool isActive(); 106 static void Destroy(); 107 108 bool isReady() { 109 // If mGMPService is not set, we aren't using GMP. 110 if (mGMPService) { 111 return mGMPReady; 112 } 113 return true; 114 } 115 116 void queueJSEPOperation(nsIRunnable* aJSEPOperation); 117 void onGMPReady(); 118 119 static void UpdateNetworkState(bool online); 120 121 RefPtr<MediaTransportHandler> GetTransportHandler() const { 122 return mTransportHandler; 123 } 124 125 SharedWebrtcState* GetSharedWebrtcState() const; 126 127 void RemovePeerConnection(const std::string& aKey); 128 void AddPeerConnection(const std::string& aKey, 129 PeerConnectionImpl* aPeerConnection); 130 PeerConnectionImpl* GetPeerConnection(const std::string& aKey) const; 131 template <typename Function> 132 void ForEachPeerConnection(Function&& aFunction) const { 133 MOZ_ASSERT(NS_IsMainThread()); 134 for (const auto& pair : mPeerConnections) { 135 aFunction(pair.second); 136 } 137 } 138 139 void ClearClosedStats(); 140 141 private: 142 std::map<const std::string, PeerConnectionImpl*> mPeerConnections; 143 144 PeerConnectionCtx(); 145 146 // This is a singleton, so don't copy construct it, etc. 147 PeerConnectionCtx(const PeerConnectionCtx& other) = delete; 148 void operator=(const PeerConnectionCtx& other) = delete; 149 virtual ~PeerConnectionCtx() = default; 150 151 nsresult Initialize(); 152 nsresult StartTelemetryTimer(); 153 void StopTelemetryTimer(); 154 nsresult Cleanup(); 155 156 void initGMP(); 157 158 static void EverySecondTelemetryCallback_m(nsITimer* timer, void*); 159 160 nsCOMPtr<nsITimer> mTelemetryTimer; 161 162 private: 163 void DeliverStats(UniquePtr<dom::RTCStatsReportInternal>&& aReport); 164 165 std::map<nsString, UniquePtr<dom::RTCStatsReportInternal>> mLastReports; 166 // We cannot form offers/answers properly until the Gecko Media Plugin stuff 167 // has been initted, which is a complicated mess of thread dispatches, 168 // including sync dispatches to main. So, we need to be able to queue up 169 // offer creation (or SetRemote, when we're the answerer) until all of this is 170 // ready to go, since blocking on this init is just begging for deadlock. 171 nsCOMPtr<mozIGeckoMediaPluginService> mGMPService; 172 bool mGMPReady; 173 nsTArray<nsCOMPtr<nsIRunnable>> mQueuedJSEPOperations; 174 175 const RefPtr<WebrtcLogSinkHandle> mLogHandle; 176 177 // Not initted, just for ICE logging stuff 178 RefPtr<MediaTransportHandler> mTransportHandler; 179 180 // State used by libwebrtc that needs to be shared across all PeerConnections 181 // and all Call instances. Set while there is at least one peer connection 182 // registered. CallWrappers can hold a ref to this object to be sure members 183 // are alive long enough. 184 RefPtr<SharedWebrtcState> mSharedWebrtcState; 185 186 static PeerConnectionCtx* gInstance; 187 188 public: 189 static mozilla::StaticRefPtr<mozilla::PeerConnectionCtxObserver> 190 gPeerConnectionCtxObserver; 191 }; 192 193 } // namespace mozilla 194 195 #endif