diff --git a/webrtc/Sdp.cpp b/webrtc/Sdp.cpp index 8b5930c3..29c67e1e 100644 --- a/webrtc/Sdp.cpp +++ b/webrtc/Sdp.cpp @@ -1034,15 +1034,17 @@ string RtcSession::toRtspSdp() const{ switch (m.type) { case TrackAudio: case TrackVideo: { - copy.media.emplace_back(m); - copy.media.back().plan.resize(1); + if (m.direction != RtpDirection::inactive) { + copy.media.emplace_back(m); + copy.media.back().plan.resize(1); + } break; } - default: - continue; + default: continue; } } + CHECK(!copy.media.empty()); auto sdp = copy.toRtcSessionSdp(); toRtsp(sdp->items); int i = 0; @@ -1368,6 +1370,18 @@ bool RtcSession::supportRtcpFb(const string &name, TrackType type) const { return ref.find(name) != ref.end(); } +bool RtcSession::supportSimulcast() const { + for (auto &m : media) { + if (!m.rtp_rids.empty()) { + return true; + } + if (!m.rtp_ssrc_sim.empty()) { + return true; + } + } + return false; +} + string const SdpConst::kTWCCRtcpFb = "transport-cc"; string const SdpConst::kRembRtcpFb = "goog-remb"; diff --git a/webrtc/Sdp.h b/webrtc/Sdp.h index 6ed2710a..614cfd50 100644 --- a/webrtc/Sdp.h +++ b/webrtc/Sdp.h @@ -673,6 +673,7 @@ public: const RtcMedia *getMedia(TrackType type) const; bool haveSSRC() const; bool supportRtcpFb(const string &name, TrackType type = TrackType::TrackVideo) const; + bool supportSimulcast() const; private: RtcSessionSdp::Ptr toRtcSessionSdp() const; diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 1a0616b1..27c9c2e0 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -448,6 +448,7 @@ void WebRtcTransportImp::onStartWebRTC() { if (canRecvRtp()) { _push_src->setSdp(getSdp(SdpType::answer).toRtspSdp()); + _simulcast = getSdp(SdpType::answer).supportSimulcast(); } if (canSendRtp()) { _reader = _play_src->getRing()->attach(getPoller(), true); @@ -794,25 +795,29 @@ void WebRtcTransportImp::onSortedRtp(MediaTrack &track, const string &rid, RtpPa } } - if (_push_src) { - if (rtp->type == TrackAudio) { - //音频 - for (auto &pr : _push_src_simulcast) { - pr.second->onWrite(rtp, false); - } - } else { - //视频 - auto &src = _push_src_simulcast[rid]; - if (!src) { - auto stream_id = rid.empty() ? _push_src->getId() : _push_src->getId() + "_" + rid; - auto src_imp = std::make_shared(_push_src->getVhost(), _push_src->getApp(), stream_id); - src_imp->setSdp(_push_src->getSdp()); - src_imp->setProtocolTranslation(_push_src->isRecording(Recorder::type_hls),_push_src->isRecording(Recorder::type_mp4)); - src_imp->setListener(shared_from_this()); - src = src_imp; - } - src->onWrite(std::move(rtp), false); + if (!_simulcast) { + assert(_push_src); + _push_src->onWrite(rtp, false); + return; + } + + if (rtp->type == TrackAudio) { + //音频 + for (auto &pr : _push_src_simulcast) { + pr.second->onWrite(rtp, false); } + } else { + //视频 + auto &src = _push_src_simulcast[rid]; + if (!src) { + auto stream_id = rid.empty() ? _push_src->getId() : _push_src->getId() + "_" + rid; + auto src_imp = std::make_shared(_push_src->getVhost(), _push_src->getApp(), stream_id); + src_imp->setSdp(_push_src->getSdp()); + src_imp->setProtocolTranslation(_push_src->isRecording(Recorder::type_hls),_push_src->isRecording(Recorder::type_mp4)); + src_imp->setListener(shared_from_this()); + src = src_imp; + } + src->onWrite(std::move(rtp), false); } } @@ -901,7 +906,7 @@ int WebRtcTransportImp::totalReaderCount(MediaSource &sender) { for (auto &src : _push_src_simulcast) { total_count += src.second->totalReaderCount(); } - return total_count; + return total_count + _push_src->totalReaderCount(); } MediaOriginType WebRtcTransportImp::getOriginType(MediaSource &sender) const { diff --git a/webrtc/WebRtcTransport.h b/webrtc/WebRtcTransport.h index 5e3523f1..30ba2f95 100644 --- a/webrtc/WebRtcTransport.h +++ b/webrtc/WebRtcTransport.h @@ -219,6 +219,7 @@ private: void createRtpChannel(const string &rid, uint32_t ssrc, const MediaTrack::Ptr &track); private: + bool _simulcast = false; uint16_t _rtx_seq[2] = {0, 0}; //用掉的总流量 uint64_t _bytes_usage = 0;