diff --git a/conf/config.ini b/conf/config.ini index 348b134d..0abe303a 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -281,6 +281,9 @@ videoMtuSize=1400 rtpMaxSize=10 # rtp 打包时,低延迟开关,默认关闭(为0),h264存在一帧多个slice(NAL)的情况,在这种情况下,如果开启可能会导致画面花屏 lowLatency=0 +# H264 rtp打包模式是否采用stap-a模式(为了在老版本浏览器上兼容webrtc)还是采用Single NAL unit packet per H.264 模式 +# 有些老的rtsp设备不支持stap-a rtp,设置此配置为0可提高兼容性 +h264_stap_a=1 [rtp_proxy] #导出调试数据(包括rtp/ps/h264)至该目录,置空则关闭数据导出 diff --git a/src/Common/config.cpp b/src/Common/config.cpp index 5783b54c..3d79d894 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -244,15 +244,15 @@ const string kVideoMtuSize = RTP_FIELD "videoMtuSize"; const string kAudioMtuSize = RTP_FIELD "audioMtuSize"; // rtp包最大长度限制,单位是KB const string kRtpMaxSize = RTP_FIELD "rtpMaxSize"; - const string kLowLatency = RTP_FIELD "lowLatency"; +const string kH264StapA = RTP_FIELD "h264_stap_a"; static onceToken token([]() { mINI::Instance()[kVideoMtuSize] = 1400; mINI::Instance()[kAudioMtuSize] = 600; mINI::Instance()[kRtpMaxSize] = 10; mINI::Instance()[kLowLatency] = 0; - + mINI::Instance()[kH264StapA] = 1; }); } // namespace Rtp diff --git a/src/Common/config.h b/src/Common/config.h index 74ea5d71..fb998cd5 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -298,6 +298,8 @@ extern const std::string kAudioMtuSize; extern const std::string kRtpMaxSize; // rtp 打包时,低延迟开关,默认关闭(为0),h264存在一帧多个slice(NAL)的情况,在这种情况下,如果开启可能会导致画面花屏 extern const std::string kLowLatency; +//H264 rtp打包模式是否采用stap-a模式(为了在老版本浏览器上兼容webrtc)还是采用Single NAL unit packet per H.264 模式 +extern const std::string kH264StapA; } // namespace Rtp ////////////组播配置/////////// diff --git a/src/Extension/H264Rtp.cpp b/src/Extension/H264Rtp.cpp index f12218a4..eae8edd1 100644 --- a/src/Extension/H264Rtp.cpp +++ b/src/Extension/H264Rtp.cpp @@ -209,8 +209,8 @@ void H264RtpEncoder::insertConfigFrame(uint64_t pts){ void H264RtpEncoder::packRtp(const char *ptr, size_t len, uint64_t pts, bool is_mark, bool gop_pos){ if (len + 3 <= getMaxSize()) { - //STAP-A模式打包小于MTU - packRtpStapA(ptr, len, pts, is_mark, gop_pos); + // 采用STAP-A/Single NAL unit packet per H.264 模式 + packRtpSmallFrame(ptr, len, pts, is_mark, gop_pos); } else { //STAP-A模式打包会大于MTU,所以采用FU-A模式 packRtpFu(ptr, len, pts, is_mark, gop_pos); @@ -220,8 +220,8 @@ void H264RtpEncoder::packRtp(const char *ptr, size_t len, uint64_t pts, bool is_ void H264RtpEncoder::packRtpFu(const char *ptr, size_t len, uint64_t pts, bool is_mark, bool gop_pos){ auto packet_size = getMaxSize() - 2; if (len <= packet_size + 1) { - //小于FU-A打包最小字节长度要求,采用STAP-A模式 - packRtpStapA(ptr, len, pts, is_mark, gop_pos); + // 小于FU-A打包最小字节长度要求,采用STAP-A/Single NAL unit packet per H.264 模式 + packRtpSmallFrame(ptr, len, pts, is_mark, gop_pos); return; } @@ -257,8 +257,17 @@ void H264RtpEncoder::packRtpFu(const char *ptr, size_t len, uint64_t pts, bool i } } +void H264RtpEncoder::packRtpSmallFrame(const char *data, size_t len, uint64_t pts, bool is_mark, bool gop_pos) { + GET_CONFIG(bool, h264_stap_a, Rtp::kH264StapA); + if (h264_stap_a) { + packRtpStapA(data, len, pts, is_mark, gop_pos); + } else { + packRtpSingleNalu(data, len, pts, is_mark, gop_pos); + } +} + void H264RtpEncoder::packRtpStapA(const char *ptr, size_t len, uint64_t pts, bool is_mark, bool gop_pos){ - //如果帧长度不超过mtu,为了兼容性 webrtc,采用STAP-A模式打包 + // 如果帧长度不超过mtu,为了兼容性 webrtc,采用STAP-A模式打包 auto rtp = makeRtp(getTrackType(), nullptr, len + 3, is_mark, pts); uint8_t *payload = rtp->getPayload(); //STAP-A @@ -270,6 +279,11 @@ void H264RtpEncoder::packRtpStapA(const char *ptr, size_t len, uint64_t pts, boo RtpCodec::inputRtp(rtp, gop_pos); } +void H264RtpEncoder::packRtpSingleNalu(const char *data, size_t len, uint64_t pts, bool is_mark, bool gop_pos) { + // Single NAL unit packet per H.264 模式 + RtpCodec::inputRtp(makeRtp(getTrackType(), data, len, is_mark, pts), gop_pos); +} + bool H264RtpEncoder::inputFrame(const Frame::Ptr &frame) { auto ptr = frame->data() + frame->prefixSize(); switch (H264_TYPE(ptr[0])) { diff --git a/src/Extension/H264Rtp.h b/src/Extension/H264Rtp.h index 77bca5d0..31200cb8 100644 --- a/src/Extension/H264Rtp.h +++ b/src/Extension/H264Rtp.h @@ -28,7 +28,7 @@ public: using Ptr = std::shared_ptr; H264RtpDecoder(); - ~H264RtpDecoder() {} + ~H264RtpDecoder() override = default; /** * 输入264 rtp包 @@ -77,9 +77,10 @@ public: uint32_t sample_rate = 90000, uint8_t pt = 96, uint8_t interleaved = TrackVideo * 2); - ~H264RtpEncoder() {} - /** + ~H264RtpEncoder() override = default; + + /** * 输入264帧 * @param frame 帧数据,必须 */ @@ -96,6 +97,8 @@ private: void packRtp(const char *data, size_t len, uint64_t pts, bool is_mark, bool gop_pos); void packRtpFu(const char *data, size_t len, uint64_t pts, bool is_mark, bool gop_pos); void packRtpStapA(const char *data, size_t len, uint64_t pts, bool is_mark, bool gop_pos); + void packRtpSingleNalu(const char *data, size_t len, uint64_t pts, bool is_mark, bool gop_pos); + void packRtpSmallFrame(const char *data, size_t len, uint64_t pts, bool is_mark, bool gop_pos); private: Frame::Ptr _sps;