RsdparsaSdpAttributeList.cpp (46574B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 5 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "sdp/RsdparsaSdpAttributeList.h" 8 9 #include <limits> 10 #include <ostream> 11 #include <string> 12 13 #include "SdpAttribute.h" 14 #include "mozilla/Assertions.h" 15 #include "nsCRT.h" 16 #include "sdp/RsdparsaSdpGlue.h" 17 #include "sdp/RsdparsaSdpInc.h" 18 19 namespace mozilla { 20 21 MOZ_RUNINIT const std::string RsdparsaSdpAttributeList::kEmptyString = ""; 22 23 RsdparsaSdpAttributeList::~RsdparsaSdpAttributeList() { 24 for (size_t i = 0; i < kNumAttributeTypes; ++i) { 25 delete mAttributes[i]; 26 } 27 } 28 29 bool RsdparsaSdpAttributeList::HasAttribute(AttributeType type, 30 bool sessionFallback) const { 31 return !!GetAttribute(type, sessionFallback); 32 } 33 34 const SdpAttribute* RsdparsaSdpAttributeList::GetAttribute( 35 AttributeType type, bool sessionFallback) const { 36 const SdpAttribute* value = mAttributes[static_cast<size_t>(type)]; 37 // Only do fallback when the attribute can appear at both the media and 38 // session level 39 if (!value && !AtSessionLevel() && sessionFallback && 40 SdpAttribute::IsAllowedAtSessionLevel(type) && 41 SdpAttribute::IsAllowedAtMediaLevel(type)) { 42 return mSessionAttributes->GetAttribute(type, false); 43 } 44 return value; 45 } 46 47 void RsdparsaSdpAttributeList::RemoveAttribute(AttributeType type) { 48 delete mAttributes[static_cast<size_t>(type)]; 49 mAttributes[static_cast<size_t>(type)] = nullptr; 50 } 51 52 void RsdparsaSdpAttributeList::Clear() { 53 for (size_t i = 0; i < kNumAttributeTypes; ++i) { 54 RemoveAttribute(static_cast<AttributeType>(i)); 55 } 56 } 57 58 uint32_t RsdparsaSdpAttributeList::Count() const { 59 uint32_t count = 0; 60 for (size_t i = 0; i < kNumAttributeTypes; ++i) { 61 if (mAttributes[i]) { 62 count++; 63 } 64 } 65 return count; 66 } 67 68 void RsdparsaSdpAttributeList::SetAttribute(SdpAttribute* attr) { 69 if (!IsAllowedHere(attr->GetType())) { 70 MOZ_ASSERT(false, "This type of attribute is not allowed here"); 71 delete attr; 72 return; 73 } 74 RemoveAttribute(attr->GetType()); 75 mAttributes[attr->GetType()] = attr; 76 } 77 78 const std::vector<std::string>& RsdparsaSdpAttributeList::GetCandidate() const { 79 if (!HasAttribute(SdpAttribute::kCandidateAttribute)) { 80 MOZ_CRASH(); 81 } 82 83 return static_cast<const SdpMultiStringAttribute*>( 84 GetAttribute(SdpAttribute::kCandidateAttribute)) 85 ->mValues; 86 } 87 88 const SdpConnectionAttribute& RsdparsaSdpAttributeList::GetConnection() const { 89 if (!HasAttribute(SdpAttribute::kConnectionAttribute)) { 90 MOZ_CRASH(); 91 } 92 93 return *static_cast<const SdpConnectionAttribute*>( 94 GetAttribute(SdpAttribute::kConnectionAttribute)); 95 } 96 97 SdpDirectionAttribute::Direction RsdparsaSdpAttributeList::GetDirection() 98 const { 99 if (!HasAttribute(SdpAttribute::kDirectionAttribute)) { 100 MOZ_CRASH(); 101 } 102 103 const SdpAttribute* attr = GetAttribute(SdpAttribute::kDirectionAttribute); 104 return static_cast<const SdpDirectionAttribute*>(attr)->mValue; 105 } 106 107 const SdpDtlsMessageAttribute& RsdparsaSdpAttributeList::GetDtlsMessage() 108 const { 109 if (!HasAttribute(SdpAttribute::kDtlsMessageAttribute)) { 110 MOZ_CRASH(); 111 } 112 const SdpAttribute* attr = GetAttribute(SdpAttribute::kDtlsMessageAttribute); 113 return *static_cast<const SdpDtlsMessageAttribute*>(attr); 114 } 115 116 const SdpExtmapAttributeList& RsdparsaSdpAttributeList::GetExtmap() const { 117 if (!HasAttribute(SdpAttribute::kExtmapAttribute)) { 118 MOZ_CRASH(); 119 } 120 121 return *static_cast<const SdpExtmapAttributeList*>( 122 GetAttribute(SdpAttribute::kExtmapAttribute)); 123 } 124 125 const SdpFingerprintAttributeList& RsdparsaSdpAttributeList::GetFingerprint() 126 const { 127 if (!HasAttribute(SdpAttribute::kFingerprintAttribute)) { 128 MOZ_CRASH(); 129 } 130 const SdpAttribute* attr = GetAttribute(SdpAttribute::kFingerprintAttribute); 131 return *static_cast<const SdpFingerprintAttributeList*>(attr); 132 } 133 134 const SdpFmtpAttributeList& RsdparsaSdpAttributeList::GetFmtp() const { 135 if (!HasAttribute(SdpAttribute::kFmtpAttribute)) { 136 MOZ_CRASH(); 137 } 138 139 return *static_cast<const SdpFmtpAttributeList*>( 140 GetAttribute(SdpAttribute::kFmtpAttribute)); 141 } 142 143 const SdpGroupAttributeList& RsdparsaSdpAttributeList::GetGroup() const { 144 if (!HasAttribute(SdpAttribute::kGroupAttribute)) { 145 MOZ_CRASH(); 146 } 147 148 return *static_cast<const SdpGroupAttributeList*>( 149 GetAttribute(SdpAttribute::kGroupAttribute)); 150 } 151 152 const SdpOptionsAttribute& RsdparsaSdpAttributeList::GetIceOptions() const { 153 if (!HasAttribute(SdpAttribute::kIceOptionsAttribute)) { 154 MOZ_CRASH(); 155 } 156 157 const SdpAttribute* attr = GetAttribute(SdpAttribute::kIceOptionsAttribute); 158 return *static_cast<const SdpOptionsAttribute*>(attr); 159 } 160 161 const std::string& RsdparsaSdpAttributeList::GetIcePwd() const { 162 if (!HasAttribute(SdpAttribute::kIcePwdAttribute)) { 163 return kEmptyString; 164 } 165 const SdpAttribute* attr = GetAttribute(SdpAttribute::kIcePwdAttribute); 166 return static_cast<const SdpStringAttribute*>(attr)->mValue; 167 } 168 169 const std::string& RsdparsaSdpAttributeList::GetIceUfrag() const { 170 if (!HasAttribute(SdpAttribute::kIceUfragAttribute)) { 171 return kEmptyString; 172 } 173 const SdpAttribute* attr = GetAttribute(SdpAttribute::kIceUfragAttribute); 174 return static_cast<const SdpStringAttribute*>(attr)->mValue; 175 } 176 177 const std::string& RsdparsaSdpAttributeList::GetIdentity() const { 178 if (!HasAttribute(SdpAttribute::kIdentityAttribute)) { 179 return kEmptyString; 180 } 181 const SdpAttribute* attr = GetAttribute(SdpAttribute::kIdentityAttribute); 182 return static_cast<const SdpStringAttribute*>(attr)->mValue; 183 } 184 185 const SdpImageattrAttributeList& RsdparsaSdpAttributeList::GetImageattr() 186 const { 187 if (!HasAttribute(SdpAttribute::kImageattrAttribute)) { 188 MOZ_CRASH(); 189 } 190 const SdpAttribute* attr = GetAttribute(SdpAttribute::kImageattrAttribute); 191 return *static_cast<const SdpImageattrAttributeList*>(attr); 192 } 193 194 const SdpSimulcastAttribute& RsdparsaSdpAttributeList::GetSimulcast() const { 195 if (!HasAttribute(SdpAttribute::kSimulcastAttribute)) { 196 MOZ_CRASH(); 197 } 198 const SdpAttribute* attr = GetAttribute(SdpAttribute::kSimulcastAttribute); 199 return *static_cast<const SdpSimulcastAttribute*>(attr); 200 } 201 202 const std::string& RsdparsaSdpAttributeList::GetLabel() const { 203 if (!HasAttribute(SdpAttribute::kLabelAttribute)) { 204 return kEmptyString; 205 } 206 const SdpAttribute* attr = GetAttribute(SdpAttribute::kLabelAttribute); 207 return static_cast<const SdpStringAttribute*>(attr)->mValue; 208 } 209 210 uint32_t RsdparsaSdpAttributeList::GetMaxptime() const { 211 if (!HasAttribute(SdpAttribute::kMaxptimeAttribute)) { 212 MOZ_CRASH(); 213 } 214 const SdpAttribute* attr = GetAttribute(SdpAttribute::kMaxptimeAttribute); 215 return static_cast<const SdpNumberAttribute*>(attr)->mValue; 216 } 217 218 const std::string& RsdparsaSdpAttributeList::GetMid() const { 219 if (!HasAttribute(SdpAttribute::kMidAttribute)) { 220 return kEmptyString; 221 } 222 const SdpAttribute* attr = GetAttribute(SdpAttribute::kMidAttribute); 223 return static_cast<const SdpStringAttribute*>(attr)->mValue; 224 } 225 226 const SdpMsidAttributeList& RsdparsaSdpAttributeList::GetMsid() const { 227 if (!HasAttribute(SdpAttribute::kMsidAttribute)) { 228 MOZ_CRASH(); 229 } 230 const SdpAttribute* attr = GetAttribute(SdpAttribute::kMsidAttribute); 231 return *static_cast<const SdpMsidAttributeList*>(attr); 232 } 233 234 const SdpMsidSemanticAttributeList& RsdparsaSdpAttributeList::GetMsidSemantic() 235 const { 236 if (!HasAttribute(SdpAttribute::kMsidSemanticAttribute)) { 237 MOZ_CRASH(); 238 } 239 const SdpAttribute* attr = GetAttribute(SdpAttribute::kMsidSemanticAttribute); 240 return *static_cast<const SdpMsidSemanticAttributeList*>(attr); 241 } 242 243 const SdpRidAttributeList& RsdparsaSdpAttributeList::GetRid() const { 244 if (!HasAttribute(SdpAttribute::kRidAttribute)) { 245 MOZ_CRASH(); 246 } 247 const SdpAttribute* attr = GetAttribute(SdpAttribute::kRidAttribute); 248 return *static_cast<const SdpRidAttributeList*>(attr); 249 } 250 251 uint32_t RsdparsaSdpAttributeList::GetPtime() const { 252 if (!HasAttribute(SdpAttribute::kPtimeAttribute)) { 253 MOZ_CRASH(); 254 } 255 const SdpAttribute* attr = GetAttribute(SdpAttribute::kPtimeAttribute); 256 return static_cast<const SdpNumberAttribute*>(attr)->mValue; 257 } 258 259 const SdpRtcpAttribute& RsdparsaSdpAttributeList::GetRtcp() const { 260 if (!HasAttribute(SdpAttribute::kRtcpAttribute)) { 261 MOZ_CRASH(); 262 } 263 const SdpAttribute* attr = GetAttribute(SdpAttribute::kRtcpAttribute); 264 return *static_cast<const SdpRtcpAttribute*>(attr); 265 } 266 267 const SdpRtcpFbAttributeList& RsdparsaSdpAttributeList::GetRtcpFb() const { 268 if (!HasAttribute(SdpAttribute::kRtcpFbAttribute)) { 269 MOZ_CRASH(); 270 } 271 const SdpAttribute* attr = GetAttribute(SdpAttribute::kRtcpFbAttribute); 272 return *static_cast<const SdpRtcpFbAttributeList*>(attr); 273 } 274 275 const SdpRemoteCandidatesAttribute& 276 RsdparsaSdpAttributeList::GetRemoteCandidates() const { 277 MOZ_CRASH("Not yet implemented"); 278 } 279 280 const SdpRtpmapAttributeList& RsdparsaSdpAttributeList::GetRtpmap() const { 281 if (!HasAttribute(SdpAttribute::kRtpmapAttribute)) { 282 MOZ_CRASH(); 283 } 284 const SdpAttribute* attr = GetAttribute(SdpAttribute::kRtpmapAttribute); 285 return *static_cast<const SdpRtpmapAttributeList*>(attr); 286 } 287 288 const SdpSctpmapAttributeList& RsdparsaSdpAttributeList::GetSctpmap() const { 289 if (!HasAttribute(SdpAttribute::kSctpmapAttribute)) { 290 MOZ_CRASH(); 291 } 292 const SdpAttribute* attr = GetAttribute(SdpAttribute::kSctpmapAttribute); 293 return *static_cast<const SdpSctpmapAttributeList*>(attr); 294 } 295 296 uint32_t RsdparsaSdpAttributeList::GetSctpPort() const { 297 if (!HasAttribute(SdpAttribute::kSctpPortAttribute)) { 298 MOZ_CRASH(); 299 } 300 301 const SdpAttribute* attr = GetAttribute(SdpAttribute::kSctpPortAttribute); 302 return static_cast<const SdpNumberAttribute*>(attr)->mValue; 303 } 304 305 uint32_t RsdparsaSdpAttributeList::GetMaxMessageSize() const { 306 if (!HasAttribute(SdpAttribute::kMaxMessageSizeAttribute)) { 307 MOZ_CRASH(); 308 } 309 310 const SdpAttribute* attr = 311 GetAttribute(SdpAttribute::kMaxMessageSizeAttribute); 312 return static_cast<const SdpNumberAttribute*>(attr)->mValue; 313 } 314 315 const SdpSetupAttribute& RsdparsaSdpAttributeList::GetSetup() const { 316 if (!HasAttribute(SdpAttribute::kSetupAttribute)) { 317 MOZ_CRASH(); 318 } 319 const SdpAttribute* attr = GetAttribute(SdpAttribute::kSetupAttribute); 320 return *static_cast<const SdpSetupAttribute*>(attr); 321 } 322 323 const SdpSsrcAttributeList& RsdparsaSdpAttributeList::GetSsrc() const { 324 if (!HasAttribute(SdpAttribute::kSsrcAttribute)) { 325 MOZ_CRASH(); 326 } 327 const SdpAttribute* attr = GetAttribute(SdpAttribute::kSsrcAttribute); 328 return *static_cast<const SdpSsrcAttributeList*>(attr); 329 } 330 331 const SdpSsrcGroupAttributeList& RsdparsaSdpAttributeList::GetSsrcGroup() 332 const { 333 if (!HasAttribute(SdpAttribute::kSsrcGroupAttribute)) { 334 MOZ_CRASH(); 335 } 336 const SdpAttribute* attr = GetAttribute(SdpAttribute::kSsrcGroupAttribute); 337 return *static_cast<const SdpSsrcGroupAttributeList*>(attr); 338 } 339 340 void RsdparsaSdpAttributeList::LoadAttribute(RustAttributeList* attributeList, 341 AttributeType type) { 342 if (!mAttributes[type]) { 343 switch (type) { 344 case SdpAttribute::kIceUfragAttribute: 345 LoadIceUfrag(attributeList); 346 return; 347 case SdpAttribute::kIcePwdAttribute: 348 LoadIcePwd(attributeList); 349 return; 350 case SdpAttribute::kIceOptionsAttribute: 351 LoadIceOptions(attributeList); 352 return; 353 case SdpAttribute::kDtlsMessageAttribute: 354 LoadDtlsMessage(attributeList); 355 return; 356 case SdpAttribute::kFingerprintAttribute: 357 LoadFingerprint(attributeList); 358 return; 359 case SdpAttribute::kIdentityAttribute: 360 LoadIdentity(attributeList); 361 return; 362 case SdpAttribute::kSetupAttribute: 363 LoadSetup(attributeList); 364 return; 365 case SdpAttribute::kSsrcAttribute: 366 LoadSsrc(attributeList); 367 return; 368 case SdpAttribute::kRtpmapAttribute: 369 LoadRtpmap(attributeList); 370 return; 371 case SdpAttribute::kFmtpAttribute: 372 LoadFmtp(attributeList); 373 return; 374 case SdpAttribute::kPtimeAttribute: 375 LoadPtime(attributeList); 376 return; 377 case SdpAttribute::kIceLiteAttribute: 378 case SdpAttribute::kRtcpMuxAttribute: 379 case SdpAttribute::kRtcpRsizeAttribute: 380 case SdpAttribute::kBundleOnlyAttribute: 381 case SdpAttribute::kEndOfCandidatesAttribute: 382 case SdpAttribute::kExtmapAllowMixedAttribute: 383 LoadFlags(attributeList); 384 return; 385 case SdpAttribute::kMaxMessageSizeAttribute: 386 LoadMaxMessageSize(attributeList); 387 return; 388 case SdpAttribute::kMidAttribute: 389 LoadMid(attributeList); 390 return; 391 case SdpAttribute::kMsidAttribute: 392 LoadMsid(attributeList); 393 return; 394 case SdpAttribute::kMsidSemanticAttribute: 395 LoadMsidSemantics(attributeList); 396 return; 397 case SdpAttribute::kGroupAttribute: 398 LoadGroup(attributeList); 399 return; 400 case SdpAttribute::kRtcpAttribute: 401 LoadRtcp(attributeList); 402 return; 403 case SdpAttribute::kRtcpFbAttribute: 404 LoadRtcpFb(attributeList); 405 return; 406 case SdpAttribute::kImageattrAttribute: 407 LoadImageattr(attributeList); 408 return; 409 case SdpAttribute::kSctpmapAttribute: 410 LoadSctpmaps(attributeList); 411 return; 412 case SdpAttribute::kDirectionAttribute: 413 LoadDirection(attributeList); 414 return; 415 case SdpAttribute::kRemoteCandidatesAttribute: 416 LoadRemoteCandidates(attributeList); 417 return; 418 case SdpAttribute::kRidAttribute: 419 LoadRids(attributeList); 420 return; 421 case SdpAttribute::kSctpPortAttribute: 422 LoadSctpPort(attributeList); 423 return; 424 case SdpAttribute::kExtmapAttribute: 425 LoadExtmap(attributeList); 426 return; 427 case SdpAttribute::kSimulcastAttribute: 428 LoadSimulcast(attributeList); 429 return; 430 case SdpAttribute::kMaxptimeAttribute: 431 LoadMaxPtime(attributeList); 432 return; 433 case SdpAttribute::kCandidateAttribute: 434 LoadCandidate(attributeList); 435 return; 436 case SdpAttribute::kSsrcGroupAttribute: 437 LoadSsrcGroup(attributeList); 438 return; 439 case SdpAttribute::kConnectionAttribute: 440 case SdpAttribute::kIceMismatchAttribute: 441 case SdpAttribute::kLabelAttribute: 442 // These attributes are unused 443 return; 444 } 445 } 446 } 447 448 void RsdparsaSdpAttributeList::LoadAll(RustAttributeList* attributeList) { 449 for (int i = SdpAttribute::kFirstAttribute; i <= SdpAttribute::kLastAttribute; 450 i++) { 451 LoadAttribute(attributeList, static_cast<SdpAttribute::AttributeType>(i)); 452 } 453 } 454 455 void RsdparsaSdpAttributeList::LoadIceUfrag(RustAttributeList* attributeList) { 456 StringView ufragStr; 457 nsresult nr = sdp_get_iceufrag(attributeList, &ufragStr); 458 if (NS_SUCCEEDED(nr)) { 459 std::string iceufrag = convertStringView(ufragStr); 460 SetAttribute( 461 new SdpStringAttribute(SdpAttribute::kIceUfragAttribute, iceufrag)); 462 } 463 } 464 465 void RsdparsaSdpAttributeList::LoadIcePwd(RustAttributeList* attributeList) { 466 StringView pwdStr; 467 nsresult nr = sdp_get_icepwd(attributeList, &pwdStr); 468 if (NS_SUCCEEDED(nr)) { 469 std::string icePwd = convertStringView(pwdStr); 470 SetAttribute( 471 new SdpStringAttribute(SdpAttribute::kIcePwdAttribute, icePwd)); 472 } 473 } 474 475 void RsdparsaSdpAttributeList::LoadIdentity(RustAttributeList* attributeList) { 476 StringView identityStr; 477 nsresult nr = sdp_get_identity(attributeList, &identityStr); 478 if (NS_SUCCEEDED(nr)) { 479 std::string identity = convertStringView(identityStr); 480 SetAttribute( 481 new SdpStringAttribute(SdpAttribute::kIdentityAttribute, identity)); 482 } 483 } 484 485 void RsdparsaSdpAttributeList::LoadIceOptions( 486 RustAttributeList* attributeList) { 487 StringVec* options; 488 nsresult nr = sdp_get_iceoptions(attributeList, &options); 489 if (NS_SUCCEEDED(nr)) { 490 std::vector<std::string> optionsVec; 491 auto optionsAttr = 492 MakeUnique<SdpOptionsAttribute>(SdpAttribute::kIceOptionsAttribute); 493 for (size_t i = 0; i < string_vec_len(options); i++) { 494 StringView optionStr; 495 string_vec_get_view(options, i, &optionStr); 496 optionsAttr->PushEntry(convertStringView(optionStr)); 497 } 498 SetAttribute(optionsAttr.release()); 499 } 500 } 501 502 void RsdparsaSdpAttributeList::LoadFingerprint( 503 RustAttributeList* attributeList) { 504 size_t nFp = sdp_get_fingerprint_count(attributeList); 505 if (nFp == 0) { 506 return; 507 } 508 auto rustFingerprints = MakeUnique<RustSdpAttributeFingerprint[]>(nFp); 509 sdp_get_fingerprints(attributeList, nFp, rustFingerprints.get()); 510 auto fingerprints = MakeUnique<SdpFingerprintAttributeList>(); 511 for (size_t i = 0; i < nFp; i++) { 512 const RustSdpAttributeFingerprint& fingerprint = rustFingerprints[i]; 513 std::string algorithm; 514 switch (fingerprint.hashAlgorithm) { 515 case RustSdpAttributeFingerprintHashAlgorithm::kSha1: 516 algorithm = "sha-1"; 517 break; 518 case RustSdpAttributeFingerprintHashAlgorithm::kSha224: 519 algorithm = "sha-224"; 520 break; 521 case RustSdpAttributeFingerprintHashAlgorithm::kSha256: 522 algorithm = "sha-256"; 523 break; 524 case RustSdpAttributeFingerprintHashAlgorithm::kSha384: 525 algorithm = "sha-384"; 526 break; 527 case RustSdpAttributeFingerprintHashAlgorithm::kSha512: 528 algorithm = "sha-512"; 529 break; 530 } 531 532 std::vector<uint8_t> fingerprintBytes = 533 convertU8Vec(fingerprint.fingerprint); 534 535 fingerprints->PushEntry(algorithm, fingerprintBytes); 536 } 537 SetAttribute(fingerprints.release()); 538 } 539 540 void RsdparsaSdpAttributeList::LoadDtlsMessage( 541 RustAttributeList* attributeList) { 542 RustSdpAttributeDtlsMessage rustDtlsMessage; 543 nsresult nr = sdp_get_dtls_message(attributeList, &rustDtlsMessage); 544 if (NS_SUCCEEDED(nr)) { 545 SdpDtlsMessageAttribute::Role role; 546 if (rustDtlsMessage.role == RustSdpAttributeDtlsMessageType::kClient) { 547 role = SdpDtlsMessageAttribute::kClient; 548 } else { 549 role = SdpDtlsMessageAttribute::kServer; 550 } 551 552 std::string value = convertStringView(rustDtlsMessage.value); 553 554 SetAttribute(new SdpDtlsMessageAttribute(role, value)); 555 } 556 } 557 558 void RsdparsaSdpAttributeList::LoadSetup(RustAttributeList* attributeList) { 559 RustSdpSetup rustSetup; 560 nsresult nr = sdp_get_setup(attributeList, &rustSetup); 561 if (NS_SUCCEEDED(nr)) { 562 SdpSetupAttribute::Role setupEnum; 563 switch (rustSetup) { 564 case RustSdpSetup::kRustActive: 565 setupEnum = SdpSetupAttribute::kActive; 566 break; 567 case RustSdpSetup::kRustActpass: 568 setupEnum = SdpSetupAttribute::kActpass; 569 break; 570 case RustSdpSetup::kRustHoldconn: 571 setupEnum = SdpSetupAttribute::kHoldconn; 572 break; 573 case RustSdpSetup::kRustPassive: 574 setupEnum = SdpSetupAttribute::kPassive; 575 break; 576 } 577 SetAttribute(new SdpSetupAttribute(setupEnum)); 578 } 579 } 580 581 void RsdparsaSdpAttributeList::LoadSsrc(RustAttributeList* attributeList) { 582 size_t numSsrc = sdp_get_ssrc_count(attributeList); 583 if (numSsrc == 0) { 584 return; 585 } 586 auto rustSsrcs = MakeUnique<RustSdpAttributeSsrc[]>(numSsrc); 587 sdp_get_ssrcs(attributeList, numSsrc, rustSsrcs.get()); 588 auto ssrcs = MakeUnique<SdpSsrcAttributeList>(); 589 for (size_t i = 0; i < numSsrc; i++) { 590 RustSdpAttributeSsrc& ssrc = rustSsrcs[i]; 591 std::string attribute = convertStringView(ssrc.attribute); 592 std::string value = convertStringView(ssrc.value); 593 if (value.length() == 0) { 594 ssrcs->PushEntry(ssrc.id, attribute); 595 } else { 596 ssrcs->PushEntry(ssrc.id, attribute + ":" + value); 597 } 598 } 599 SetAttribute(ssrcs.release()); 600 } 601 602 void RsdparsaSdpAttributeList::LoadSsrcGroup(RustAttributeList* attributeList) { 603 size_t numSsrcGroups = sdp_get_ssrc_group_count(attributeList); 604 if (numSsrcGroups == 0) { 605 return; 606 } 607 auto rustSsrcGroups = MakeUnique<RustSdpAttributeSsrcGroup[]>(numSsrcGroups); 608 sdp_get_ssrc_groups(attributeList, numSsrcGroups, rustSsrcGroups.get()); 609 auto ssrcGroups = MakeUnique<SdpSsrcGroupAttributeList>(); 610 for (size_t i = 0; i < numSsrcGroups; i++) { 611 RustSdpAttributeSsrcGroup& ssrcGroup = rustSsrcGroups[i]; 612 SdpSsrcGroupAttributeList::Semantics semantic; 613 switch (ssrcGroup.semantic) { 614 case RustSdpAttributeSsrcGroupSemantic ::kRustDup: 615 semantic = SdpSsrcGroupAttributeList::kDup; 616 break; 617 case RustSdpAttributeSsrcGroupSemantic ::kRustFec: 618 semantic = SdpSsrcGroupAttributeList::kFec; 619 break; 620 case RustSdpAttributeSsrcGroupSemantic ::kRustFecFr: 621 semantic = SdpSsrcGroupAttributeList::kFecFr; 622 break; 623 case RustSdpAttributeSsrcGroupSemantic ::kRustFid: 624 semantic = SdpSsrcGroupAttributeList::kFid; 625 break; 626 case RustSdpAttributeSsrcGroupSemantic ::kRustSim: 627 semantic = SdpSsrcGroupAttributeList::kSim; 628 break; 629 } 630 std::vector<uint32_t> ssrcs; 631 for (size_t i = 0; i < ssrc_vec_len(ssrcGroup.ssrcs); ++i) { 632 uint32_t ssrc; 633 ssrc_vec_get_id(ssrcGroup.ssrcs, i, &ssrc); 634 ssrcs.push_back(ssrc); 635 } 636 ssrcGroups->PushEntry(semantic, ssrcs); 637 } 638 SetAttribute(ssrcGroups.release()); 639 } 640 641 struct FmtDefaults { 642 uint32_t minimumChannels = 0; 643 }; 644 645 std::tuple<SdpRtpmapAttributeList::CodecType, FmtDefaults> strToCodecType( 646 const std::string& name) { 647 auto codec = SdpRtpmapAttributeList::kOtherCodec; 648 FmtDefaults defaults = {0}; // This is tracked to match SIPCC behavior only 649 if (!nsCRT::strcasecmp(name.c_str(), "opus")) { 650 codec = SdpRtpmapAttributeList::kOpus; 651 defaults = {0}; 652 } else if (!nsCRT::strcasecmp(name.c_str(), "G722")) { 653 codec = SdpRtpmapAttributeList::kG722; 654 defaults = {1}; 655 } else if (!nsCRT::strcasecmp(name.c_str(), "PCMU")) { 656 codec = SdpRtpmapAttributeList::kPCMU; 657 defaults = {1}; 658 } else if (!nsCRT::strcasecmp(name.c_str(), "PCMA")) { 659 codec = SdpRtpmapAttributeList::kPCMA; 660 defaults = {1}; 661 } else if (!nsCRT::strcasecmp(name.c_str(), "VP8")) { 662 codec = SdpRtpmapAttributeList::kVP8; 663 defaults = {0}; 664 } else if (!nsCRT::strcasecmp(name.c_str(), "VP9")) { 665 codec = SdpRtpmapAttributeList::kVP9; 666 defaults = {0}; 667 } else if (!nsCRT::strcasecmp(name.c_str(), "iLBC")) { 668 codec = SdpRtpmapAttributeList::kiLBC; 669 defaults = {1}; 670 } else if (!nsCRT::strcasecmp(name.c_str(), "iSAC")) { 671 codec = SdpRtpmapAttributeList::kiSAC; 672 defaults = {1}; 673 } else if (!nsCRT::strcasecmp(name.c_str(), "H264")) { 674 codec = SdpRtpmapAttributeList::kH264; 675 defaults = {0}; 676 } else if (!nsCRT::strcasecmp(name.c_str(), "red")) { 677 codec = SdpRtpmapAttributeList::kRed; 678 defaults = {0}; 679 } else if (!nsCRT::strcasecmp(name.c_str(), "ulpfec")) { 680 codec = SdpRtpmapAttributeList::kUlpfec; 681 defaults = {0}; 682 } else if (!nsCRT::strcasecmp(name.c_str(), "telephone-event")) { 683 codec = SdpRtpmapAttributeList::kTelephoneEvent; 684 defaults = {1}; 685 } else if (!nsCRT::strcasecmp(name.c_str(), "rtx")) { 686 codec = SdpRtpmapAttributeList::kRtx; 687 defaults = {0}; 688 } 689 return std::make_tuple(codec, defaults); 690 } 691 692 void RsdparsaSdpAttributeList::LoadRtpmap(RustAttributeList* attributeList) { 693 size_t numRtpmap = sdp_get_rtpmap_count(attributeList); 694 if (numRtpmap == 0) { 695 return; 696 } 697 auto rustRtpmaps = MakeUnique<RustSdpAttributeRtpmap[]>(numRtpmap); 698 sdp_get_rtpmaps(attributeList, numRtpmap, rustRtpmaps.get()); 699 auto rtpmapList = MakeUnique<SdpRtpmapAttributeList>(); 700 for (size_t i = 0; i < numRtpmap; i++) { 701 RustSdpAttributeRtpmap& rtpmap = rustRtpmaps[i]; 702 std::string payloadType = std::to_string(rtpmap.payloadType); 703 std::string name = convertStringView(rtpmap.codecName); 704 auto [codec, defaults] = strToCodecType(name); 705 uint32_t channels = rtpmap.channels; 706 if (channels == 0) { 707 channels = defaults.minimumChannels; 708 } 709 rtpmapList->PushEntry(payloadType, codec, name, rtpmap.frequency, channels); 710 } 711 SetAttribute(rtpmapList.release()); 712 } 713 714 void RsdparsaSdpAttributeList::LoadFmtp(RustAttributeList* attributeList) { 715 size_t numFmtp = sdp_get_fmtp_count(attributeList); 716 if (numFmtp == 0) { 717 return; 718 } 719 auto rustFmtps = MakeUnique<RustSdpAttributeFmtp[]>(numFmtp); 720 size_t numValidFmtp = sdp_get_fmtp(attributeList, numFmtp, rustFmtps.get()); 721 auto fmtpList = MakeUnique<SdpFmtpAttributeList>(); 722 for (size_t i = 0; i < numValidFmtp; i++) { 723 const RustSdpAttributeFmtp& fmtp = rustFmtps[i]; 724 uint8_t payloadType = fmtp.payloadType; 725 std::string codecName = convertStringView(fmtp.codecName); 726 const RustSdpAttributeFmtpParameters& rustFmtpParameters = fmtp.parameters; 727 728 UniquePtr<SdpFmtpAttributeList::Parameters> fmtpParameters; 729 730 // use the upper case version of the codec name 731 std::transform(codecName.begin(), codecName.end(), codecName.begin(), 732 ::toupper); 733 734 if (codecName == "H264") { 735 SdpFmtpAttributeList::H264Parameters h264Parameters; 736 737 h264Parameters.packetization_mode = rustFmtpParameters.packetization_mode; 738 h264Parameters.level_asymmetry_allowed = 739 rustFmtpParameters.level_asymmetry_allowed; 740 h264Parameters.profile_level_id = rustFmtpParameters.profile_level_id; 741 h264Parameters.max_mbps = rustFmtpParameters.max_mbps; 742 h264Parameters.max_fs = rustFmtpParameters.max_fs; 743 h264Parameters.max_cpb = rustFmtpParameters.max_cpb; 744 h264Parameters.max_dpb = rustFmtpParameters.max_dpb; 745 h264Parameters.max_br = rustFmtpParameters.max_br; 746 747 // TODO(bug 1466859): Support sprop-parameter-sets 748 749 fmtpParameters.reset( 750 new SdpFmtpAttributeList::H264Parameters(std::move(h264Parameters))); 751 } else if (codecName == "OPUS") { 752 SdpFmtpAttributeList::OpusParameters opusParameters; 753 754 opusParameters.maxplaybackrate = rustFmtpParameters.maxplaybackrate; 755 opusParameters.maxAverageBitrate = rustFmtpParameters.maxaveragebitrate; 756 opusParameters.useDTX = rustFmtpParameters.usedtx; 757 opusParameters.stereo = rustFmtpParameters.stereo; 758 opusParameters.useInBandFec = rustFmtpParameters.useinbandfec; 759 opusParameters.frameSizeMs = rustFmtpParameters.ptime; 760 opusParameters.minFrameSizeMs = rustFmtpParameters.minptime; 761 opusParameters.maxFrameSizeMs = rustFmtpParameters.maxptime; 762 opusParameters.useCbr = rustFmtpParameters.cbr; 763 764 fmtpParameters.reset( 765 new SdpFmtpAttributeList::OpusParameters(std::move(opusParameters))); 766 } else if ((codecName == "VP8") || (codecName == "VP9")) { 767 SdpFmtpAttributeList::VP8Parameters vp8Parameters( 768 codecName == "VP8" ? SdpRtpmapAttributeList::kVP8 769 : SdpRtpmapAttributeList::kVP9); 770 771 vp8Parameters.max_fs = rustFmtpParameters.max_fs; 772 vp8Parameters.max_fr = rustFmtpParameters.max_fr; 773 774 fmtpParameters.reset( 775 new SdpFmtpAttributeList::VP8Parameters(std::move(vp8Parameters))); 776 } else if (codecName == "TELEPHONE-EVENT") { 777 SdpFmtpAttributeList::TelephoneEventParameters telephoneEventParameters; 778 779 telephoneEventParameters.dtmfTones = 780 convertStringView(rustFmtpParameters.dtmf_tones); 781 782 fmtpParameters.reset(new SdpFmtpAttributeList::TelephoneEventParameters( 783 std::move(telephoneEventParameters))); 784 } else if (codecName == "RED") { 785 SdpFmtpAttributeList::RedParameters redParameters; 786 787 redParameters.encodings = convertU8Vec(rustFmtpParameters.encodings); 788 789 fmtpParameters.reset( 790 new SdpFmtpAttributeList::RedParameters(std::move(redParameters))); 791 } else if (codecName == "RTX") { 792 SdpFmtpAttributeList::RtxParameters rtxParameters; 793 794 rtxParameters.apt = rustFmtpParameters.rtx.apt; 795 if (rustFmtpParameters.rtx.has_rtx_time) { 796 rtxParameters.rtx_time = Some(rustFmtpParameters.rtx.rtx_time); 797 } 798 799 fmtpParameters.reset( 800 new SdpFmtpAttributeList::RtxParameters(rtxParameters)); 801 } else if (codecName == "AV1") { 802 SdpFmtpAttributeList::Av1Parameters av1Parameters; 803 804 av1Parameters.profile = rustFmtpParameters.av1.has_profile 805 ? Some(rustFmtpParameters.av1.profile) 806 : Nothing(); 807 av1Parameters.levelIdx = rustFmtpParameters.av1.has_level_idx 808 ? Some(rustFmtpParameters.av1.level_idx) 809 : Nothing(); 810 av1Parameters.tier = rustFmtpParameters.av1.has_tier 811 ? Some(rustFmtpParameters.av1.tier) 812 : Nothing(); 813 fmtpParameters.reset( 814 new SdpFmtpAttributeList::Av1Parameters(av1Parameters)); 815 816 } else { 817 // The parameter set is unknown so skip it 818 continue; 819 } 820 fmtpList->PushEntry(std::to_string(payloadType), *fmtpParameters); 821 } 822 SetAttribute(fmtpList.release()); 823 } 824 825 void RsdparsaSdpAttributeList::LoadPtime(RustAttributeList* attributeList) { 826 int64_t ptime = sdp_get_ptime(attributeList); 827 if (ptime >= 0) { 828 SetAttribute(new SdpNumberAttribute(SdpAttribute::kPtimeAttribute, 829 static_cast<uint32_t>(ptime))); 830 } 831 } 832 833 void RsdparsaSdpAttributeList::LoadFlags(RustAttributeList* attributeList) { 834 RustSdpAttributeFlags flags = sdp_get_attribute_flags(attributeList); 835 if (flags.iceLite) { 836 SetAttribute(new SdpFlagAttribute(SdpAttribute::kIceLiteAttribute)); 837 } 838 if (flags.rtcpMux) { 839 SetAttribute(new SdpFlagAttribute(SdpAttribute::kRtcpMuxAttribute)); 840 } 841 if (flags.rtcpRsize) { 842 SetAttribute(new SdpFlagAttribute(SdpAttribute::kRtcpRsizeAttribute)); 843 } 844 if (flags.bundleOnly) { 845 SetAttribute(new SdpFlagAttribute(SdpAttribute::kBundleOnlyAttribute)); 846 } 847 if (flags.endOfCandidates) { 848 SetAttribute(new SdpFlagAttribute(SdpAttribute::kEndOfCandidatesAttribute)); 849 } 850 if (flags.extmapAllowMixed) { 851 SetAttribute( 852 new SdpFlagAttribute(SdpAttribute::kExtmapAllowMixedAttribute)); 853 } 854 } 855 856 void RsdparsaSdpAttributeList::LoadMaxMessageSize( 857 RustAttributeList* attributeList) { 858 int64_t max_msg_size = sdp_get_max_msg_size(attributeList); 859 if (max_msg_size >= 0) { 860 SetAttribute(new SdpNumberAttribute(SdpAttribute::kMaxMessageSizeAttribute, 861 static_cast<uint32_t>(max_msg_size))); 862 } 863 } 864 865 void RsdparsaSdpAttributeList::LoadMid(RustAttributeList* attributeList) { 866 StringView rustMid; 867 if (NS_SUCCEEDED(sdp_get_mid(attributeList, &rustMid))) { 868 std::string mid = convertStringView(rustMid); 869 SetAttribute(new SdpStringAttribute(SdpAttribute::kMidAttribute, mid)); 870 } 871 } 872 873 void RsdparsaSdpAttributeList::LoadMsid(RustAttributeList* attributeList) { 874 size_t numMsid = sdp_get_msid_count(attributeList); 875 if (numMsid == 0) { 876 return; 877 } 878 auto rustMsid = MakeUnique<RustSdpAttributeMsid[]>(numMsid); 879 sdp_get_msids(attributeList, numMsid, rustMsid.get()); 880 auto msids = MakeUnique<SdpMsidAttributeList>(); 881 for (size_t i = 0; i < numMsid; i++) { 882 RustSdpAttributeMsid& msid = rustMsid[i]; 883 std::string id = convertStringView(msid.id); 884 std::string appdata = convertStringView(msid.appdata); 885 msids->PushEntry(id, appdata); 886 } 887 SetAttribute(msids.release()); 888 } 889 890 void RsdparsaSdpAttributeList::LoadMsidSemantics( 891 RustAttributeList* attributeList) { 892 size_t numMsidSemantic = sdp_get_msid_semantic_count(attributeList); 893 if (numMsidSemantic == 0) { 894 return; 895 } 896 auto rustMsidSemantics = 897 MakeUnique<RustSdpAttributeMsidSemantic[]>(numMsidSemantic); 898 sdp_get_msid_semantics(attributeList, numMsidSemantic, 899 rustMsidSemantics.get()); 900 auto msidSemantics = MakeUnique<SdpMsidSemanticAttributeList>(); 901 for (size_t i = 0; i < numMsidSemantic; i++) { 902 RustSdpAttributeMsidSemantic& rustMsidSemantic = rustMsidSemantics[i]; 903 std::string semantic = convertStringView(rustMsidSemantic.semantic); 904 std::vector<std::string> msids = convertStringVec(rustMsidSemantic.msids); 905 msidSemantics->PushEntry(semantic, msids); 906 } 907 SetAttribute(msidSemantics.release()); 908 } 909 910 void RsdparsaSdpAttributeList::LoadGroup(RustAttributeList* attributeList) { 911 size_t numGroup = sdp_get_group_count(attributeList); 912 if (numGroup == 0) { 913 return; 914 } 915 auto rustGroups = MakeUnique<RustSdpAttributeGroup[]>(numGroup); 916 sdp_get_groups(attributeList, numGroup, rustGroups.get()); 917 auto groups = MakeUnique<SdpGroupAttributeList>(); 918 for (size_t i = 0; i < numGroup; i++) { 919 RustSdpAttributeGroup& group = rustGroups[i]; 920 SdpGroupAttributeList::Semantics semantic; 921 switch (group.semantic) { 922 case RustSdpAttributeGroupSemantic ::kRustLipSynchronization: 923 semantic = SdpGroupAttributeList::kLs; 924 break; 925 case RustSdpAttributeGroupSemantic ::kRustFlowIdentification: 926 semantic = SdpGroupAttributeList::kFid; 927 break; 928 case RustSdpAttributeGroupSemantic ::kRustSingleReservationFlow: 929 semantic = SdpGroupAttributeList::kSrf; 930 break; 931 case RustSdpAttributeGroupSemantic ::kRustAlternateNetworkAddressType: 932 semantic = SdpGroupAttributeList::kAnat; 933 break; 934 case RustSdpAttributeGroupSemantic ::kRustForwardErrorCorrection: 935 semantic = SdpGroupAttributeList::kFec; 936 break; 937 case RustSdpAttributeGroupSemantic ::kRustDecodingDependency: 938 semantic = SdpGroupAttributeList::kDdp; 939 break; 940 case RustSdpAttributeGroupSemantic ::kRustBundle: 941 semantic = SdpGroupAttributeList::kBundle; 942 break; 943 } 944 std::vector<std::string> tags = convertStringVec(group.tags); 945 groups->PushEntry(semantic, tags); 946 } 947 SetAttribute(groups.release()); 948 } 949 950 void RsdparsaSdpAttributeList::LoadRtcp(RustAttributeList* attributeList) { 951 RustSdpAttributeRtcp rtcp; 952 if (NS_SUCCEEDED(sdp_get_rtcp(attributeList, &rtcp))) { 953 if (rtcp.has_address) { 954 auto address = convertExplicitlyTypedAddress(&rtcp.unicastAddr); 955 SetAttribute(new SdpRtcpAttribute(rtcp.port, sdp::kInternet, 956 address.first, address.second)); 957 } else { 958 SetAttribute(new SdpRtcpAttribute(rtcp.port)); 959 } 960 } 961 } 962 963 void RsdparsaSdpAttributeList::LoadRtcpFb(RustAttributeList* attributeList) { 964 auto rtcpfbsCount = sdp_get_rtcpfb_count(attributeList); 965 if (!rtcpfbsCount) { 966 return; 967 } 968 969 auto rustRtcpfbs = MakeUnique<RustSdpAttributeRtcpFb[]>(rtcpfbsCount); 970 sdp_get_rtcpfbs(attributeList, rtcpfbsCount, rustRtcpfbs.get()); 971 972 auto rtcpfbList = MakeUnique<SdpRtcpFbAttributeList>(); 973 for (size_t i = 0; i < rtcpfbsCount; i++) { 974 RustSdpAttributeRtcpFb& rtcpfb = rustRtcpfbs[i]; 975 uint32_t payloadTypeU32 = rtcpfb.payloadType; 976 977 std::stringstream ss; 978 if (payloadTypeU32 == std::numeric_limits<uint32_t>::max()) { 979 ss << "*"; 980 } else { 981 ss << payloadTypeU32; 982 } 983 984 uint32_t feedbackType = rtcpfb.feedbackType; 985 std::string parameter = convertStringView(rtcpfb.parameter); 986 std::string extra = convertStringView(rtcpfb.extra); 987 988 rtcpfbList->PushEntry( 989 ss.str(), static_cast<SdpRtcpFbAttributeList::Type>(feedbackType), 990 parameter, extra); 991 } 992 993 SetAttribute(rtcpfbList.release()); 994 } 995 996 SdpSimulcastAttribute::Versions LoadSimulcastVersions( 997 const RustSdpAttributeSimulcastVersionVec* rustVersionList) { 998 size_t rustVersionCount = sdp_simulcast_get_version_count(rustVersionList); 999 auto rustVersionArray = 1000 MakeUnique<RustSdpAttributeSimulcastVersion[]>(rustVersionCount); 1001 sdp_simulcast_get_versions(rustVersionList, rustVersionCount, 1002 rustVersionArray.get()); 1003 1004 SdpSimulcastAttribute::Versions versions; 1005 1006 for (size_t i = 0; i < rustVersionCount; i++) { 1007 const RustSdpAttributeSimulcastVersion& rustVersion = rustVersionArray[i]; 1008 size_t rustIdCount = sdp_simulcast_get_ids_count(rustVersion.ids); 1009 if (!rustIdCount) { 1010 continue; 1011 } 1012 1013 SdpSimulcastAttribute::Version version; 1014 auto rustIdArray = MakeUnique<RustSdpAttributeSimulcastId[]>(rustIdCount); 1015 sdp_simulcast_get_ids(rustVersion.ids, rustIdCount, rustIdArray.get()); 1016 1017 for (size_t j = 0; j < rustIdCount; j++) { 1018 const RustSdpAttributeSimulcastId& rustId = rustIdArray[j]; 1019 std::string id = convertStringView(rustId.id); 1020 // TODO: Bug 1225877. Added support for 'paused'-state 1021 version.choices.push_back( 1022 SdpSimulcastAttribute::Encoding(id, rustId.paused)); 1023 } 1024 1025 versions.push_back(version); 1026 } 1027 1028 return versions; 1029 } 1030 1031 void RsdparsaSdpAttributeList::LoadSimulcast(RustAttributeList* attributeList) { 1032 RustSdpAttributeSimulcast rustSimulcast; 1033 if (NS_SUCCEEDED(sdp_get_simulcast(attributeList, &rustSimulcast))) { 1034 auto simulcast = MakeUnique<SdpSimulcastAttribute>(); 1035 1036 simulcast->sendVersions = LoadSimulcastVersions(rustSimulcast.send); 1037 simulcast->recvVersions = LoadSimulcastVersions(rustSimulcast.recv); 1038 1039 SetAttribute(simulcast.release()); 1040 } 1041 } 1042 1043 SdpImageattrAttributeList::XYRange LoadImageattrXYRange( 1044 const RustSdpAttributeImageAttrXYRange& rustXYRange) { 1045 SdpImageattrAttributeList::XYRange xyRange; 1046 1047 if (!rustXYRange.discrete_values) { 1048 xyRange.min = rustXYRange.min; 1049 xyRange.max = rustXYRange.max; 1050 xyRange.step = rustXYRange.step; 1051 1052 } else { 1053 xyRange.discreteValues = convertU32Vec(rustXYRange.discrete_values); 1054 } 1055 1056 return xyRange; 1057 } 1058 1059 std::vector<SdpImageattrAttributeList::Set> LoadImageattrSets( 1060 const RustSdpAttributeImageAttrSetVec* rustSets) { 1061 std::vector<SdpImageattrAttributeList::Set> sets; 1062 1063 size_t rustSetCount = sdp_imageattr_get_set_count(rustSets); 1064 if (!rustSetCount) { 1065 return sets; 1066 } 1067 1068 auto rustSetArray = MakeUnique<RustSdpAttributeImageAttrSet[]>(rustSetCount); 1069 sdp_imageattr_get_sets(rustSets, rustSetCount, rustSetArray.get()); 1070 1071 for (size_t i = 0; i < rustSetCount; i++) { 1072 const RustSdpAttributeImageAttrSet& rustSet = rustSetArray[i]; 1073 SdpImageattrAttributeList::Set set; 1074 1075 set.xRange = LoadImageattrXYRange(rustSet.x); 1076 set.yRange = LoadImageattrXYRange(rustSet.y); 1077 1078 if (rustSet.has_sar) { 1079 if (!rustSet.sar.discrete_values) { 1080 set.sRange.min = rustSet.sar.min; 1081 set.sRange.max = rustSet.sar.max; 1082 } else { 1083 set.sRange.discreteValues = convertF32Vec(rustSet.sar.discrete_values); 1084 } 1085 } 1086 1087 if (rustSet.has_par) { 1088 set.pRange.min = rustSet.par.min; 1089 set.pRange.max = rustSet.par.max; 1090 } 1091 1092 set.qValue = rustSet.q; 1093 1094 sets.push_back(set); 1095 } 1096 1097 return sets; 1098 } 1099 1100 void RsdparsaSdpAttributeList::LoadImageattr(RustAttributeList* attributeList) { 1101 size_t numImageattrs = sdp_get_imageattr_count(attributeList); 1102 if (numImageattrs == 0) { 1103 return; 1104 } 1105 auto rustImageattrs = MakeUnique<RustSdpAttributeImageAttr[]>(numImageattrs); 1106 sdp_get_imageattrs(attributeList, numImageattrs, rustImageattrs.get()); 1107 auto imageattrList = MakeUnique<SdpImageattrAttributeList>(); 1108 for (size_t i = 0; i < numImageattrs; i++) { 1109 const RustSdpAttributeImageAttr& rustImageAttr = rustImageattrs[i]; 1110 1111 SdpImageattrAttributeList::Imageattr imageAttr; 1112 1113 if (rustImageAttr.payloadType != std::numeric_limits<uint32_t>::max()) { 1114 imageAttr.pt = Some(rustImageAttr.payloadType); 1115 } 1116 1117 if (rustImageAttr.send.sets) { 1118 imageAttr.sendSets = LoadImageattrSets(rustImageAttr.send.sets); 1119 } else { 1120 imageAttr.sendAll = true; 1121 } 1122 1123 if (rustImageAttr.recv.sets) { 1124 imageAttr.recvSets = LoadImageattrSets(rustImageAttr.recv.sets); 1125 } else { 1126 imageAttr.recvAll = true; 1127 } 1128 1129 imageattrList->mImageattrs.push_back(imageAttr); 1130 } 1131 SetAttribute(imageattrList.release()); 1132 } 1133 1134 void RsdparsaSdpAttributeList::LoadSctpmaps(RustAttributeList* attributeList) { 1135 size_t numSctpmaps = sdp_get_sctpmap_count(attributeList); 1136 if (numSctpmaps == 0) { 1137 return; 1138 } 1139 auto rustSctpmaps = MakeUnique<RustSdpAttributeSctpmap[]>(numSctpmaps); 1140 sdp_get_sctpmaps(attributeList, numSctpmaps, rustSctpmaps.get()); 1141 auto sctpmapList = MakeUnique<SdpSctpmapAttributeList>(); 1142 for (size_t i = 0; i < numSctpmaps; i++) { 1143 RustSdpAttributeSctpmap& sctpmap = rustSctpmaps[i]; 1144 sctpmapList->PushEntry(std::to_string(sctpmap.port), "webrtc-datachannel", 1145 sctpmap.channels); 1146 } 1147 SetAttribute(sctpmapList.release()); 1148 } 1149 1150 void RsdparsaSdpAttributeList::LoadDirection(RustAttributeList* attributeList) { 1151 SdpDirectionAttribute::Direction dir; 1152 RustDirection rustDir = sdp_get_direction(attributeList); 1153 switch (rustDir) { 1154 case RustDirection::kRustRecvonly: 1155 dir = SdpDirectionAttribute::kRecvonly; 1156 break; 1157 case RustDirection::kRustSendonly: 1158 dir = SdpDirectionAttribute::kSendonly; 1159 break; 1160 case RustDirection::kRustSendrecv: 1161 dir = SdpDirectionAttribute::kSendrecv; 1162 break; 1163 case RustDirection::kRustInactive: 1164 dir = SdpDirectionAttribute::kInactive; 1165 break; 1166 } 1167 SetAttribute(new SdpDirectionAttribute(dir)); 1168 } 1169 1170 void RsdparsaSdpAttributeList::LoadRemoteCandidates( 1171 RustAttributeList* attributeList) { 1172 size_t nC = sdp_get_remote_candidate_count(attributeList); 1173 if (nC == 0) { 1174 return; 1175 } 1176 auto rustCandidates = MakeUnique<RustSdpAttributeRemoteCandidate[]>(nC); 1177 sdp_get_remote_candidates(attributeList, nC, rustCandidates.get()); 1178 std::vector<SdpRemoteCandidatesAttribute::Candidate> candidates; 1179 for (size_t i = 0; i < nC; i++) { 1180 RustSdpAttributeRemoteCandidate& rustCandidate = rustCandidates[i]; 1181 SdpRemoteCandidatesAttribute::Candidate candidate; 1182 candidate.port = rustCandidate.port; 1183 candidate.id = std::to_string(rustCandidate.component); 1184 candidate.address = convertAddress(&rustCandidate.address); 1185 candidates.push_back(candidate); 1186 } 1187 SdpRemoteCandidatesAttribute* candidatesList; 1188 candidatesList = new SdpRemoteCandidatesAttribute(candidates); 1189 SetAttribute(candidatesList); 1190 } 1191 1192 void RsdparsaSdpAttributeList::LoadRids(RustAttributeList* attributeList) { 1193 size_t numRids = sdp_get_rid_count(attributeList); 1194 if (numRids == 0) { 1195 return; 1196 } 1197 1198 auto rustRids = MakeUnique<RustSdpAttributeRid[]>(numRids); 1199 sdp_get_rids(attributeList, numRids, rustRids.get()); 1200 1201 auto ridList = MakeUnique<SdpRidAttributeList>(); 1202 for (size_t i = 0; i < numRids; i++) { 1203 const RustSdpAttributeRid& rid = rustRids[i]; 1204 1205 std::string id = convertStringView(rid.id); 1206 auto direction = static_cast<sdp::Direction>(rid.direction); 1207 std::vector<uint16_t> formats = convertU16Vec(rid.formats); 1208 1209 VideoEncodingConstraints parameters; 1210 parameters.maxWidth = rid.params.max_width; 1211 parameters.maxHeight = rid.params.max_height; 1212 // Right now, we treat max-fps=0 and the absence of max-fps as no limit. 1213 // We will eventually want to treat max-fps=0 as 0 frames per second, and 1214 // the absence of max-fps as no limit (bug 1762632). 1215 if (rid.params.max_fps) { 1216 parameters.maxFps = Some(rid.params.max_fps); 1217 } 1218 parameters.maxFs = rid.params.max_fs; 1219 parameters.maxBr = rid.params.max_br; 1220 parameters.maxPps = rid.params.max_pps; 1221 1222 std::vector<std::string> depends = convertStringVec(rid.depends); 1223 1224 ridList->PushEntry(id, direction, formats, parameters, depends); 1225 } 1226 1227 SetAttribute(ridList.release()); 1228 } 1229 1230 void RsdparsaSdpAttributeList::LoadSctpPort(RustAttributeList* attributeList) { 1231 int64_t port = sdp_get_sctp_port(attributeList); 1232 if (port >= 0) { 1233 SetAttribute(new SdpNumberAttribute(SdpAttribute::kSctpPortAttribute, 1234 static_cast<uint32_t>(port))); 1235 } 1236 } 1237 1238 void RsdparsaSdpAttributeList::LoadExtmap(RustAttributeList* attributeList) { 1239 size_t numExtmap = sdp_get_extmap_count(attributeList); 1240 if (numExtmap == 0) { 1241 return; 1242 } 1243 auto rustExtmaps = MakeUnique<RustSdpAttributeExtmap[]>(numExtmap); 1244 sdp_get_extmaps(attributeList, numExtmap, rustExtmaps.get()); 1245 auto extmaps = MakeUnique<SdpExtmapAttributeList>(); 1246 for (size_t i = 0; i < numExtmap; i++) { 1247 RustSdpAttributeExtmap& rustExtmap = rustExtmaps[i]; 1248 std::string name = convertStringView(rustExtmap.url); 1249 SdpDirectionAttribute::Direction direction; 1250 bool directionSpecified = rustExtmap.direction_specified; 1251 switch (rustExtmap.direction) { 1252 case RustDirection::kRustRecvonly: 1253 direction = SdpDirectionAttribute::kRecvonly; 1254 break; 1255 case RustDirection::kRustSendonly: 1256 direction = SdpDirectionAttribute::kSendonly; 1257 break; 1258 case RustDirection::kRustSendrecv: 1259 direction = SdpDirectionAttribute::kSendrecv; 1260 break; 1261 case RustDirection::kRustInactive: 1262 direction = SdpDirectionAttribute::kInactive; 1263 break; 1264 } 1265 std::string extensionAttributes; 1266 extensionAttributes = convertStringView(rustExtmap.extensionAttributes); 1267 extmaps->PushEntry((uint16_t)rustExtmap.id, direction, directionSpecified, 1268 name, extensionAttributes); 1269 } 1270 SetAttribute(extmaps.release()); 1271 } 1272 1273 void RsdparsaSdpAttributeList::LoadMaxPtime(RustAttributeList* attributeList) { 1274 uint64_t maxPtime = 0; 1275 nsresult nr = sdp_get_maxptime(attributeList, &maxPtime); 1276 if (NS_SUCCEEDED(nr)) { 1277 SetAttribute( 1278 new SdpNumberAttribute(SdpAttribute::kMaxptimeAttribute, maxPtime)); 1279 } 1280 } 1281 1282 void RsdparsaSdpAttributeList::LoadCandidate(RustAttributeList* attributeList) { 1283 size_t candidatesCount = sdp_get_candidate_count(attributeList); 1284 if (!candidatesCount) { 1285 return; 1286 } 1287 1288 StringVec* rustCandidatesStrings; 1289 sdp_get_candidates(attributeList, candidatesCount, &rustCandidatesStrings); 1290 1291 std::vector<std::string> candidatesStrings = 1292 convertStringVec(rustCandidatesStrings); 1293 free_boxed_string_vec(rustCandidatesStrings); 1294 1295 auto candidates = 1296 MakeUnique<SdpMultiStringAttribute>(SdpAttribute::kCandidateAttribute); 1297 candidates->mValues = candidatesStrings; 1298 1299 SetAttribute(candidates.release()); 1300 } 1301 1302 bool RsdparsaSdpAttributeList::IsAllowedHere(SdpAttribute::AttributeType type) { 1303 if (AtSessionLevel() && !SdpAttribute::IsAllowedAtSessionLevel(type)) { 1304 return false; 1305 } 1306 1307 if (!AtSessionLevel() && !SdpAttribute::IsAllowedAtMediaLevel(type)) { 1308 return false; 1309 } 1310 1311 return true; 1312 } 1313 1314 void RsdparsaSdpAttributeList::Serialize(std::ostream& os) const { 1315 for (size_t i = 0; i < kNumAttributeTypes; ++i) { 1316 if (mAttributes[i]) { 1317 os << *mAttributes[i]; 1318 } 1319 } 1320 } 1321 1322 } // namespace mozilla