summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/jsapi/RTCRtpSender.h
blob: 9b26b6897ea9109726e5260c27d731a2c35a88c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/* 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 _RTCRtpSender_h_
#define _RTCRtpSender_h_

#include "nsISupports.h"
#include "nsWrapperCache.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StateMirroring.h"
#include "mozilla/Maybe.h"
#include "js/RootingAPI.h"
#include "libwebrtcglue/RtpRtcpConfig.h"
#include "nsTArray.h"
#include "mozilla/dom/RTCStatsReportBinding.h"
#include "mozilla/dom/RTCRtpCapabilitiesBinding.h"
#include "mozilla/dom/RTCRtpParametersBinding.h"
#include "RTCStatsReport.h"
#include "jsep/JsepTrack.h"
#include "transportbridge/MediaPipeline.h"

class nsPIDOMWindowInner;

namespace mozilla {
class MediaSessionConduit;
class MediaTransportHandler;
class JsepTransceiver;
class PeerConnectionImpl;
class DOMMediaStream;

namespace dom {
class MediaStreamTrack;
class Promise;
class RTCDtlsTransport;
class RTCDTMFSender;
struct RTCRtpCapabilities;
class RTCRtpTransceiver;
class RTCRtpScriptTransform;

class RTCRtpSender : public nsISupports,
                     public nsWrapperCache,
                     public MediaPipelineTransmitControlInterface {
 public:
  RTCRtpSender(nsPIDOMWindowInner* aWindow, PeerConnectionImpl* aPc,
               MediaTransportHandler* aTransportHandler,
               AbstractThread* aCallThread, nsISerialEventTarget* aStsThread,
               MediaSessionConduit* aConduit, dom::MediaStreamTrack* aTrack,
               const Sequence<RTCRtpEncodingParameters>& aEncodings,
               RTCRtpTransceiver* aTransceiver);

  // nsISupports
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(RTCRtpSender)

  JSObject* WrapObject(JSContext* aCx,
                       JS::Handle<JSObject*> aGivenProto) override;

  // webidl
  MediaStreamTrack* GetTrack() const { return mSenderTrack; }
  RTCDtlsTransport* GetTransport() const;
  RTCDTMFSender* GetDtmf() const;
  MOZ_CAN_RUN_SCRIPT
  already_AddRefed<Promise> ReplaceTrack(MediaStreamTrack* aWithTrack,
                                         ErrorResult& aError);
  already_AddRefed<Promise> GetStats(ErrorResult& aError);
  static void GetCapabilities(const GlobalObject&, const nsAString& kind,
                              Nullable<dom::RTCRtpCapabilities>& result);
  already_AddRefed<Promise> SetParameters(
      const dom::RTCRtpSendParameters& aParameters, ErrorResult& aError);
  // Not a simple getter, so not const
  // See https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-getparameters
  void GetParameters(RTCRtpSendParameters& aParameters);

  static void CheckAndRectifyEncodings(
      Sequence<RTCRtpEncodingParameters>& aEncodings, bool aVideo,
      ErrorResult& aRv);

  RTCRtpScriptTransform* GetTransform() const { return mTransform; }

  void SetTransform(RTCRtpScriptTransform* aTransform, ErrorResult& aError);
  bool GenerateKeyFrame(const Maybe<std::string>& aRid);

  nsPIDOMWindowInner* GetParentObject() const;
  nsTArray<RefPtr<RTCStatsPromise>> GetStatsInternal(
      bool aSkipIceStats = false);

  void SetStreams(const Sequence<OwningNonNull<DOMMediaStream>>& aStreams,
                  ErrorResult& aRv);
  // ChromeOnly webidl
  void GetStreams(nsTArray<RefPtr<DOMMediaStream>>& aStreams);
  // ChromeOnly webidl
  void SetStreamsImpl(const Sequence<OwningNonNull<DOMMediaStream>>& aStreams);
  // ChromeOnly webidl
  void SetTrack(const RefPtr<MediaStreamTrack>& aTrack);
  void Shutdown();
  void BreakCycles();
  void Unlink();
  // Terminal state, reached through stopping RTCRtpTransceiver.
  void Stop();
  bool HasTrack(const dom::MediaStreamTrack* aTrack) const;
  bool IsMyPc(const PeerConnectionImpl* aPc) const { return mPc.get() == aPc; }
  RefPtr<MediaPipelineTransmit> GetPipeline() const;
  already_AddRefed<dom::Promise> MakePromise(ErrorResult& aError) const;
  bool SeamlessTrackSwitch(const RefPtr<MediaStreamTrack>& aWithTrack);
  bool SetSenderTrackWithClosedCheck(const RefPtr<MediaStreamTrack>& aTrack);

  // This is called when we set an answer (ie; when the transport is finalized).
  void UpdateTransport();
  void SyncToJsep(JsepTransceiver& aJsepTransceiver) const;
  void SyncFromJsep(const JsepTransceiver& aJsepTransceiver);
  void MaybeUpdateConduit();

  Canonical<Ssrcs>& CanonicalSsrcs() { return mSsrcs; }
  Canonical<Ssrcs>& CanonicalVideoRtxSsrcs() { return mVideoRtxSsrcs; }
  Canonical<RtpExtList>& CanonicalLocalRtpExtensions() {
    return mLocalRtpExtensions;
  }

  Canonical<Maybe<AudioCodecConfig>>& CanonicalAudioCodec() {
    return mAudioCodec;
  }

  Canonical<Maybe<VideoCodecConfig>>& CanonicalVideoCodec() {
    return mVideoCodec;
  }
  Canonical<Maybe<RtpRtcpConfig>>& CanonicalVideoRtpRtcpConfig() {
    return mVideoRtpRtcpConfig;
  }
  Canonical<webrtc::VideoCodecMode>& CanonicalVideoCodecMode() {
    return mVideoCodecMode;
  }
  Canonical<std::string>& CanonicalCname() { return mCname; }
  Canonical<bool>& CanonicalTransmitting() override { return mTransmitting; }

  Canonical<RefPtr<FrameTransformerProxy>>& CanonicalFrameTransformerProxy() {
    return mFrameTransformerProxy;
  }

  bool HasPendingSetParameters() const { return mPendingParameters.isSome(); }
  void InvalidateLastReturnedParameters() {
    mLastReturnedParameters = Nothing();
  }

 private:
  virtual ~RTCRtpSender();

  std::string GetMid() const;
  JsepTransceiver& GetJsepTransceiver();
  static void ApplyJsEncodingToConduitEncoding(
      const RTCRtpEncodingParameters& aJsEncoding,
      VideoCodecConfig::Encoding* aConduitEncoding);
  void UpdateRestorableEncodings(
      const Sequence<RTCRtpEncodingParameters>& aEncodings);
  Sequence<RTCRtpEncodingParameters> GetMatchingEncodings(
      const std::vector<std::string>& aRids) const;
  Sequence<RTCRtpEncodingParameters> ToSendEncodings(
      const std::vector<std::string>& aRids) const;
  void MaybeGetJsepRids();
  void UpdateDtmfSender();

  void WarnAboutBadSetParameters(const nsCString& aError);
  nsCString GetEffectiveTLDPlus1() const;

  WatchManager<RTCRtpSender> mWatchManager;
  nsCOMPtr<nsPIDOMWindowInner> mWindow;
  RefPtr<PeerConnectionImpl> mPc;
  RefPtr<dom::MediaStreamTrack> mSenderTrack;
  bool mSenderTrackSetByAddTrack = false;
  RTCRtpSendParameters mParameters;
  Maybe<RTCRtpSendParameters> mPendingParameters;
  uint32_t mNumSetParametersCalls = 0;
  // When JSEP goes from simulcast to unicast without a rid, and we started out
  // as unicast without a rid, we are supposed to restore that unicast encoding
  // from before.
  Maybe<RTCRtpEncodingParameters> mUnicastEncoding;
  bool mSimulcastEnvelopeSet = false;
  bool mSimulcastEnvelopeSetByJSEP = false;
  bool mPendingRidChangeFromCompatMode = false;
  Maybe<RTCRtpSendParameters> mLastReturnedParameters;
  RefPtr<MediaPipelineTransmit> mPipeline;
  RefPtr<MediaTransportHandler> mTransportHandler;
  RefPtr<RTCRtpTransceiver> mTransceiver;
  nsTArray<RefPtr<DOMMediaStream>> mStreams;
  RefPtr<RTCRtpScriptTransform> mTransform;
  bool mHaveSetupTransport = false;
  // TODO(bug 1803388): Remove this stuff once it is no longer needed.
  bool mAllowOldSetParameters = false;

  // TODO(bug 1803388): Remove the glean warnings once they are no longer needed
  bool mHaveWarnedBecauseNoGetParameters = false;
  bool mHaveWarnedBecauseEncodingCountChange = false;
  bool mHaveWarnedBecauseNoTransactionId = false;
  // TODO(bug 1803389): Remove the glean errors once they are no longer needed.
  bool mHaveFailedBecauseNoGetParameters = false;
  bool mHaveFailedBecauseEncodingCountChange = false;
  bool mHaveFailedBecauseRidChange = false;
  bool mHaveFailedBecauseNoTransactionId = false;
  bool mHaveFailedBecauseStaleTransactionId = false;
  bool mHaveFailedBecauseNoEncodings = false;
  bool mHaveFailedBecauseOtherError = false;

  // Limits logging of codec information
  bool mHaveLoggedUlpfecInfo = false;
  bool mHaveLoggedOtherFec = false;
  bool mHaveLoggedVideoPreferredCodec = false;
  bool mHaveLoggedAudioPreferredCodec = false;

  RefPtr<dom::RTCDTMFSender> mDtmf;

  class BaseConfig {
   public:
    // TODO(bug 1744116): Use = default here
    bool operator==(const BaseConfig& aOther) const {
      return mSsrcs == aOther.mSsrcs &&
             mLocalRtpExtensions == aOther.mLocalRtpExtensions &&
             mCname == aOther.mCname && mTransmitting == aOther.mTransmitting;
    }
    Ssrcs mSsrcs;
    RtpExtList mLocalRtpExtensions;
    std::string mCname;
    bool mTransmitting = false;
  };

  class VideoConfig : public BaseConfig {
   public:
    // TODO(bug 1744116): Use = default here
    bool operator==(const VideoConfig& aOther) const {
      return BaseConfig::operator==(aOther) &&
             mVideoRtxSsrcs == aOther.mVideoRtxSsrcs &&
             mVideoCodec == aOther.mVideoCodec &&
             mVideoRtpRtcpConfig == aOther.mVideoRtpRtcpConfig &&
             mVideoCodecMode == aOther.mVideoCodecMode;
    }
    Ssrcs mVideoRtxSsrcs;
    Maybe<VideoCodecConfig> mVideoCodec;
    Maybe<RtpRtcpConfig> mVideoRtpRtcpConfig;
    webrtc::VideoCodecMode mVideoCodecMode =
        webrtc::VideoCodecMode::kRealtimeVideo;
  };

  class AudioConfig : public BaseConfig {
   public:
    // TODO(bug 1744116): Use = default here
    bool operator==(const AudioConfig& aOther) const {
      return BaseConfig::operator==(aOther) &&
             mAudioCodec == aOther.mAudioCodec && mDtmfPt == aOther.mDtmfPt &&
             mDtmfFreq == aOther.mDtmfFreq;
    }
    Maybe<AudioCodecConfig> mAudioCodec;
    int32_t mDtmfPt = -1;
    int32_t mDtmfFreq = 0;
  };

  Maybe<VideoConfig> GetNewVideoConfig();
  Maybe<AudioConfig> GetNewAudioConfig();
  void UpdateBaseConfig(BaseConfig* aConfig);
  void ApplyVideoConfig(const VideoConfig& aConfig);
  void ApplyAudioConfig(const AudioConfig& aConfig);

  Canonical<Ssrcs> mSsrcs;
  Canonical<Ssrcs> mVideoRtxSsrcs;
  Canonical<RtpExtList> mLocalRtpExtensions;

  Canonical<Maybe<AudioCodecConfig>> mAudioCodec;
  Canonical<Maybe<VideoCodecConfig>> mVideoCodec;
  Canonical<Maybe<RtpRtcpConfig>> mVideoRtpRtcpConfig;
  Canonical<webrtc::VideoCodecMode> mVideoCodecMode;
  Canonical<std::string> mCname;
  Canonical<bool> mTransmitting;
  Canonical<RefPtr<FrameTransformerProxy>> mFrameTransformerProxy;
};

}  // namespace dom
}  // namespace mozilla
#endif  // _RTCRtpSender_h_