diff --git a/conf/config.ini b/conf/config.ini index aaff9999..bc2286b4 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -264,6 +264,8 @@ audioMtuSize=600 videoMtuSize=1400 #rtp包最大长度限制,单位KB,主要用于识别TCP上下文破坏时,获取到错误的rtp rtpMaxSize=10 +# rtp 打包时,低延迟开关,默认关闭(为0),h264存在一帧多个slice(NAL)的情况,在这种情况下,如果开启可能会导致画面花屏 +lowLatency=0 [rtp_proxy] #导出调试数据(包括rtp/ps/h264)至该目录,置空则关闭数据导出 @@ -352,7 +354,8 @@ keepAliveSecond=15 port=554 #rtsps服务器监听地址 sslport=0 - +#rtsp 转发是否使用低延迟模式,当开启时,不会缓存rtp包,来提高并发,可以降低一帧的延迟 +lowLatency=0 [shell] #调试telnet服务器接受最大bufffer大小 maxReqSize=1024 diff --git a/src/Common/MediaSource.h b/src/Common/MediaSource.h index 8fbff060..fe61d685 100644 --- a/src/Common/MediaSource.h +++ b/src/Common/MediaSource.h @@ -398,6 +398,12 @@ private: //但是却对性能提升很大,这样做还是比较划算的 GET_CONFIG(int, mergeWriteMS, General::kMergeWriteMS); + + GET_CONFIG(int, rtspLowLatency, Rtsp::kLowLatency); + if(std::is_same::value && rtspLowLatency){ + return true; + } + return std::is_same::value ? false : (mergeWriteMS <= 0); } diff --git a/src/Common/config.cpp b/src/Common/config.cpp index fa66c450..9f5976e2 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -173,6 +173,7 @@ const string kAuthBasic = RTSP_FIELD "authBasic"; const string kHandshakeSecond = RTSP_FIELD "handshakeSecond"; const string kKeepAliveSecond = RTSP_FIELD "keepAliveSecond"; const string kDirectProxy = RTSP_FIELD "directProxy"; +const string kLowLatency = RTSP_FIELD"lowLatency"; static onceToken token([]() { // 默认Md5方式认证 @@ -180,6 +181,7 @@ static onceToken token([]() { mINI::Instance()[kHandshakeSecond] = 15; mINI::Instance()[kKeepAliveSecond] = 15; mINI::Instance()[kDirectProxy] = 1; + mINI::Instance()[kLowLatency] = 0; }); } // namespace Rtsp @@ -206,10 +208,14 @@ const string kAudioMtuSize = RTP_FIELD "audioMtuSize"; // rtp包最大长度限制,单位是KB const string kRtpMaxSize = RTP_FIELD "rtpMaxSize"; +const string kLowLatency = RTP_FIELD "lowLatency"; + static onceToken token([]() { mINI::Instance()[kVideoMtuSize] = 1400; mINI::Instance()[kAudioMtuSize] = 600; mINI::Instance()[kRtpMaxSize] = 10; + mINI::Instance()[kLowLatency] = 0; + }); } // namespace Rtp diff --git a/src/Common/config.h b/src/Common/config.h index 65176b5e..312878b6 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -251,6 +251,9 @@ extern const std::string kKeepAliveSecond; // 假定您的拉流源地址不是264或265或AAC,那么你可以使用直接代理的方式来支持rtsp代理 // 默认开启rtsp直接代理,rtmp由于没有这些问题,是强制开启直接代理的 extern const std::string kDirectProxy; + +// rtsp 转发是否使用低延迟模式,当开启时,不会缓存rtp包,来提高并发,可以降低一帧的延迟 +extern const std::string kLowLatency; } // namespace Rtsp ////////////RTMP服务器配置/////////// @@ -271,6 +274,8 @@ extern const std::string kVideoMtuSize; extern const std::string kAudioMtuSize; // rtp包最大长度限制, 单位KB extern const std::string kRtpMaxSize; +// rtp 打包时,低延迟开关,默认关闭(为0),h264存在一帧多个slice(NAL)的情况,在这种情况下,如果开启可能会导致画面花屏 +extern const std::string kLowLatency; } // namespace Rtp ////////////组播配置/////////// diff --git a/src/Extension/H264Rtp.cpp b/src/Extension/H264Rtp.cpp index a5331e26..1130102f 100644 --- a/src/Extension/H264Rtp.cpp +++ b/src/Extension/H264Rtp.cpp @@ -283,11 +283,19 @@ bool H264RtpEncoder::inputFrame(const Frame::Ptr &frame) { default: break; } - if (_last_frame) { - //如果时间戳发生了变化,那么markbit才置true - inputFrame_l(_last_frame, _last_frame->pts() != frame->pts()); + GET_CONFIG(int,lowLatency,Rtp::kLowLatency); + if (lowLatency) { // 低延迟模式 + if (_last_frame) { + flush(); + } + inputFrame_l(frame, true); + } else { + if (_last_frame) { + //如果时间戳发生了变化,那么markbit才置true + inputFrame_l(_last_frame, _last_frame->pts() != frame->pts()); + } + _last_frame = Frame::getCacheAbleFrame(frame); } - _last_frame = Frame::getCacheAbleFrame(frame); return true; }