mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-10-30 16:27:36 +08:00
初步实现webrtc datachannel sdp握手
This commit is contained in:
parent
03dfcbad36
commit
1ed793fe97
@ -372,9 +372,7 @@ void SdpMedia::parse(const string &str) {
|
||||
port = atoi(vec[1].data());
|
||||
proto = vec[2];
|
||||
for (size_t i = 3; i < vec.size(); ++i) {
|
||||
auto pt = atoi(vec[i].data());
|
||||
CHECK_SDP(type == TrackApplication || pt <= 0xFF);
|
||||
fmts.emplace_back(pt);
|
||||
fmts.emplace_back(vec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,7 +381,7 @@ string SdpMedia::toString() const {
|
||||
value = string(getTrackString(type)) + " " + to_string(port) + " " + proto;
|
||||
for (auto fmt : fmts) {
|
||||
value += ' ';
|
||||
value += to_string(fmt);
|
||||
value += fmt;
|
||||
}
|
||||
}
|
||||
return SdpItem::toString();
|
||||
@ -921,7 +919,9 @@ void RtcSession::loadFrom(const string &str) {
|
||||
//添加失败,有多条
|
||||
CHECK(fmtp_map.emplace(fmtp.pt, fmtp).second, "该pt存在多条a=fmtp:", (int)fmtp.pt);
|
||||
}
|
||||
for (auto &pt : mline.fmts) {
|
||||
for (auto &item : mline.fmts) {
|
||||
auto pt = atoi(item.c_str());
|
||||
CHECK(pt < 0xFF, "invalid payload type: ", item);
|
||||
//遍历所有编码方案的pt
|
||||
rtc_media.plan.emplace_back();
|
||||
auto &plan = rtc_media.plan.back();
|
||||
@ -1078,10 +1078,10 @@ RtcSessionSdp::Ptr RtcSession::toRtcSessionSdp() const{
|
||||
mline->port = m.port;
|
||||
mline->proto = m.proto;
|
||||
for (auto &p : m.plan) {
|
||||
mline->fmts.emplace_back(p.pt);
|
||||
mline->fmts.emplace_back(to_string(p.pt));
|
||||
}
|
||||
if (m.type == TrackApplication) {
|
||||
mline->fmts.emplace_back(m.sctp_port);
|
||||
mline->fmts.emplace_back("webrtc-datachannel");
|
||||
}
|
||||
sdp_media.items.emplace_back(std::move(mline));
|
||||
sdp_media.items.emplace_back(std::make_shared<SdpConnection>(m.addr));
|
||||
@ -1201,7 +1201,9 @@ RtcSessionSdp::Ptr RtcSession::toRtcSessionSdp() const{
|
||||
}
|
||||
|
||||
} else {
|
||||
sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared<SdpAttrSctpMap>(m.sctpmap)));
|
||||
if (!m.sctpmap.empty()) {
|
||||
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))));
|
||||
}
|
||||
|
||||
@ -1567,6 +1569,15 @@ static RtpDirection matchDirection(RtpDirection offer_direction, RtpDirection su
|
||||
}
|
||||
}
|
||||
|
||||
static DtlsRole mathDtlsRole(DtlsRole role){
|
||||
switch (role) {
|
||||
case DtlsRole::actpass:
|
||||
case DtlsRole::active: return DtlsRole::passive;
|
||||
case DtlsRole::passive: return DtlsRole::active;
|
||||
default: CHECK(0, "invalid role:", getDtlsRoleString(role)); return DtlsRole::passive;
|
||||
}
|
||||
}
|
||||
|
||||
void RtcConfigure::matchMedia(const shared_ptr<RtcSession> &ret, TrackType type, const vector<RtcMedia> &medias, const RtcTrackConfigure &configure){
|
||||
bool check_profile = true;
|
||||
bool check_codec = true;
|
||||
@ -1577,6 +1588,14 @@ RETRY:
|
||||
if (offer_media.type != type) {
|
||||
continue;
|
||||
}
|
||||
if (type == TrackApplication) {
|
||||
RtcMedia answer_media = offer_media;
|
||||
answer_media.role = mathDtlsRole(offer_media.role);
|
||||
answer_media.direction = matchDirection(offer_media.direction, configure.direction);
|
||||
answer_media.candidate = configure.candidate;
|
||||
ret->media.emplace_back(answer_media);
|
||||
return;
|
||||
}
|
||||
for (auto &codec : configure.preferred_codec) {
|
||||
if (offer_media.ice_lite && configure.ice_lite) {
|
||||
WarnL << "answer sdp配置为ice_lite模式,与offer sdp中的ice_lite模式冲突";
|
||||
@ -1617,18 +1636,7 @@ RETRY:
|
||||
answer_media.ice_lite = configure.ice_lite;
|
||||
answer_media.candidate = configure.candidate;
|
||||
answer_media.rtp_rids = offer_media.rtp_rids;
|
||||
switch (offer_media.role) {
|
||||
case DtlsRole::actpass :
|
||||
case DtlsRole::active : {
|
||||
answer_media.role = DtlsRole::passive;
|
||||
break;
|
||||
}
|
||||
case DtlsRole::passive : {
|
||||
answer_media.role = DtlsRole::active;
|
||||
break;
|
||||
}
|
||||
default: continue;
|
||||
}
|
||||
answer_media.role = mathDtlsRole(offer_media.role);
|
||||
|
||||
//如果codec匹配失败,那么禁用该track
|
||||
answer_media.direction = check_codec ? matchDirection(offer_media.direction, configure.direction)
|
||||
|
@ -196,7 +196,7 @@ public:
|
||||
//RTP/AVPF: 应用场景为视频/音频的 RTP 协议,支持 RTCP-based Feedback。参考 RFC 4585
|
||||
//RTP/SAVPF: 应用场景为视频/音频的 SRTP 协议,支持 RTCP-based Feedback。参考 RFC 5124
|
||||
std::string proto;
|
||||
std::vector<uint32_t> fmts;
|
||||
std::vector<std::string> fmts;
|
||||
|
||||
void parse(const std::string &str) override;
|
||||
std::string toString() const override;
|
||||
@ -426,12 +426,13 @@ public:
|
||||
//https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-05
|
||||
//a=sctpmap:5000 webrtc-datachannel 1024
|
||||
//a=sctpmap: sctpmap-number media-subtypes [streams]
|
||||
uint16_t port;
|
||||
uint16_t port = 0;
|
||||
std::string subtypes;
|
||||
uint32_t streams;
|
||||
uint32_t streams = 0;
|
||||
void parse(const std::string &str) override;
|
||||
std::string toString() const override;
|
||||
const char* getKey() const override { return "sctpmap";}
|
||||
bool empty() const { return port == 0 && subtypes.empty() && streams == 0; }
|
||||
};
|
||||
|
||||
class SdpAttrCandidate : public SdpItem {
|
||||
|
@ -368,6 +368,9 @@ bool WebRtcTransportImp::canRecvRtp() const{
|
||||
void WebRtcTransportImp::onStartWebRTC() {
|
||||
//获取ssrc和pt相关信息,届时收到rtp和rtcp时分别可以根据pt和ssrc找到相关的信息
|
||||
for (auto &m_answer : _answer_sdp->media) {
|
||||
if (m_answer.type == TrackApplication) {
|
||||
continue;
|
||||
}
|
||||
auto m_offer = _offer_sdp->getMedia(m_answer.type);
|
||||
auto track = std::make_shared<MediaTrack>();
|
||||
|
||||
@ -376,7 +379,7 @@ void WebRtcTransportImp::onStartWebRTC() {
|
||||
track->answer_ssrc_rtx = m_answer.getRtxSSRC();
|
||||
track->offer_ssrc_rtp = m_offer->getRtpSSRC();
|
||||
track->offer_ssrc_rtx = m_offer->getRtxSSRC();
|
||||
track->plan_rtp = &m_answer.plan[0];;
|
||||
track->plan_rtp = &m_answer.plan[0];
|
||||
track->plan_rtx = m_answer.getRelatedRtxPlan(track->plan_rtp->pt);
|
||||
track->rtcp_context_send = std::make_shared<RtcpContextForSend>();
|
||||
|
||||
@ -399,28 +402,26 @@ void WebRtcTransportImp::onStartWebRTC() {
|
||||
//rtx pt --> MediaTrack
|
||||
_pt_to_track.emplace(track->plan_rtx->pt, std::unique_ptr<WrappedMediaTrack>(new WrappedRtxTrack(track)));
|
||||
}
|
||||
if (m_offer->type != TrackApplication) {
|
||||
//记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id
|
||||
track->rtp_ext_ctx = std::make_shared<RtpExtContext>(*m_offer);
|
||||
weak_ptr<MediaTrack> weak_track = track;
|
||||
track->rtp_ext_ctx->setOnGetRtp([this, weak_track](uint8_t pt, uint32_t ssrc, const string &rid) {
|
||||
//ssrc --> MediaTrack
|
||||
auto track = weak_track.lock();
|
||||
assert(track);
|
||||
_ssrc_to_track[ssrc] = std::move(track);
|
||||
InfoL << "get rtp, pt:" << (int) pt << ", ssrc:" << ssrc << ", rid:" << rid;
|
||||
});
|
||||
//记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id
|
||||
track->rtp_ext_ctx = std::make_shared<RtpExtContext>(*m_offer);
|
||||
weak_ptr<MediaTrack> weak_track = track;
|
||||
track->rtp_ext_ctx->setOnGetRtp([this, weak_track](uint8_t pt, uint32_t ssrc, const string &rid) {
|
||||
//ssrc --> MediaTrack
|
||||
auto track = weak_track.lock();
|
||||
assert(track);
|
||||
_ssrc_to_track[ssrc] = std::move(track);
|
||||
InfoL << "get rtp, pt:" << (int) pt << ", ssrc:" << ssrc << ", rid:" << rid;
|
||||
});
|
||||
|
||||
size_t index = 0;
|
||||
for (auto &ssrc : m_offer->rtp_ssrc_sim) {
|
||||
//记录ssrc对应的MediaTrack
|
||||
_ssrc_to_track[ssrc.ssrc] = track;
|
||||
if (m_offer->rtp_rids.size() > index) {
|
||||
//支持firefox的simulcast, 提前映射好ssrc和rid的关系
|
||||
track->rtp_ext_ctx->setRid(ssrc.ssrc, m_offer->rtp_rids[index]);
|
||||
}
|
||||
++index;
|
||||
size_t index = 0;
|
||||
for (auto &ssrc : m_offer->rtp_ssrc_sim) {
|
||||
//记录ssrc对应的MediaTrack
|
||||
_ssrc_to_track[ssrc.ssrc] = track;
|
||||
if (m_offer->rtp_rids.size() > index) {
|
||||
//支持firefox的simulcast, 提前映射好ssrc和rid的关系
|
||||
track->rtp_ext_ctx->setRid(ssrc.ssrc, m_offer->rtp_rids[index]);
|
||||
}
|
||||
++index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user