mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-25 12:11:36 +08:00
整理优化webrtc ssrc与simulcast相关代码
This commit is contained in:
parent
fbc5378058
commit
acbe99cb43
163
webrtc/Sdp.cpp
163
webrtc/Sdp.cpp
@ -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 : {
|
||||||
|
@ -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{
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user