blob: db781acfc776eea9ea2942ffb9ceb82aec10ab16 [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
Steve Anton10542f22019-01-11 09:11:00 -080011#include "media/base/stream_params.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000012
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <stdint.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020014
sergeyu@chromium.org5bc25c42013-12-05 00:24:06 +000015#include <list>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000016
Steve Anton2c9ebef2019-01-28 17:27:58 -080017#include "absl/algorithm/container.h"
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "api/array_view.h"
Jonas Olsson88c99562018-05-03 11:45:33 +020019#include "rtc_base/strings/string_builder.h"
Steve Antonac7539e2018-02-26 17:20:29 -080020
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +000021namespace cricket {
pthatcher@webrtc.orge2b75852014-12-16 21:09:08 +000022namespace {
Amit Hilbuchc57d5732018-12-11 15:30:11 -080023
Steve Antonc6643142019-02-15 10:50:44 -080024void AppendSsrcs(rtc::ArrayView<const uint32_t> ssrcs,
25 rtc::SimpleStringBuilder* sb) {
26 *sb << "ssrcs:[";
Amit Hilbuchc57d5732018-12-11 15:30:11 -080027 const char* delimiter = "";
Steve Antonc6643142019-02-15 10:50:44 -080028 for (uint32_t ssrc : ssrcs) {
29 *sb << delimiter << ssrc;
Amit Hilbuchc57d5732018-12-11 15:30:11 -080030 delimiter = ",";
31 }
Steve Antonc6643142019-02-15 10:50:44 -080032 *sb << "]";
33}
34
35void AppendSsrcGroups(rtc::ArrayView<const SsrcGroup> ssrc_groups,
36 rtc::SimpleStringBuilder* sb) {
37 *sb << "ssrc_groups:";
38 const char* delimiter = "";
39 for (const SsrcGroup& ssrc_group : ssrc_groups) {
40 *sb << delimiter << ssrc_group.ToString();
41 delimiter = ",";
42 }
43}
44
45void AppendStreamIds(rtc::ArrayView<const std::string> stream_ids,
46 rtc::SimpleStringBuilder* sb) {
47 *sb << "stream_ids:";
48 const char* delimiter = "";
49 for (const std::string& stream_id : stream_ids) {
50 *sb << delimiter << stream_id;
51 delimiter = ",";
52 }
53}
54
55void AppendRids(rtc::ArrayView<const RidDescription> rids,
56 rtc::SimpleStringBuilder* sb) {
57 *sb << "rids:[";
58 const char* delimiter = "";
59 for (const RidDescription& rid : rids) {
60 *sb << delimiter << rid.rid;
61 delimiter = ",";
62 }
63 *sb << "]";
Amit Hilbuchc57d5732018-12-11 15:30:11 -080064}
65
Yves Gerey665174f2018-06-19 15:03:05 +020066} // namespace
pthatcher@webrtc.orge2b75852014-12-16 21:09:08 +000067
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068const char kFecSsrcGroupSemantics[] = "FEC";
brandtr9688e382016-11-22 00:59:48 -080069const char kFecFrSsrcGroupSemantics[] = "FEC-FR";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000070const char kFidSsrcGroupSemantics[] = "FID";
wu@webrtc.orgcecfd182013-10-30 05:18:12 +000071const char kSimSsrcGroupSemantics[] = "SIM";
henrike@webrtc.org28e20752013-07-10 00:45:36 +000072
tommi@webrtc.org586f2ed2015-01-22 23:00:41 +000073bool GetStream(const StreamParamsVec& streams,
74 const StreamSelector& selector,
75 StreamParams* stream_out) {
76 const StreamParams* found = GetStream(streams, selector);
77 if (found && stream_out)
78 *stream_out = *found;
79 return found != nullptr;
80}
81
Paulina Hensman11b34f42018-04-09 14:24:52 +020082SsrcGroup::SsrcGroup(const std::string& usage,
83 const std::vector<uint32_t>& ssrcs)
84 : semantics(usage), ssrcs(ssrcs) {}
85SsrcGroup::SsrcGroup(const SsrcGroup&) = default;
86SsrcGroup::SsrcGroup(SsrcGroup&&) = default;
87SsrcGroup::~SsrcGroup() = default;
88
89SsrcGroup& SsrcGroup::operator=(const SsrcGroup&) = default;
90SsrcGroup& SsrcGroup::operator=(SsrcGroup&&) = default;
91
henrike@webrtc.org28e20752013-07-10 00:45:36 +000092bool SsrcGroup::has_semantics(const std::string& semantics_in) const {
93 return (semantics == semantics_in && ssrcs.size() > 0);
94}
95
96std::string SsrcGroup::ToString() const {
Jonas Olsson88c99562018-05-03 11:45:33 +020097 char buf[1024];
98 rtc::SimpleStringBuilder sb(buf);
99 sb << "{";
100 sb << "semantics:" << semantics << ";";
Steve Antonc6643142019-02-15 10:50:44 -0800101 AppendSsrcs(ssrcs, &sb);
Jonas Olsson88c99562018-05-03 11:45:33 +0200102 sb << "}";
103 return sb.str();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000104}
105
Paulina Hensman11b34f42018-04-09 14:24:52 +0200106StreamParams::StreamParams() = default;
107StreamParams::StreamParams(const StreamParams&) = default;
108StreamParams::StreamParams(StreamParams&&) = default;
109StreamParams::~StreamParams() = default;
110StreamParams& StreamParams::operator=(const StreamParams&) = default;
111StreamParams& StreamParams::operator=(StreamParams&&) = default;
112
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800113bool StreamParams::operator==(const StreamParams& other) const {
114 return (groupid == other.groupid && id == other.id && ssrcs == other.ssrcs &&
115 ssrc_groups == other.ssrc_groups && cname == other.cname &&
116 stream_ids_ == other.stream_ids_ &&
117 // RIDs are not required to be in the same order for equality.
Steve Anton2c9ebef2019-01-28 17:27:58 -0800118 absl::c_is_permutation(rids_, other.rids_));
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800119}
120
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000121std::string StreamParams::ToString() const {
Jonas Olsson88c99562018-05-03 11:45:33 +0200122 char buf[2 * 1024];
123 rtc::SimpleStringBuilder sb(buf);
124 sb << "{";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000125 if (!groupid.empty()) {
Jonas Olsson88c99562018-05-03 11:45:33 +0200126 sb << "groupid:" << groupid << ";";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000127 }
128 if (!id.empty()) {
Jonas Olsson88c99562018-05-03 11:45:33 +0200129 sb << "id:" << id << ";";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000130 }
Steve Antonc6643142019-02-15 10:50:44 -0800131 AppendSsrcs(ssrcs, &sb);
132 sb << ";";
133 AppendSsrcGroups(ssrc_groups, &sb);
Jonas Olsson88c99562018-05-03 11:45:33 +0200134 sb << ";";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000135 if (!cname.empty()) {
Jonas Olsson88c99562018-05-03 11:45:33 +0200136 sb << "cname:" << cname << ";";
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000137 }
Steve Antonc6643142019-02-15 10:50:44 -0800138 AppendStreamIds(stream_ids_, &sb);
Jonas Olsson88c99562018-05-03 11:45:33 +0200139 sb << ";";
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800140 if (!rids_.empty()) {
Steve Antonc6643142019-02-15 10:50:44 -0800141 AppendRids(rids_, &sb);
142 sb << ";";
Amit Hilbuchc57d5732018-12-11 15:30:11 -0800143 }
Jonas Olsson88c99562018-05-03 11:45:33 +0200144 sb << "}";
145 return sb.str();
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000146}
Amit Hilbuchbcd39d42019-01-25 17:13:56 -0800147
148void StreamParams::GenerateSsrcs(int num_layers,
149 bool generate_fid,
150 bool generate_fec_fr,
151 rtc::UniqueRandomIdGenerator* ssrc_generator) {
152 RTC_DCHECK_GE(num_layers, 0);
153 RTC_DCHECK(ssrc_generator);
154 std::vector<uint32_t> primary_ssrcs;
155 for (int i = 0; i < num_layers; ++i) {
156 uint32_t ssrc = ssrc_generator->GenerateId();
157 primary_ssrcs.push_back(ssrc);
158 add_ssrc(ssrc);
159 }
160
161 if (num_layers > 1) {
162 SsrcGroup simulcast(kSimSsrcGroupSemantics, primary_ssrcs);
163 ssrc_groups.push_back(simulcast);
164 }
165
166 if (generate_fid) {
167 for (uint32_t ssrc : primary_ssrcs) {
168 AddFidSsrc(ssrc, ssrc_generator->GenerateId());
169 }
170 }
171
172 if (generate_fec_fr) {
173 for (uint32_t ssrc : primary_ssrcs) {
174 AddFecFrSsrc(ssrc, ssrc_generator->GenerateId());
175 }
176 }
177}
178
Peter Boström0c4e06b2015-10-07 12:23:21 +0200179void StreamParams::GetPrimarySsrcs(std::vector<uint32_t>* ssrcs) const {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000180 const SsrcGroup* sim_group = get_ssrc_group(kSimSsrcGroupSemantics);
181 if (sim_group == NULL) {
182 ssrcs->push_back(first_ssrc());
183 } else {
Steve Antonc6643142019-02-15 10:50:44 -0800184 ssrcs->insert(ssrcs->end(), sim_group->ssrcs.begin(),
185 sim_group->ssrcs.end());
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000186 }
187}
188
Peter Boström0c4e06b2015-10-07 12:23:21 +0200189void StreamParams::GetFidSsrcs(const std::vector<uint32_t>& primary_ssrcs,
190 std::vector<uint32_t>* fid_ssrcs) const {
Steve Antonc6643142019-02-15 10:50:44 -0800191 for (uint32_t primary_ssrc : primary_ssrcs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +0200192 uint32_t fid_ssrc;
Steve Antonc6643142019-02-15 10:50:44 -0800193 if (GetFidSsrc(primary_ssrc, &fid_ssrc)) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000194 fid_ssrcs->push_back(fid_ssrc);
195 }
196 }
197}
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000198
199bool StreamParams::AddSecondarySsrc(const std::string& semantics,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200200 uint32_t primary_ssrc,
201 uint32_t secondary_ssrc) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000202 if (!has_ssrc(primary_ssrc)) {
203 return false;
204 }
205
206 ssrcs.push_back(secondary_ssrc);
Steve Antonc6643142019-02-15 10:50:44 -0800207 ssrc_groups.push_back(SsrcGroup(semantics, {primary_ssrc, secondary_ssrc}));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000208 return true;
209}
210
211bool StreamParams::GetSecondarySsrc(const std::string& semantics,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200212 uint32_t primary_ssrc,
213 uint32_t* secondary_ssrc) const {
Steve Antonc6643142019-02-15 10:50:44 -0800214 for (const SsrcGroup& ssrc_group : ssrc_groups) {
215 if (ssrc_group.has_semantics(semantics) && ssrc_group.ssrcs.size() >= 2 &&
216 ssrc_group.ssrcs[0] == primary_ssrc) {
217 *secondary_ssrc = ssrc_group.ssrcs[1];
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000218 return true;
219 }
220 }
221 return false;
222}
223
Seth Hampson845e8782018-03-02 11:34:10 -0800224std::vector<std::string> StreamParams::stream_ids() const {
Seth Hampson5b4f0752018-04-02 16:31:36 -0700225 return stream_ids_;
Steve Antonac7539e2018-02-26 17:20:29 -0800226}
227
Seth Hampson845e8782018-03-02 11:34:10 -0800228void StreamParams::set_stream_ids(const std::vector<std::string>& stream_ids) {
Seth Hampson5b4f0752018-04-02 16:31:36 -0700229 stream_ids_ = stream_ids;
Steve Antonac7539e2018-02-26 17:20:29 -0800230}
231
Seth Hampson845e8782018-03-02 11:34:10 -0800232std::string StreamParams::first_stream_id() const {
Seth Hampson5b4f0752018-04-02 16:31:36 -0700233 return stream_ids_.empty() ? "" : stream_ids_[0];
Steve Anton5a26a3a2018-02-28 11:38:47 -0800234}
235
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000236} // namespace cricket