From dcde554907b0843063a51ce6b84a4d90c30ace64 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 15 Jun 2025 09:23:55 -0400 Subject: [PATCH] Debugging: Drop the specified N original SRTP packet for testing NACK. --- trunk/auto/auto_headers.sh | 6 ++++++ trunk/auto/options.sh | 4 ++++ trunk/src/app/srs_app_rtc_network.cpp | 15 +++++++++++++++ trunk/src/app/srs_app_rtc_source.cpp | 3 +++ trunk/src/kernel/srs_kernel_rtc_rtp.cpp | 7 +++++++ trunk/src/kernel/srs_kernel_rtc_rtp.hpp | 11 +++++++++++ 6 files changed, 46 insertions(+) diff --git a/trunk/auto/auto_headers.sh b/trunk/auto/auto_headers.sh index 34428955e..5a85fd2a2 100755 --- a/trunk/auto/auto_headers.sh +++ b/trunk/auto/auto_headers.sh @@ -239,6 +239,12 @@ else srs_undefine_macro "SRS_DEBUG_STATS" $SRS_AUTO_HEADERS_H fi +if [[ $SRS_DEBUG_NACK_DROP == YES ]]; then + srs_define_macro "SRS_DEBUG_NACK_DROP" $SRS_AUTO_HEADERS_H +else + srs_undefine_macro "SRS_DEBUG_NACK_DROP" $SRS_AUTO_HEADERS_H +fi + # prefix echo "" >> $SRS_AUTO_HEADERS_H echo "#define SRS_PREFIX \"${SRS_PREFIX}\"" >> $SRS_AUTO_HEADERS_H diff --git a/trunk/auto/options.sh b/trunk/auto/options.sh index 64501f552..9a186f462 100755 --- a/trunk/auto/options.sh +++ b/trunk/auto/options.sh @@ -131,6 +131,7 @@ SRS_NASM=YES SRS_SRTP_ASM=YES SRS_DEBUG=NO SRS_DEBUG_STATS=NO +SRS_DEBUG_NACK_DROP=NO ##################################################################################### function apply_system_options() { @@ -244,6 +245,7 @@ Experts: --build-tag= Set the build object directory suffix. --debug=on|off Whether enable the debug code, may hurt performance. Default: $(value2switch $SRS_DEBUG) --debug-stats=on|off Whether enable the debug stats, may hurt performance. Default: $(value2switch $SRS_DEBUG_STATS) + --debug-nack-drop=on|off Whether enable the debug nack drop, always drop the first number N packet. Default: $(value2switch $SRS_DEBUG_NACK_DROP) --gcov=on|off Whether enable the GCOV for coverage. Default: $(value2switch $SRS_GCOV) --log-verbose=on|off Whether enable the log verbose level. Default: $(value2switch $SRS_LOG_VERBOSE) --log-info=on|off Whether enable the log info level. Default: $(value2switch $SRS_LOG_INFO) @@ -388,6 +390,7 @@ function parse_user_option() { --log-level_v2) SRS_LOG_LEVEL_V2=$(switch2value $value) ;; --debug) SRS_DEBUG=$(switch2value $value) ;; --debug-stats) SRS_DEBUG_STATS=$(switch2value $value) ;; + --debug-nack-drop) SRS_DEBUG_NACK_DROP=$(switch2value $value) ;; --cross-build) SRS_CROSS_BUILD=YES ;; --generic-linux) SRS_GENERIC_LINUX=$(switch2value $value) ;; @@ -683,6 +686,7 @@ function regenerate_options() { SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --apm=$(value2switch $SRS_APM)" SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --debug=$(value2switch $SRS_DEBUG)" SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --debug-stats=$(value2switch $SRS_DEBUG_STATS)" + SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --debug-nack-drop=$(value2switch $SRS_DEBUG_NACK_DROP)" SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --cross-build=$(value2switch $SRS_CROSS_BUILD)" SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --sanitizer=$(value2switch $SRS_SANITIZER)" SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --sanitizer-static=$(value2switch $SRS_SANITIZER_STATIC)" diff --git a/trunk/src/app/srs_app_rtc_network.cpp b/trunk/src/app/srs_app_rtc_network.cpp index 7f13123d9..b53e923c5 100644 --- a/trunk/src/app/srs_app_rtc_network.cpp +++ b/trunk/src/app/srs_app_rtc_network.cpp @@ -261,6 +261,21 @@ srs_error_t SrsRtcUdpNetwork::on_rtp(char* data, int nb_data) { srs_error_t err = srs_success; +#ifdef SRS_NACK_DEBUG_DROP_ENABLED + static int nn_pkts = 0; + bool drop = false; + uint32_t ssrc = srs_rtp_fast_parse_ssrc(data, nb_data); + uint16_t seq = srs_rtp_fast_parse_seq(data, nb_data); + uint8_t pt = srs_rtp_fast_parse_pt(data, nb_data); + if (pt && ssrc && pt == SRS_NACK_DEBUG_DROP_PACKET_PT && (nn_pkts++) < 100) { + drop = (nn_pkts == SRS_NACK_DEBUG_DROP_PACKET_N); + srs_trace(">>> #%d%s rtp seq=%u, pt=%u, ssrc=%u", nn_pkts, drop ? " (dropped)" : "", seq, pt, ssrc); + } + if (drop) { + return err; + } +#endif + // Update stat when we received data. delta_->add_delta(nb_data, 0); diff --git a/trunk/src/app/srs_app_rtc_source.cpp b/trunk/src/app/srs_app_rtc_source.cpp index 1e5deef0d..5ac86f91d 100644 --- a/trunk/src/app/srs_app_rtc_source.cpp +++ b/trunk/src/app/srs_app_rtc_source.cpp @@ -2757,6 +2757,9 @@ srs_error_t SrsRtcRecvTrack::on_nack(SrsRtpPacket** ppkt) if (nack_info) { // seq had been received. nack_receiver_->remove(seq); +#ifdef SRS_NACK_DEBUG_DROP_ENABLED + srs_trace("NACK: recovered seq=%u", seq); +#endif return err; } diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp index 1b1d91b15..ba2ebddae 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp @@ -55,6 +55,13 @@ uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size) pp[0] = *p++; return value; } +uint16_t srs_rtp_fast_parse_seq(char* buf, int size) +{ + if (size < 4) { + return 0; + } + return ((uint8_t)buf[2] << 8) | (uint8_t)buf[3]; +} uint8_t srs_rtp_fast_parse_pt(char* buf, int size) { if (size < 12) { diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp index ff731db0b..b4c4b9143 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp @@ -16,6 +16,16 @@ #include #include +// Indicates whether to enable debugging for NACK. If enabled, the specified PT(109) +// video packet will always be dropped. You can use this option to verify the NACK +// logic. Note that you should restart SRS after each test, as a global variable +// controls the debugging. +#ifdef SRS_DEBUG_NACK_DROP +#define SRS_NACK_DEBUG_DROP_ENABLED +#endif +#define SRS_NACK_DEBUG_DROP_PACKET_PT 109 +#define SRS_NACK_DEBUG_DROP_PACKET_N 3 + class SrsRtpPacket; // The RTP packet max size, should never exceed this size. @@ -50,6 +60,7 @@ class SrsRtpExtensionTypes; // Fast parse the SSRC from RTP packet. Return 0 if invalid. uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size); +uint16_t srs_rtp_fast_parse_seq(char* buf, int size); uint8_t srs_rtp_fast_parse_pt(char* buf, int size); srs_error_t srs_rtp_fast_parse_twcc(char* buf, int size, uint8_t twcc_id, uint16_t& twcc_sn);