diff --git a/conf/config.ini b/conf/config.ini index c158d843..ed4727af 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -168,8 +168,6 @@ checkSource=1 dumpDir= #udp和tcp代理服务器,支持rtp(必须是ts或ps类型)代理 port=10000 -#rtp如果是ts/ps类型则选择MP2P,还可以设置为MP4V-ES -rtp_type=MP2P #rtp超时时间,单位秒 timeoutSec=15 diff --git a/src/Common/config.cpp b/src/Common/config.cpp index 89ad9bbf..ded712dc 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -282,15 +282,12 @@ namespace RtpProxy { const string kDumpDir = RTP_PROXY_FIELD"dumpDir"; //是否限制udp数据来源ip和端口 const string kCheckSource = RTP_PROXY_FIELD"checkSource"; -//rtp类型,支持MP2P/MP4V-ES -const string kRtpType = RTP_PROXY_FIELD"rtp_type"; //rtp接收超时时间 const string kTimeoutSec = RTP_PROXY_FIELD"timeoutSec"; onceToken token([](){ mINI::Instance()[kDumpDir] = ""; mINI::Instance()[kCheckSource] = 1; - mINI::Instance()[kRtpType] = "MP2P"; mINI::Instance()[kTimeoutSec] = 15; },nullptr); } //namespace RtpProxy diff --git a/src/Common/config.h b/src/Common/config.h index 9b9cab0c..ba81611c 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -306,8 +306,6 @@ namespace RtpProxy { extern const string kDumpDir; //是否限制udp数据来源ip和端口 extern const string kCheckSource; -//rtp类型,支持MP2P/MP4V-ES -extern const string kRtpType; //rtp接收超时时间 extern const string kTimeoutSec; } //namespace RtpProxy diff --git a/src/Rtp/RtpDecoder.cpp b/src/Rtp/RtpDecoder.cpp index 5f78cd7c..e7b63fb9 100644 --- a/src/Rtp/RtpDecoder.cpp +++ b/src/Rtp/RtpDecoder.cpp @@ -29,7 +29,6 @@ #include "Util/logger.h" #include "RtpDecoder.h" #include "rtp-payload.h" - using namespace toolkit; namespace mediakit{ @@ -45,7 +44,13 @@ RtpDecoder::~RtpDecoder() { } } -void RtpDecoder::decodeRtp(const void *data, int bytes,const char *type_name) { +void RtpDecoder::decodeRtp(const void *data, int bytes,const string &type_name) { + if(_rtp_type != type_name && _rtp_decoder){ + //rtp类型发生变化,切换之 + rtp_payload_decode_destroy(_rtp_decoder); + _rtp_decoder = nullptr; + } + if(!_rtp_decoder){ static rtp_payload_t s_func= { [](void* param, int bytes){ @@ -64,11 +69,14 @@ void RtpDecoder::decodeRtp(const void *data, int bytes,const char *type_name) { uint8_t rtp_type = 0x7F & ((uint8_t *) data)[1]; InfoL << "rtp type:" << (int) rtp_type; - _rtp_decoder = rtp_payload_decode_create(rtp_type, type_name, &s_func, this); + _rtp_decoder = rtp_payload_decode_create(rtp_type, type_name.data(), &s_func, this); if (!_rtp_decoder) { WarnL << "unsupported rtp type:" << (int) rtp_type << ",size:" << bytes << ",hexdump" << hexdump(data, bytes > 16 ? 16 : bytes); + }else{ + _rtp_type = type_name; } } + if(_rtp_decoder){ rtp_payload_decode_input(_rtp_decoder,data,bytes); } diff --git a/src/Rtp/RtpDecoder.h b/src/Rtp/RtpDecoder.h index 845dbdbd..c89aebe3 100644 --- a/src/Rtp/RtpDecoder.h +++ b/src/Rtp/RtpDecoder.h @@ -38,11 +38,12 @@ public: RtpDecoder(); virtual ~RtpDecoder(); protected: - void decodeRtp(const void *data, int bytes,const char *type_name); + void decodeRtp(const void *data, int bytes,const string &type_name); virtual void onRtpDecode(const void *packet, int bytes, uint32_t timestamp, int flags) = 0; private: void *_rtp_decoder = nullptr; BufferRaw::Ptr _buffer; + string _rtp_type; }; }//namespace mediakit diff --git a/src/Rtp/RtpProcess.cpp b/src/Rtp/RtpProcess.cpp index 85e68656..83ceb843 100644 --- a/src/Rtp/RtpProcess.cpp +++ b/src/Rtp/RtpProcess.cpp @@ -33,6 +33,7 @@ namespace mediakit{ +static const vector kRtpTypes = {"MP2P","MP4V-ES"}; /** * 合并一些时间戳相同的frame @@ -84,6 +85,7 @@ RtpProcess::RtpProcess(uint32_t ssrc) { _track->_samplerate = 90000; _track->_type = TrackVideo; _track->_ssrc = _ssrc; + getNextRtpType(); DebugL << printSSRC(_ssrc); GET_CONFIG(bool,toRtxp,General::kPublishToRtxp); @@ -153,6 +155,14 @@ bool RtpProcess::inputRtp(const char *data, int data_len,const struct sockaddr * return ret; } +void RtpProcess::getNextRtpType(){ + _rtp_type = kRtpTypes[_rtp_type_idx++]; + _rtp_dec_failed_cnt = 0; + if(_rtp_type_idx == kRtpTypes.size()){ + _rtp_type_idx = 0; + } +} + void RtpProcess::onRtpSorted(const RtpPacket::Ptr &rtp, int) { if(rtp->sequence != _sequence + 1){ WarnL << rtp->sequence << " != " << _sequence << "+1"; @@ -166,8 +176,7 @@ void RtpProcess::onRtpSorted(const RtpPacket::Ptr &rtp, int) { fwrite((uint8_t *) rtp->data() + 4, rtp->size() - 4, 1, _save_file_rtp.get()); } - GET_CONFIG(string,rtp_type,::RtpProxy::kRtpType); - decodeRtp(rtp->data() + 4 ,rtp->size() - 4,rtp_type.data()); + decodeRtp(rtp->data() + 4 ,rtp->size() - 4,_rtp_type); } void RtpProcess::onRtpDecode(const void *packet, int bytes, uint32_t, int flags) { @@ -178,6 +187,12 @@ void RtpProcess::onRtpDecode(const void *packet, int bytes, uint32_t, int flags) auto ret = decodePS((uint8_t *)packet,bytes); if(ret != bytes){ WarnL << ret << " != " << bytes << " " << flags; + if(++_rtp_dec_failed_cnt == 10){ + getNextRtpType(); + InfoL << "rtp of ssrc " << printSSRC(_ssrc) << " change to type: " << _rtp_type ; + } + } else{ + _rtp_dec_failed_cnt = 0; } } @@ -307,5 +322,6 @@ void RtpProcess::setListener(const std::weak_ptr &listener){ _muxer->setListener(listener); } + }//namespace mediakit #endif//defined(ENABLE_RTPPROXY) \ No newline at end of file diff --git a/src/Rtp/RtpProcess.h b/src/Rtp/RtpProcess.h index c9fb7397..bf0b979a 100644 --- a/src/Rtp/RtpProcess.h +++ b/src/Rtp/RtpProcess.h @@ -62,6 +62,8 @@ protected: int64_t dts, const void *data, int bytes) override ; +private: + void getNextRtpType(); private: std::shared_ptr _save_file_rtp; std::shared_ptr _save_file_ps; @@ -77,6 +79,9 @@ private: Ticker _last_rtp_time; map _stamps; uint32_t _dts = 0; + int _rtp_type_idx = 0; + string _rtp_type; + int _rtp_dec_failed_cnt = 0; }; }//namespace mediakit diff --git a/tests/test_rtp.cpp b/tests/test_rtp.cpp index 52c8fe03..8e36a131 100644 --- a/tests/test_rtp.cpp +++ b/tests/test_rtp.cpp @@ -98,8 +98,6 @@ int main(int argc,char *argv[]) { rtspSrv->start(554);//默认554 rtmpSrv->start(1935);//默认1935 httpSrv->start(80);//默认80 - //此处可以选择MP4V-ES或MP2P - mINI::Instance()[RtpProxy::kRtpType] = "MP4V-ES"; //此处选择是否导出调试文件 // mINI::Instance()[RtpProxy::kDumpDir] = "/Users/xzl/Desktop/";