SdpAttribute.h (60862B)
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 #ifndef _SDPATTRIBUTE_H_ 8 #define _SDPATTRIBUTE_H_ 9 10 #include <algorithm> 11 #include <cctype> 12 #include <cstring> 13 #include <iomanip> 14 #include <ostream> 15 #include <sstream> 16 #include <string> 17 #include <vector> 18 19 #include "common/EncodingConstraints.h" 20 #include "mozilla/Assertions.h" 21 #include "mozilla/Maybe.h" 22 #include "mozilla/UniquePtr.h" 23 #include "nsString.h" 24 #include "sdp/SdpEnum.h" 25 26 namespace mozilla { 27 28 /** 29 * Base class for SDP attributes 30 */ 31 class SdpAttribute { 32 public: 33 enum AttributeType { 34 kFirstAttribute = 0, 35 kBundleOnlyAttribute = 0, 36 kCandidateAttribute, 37 kConnectionAttribute, 38 kDirectionAttribute, 39 kDtlsMessageAttribute, 40 kEndOfCandidatesAttribute, 41 kExtmapAttribute, 42 kExtmapAllowMixedAttribute, 43 kFingerprintAttribute, 44 kFmtpAttribute, 45 kGroupAttribute, 46 kIceLiteAttribute, 47 kIceMismatchAttribute, 48 kIceOptionsAttribute, 49 kIcePwdAttribute, 50 kIceUfragAttribute, 51 kIdentityAttribute, 52 kImageattrAttribute, 53 kLabelAttribute, 54 kMaxptimeAttribute, 55 kMidAttribute, 56 kMsidAttribute, 57 kMsidSemanticAttribute, 58 kPtimeAttribute, 59 kRemoteCandidatesAttribute, 60 kRidAttribute, 61 kRtcpAttribute, 62 kRtcpFbAttribute, 63 kRtcpMuxAttribute, 64 kRtcpRsizeAttribute, 65 kRtpmapAttribute, 66 kSctpmapAttribute, 67 kSetupAttribute, 68 kSimulcastAttribute, 69 kSsrcAttribute, 70 kSsrcGroupAttribute, 71 kSctpPortAttribute, 72 kMaxMessageSizeAttribute, 73 kLastAttribute = kMaxMessageSizeAttribute 74 }; 75 76 explicit SdpAttribute(AttributeType type) : mType(type) {} 77 virtual ~SdpAttribute() = default; 78 79 virtual SdpAttribute* Clone() const = 0; 80 81 AttributeType GetType() const { return mType; } 82 83 virtual void Serialize(std::ostream&) const = 0; 84 85 static bool IsAllowedAtSessionLevel(AttributeType type); 86 static bool IsAllowedAtMediaLevel(AttributeType type); 87 static const std::string GetAttributeTypeString(AttributeType type); 88 89 protected: 90 AttributeType mType; 91 }; 92 93 inline std::ostream& operator<<(std::ostream& os, const SdpAttribute& attr) { 94 attr.Serialize(os); 95 return os; 96 } 97 98 inline std::ostream& operator<<(std::ostream& os, 99 const SdpAttribute::AttributeType type) { 100 os << SdpAttribute::GetAttributeTypeString(type); 101 return os; 102 } 103 104 /////////////////////////////////////////////////////////////////////////// 105 // a=candidate, RFC5245 106 //------------------------------------------------------------------------- 107 // 108 // candidate-attribute = "candidate" ":" foundation SP component-id SP 109 // transport SP 110 // priority SP 111 // connection-address SP ;from RFC 4566 112 // port ;port from RFC 4566 113 // SP cand-type 114 // [SP rel-addr] 115 // [SP rel-port] 116 // *(SP extension-att-name SP 117 // extension-att-value) 118 // foundation = 1*32ice-char 119 // component-id = 1*5DIGIT 120 // transport = "UDP" / transport-extension 121 // transport-extension = token ; from RFC 3261 122 // priority = 1*10DIGIT 123 // cand-type = "typ" SP candidate-types 124 // candidate-types = "host" / "srflx" / "prflx" / "relay" / token 125 // rel-addr = "raddr" SP connection-address 126 // rel-port = "rport" SP port 127 // extension-att-name = byte-string ;from RFC 4566 128 // extension-att-value = byte-string 129 // ice-char = ALPHA / DIGIT / "+" / "/" 130 131 // We use a SdpMultiStringAttribute for candidates 132 133 /////////////////////////////////////////////////////////////////////////// 134 // a=connection, RFC4145 135 //------------------------------------------------------------------------- 136 // connection-attr = "a=connection:" conn-value 137 // conn-value = "new" / "existing" 138 class SdpConnectionAttribute : public SdpAttribute { 139 public: 140 enum ConnValue { kNew, kExisting }; 141 142 explicit SdpConnectionAttribute(SdpConnectionAttribute::ConnValue value) 143 : SdpAttribute(kConnectionAttribute), mValue(value) {} 144 145 SdpAttribute* Clone() const override { 146 return new SdpConnectionAttribute(*this); 147 } 148 149 virtual void Serialize(std::ostream& os) const override; 150 151 ConnValue mValue; 152 }; 153 154 inline std::ostream& operator<<(std::ostream& os, 155 SdpConnectionAttribute::ConnValue c) { 156 switch (c) { 157 case SdpConnectionAttribute::kNew: 158 os << "new"; 159 break; 160 case SdpConnectionAttribute::kExisting: 161 os << "existing"; 162 break; 163 default: 164 MOZ_ASSERT(false); 165 os << "?"; 166 } 167 return os; 168 } 169 170 /////////////////////////////////////////////////////////////////////////// 171 // a=sendrecv / a=sendonly / a=recvonly / a=inactive, RFC 4566 172 //------------------------------------------------------------------------- 173 class SdpDirectionAttribute : public SdpAttribute { 174 public: 175 enum Direction { 176 kInactive = 0, 177 kSendonly = sdp::kSend, 178 kRecvonly = sdp::kRecv, 179 kSendrecv = sdp::kSend | sdp::kRecv 180 }; 181 182 explicit SdpDirectionAttribute(Direction value) 183 : SdpAttribute(kDirectionAttribute), mValue(value) {} 184 185 SdpAttribute* Clone() const override { 186 return new SdpDirectionAttribute(*this); 187 } 188 189 virtual void Serialize(std::ostream& os) const override; 190 191 Direction mValue; 192 }; 193 194 inline std::ostream& operator<<(std::ostream& os, 195 SdpDirectionAttribute::Direction d) { 196 switch (d) { 197 case SdpDirectionAttribute::kSendonly: 198 os << "sendonly"; 199 break; 200 case SdpDirectionAttribute::kRecvonly: 201 os << "recvonly"; 202 break; 203 case SdpDirectionAttribute::kSendrecv: 204 os << "sendrecv"; 205 break; 206 case SdpDirectionAttribute::kInactive: 207 os << "inactive"; 208 break; 209 default: 210 MOZ_ASSERT(false); 211 os << "?"; 212 } 213 return os; 214 } 215 216 inline SdpDirectionAttribute::Direction reverse( 217 SdpDirectionAttribute::Direction d) { 218 switch (d) { 219 case SdpDirectionAttribute::Direction::kInactive: 220 return SdpDirectionAttribute::Direction::kInactive; 221 case SdpDirectionAttribute::Direction::kSendonly: 222 return SdpDirectionAttribute::Direction::kRecvonly; 223 case SdpDirectionAttribute::Direction::kRecvonly: 224 return SdpDirectionAttribute::Direction::kSendonly; 225 case SdpDirectionAttribute::Direction::kSendrecv: 226 return SdpDirectionAttribute::Direction::kSendrecv; 227 } 228 MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Invalid direction!"); 229 MOZ_RELEASE_ASSERT(false); 230 } 231 232 inline SdpDirectionAttribute::Direction operator|( 233 SdpDirectionAttribute::Direction d1, SdpDirectionAttribute::Direction d2) { 234 return (SdpDirectionAttribute::Direction)((unsigned)d1 | (unsigned)d2); 235 } 236 237 inline SdpDirectionAttribute::Direction operator&( 238 SdpDirectionAttribute::Direction d1, SdpDirectionAttribute::Direction d2) { 239 return (SdpDirectionAttribute::Direction)((unsigned)d1 & (unsigned)d2); 240 } 241 242 inline SdpDirectionAttribute::Direction operator|=( 243 SdpDirectionAttribute::Direction& d1, SdpDirectionAttribute::Direction d2) { 244 d1 = d1 | d2; 245 return d1; 246 } 247 248 inline SdpDirectionAttribute::Direction operator&=( 249 SdpDirectionAttribute::Direction& d1, SdpDirectionAttribute::Direction d2) { 250 d1 = d1 & d2; 251 return d1; 252 } 253 254 /////////////////////////////////////////////////////////////////////////// 255 // a=dtls-message, draft-rescorla-dtls-in-sdp 256 //------------------------------------------------------------------------- 257 // attribute =/ dtls-message-attribute 258 // 259 // dtls-message-attribute = "dtls-message" ":" role SP value 260 // 261 // role = "client" / "server" 262 // 263 // value = 1*(ALPHA / DIGIT / "+" / "/" / "=" ) 264 // ; base64 encoded message 265 class SdpDtlsMessageAttribute : public SdpAttribute { 266 public: 267 enum Role { kClient, kServer }; 268 269 explicit SdpDtlsMessageAttribute(Role role, const std::string& value) 270 : SdpAttribute(kDtlsMessageAttribute), mRole(role), mValue(value) {} 271 272 // TODO: remove this, Bug 1469702 273 explicit SdpDtlsMessageAttribute(const std::string& unparsed) 274 : SdpAttribute(kDtlsMessageAttribute), mRole(kClient) { 275 std::istringstream is(unparsed); 276 std::string error; 277 // We're not really worried about errors here if we don't parse; 278 // this attribute is a pure optimization. 279 Parse(is, &error); 280 } 281 282 SdpAttribute* Clone() const override { 283 return new SdpDtlsMessageAttribute(*this); 284 } 285 286 virtual void Serialize(std::ostream& os) const override; 287 288 // TODO: remove this, Bug 1469702 289 bool Parse(std::istream& is, std::string* error); 290 291 Role mRole; 292 std::string mValue; 293 }; 294 295 inline std::ostream& operator<<(std::ostream& os, 296 SdpDtlsMessageAttribute::Role r) { 297 switch (r) { 298 case SdpDtlsMessageAttribute::kClient: 299 os << "client"; 300 break; 301 case SdpDtlsMessageAttribute::kServer: 302 os << "server"; 303 break; 304 default: 305 MOZ_ASSERT(false); 306 os << "?"; 307 } 308 return os; 309 } 310 311 /////////////////////////////////////////////////////////////////////////// 312 // a=extmap, RFC5285 313 //------------------------------------------------------------------------- 314 // RFC5285 315 // extmap = mapentry SP extensionname [SP extensionattributes] 316 // 317 // extensionname = URI 318 // 319 // direction = "sendonly" / "recvonly" / "sendrecv" / "inactive" 320 // 321 // mapentry = "extmap:" 1*5DIGIT ["/" direction] 322 // 323 // extensionattributes = byte-string 324 // 325 // URI = <Defined in RFC 3986> 326 // 327 // byte-string = <Defined in RFC 4566> 328 // 329 // SP = <Defined in RFC 5234> 330 // 331 // DIGIT = <Defined in RFC 5234> 332 class SdpExtmapAttributeList : public SdpAttribute { 333 public: 334 SdpExtmapAttributeList() : SdpAttribute(kExtmapAttribute) {} 335 336 struct Extmap { 337 uint16_t entry; 338 SdpDirectionAttribute::Direction direction; 339 bool direction_specified; 340 std::string extensionname; 341 std::string extensionattributes; 342 }; 343 344 void PushEntry(uint16_t entry, SdpDirectionAttribute::Direction direction, 345 bool direction_specified, const std::string& extensionname, 346 const std::string& extensionattributes = "") { 347 Extmap value = {entry, direction, direction_specified, extensionname, 348 extensionattributes}; 349 mExtmaps.push_back(value); 350 } 351 352 SdpAttribute* Clone() const override { 353 return new SdpExtmapAttributeList(*this); 354 } 355 356 virtual void Serialize(std::ostream& os) const override; 357 358 std::vector<Extmap> mExtmaps; 359 }; 360 361 /////////////////////////////////////////////////////////////////////////// 362 // a=fingerprint, RFC4572 363 //------------------------------------------------------------------------- 364 // fingerprint-attribute = "fingerprint" ":" hash-func SP fingerprint 365 // 366 // hash-func = "sha-1" / "sha-224" / "sha-256" / 367 // "sha-384" / "sha-512" / 368 // "md5" / "md2" / token 369 // ; Additional hash functions can only come 370 // ; from updates to RFC 3279 371 // 372 // fingerprint = 2UHEX *(":" 2UHEX) 373 // ; Each byte in upper-case hex, separated 374 // ; by colons. 375 // 376 // UHEX = DIGIT / %x41-46 ; A-F uppercase 377 class SdpFingerprintAttributeList : public SdpAttribute { 378 public: 379 SdpFingerprintAttributeList() : SdpAttribute(kFingerprintAttribute) {} 380 381 enum HashAlgorithm { 382 kSha1, 383 kSha224, 384 kSha256, 385 kSha384, 386 kSha512, 387 kMd5, 388 kMd2, 389 kUnknownAlgorithm 390 }; 391 392 struct Fingerprint { 393 HashAlgorithm hashFunc; 394 std::vector<uint8_t> fingerprint; 395 }; 396 397 // For use by application programmers. Enforces that it's a known and 398 // reasonable algorithm. 399 void PushEntry(std::string algorithm_str, 400 const std::vector<uint8_t>& fingerprint, 401 bool enforcePlausible = true) { 402 std::transform(algorithm_str.begin(), algorithm_str.end(), 403 algorithm_str.begin(), ::tolower); 404 405 SdpFingerprintAttributeList::HashAlgorithm algorithm = 406 SdpFingerprintAttributeList::kUnknownAlgorithm; 407 408 if (algorithm_str == "sha-1") { 409 algorithm = SdpFingerprintAttributeList::kSha1; 410 } else if (algorithm_str == "sha-224") { 411 algorithm = SdpFingerprintAttributeList::kSha224; 412 } else if (algorithm_str == "sha-256") { 413 algorithm = SdpFingerprintAttributeList::kSha256; 414 } else if (algorithm_str == "sha-384") { 415 algorithm = SdpFingerprintAttributeList::kSha384; 416 } else if (algorithm_str == "sha-512") { 417 algorithm = SdpFingerprintAttributeList::kSha512; 418 } else if (algorithm_str == "md5") { 419 algorithm = SdpFingerprintAttributeList::kMd5; 420 } else if (algorithm_str == "md2") { 421 algorithm = SdpFingerprintAttributeList::kMd2; 422 } 423 424 if ((algorithm == SdpFingerprintAttributeList::kUnknownAlgorithm) || 425 fingerprint.empty()) { 426 if (enforcePlausible) { 427 MOZ_ASSERT(false, "Unknown fingerprint algorithm"); 428 } else { 429 return; 430 } 431 } 432 433 PushEntry(algorithm, fingerprint); 434 } 435 436 void PushEntry(HashAlgorithm hashFunc, 437 const std::vector<uint8_t>& fingerprint) { 438 Fingerprint value = {hashFunc, fingerprint}; 439 mFingerprints.push_back(value); 440 } 441 442 SdpAttribute* Clone() const override { 443 return new SdpFingerprintAttributeList(*this); 444 } 445 446 virtual void Serialize(std::ostream& os) const override; 447 448 std::vector<Fingerprint> mFingerprints; 449 450 static std::string FormatFingerprint(const std::vector<uint8_t>& fp); 451 static std::vector<uint8_t> ParseFingerprint(const std::string& str); 452 }; 453 454 inline nsLiteralCString ToString(SdpFingerprintAttributeList::HashAlgorithm a) { 455 static constexpr nsLiteralCString Values[] = { 456 "sha-1"_ns, "sha-224"_ns, "sha-256"_ns, "sha-384"_ns, 457 "sha-512"_ns, "md5"_ns, "md2"_ns, 458 }; 459 if (a < std::size(Values)) return Values[a]; 460 MOZ_ASSERT(false); 461 return "?"_ns; 462 } 463 464 inline std::ostream& operator<<(std::ostream& os, 465 SdpFingerprintAttributeList::HashAlgorithm a) { 466 return os << ToString(a); 467 } 468 469 /////////////////////////////////////////////////////////////////////////// 470 // a=group, RFC5888 471 //------------------------------------------------------------------------- 472 // group-attribute = "a=group:" semantics 473 // *(SP identification-tag) 474 // semantics = "LS" / "FID" / semantics-extension 475 // semantics-extension = token 476 // identification-tag = token 477 class SdpGroupAttributeList : public SdpAttribute { 478 public: 479 SdpGroupAttributeList() : SdpAttribute(kGroupAttribute) {} 480 481 enum Semantics { 482 kLs, // RFC5888 483 kFid, // RFC5888 484 kSrf, // RFC3524 485 kAnat, // RFC4091 486 kFec, // RFC5956 487 kFecFr, // RFC5956 488 kCs, // draft-mehta-rmt-flute-sdp-05 489 kDdp, // RFC5583 490 kDup, // RFC7104 491 kBundle // draft-ietf-mmusic-bundle 492 }; 493 494 struct Group { 495 Semantics semantics; 496 std::vector<std::string> tags; 497 }; 498 499 void PushEntry(Semantics semantics, const std::vector<std::string>& tags) { 500 Group value = {semantics, tags}; 501 mGroups.push_back(value); 502 } 503 504 void RemoveMid(const std::string& mid) { 505 for (auto i = mGroups.begin(); i != mGroups.end();) { 506 auto tag = std::find(i->tags.begin(), i->tags.end(), mid); 507 if (tag != i->tags.end()) { 508 i->tags.erase(tag); 509 } 510 511 if (i->tags.empty()) { 512 i = mGroups.erase(i); 513 } else { 514 ++i; 515 } 516 } 517 } 518 519 SdpAttribute* Clone() const override { 520 return new SdpGroupAttributeList(*this); 521 } 522 523 virtual void Serialize(std::ostream& os) const override; 524 525 std::vector<Group> mGroups; 526 }; 527 528 inline std::ostream& operator<<(std::ostream& os, 529 SdpGroupAttributeList::Semantics s) { 530 switch (s) { 531 case SdpGroupAttributeList::kLs: 532 os << "LS"; 533 break; 534 case SdpGroupAttributeList::kFid: 535 os << "FID"; 536 break; 537 case SdpGroupAttributeList::kSrf: 538 os << "SRF"; 539 break; 540 case SdpGroupAttributeList::kAnat: 541 os << "ANAT"; 542 break; 543 case SdpGroupAttributeList::kFec: 544 os << "FEC"; 545 break; 546 case SdpGroupAttributeList::kFecFr: 547 os << "FEC-FR"; 548 break; 549 case SdpGroupAttributeList::kCs: 550 os << "CS"; 551 break; 552 case SdpGroupAttributeList::kDdp: 553 os << "DDP"; 554 break; 555 case SdpGroupAttributeList::kDup: 556 os << "DUP"; 557 break; 558 case SdpGroupAttributeList::kBundle: 559 os << "BUNDLE"; 560 break; 561 default: 562 MOZ_ASSERT(false); 563 os << "?"; 564 } 565 return os; 566 } 567 568 /////////////////////////////////////////////////////////////////////////// 569 // a=identity, draft-ietf-rtcweb-security-arch 570 //------------------------------------------------------------------------- 571 // identity-attribute = "identity:" identity-assertion 572 // [ SP identity-extension 573 // *(";" [ SP ] identity-extension) ] 574 // identity-assertion = base64 575 // base64 = 1*(ALPHA / DIGIT / "+" / "/" / "=" ) 576 // identity-extension = extension-att-name [ "=" extension-att-value ] 577 // extension-att-name = token 578 // extension-att-value = 1*(%x01-09 / %x0b-0c / %x0e-3a / %x3c-ff) 579 // ; byte-string from [RFC4566] omitting ";" 580 581 // We're just using an SdpStringAttribute for this right now 582 #if 0 583 class SdpIdentityAttribute : public SdpAttribute 584 { 585 public: 586 explicit SdpIdentityAttribute(const std::string &assertion, 587 const std::vector<std::string> &extensions = 588 std::vector<std::string>()) : 589 SdpAttribute(kIdentityAttribute), 590 mAssertion(assertion), 591 mExtensions(extensions) {} 592 593 virtual void Serialize(std::ostream& os) const override; 594 595 std::string mAssertion; 596 std::vector<std::string> mExtensions; 597 } 598 #endif 599 600 /////////////////////////////////////////////////////////////////////////// 601 // a=imageattr, RFC6236 602 //------------------------------------------------------------------------- 603 // image-attr = "imageattr:" PT 1*2( 1*WSP ( "send" / "recv" ) 604 // 1*WSP attr-list ) 605 // PT = 1*DIGIT / "*" 606 // attr-list = ( set *(1*WSP set) ) / "*" 607 // ; WSP and DIGIT defined in [RFC5234] 608 // 609 // set= "[" "x=" xyrange "," "y=" xyrange *( "," key-value ) "]" 610 // ; x is the horizontal image size range (pixel count) 611 // ; y is the vertical image size range (pixel count) 612 // 613 // key-value = ( "sar=" srange ) 614 // / ( "par=" prange ) 615 // / ( "q=" qvalue ) 616 // ; Key-value MAY be extended with other keyword 617 // ; parameters. 618 // ; At most, one instance each of sar, par, or q 619 // ; is allowed in a set. 620 // ; 621 // ; sar (sample aspect ratio) is the sample aspect ratio 622 // ; associated with the set (optional, MAY be ignored) 623 // ; par (picture aspect ratio) is the allowed 624 // ; ratio between the display's x and y physical 625 // ; size (optional) 626 // ; q (optional, range [0.0..1.0], default value 0.5) 627 // ; is the preference for the given set, 628 // ; a higher value means a higher preference 629 // 630 // onetonine = "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" 631 // ; Digit between 1 and 9 632 // xyvalue = onetonine *5DIGIT 633 // ; Digit between 1 and 9 that is 634 // ; followed by 0 to 5 other digits 635 // step = xyvalue 636 // xyrange = ( "[" xyvalue ":" [ step ":" ] xyvalue "]" ) 637 // ; Range between a lower and an upper value 638 // ; with an optional step, default step = 1 639 // ; The rightmost occurrence of xyvalue MUST have a 640 // ; higher value than the leftmost occurrence. 641 // / ( "[" xyvalue 1*( "," xyvalue ) "]" ) 642 // ; Discrete values separated by ',' 643 // / ( xyvalue ) 644 // ; A single value 645 // spvalue = ( "0" "." onetonine *3DIGIT ) 646 // ; Values between 0.1000 and 0.9999 647 // / ( onetonine "." 1*4DIGIT ) 648 // ; Values between 1.0000 and 9.9999 649 // srange = ( "[" spvalue 1*( "," spvalue ) "]" ) 650 // ; Discrete values separated by ','. 651 // ; Each occurrence of spvalue MUST be 652 // ; greater than the previous occurrence. 653 // / ( "[" spvalue "-" spvalue "]" ) 654 // ; Range between a lower and an upper level (inclusive) 655 // ; The second occurrence of spvalue MUST have a higher 656 // ; value than the first 657 // / ( spvalue ) 658 // ; A single value 659 // 660 // prange = ( "[" spvalue "-" spvalue "]" ) 661 // ; Range between a lower and an upper level (inclusive) 662 // ; The second occurrence of spvalue MUST have a higher 663 // ; value than the first 664 // 665 // qvalue = ( "0" "." 1*2DIGIT ) 666 // / ( "1" "." 1*2("0") ) 667 // ; Values between 0.00 and 1.00 668 // 669 // XXX TBD -- We don't use this yet, and it's a project unto itself. 670 // 671 672 class SdpImageattrAttributeList : public SdpAttribute { 673 public: 674 SdpImageattrAttributeList() : SdpAttribute(kImageattrAttribute) {} 675 676 class XYRange { 677 public: 678 XYRange() : min(0), max(0), step(1) {} 679 void Serialize(std::ostream& os) const; 680 // TODO: Remove this Bug 1469702 681 bool Parse(std::istream& is, std::string* error); 682 // TODO: Remove this Bug 1469702 683 bool ParseAfterBracket(std::istream& is, std::string* error); 684 // TODO: Remove this Bug 1469702 685 bool ParseAfterMin(std::istream& is, std::string* error); 686 // TODO: Remove this Bug 1469702 687 bool ParseDiscreteValues(std::istream& is, std::string* error); 688 std::vector<uint32_t> discreteValues; 689 // min/max are used iff discreteValues is empty 690 uint32_t min; 691 uint32_t max; 692 uint32_t step; 693 }; 694 695 class SRange { 696 public: 697 SRange() : min(0), max(0) {} 698 void Serialize(std::ostream& os) const; 699 // TODO: Remove this Bug 1469702 700 bool Parse(std::istream& is, std::string* error); 701 // TODO: Remove this Bug 1469702 702 bool ParseAfterBracket(std::istream& is, std::string* error); 703 // TODO: Remove this Bug 1469702 704 bool ParseAfterMin(std::istream& is, std::string* error); 705 // TODO: Remove this Bug 1469702 706 bool ParseDiscreteValues(std::istream& is, std::string* error); 707 bool IsSet() const { return !discreteValues.empty() || (min && max); } 708 std::vector<float> discreteValues; 709 // min/max are used iff discreteValues is empty 710 float min; 711 float max; 712 }; 713 714 class PRange { 715 public: 716 PRange() : min(0), max(0) {} 717 void Serialize(std::ostream& os) const; 718 // TODO: Remove this Bug 1469702 719 bool Parse(std::istream& is, std::string* error); 720 bool IsSet() const { return min && max; } 721 float min; 722 float max; 723 }; 724 725 class Set { 726 public: 727 Set() : qValue(-1) {} 728 void Serialize(std::ostream& os) const; 729 // TODO: Remove this Bug 1469702 730 bool Parse(std::istream& is, std::string* error); 731 XYRange xRange; 732 XYRange yRange; 733 SRange sRange; 734 PRange pRange; 735 float qValue; 736 }; 737 738 class Imageattr { 739 public: 740 Imageattr() : sendAll(false), recvAll(false) {} 741 void Serialize(std::ostream& os) const; 742 // TODO: Remove this Bug 1469702 743 bool Parse(std::istream& is, std::string* error); 744 // TODO: Remove this Bug 1469702 745 bool ParseSets(std::istream& is, std::string* error); 746 // If not set, this means all payload types 747 Maybe<uint16_t> pt; 748 bool sendAll; 749 std::vector<Set> sendSets; 750 bool recvAll; 751 std::vector<Set> recvSets; 752 }; 753 754 SdpAttribute* Clone() const override { 755 return new SdpImageattrAttributeList(*this); 756 } 757 758 virtual void Serialize(std::ostream& os) const override; 759 760 // TODO: Remove this Bug 1469702 761 bool PushEntry(const std::string& raw, std::string* error, size_t* errorPos); 762 763 std::vector<Imageattr> mImageattrs; 764 }; 765 766 /////////////////////////////////////////////////////////////////////////// 767 // a=msid, draft-ietf-mmusic-msid 768 //------------------------------------------------------------------------- 769 // msid-attr = "msid:" identifier [ SP appdata ] 770 // identifier = 1*64token-char ; see RFC 4566 771 // appdata = 1*64token-char ; see RFC 4566 772 class SdpMsidAttributeList : public SdpAttribute { 773 public: 774 SdpMsidAttributeList() : SdpAttribute(kMsidAttribute) {} 775 776 struct Msid { 777 std::string identifier; 778 std::string appdata; 779 }; 780 781 void PushEntry(const std::string& identifier, 782 const std::string& appdata = "") { 783 Msid value = {identifier, appdata}; 784 mMsids.push_back(value); 785 } 786 787 SdpAttribute* Clone() const override { 788 return new SdpMsidAttributeList(*this); 789 } 790 791 virtual void Serialize(std::ostream& os) const override; 792 793 std::vector<Msid> mMsids; 794 }; 795 796 /////////////////////////////////////////////////////////////////////////// 797 // a=msid-semantic, draft-ietf-mmusic-msid 798 //------------------------------------------------------------------------- 799 // msid-semantic-attr = "msid-semantic:" msid-semantic msid-list 800 // msid-semantic = token ; see RFC 4566 801 // msid-list = *(" " msid-id) / " *" 802 class SdpMsidSemanticAttributeList : public SdpAttribute { 803 public: 804 SdpMsidSemanticAttributeList() : SdpAttribute(kMsidSemanticAttribute) {} 805 806 struct MsidSemantic { 807 // TODO: Once we have some more of these, we might want to make an enum 808 std::string semantic; 809 std::vector<std::string> msids; 810 }; 811 812 void PushEntry(const std::string& semantic, 813 const std::vector<std::string>& msids) { 814 MsidSemantic value = {semantic, msids}; 815 mMsidSemantics.push_back(value); 816 } 817 818 SdpAttribute* Clone() const override { 819 return new SdpMsidSemanticAttributeList(*this); 820 } 821 822 virtual void Serialize(std::ostream& os) const override; 823 824 std::vector<MsidSemantic> mMsidSemantics; 825 }; 826 827 /////////////////////////////////////////////////////////////////////////// 828 // a=remote-candiate, RFC5245 829 //------------------------------------------------------------------------- 830 // remote-candidate-att = "remote-candidates" ":" remote-candidate 831 // 0*(SP remote-candidate) 832 // remote-candidate = component-ID SP connection-address SP port 833 class SdpRemoteCandidatesAttribute : public SdpAttribute { 834 public: 835 struct Candidate { 836 std::string id; 837 std::string address; 838 uint16_t port; 839 }; 840 841 explicit SdpRemoteCandidatesAttribute( 842 const std::vector<Candidate>& candidates) 843 : SdpAttribute(kRemoteCandidatesAttribute), mCandidates(candidates) {} 844 845 SdpAttribute* Clone() const override { 846 return new SdpRemoteCandidatesAttribute(*this); 847 } 848 849 virtual void Serialize(std::ostream& os) const override; 850 851 std::vector<Candidate> mCandidates; 852 }; 853 854 /* 855 a=rid, draft-pthatcher-mmusic-rid-01 856 857 rid-syntax = "a=rid:" rid-identifier SP rid-dir 858 [ rid-pt-param-list / rid-param-list ] 859 860 rid-identifier = 1*(alpha-numeric / "-" / "_") 861 862 rid-dir = "send" / "recv" 863 864 rid-pt-param-list = SP rid-fmt-list *(";" rid-param) 865 866 rid-param-list = SP rid-param *(";" rid-param) 867 868 rid-fmt-list = "pt=" fmt *( "," fmt ) 869 ; fmt defined in {{RFC4566}} 870 871 rid-param = rid-width-param 872 / rid-height-param 873 / rid-fps-param 874 / rid-fs-param 875 / rid-br-param 876 / rid-pps-param 877 / rid-depend-param 878 / rid-param-other 879 880 rid-width-param = "max-width" [ "=" int-param-val ] 881 882 rid-height-param = "max-height" [ "=" int-param-val ] 883 884 rid-fps-param = "max-fps" [ "=" int-param-val ] 885 886 rid-fs-param = "max-fs" [ "=" int-param-val ] 887 888 rid-br-param = "max-br" [ "=" int-param-val ] 889 890 rid-pps-param = "max-pps" [ "=" int-param-val ] 891 892 rid-depend-param = "depend=" rid-list 893 894 rid-param-other = 1*(alpha-numeric / "-") [ "=" param-val ] 895 896 rid-list = rid-identifier *( "," rid-identifier ) 897 898 int-param-val = 1*DIGIT 899 900 param-val = *( %x20-58 / %x60-7E ) 901 ; Any printable character except semicolon 902 */ 903 class SdpRidAttributeList : public SdpAttribute { 904 public: 905 explicit SdpRidAttributeList() : SdpAttribute(kRidAttribute) {} 906 907 struct Rid { 908 Rid() : direction(sdp::kSend) {} 909 910 // Remove this function. See Bug 1469702 911 bool Parse(std::istream& is, std::string* error); 912 // Remove this function. See Bug 1469702 913 bool ParseParameters(std::istream& is, std::string* error); 914 // Remove this function. See Bug 1469702 915 bool ParseDepend(std::istream& is, std::string* error); 916 // Remove this function. See Bug 1469702 917 bool ParseFormats(std::istream& is, std::string* error); 918 919 void Serialize(std::ostream& os) const; 920 void SerializeParameters(std::ostream& os) const; 921 bool HasFormat(const std::string& format) const; 922 bool HasParameters() const { 923 return !formats.empty() || constraints.maxWidth || 924 constraints.maxHeight || constraints.maxFps || constraints.maxFs || 925 constraints.maxBr || constraints.maxPps || !dependIds.empty(); 926 } 927 928 std::string id; 929 sdp::Direction direction; 930 std::vector<uint16_t> formats; // Empty implies all 931 VideoEncodingConstraints constraints; 932 std::vector<std::string> dependIds; 933 }; 934 935 SdpAttribute* Clone() const override { 936 return new SdpRidAttributeList(*this); 937 } 938 939 static bool CheckRidValidity(const std::string& aRid, std::string* aError); 940 static size_t kMaxRidLength; 941 942 virtual void Serialize(std::ostream& os) const override; 943 944 // Remove this function. See Bug 1469702 945 bool PushEntry(const std::string& raw, std::string* error, size_t* errorPos); 946 947 void PushEntry(const std::string& id, sdp::Direction dir, 948 const std::vector<uint16_t>& formats, 949 const VideoEncodingConstraints& constraints, 950 const std::vector<std::string>& dependIds); 951 952 std::vector<Rid> mRids; 953 }; 954 955 /////////////////////////////////////////////////////////////////////////// 956 // a=rtcp, RFC3605 957 //------------------------------------------------------------------------- 958 // rtcp-attribute = "a=rtcp:" port [nettype space addrtype space 959 // connection-address] CRLF 960 class SdpRtcpAttribute : public SdpAttribute { 961 public: 962 explicit SdpRtcpAttribute(uint16_t port) 963 : SdpAttribute(kRtcpAttribute), 964 mPort(port), 965 mNetType(sdp::kNetTypeNone), 966 mAddrType(sdp::kAddrTypeNone) {} 967 968 SdpRtcpAttribute(uint16_t port, sdp::NetType netType, sdp::AddrType addrType, 969 const std::string& address) 970 : SdpAttribute(kRtcpAttribute), 971 mPort(port), 972 mNetType(netType), 973 mAddrType(addrType), 974 mAddress(address) { 975 MOZ_ASSERT(netType != sdp::kNetTypeNone); 976 MOZ_ASSERT(addrType != sdp::kAddrTypeNone); 977 MOZ_ASSERT(!address.empty()); 978 } 979 980 SdpAttribute* Clone() const override { return new SdpRtcpAttribute(*this); } 981 982 virtual void Serialize(std::ostream& os) const override; 983 984 uint16_t mPort; 985 sdp::NetType mNetType; 986 sdp::AddrType mAddrType; 987 std::string mAddress; 988 }; 989 990 /////////////////////////////////////////////////////////////////////////// 991 // a=rtcp-fb, RFC4585 992 //------------------------------------------------------------------------- 993 // rtcp-fb-syntax = "a=rtcp-fb:" rtcp-fb-pt SP rtcp-fb-val CRLF 994 // 995 // rtcp-fb-pt = "*" ; wildcard: applies to all formats 996 // / fmt ; as defined in SDP spec 997 // 998 // rtcp-fb-val = "ack" rtcp-fb-ack-param 999 // / "nack" rtcp-fb-nack-param 1000 // / "trr-int" SP 1*DIGIT 1001 // / rtcp-fb-id rtcp-fb-param 1002 // 1003 // rtcp-fb-id = 1*(alpha-numeric / "-" / "_") 1004 // 1005 // rtcp-fb-param = SP "app" [SP byte-string] 1006 // / SP token [SP byte-string] 1007 // / ; empty 1008 // 1009 // rtcp-fb-ack-param = SP "rpsi" 1010 // / SP "app" [SP byte-string] 1011 // / SP token [SP byte-string] 1012 // / ; empty 1013 // 1014 // rtcp-fb-nack-param = SP "pli" 1015 // / SP "sli" 1016 // / SP "rpsi" 1017 // / SP "app" [SP byte-string] 1018 // / SP token [SP byte-string] 1019 // / ; empty 1020 // 1021 class SdpRtcpFbAttributeList : public SdpAttribute { 1022 public: 1023 SdpRtcpFbAttributeList() : SdpAttribute(kRtcpFbAttribute) {} 1024 1025 enum Type { kAck, kApp, kCcm, kNack, kTrrInt, kRemb, kTransportCC }; 1026 1027 static const char* pli; 1028 static const char* sli; 1029 static const char* rpsi; 1030 static const char* app; 1031 1032 static const char* fir; 1033 static const char* tmmbr; 1034 static const char* tstr; 1035 static const char* vbcm; 1036 1037 struct Feedback { 1038 std::string pt; 1039 Type type; 1040 std::string parameter; 1041 std::string extra; 1042 // TODO(bug 1744307): Use =default here once it is supported 1043 bool operator==(const Feedback& aOther) const { 1044 return pt == aOther.pt && type == aOther.type && 1045 parameter == aOther.parameter && extra == aOther.extra; 1046 } 1047 }; 1048 1049 void PushEntry(const std::string& pt, Type type, 1050 const std::string& parameter = "", 1051 const std::string& extra = "") { 1052 Feedback value = {pt, type, parameter, extra}; 1053 mFeedbacks.push_back(value); 1054 } 1055 1056 SdpAttribute* Clone() const override { 1057 return new SdpRtcpFbAttributeList(*this); 1058 } 1059 1060 virtual void Serialize(std::ostream& os) const override; 1061 1062 std::vector<Feedback> mFeedbacks; 1063 }; 1064 1065 inline std::ostream& operator<<(std::ostream& os, 1066 SdpRtcpFbAttributeList::Type type) { 1067 switch (type) { 1068 case SdpRtcpFbAttributeList::kAck: 1069 os << "ack"; 1070 break; 1071 case SdpRtcpFbAttributeList::kApp: 1072 os << "app"; 1073 break; 1074 case SdpRtcpFbAttributeList::kCcm: 1075 os << "ccm"; 1076 break; 1077 case SdpRtcpFbAttributeList::kNack: 1078 os << "nack"; 1079 break; 1080 case SdpRtcpFbAttributeList::kTrrInt: 1081 os << "trr-int"; 1082 break; 1083 case SdpRtcpFbAttributeList::kRemb: 1084 os << "goog-remb"; 1085 break; 1086 case SdpRtcpFbAttributeList::kTransportCC: 1087 os << "transport-cc"; 1088 break; 1089 default: 1090 MOZ_ASSERT(false); 1091 os << "?"; 1092 } 1093 return os; 1094 } 1095 1096 /////////////////////////////////////////////////////////////////////////// 1097 // a=rtpmap, RFC4566 1098 //------------------------------------------------------------------------- 1099 // a=rtpmap:<payload type> <encoding name>/<clock rate> [/<encoding parameters>] 1100 class SdpRtpmapAttributeList : public SdpAttribute { 1101 public: 1102 SdpRtpmapAttributeList() : SdpAttribute(kRtpmapAttribute) {} 1103 1104 // Minimal set to get going 1105 enum CodecType { 1106 kOpus, 1107 kG722, 1108 kPCMU, 1109 kPCMA, 1110 kVP8, 1111 kVP9, 1112 kiLBC, 1113 kiSAC, 1114 kH264, 1115 kAV1, 1116 kRed, 1117 kUlpfec, 1118 kTelephoneEvent, 1119 kRtx, 1120 kOtherCodec 1121 }; 1122 1123 struct Rtpmap { 1124 std::string pt; 1125 CodecType codec; 1126 std::string name; 1127 uint32_t clock; 1128 // Technically, this could mean something else in the future. 1129 // In practice, that's probably not going to happen. 1130 uint32_t channels; 1131 }; 1132 1133 void PushEntry(const std::string& pt, CodecType codec, 1134 const std::string& name, uint32_t clock, 1135 uint32_t channels = 0) { 1136 Rtpmap value = {pt, codec, name, clock, channels}; 1137 mRtpmaps.push_back(value); 1138 } 1139 1140 SdpAttribute* Clone() const override { 1141 return new SdpRtpmapAttributeList(*this); 1142 } 1143 1144 virtual void Serialize(std::ostream& os) const override; 1145 1146 bool HasEntry(const std::string& pt) const { 1147 for (auto it = mRtpmaps.begin(); it != mRtpmaps.end(); ++it) { 1148 if (it->pt == pt) { 1149 return true; 1150 } 1151 } 1152 return false; 1153 } 1154 1155 const Rtpmap& GetEntry(const std::string& pt) const { 1156 for (auto it = mRtpmaps.begin(); it != mRtpmaps.end(); ++it) { 1157 if (it->pt == pt) { 1158 return *it; 1159 } 1160 } 1161 MOZ_CRASH(); 1162 } 1163 1164 std::vector<Rtpmap> mRtpmaps; 1165 }; 1166 1167 inline std::ostream& operator<<(std::ostream& os, 1168 SdpRtpmapAttributeList::CodecType c) { 1169 switch (c) { 1170 case SdpRtpmapAttributeList::kOpus: 1171 os << "opus"; 1172 break; 1173 case SdpRtpmapAttributeList::kG722: 1174 os << "G722"; 1175 break; 1176 case SdpRtpmapAttributeList::kPCMU: 1177 os << "PCMU"; 1178 break; 1179 case SdpRtpmapAttributeList::kPCMA: 1180 os << "PCMA"; 1181 break; 1182 case SdpRtpmapAttributeList::kVP8: 1183 os << "VP8"; 1184 break; 1185 case SdpRtpmapAttributeList::kVP9: 1186 os << "VP9"; 1187 break; 1188 case SdpRtpmapAttributeList::kiLBC: 1189 os << "iLBC"; 1190 break; 1191 case SdpRtpmapAttributeList::kiSAC: 1192 os << "iSAC"; 1193 break; 1194 case SdpRtpmapAttributeList::kH264: 1195 os << "H264"; 1196 break; 1197 case SdpRtpmapAttributeList::kAV1: 1198 os << "AV1"; 1199 break; 1200 case SdpRtpmapAttributeList::kRed: 1201 os << "red"; 1202 break; 1203 case SdpRtpmapAttributeList::kUlpfec: 1204 os << "ulpfec"; 1205 break; 1206 case SdpRtpmapAttributeList::kTelephoneEvent: 1207 os << "telephone-event"; 1208 break; 1209 case SdpRtpmapAttributeList::kRtx: 1210 os << "rtx"; 1211 break; 1212 default: 1213 MOZ_ASSERT(false); 1214 os << "?"; 1215 } 1216 return os; 1217 } 1218 1219 /////////////////////////////////////////////////////////////////////////// 1220 // a=fmtp, RFC4566, RFC5576 1221 //------------------------------------------------------------------------- 1222 // a=fmtp:<format> <format specific parameters> 1223 // 1224 class SdpFmtpAttributeList : public SdpAttribute { 1225 public: 1226 SdpFmtpAttributeList() : SdpAttribute(kFmtpAttribute) {} 1227 1228 // Base class for format parameters 1229 class Parameters { 1230 public: 1231 explicit Parameters(SdpRtpmapAttributeList::CodecType aCodec) 1232 : codec_type(aCodec) {} 1233 1234 virtual ~Parameters() = default; 1235 virtual Parameters* Clone() const = 0; 1236 virtual bool ShouldSerialize() const { return true; } 1237 virtual void Serialize(std::ostream& os) const = 0; 1238 virtual bool CompareEq(const Parameters& other) const = 0; 1239 1240 bool operator==(const Parameters& other) const { 1241 return codec_type == other.codec_type && CompareEq(other); 1242 } 1243 SdpRtpmapAttributeList::CodecType codec_type; 1244 }; 1245 1246 class RedParameters : public Parameters { 1247 public: 1248 RedParameters() : Parameters(SdpRtpmapAttributeList::kRed) {} 1249 1250 virtual Parameters* Clone() const override { 1251 return new RedParameters(*this); 1252 } 1253 1254 virtual void Serialize(std::ostream& os) const override { 1255 for (size_t i = 0; i < encodings.size(); ++i) { 1256 os << (i != 0 ? "/" : "") << std::to_string(encodings[i]); 1257 } 1258 } 1259 1260 virtual bool CompareEq(const Parameters& other) const override { 1261 return encodings == static_cast<const RedParameters&>(other).encodings; 1262 } 1263 1264 std::vector<uint8_t> encodings; 1265 }; 1266 1267 struct Av1Parameters : public Parameters { 1268 // https://aomediacodec.github.io/av1-rtp-spec/#722-rid-restrictions-mapping-for-av1 1269 Maybe<uint8_t> profile; 1270 static constexpr uint8_t kDefaultProfile = 0; 1271 Maybe<uint8_t> levelIdx; 1272 static constexpr uint8_t kDefaultLevelIdx = 5; 1273 Maybe<uint8_t> tier; 1274 static constexpr uint8_t kDefaultTier = 0; 1275 1276 Av1Parameters() : Parameters(SdpRtpmapAttributeList::kAV1) {} 1277 Av1Parameters(const Av1Parameters&) = default; 1278 1279 virtual ~Av1Parameters() = default; 1280 1281 virtual Parameters* Clone() const override { 1282 return new Av1Parameters(*this); 1283 } 1284 1285 // Returns the profile parameter if set, or the spec mandated default of 0. 1286 auto profileValue() const -> uint8_t { 1287 return profile.valueOr(kDefaultProfile); 1288 } 1289 // Returns the level-idx parameter if set, or the spec mandated default of 1290 // 5. 1291 auto levelIdxValue() const -> uint8_t { 1292 return levelIdx.valueOr(kDefaultLevelIdx); 1293 } 1294 // Returns the tier parameter if set, or the spec mandated default of 0. 1295 auto tierValue() const -> uint8_t { return tier.valueOr(kDefaultTier); } 1296 1297 virtual bool ShouldSerialize() const override { 1298 return profile.isSome() || levelIdx.isSome() || tier.isSome(); 1299 }; 1300 1301 virtual void Serialize(std::ostream& os) const override { 1302 bool first = true; 1303 profile.apply([&](const auto& profileV) { 1304 os << "profile=" << static_cast<int>(profileV); 1305 first = false; 1306 }); 1307 levelIdx.apply([&](const auto& levelIdxV) { 1308 os << (first ? "" : ";") << "level-idx=" << static_cast<int>(levelIdxV); 1309 first = false; 1310 }); 1311 tier.apply([&](const auto& tierV) { 1312 os << (first ? "" : ";") << "tier=" << static_cast<int>(tierV); 1313 }); 1314 } 1315 1316 virtual bool CompareEq(const Parameters& aOther) const override { 1317 return aOther.codec_type == codec_type && 1318 static_cast<const Av1Parameters&>(aOther).profile == profile && 1319 static_cast<const Av1Parameters&>(aOther).levelIdx == levelIdx && 1320 static_cast<const Av1Parameters&>(aOther).tier == tier; 1321 } 1322 }; 1323 1324 class RtxParameters : public Parameters { 1325 public: 1326 uint8_t apt = 255; // Valid payload types are 0 - 127, use 255 to represent 1327 // unset value. 1328 Maybe<uint32_t> rtx_time; 1329 1330 RtxParameters() : Parameters(SdpRtpmapAttributeList::kRtx) {} 1331 1332 virtual ~RtxParameters() = default; 1333 1334 virtual Parameters* Clone() const override { 1335 return new RtxParameters(*this); 1336 } 1337 1338 virtual void Serialize(std::ostream& os) const override { 1339 if (apt <= 127) { 1340 os << "apt=" << static_cast<uint32_t>(apt); 1341 rtx_time.apply([&](const auto& time) { os << ";rtx-time=" << time; }); 1342 } 1343 } 1344 1345 virtual bool CompareEq(const Parameters& aOther) const override { 1346 if (aOther.codec_type != codec_type) { 1347 return false; 1348 } 1349 auto other = static_cast<const RtxParameters&>(aOther); 1350 return other.apt == apt && other.rtx_time == rtx_time; 1351 } 1352 }; 1353 1354 class H264Parameters : public Parameters { 1355 public: 1356 // Baseline no constraints level 1 1357 static const uint32_t kDefaultProfileLevelId = 0x42000A; 1358 1359 H264Parameters() 1360 : Parameters(SdpRtpmapAttributeList::kH264), 1361 packetization_mode(0), 1362 level_asymmetry_allowed(false), 1363 profile_level_id(kDefaultProfileLevelId), 1364 max_mbps(0), 1365 max_fs(0), 1366 max_cpb(0), 1367 max_dpb(0), 1368 max_br(0) { 1369 memset(sprop_parameter_sets, 0, sizeof(sprop_parameter_sets)); 1370 } 1371 1372 virtual Parameters* Clone() const override { 1373 return new H264Parameters(*this); 1374 } 1375 1376 virtual void Serialize(std::ostream& os) const override { 1377 // Note: don't move this, since having an unconditional param up top 1378 // lets us avoid a whole bunch of conditional streaming of ';' below 1379 os << "profile-level-id=" << std::hex << std::setfill('0') << std::setw(6) 1380 << profile_level_id << std::dec << std::setfill(' '); 1381 1382 os << ";level-asymmetry-allowed=" << (level_asymmetry_allowed ? 1 : 0); 1383 1384 if (strlen(sprop_parameter_sets)) { 1385 os << ";sprop-parameter-sets=" << sprop_parameter_sets; 1386 } 1387 1388 if (packetization_mode != 0) { 1389 os << ";packetization-mode=" << packetization_mode; 1390 } 1391 1392 if (max_mbps != 0) { 1393 os << ";max-mbps=" << max_mbps; 1394 } 1395 1396 if (max_fs != 0) { 1397 os << ";max-fs=" << max_fs; 1398 } 1399 1400 if (max_cpb != 0) { 1401 os << ";max-cpb=" << max_cpb; 1402 } 1403 1404 if (max_dpb != 0) { 1405 os << ";max-dpb=" << max_dpb; 1406 } 1407 1408 if (max_br != 0) { 1409 os << ";max-br=" << max_br; 1410 } 1411 } 1412 1413 virtual bool CompareEq(const Parameters& other) const override { 1414 const auto& otherH264 = static_cast<const H264Parameters&>(other); 1415 1416 // sprop is not comapred here as it does not get parsed in the rsdparsa 1417 return packetization_mode == otherH264.packetization_mode && 1418 level_asymmetry_allowed == otherH264.level_asymmetry_allowed && 1419 profile_level_id == otherH264.profile_level_id && 1420 max_mbps == otherH264.max_mbps && max_fs == otherH264.max_fs && 1421 max_cpb == otherH264.max_cpb && max_dpb == otherH264.max_dpb && 1422 max_br == otherH264.max_br; 1423 } 1424 1425 static const size_t max_sprop_len = 128; 1426 char sprop_parameter_sets[max_sprop_len]; 1427 unsigned int packetization_mode; 1428 bool level_asymmetry_allowed; 1429 unsigned int profile_level_id; 1430 unsigned int max_mbps; 1431 unsigned int max_fs; 1432 unsigned int max_cpb; 1433 unsigned int max_dpb; 1434 unsigned int max_br; 1435 }; 1436 1437 // Also used for VP9 since they share parameters 1438 class VP8Parameters : public Parameters { 1439 public: 1440 explicit VP8Parameters(SdpRtpmapAttributeList::CodecType type) 1441 : Parameters(type), max_fs(0), max_fr(0) {} 1442 1443 virtual Parameters* Clone() const override { 1444 return new VP8Parameters(*this); 1445 } 1446 1447 virtual void Serialize(std::ostream& os) const override { 1448 // draft-ietf-payload-vp8-11 says these are mandatory, upper layer 1449 // needs to ensure they're set properly. 1450 os << "max-fs=" << max_fs; 1451 os << ";max-fr=" << max_fr; 1452 } 1453 1454 virtual bool CompareEq(const Parameters& other) const override { 1455 const auto& otherVP8 = static_cast<const VP8Parameters&>(other); 1456 1457 return max_fs == otherVP8.max_fs && max_fr == otherVP8.max_fr; 1458 } 1459 1460 unsigned int max_fs; 1461 unsigned int max_fr; 1462 }; 1463 1464 class OpusParameters : public Parameters { 1465 public: 1466 enum { 1467 kDefaultMaxPlaybackRate = 48000, 1468 kDefaultStereo = 0, 1469 kDefaultUseInBandFec = 0, 1470 kDefaultMaxAverageBitrate = 0, 1471 kDefaultUseDTX = 0, 1472 kDefaultFrameSize = 0, 1473 kDefaultMinFrameSize = 0, 1474 kDefaultMaxFrameSize = 0, 1475 kDefaultUseCbr = 0 1476 }; 1477 OpusParameters() 1478 : Parameters(SdpRtpmapAttributeList::kOpus), 1479 maxplaybackrate(kDefaultMaxPlaybackRate), 1480 stereo(kDefaultStereo), 1481 useInBandFec(kDefaultUseInBandFec), 1482 maxAverageBitrate(kDefaultMaxAverageBitrate), 1483 useDTX(kDefaultUseDTX), 1484 frameSizeMs(kDefaultFrameSize), 1485 minFrameSizeMs(kDefaultMinFrameSize), 1486 maxFrameSizeMs(kDefaultMaxFrameSize), 1487 useCbr(kDefaultUseCbr) {} 1488 1489 Parameters* Clone() const override { return new OpusParameters(*this); } 1490 1491 void Serialize(std::ostream& os) const override { 1492 os << "maxplaybackrate=" << maxplaybackrate << ";stereo=" << stereo 1493 << ";useinbandfec=" << useInBandFec; 1494 1495 if (useDTX) { 1496 os << ";usedtx=1"; 1497 } 1498 if (maxAverageBitrate) { 1499 os << ";maxaveragebitrate=" << maxAverageBitrate; 1500 } 1501 if (frameSizeMs) { 1502 os << ";ptime=" << frameSizeMs; 1503 } 1504 if (minFrameSizeMs) { 1505 os << ";minptime=" << minFrameSizeMs; 1506 } 1507 if (maxFrameSizeMs) { 1508 os << ";maxptime=" << maxFrameSizeMs; 1509 } 1510 if (useCbr) { 1511 os << ";cbr=1"; 1512 } 1513 } 1514 1515 virtual bool CompareEq(const Parameters& other) const override { 1516 const auto& otherOpus = static_cast<const OpusParameters&>(other); 1517 1518 bool maxplaybackrateIsEq = (maxplaybackrate == otherOpus.maxplaybackrate); 1519 1520 // This is due to a bug in sipcc that causes maxplaybackrate to 1521 // always be 0 if it appears in the fmtp 1522 if (((maxplaybackrate == 0) && (otherOpus.maxplaybackrate != 0)) || 1523 ((maxplaybackrate != 0) && (otherOpus.maxplaybackrate == 0))) { 1524 maxplaybackrateIsEq = true; 1525 } 1526 1527 return maxplaybackrateIsEq && stereo == otherOpus.stereo && 1528 useInBandFec == otherOpus.useInBandFec && 1529 maxAverageBitrate == otherOpus.maxAverageBitrate && 1530 useDTX == otherOpus.useDTX && 1531 frameSizeMs == otherOpus.frameSizeMs && 1532 minFrameSizeMs == otherOpus.minFrameSizeMs && 1533 maxFrameSizeMs == otherOpus.maxFrameSizeMs && 1534 useCbr == otherOpus.useCbr; 1535 } 1536 1537 unsigned int maxplaybackrate; 1538 unsigned int stereo; 1539 unsigned int useInBandFec; 1540 uint32_t maxAverageBitrate; 1541 bool useDTX; 1542 uint32_t frameSizeMs; 1543 uint32_t minFrameSizeMs; 1544 uint32_t maxFrameSizeMs; 1545 bool useCbr; 1546 }; 1547 1548 class TelephoneEventParameters : public Parameters { 1549 public: 1550 TelephoneEventParameters() 1551 : Parameters(SdpRtpmapAttributeList::kTelephoneEvent), 1552 dtmfTones("0-15") {} 1553 1554 virtual Parameters* Clone() const override { 1555 return new TelephoneEventParameters(*this); 1556 } 1557 1558 void Serialize(std::ostream& os) const override { os << dtmfTones; } 1559 1560 virtual bool CompareEq(const Parameters& other) const override { 1561 return dtmfTones == 1562 static_cast<const TelephoneEventParameters&>(other).dtmfTones; 1563 } 1564 1565 std::string dtmfTones; 1566 }; 1567 1568 class Fmtp { 1569 public: 1570 Fmtp(const std::string& aFormat, const Parameters& aParameters) 1571 : format(aFormat), parameters(aParameters.Clone()) {} 1572 1573 // TODO: Rip all of this out when we have move semantics in the stl. 1574 Fmtp(const Fmtp& orig) { *this = orig; } 1575 1576 Fmtp& operator=(const Fmtp& rhs) { 1577 if (this != &rhs) { 1578 format = rhs.format; 1579 parameters.reset(rhs.parameters ? rhs.parameters->Clone() : nullptr); 1580 } 1581 return *this; 1582 } 1583 1584 bool operator==(const Fmtp& other) const { 1585 return format == other.format && *parameters == *other.parameters; 1586 } 1587 1588 // The contract around these is as follows: 1589 // * |parameters| is only set if we recognized the media type and had 1590 // a subclass of Parameters to represent that type of parameters 1591 // * |parameters| is a best-effort representation; it might be missing 1592 // stuff 1593 // * Parameters::codec_type tells you the concrete class, eg 1594 // kH264 -> H264Parameters 1595 std::string format; 1596 UniquePtr<Parameters> parameters; 1597 }; 1598 1599 bool operator==(const SdpFmtpAttributeList& other) const; 1600 1601 SdpAttribute* Clone() const override { 1602 return new SdpFmtpAttributeList(*this); 1603 } 1604 1605 virtual void Serialize(std::ostream& os) const override; 1606 1607 void PushEntry(const std::string& format, const Parameters& parameters) { 1608 mFmtps.push_back(Fmtp(format, parameters)); 1609 } 1610 1611 std::vector<Fmtp> mFmtps; 1612 }; 1613 1614 /////////////////////////////////////////////////////////////////////////// 1615 // a=sctpmap, draft-ietf-mmusic-sctp-sdp-05 1616 //------------------------------------------------------------------------- 1617 // sctpmap-attr = "a=sctpmap:" sctpmap-number media-subtypes 1618 // [streams] 1619 // sctpmap-number = 1*DIGIT 1620 // protocol = labelstring 1621 // labelstring = text 1622 // text = byte-string 1623 // streams = 1*DIGIT 1624 // 1625 // We're going to pretend that there are spaces where they make sense. 1626 class SdpSctpmapAttributeList : public SdpAttribute { 1627 public: 1628 SdpSctpmapAttributeList() : SdpAttribute(kSctpmapAttribute) {} 1629 1630 struct Sctpmap { 1631 std::string pt; 1632 std::string name; 1633 uint32_t streams; 1634 }; 1635 1636 void PushEntry(const std::string& pt, const std::string& name, 1637 uint32_t streams = 0) { 1638 Sctpmap value = {pt, name, streams}; 1639 mSctpmaps.push_back(value); 1640 } 1641 1642 SdpAttribute* Clone() const override { 1643 return new SdpSctpmapAttributeList(*this); 1644 } 1645 1646 virtual void Serialize(std::ostream& os) const override; 1647 1648 bool HasEntry(const std::string& pt) const { 1649 for (auto it = mSctpmaps.begin(); it != mSctpmaps.end(); ++it) { 1650 if (it->pt == pt) { 1651 return true; 1652 } 1653 } 1654 return false; 1655 } 1656 1657 const Sctpmap& GetFirstEntry() const { return mSctpmaps[0]; } 1658 1659 std::vector<Sctpmap> mSctpmaps; 1660 }; 1661 1662 /////////////////////////////////////////////////////////////////////////// 1663 // a=setup, RFC4145 1664 //------------------------------------------------------------------------- 1665 // setup-attr = "a=setup:" role 1666 // role = "active" / "passive" / "actpass" / "holdconn" 1667 class SdpSetupAttribute : public SdpAttribute { 1668 public: 1669 enum Role { kActive, kPassive, kActpass, kHoldconn }; 1670 1671 explicit SdpSetupAttribute(Role role) 1672 : SdpAttribute(kSetupAttribute), mRole(role) {} 1673 1674 SdpAttribute* Clone() const override { return new SdpSetupAttribute(*this); } 1675 1676 virtual void Serialize(std::ostream& os) const override; 1677 1678 Role mRole; 1679 }; 1680 1681 inline std::ostream& operator<<(std::ostream& os, SdpSetupAttribute::Role r) { 1682 switch (r) { 1683 case SdpSetupAttribute::kActive: 1684 os << "active"; 1685 break; 1686 case SdpSetupAttribute::kPassive: 1687 os << "passive"; 1688 break; 1689 case SdpSetupAttribute::kActpass: 1690 os << "actpass"; 1691 break; 1692 case SdpSetupAttribute::kHoldconn: 1693 os << "holdconn"; 1694 break; 1695 default: 1696 MOZ_ASSERT(false); 1697 os << "?"; 1698 } 1699 return os; 1700 } 1701 1702 // Old draft-04 1703 // sc-attr = "a=simulcast:" 1*2( WSP sc-str-list ) [WSP sc-pause-list] 1704 // sc-str-list = sc-dir WSP sc-id-type "=" sc-alt-list *( ";" sc-alt-list ) 1705 // sc-pause-list = "paused=" sc-alt-list 1706 // sc-dir = "send" / "recv" 1707 // sc-id-type = "pt" / "rid" / token 1708 // sc-alt-list = sc-id *( "," sc-id ) 1709 // sc-id = fmt / rid-identifier / token 1710 // ; WSP defined in [RFC5234] 1711 // ; fmt, token defined in [RFC4566] 1712 // ; rid-identifier defined in [I-D.pthatcher-mmusic-rid] 1713 // 1714 // New draft 14, need to parse this for now, will eventually emit it 1715 // sc-value = ( sc-send [SP sc-recv] ) / ( sc-recv [SP sc-send] ) 1716 // sc-send = %s"send" SP sc-str-list 1717 // sc-recv = %s"recv" SP sc-str-list 1718 // sc-str-list = sc-alt-list *( ";" sc-alt-list ) 1719 // sc-alt-list = sc-id *( "," sc-id ) 1720 // sc-id-paused = "~" 1721 // sc-id = [sc-id-paused] rid-id 1722 // ; SP defined in [RFC5234] 1723 // ; rid-id defined in [I-D.ietf-mmusic-rid] 1724 1725 class SdpSimulcastAttribute : public SdpAttribute { 1726 public: 1727 SdpSimulcastAttribute() : SdpAttribute(kSimulcastAttribute) {} 1728 1729 SdpAttribute* Clone() const override { 1730 return new SdpSimulcastAttribute(*this); 1731 } 1732 1733 void Serialize(std::ostream& os) const override; 1734 bool Parse(std::istream& is, std::string* error); 1735 1736 class Encoding { 1737 public: 1738 Encoding(const std::string& aRid, bool aPaused) 1739 : rid(aRid), paused(aPaused) {} 1740 std::string rid; 1741 bool paused = false; 1742 }; 1743 1744 class Version { 1745 public: 1746 void Serialize(std::ostream& os) const; 1747 bool IsSet() const { return !choices.empty(); } 1748 bool Parse(std::istream& is, std::string* error); 1749 1750 std::vector<Encoding> choices; 1751 }; 1752 1753 class Versions : public std::vector<Version> { 1754 public: 1755 void Serialize(std::ostream& os) const; 1756 bool IsSet() const { 1757 if (empty()) { 1758 return false; 1759 } 1760 1761 for (const Version& version : *this) { 1762 if (version.IsSet()) { 1763 return true; 1764 } 1765 } 1766 1767 return false; 1768 } 1769 1770 bool Parse(std::istream& is, std::string* error); 1771 }; 1772 1773 Versions sendVersions; 1774 Versions recvVersions; 1775 }; 1776 1777 /////////////////////////////////////////////////////////////////////////// 1778 // a=ssrc, RFC5576 1779 //------------------------------------------------------------------------- 1780 // ssrc-attr = "ssrc:" ssrc-id SP attribute 1781 // ; The base definition of "attribute" is in RFC 4566. 1782 // ; (It is the content of "a=" lines.) 1783 // 1784 // ssrc-id = integer ; 0 .. 2**32 - 1 1785 //------------------------------------------------------------------------- 1786 // TODO -- In the future, it might be nice if we ran a parse on the 1787 // attribute section of this so that we could interpret it semantically. 1788 // For WebRTC, the key use case for a=ssrc is assocaiting SSRCs with 1789 // media sections, and we're not really going to care about the attribute 1790 // itself. So we're just going to store it as a string for the time being. 1791 // Issue 187. 1792 class SdpSsrcAttributeList : public SdpAttribute { 1793 public: 1794 SdpSsrcAttributeList() : SdpAttribute(kSsrcAttribute) {} 1795 1796 struct Ssrc { 1797 uint32_t ssrc; 1798 std::string attribute; 1799 }; 1800 1801 void PushEntry(uint32_t ssrc, const std::string& attribute) { 1802 Ssrc value = {ssrc, attribute}; 1803 mSsrcs.push_back(value); 1804 } 1805 1806 SdpAttribute* Clone() const override { 1807 return new SdpSsrcAttributeList(*this); 1808 } 1809 1810 virtual void Serialize(std::ostream& os) const override; 1811 1812 std::vector<Ssrc> mSsrcs; 1813 }; 1814 1815 /////////////////////////////////////////////////////////////////////////// 1816 // a=ssrc-group, RFC5576 1817 //------------------------------------------------------------------------- 1818 // ssrc-group-attr = "ssrc-group:" semantics *(SP ssrc-id) 1819 // 1820 // semantics = "FEC" / "FID" / token 1821 // 1822 // ssrc-id = integer ; 0 .. 2**32 - 1 1823 class SdpSsrcGroupAttributeList : public SdpAttribute { 1824 public: 1825 enum Semantics { 1826 kFec, // RFC5576 1827 kFid, // RFC5576 1828 kFecFr, // RFC5956 1829 kDup, // RFC7104 1830 kSim // non-standard, used by hangouts 1831 }; 1832 1833 struct SsrcGroup { 1834 Semantics semantics; 1835 std::vector<uint32_t> ssrcs; 1836 }; 1837 1838 SdpSsrcGroupAttributeList() : SdpAttribute(kSsrcGroupAttribute) {} 1839 1840 void PushEntry(Semantics semantics, const std::vector<uint32_t>& ssrcs) { 1841 SsrcGroup value = {semantics, ssrcs}; 1842 mSsrcGroups.push_back(value); 1843 } 1844 1845 SdpAttribute* Clone() const override { 1846 return new SdpSsrcGroupAttributeList(*this); 1847 } 1848 1849 virtual void Serialize(std::ostream& os) const override; 1850 1851 std::vector<SsrcGroup> mSsrcGroups; 1852 }; 1853 1854 inline std::ostream& operator<<(std::ostream& os, 1855 SdpSsrcGroupAttributeList::Semantics s) { 1856 switch (s) { 1857 case SdpSsrcGroupAttributeList::kFec: 1858 os << "FEC"; 1859 break; 1860 case SdpSsrcGroupAttributeList::kFid: 1861 os << "FID"; 1862 break; 1863 case SdpSsrcGroupAttributeList::kFecFr: 1864 os << "FEC-FR"; 1865 break; 1866 case SdpSsrcGroupAttributeList::kDup: 1867 os << "DUP"; 1868 break; 1869 case SdpSsrcGroupAttributeList::kSim: 1870 os << "SIM"; 1871 break; 1872 default: 1873 MOZ_ASSERT(false); 1874 os << "?"; 1875 } 1876 return os; 1877 } 1878 1879 /////////////////////////////////////////////////////////////////////////// 1880 class SdpMultiStringAttribute : public SdpAttribute { 1881 public: 1882 explicit SdpMultiStringAttribute(AttributeType type) : SdpAttribute(type) {} 1883 1884 void PushEntry(const std::string& entry) { mValues.push_back(entry); } 1885 1886 SdpAttribute* Clone() const override { 1887 return new SdpMultiStringAttribute(*this); 1888 } 1889 1890 virtual void Serialize(std::ostream& os) const override; 1891 1892 std::vector<std::string> mValues; 1893 }; 1894 1895 // otherwise identical to SdpMultiStringAttribute, this is used for 1896 // ice-options and other places where the value is serialized onto 1897 // a single line with space separating tokens 1898 class SdpOptionsAttribute : public SdpAttribute { 1899 public: 1900 explicit SdpOptionsAttribute(AttributeType type) : SdpAttribute(type) {} 1901 1902 void PushEntry(const std::string& entry) { mValues.push_back(entry); } 1903 1904 void Load(const std::string& value); 1905 1906 SdpAttribute* Clone() const override { 1907 return new SdpOptionsAttribute(*this); 1908 } 1909 1910 virtual void Serialize(std::ostream& os) const override; 1911 1912 std::vector<std::string> mValues; 1913 }; 1914 1915 // Used for attributes that take no value (eg; a=ice-lite) 1916 class SdpFlagAttribute : public SdpAttribute { 1917 public: 1918 explicit SdpFlagAttribute(AttributeType type) : SdpAttribute(type) {} 1919 1920 SdpAttribute* Clone() const override { return new SdpFlagAttribute(*this); } 1921 1922 virtual void Serialize(std::ostream& os) const override; 1923 }; 1924 1925 // Used for any other kind of single-valued attribute not otherwise specialized 1926 class SdpStringAttribute : public SdpAttribute { 1927 public: 1928 explicit SdpStringAttribute(AttributeType type, const std::string& value) 1929 : SdpAttribute(type), mValue(value) {} 1930 1931 SdpAttribute* Clone() const override { return new SdpStringAttribute(*this); } 1932 1933 virtual void Serialize(std::ostream& os) const override; 1934 1935 std::string mValue; 1936 }; 1937 1938 // Used for any purely (non-negative) numeric attribute 1939 class SdpNumberAttribute : public SdpAttribute { 1940 public: 1941 explicit SdpNumberAttribute(AttributeType type, uint32_t value = 0) 1942 : SdpAttribute(type), mValue(value) {} 1943 1944 SdpAttribute* Clone() const override { return new SdpNumberAttribute(*this); } 1945 1946 virtual void Serialize(std::ostream& os) const override; 1947 1948 uint32_t mValue; 1949 }; 1950 1951 } // namespace mozilla 1952 1953 #endif