From aa06245971e1da002258c03f442034dc83e38c96 Mon Sep 17 00:00:00 2001 From: xbpeng Date: Fri, 10 Nov 2023 16:19:15 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=82=E9=85=8D=E5=AF=B9=E6=96=B9=E6=B5=81?= =?UTF-8?q?=E5=AA=92=E4=BD=93=E4=B8=8D=E8=A7=84=E8=8C=83=E5=8F=91rtp?= =?UTF-8?q?=E5=8C=85=E9=97=AE=E9=A2=98=E3=80=82=20=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=9Artp-ps=EF=BC=88tcp=EF=BC=89=E5=8C=85=E7=9A=84=E6=90=9C?= =?UTF-8?q?=E7=B4=A2=E6=81=A2=E5=A4=8D=EF=BC=8C=E9=80=821-=E5=BB=BA?= =?UTF-8?q?=E7=AB=8Btcp=E9=93=BE=E6=8E=A5=E5=90=8E=EF=BC=8C=E5=B9=B6?= =?UTF-8?q?=E4=B8=8D=E6=98=AF=E4=BB=8Ertp=E5=8C=85=E5=A4=B4=E5=BC=80?= =?UTF-8?q?=E5=A7=8B=E5=8F=91=E6=95=B0=E6=8D=AE=EF=BC=8C=E6=89=80=E4=BB=A5?= =?UTF-8?q?zlm=E6=97=A0=E6=B3=95=E8=A7=A3=E6=9E=90=E5=87=BA=E6=AD=A3?= =?UTF-8?q?=E7=A1=AE=E7=9A=84=E5=8C=85=E3=80=82=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E6=96=B9=E6=A1=88=EF=BC=9A=201-=E5=9C=A8tcp=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=8A=A5=E6=96=87=E4=B8=AD=E6=90=9C=E7=B4=A20x000001bb(?= =?UTF-8?q?=E5=85=B3=E9=94=AE=E5=B8=A7=E7=9A=84system=20header)=EF=BC=8C?= =?UTF-8?q?=E6=89=BE=E5=88=B0=E5=90=8E=E5=81=8F=E7=A7=BB=E5=9B=BA=E5=AE=9A?= =?UTF-8?q?=E5=AD=97=E8=8A=82=E6=81=A2=E5=A4=8Drtp=E5=8C=85=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Rtp/RtpSession.cpp | 61 ++++++++++++++++++++++++++++++++++++++++-- src/Rtp/RtpSession.h | 4 +++ 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/src/Rtp/RtpSession.cpp b/src/Rtp/RtpSession.cpp index 38b6d4cd..82f3c72a 100644 --- a/src/Rtp/RtpSession.cpp +++ b/src/Rtp/RtpSession.cpp @@ -164,8 +164,23 @@ static const char *findSSRC(const char *data, ssize_t len, uint32_t ssrc) { return nullptr; } +static const char *findPsHeaderFlag(const char *data, ssize_t len) { + for (ssize_t i = 2; i <= len - 4; ++i) { + auto ptr = (const uint8_t *) data + i; + //PsHeader 0x000001ba、PsSystemHeader0x000001bb(关键帧标识) + if (ptr[0] == (0x00) && ptr[1] == (0x00) && ptr[2] == (0x01) && ptr[3] == (0xbb)) { + return (const char *) ptr; + } + } + + return nullptr; +} + //rtp长度到ssrc间的长度固定为10 static size_t constexpr kSSRCOffset = 2 + 4 + 4; +// rtp长度到ps header间的长度固定为14 (暂时不采用找ps header,采用找system header代替) +// rtp长度到ps system header间的长度固定为20 (关键帧标识) +static size_t constexpr kPSHeaderOffset = 2 + 4 + 4 + 4 + 20; const char *RtpSession::onSearchPacketTail(const char *data, size_t len) { if (!_search_rtp) { @@ -173,12 +188,26 @@ const char *RtpSession::onSearchPacketTail(const char *data, size_t len) { return RtpSplitter::onSearchPacketTail(data, len); } if (!_process) { - throw SockException(Err_shutdown, "ssrc未获取到,无法通过ssrc恢复tcp上下文"); + InfoL << "ssrc未获取到,无法通过ssrc恢复tcp上下文;尝试搜索PsSystemHeader恢复tcp上下文。"; + auto rtp_ptr1 = searchByPsHeaderFlag(data,len); + return rtp_ptr1; } + auto rtp_ptr0 = searchBySSRC(data,len); + if(rtp_ptr0) { + return rtp_ptr0; + } + // ssrc搜索失败继续尝试搜索ps header flag + auto rtp_ptr2 = searchByPsHeaderFlag(data,len); + return rtp_ptr2; +} + +const char *RtpSession::searchBySSRC(const char *data, size_t len) { + InfoL << "尝试rtp搜索ssrc..._ssrc=" << _ssrc; //搜索第一个rtp的ssrc auto ssrc_ptr0 = findSSRC(data, len, _ssrc); if (!ssrc_ptr0) { //未搜索到任意rtp,返回数据不够 + InfoL << "rtp搜索ssrc失败(第一个数据不够),丢弃rtp数据为:" << len; return nullptr; } //这两个字节是第一个rtp的长度字段 @@ -189,13 +218,14 @@ const char *RtpSession::onSearchPacketTail(const char *data, size_t len) { auto ssrc_ptr1 = findSSRC(ssrc_ptr0 + rtp_len, data + (ssize_t) len - ssrc_ptr0 - rtp_len, _ssrc); if (!ssrc_ptr1) { //未搜索到第二个rtp,返回数据不够 + InfoL << "rtp搜索ssrc失败(第二个数据不够),丢弃rtp数据为:" << len; return nullptr; } //两个ssrc的间隔正好等于rtp的长度(外加rtp长度字段),那么说明找到rtp auto ssrc_offset = ssrc_ptr1 - ssrc_ptr0; if (ssrc_offset == rtp_len + 2 || ssrc_offset == rtp_len + 4) { - InfoL << "rtp搜索成功,tcp上下文恢复成功,丢弃的rtp残余数据为:" << rtp_len_ptr - data; + InfoL << "rtp搜索ssrc成功,tcp上下文恢复成功,丢弃的rtp残余数据为:" << rtp_len_ptr - data; _search_rtp_finished = true; if (rtp_len_ptr == data) { //停止搜索rtp,否则会进入死循环 @@ -208,5 +238,32 @@ const char *RtpSession::onSearchPacketTail(const char *data, size_t len) { return ssrc_ptr1 - kSSRCOffset; } +const char *RtpSession::searchByPsHeaderFlag(const char *data, size_t len) { + InfoL << "尝试rtp搜索PsSystemHeaderFlag..._ssrc=" << _ssrc; + // 搜索rtp中的第一个PsHeaderFlag + auto ps_header_flag_ptr = findPsHeaderFlag(data,len); + if (!ps_header_flag_ptr) { + InfoL << "rtp搜索flag失败,丢弃rtp数据为:" << len; + return nullptr; + } + + + auto rtp_ptr = ps_header_flag_ptr - kPSHeaderOffset; + _search_rtp_finished = true; + if (rtp_ptr == data) { + //停止搜索rtp,否则会进入死循环 + _search_rtp = false; + } + InfoL << "rtp搜索flag成功,tcp上下文恢复成功,丢弃的rtp残余数据为:" << rtp_ptr - data; + + // TODO or Not ? 更新设置ssrc + uint32_t rtp_ssrc = 0; + RtpSelector::getSSRC(rtp_ptr+2, len, rtp_ssrc); + _ssrc = rtp_ssrc; + InfoL << "设置_ssrc为:" << _ssrc; + // RtpServer::updateSSRC(uint32_t ssrc) + return rtp_ptr; +} + }//namespace mediakit #endif//defined(ENABLE_RTPPROXY) \ No newline at end of file diff --git a/src/Rtp/RtpSession.h b/src/Rtp/RtpSession.h index 81a8c2e1..0de60db4 100644 --- a/src/Rtp/RtpSession.h +++ b/src/Rtp/RtpSession.h @@ -41,6 +41,10 @@ protected: void onRtpPacket(const char *data, size_t len) override; // RtpSplitter override const char *onSearchPacketTail(const char *data, size_t len) override; + // 搜寻SSRC + const char *searchBySSRC(const char *data, size_t len); + // 搜寻PS包里的关键帧标头 + const char *searchByPsHeaderFlag(const char *data, size_t len); private: bool _delay_close = false;