blob: 1fc81340170462cb97f9a55bca6e078e6b5171e7 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
11// This file contains structures for describing SSRCs from a media source such
12// as a MediaStreamTrack when it is sent across an RTP session. Multiple media
13// sources may be sent across the same RTP session, each of them will be
14// described by one StreamParams object
15// SsrcGroup is used to describe the relationship between the SSRCs that
16// are used for this media source.
wu@webrtc.orgcecfd182013-10-30 05:18:12 +000017// E.x: Consider a source that is sent as 3 simulcast streams
18// Let the simulcast elements have SSRC 10, 20, 30.
19// Let each simulcast element use FEC and let the protection packets have
20// SSRC 11,21,31.
21// To describe this 4 SsrcGroups are needed,
22// StreamParams would then contain ssrc = {10,11,20,21,30,31} and
23// ssrc_groups = {{SIM,{10,20,30}, {FEC,{10,11}, {FEC, {20,21}, {FEC {30,31}}}
24// Please see RFC 5576.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000025
kjellandera96e2d72016-02-04 23:52:28 -080026#ifndef WEBRTC_MEDIA_BASE_STREAMPARAMS_H_
27#define WEBRTC_MEDIA_BASE_STREAMPARAMS_H_
henrike@webrtc.org28e20752013-07-10 00:45:36 +000028
pbosc7c26a02017-01-02 08:42:32 -080029#include <stdint.h>
30
henrike@webrtc.org28e20752013-07-10 00:45:36 +000031#include <algorithm>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000032#include <set>
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000033#include <string>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034#include <vector>
35
Edward Lemurc20978e2017-07-06 19:44:34 +020036#include "webrtc/rtc_base/constructormagic.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000037
38namespace cricket {
39
40extern const char kFecSsrcGroupSemantics[];
brandtr9688e382016-11-22 00:59:48 -080041extern const char kFecFrSsrcGroupSemantics[];
henrike@webrtc.org28e20752013-07-10 00:45:36 +000042extern const char kFidSsrcGroupSemantics[];
wu@webrtc.orgcecfd182013-10-30 05:18:12 +000043extern const char kSimSsrcGroupSemantics[];
henrike@webrtc.org28e20752013-07-10 00:45:36 +000044
45struct SsrcGroup {
Peter Boström0c4e06b2015-10-07 12:23:21 +020046 SsrcGroup(const std::string& usage, const std::vector<uint32_t>& ssrcs)
47 : semantics(usage), ssrcs(ssrcs) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048
49 bool operator==(const SsrcGroup& other) const {
50 return (semantics == other.semantics && ssrcs == other.ssrcs);
51 }
52 bool operator!=(const SsrcGroup &other) const {
53 return !(*this == other);
54 }
55
56 bool has_semantics(const std::string& semantics) const;
57
58 std::string ToString() const;
59
60 std::string semantics; // e.g FIX, FEC, SIM.
Peter Boström0c4e06b2015-10-07 12:23:21 +020061 std::vector<uint32_t> ssrcs; // SSRCs of this type.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000062};
63
64struct StreamParams {
Peter Boström0c4e06b2015-10-07 12:23:21 +020065 static StreamParams CreateLegacy(uint32_t ssrc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000066 StreamParams stream;
67 stream.ssrcs.push_back(ssrc);
68 return stream;
69 }
70
71 bool operator==(const StreamParams& other) const {
72 return (groupid == other.groupid &&
73 id == other.id &&
74 ssrcs == other.ssrcs &&
75 ssrc_groups == other.ssrc_groups &&
76 type == other.type &&
77 display == other.display &&
78 cname == other.cname &&
79 sync_label == other.sync_label);
80 }
81 bool operator!=(const StreamParams &other) const {
82 return !(*this == other);
83 }
84
Peter Boström0c4e06b2015-10-07 12:23:21 +020085 uint32_t first_ssrc() const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086 if (ssrcs.empty()) {
87 return 0;
88 }
89
90 return ssrcs[0];
91 }
92 bool has_ssrcs() const {
93 return !ssrcs.empty();
94 }
Peter Boström0c4e06b2015-10-07 12:23:21 +020095 bool has_ssrc(uint32_t ssrc) const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000096 return std::find(ssrcs.begin(), ssrcs.end(), ssrc) != ssrcs.end();
97 }
Peter Boström0c4e06b2015-10-07 12:23:21 +020098 void add_ssrc(uint32_t ssrc) { ssrcs.push_back(ssrc); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000099 bool has_ssrc_groups() const {
100 return !ssrc_groups.empty();
101 }
102 bool has_ssrc_group(const std::string& semantics) const {
103 return (get_ssrc_group(semantics) != NULL);
104 }
105 const SsrcGroup* get_ssrc_group(const std::string& semantics) const {
106 for (std::vector<SsrcGroup>::const_iterator it = ssrc_groups.begin();
107 it != ssrc_groups.end(); ++it) {
108 if (it->has_semantics(semantics)) {
109 return &(*it);
110 }
111 }
112 return NULL;
113 }
114
115 // Convenience function to add an FID ssrc for a primary_ssrc
116 // that's already been added.
brandtr9688e382016-11-22 00:59:48 -0800117 bool AddFidSsrc(uint32_t primary_ssrc, uint32_t fid_ssrc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000118 return AddSecondarySsrc(kFidSsrcGroupSemantics, primary_ssrc, fid_ssrc);
119 }
120
121 // Convenience function to lookup the FID ssrc for a primary_ssrc.
122 // Returns false if primary_ssrc not found or FID not defined for it.
brandtr9688e382016-11-22 00:59:48 -0800123 bool GetFidSsrc(uint32_t primary_ssrc, uint32_t* fid_ssrc) const {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000124 return GetSecondarySsrc(kFidSsrcGroupSemantics, primary_ssrc, fid_ssrc);
125 }
126
brandtr9688e382016-11-22 00:59:48 -0800127 // Convenience function to add an FEC-FR ssrc for a primary_ssrc
128 // that's already been added.
129 bool AddFecFrSsrc(uint32_t primary_ssrc, uint32_t fecfr_ssrc) {
130 return AddSecondarySsrc(kFecFrSsrcGroupSemantics, primary_ssrc, fecfr_ssrc);
131 }
132
133 // Convenience function to lookup the FEC-FR ssrc for a primary_ssrc.
134 // Returns false if primary_ssrc not found or FEC-FR not defined for it.
135 bool GetFecFrSsrc(uint32_t primary_ssrc, uint32_t* fecfr_ssrc) const {
136 return GetSecondarySsrc(kFecFrSsrcGroupSemantics, primary_ssrc, fecfr_ssrc);
137 }
138
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000139 // Convenience to get all the SIM SSRCs if there are SIM ssrcs, or
140 // the first SSRC otherwise.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200141 void GetPrimarySsrcs(std::vector<uint32_t>* ssrcs) const;
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000142
143 // Convenience to get all the FID SSRCs for the given primary ssrcs.
144 // If a given primary SSRC does not have a FID SSRC, the list of FID
145 // SSRCS will be smaller than the list of primary SSRCs.
Peter Boström0c4e06b2015-10-07 12:23:21 +0200146 void GetFidSsrcs(const std::vector<uint32_t>& primary_ssrcs,
147 std::vector<uint32_t>* fid_ssrcs) const;
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000148
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000149 std::string ToString() const;
150
151 // Resource of the MUC jid of the participant of with this stream.
152 // For 1:1 calls, should be left empty (which means remote streams
153 // and local streams should not be mixed together).
154 std::string groupid;
155 // Unique per-groupid, not across all groupids
156 std::string id;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200157 std::vector<uint32_t> ssrcs; // All SSRCs for this source
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000158 std::vector<SsrcGroup> ssrc_groups; // e.g. FID, FEC, SIM
159 // Examples: "camera", "screencast"
160 std::string type;
161 // Friendly name describing stream
162 std::string display;
163 std::string cname; // RTCP CNAME
164 std::string sync_label; // Friendly name of cname.
165
166 private:
Peter Boström0c4e06b2015-10-07 12:23:21 +0200167 bool AddSecondarySsrc(const std::string& semantics,
168 uint32_t primary_ssrc,
169 uint32_t secondary_ssrc);
170 bool GetSecondarySsrc(const std::string& semantics,
171 uint32_t primary_ssrc,
172 uint32_t* secondary_ssrc) const;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000173};
174
175// A Stream can be selected by either groupid+id or ssrc.
176struct StreamSelector {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200177 explicit StreamSelector(uint32_t ssrc) : ssrc(ssrc) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000178
179 StreamSelector(const std::string& groupid,
180 const std::string& streamid) :
181 ssrc(0),
182 groupid(groupid),
183 streamid(streamid) {
184 }
185
186 bool Matches(const StreamParams& stream) const {
187 if (ssrc == 0) {
188 return stream.groupid == groupid && stream.id == streamid;
189 } else {
190 return stream.has_ssrc(ssrc);
191 }
192 }
193
Peter Boström0c4e06b2015-10-07 12:23:21 +0200194 uint32_t ssrc;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000195 std::string groupid;
196 std::string streamid;
197};
198
199typedef std::vector<StreamParams> StreamParamsVec;
200
pthatcher@webrtc.orge2b75852014-12-16 21:09:08 +0000201// A collection of audio and video and data streams. Most of the
202// methods are merely for convenience. Many of these methods are keyed
203// by ssrc, which is the source identifier in the RTP spec
204// (http://tools.ietf.org/html/rfc3550).
205// TODO(pthatcher): Add basic unit test for these.
206// See https://code.google.com/p/webrtc/issues/detail?id=4107
207struct MediaStreams {
208 public:
209 MediaStreams() {}
210 void CopyFrom(const MediaStreams& sources);
211
212 bool empty() const {
213 return audio_.empty() && video_.empty() && data_.empty();
214 }
215
216 std::vector<StreamParams>* mutable_audio() { return &audio_; }
217 std::vector<StreamParams>* mutable_video() { return &video_; }
218 std::vector<StreamParams>* mutable_data() { return &data_; }
219 const std::vector<StreamParams>& audio() const { return audio_; }
220 const std::vector<StreamParams>& video() const { return video_; }
221 const std::vector<StreamParams>& data() const { return data_; }
222
223 // Gets a stream, returning true if found.
224 bool GetAudioStream(
225 const StreamSelector& selector, StreamParams* stream);
226 bool GetVideoStream(
227 const StreamSelector& selector, StreamParams* stream);
228 bool GetDataStream(
229 const StreamSelector& selector, StreamParams* stream);
230 // Adds a stream.
231 void AddAudioStream(const StreamParams& stream);
232 void AddVideoStream(const StreamParams& stream);
233 void AddDataStream(const StreamParams& stream);
234 // Removes a stream, returning true if found and removed.
235 bool RemoveAudioStream(const StreamSelector& selector);
236 bool RemoveVideoStream(const StreamSelector& selector);
237 bool RemoveDataStream(const StreamSelector& selector);
238
239 private:
240 std::vector<StreamParams> audio_;
241 std::vector<StreamParams> video_;
242 std::vector<StreamParams> data_;
243
henrikg3c089d72015-09-16 05:37:44 -0700244 RTC_DISALLOW_COPY_AND_ASSIGN(MediaStreams);
pthatcher@webrtc.orge2b75852014-12-16 21:09:08 +0000245};
246
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000247template <class Condition>
248const StreamParams* GetStream(const StreamParamsVec& streams,
249 Condition condition) {
250 StreamParamsVec::const_iterator found =
251 std::find_if(streams.begin(), streams.end(), condition);
252 return found == streams.end() ? nullptr : &(*found);
253}
254
deadbeef2f425aa2017-04-14 10:41:32 -0700255template <class Condition>
256StreamParams* GetStream(StreamParamsVec& streams, Condition condition) {
257 StreamParamsVec::iterator found =
258 std::find_if(streams.begin(), streams.end(), condition);
259 return found == streams.end() ? nullptr : &(*found);
260}
261
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000262inline const StreamParams* GetStreamBySsrc(const StreamParamsVec& streams,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200263 uint32_t ssrc) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000264 return GetStream(streams,
265 [&ssrc](const StreamParams& sp) { return sp.has_ssrc(ssrc); });
266}
267
268inline const StreamParams* GetStreamByIds(const StreamParamsVec& streams,
269 const std::string& groupid,
270 const std::string& id) {
deadbeef2f425aa2017-04-14 10:41:32 -0700271 return GetStream(streams, [&groupid, &id](const StreamParams& sp) {
272 return sp.groupid == groupid && sp.id == id;
273 });
274}
275
276inline StreamParams* GetStreamByIds(StreamParamsVec& streams,
277 const std::string& groupid,
278 const std::string& id) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000279 return GetStream(streams,
280 [&groupid, &id](const StreamParams& sp) {
281 return sp.groupid == groupid && sp.id == id;
282 });
283}
284
285inline const StreamParams* GetStream(const StreamParamsVec& streams,
286 const StreamSelector& selector) {
287 return GetStream(streams,
288 [&selector](const StreamParams& sp) { return selector.Matches(sp); });
289}
290
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000291template <class Condition>
292bool RemoveStream(StreamParamsVec* streams, Condition condition) {
293 auto iter(std::remove_if(streams->begin(), streams->end(), condition));
294 if (iter == streams->end())
295 return false;
296 streams->erase(iter, streams->end());
297 return true;
298}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000299
300// Removes the stream from streams. Returns true if a stream is
301// found and removed.
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000302inline bool RemoveStream(StreamParamsVec* streams,
303 const StreamSelector& selector) {
304 return RemoveStream(streams,
305 [&selector](const StreamParams& sp) { return selector.Matches(sp); });
306}
Peter Boström0c4e06b2015-10-07 12:23:21 +0200307inline bool RemoveStreamBySsrc(StreamParamsVec* streams, uint32_t ssrc) {
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +0000308 return RemoveStream(streams,
309 [&ssrc](const StreamParams& sp) { return sp.has_ssrc(ssrc); });
310}
311inline bool RemoveStreamByIds(StreamParamsVec* streams,
312 const std::string& groupid,
313 const std::string& id) {
314 return RemoveStream(streams,
315 [&groupid, &id](const StreamParams& sp) {
316 return sp.groupid == groupid && sp.id == id;
317 });
318}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000319
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000320// Checks if |sp| defines parameters for a single primary stream. There may
brandtr9688e382016-11-22 00:59:48 -0800321// be an RTX stream or a FlexFEC stream (or both) associated with the primary
322// stream. Leaving as non-static so we can test this function.
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +0000323bool IsOneSsrcStream(const StreamParams& sp);
324
325// Checks if |sp| defines parameters for one Simulcast stream. There may be RTX
326// streams associated with the simulcast streams. Leaving as non-static so we
327// can test this function.
328bool IsSimulcastStream(const StreamParams& sp);
329
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000330} // namespace cricket
331
kjellandera96e2d72016-02-04 23:52:28 -0800332#endif // WEBRTC_MEDIA_BASE_STREAMPARAMS_H_