stream_params.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. /*
  2. * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
  3. *
  4. * 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.
  9. */
  10. // This file contains structures for describing SSRCs from a media source such
  11. // as a MediaStreamTrack when it is sent across an RTP session. Multiple media
  12. // sources may be sent across the same RTP session, each of them will be
  13. // described by one StreamParams object
  14. // SsrcGroup is used to describe the relationship between the SSRCs that
  15. // are used for this media source.
  16. // E.x: Consider a source that is sent as 3 simulcast streams
  17. // Let the simulcast elements have SSRC 10, 20, 30.
  18. // Let each simulcast element use FEC and let the protection packets have
  19. // SSRC 11,21,31.
  20. // To describe this 4 SsrcGroups are needed,
  21. // StreamParams would then contain ssrc = {10,11,20,21,30,31} and
  22. // ssrc_groups = {{SIM,{10,20,30}, {FEC,{10,11}, {FEC, {20,21}, {FEC {30,31}}}
  23. // Please see RFC 5576.
  24. // A spec-compliant way to achieve this is to use RIDs and Simulcast attribute
  25. // instead of the ssrc-group. In this method, the StreamParam object will
  26. // have multiple RidDescriptions, each corresponding to a simulcast layer
  27. // and the media section will have a simulcast attribute that indicates
  28. // that these layers are for the same source. This also removes the extra
  29. // lines for redundancy streams, as the same RIDs appear in the redundancy
  30. // packets.
  31. // Note: in the spec compliant simulcast scenario, some of the RIDs might be
  32. // alternatives for one another (such as different encodings for same data).
  33. // In the context of the StreamParams class, the notion of alternatives does
  34. // not exist and all the RIDs will describe different layers of the same source.
  35. // When the StreamParams class is used to configure the media engine, simulcast
  36. // considerations will be used to remove the alternative layers outside of this
  37. // class.
  38. // As an example, let the simulcast layers have RID 10, 20, 30.
  39. // StreamParams would contain rid = { 10, 20, 30 }.
  40. // MediaSection would contain SimulcastDescription specifying these rids.
  41. // a=simulcast:send 10;20;30 (or a=simulcast:send 10,20;30 or similar).
  42. // See https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-13
  43. // and https://tools.ietf.org/html/draft-ietf-mmusic-rid-15.
  44. #ifndef MEDIA_BASE_STREAM_PARAMS_H_
  45. #define MEDIA_BASE_STREAM_PARAMS_H_
  46. #include <stddef.h>
  47. #include <cstdint>
  48. #include <string>
  49. #include <vector>
  50. #include "absl/algorithm/container.h"
  51. #include "media/base/rid_description.h"
  52. #include "rtc_base/constructor_magic.h"
  53. #include "rtc_base/unique_id_generator.h"
  54. namespace cricket {
  55. extern const char kFecSsrcGroupSemantics[];
  56. extern const char kFecFrSsrcGroupSemantics[];
  57. extern const char kFidSsrcGroupSemantics[];
  58. extern const char kSimSsrcGroupSemantics[];
  59. struct SsrcGroup {
  60. SsrcGroup(const std::string& usage, const std::vector<uint32_t>& ssrcs);
  61. SsrcGroup(const SsrcGroup&);
  62. SsrcGroup(SsrcGroup&&);
  63. ~SsrcGroup();
  64. SsrcGroup& operator=(const SsrcGroup&);
  65. SsrcGroup& operator=(SsrcGroup&&);
  66. bool operator==(const SsrcGroup& other) const {
  67. return (semantics == other.semantics && ssrcs == other.ssrcs);
  68. }
  69. bool operator!=(const SsrcGroup& other) const { return !(*this == other); }
  70. bool has_semantics(const std::string& semantics) const;
  71. std::string ToString() const;
  72. std::string semantics; // e.g FIX, FEC, SIM.
  73. std::vector<uint32_t> ssrcs; // SSRCs of this type.
  74. };
  75. // StreamParams is used to represent a sender/track in a SessionDescription.
  76. // In Plan B, this means that multiple StreamParams can exist within one
  77. // MediaContentDescription, while in UnifiedPlan this means that there is one
  78. // StreamParams per MediaContentDescription.
  79. struct StreamParams {
  80. StreamParams();
  81. StreamParams(const StreamParams&);
  82. StreamParams(StreamParams&&);
  83. ~StreamParams();
  84. StreamParams& operator=(const StreamParams&);
  85. StreamParams& operator=(StreamParams&&);
  86. static StreamParams CreateLegacy(uint32_t ssrc) {
  87. StreamParams stream;
  88. stream.ssrcs.push_back(ssrc);
  89. return stream;
  90. }
  91. bool operator==(const StreamParams& other) const;
  92. bool operator!=(const StreamParams& other) const { return !(*this == other); }
  93. uint32_t first_ssrc() const {
  94. if (ssrcs.empty()) {
  95. return 0;
  96. }
  97. return ssrcs[0];
  98. }
  99. bool has_ssrcs() const { return !ssrcs.empty(); }
  100. bool has_ssrc(uint32_t ssrc) const {
  101. return absl::c_linear_search(ssrcs, ssrc);
  102. }
  103. void add_ssrc(uint32_t ssrc) { ssrcs.push_back(ssrc); }
  104. bool has_ssrc_groups() const { return !ssrc_groups.empty(); }
  105. bool has_ssrc_group(const std::string& semantics) const {
  106. return (get_ssrc_group(semantics) != NULL);
  107. }
  108. const SsrcGroup* get_ssrc_group(const std::string& semantics) const {
  109. for (const SsrcGroup& ssrc_group : ssrc_groups) {
  110. if (ssrc_group.has_semantics(semantics)) {
  111. return &ssrc_group;
  112. }
  113. }
  114. return NULL;
  115. }
  116. // Convenience function to add an FID ssrc for a primary_ssrc
  117. // that's already been added.
  118. bool AddFidSsrc(uint32_t primary_ssrc, uint32_t fid_ssrc) {
  119. return AddSecondarySsrc(kFidSsrcGroupSemantics, primary_ssrc, fid_ssrc);
  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.
  123. bool GetFidSsrc(uint32_t primary_ssrc, uint32_t* fid_ssrc) const {
  124. return GetSecondarySsrc(kFidSsrcGroupSemantics, primary_ssrc, fid_ssrc);
  125. }
  126. // Convenience function to add an FEC-FR ssrc for a primary_ssrc
  127. // that's already been added.
  128. bool AddFecFrSsrc(uint32_t primary_ssrc, uint32_t fecfr_ssrc) {
  129. return AddSecondarySsrc(kFecFrSsrcGroupSemantics, primary_ssrc, fecfr_ssrc);
  130. }
  131. // Convenience function to lookup the FEC-FR ssrc for a primary_ssrc.
  132. // Returns false if primary_ssrc not found or FEC-FR not defined for it.
  133. bool GetFecFrSsrc(uint32_t primary_ssrc, uint32_t* fecfr_ssrc) const {
  134. return GetSecondarySsrc(kFecFrSsrcGroupSemantics, primary_ssrc, fecfr_ssrc);
  135. }
  136. // Convenience function to populate the StreamParams with the requested number
  137. // of SSRCs along with accompanying FID and FEC-FR ssrcs if requested.
  138. // SSRCs are generated using the given generator.
  139. void GenerateSsrcs(int num_layers,
  140. bool generate_fid,
  141. bool generate_fec_fr,
  142. rtc::UniqueRandomIdGenerator* ssrc_generator);
  143. // Convenience to get all the SIM SSRCs if there are SIM ssrcs, or
  144. // the first SSRC otherwise.
  145. void GetPrimarySsrcs(std::vector<uint32_t>* ssrcs) const;
  146. // Convenience to get all the FID SSRCs for the given primary ssrcs.
  147. // If a given primary SSRC does not have a FID SSRC, the list of FID
  148. // SSRCS will be smaller than the list of primary SSRCs.
  149. void GetFidSsrcs(const std::vector<uint32_t>& primary_ssrcs,
  150. std::vector<uint32_t>* fid_ssrcs) const;
  151. // Stream ids serialized to SDP.
  152. std::vector<std::string> stream_ids() const;
  153. void set_stream_ids(const std::vector<std::string>& stream_ids);
  154. // Returns the first stream id or "" if none exist. This method exists only
  155. // as temporary backwards compatibility with the old sync_label.
  156. std::string first_stream_id() const;
  157. std::string ToString() const;
  158. // Resource of the MUC jid of the participant of with this stream.
  159. // For 1:1 calls, should be left empty (which means remote streams
  160. // and local streams should not be mixed together). This is not used
  161. // internally and should be deprecated.
  162. std::string groupid;
  163. // A unique identifier of the StreamParams object. When the SDP is created,
  164. // this comes from the track ID of the sender that the StreamParams object
  165. // is associated with.
  166. std::string id;
  167. // There may be no SSRCs stored in unsignaled case when stream_ids are
  168. // signaled with a=msid lines.
  169. std::vector<uint32_t> ssrcs; // All SSRCs for this source
  170. std::vector<SsrcGroup> ssrc_groups; // e.g. FID, FEC, SIM
  171. std::string cname; // RTCP CNAME
  172. // RID functionality according to
  173. // https://tools.ietf.org/html/draft-ietf-mmusic-rid-15
  174. // Each layer can be represented by a RID identifier and can also have
  175. // restrictions (such as max-width, max-height, etc.)
  176. // If the track has multiple layers (ex. Simulcast), each layer will be
  177. // represented by a RID.
  178. bool has_rids() const { return !rids_.empty(); }
  179. const std::vector<RidDescription>& rids() const { return rids_; }
  180. void set_rids(const std::vector<RidDescription>& rids) { rids_ = rids; }
  181. private:
  182. bool AddSecondarySsrc(const std::string& semantics,
  183. uint32_t primary_ssrc,
  184. uint32_t secondary_ssrc);
  185. bool GetSecondarySsrc(const std::string& semantics,
  186. uint32_t primary_ssrc,
  187. uint32_t* secondary_ssrc) const;
  188. // The stream IDs of the sender that the StreamParams object is associated
  189. // with. In Plan B this should always be size of 1, while in Unified Plan this
  190. // could be none or multiple stream IDs.
  191. std::vector<std::string> stream_ids_;
  192. std::vector<RidDescription> rids_;
  193. };
  194. // A Stream can be selected by either groupid+id or ssrc.
  195. struct StreamSelector {
  196. explicit StreamSelector(uint32_t ssrc) : ssrc(ssrc) {}
  197. StreamSelector(const std::string& groupid, const std::string& streamid)
  198. : ssrc(0), groupid(groupid), streamid(streamid) {}
  199. explicit StreamSelector(const std::string& streamid)
  200. : ssrc(0), streamid(streamid) {}
  201. bool Matches(const StreamParams& stream) const {
  202. if (ssrc == 0) {
  203. return stream.groupid == groupid && stream.id == streamid;
  204. } else {
  205. return stream.has_ssrc(ssrc);
  206. }
  207. }
  208. uint32_t ssrc;
  209. std::string groupid;
  210. std::string streamid;
  211. };
  212. typedef std::vector<StreamParams> StreamParamsVec;
  213. template <class Condition>
  214. const StreamParams* GetStream(const StreamParamsVec& streams,
  215. Condition condition) {
  216. auto found = absl::c_find_if(streams, condition);
  217. return found == streams.end() ? nullptr : &(*found);
  218. }
  219. template <class Condition>
  220. StreamParams* GetStream(StreamParamsVec& streams, Condition condition) {
  221. auto found = absl::c_find_if(streams, condition);
  222. return found == streams.end() ? nullptr : &(*found);
  223. }
  224. inline bool HasStreamWithNoSsrcs(const StreamParamsVec& streams) {
  225. return GetStream(streams,
  226. [](const StreamParams& sp) { return !sp.has_ssrcs(); });
  227. }
  228. inline const StreamParams* GetStreamBySsrc(const StreamParamsVec& streams,
  229. uint32_t ssrc) {
  230. return GetStream(
  231. streams, [&ssrc](const StreamParams& sp) { return sp.has_ssrc(ssrc); });
  232. }
  233. inline const StreamParams* GetStreamByIds(const StreamParamsVec& streams,
  234. const std::string& groupid,
  235. const std::string& id) {
  236. return GetStream(streams, [&groupid, &id](const StreamParams& sp) {
  237. return sp.groupid == groupid && sp.id == id;
  238. });
  239. }
  240. inline StreamParams* GetStreamByIds(StreamParamsVec& streams,
  241. const std::string& groupid,
  242. const std::string& id) {
  243. return GetStream(streams, [&groupid, &id](const StreamParams& sp) {
  244. return sp.groupid == groupid && sp.id == id;
  245. });
  246. }
  247. inline const StreamParams* GetStream(const StreamParamsVec& streams,
  248. const StreamSelector& selector) {
  249. return GetStream(streams, [&selector](const StreamParams& sp) {
  250. return selector.Matches(sp);
  251. });
  252. }
  253. template <class Condition>
  254. bool RemoveStream(StreamParamsVec* streams, Condition condition) {
  255. auto iter(std::remove_if(streams->begin(), streams->end(), condition));
  256. if (iter == streams->end())
  257. return false;
  258. streams->erase(iter, streams->end());
  259. return true;
  260. }
  261. // Removes the stream from streams. Returns true if a stream is
  262. // found and removed.
  263. inline bool RemoveStream(StreamParamsVec* streams,
  264. const StreamSelector& selector) {
  265. return RemoveStream(streams, [&selector](const StreamParams& sp) {
  266. return selector.Matches(sp);
  267. });
  268. }
  269. inline bool RemoveStreamBySsrc(StreamParamsVec* streams, uint32_t ssrc) {
  270. return RemoveStream(
  271. streams, [&ssrc](const StreamParams& sp) { return sp.has_ssrc(ssrc); });
  272. }
  273. inline bool RemoveStreamByIds(StreamParamsVec* streams,
  274. const std::string& groupid,
  275. const std::string& id) {
  276. return RemoveStream(streams, [&groupid, &id](const StreamParams& sp) {
  277. return sp.groupid == groupid && sp.id == id;
  278. });
  279. }
  280. } // namespace cricket
  281. #endif // MEDIA_BASE_STREAM_PARAMS_H_