整理优化webrtc ssrc与simulcast相关代码

This commit is contained in:
ziyue 2021-10-12 21:26:01 +08:00
parent fbc5378058
commit acbe99cb43
3 changed files with 103 additions and 67 deletions

View File

@ -870,57 +870,72 @@ void RtcSession::loadFrom(const string &str, bool check) {
} }
auto ssrc_groups = media.getAllItem<SdpAttrSSRCGroup>('a', "ssrc-group"); auto ssrc_groups = media.getAllItem<SdpAttrSSRCGroup>('a', "ssrc-group");
bool have_rtx_ssrc = false;
SdpAttrSSRCGroup *ssrc_group_sim = nullptr; SdpAttrSSRCGroup *ssrc_group_sim = nullptr;
SdpAttrSSRCGroup *ssrc_group_fid = nullptr;
for (auto &group : ssrc_groups) { for (auto &group : ssrc_groups) {
if (group.isFID()) { if (group.isFID()) {
ssrc_group_fid = &group; have_rtx_ssrc = true;
//ssrc-group:FID字段必须包含rtp/rtx的ssrc
CHECK(group.ssrcs.size() == 2);
//根据rtp ssrc找到对象
auto it = rtc_ssrc_map.find(group.ssrcs[0]);
CHECK(it != rtc_ssrc_map.end());
//设置rtx ssrc
it->second.rtx_ssrc = group.ssrcs[1];
rtc_media.rtp_rtx_ssrc.emplace_back(it->second);
} else if (group.isSIM()) { } else if (group.isSIM()) {
CHECK(!ssrc_group_sim);
ssrc_group_sim = &group; ssrc_group_sim = &group;
} }
} }
if (ssrc_group_fid) { if (!have_rtx_ssrc) {
//指定了ssrc-group:FID字段 //按照sdp顺序依次添加ssrc
for (auto ssrc : ssrc_group_fid->ssrcs) { for (auto &attr : ssrc_attr) {
auto it = rtc_ssrc_map.find(ssrc); if (attr.attribute == "cname") {
if (it == rtc_ssrc_map.end()) { rtc_media.rtp_rtx_ssrc.emplace_back(rtc_ssrc_map[attr.ssrc]);
throw std::invalid_argument("a=ssrc-group:FID字段指定的ssrc未找到");
} }
rtc_media.rtp_rtx_ssrc.emplace_back(it->second);
} }
CHECK(rtc_media.rtp_rtx_ssrc.size() == 2); }
} else {
auto simulcast = media.getItemClass<SdpAttrSimulcast>('a', "simulcast"); auto simulcast = media.getItemClass<SdpAttrSimulcast>('a', "simulcast");
if (simulcast.empty()) { if (!simulcast.empty()) {
//没有指定ssrc-group:FID字段,也不是simulcast那么只有1个或0个ssrc // a=rid:h send
if (rtc_ssrc_map.size() == 1) { // a=rid:m send
rtc_media.rtp_rtx_ssrc.emplace_back(rtc_ssrc_map.begin()->second); // a=rid:l send
} else if (rtc_ssrc_map.size() > 1) { // a=simulcast:send h;m;l
throw std::invalid_argument("sdp中不存在a=ssrc-group:FID字段,但是ssrc却大于1个"); // 风格的simulcast
} unordered_set<string> rid_map;
} else { for (auto &rid : simulcast.rids) {
//开启simulcast rid_map.emplace(rid);
rtc_media.rtp_rids = simulcast.rids;
//simulcast最少要求2种方案
CHECK(rtc_media.rtp_rids.size() >= 2);
} }
for (auto &rid : media.getAllItem<SdpAttrRid>('a', "rid")) {
CHECK(rid.direction == simulcast.direction);
CHECK(rid_map.find(rid.rid) != rid_map.end());
}
//simulcast最少要求2种方案
CHECK(simulcast.rids.size() >= 2);
rtc_media.rtp_rids = simulcast.rids;
} }
if (ssrc_group_sim) { if (ssrc_group_sim) {
//指定了a=ssrc-group:SIM //指定了a=ssrc-group:SIM
for (auto ssrc : ssrc_group_sim->ssrcs) { for (auto ssrc : ssrc_group_sim->ssrcs) {
auto it = rtc_ssrc_map.find(ssrc); auto it = rtc_ssrc_map.find(ssrc);
if (it == rtc_ssrc_map.end()) { CHECK(it != rtc_ssrc_map.end());
throw std::invalid_argument("a=ssrc-group:SIM字段指定的ssrc未找到");
}
rtc_media.rtp_ssrc_sim.emplace_back(it->second); rtc_media.rtp_ssrc_sim.emplace_back(it->second);
} }
} else if (!rtc_media.rtp_rids.empty()) { } else if (!rtc_media.rtp_rids.empty()) {
//未指定a=ssrc-group:SIM但是指定了a=simulcast,且可能指定了ssrc //未指定a=ssrc-group:SIM, 但是指定了a=simulcast, 那么只能根据ssrc顺序来对应rid顺序
for (auto &attr : ssrc_attr) { rtc_media.rtp_ssrc_sim = rtc_media.rtp_rtx_ssrc;
rtc_media.rtp_ssrc_sim.emplace_back(rtc_ssrc_map[attr.ssrc]); }
}
if (!rtc_media.supportSimulcast()) {
//不支持simulcast的情况下最多一组ssrc
CHECK(rtc_media.rtp_rtx_ssrc.size() <= 1);
} else {
//simulcast的情况下要么没有指定ssrc要么指定的ssrc个数与rid个数一致
CHECK(rtc_media.rtp_ssrc_sim.empty() || rtc_media.rtp_ssrc_sim.size() == rtc_media.rtp_rids.size());
} }
auto rtpmap_arr = media.getAllItem<SdpAttrRtpMap>('a', "rtpmap"); auto rtpmap_arr = media.getAllItem<SdpAttrRtpMap>('a', "rtpmap");
@ -1161,43 +1176,56 @@ RtcSessionSdp::Ptr RtcSession::toRtcSessionSdp() const{
static auto addSSRCItem = [](const RtcSSRC &rtp_ssrc, vector<SdpItem::Ptr> &items) { static auto addSSRCItem = [](const RtcSSRC &rtp_ssrc, vector<SdpItem::Ptr> &items) {
CHECK(!rtp_ssrc.empty()); CHECK(!rtp_ssrc.empty());
SdpAttrSSRC ssrc; auto ssrc_num = rtp_ssrc.ssrc;
ssrc.ssrc = rtp_ssrc.ssrc; for (auto i = 0; i < 2; ++i) {
SdpAttrSSRC ssrc;
ssrc.ssrc = ssrc_num;
ssrc.attribute = "cname"; ssrc.attribute = "cname";
ssrc.attribute_value = rtp_ssrc.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))); items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrSSRC>(ssrc)));
}
if (!rtp_ssrc.mslabel.empty()) { if (!rtp_ssrc.msid.empty()) {
ssrc.attribute = "mslabel"; ssrc.attribute = "msid";
ssrc.attribute_value = rtp_ssrc.mslabel; ssrc.attribute_value = rtp_ssrc.msid;
items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrSSRC>(ssrc))); items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrSSRC>(ssrc)));
} }
if (!rtp_ssrc.label.empty()) { if (!rtp_ssrc.mslabel.empty()) {
ssrc.attribute = "label"; ssrc.attribute = "mslabel";
ssrc.attribute_value = rtp_ssrc.label; ssrc.attribute_value = rtp_ssrc.mslabel;
items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrSSRC>(ssrc))); 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 (rtp_ssrc.rtx_ssrc) {
ssrc_num = rtp_ssrc.rtx_ssrc;
} else {
break;
}
} }
}; };
{ {
auto group = std::make_shared<SdpAttrSSRCGroup>();
for (auto &ssrc : m.rtp_rtx_ssrc) { for (auto &ssrc : m.rtp_rtx_ssrc) {
//添加a=ssrc字段 //添加a=ssrc字段
addSSRCItem(ssrc, sdp_media.items); addSSRCItem(ssrc, sdp_media.items);
group->ssrcs.emplace_back(ssrc.ssrc);
} }
if (group->ssrcs.size() >= 2) {
group->type = "FID"; for (auto &ssrc : m.rtp_rtx_ssrc) {
//生成a=ssrc-group:FID字段 //生成a=ssrc-group:FID字段
sdp_media.items.emplace_back(wrapSdpAttr(std::move(group))); if (ssrc.rtx_ssrc) {
//有rtx ssrc
auto group = std::make_shared<SdpAttrSSRCGroup>();
group->type = "FID";
group->ssrcs.emplace_back(ssrc.ssrc);
group->ssrcs.emplace_back(ssrc.rtx_ssrc);
sdp_media.items.emplace_back(wrapSdpAttr(std::move(group)));
}
} }
} }
@ -1205,9 +1233,7 @@ RtcSessionSdp::Ptr RtcSession::toRtcSessionSdp() const{
if (m.rtp_ssrc_sim.size() >= 2) { if (m.rtp_ssrc_sim.size() >= 2) {
//simulcast 要求 2~3路 //simulcast 要求 2~3路
auto group = std::make_shared<SdpAttrSSRCGroup>(); auto group = std::make_shared<SdpAttrSSRCGroup>();
for (auto &ssrc : m.rtp_ssrc_sim) { for (auto &ssrc : m.rtp_ssrc_sim) {
//添加simulcast的ssrc
addSSRCItem(ssrc, sdp_media.items);
group->ssrcs.emplace_back(ssrc.ssrc); group->ssrcs.emplace_back(ssrc.ssrc);
} }
//添加a=ssrc-group:SIM字段 //添加a=ssrc-group:SIM字段
@ -1294,12 +1320,22 @@ uint32_t RtcMedia::getRtpSSRC() const {
} }
uint32_t RtcMedia::getRtxSSRC() const { uint32_t RtcMedia::getRtxSSRC() const {
if (rtp_rtx_ssrc.size() > 1) { if (rtp_rtx_ssrc.size()) {
return rtp_rtx_ssrc[1].ssrc; return rtp_rtx_ssrc[0].rtx_ssrc;
} }
return 0; return 0;
} }
bool RtcMedia::supportSimulcast() const {
if (!rtp_rids.empty()) {
return true;
}
if (!rtp_ssrc_sim.empty()) {
return true;
}
return false;
}
void RtcMedia::checkValid() const{ void RtcMedia::checkValid() const{
CHECK(type != TrackInvalid); CHECK(type != TrackInvalid);
CHECK(!mid.empty()); CHECK(!mid.empty());
@ -1372,15 +1408,13 @@ bool RtcSession::supportRtcpFb(const string &name, TrackType type) const {
bool RtcSession::supportSimulcast() const { bool RtcSession::supportSimulcast() const {
for (auto &m : media) { for (auto &m : media) {
if (!m.rtp_rids.empty()) { if (m.supportSimulcast()) {
return true;
}
if (!m.rtp_ssrc_sim.empty()) {
return true; return true;
} }
} }
return false; return false;
} }
void RtcSession::checkSdp() const { void RtcSession::checkSdp() const {
for (auto &m : media) { for (auto &m : media) {
if (m.type != TrackApplication && !m.rtcp_mux) { if (m.type != TrackApplication && !m.rtcp_mux) {
@ -1636,6 +1670,7 @@ RETRY:
answer_media.candidate = configure.candidate; answer_media.candidate = configure.candidate;
answer_media.rtp_rids = offer_media.rtp_rids; answer_media.rtp_rids = offer_media.rtp_rids;
answer_media.rtp_ssrc_sim = offer_media.rtp_ssrc_sim; answer_media.rtp_ssrc_sim = offer_media.rtp_ssrc_sim;
answer_media.rtp_rtx_ssrc = offer_media.rtp_rtx_ssrc;
switch (offer_media.role) { switch (offer_media.role) {
case DtlsRole::actpass : case DtlsRole::actpass :
case DtlsRole::active : { case DtlsRole::active : {

View File

@ -573,6 +573,7 @@ public:
class RtcSSRC{ class RtcSSRC{
public: public:
uint32_t ssrc {0}; uint32_t ssrc {0};
uint32_t rtx_ssrc {0};
string cname; string cname;
string msid; string msid;
string mslabel; string mslabel;
@ -647,6 +648,7 @@ public:
const RtcCodecPlan *getRelatedRtxPlan(uint8_t pt) const; const RtcCodecPlan *getRelatedRtxPlan(uint8_t pt) const;
uint32_t getRtpSSRC() const; uint32_t getRtpSSRC() const;
uint32_t getRtxSSRC() const; uint32_t getRtxSSRC() const;
bool supportSimulcast() const;
}; };
class RtcSession{ class RtcSession{

View File

@ -539,9 +539,8 @@ void WebRtcTransportImp::onCheckAnswer(RtcSession &sdp) {
m.rtp_rtx_ssrc[0].msid = RTP_MSID; m.rtp_rtx_ssrc[0].msid = RTP_MSID;
if (m.getRelatedRtxPlan(m.plan[0].pt)) { if (m.getRelatedRtxPlan(m.plan[0].pt)) {
m.rtp_rtx_ssrc.emplace_back(); //rtx ssrc
m.rtp_rtx_ssrc[1] = m.rtp_rtx_ssrc[0]; m.rtp_rtx_ssrc[0].rtx_ssrc = m.rtp_rtx_ssrc[0].ssrc + RTX_SSRC_OFFSET;
m.rtp_rtx_ssrc[1].ssrc += RTX_SSRC_OFFSET;
} }
} }
} }