From fb491f3e7914968d5ace65cbf5c063b334b90bae Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Fri, 9 Jan 2026 11:39:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9Ewebrtc=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E9=80=89=E9=A1=B9nackAudioRtpSize=E3=80=81preferred=5Ftcp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit nackAudioRtpSize: 音频nack包中rtp个数,减小此值可以让nack包响应更灵敏 preferred_tcp: 是否优先采用webrtc over tcp模式 --- conf/config.ini | 6 +++++- webrtc/IceTransport.cpp | 2 +- webrtc/Nack.cpp | 9 +++++++-- webrtc/Nack.h | 3 ++- webrtc/WebRtcTransport.cpp | 19 +++++++++++++------ webrtc/WebRtcTransport.h | 2 +- 6 files changed, 29 insertions(+), 12 deletions(-) diff --git a/conf/config.ini b/conf/config.ini index 344118bc..907f7882 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -412,10 +412,14 @@ nackMaxMS=3000 nackMaxCount=15 #nack重传频率,rtt的倍数 nackIntervalRatio=1.0 -#nack包中rtp个数,减小此值可以让nack包响应更灵敏 +#视频nack包中rtp个数,减小此值可以让nack包响应更灵敏 nackRtpSize=8 +#音频nack包中rtp个数,减小此值可以让nack包响应更灵敏 +nackAudioRtpSize=4 #是否尝试过滤 b帧 bfilter=0 +# 是否优先采用webrtc over tcp模式 +preferred_tcp=0 [srt] #srt播放推流、播放超时时间,单位秒 diff --git a/webrtc/IceTransport.cpp b/webrtc/IceTransport.cpp index c946b54e..84eecdca 100644 --- a/webrtc/IceTransport.cpp +++ b/webrtc/IceTransport.cpp @@ -1175,7 +1175,7 @@ void IceAgent::connectivityCheck(const Pair::Ptr &pair, CandidateTuple& candidat } void IceAgent::tryTriggerredCheck(const Pair::Ptr& pair) { - DebugL; + // DebugL; //FIXME 暂不实现,因为当前实现基本收到candidate就会发起check } diff --git a/webrtc/Nack.cpp b/webrtc/Nack.cpp index bb61d5af..82f03552 100644 --- a/webrtc/Nack.cpp +++ b/webrtc/Nack.cpp @@ -46,6 +46,7 @@ const string kNackIntervalRatio = RTC_FIELD "nackIntervalRatio"; // nack包中rtp个数,减小此值可以让nack包响应更灵敏 [AUTO-TRANSLATED:12393868] // Number of rtp in nack packet, reducing this value can make nack packet response more sensitive const string kNackRtpSize = RTC_FIELD "nackRtpSize"; +const string kNackAudioRtpSize = RTC_FIELD "nackAudioRtpSize"; static onceToken token([]() { mINI::Instance()[kMaxRtpCacheMS] = 5 * 1000; @@ -55,6 +56,7 @@ static onceToken token([]() { mINI::Instance()[kNackMaxCount] = 15; mINI::Instance()[kNackIntervalRatio] = 1.0f; mINI::Instance()[kNackRtpSize] = 8; + mINI::Instance()[kNackAudioRtpSize] = 4; }); } // namespace Rtc @@ -155,7 +157,8 @@ int64_t NackList::getNtpStamp(uint16_t seq) { //////////////////////////////////////////////////////////////////////////////////////////////// -NackContext::NackContext() { +NackContext::NackContext(TrackType type) { + _type = type; setOnNack(nullptr); } @@ -217,7 +220,9 @@ void NackContext::makeNack(uint16_t max_seq, bool flush) { // 最多生成5个nack包,防止seq大幅跳跃导致一直循环 [AUTO-TRANSLATED:9cc5da25] // Generate at most 5 nack packets to prevent seq from jumping significantly and causing continuous loops auto max_nack = 5u; - GET_CONFIG(uint32_t, nack_rtpsize, Rtc::kNackRtpSize); + GET_CONFIG(uint32_t, nack_video_rtpsize, Rtc::kNackRtpSize); + GET_CONFIG(uint32_t, nack_audio_rtpsize, Rtc::kNackAudioRtpSize); + auto nack_rtpsize = _type == TrackVideo ? nack_video_rtpsize : nack_audio_rtpsize; // kNackRtpSize must between 0 and 16 nack_rtpsize = std::min(nack_rtpsize, FCI_NACK::kBitSize); while (_nack_seq != max_seq && max_nack--) { diff --git a/webrtc/Nack.h b/webrtc/Nack.h index 49a768af..87fc4c59 100644 --- a/webrtc/Nack.h +++ b/webrtc/Nack.h @@ -55,7 +55,7 @@ public: using Ptr = std::shared_ptr; using onNack = std::function; - NackContext(); + NackContext(TrackType type = TrackVideo); void received(uint16_t seq, bool is_rtx = false); void setOnNack(onNack cb); @@ -71,6 +71,7 @@ private: private: bool _started = false; int _rtt = 50; + TrackType _type; onNack _cb; std::set _seq; // 最新nack包中的rtp seq值 [AUTO-TRANSLATED:6984d95a] diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 2ad0fb10..6cbfadff 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -82,6 +82,7 @@ const string kMinBitrate = RTC_FIELD "min_bitrate"; // 数据通道设置 [AUTO-TRANSLATED:2dc48bc3] // Data channel setting const string kDataChannelEcho = RTC_FIELD "datachannel_echo"; +const string kPreferredTcp = RTC_FIELD "preferred_tcp"; static onceToken token([]() { mINI::Instance()[kTimeOutSec] = 15; @@ -105,6 +106,7 @@ static onceToken token([]() { mINI::Instance()[kIceTransportPolicy] = 0; // 默认值:不限制(kAll) mINI::Instance()[kIceUfrag] = "ZLMediaKit"; mINI::Instance()[kIcePwd] = "ZLMediaKit"; + mINI::Instance()[kPreferredTcp] = 0; }); } // namespace Rtc @@ -1102,7 +1104,7 @@ void WebRtcTransportImp::setIceCandidate(vector cands) { class RtpChannel : public RtpTrackImp, public std::enable_shared_from_this { public: - RtpChannel(EventPoller::Ptr poller, RtpTrackImp::OnSorted cb, function on_nack) { + RtpChannel(TrackType type, EventPoller::Ptr poller, RtpTrackImp::OnSorted cb, function on_nack) : _nack_ctx(type){ _poller = std::move(poller); _on_nack = std::move(on_nack); setOnSorted(std::move(cb)); @@ -1314,7 +1316,7 @@ void WebRtcTransportImp::createRtpChannel(const string &rid, uint32_t ssrc, Medi // rid --> RtpReceiverImp auto &ref = track.rtp_channel[rid]; weak_ptr weak_self = static_pointer_cast(shared_from_this()); - ref = std::make_shared( + ref = std::make_shared(track.media->type, getPoller(), [&track, this, rid](RtpPacket::Ptr rtp) mutable { onSortedRtp(track, rid, std::move(rtp)); }, [&track, weak_self, ssrc](const FCI_NACK &nack) mutable { // nack发送可能由定时器异步触发 [AUTO-TRANSLATED:186d6723] @@ -1631,6 +1633,7 @@ WebRtcPluginManager &WebRtcPluginManager::Instance() { } void WebRtcPluginManager::registerPlugin(const string &type, Plugin cb) { + InfoL << "Load webrtc plugin:" << type; lock_guard lck(_mtx_creator); _map_creator[type] = std::move(cb); } @@ -1667,6 +1670,7 @@ void echo_plugin(SocketHelper& sender, const WebRtcArgs &args, const onCreateWeb cb(*WebRtcEchoTest::create(EventPollerPool::Instance().getPoller())); } +template void push_plugin(SocketHelper& sender, const WebRtcArgs &args, const onCreateWebRtc &cb) { MediaInfo info(args["url"]); Broadcast::PublishAuthInvoker invoker = [cb, info](const string &err, const ProtocolOption &option) mutable { @@ -1711,7 +1715,7 @@ void push_plugin(SocketHelper& sender, const WebRtcArgs &args, const onCreateWeb push_src_ownership = push_src->getOwnership(); push_src->setProtocolOption(option); } - auto rtc = WebRtcPusher::create(EventPollerPool::Instance().getPoller(), push_src, push_src_ownership, info, option, + auto rtc = Type::create(EventPollerPool::Instance().getPoller(), push_src, push_src_ownership, info, option, WebRtcTransport::Role::PEER, WebRtcTransport::SignalingProtocols::WHEP_WHIP); push_src->setListener(rtc); cb(*rtc); @@ -1782,9 +1786,12 @@ static void setWebRtcArgs(const WebRtcArgs &args, WebRtcInterface &rtc) { } } - bool preferred_tcp = args["preferred_tcp"]; - { + auto preferred_tcp = args["preferred_tcp"]; + if (!preferred_tcp.empty()) { rtc.setPreferredTcp(preferred_tcp); + } else { + GET_CONFIG(bool, s_preferred_tcp, Rtc::kPreferredTcp); + rtc.setPreferredTcp(s_preferred_tcp); } { @@ -1832,7 +1839,7 @@ static onceToken s_rtc_auto_register([]() { // Enable echo plugin only in debug mode WebRtcPluginManager::Instance().registerPlugin("echo", echo_plugin); #endif - WebRtcPluginManager::Instance().registerPlugin("push", push_plugin); + WebRtcPluginManager::Instance().registerPlugin("push", push_plugin); WebRtcPluginManager::Instance().registerPlugin("play", play_plugin); WebRtcPluginManager::Instance().registerPlugin("talk", play_plugin); diff --git a/webrtc/WebRtcTransport.h b/webrtc/WebRtcTransport.h index 7f254a19..d18bb557 100644 --- a/webrtc/WebRtcTransport.h +++ b/webrtc/WebRtcTransport.h @@ -286,7 +286,7 @@ public: struct WrappedMediaTrack { MediaTrack::Ptr track; - explicit WrappedMediaTrack(MediaTrack::Ptr ptr): track(ptr) {} + explicit WrappedMediaTrack(MediaTrack::Ptr ptr): track(std::move(ptr)) {} virtual ~WrappedMediaTrack() {} virtual void inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) = 0; };