diff --git a/webrtc/Sdp.cpp b/webrtc/Sdp.cpp index 7ac165af..70e83730 100644 --- a/webrtc/Sdp.cpp +++ b/webrtc/Sdp.cpp @@ -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(m.addr)); @@ -1201,7 +1201,9 @@ RtcSessionSdp::Ptr RtcSession::toRtcSessionSdp() const{ } } else { - sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared(m.sctpmap))); + if (!m.sctpmap.empty()) { + sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared(m.sctpmap))); + } sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared("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 &ret, TrackType type, const vector &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) diff --git a/webrtc/Sdp.h b/webrtc/Sdp.h index f891aee2..942c5800 100644 --- a/webrtc/Sdp.h +++ b/webrtc/Sdp.h @@ -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 fmts; + std::vector 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 { diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 845f1f0b..21087b23 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -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(); @@ -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(); @@ -399,28 +402,26 @@ void WebRtcTransportImp::onStartWebRTC() { //rtx pt --> MediaTrack _pt_to_track.emplace(track->plan_rtx->pt, std::unique_ptr(new WrappedRtxTrack(track))); } - if (m_offer->type != TrackApplication) { - //记录rtp ext类型与id的关系,方便接收或发送rtp时修改rtp ext id - track->rtp_ext_ctx = std::make_shared(*m_offer); - weak_ptr 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(*m_offer); + weak_ptr 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; } } }