diff --git a/trunk/src/app/srs_app_rtc_conn.cpp b/trunk/src/app/srs_app_rtc_conn.cpp index f5478829e..a5a0bdd5a 100644 --- a/trunk/src/app/srs_app_rtc_conn.cpp +++ b/trunk/src/app/srs_app_rtc_conn.cpp @@ -2095,19 +2095,14 @@ srs_error_t SrsRtcConnection::find_publisher(char* buf, int size, SrsRtcPublishS return srs_error_new(ERROR_RTC_RTCP, "no publisher"); } - SrsRtpHeader header; - if (true) { - SrsBuffer* buffer = new SrsBuffer(buf, size); - SrsAutoFree(SrsBuffer, buffer); - header.ignore_padding(true); - if(srs_success != (err = header.decode(buffer))) { - return srs_error_wrap(err, "decode rtp header"); - } + uint32_t ssrc = srs_rtp_fast_parse_ssrc(buf, size); + if (ssrc == 0) { + return srs_error_new(ERROR_RTC_NO_PUBLISHER, "invalid ssrc"); } - map::iterator it = publishers_ssrc_map_.find(header.get_ssrc()); + map::iterator it = publishers_ssrc_map_.find(ssrc); if(it == publishers_ssrc_map_.end()) { - return srs_error_new(ERROR_RTC_NO_PUBLISHER, "no publisher for ssrc:%u", header.get_ssrc()); + return srs_error_new(ERROR_RTC_NO_PUBLISHER, "no publisher for ssrc:%u", ssrc); } *ppublisher = it->second; diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp index f5f6959d3..8a201dd6f 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.cpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.cpp @@ -33,6 +33,37 @@ using namespace std; #include #include +uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size) +{ + /* @see https://tools.ietf.org/html/rfc1889#section-5.1 + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |V=2|P|X| CC |M| PT | sequence number | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | timestamp | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | synchronization source (SSRC) identifier | + +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ + | contributing source (CSRC) identifiers | + | .... | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if (size < 12) { + return 0; + } + + uint32_t value = 0; + char* pp = (char*)&value; + + char* p = buf + 8; + pp[3] = *p++; + pp[2] = *p++; + pp[1] = *p++; + pp[0] = *p++; + return value; +} + // If value is newer than pre_value,return true; otherwise false bool srs_seq_is_newer(uint16_t value, uint16_t pre_value) { diff --git a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp index e5e647b69..efce04ed3 100644 --- a/trunk/src/kernel/srs_kernel_rtc_rtp.hpp +++ b/trunk/src/kernel/srs_kernel_rtc_rtp.hpp @@ -58,6 +58,9 @@ class SrsRtpRawPayload; class SrsRtpFUAPayload2; class SrsSharedPtrMessage; +// Fast parse the SSRC from RTP packet. Return 0 if invalid. +uint32_t srs_rtp_fast_parse_ssrc(char* buf, int size); + // The "distance" between two uint16 number, for example: // distance(prev_value=3, value=5) === (int16_t)(uint16_t)((uint16_t)3-(uint16_t)5) === -2 // distance(prev_value=3, value=65534) === (int16_t)(uint16_t)((uint16_t)3-(uint16_t)65534) === 5