stream_params.cc (7247B)
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 11 #include "media/base/stream_params.h" 12 13 #include <cstddef> 14 #include <cstdint> 15 #include <string> 16 #include <vector> 17 18 #include "absl/algorithm/container.h" 19 #include "api/array_view.h" 20 #include "media/base/rid_description.h" 21 #include "rtc_base/checks.h" 22 #include "rtc_base/strings/string_builder.h" 23 #include "rtc_base/unique_id_generator.h" 24 25 namespace webrtc { 26 namespace { 27 28 void AppendSsrcs(ArrayView<const uint32_t> ssrcs, SimpleStringBuilder* sb) { 29 *sb << "ssrcs:["; 30 const char* delimiter = ""; 31 for (uint32_t ssrc : ssrcs) { 32 *sb << delimiter << ssrc; 33 delimiter = ","; 34 } 35 *sb << "]"; 36 } 37 38 void AppendSsrcGroups(ArrayView<const SsrcGroup> ssrc_groups, 39 SimpleStringBuilder* sb) { 40 *sb << "ssrc_groups:"; 41 const char* delimiter = ""; 42 for (const SsrcGroup& ssrc_group : ssrc_groups) { 43 *sb << delimiter << ssrc_group.ToString(); 44 delimiter = ","; 45 } 46 } 47 48 void AppendStreamIds(ArrayView<const std::string> stream_ids, 49 SimpleStringBuilder* sb) { 50 *sb << "stream_ids:"; 51 const char* delimiter = ""; 52 for (const std::string& stream_id : stream_ids) { 53 *sb << delimiter << stream_id; 54 delimiter = ","; 55 } 56 } 57 58 void AppendRids(ArrayView<const RidDescription> rids, SimpleStringBuilder* sb) { 59 *sb << "rids:["; 60 const char* delimiter = ""; 61 for (const RidDescription& rid : rids) { 62 *sb << delimiter << rid.rid; 63 delimiter = ","; 64 } 65 *sb << "]"; 66 } 67 68 } // namespace 69 70 const char kFecSsrcGroupSemantics[] = "FEC"; 71 const char kFecFrSsrcGroupSemantics[] = "FEC-FR"; 72 const char kFidSsrcGroupSemantics[] = "FID"; 73 const char kSimSsrcGroupSemantics[] = "SIM"; 74 75 bool GetStream(const StreamParamsVec& streams, 76 const StreamSelector& selector, 77 StreamParams* stream_out) { 78 const StreamParams* found = GetStream(streams, selector); 79 if (found && stream_out) 80 *stream_out = *found; 81 return found != nullptr; 82 } 83 84 SsrcGroup::SsrcGroup(const std::string& usage, 85 const std::vector<uint32_t>& ssrcs) 86 : semantics(usage), ssrcs(ssrcs) {} 87 SsrcGroup::SsrcGroup(const SsrcGroup&) = default; 88 SsrcGroup::SsrcGroup(SsrcGroup&&) = default; 89 SsrcGroup::~SsrcGroup() = default; 90 91 SsrcGroup& SsrcGroup::operator=(const SsrcGroup&) = default; 92 SsrcGroup& SsrcGroup::operator=(SsrcGroup&&) = default; 93 94 bool SsrcGroup::has_semantics(const std::string& semantics_in) const { 95 return (semantics == semantics_in && !ssrcs.empty()); 96 } 97 98 std::string SsrcGroup::ToString() const { 99 char buf[1024]; 100 SimpleStringBuilder sb(buf); 101 sb << "{"; 102 sb << "semantics:" << semantics << ";"; 103 AppendSsrcs(ssrcs, &sb); 104 sb << "}"; 105 return sb.str(); 106 } 107 108 StreamParams::StreamParams() = default; 109 StreamParams::StreamParams(const StreamParams&) = default; 110 StreamParams::StreamParams(StreamParams&&) = default; 111 StreamParams::~StreamParams() = default; 112 StreamParams& StreamParams::operator=(const StreamParams&) = default; 113 StreamParams& StreamParams::operator=(StreamParams&&) = default; 114 115 bool StreamParams::operator==(const StreamParams& other) const { 116 return (id == other.id && ssrcs == other.ssrcs && 117 ssrc_groups == other.ssrc_groups && cname == other.cname && 118 stream_ids_ == other.stream_ids_ && 119 // RIDs are not required to be in the same order for equality. 120 absl::c_is_permutation(rids_, other.rids_)); 121 } 122 123 std::string StreamParams::ToString() const { 124 char buf[2 * 1024]; 125 SimpleStringBuilder sb(buf); 126 sb << "{"; 127 if (!id.empty()) { 128 sb << "id:" << id << ";"; 129 } 130 AppendSsrcs(ssrcs, &sb); 131 sb << ";"; 132 AppendSsrcGroups(ssrc_groups, &sb); 133 sb << ";"; 134 if (!cname.empty()) { 135 sb << "cname:" << cname << ";"; 136 } 137 AppendStreamIds(stream_ids_, &sb); 138 sb << ";"; 139 if (!rids_.empty()) { 140 AppendRids(rids_, &sb); 141 sb << ";"; 142 } 143 sb << "}"; 144 return sb.str(); 145 } 146 147 void StreamParams::GenerateSsrcs(int num_layers, 148 bool generate_fid, 149 bool generate_fec_fr, 150 UniqueRandomIdGenerator* ssrc_generator) { 151 RTC_DCHECK_GE(num_layers, 0); 152 RTC_DCHECK(ssrc_generator); 153 std::vector<uint32_t> primary_ssrcs; 154 for (int i = 0; i < num_layers; ++i) { 155 uint32_t ssrc = ssrc_generator->GenerateId(); 156 primary_ssrcs.push_back(ssrc); 157 add_ssrc(ssrc); 158 } 159 160 if (num_layers > 1) { 161 SsrcGroup simulcast(kSimSsrcGroupSemantics, primary_ssrcs); 162 ssrc_groups.push_back(simulcast); 163 } 164 165 if (generate_fid) { 166 for (uint32_t ssrc : primary_ssrcs) { 167 AddFidSsrc(ssrc, ssrc_generator->GenerateId()); 168 } 169 } 170 171 if (generate_fec_fr) { 172 for (uint32_t ssrc : primary_ssrcs) { 173 AddFecFrSsrc(ssrc, ssrc_generator->GenerateId()); 174 } 175 } 176 } 177 178 void StreamParams::GetPrimarySsrcs(std::vector<uint32_t>* primary_ssrcs) const { 179 const SsrcGroup* sim_group = get_ssrc_group(kSimSsrcGroupSemantics); 180 if (sim_group == nullptr) { 181 primary_ssrcs->push_back(first_ssrc()); 182 } else { 183 primary_ssrcs->insert(primary_ssrcs->end(), sim_group->ssrcs.begin(), 184 sim_group->ssrcs.end()); 185 } 186 } 187 188 void StreamParams::GetSecondarySsrcs( 189 const std::string& semantics, 190 const std::vector<uint32_t>& primary_ssrcs, 191 std::vector<uint32_t>* secondary_ssrcs) const { 192 for (uint32_t primary_ssrc : primary_ssrcs) { 193 uint32_t secondary_ssrc; 194 if (GetSecondarySsrc(semantics, primary_ssrc, &secondary_ssrc)) { 195 secondary_ssrcs->push_back(secondary_ssrc); 196 } 197 } 198 } 199 200 void StreamParams::GetFidSsrcs(const std::vector<uint32_t>& primary_ssrcs, 201 std::vector<uint32_t>* fid_ssrcs) const { 202 return GetSecondarySsrcs(kFidSsrcGroupSemantics, primary_ssrcs, fid_ssrcs); 203 } 204 205 bool StreamParams::AddSecondarySsrc(const std::string& semantics, 206 uint32_t primary_ssrc, 207 uint32_t secondary_ssrc) { 208 if (!has_ssrc(primary_ssrc)) { 209 return false; 210 } 211 212 ssrcs.push_back(secondary_ssrc); 213 ssrc_groups.push_back(SsrcGroup(semantics, {primary_ssrc, secondary_ssrc})); 214 return true; 215 } 216 217 bool StreamParams::GetSecondarySsrc(const std::string& semantics, 218 uint32_t primary_ssrc, 219 uint32_t* secondary_ssrc) const { 220 for (const SsrcGroup& ssrc_group : ssrc_groups) { 221 if (ssrc_group.has_semantics(semantics) && ssrc_group.ssrcs.size() >= 2 && 222 ssrc_group.ssrcs[0] == primary_ssrc) { 223 *secondary_ssrc = ssrc_group.ssrcs[1]; 224 return true; 225 } 226 } 227 return false; 228 } 229 230 std::vector<std::string> StreamParams::stream_ids() const { 231 return stream_ids_; 232 } 233 234 void StreamParams::set_stream_ids(const std::vector<std::string>& stream_ids) { 235 stream_ids_ = stream_ids; 236 } 237 238 std::string StreamParams::first_stream_id() const { 239 return stream_ids_.empty() ? "" : stream_ids_[0]; 240 } 241 242 } // namespace webrtc