完成sdp转string

This commit is contained in:
ziyue 2021-03-30 13:09:02 +08:00
parent 6d16ae91e6
commit c6a5471a23
2 changed files with 194 additions and 5 deletions

View File

@ -52,6 +52,18 @@ public:
RtpDirection getDirection() const override {return RtpDirection::inactive;} RtpDirection getDirection() const override {return RtpDirection::inactive;}
}; };
class DirectionInterfaceImp : public SdpItem, public DirectionInterface{
public:
DirectionInterfaceImp(RtpDirection direct){
direction = direct;
}
const char* getKey() const override { return getRtpDirectionString(getDirection());}
RtpDirection getDirection() const override {return direction;}
private:
RtpDirection direction;
};
static bool registerAllItem(){ static bool registerAllItem(){
registerSdpItem<SdpString<'v'> >(); registerSdpItem<SdpString<'v'> >();
registerSdpItem<SdpString<'s'> >(); registerSdpItem<SdpString<'s'> >();
@ -502,7 +514,7 @@ void SdpAttrExtmap::parse(const string &str) {
string SdpAttrExtmap::toString() const { string SdpAttrExtmap::toString() const {
if (value.empty()) { if (value.empty()) {
if(direction == RtpDirection::invalid){ if(direction == RtpDirection::invalid || direction == RtpDirection::sendrecv){
value = to_string(index) + " " + ext; value = to_string(index) + " " + ext;
} else { } else {
value = to_string(index) + "/" + getRtpDirectionString(direction) + " " + ext; value = to_string(index) + "/" + getRtpDirectionString(direction) + " " + ext;
@ -630,9 +642,9 @@ void SdpAttrSSRCGroup::parse(const string &str) {
string SdpAttrSSRCGroup::toString() const { string SdpAttrSSRCGroup::toString() const {
if (value.empty()) { if (value.empty()) {
if (type == "FID") { if (isFID()) {
value = type + " " + to_string(u.fid.rtp_ssrc) + " " + to_string(u.fid.rtx_ssrc); value = type + " " + to_string(u.fid.rtp_ssrc) + " " + to_string(u.fid.rtx_ssrc);
} else if (type == "SIM") { } else if (isSIM()) {
value = type + " " + to_string(u.sim.rtp_ssrc_low) + " " + to_string(u.sim.rtp_ssrc_mid) + " " + to_string(u.sim.rtp_ssrc_high); value = type + " " + to_string(u.sim.rtp_ssrc_low) + " " + to_string(u.sim.rtp_ssrc_mid) + " " + to_string(u.sim.rtp_ssrc_high);
} else { } else {
SDP_THROW2(); SDP_THROW2();
@ -849,7 +861,8 @@ void test_sdp(){
RtcSession session2; RtcSession session2;
session2.loadFrom(str2); session2.loadFrom(str2);
InfoL; DebugL << session1.toString();
DebugL << session2.toString();
} }
void RtcSession::loadFrom(const string &str) { void RtcSession::loadFrom(const string &str) {
@ -1013,6 +1026,165 @@ void RtcSession::loadFrom(const string &str) {
checkValid(); checkValid();
} }
std::shared_ptr<SdpItem> wrapSdpAttr(SdpItem::Ptr item){
auto ret = std::make_shared<SdpAttr>();
ret->detail = std::move(item);
return ret;
}
string RtcSession::toString() const{
checkValid();
RtcSessionSdp sdp;
sdp.items.emplace_back(std::make_shared<SdpString<'v'> >(to_string(version)));
sdp.items.emplace_back(std::make_shared<SdpOrigin>(origin));
sdp.items.emplace_back(std::make_shared<SdpString<'s'> >(session_name));
if (!session_info.empty()) {
sdp.items.emplace_back(std::make_shared<SdpString<'i'> >(session_info));
}
sdp.items.emplace_back(std::make_shared<SdpTime>(time));
sdp.items.emplace_back(std::make_shared<SdpConnection>(connection));
if (!bandwidth.empty()) {
sdp.items.emplace_back(std::make_shared<SdpBandwidth>(bandwidth));
}
sdp.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrMsidSemantic>(msid_semantic)));
sdp.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrGroup>(group)));
for (auto &m : media) {
sdp.medias.emplace_back();
auto &sdp_media = sdp.medias.back();
auto mline = std::make_shared<SdpMedia>();
mline->type = m.type;
mline->port = m.port;
mline->proto = m.proto;
for (auto &p : m.plan) {
mline->fmts.emplace_back(p.pt);
}
if (m.type == TrackApplication) {
mline->fmts.emplace_back(m.sctp_port);
}
sdp_media.items.emplace_back(std::move(mline));
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrMid>(m.mid)));
sdp_media.items.emplace_back(std::make_shared<SdpConnection>(m.addr));
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrIceUfrag>(m.ice_ufrag)));
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrIcePwd>(m.ice_pwd)));
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrFingerprint>(m.fingerprint)));
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrSetup>(m.role)));
if (m.ice_trickle) {
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpCommon>("ice-trickle")));
}
if (m.ice_lite) {
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpCommon>("ice-lite")));
}
if (m.ice_renomination) {
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpCommon>("ice-renomination")));
}
for (auto &ext : m.extmap) {
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrExtmap>(ext)));
}
if (m.direction != RtpDirection::invalid) {
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<DirectionInterfaceImp>(m.direction)));
}
if (m.rtcp_addr.port) {
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrRtcp>(m.rtcp_addr)));
}
if (m.rtcp_mux) {
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpCommon>("rtcp-mux")));
}
if (m.rtcp_rsize) {
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpCommon>("rtcp-rsize")));
}
if(m.type != TrackApplication) {
for (auto &p : m.plan) {
auto rtp_map = std::make_shared<SdpAttrRtpMap>();
rtp_map->pt = p.pt;
rtp_map->codec = p.codec;
rtp_map->sample_rate = p.sample_rate;
rtp_map->channel = p.channel;
sdp_media.items.emplace_back(wrapSdpAttr(std::move(rtp_map)));
for (auto &fb : p.rtcp_fb) {
auto rtcp_fb = std::make_shared<SdpAttrRtcpFb>();
rtcp_fb->pt = p.pt;
rtcp_fb->rtcp_type = fb;
sdp_media.items.emplace_back(wrapSdpAttr(std::move(rtcp_fb)));
}
if (!p.fmtp.empty()) {
auto fmtp = std::make_shared<SdpAttrFmtp>();
fmtp->pt = p.pt;
fmtp->arr = p.fmtp;
sdp_media.items.emplace_back(wrapSdpAttr(std::move(fmtp)));
}
}
if (!m.rtp_ssrc.empty() && !m.rtx_ssrc.empty()) {
auto group = std::make_shared<SdpAttrSSRCGroup>();
group->type = "FID";
group->u.fid.rtp_ssrc = m.rtp_ssrc.ssrc;
group->u.fid.rtx_ssrc = m.rtx_ssrc.ssrc;
sdp_media.items.emplace_back(wrapSdpAttr(std::move(group)));
}
static auto addSSRCItem = [](const RtcSSRC &rtp_ssrc, vector<SdpItem::Ptr> &items) {
SdpAttrSSRC ssrc;
ssrc.ssrc = rtp_ssrc.ssrc;
ssrc.attribute = "cname";
ssrc.attribute_value = rtp_ssrc.cname;
items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrSSRC>(ssrc)));
if (!rtp_ssrc.msid.empty()) {
ssrc.attribute = "msid";
ssrc.attribute_value = rtp_ssrc.msid;
items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrSSRC>(ssrc)));
}
if (!rtp_ssrc.mslabel.empty()) {
ssrc.attribute = "mslabel";
ssrc.attribute_value = rtp_ssrc.mslabel;
items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrSSRC>(ssrc)));
}
if (!rtp_ssrc.label.empty()) {
ssrc.attribute = "label";
ssrc.attribute_value = rtp_ssrc.label;
items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrSSRC>(ssrc)));
}
};
if (!m.rtp_ssrc.empty()) {
addSSRCItem(m.rtp_ssrc, sdp_media.items);
}
if (!m.rtx_ssrc.empty()) {
addSSRCItem(m.rtx_ssrc, sdp_media.items);
}
bool enable_sim = false;
if (!m.rtp_ssrc_low.empty() && !m.rtp_ssrc_mid.empty() && !m.rtp_ssrc_high.empty()) {
auto group = std::make_shared<SdpAttrSSRCGroup>();
group->type = "SIM";
group->u.sim.rtp_ssrc_low = m.rtp_ssrc_low.ssrc;
group->u.sim.rtp_ssrc_mid = m.rtp_ssrc_mid.ssrc;
group->u.sim.rtp_ssrc_high = m.rtp_ssrc_high.ssrc;
sdp_media.items.emplace_back(wrapSdpAttr(std::move(group)));
enable_sim = true;
}
if (enable_sim) {
addSSRCItem(m.rtp_ssrc_low, sdp_media.items);
addSSRCItem(m.rtp_ssrc_mid, sdp_media.items);
addSSRCItem(m.rtp_ssrc_high, sdp_media.items);
}
} else {
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrSctpMap>(m.sctpmap)));
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpCommon>("sctp-port", to_string(m.sctp_port))));
}
for (auto &cand : m.candidate) {
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrCandidate>(cand)));
}
}
return sdp.toString();
}
string RtcCodecPlan::getFmtp(const char *key) const{ string RtcCodecPlan::getFmtp(const char *key) const{
for (auto &item : fmtp) { for (auto &item : fmtp) {
if (strcasecmp(item.first.data(), key) == 0) { if (strcasecmp(item.first.data(), key) == 0) {

View File

@ -96,6 +96,8 @@ protected:
template <char KEY> template <char KEY>
class SdpString : public SdpItem{ class SdpString : public SdpItem{
public: public:
SdpString() = default;
SdpString(string val) {value == std::move(val);}
// *=* // *=*
const char* getKey() const override { static string key(1, KEY); return key.data();} const char* getKey() const override { static string key(1, KEY); return key.data();}
}; };
@ -104,6 +106,11 @@ 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); }
SdpCommon(string key, string val) {
this->key = std::move(key);
this->value = std::move(val);
}
const char* getKey() const override { return key.data();} const char* getKey() const override { return key.data();}
}; };
@ -163,6 +170,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() const override { return "b";} const char* getKey() const override { return "b";}
bool empty() const {return bandwidth == 0;}
}; };
class SdpMedia : public SdpItem { class SdpMedia : public SdpItem {
@ -243,7 +251,7 @@ public:
class SdpAttrRtcp : public SdpItem { class SdpAttrRtcp : public SdpItem {
public: public:
// a=rtcp:9 IN IP4 0.0.0.0 // a=rtcp:9 IN IP4 0.0.0.0
uint16_t port; uint16_t port{0};
string nettype {"IN"}; string nettype {"IN"};
string addrtype {"IP4"}; string addrtype {"IP4"};
string address {"0.0.0.0"}; string address {"0.0.0.0"};
@ -254,12 +262,16 @@ public:
class SdpAttrIceUfrag : public SdpItem { class SdpAttrIceUfrag : public SdpItem {
public: public:
SdpAttrIceUfrag() = default;
SdpAttrIceUfrag(string str) {value = std::move(str);}
//a=ice-ufrag:sXJ3 //a=ice-ufrag:sXJ3
const char* getKey() const override { return "ice-ufrag";} const char* getKey() const override { return "ice-ufrag";}
}; };
class SdpAttrIcePwd : public SdpItem { class SdpAttrIcePwd : public SdpItem {
public: public:
SdpAttrIcePwd() = default;
SdpAttrIcePwd(string str) {value = std::move(str);}
//a=ice-pwd:yEclOTrLg1gEubBFefOqtmyV //a=ice-pwd:yEclOTrLg1gEubBFefOqtmyV
const char* getKey() const override { return "ice-pwd";} const char* getKey() const override { return "ice-pwd";}
}; };
@ -283,6 +295,8 @@ public:
class SdpAttrSetup : public SdpItem { class SdpAttrSetup : public SdpItem {
public: public:
//a=setup:actpass //a=setup:actpass
SdpAttrSetup() = default;
SdpAttrSetup(DtlsRole r) { role = r; }
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;
@ -291,6 +305,8 @@ public:
class SdpAttrMid : public SdpItem { class SdpAttrMid : public SdpItem {
public: public:
SdpAttrMid() = default;
SdpAttrMid(string val) { value = std::move(val); }
//a=mid:audio //a=mid:audio
const char* getKey() const override { return "mid";} const char* getKey() const override { return "mid";}
}; };
@ -607,6 +623,7 @@ public:
void loadFrom(const string &sdp); void loadFrom(const string &sdp);
void checkValid() const; void checkValid() const;
string toString() const;
}; };
class RtcConfigure { class RtcConfigure {