mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 20:27:34 +08:00
sdp 支持ssrc-group属性
This commit is contained in:
parent
81f29fea61
commit
6fa385f3a1
@ -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)) {
|
||||||
|
81
webrtc/Sdp.h
81
webrtc/Sdp.h
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user