summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/jsapi/TransceiverImpl.h
blob: 335faa7579e68a5f17dfb7a5c0b18e7eaa50549b (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
/* 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 _TRANSCEIVERIMPL_H_
#define _TRANSCEIVERIMPL_H_

#include <string>
#include "mozilla/RefPtr.h"
#include "nsCOMPtr.h"
#include "nsISerialEventTarget.h"
#include "nsTArray.h"
#include "mozilla/dom/MediaStreamTrack.h"
#include "ErrorList.h"
#include "jsep/JsepTransceiver.h"
#include "transport/transportlayer.h"  // For TransportLayer::State

class nsIPrincipal;

namespace mozilla {
class PeerIdentity;
class JsepTransceiver;
enum class MediaSessionConduitLocalDirection : int;
class MediaSessionConduit;
class VideoSessionConduit;
class AudioSessionConduit;
struct AudioCodecConfig;
class VideoCodecConfig;  // Why is this a class, but AudioCodecConfig a struct?
class MediaPipelineTransmit;
class MediaPipeline;
class MediaPipelineFilter;
class MediaTransportHandler;
class WebRtcCallWrapper;
class JsepTrackNegotiatedDetails;

namespace dom {
class RTCDtlsTransport;
class RTCDTMFSender;
class RTCRtpTransceiver;
struct RTCRtpSourceEntry;
class RTCRtpReceiver;
}  // namespace dom

/**
 * This is what ties all the various pieces that make up a transceiver
 * together. This includes:
 * MediaStreamTrack for rendering and capture
 * MediaTransportHandler for RTP transmission/reception
 * Audio/VideoConduit for feeding RTP/RTCP into webrtc.org for decoding, and
 * feeding audio/video frames into webrtc.org for encoding into RTP/RTCP.
 */
class TransceiverImpl : public nsISupports,
                        public nsWrapperCache,
                        public sigslot::has_slots<> {
 public:
  /**
   * |aSendTrack| might or might not be set.
   */
  TransceiverImpl(nsPIDOMWindowInner* aWindow, bool aPrivacyNeeded,
                  const std::string& aPCHandle,
                  MediaTransportHandler* aTransportHandler,
                  JsepTransceiver* aJsepTransceiver,
                  nsISerialEventTarget* aMainThread,
                  nsISerialEventTarget* aStsThread,
                  dom::MediaStreamTrack* aSendTrack,
                  WebRtcCallWrapper* aCallWrapper);

  bool IsValid() const { return !!mConduit; }

  nsresult UpdateSendTrack(dom::MediaStreamTrack* aSendTrack);

  nsresult UpdateSinkIdentity(const dom::MediaStreamTrack* aTrack,
                              nsIPrincipal* aPrincipal,
                              const PeerIdentity* aSinkIdentity);

  nsresult UpdateTransport();

  nsresult UpdateConduit();

  void ResetSync();

  nsresult SyncWithMatchingVideoConduits(
      std::vector<RefPtr<TransceiverImpl>>& transceivers);

  void Shutdown_m();

  bool ConduitHasPluginID(uint64_t aPluginID);

  bool HasSendTrack(const dom::MediaStreamTrack* aSendTrack) const;

  // This is so PCImpl can unregister from PrincipalChanged callbacks; maybe we
  // should have TransceiverImpl handle these callbacks instead? It would need
  // to be able to get a ref to PCImpl though.
  RefPtr<dom::MediaStreamTrack> GetSendTrack() { return mSendTrack; }

  // for webidl
  JSObject* WrapObject(JSContext* aCx,
                       JS::Handle<JSObject*> aGivenProto) override;
  nsPIDOMWindowInner* GetParentObject() const;
  void SyncWithJS(dom::RTCRtpTransceiver& aJsTransceiver, ErrorResult& aRv);
  dom::RTCRtpReceiver* Receiver() const { return mReceiver; }
  dom::RTCDTMFSender* GetDtmf() const { return mDtmf; }
  dom::RTCDtlsTransport* GetDtlsTransport() const { return mDtlsTransport; }

  bool CanSendDTMF() const;

  // TODO: These are for stats; try to find a cleaner way.
  RefPtr<MediaPipelineTransmit> GetSendPipeline();

  void UpdateDtlsTransportState(const std::string& aTransportId,
                                TransportLayer::State aState);
  void SetDtlsTransport(dom::RTCDtlsTransport* aDtlsTransport, bool aStable);
  void RollbackToStableDtlsTransport();

  std::string GetTransportId() const {
    return mJsepTransceiver->mTransport.mTransportId;
  }

  bool IsVideo() const;

  bool IsSending() const {
    return !mJsepTransceiver->IsStopped() &&
           mJsepTransceiver->mSendTrack.GetActive();
  }

  bool IsReceiving() const {
    return !mJsepTransceiver->IsStopped() &&
           mJsepTransceiver->mRecvTrack.GetActive();
  }

  MediaSessionConduit* GetConduit() const { return mConduit; }

  // nsISupports
  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TransceiverImpl)

  static nsresult NegotiatedDetailsToAudioCodecConfigs(
      const JsepTrackNegotiatedDetails& aDetails,
      std::vector<UniquePtr<AudioCodecConfig>>* aConfigs);

  static nsresult NegotiatedDetailsToVideoCodecConfigs(
      const JsepTrackNegotiatedDetails& aDetails,
      std::vector<UniquePtr<VideoCodecConfig>>* aConfigs);

  static void UpdateConduitRtpExtmap(
      MediaSessionConduit& aConduit, const JsepTrackNegotiatedDetails& aDetails,
      const MediaSessionConduitLocalDirection aDir);

 private:
  virtual ~TransceiverImpl();
  void InitAudio();
  void InitVideo();
  nsresult UpdateAudioConduit();
  nsresult UpdateVideoConduit();
  nsresult ConfigureVideoCodecMode(VideoSessionConduit& aConduit);
  void Stop();

  nsCOMPtr<nsPIDOMWindowInner> mWindow;
  const std::string mPCHandle;
  RefPtr<MediaTransportHandler> mTransportHandler;
  RefPtr<JsepTransceiver> mJsepTransceiver;
  std::string mMid;
  bool mHaveSetupTransport;
  nsCOMPtr<nsISerialEventTarget> mMainThread;
  nsCOMPtr<nsISerialEventTarget> mStsThread;
  RefPtr<dom::MediaStreamTrack> mSendTrack;
  // state for webrtc.org that is shared between all transceivers
  RefPtr<WebRtcCallWrapper> mCallWrapper;
  RefPtr<MediaSessionConduit> mConduit;
  RefPtr<MediaPipelineTransmit> mTransmitPipeline;
  // The spec says both RTCRtpReceiver and RTCRtpSender have a slot for
  // an RTCDtlsTransport.  They are always the same, so we'll store it
  // here.
  RefPtr<dom::RTCDtlsTransport> mDtlsTransport;
  // The spec says both RTCRtpReceiver and RTCRtpSender have a slot for
  // a last stable state RTCDtlsTransport.  They are always the same, so
  // we'll store it here.
  RefPtr<dom::RTCDtlsTransport> mLastStableDtlsTransport;
  RefPtr<dom::RTCRtpReceiver> mReceiver;
  // TODO(bug 1616937): Move this to RTCRtpSender
  RefPtr<dom::RTCDTMFSender> mDtmf;
};

}  // namespace mozilla

#endif  // _TRANSCEIVERIMPL_H_