sdp 支持ssrc-group属性

This commit is contained in:
xiongziliang 2021-03-28 23:31:21 +08:00
parent 81f29fea61
commit 6fa385f3a1
2 changed files with 105 additions and 33 deletions

View File

@ -21,31 +21,31 @@ void registerSdpItem(){
class DirectionInterface { class DirectionInterface {
public: public:
virtual RtpDirection getDirection() = 0; virtual RtpDirection getDirection() const = 0;
}; };
class SdpDirectionSendonly : public SdpItem, public DirectionInterface{ class SdpDirectionSendonly : public SdpItem, public DirectionInterface{
public: public:
const char* getKey() override { return getRtpDirectionString(getDirection());} const char* getKey() const override { return getRtpDirectionString(getDirection());}
RtpDirection getDirection() override {return RtpDirection::sendonly;} RtpDirection getDirection() const override {return RtpDirection::sendonly;}
}; };
class SdpDirectionRecvonly : public SdpItem, public DirectionInterface{ class SdpDirectionRecvonly : public SdpItem, public DirectionInterface{
public: public:
const char* getKey() override { return getRtpDirectionString(getDirection());} const char* getKey() const override { return getRtpDirectionString(getDirection());}
RtpDirection getDirection() override {return RtpDirection::recvonly;} RtpDirection getDirection() const override {return RtpDirection::recvonly;}
}; };
class SdpDirectionSendrecv : public SdpItem, public DirectionInterface{ class SdpDirectionSendrecv : public SdpItem, public DirectionInterface{
public: public:
const char* getKey() override { return getRtpDirectionString(getDirection());} const char* getKey() const override { return getRtpDirectionString(getDirection());}
RtpDirection getDirection() override {return RtpDirection::sendrecv;} RtpDirection getDirection() const override {return RtpDirection::sendrecv;}
}; };
class SdpDirectionInactive : public SdpItem, public DirectionInterface{ class SdpDirectionInactive : public SdpItem, public DirectionInterface{
public: public:
const char* getKey() override { return getRtpDirectionString(getDirection());} const char* getKey() const override { return getRtpDirectionString(getDirection());}
RtpDirection getDirection() override {return RtpDirection::inactive;} RtpDirection getDirection() const override {return RtpDirection::inactive;}
}; };
static bool registerAllItem(){ static bool registerAllItem(){
@ -69,6 +69,7 @@ static bool registerAllItem(){
registerSdpItem<SdpAttrRtcp>(); registerSdpItem<SdpAttrRtcp>();
registerSdpItem<SdpAttrIceUfrag>(); registerSdpItem<SdpAttrIceUfrag>();
registerSdpItem<SdpAttrIcePwd>(); registerSdpItem<SdpAttrIcePwd>();
registerSdpItem<SdpAttrIceOption>();
registerSdpItem<SdpAttrFingerprint>(); registerSdpItem<SdpAttrFingerprint>();
registerSdpItem<SdpAttrSetup>(); registerSdpItem<SdpAttrSetup>();
registerSdpItem<SdpAttrMid>(); registerSdpItem<SdpAttrMid>();
@ -77,6 +78,7 @@ static bool registerAllItem(){
registerSdpItem<SdpAttrRtcpFb>(); registerSdpItem<SdpAttrRtcpFb>();
registerSdpItem<SdpAttrFmtp>(); registerSdpItem<SdpAttrFmtp>();
registerSdpItem<SdpAttrSSRC>(); registerSdpItem<SdpAttrSSRC>();
registerSdpItem<SdpAttrSSRCGroup>();
registerSdpItem<SdpAttrSctpMap>(); registerSdpItem<SdpAttrSctpMap>();
registerSdpItem<SdpAttrCandidate>(); registerSdpItem<SdpAttrCandidate>();
registerSdpItem<SdpDirectionSendonly>(); registerSdpItem<SdpDirectionSendonly>();
@ -230,6 +232,8 @@ RtpDirection RtcMedia::getDirection() const{
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
#define SDP_THROW() throw std::invalid_argument(StrPrinter << "解析sdp " << getKey() << " 字段失败:" << str) #define SDP_THROW() throw std::invalid_argument(StrPrinter << "解析sdp " << getKey() << " 字段失败:" << str)
#define SDP_THROW2() throw std::invalid_argument(StrPrinter << "生成sdp " << getKey() << " 字段失败")
void SdpTime::parse(const string &str) { void SdpTime::parse(const string &str) {
if (sscanf(str.data(), "%" PRIu64 " %" PRIu64, &start, &stop) != 2) { if (sscanf(str.data(), "%" PRIu64 " %" PRIu64, &start, &stop) != 2) {
SDP_THROW(); SDP_THROW();
@ -555,6 +559,41 @@ string SdpAttrSSRC::toString() const {
return SdpItem::toString(); return SdpItem::toString();
} }
void SdpAttrSSRCGroup::parse(const string &str) {
auto vec = split(str, " ");
if (vec.size() == 3) {
if (vec[0] != "FID") {
SDP_THROW();
}
type = std::move(vec[0]);
u.fid.rtp_ssrc = atoi(vec[1].data());
u.fid.rtx_ssrc = atoi(vec[2].data());
} else if (vec.size() == 4) {
if (vec[0] != "SIM") {
SDP_THROW();
}
type = std::move(vec[0]);
u.sim.rtp_ssrc_low = atoi(vec[1].data());
u.sim.rtp_ssrc_mid = atoi(vec[2].data());
u.sim.rtp_ssrc_high = atoi(vec[3].data());
} else {
SDP_THROW();
}
}
string SdpAttrSSRCGroup::toString() const {
if (value.empty()) {
if (type == "FID") {
value = type + " " + to_string(u.fid.rtp_ssrc) + " " + to_string(u.fid.rtx_ssrc);
} else if (type == "SIM") {
value = type + " " + to_string(u.sim.rtp_ssrc_low) + " " + to_string(u.sim.rtp_ssrc_mid) + " " + to_string(u.sim.rtp_ssrc_high);
} else {
SDP_THROW2();
}
}
return SdpItem::toString();
}
void SdpAttrSctpMap::parse(const string &str) { void SdpAttrSctpMap::parse(const string &str) {
char subtypes_buf[64] = {0}; char subtypes_buf[64] = {0};
if (3 == sscanf(str.data(), "%" PRIu16 " %63[^ ] %" PRId32, &port, subtypes_buf, &streams)) { if (3 == sscanf(str.data(), "%" PRIu16 " %63[^ ] %" PRId32, &port, subtypes_buf, &streams)) {

View File

@ -87,7 +87,7 @@ public:
virtual string toString() const { virtual string toString() const {
return value; return value;
} }
virtual const char* getKey() = 0; virtual const char* getKey() const = 0;
protected: protected:
mutable string value; mutable string value;
@ -97,14 +97,14 @@ template <char KEY>
class SdpString : public SdpItem{ class SdpString : public SdpItem{
public: public:
// *=* // *=*
const char* getKey() override { static string key(1, KEY); return key.data();} const char* getKey() const override { static string key(1, KEY); return key.data();}
}; };
class SdpCommon : public SdpItem { class SdpCommon : public SdpItem {
public: public:
string key; string key;
SdpCommon(string key) { this->key = std::move(key); } SdpCommon(string key) { this->key = std::move(key); }
const char* getKey() override { return key.data();} const char* getKey() const override { return key.data();}
}; };
class SdpTime : public SdpItem{ class SdpTime : public SdpItem{
@ -115,7 +115,7 @@ public:
uint64_t stop {0}; uint64_t stop {0};
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "t";} const char* getKey() const override { return "t";}
}; };
class SdpOrigin : public SdpItem{ class SdpOrigin : public SdpItem{
@ -131,7 +131,7 @@ public:
string address {"0.0.0.0"}; string address {"0.0.0.0"};
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "o";} const char* getKey() const override { return "o";}
}; };
class SdpConnection : public SdpItem { class SdpConnection : public SdpItem {
@ -144,7 +144,7 @@ public:
string address {"0.0.0.0"}; string address {"0.0.0.0"};
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "c";} const char* getKey() const override { return "c";}
}; };
class SdpBandwidth : public SdpItem { class SdpBandwidth : public SdpItem {
@ -158,7 +158,7 @@ public:
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "b";} const char* getKey() const override { return "b";}
}; };
class SdpMedia : public SdpItem { class SdpMedia : public SdpItem {
@ -172,7 +172,7 @@ public:
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "m";} const char* getKey() const override { return "m";}
}; };
class SdpAttr : public SdpItem{ class SdpAttr : public SdpItem{
@ -184,7 +184,7 @@ public:
SdpItem::Ptr detail; SdpItem::Ptr detail;
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "a";} const char* getKey() const override { return "a";}
}; };
class SdpAttrGroup : public SdpItem{ class SdpAttrGroup : public SdpItem{
@ -197,7 +197,7 @@ public:
vector<string> mids; vector<string> mids;
void parse(const string &str) override ; void parse(const string &str) override ;
string toString() const override ; string toString() const override ;
const char* getKey() override { return "group";} const char* getKey() const override { return "group";}
}; };
class SdpAttrMsidSemantic : public SdpItem { class SdpAttrMsidSemantic : public SdpItem {
@ -226,7 +226,7 @@ public:
string token; string token;
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "msid-semantic";} const char* getKey() const override { return "msid-semantic";}
}; };
class SdpAttrRtcp : public SdpItem { class SdpAttrRtcp : public SdpItem {
@ -238,19 +238,25 @@ public:
string address {"0.0.0.0"}; string address {"0.0.0.0"};
void parse(const string &str) override;; void parse(const string &str) override;;
string toString() const override; string toString() const override;
const char* getKey() override { return "rtcp";} const char* getKey() const override { return "rtcp";}
}; };
class SdpAttrIceUfrag : public SdpItem { class SdpAttrIceUfrag : public SdpItem {
public: public:
//a=ice-ufrag:sXJ3 //a=ice-ufrag:sXJ3
const char* getKey() override { return "ice-ufrag";} const char* getKey() const override { return "ice-ufrag";}
}; };
class SdpAttrIcePwd : public SdpItem { class SdpAttrIcePwd : public SdpItem {
public: public:
//a=ice-pwd:yEclOTrLg1gEubBFefOqtmyV //a=ice-pwd:yEclOTrLg1gEubBFefOqtmyV
const char* getKey() override { return "ice-pwd";} const char* getKey() const override { return "ice-pwd";}
};
class SdpAttrIceOption : public SdpItem {
public:
//a=ice-options:trickle
const char* getKey() const override { return "ice-options";}
}; };
class SdpAttrFingerprint : public SdpItem { class SdpAttrFingerprint : public SdpItem {
@ -260,7 +266,7 @@ public:
string hash; string hash;
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "fingerprint";} const char* getKey() const override { return "fingerprint";}
}; };
class SdpAttrSetup : public SdpItem { class SdpAttrSetup : public SdpItem {
@ -269,13 +275,13 @@ public:
DtlsRole role{DtlsRole::actpass}; DtlsRole role{DtlsRole::actpass};
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "setup";} const char* getKey() const override { return "setup";}
}; };
class SdpAttrMid : public SdpItem { class SdpAttrMid : public SdpItem {
public: public:
//a=mid:audio //a=mid:audio
const char* getKey() override { return "mid";} const char* getKey() const override { return "mid";}
}; };
class SdpAttrExtmap : public SdpItem { class SdpAttrExtmap : public SdpItem {
@ -285,7 +291,7 @@ public:
string ext; string ext;
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "extmap";} const char* getKey() const override { return "extmap";}
}; };
class SdpAttrRtpMap : public SdpItem { class SdpAttrRtpMap : public SdpItem {
@ -297,7 +303,7 @@ public:
int channel {0}; int channel {0};
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "rtpmap";} const char* getKey() const override { return "rtpmap";}
}; };
class SdpAttrRtcpFb : public SdpItem { class SdpAttrRtcpFb : public SdpItem {
@ -307,7 +313,7 @@ public:
vector<string> arr; vector<string> arr;
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "rtcp-fb";} const char* getKey() const override { return "rtcp-fb";}
}; };
class SdpAttrFmtp : public SdpItem { class SdpAttrFmtp : public SdpItem {
@ -317,7 +323,7 @@ public:
vector<std::pair<string, string> > arr; vector<std::pair<string, string> > arr;
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "fmtp";} const char* getKey() const override { return "fmtp";}
}; };
class SdpAttrSSRC : public SdpItem { class SdpAttrSSRC : public SdpItem {
@ -330,7 +336,34 @@ public:
string attribute_value; string attribute_value;
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "ssrc";} const char* getKey() const override { return "ssrc";}
};
class SdpAttrSSRCGroup : public SdpItem {
public:
//a=ssrc-group 定义参考 RFC 5576 ,用于描述多个 ssrc 之间的关联,常见的有两种:
//a=ssrc-group:FID 2430709021 3715850271
// FID (Flow Identification) 最初用在 FEC 的关联中WebRTC 中通常用于关联一组常规 RTP stream 和 重传 RTP stream 。
//a=ssrc-group:SIM 360918977 360918978 360918980
// 在 Chrome 独有的 SDP munging 风格的 simulcast 中使用,将三组编码质量由低到高的 MediaStreamTrack 关联在一起。
string type{"FID"};
union {
struct {
uint32_t rtp_ssrc;
uint32_t rtx_ssrc;
} fid;
struct {
uint32_t rtp_ssrc_low;
uint32_t rtp_ssrc_mid;
uint32_t rtp_ssrc_high;
} sim;
} u;
void parse(const string &str) override;
string toString() const override;
const char* getKey() const override { return "ssrc-group";}
}; };
class SdpAttrSctpMap : public SdpItem { class SdpAttrSctpMap : public SdpItem {
@ -343,7 +376,7 @@ public:
int streams; int streams;
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "sctpmap";} const char* getKey() const override { return "sctpmap";}
}; };
class SdpAttrCandidate : public SdpItem { class SdpAttrCandidate : public SdpItem {
@ -363,7 +396,7 @@ public:
void parse(const string &str) override; void parse(const string &str) override;
string toString() const override; string toString() const override;
const char* getKey() override { return "candidate";} const char* getKey() const override { return "candidate";}
}; };
class RtcMedia { class RtcMedia {