Line data Source code
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 file,
3 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
4 :
5 : #ifndef _JSEPTRACK_H_
6 : #define _JSEPTRACK_H_
7 :
8 : #include <functional>
9 : #include <algorithm>
10 : #include <string>
11 : #include <map>
12 : #include <set>
13 :
14 : #include <mozilla/RefPtr.h>
15 : #include <mozilla/UniquePtr.h>
16 : #include <mozilla/Maybe.h>
17 : #include "nsISupportsImpl.h"
18 : #include "nsError.h"
19 :
20 : #include "signaling/src/jsep/JsepTransport.h"
21 : #include "signaling/src/jsep/JsepTrackEncoding.h"
22 : #include "signaling/src/sdp/Sdp.h"
23 : #include "signaling/src/sdp/SdpAttribute.h"
24 : #include "signaling/src/sdp/SdpMediaSection.h"
25 : #include "signaling/src/common/PtrVector.h"
26 :
27 : namespace mozilla {
28 :
29 0 : class JsepTrackNegotiatedDetails
30 : {
31 : public:
32 0 : JsepTrackNegotiatedDetails() :
33 0 : mTias(0)
34 0 : {}
35 :
36 : size_t
37 0 : GetEncodingCount() const
38 : {
39 0 : return mEncodings.values.size();
40 : }
41 :
42 : const JsepTrackEncoding&
43 0 : GetEncoding(size_t index) const
44 : {
45 0 : MOZ_RELEASE_ASSERT(index < mEncodings.values.size());
46 0 : return *mEncodings.values[index];
47 : }
48 :
49 : const SdpExtmapAttributeList::Extmap*
50 0 : GetExt(const std::string& ext_name) const
51 : {
52 0 : auto it = mExtmap.find(ext_name);
53 0 : if (it != mExtmap.end()) {
54 0 : return &it->second;
55 : }
56 0 : return nullptr;
57 : }
58 :
59 : void
60 0 : ForEachRTPHeaderExtension(
61 : const std::function<void(const SdpExtmapAttributeList::Extmap& extmap)> & fn) const
62 : {
63 0 : for(auto entry: mExtmap) {
64 0 : fn(entry.second);
65 : }
66 0 : }
67 :
68 0 : std::vector<uint8_t> GetUniquePayloadTypes() const
69 : {
70 0 : return mUniquePayloadTypes;
71 : }
72 :
73 0 : uint32_t GetTias() const
74 : {
75 0 : return mTias;
76 : }
77 :
78 : private:
79 : friend class JsepTrack;
80 :
81 : std::map<std::string, SdpExtmapAttributeList::Extmap> mExtmap;
82 : std::vector<uint8_t> mUniquePayloadTypes;
83 : PtrVector<JsepTrackEncoding> mEncodings;
84 : uint32_t mTias; // bits per second
85 : };
86 :
87 : class JsepTrack
88 : {
89 : public:
90 0 : JsepTrack(mozilla::SdpMediaSection::MediaType type,
91 : const std::string& streamid,
92 : const std::string& trackid,
93 : sdp::Direction direction = sdp::kSend)
94 0 : : mType(type),
95 : mStreamId(streamid),
96 : mTrackId(trackid),
97 : mDirection(direction),
98 0 : mActive(false)
99 0 : {}
100 :
101 : virtual mozilla::SdpMediaSection::MediaType
102 0 : GetMediaType() const
103 : {
104 0 : return mType;
105 : }
106 :
107 : virtual const std::string&
108 0 : GetStreamId() const
109 : {
110 0 : return mStreamId;
111 : }
112 :
113 : virtual void
114 0 : SetStreamId(const std::string& id)
115 : {
116 0 : mStreamId = id;
117 0 : }
118 :
119 : virtual const std::string&
120 0 : GetTrackId() const
121 : {
122 0 : return mTrackId;
123 : }
124 :
125 : virtual void
126 0 : SetTrackId(const std::string& id)
127 : {
128 0 : mTrackId = id;
129 0 : }
130 :
131 : virtual const std::string&
132 0 : GetCNAME() const
133 : {
134 0 : return mCNAME;
135 : }
136 :
137 : virtual void
138 0 : SetCNAME(const std::string& cname)
139 : {
140 0 : mCNAME = cname;
141 0 : }
142 :
143 : virtual sdp::Direction
144 0 : GetDirection() const
145 : {
146 0 : return mDirection;
147 : }
148 :
149 : virtual const std::vector<uint32_t>&
150 0 : GetSsrcs() const
151 : {
152 0 : return mSsrcs;
153 : }
154 :
155 : virtual void
156 0 : AddSsrc(uint32_t ssrc)
157 : {
158 0 : if (mType != SdpMediaSection::kApplication) {
159 0 : mSsrcs.push_back(ssrc);
160 : }
161 0 : }
162 :
163 : bool
164 0 : GetActive() const
165 : {
166 0 : return mActive;
167 : }
168 :
169 : void
170 0 : SetActive(bool active)
171 : {
172 0 : mActive = active;
173 0 : }
174 :
175 : virtual void PopulateCodecs(
176 : const std::vector<JsepCodecDescription*>& prototype);
177 :
178 : template <class UnaryFunction>
179 0 : void ForEachCodec(UnaryFunction func)
180 : {
181 0 : std::for_each(mPrototypeCodecs.values.begin(),
182 : mPrototypeCodecs.values.end(), func);
183 0 : }
184 :
185 : template <class BinaryPredicate>
186 0 : void SortCodecs(BinaryPredicate sorter)
187 : {
188 0 : std::stable_sort(mPrototypeCodecs.values.begin(),
189 : mPrototypeCodecs.values.end(), sorter);
190 0 : }
191 :
192 : virtual void AddToOffer(SdpMediaSection* offer) const;
193 : virtual void AddToAnswer(const SdpMediaSection& offer,
194 : SdpMediaSection* answer) const;
195 : virtual void Negotiate(const SdpMediaSection& answer,
196 : const SdpMediaSection& remote);
197 : static void SetUniquePayloadTypes(
198 : const std::vector<RefPtr<JsepTrack>>& tracks);
199 : virtual void GetNegotiatedPayloadTypes(std::vector<uint16_t>* payloadTypes);
200 :
201 : // This will be set when negotiation is carried out.
202 : virtual const JsepTrackNegotiatedDetails*
203 0 : GetNegotiatedDetails() const
204 : {
205 0 : if (mNegotiatedDetails) {
206 0 : return mNegotiatedDetails.get();
207 : }
208 0 : return nullptr;
209 : }
210 :
211 : virtual JsepTrackNegotiatedDetails*
212 0 : GetNegotiatedDetails()
213 : {
214 0 : if (mNegotiatedDetails) {
215 0 : return mNegotiatedDetails.get();
216 : }
217 0 : return nullptr;
218 : }
219 :
220 : virtual void
221 0 : ClearNegotiatedDetails()
222 : {
223 0 : mNegotiatedDetails.reset();
224 0 : }
225 :
226 0 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(JsepTrack);
227 :
228 0 : struct JsConstraints
229 : {
230 : std::string rid;
231 : EncodingConstraints constraints;
232 : };
233 :
234 0 : void SetJsConstraints(const std::vector<JsConstraints>& constraintsList)
235 : {
236 0 : mJsEncodeConstraints = constraintsList;
237 0 : }
238 :
239 0 : void GetJsConstraints(std::vector<JsConstraints>* outConstraintsList) const
240 : {
241 0 : MOZ_ASSERT(outConstraintsList);
242 0 : *outConstraintsList = mJsEncodeConstraints;
243 0 : }
244 :
245 : static void AddToMsection(const std::vector<JsConstraints>& constraintsList,
246 : sdp::Direction direction,
247 : SdpMediaSection* msection);
248 :
249 : protected:
250 0 : virtual ~JsepTrack() {}
251 :
252 : private:
253 : std::vector<JsepCodecDescription*> GetCodecClones() const;
254 : static void EnsureNoDuplicatePayloadTypes(
255 : std::vector<JsepCodecDescription*>* codecs);
256 : static void GetPayloadTypes(
257 : const std::vector<JsepCodecDescription*>& codecs,
258 : std::vector<uint16_t>* pts);
259 : static void EnsurePayloadTypeIsUnique(std::set<uint16_t>* uniquePayloadTypes,
260 : JsepCodecDescription* codec);
261 : void AddToMsection(const std::vector<JsepCodecDescription*>& codecs,
262 : SdpMediaSection* msection) const;
263 : void GetRids(const SdpMediaSection& msection,
264 : sdp::Direction direction,
265 : std::vector<SdpRidAttributeList::Rid>* rids) const;
266 : void CreateEncodings(
267 : const SdpMediaSection& remote,
268 : const std::vector<JsepCodecDescription*>& negotiatedCodecs,
269 : JsepTrackNegotiatedDetails* details);
270 :
271 : // |formatChanges| is set on completion of offer/answer, and records how the
272 : // formats in |codecs| were changed, which is used by |Negotiate| to update
273 : // |mPrototypeCodecs|.
274 : virtual void NegotiateCodecs(
275 : const SdpMediaSection& remote,
276 : std::vector<JsepCodecDescription*>* codecs,
277 : std::map<std::string, std::string>* formatChanges = nullptr) const;
278 :
279 : JsConstraints* FindConstraints(
280 : const std::string& rid,
281 : std::vector<JsConstraints>& constraintsList) const;
282 : void NegotiateRids(const std::vector<SdpRidAttributeList::Rid>& rids,
283 : std::vector<JsConstraints>* constraints) const;
284 :
285 : const mozilla::SdpMediaSection::MediaType mType;
286 : std::string mStreamId;
287 : std::string mTrackId;
288 : std::string mCNAME;
289 : const sdp::Direction mDirection;
290 : PtrVector<JsepCodecDescription> mPrototypeCodecs;
291 : // Holds encoding params/constraints from JS. Simulcast happens when there are
292 : // multiple of these. If there are none, we assume unconstrained unicast with
293 : // no rid.
294 : std::vector<JsConstraints> mJsEncodeConstraints;
295 : UniquePtr<JsepTrackNegotiatedDetails> mNegotiatedDetails;
296 : std::vector<uint32_t> mSsrcs;
297 : bool mActive;
298 : };
299 :
300 : // Need a better name for this.
301 0 : struct JsepTrackPair {
302 : size_t mLevel;
303 : // Is this track pair sharing a transport with another?
304 : size_t mBundleLevel = SIZE_MAX; // SIZE_MAX if no bundle level
305 : uint32_t mRecvonlySsrc;
306 : RefPtr<JsepTrack> mSending;
307 : RefPtr<JsepTrack> mReceiving;
308 : RefPtr<JsepTransport> mRtpTransport;
309 : RefPtr<JsepTransport> mRtcpTransport;
310 :
311 0 : bool HasBundleLevel() const {
312 0 : return mBundleLevel != SIZE_MAX;
313 : }
314 :
315 0 : size_t BundleLevel() const {
316 0 : MOZ_ASSERT(HasBundleLevel());
317 0 : return mBundleLevel;
318 : }
319 :
320 0 : void SetBundleLevel(size_t aBundleLevel) {
321 0 : MOZ_ASSERT(aBundleLevel != SIZE_MAX);
322 0 : mBundleLevel = aBundleLevel;
323 0 : }
324 : };
325 :
326 : } // namespace mozilla
327 :
328 : #endif
|