From d6e11706eca9fc94f5751fe53aaa4521279b48c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=8F=E7=AB=8B=E6=96=B0?= Date: Mon, 17 Feb 2020 18:46:05 +0800 Subject: [PATCH 01/16] Fix disconnect RTSP connection has assertion, resulting in program exit --- trunk/src/app/srs_app_rtsp.cpp | 20 ++++++++++++++++++-- trunk/src/app/srs_app_rtsp.hpp | 5 ++++- trunk/src/app/srs_app_server.cpp | 1 + trunk/src/app/srs_app_server.hpp | 3 ++- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/trunk/src/app/srs_app_rtsp.cpp b/trunk/src/app/srs_app_rtsp.cpp index 4488b6d98..2577f3128 100644 --- a/trunk/src/app/srs_app_rtsp.cpp +++ b/trunk/src/app/srs_app_rtsp.cpp @@ -240,6 +240,11 @@ srs_error_t SrsRtspConn::serve() return err; } +std::string SrsRtspConn::remote_ip() +{ + return ""; +} + srs_error_t SrsRtspConn::do_cycle() { srs_error_t err = srs_success; @@ -681,6 +686,7 @@ SrsRtspCaster::SrsRtspCaster(SrsConfDirective* c) output = _srs_config->get_stream_caster_output(c); local_port_min = _srs_config->get_stream_caster_rtp_port_min(c); local_port_max = _srs_config->get_stream_caster_rtp_port_max(c); + manager = new SrsCoroutineManager(); } SrsRtspCaster::~SrsRtspCaster() @@ -688,10 +694,20 @@ SrsRtspCaster::~SrsRtspCaster() std::vector::iterator it; for (it = clients.begin(); it != clients.end(); ++it) { SrsRtspConn* conn = *it; - srs_freep(conn); + manager->remove(conn); } clients.clear(); used_ports.clear(); + + srs_freep(manager); +} + +srs_error_t SrsRtspCaster::initialize() +{ + srs_error_t err = srs_success; + if ((err = manager->start()) != srs_success) { + return srs_error_wrap(err, "start manager"); + } } srs_error_t SrsRtspCaster::alloc_port(int* pport) @@ -744,6 +760,6 @@ void SrsRtspCaster::remove(SrsRtspConn* conn) } srs_info("rtsp: remove connection from caster."); - srs_freep(conn); + manager->remove(conn); } diff --git a/trunk/src/app/srs_app_rtsp.hpp b/trunk/src/app/srs_app_rtsp.hpp index 7bbd52651..0ca748535 100644 --- a/trunk/src/app/srs_app_rtsp.hpp +++ b/trunk/src/app/srs_app_rtsp.hpp @@ -100,7 +100,7 @@ public: }; // The rtsp connection serve the fd. -class SrsRtspConn : public ISrsCoroutineHandler +class SrsRtspConn : public ISrsCoroutineHandler, public ISrsConnection { private: std::string output_template; @@ -143,6 +143,7 @@ public: virtual ~SrsRtspConn(); public: virtual srs_error_t serve(); + virtual std::string remote_ip(); private: virtual srs_error_t do_cycle(); // internal methods @@ -179,6 +180,7 @@ private: std::map used_ports; private: std::vector clients; + SrsCoroutineManager* manager; public: SrsRtspCaster(SrsConfDirective* c); virtual ~SrsRtspCaster(); @@ -188,6 +190,7 @@ public: virtual srs_error_t alloc_port(int* pport); // Free the alloced rtp port. virtual void free_port(int lpmin, int lpmax); + virtual srs_error_t initialize(); // Interface ISrsTcpHandler public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 61eeb2309..2edc525aa 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -179,6 +179,7 @@ SrsRtspListener::SrsRtspListener(SrsServer* svr, SrsListenerType t, SrsConfDirec srs_assert(type == SrsListenerRtsp); if (type == SrsListenerRtsp) { caster = new SrsRtspCaster(c); + caster->initialize(); } } diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index fd8cbe3ad..f43d7fc04 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -50,6 +50,7 @@ class ISrsUdpHandler; class SrsUdpListener; class SrsTcpListener; class SrsAppCasterFlv; +class SrsRtspCaster; class SrsCoroutineManager; // The listener type for server to identify the connection, @@ -107,7 +108,7 @@ class SrsRtspListener : virtual public SrsListener, virtual public ISrsTcpHandle { private: SrsTcpListener* listener; - ISrsTcpHandler* caster; + SrsRtspCaster* caster; public: SrsRtspListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c); virtual ~SrsRtspListener(); From bbdbcf173cbe983817424782d8dcd4ad96f64c70 Mon Sep 17 00:00:00 2001 From: winlin Date: Wed, 26 Feb 2020 09:06:53 +0800 Subject: [PATCH 02/16] For #1615, refactor the version and API for SRT. --- trunk/src/srt/srt_server.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/trunk/src/srt/srt_server.cpp b/trunk/src/srt/srt_server.cpp index eb41866e0..7576d3bf5 100644 --- a/trunk/src/srt/srt_server.cpp +++ b/trunk/src/srt/srt_server.cpp @@ -257,8 +257,9 @@ void srt_server::on_work() } } - // @see 2020-01-28 https://github.com/Haivision/srt/commit/b8c70ec801a56bea151ecce9c09c4ebb720c2f68#diff-fb66028e8746fea578788532533a296bR786 -#if SRT_VERSION_MAJOR > 1 || SRT_VERSION_MINOR > 4 || SRT_VERSION_PATCH > 1 + // New API at 2020-01-28, >1.4.1 + // @see https://github.com/Haivision/srt/commit/b8c70ec801a56bea151ecce9c09c4ebb720c2f68#diff-fb66028e8746fea578788532533a296bR786 +#if (SRT_VERSION_MAJOR<<24 | SRT_VERSION_MINOR<<16 | SRT_VERSION_PATCH<<8) > 0x01040100 srt_epoll_clear_usocks(_pollid); #endif } From 4bd37d43b464a39a3a5fc5fb62a174b4870a4745 Mon Sep 17 00:00:00 2001 From: runner365 Date: Wed, 26 Feb 2020 11:14:05 +0800 Subject: [PATCH 03/16] solve dts==0 bugs; solve large aac 2930bytes timestamp bugs --- output.txt | 0 trunk/conf/srt.conf | 4 +++ trunk/src/srt/srt_to_rtmp.cpp | 66 ++++++++++++++++++++++++++++------- trunk/src/srt/srt_to_rtmp.hpp | 2 ++ trunk/src/srt/ts_demux.cpp | 1 - 5 files changed, 59 insertions(+), 14 deletions(-) create mode 100644 output.txt diff --git a/output.txt b/output.txt new file mode 100644 index 000000000..e69de29bb diff --git a/trunk/conf/srt.conf b/trunk/conf/srt.conf index b9fcc9d32..2aa29aa36 100644 --- a/trunk/conf/srt.conf +++ b/trunk/conf/srt.conf @@ -27,6 +27,10 @@ srt_server { # @doc https://github.com/ossrs/srs/issues/1147#issuecomment-577607026 vhost __defaultVhost__ { + play { + #atc on; + mix_correct on; + } } vhost srs.srt.com.cn { } diff --git a/trunk/src/srt/srt_to_rtmp.cpp b/trunk/src/srt/srt_to_rtmp.cpp index 13e83056d..71a903b94 100644 --- a/trunk/src/srt/srt_to_rtmp.cpp +++ b/trunk/src/srt/srt_to_rtmp.cpp @@ -381,7 +381,7 @@ srs_error_t rtmp_client::write_audio_raw_frame(char* frame, int frame_size, SrsR if ((err = _aac_ptr->mux_aac2flv(frame, frame_size, codec, dts, &data, &size)) != srs_success) { return srs_error_wrap(err, "mux aac to flv"); } - + return rtmp_write_packet(SrsFrameTypeAudio, dts, data, size); } @@ -410,7 +410,12 @@ srs_error_t rtmp_client::on_ts_video(std::shared_ptr avs_ptr, uint64_ if ((err = connect()) != srs_success) { return srs_error_wrap(err, "connect"); } - + dts = dts / 90; + pts = pts / 90; + + if (dts == 0) { + dts = pts; + } // send each frame. while (!avs_ptr->empty()) { char* frame = NULL; @@ -480,14 +485,46 @@ srs_error_t rtmp_client::on_ts_video(std::shared_ptr avs_ptr, uint64_ return err; } +int rtmp_client::get_sample_rate(char sound_rate) { + int sample_rate = 44100; + + switch (sound_rate) + { + case SrsAudioSampleRate44100: + sample_rate = 44100; + break; + case SrsAudioSampleRate22050: + sample_rate = 22050; + break; + case SrsAudioSampleRate11025: + sample_rate = 11025; + break; + case SrsAudioSampleRate5512: + sample_rate = 5512; + break; + default: + break; + } + return sample_rate; +} + srs_error_t rtmp_client::on_ts_audio(std::shared_ptr avs_ptr, uint64_t dts, uint64_t pts) { srs_error_t err = srs_success; + uint64_t last_dts; + uint64_t real_dts; + int index = 0; + int sample_size = 1024; // ensure rtmp connected. if ((err = connect()) != srs_success) { return srs_error_wrap(err, "connect"); } + last_dts = dts/90; + if (last_dts == 0) { + last_dts = pts/90; + } + // send each frame. while (!avs_ptr->empty()) { char* frame = NULL; @@ -496,16 +533,21 @@ srs_error_t rtmp_client::on_ts_audio(std::shared_ptr avs_ptr, uint64_ if ((err = _aac_ptr->adts_demux(avs_ptr.get(), &frame, &frame_size, codec)) != srs_success) { return srs_error_wrap(err, "demux adts"); } - //srs_trace("audio annexb demux sampling_frequency_index:%d, aac_packet_type:%d, sound_rate:%d, sound_size:%d", - // codec.sampling_frequency_index, codec.aac_packet_type, codec.sound_rate, - // codec.sound_size); - //srs_trace_data(frame, frame_size, "audio annexb demux:"); - // ignore invalid frame, - // * atleast 1bytes for aac to decode the data. + if (frame_size <= 0) { continue; } - + int sample_rate = get_sample_rate(codec.sound_rate); + + if (codec.aac_packet_type > SrsAudioOpusFrameTraitRaw) { + sample_size = 2048; + } else { + sample_size = 1024; + } + + real_dts = last_dts + index * 1000.0 * sample_size / sample_rate; + index++; + // generate sh. if (_aac_specific_config.empty()) { std::string sh; @@ -516,14 +558,14 @@ srs_error_t rtmp_client::on_ts_audio(std::shared_ptr avs_ptr, uint64_ codec.aac_packet_type = 0; - if ((err = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), &codec, dts)) != srs_success) { + if ((err = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), &codec, real_dts)) != srs_success) { return srs_error_wrap(err, "write raw audio frame"); } } // audio raw data. codec.aac_packet_type = 1; - if ((err = write_audio_raw_frame(frame, frame_size, &codec, dts)) != srs_success) { + if ((err = write_audio_raw_frame(frame, frame_size, &codec, real_dts)) != srs_success) { return srs_error_wrap(err, "write audio raw frame"); } _last_live_ts = now_ms(); @@ -541,8 +583,6 @@ void rtmp_client::on_data_callback(SRT_DATA_MSG_PTR data_ptr, unsigned int media } auto avs_ptr = std::make_shared((char*)data_ptr->get_data(), data_ptr->data_len()); - dts = dts / 90; - pts = pts / 90; if (media_type == STREAM_TYPE_VIDEO_H264) { on_ts_video(avs_ptr, dts, pts); diff --git a/trunk/src/srt/srt_to_rtmp.hpp b/trunk/src/srt/srt_to_rtmp.hpp index 08735c09d..3a3dea3d9 100644 --- a/trunk/src/srt/srt_to_rtmp.hpp +++ b/trunk/src/srt/srt_to_rtmp.hpp @@ -46,6 +46,8 @@ private: virtual srs_error_t write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts); virtual srs_error_t write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts); + int get_sample_rate(char sound_rate); + private: virtual srs_error_t rtmp_write_packet(char type, uint32_t timestamp, char* data, int size); diff --git a/trunk/src/srt/ts_demux.cpp b/trunk/src/srt/ts_demux.cpp index 13cee93ec..3eed4f74f 100644 --- a/trunk/src/srt/ts_demux.cpp +++ b/trunk/src/srt/ts_demux.cpp @@ -291,7 +291,6 @@ int ts_demux::decode(SRT_DATA_MSG_PTR data_ptr, TS_DATA_CALLBACK_PTR callback) return -1; } - unsigned int count = data_ptr->data_len()/188; path = data_ptr->get_path(); for (unsigned int index = 0; index < count; index++) From 9e90870779f3488e2370fbdf7d8c2bcbc3962624 Mon Sep 17 00:00:00 2001 From: runner365 Date: Wed, 26 Feb 2020 11:14:34 +0800 Subject: [PATCH 04/16] solve dts==0 bugs; solve large aac 2930bytes timestamp bugs --- output.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 output.txt diff --git a/output.txt b/output.txt deleted file mode 100644 index e69de29bb..000000000 From 7f4cc6221c232d2b790a015edb75d8602cd3d5eb Mon Sep 17 00:00:00 2001 From: runner365 Date: Sat, 29 Feb 2020 16:47:20 +0800 Subject: [PATCH 05/16] 1,solve audio timestamp bugs;2,solve video dts increase bugs --- trunk/conf/srt.conf | 4 - trunk/src/app/srs_app_config.cpp | 16 +++- trunk/src/app/srs_app_config.hpp | 2 + trunk/src/srt/srt_handle.cpp | 1 + trunk/src/srt/srt_to_rtmp.cpp | 141 +++++++++++++++++++++++++++---- trunk/src/srt/srt_to_rtmp.hpp | 37 ++++++++ trunk/src/srt/ts_demux.cpp | 8 +- 7 files changed, 186 insertions(+), 23 deletions(-) diff --git a/trunk/conf/srt.conf b/trunk/conf/srt.conf index 2aa29aa36..b9fcc9d32 100644 --- a/trunk/conf/srt.conf +++ b/trunk/conf/srt.conf @@ -27,10 +27,6 @@ srt_server { # @doc https://github.com/ossrs/srs/issues/1147#issuecomment-577607026 vhost __defaultVhost__ { - play { - #atc on; - mix_correct on; - } } vhost srs.srt.com.cn { } diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 0eaabb4c9..627a01580 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3530,7 +3530,7 @@ srs_error_t SrsConfig::check_normal_config() && n != "mss" && n != "latency" && n != "recvlatency" && n != "peerlatency" && n != "tlpkdrop" && n != "connect_timeout" && n != "sendbuf" && n != "recvbuf" && n != "payloadsize" - && n != "default_app") { + && n != "default_app" && n != "mix_correct") { return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal srt_stream.%s", n.c_str()); } } @@ -6754,6 +6754,20 @@ unsigned short SrsConfig::get_srt_listen_port() return (unsigned short)atoi(conf->arg0().c_str()); } +bool SrsConfig::get_srt_mix_correct() { + static bool DEFAULT = true; + SrsConfDirective* conf = root->get("srt_server"); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("mix_correct"); + if (!conf || conf->arg0().empty()) { + return DEFAULT; + } + return SRS_CONF_PERFER_FALSE(conf->arg0()); +} + int SrsConfig::get_srto_maxbw() { static int64_t DEFAULT = -1; SrsConfDirective* conf = root->get("srt_server"); diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index dde708f8e..4360c41da 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -625,6 +625,8 @@ public: virtual int get_srto_payloadsize(); // Get the default app. virtual std::string get_default_app_name(); + // Get the mix_correct + virtual bool get_srt_mix_correct(); // http_hooks section private: diff --git a/trunk/src/srt/srt_handle.cpp b/trunk/src/srt/srt_handle.cpp index 4592785e3..634376275 100644 --- a/trunk/src/srt/srt_handle.cpp +++ b/trunk/src/srt/srt_handle.cpp @@ -145,6 +145,7 @@ void srt_handle::add_newconn(SRT_CONN_PTR conn_ptr, int events) { srs_trace("srto SRTO_RCVBUF=%d", val_i); srt_getsockopt(conn_ptr->get_conn(), 0, SRTO_MAXBW, &val_i, &opt_len); srs_trace("srto SRTO_MAXBW=%d", val_i); + srs_trace("srt mix_correct is %s", _srs_config->get_srt_mix_correct() ? "enable" : "disable"); if (conn_ptr->get_mode() == PULL_SRT_MODE) { add_new_puller(conn_ptr, conn_ptr->get_subpath()); diff --git a/trunk/src/srt/srt_to_rtmp.cpp b/trunk/src/srt/srt_to_rtmp.cpp index 71a903b94..ec2d7d828 100644 --- a/trunk/src/srt/srt_to_rtmp.cpp +++ b/trunk/src/srt/srt_to_rtmp.cpp @@ -322,12 +322,13 @@ srs_error_t rtmp_client::write_h264_sps_pps(uint32_t dts, uint32_t pts) { return srs_error_wrap(err, "avc to flv"); } - // the timestamp in rtmp message header is dts. - uint32_t timestamp = dts; - if ((err = rtmp_write_packet(SrsFrameTypeVideo, timestamp, flv, nb_flv)) != srs_success) { - return srs_error_wrap(err, "write packet"); + if (_srs_config->get_srt_mix_correct()) { + _rtmp_queue.insert_rtmp_data((unsigned char*)flv, nb_flv, (int64_t)dts, SrsFrameTypeVideo); + rtmp_write_work(); + } else { + rtmp_write_packet(SrsFrameTypeVideo, dts, flv, nb_flv); } - + // reset sps and pps. _h264_sps_changed = false; _h264_pps_changed = false; @@ -367,10 +368,14 @@ srs_error_t rtmp_client::write_h264_ipb_frame(char* frame, int frame_size, uint3 if ((err = _avc_ptr->mux_avc2flv(ibp, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != srs_success) { return srs_error_wrap(err, "mux avc to flv"); } - - // the timestamp in rtmp message header is dts. - uint32_t timestamp = dts; - return rtmp_write_packet(SrsFrameTypeVideo, timestamp, flv, nb_flv); + if (_srs_config->get_srt_mix_correct()) { + _rtmp_queue.insert_rtmp_data((unsigned char*)flv, nb_flv, (int64_t)dts, SrsFrameTypeVideo); + rtmp_write_work(); + } else { + rtmp_write_packet(SrsFrameTypeVideo, dts, flv, nb_flv); + } + + return err; } srs_error_t rtmp_client::write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts) { @@ -381,14 +386,20 @@ srs_error_t rtmp_client::write_audio_raw_frame(char* frame, int frame_size, SrsR if ((err = _aac_ptr->mux_aac2flv(frame, frame_size, codec, dts, &data, &size)) != srs_success) { return srs_error_wrap(err, "mux aac to flv"); } + if (_srs_config->get_srt_mix_correct()) { + _rtmp_queue.insert_rtmp_data((unsigned char*)data, size, (int64_t)dts, SrsFrameTypeAudio); + rtmp_write_work(); + } else { + rtmp_write_packet(SrsFrameTypeAudio, dts, data, size); + } - return rtmp_write_packet(SrsFrameTypeAudio, dts, data, size); + return err; } srs_error_t rtmp_client::rtmp_write_packet(char type, uint32_t timestamp, char* data, int size) { srs_error_t err = srs_success; SrsSharedPtrMessage* msg = NULL; - + if ((err = srs_rtmp_create_msg(type, timestamp, data, size, _rtmp_conn_ptr->sid(), &msg)) != srs_success) { return srs_error_wrap(err, "create message"); } @@ -403,6 +414,19 @@ srs_error_t rtmp_client::rtmp_write_packet(char type, uint32_t timestamp, char* return err; } +void rtmp_client::rtmp_write_work() { + rtmp_packet_info_s packet_info; + bool ret = false; + + do { + ret = _rtmp_queue.get_rtmp_data(packet_info); + if (ret) { + rtmp_write_packet(packet_info._type, packet_info._dts, (char*)packet_info._data, packet_info._len); + } + } while(ret); + return; +} + srs_error_t rtmp_client::on_ts_video(std::shared_ptr avs_ptr, uint64_t dts, uint64_t pts) { srs_error_t err = srs_success; @@ -416,6 +440,7 @@ srs_error_t rtmp_client::on_ts_video(std::shared_ptr avs_ptr, uint64_ if (dts == 0) { dts = pts; } + // send each frame. while (!avs_ptr->empty()) { char* frame = NULL; @@ -510,8 +535,9 @@ int rtmp_client::get_sample_rate(char sound_rate) { srs_error_t rtmp_client::on_ts_audio(std::shared_ptr avs_ptr, uint64_t dts, uint64_t pts) { srs_error_t err = srs_success; - uint64_t last_dts; + uint64_t base_dts; uint64_t real_dts; + uint64_t first_dts; int index = 0; int sample_size = 1024; @@ -520,11 +546,11 @@ srs_error_t rtmp_client::on_ts_audio(std::shared_ptr avs_ptr, uint64_ return srs_error_wrap(err, "connect"); } - last_dts = dts/90; - if (last_dts == 0) { - last_dts = pts/90; + base_dts = dts/90; + if (base_dts == 0) { + base_dts = pts/90; } - + // send each frame. while (!avs_ptr->empty()) { char* frame = NULL; @@ -545,7 +571,10 @@ srs_error_t rtmp_client::on_ts_audio(std::shared_ptr avs_ptr, uint64_ sample_size = 1024; } - real_dts = last_dts + index * 1000.0 * sample_size / sample_rate; + real_dts = base_dts + index * 1000.0 * sample_size / sample_rate; + if (index == 0) { + first_dts = real_dts; + } index++; // generate sh. @@ -571,6 +600,12 @@ srs_error_t rtmp_client::on_ts_audio(std::shared_ptr avs_ptr, uint64_ _last_live_ts = now_ms(); } + uint64_t diff_t = real_dts - first_dts; + diff_t += 100; + if ((diff_t > 200) && (diff_t < 600)) { + srs_info("set_queue_timeout timeout:%lu", diff_t); + _rtmp_queue.set_queue_timeout(diff_t); + } return err; } @@ -594,3 +629,75 @@ void rtmp_client::on_data_callback(SRT_DATA_MSG_PTR data_ptr, unsigned int media } return; } + +rtmp_packet_queue::rtmp_packet_queue():_queue_timeout(QUEUE_DEF_TIMEOUT) + ,_queue_maxlen(QUEUE_LEN_MAX) + ,_first_packet_t(-1) + ,_first_local_t(-1) { + +} + +rtmp_packet_queue::~rtmp_packet_queue() { + for (auto item : _send_map) { + rtmp_packet_info_s info = item.second; + if (info._data) { + delete info._data; + } + } + _send_map.clear(); +} + +void rtmp_packet_queue::set_queue_timeout(int64_t queue_timeout) { + _queue_timeout = queue_timeout; +} + +void rtmp_packet_queue::insert_rtmp_data(unsigned char* data, int len, int64_t dts, char media_type) { + rtmp_packet_info_s packet_info; + + packet_info._data = data; + packet_info._len = len; + packet_info._dts = dts; + packet_info._type = media_type; + + if (_first_packet_t == -1) { + _first_packet_t = dts; + _first_local_t = (int64_t)now_ms(); + } + + _send_map.insert(std::make_pair(dts, packet_info)); + return; +} + +bool rtmp_packet_queue::is_ready() { + if (!_srs_config->get_srt_mix_correct() && !_send_map.empty()) { + return true; + } + if (_send_map.size() < 2) { + return false; + } + + if (_send_map.size() >= (size_t)_queue_maxlen) { + return true; + } + + auto first_item = _send_map.begin(); + int64_t now_t = (int64_t)now_ms(); + + int64_t diff_t = (now_t - _first_local_t) - (first_item->first - _first_packet_t); + + if (diff_t >= _queue_timeout) { + return true; + } + return false; +} + +bool rtmp_packet_queue::get_rtmp_data(rtmp_packet_info_s& packet_info) { + if (!is_ready()) { + return false; + } + auto iter = _send_map.begin(); + packet_info = iter->second; + _send_map.erase(iter); + + return true; +} \ No newline at end of file diff --git a/trunk/src/srt/srt_to_rtmp.hpp b/trunk/src/srt/srt_to_rtmp.hpp index 3a3dea3d9..5fcaf6acf 100644 --- a/trunk/src/srt/srt_to_rtmp.hpp +++ b/trunk/src/srt/srt_to_rtmp.hpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,37 @@ typedef std::shared_ptr AAC_PTR; #define DEFAULT_VHOST "__default_host__" +#define QUEUE_DEF_TIMEOUT 500 +#define QUEUE_LEN_MAX 100 + +typedef struct { + unsigned char* _data; + int _len; + int64_t _dts; + char _type; + char reserve[3]; +} rtmp_packet_info_s; + +class rtmp_packet_queue { +public: + rtmp_packet_queue(); + ~rtmp_packet_queue(); + + void set_queue_timeout(int64_t queue_timeout); + void insert_rtmp_data(unsigned char* data, int len, int64_t dts, char media_type); + bool get_rtmp_data(rtmp_packet_info_s& packet_info); + +private: + bool is_ready(); + +private: + int64_t _queue_timeout; + int64_t _queue_maxlen; + int64_t _first_packet_t; + int64_t _first_local_t; + std::multimap _send_map;//key:dts, value:rtmp_packet_info +}; + class rtmp_client : public ts_media_data_callback_I, public std::enable_shared_from_this { public: rtmp_client(std::string key_path); @@ -48,6 +80,8 @@ private: int get_sample_rate(char sound_rate); + void rtmp_write_work(); + private: virtual srs_error_t rtmp_write_packet(char type, uint32_t timestamp, char* data, int size); @@ -73,6 +107,9 @@ private: RTMP_CONN_PTR _rtmp_conn_ptr; bool _connect_flag; int64_t _last_live_ts; + +private: + rtmp_packet_queue _rtmp_queue; }; typedef std::shared_ptr RTMP_CLIENT_PTR; diff --git a/trunk/src/srt/ts_demux.cpp b/trunk/src/srt/ts_demux.cpp index 3eed4f74f..ead598bbe 100644 --- a/trunk/src/srt/ts_demux.cpp +++ b/trunk/src/srt/ts_demux.cpp @@ -259,11 +259,17 @@ int ts_demux::decode_unit(unsigned char* data_p, std::string key_path, TS_DATA_C if(ts_header_info._payload_unit_start_indicator){ unsigned char* ret_data_p = nullptr; size_t ret_size = 0; + uint64_t dts = 0; + uint64_t pts = 0; //callback last media data in data buffer on_callback(callback, _last_pid, key_path, _last_dts, _last_pts); - pes_parse(data_p+npos, npos, &ret_data_p, ret_size, _last_dts, _last_pts); + pes_parse(data_p+npos, npos, &ret_data_p, ret_size, dts, pts); + + _last_pts = pts; + _last_dts = (dts == 0) ? pts : dts; + if ((ret_data_p != nullptr) && (ret_size > 0)) { insert_into_databuf(ret_data_p, ret_size, key_path, ts_header_info._PID); } From f917cc1e0cee76c22a6e44f2b24f0856ab9742ae Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 1 Mar 2020 10:09:44 +0800 Subject: [PATCH 06/16] For SRT, perfer mix_correct to true as default. --- trunk/src/app/srs_app_config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 627a01580..5781d2f1b 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -6765,7 +6765,7 @@ bool SrsConfig::get_srt_mix_correct() { if (!conf || conf->arg0().empty()) { return DEFAULT; } - return SRS_CONF_PERFER_FALSE(conf->arg0()); + return SRS_CONF_PERFER_TRUE(conf->arg0()); } int SrsConfig::get_srto_maxbw() { From 1b9a705e4b03db4acefbb51f51b6a730144b7858 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 1 Mar 2020 10:17:03 +0800 Subject: [PATCH 07/16] For #1621, support mix_correct for aggregate aac packets. 4.0.10 --- README.md | 2 ++ trunk/src/core/srs_core_version4.hpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bec6c8de6..9e54d43a2 100755 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ For previous versions, please read: ## V4 changes +* v4.0, 2020-03-01, For [#1621][bug #1621], support mix_correct for aggregate aac packets. 4.0.10 * v4.0, 2020-02-25, For [#1615][bug #1615], support default app(live) for vmix SRT. 4.0.9 * v4.0, 2020-02-21, For [#1598][bug #1598], support SLB health checking by TCP. 4.0.8 * v4.0, 2020-02-19, For [#1579][bug #1579], support rolling update of k8s. 4.0.7 @@ -1687,6 +1688,7 @@ Winlin [bug #1579]: https://github.com/ossrs/srs/issues/1579 [bug #1598]: https://github.com/ossrs/srs/issues/1598 [bug #1615]: https://github.com/ossrs/srs/issues/1615 +[bug #1621]: https://github.com/ossrs/srs/issues/1621 [bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx [exo #828]: https://github.com/google/ExoPlayer/pull/828 diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index da3e2b804..548632cf5 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -24,6 +24,6 @@ #ifndef SRS_CORE_VERSION4_HPP #define SRS_CORE_VERSION4_HPP -#define SRS_VERSION4_REVISION 9 +#define SRS_VERSION4_REVISION 10 #endif From 72155fc64523cd7d6b2c8617b0085d31ba993b48 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 1 Mar 2020 10:34:33 +0800 Subject: [PATCH 08/16] For #1621, support mix_correct for aggregate aac for SRT. 4.0.10 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9e54d43a2..87f6be55f 100755 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ For previous versions, please read: ## V4 changes -* v4.0, 2020-03-01, For [#1621][bug #1621], support mix_correct for aggregate aac packets. 4.0.10 +* v4.0, 2020-03-01, For [#1621][bug #1621], support mix_correct for aggregate aac for SRT. 4.0.10 * v4.0, 2020-02-25, For [#1615][bug #1615], support default app(live) for vmix SRT. 4.0.9 * v4.0, 2020-02-21, For [#1598][bug #1598], support SLB health checking by TCP. 4.0.8 * v4.0, 2020-02-19, For [#1579][bug #1579], support rolling update of k8s. 4.0.7 From 40a09958c4d01f30a2231b77bea7096f82fc3155 Mon Sep 17 00:00:00 2001 From: runner365 Date: Sun, 1 Mar 2020 19:42:32 +0800 Subject: [PATCH 09/16] add checking for pes_parse --- trunk/src/srt/ts_demux.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/trunk/src/srt/ts_demux.cpp b/trunk/src/srt/ts_demux.cpp index ead598bbe..db486d5ad 100644 --- a/trunk/src/srt/ts_demux.cpp +++ b/trunk/src/srt/ts_demux.cpp @@ -265,7 +265,11 @@ int ts_demux::decode_unit(unsigned char* data_p, std::string key_path, TS_DATA_C //callback last media data in data buffer on_callback(callback, _last_pid, key_path, _last_dts, _last_pts); - pes_parse(data_p+npos, npos, &ret_data_p, ret_size, dts, pts); + int ret = pes_parse(data_p+npos, npos, &ret_data_p, ret_size, dts, pts); + assert(ret <= 188); + if (ret > 188) { + return -1; + } _last_pts = pts; _last_dts = (dts == 0) ? pts : dts; From b525fc65aa3e79215da3b64510af38048feeb19a Mon Sep 17 00:00:00 2001 From: Xiaofeng Wang Date: Tue, 3 Mar 2020 21:05:49 +0800 Subject: [PATCH 10/16] Remove unused ip variable * "inet addr" is not compatible with rhel/centos 7+; * ifconfig has been replaced by ip-utils in newer distro; --- trunk/configure | 1 - 1 file changed, 1 deletion(-) diff --git a/trunk/configure b/trunk/configure index d233f66db..8ba25a8ba 100755 --- a/trunk/configure +++ b/trunk/configure @@ -730,7 +730,6 @@ fi # next step ##################################################################################### if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then - ip=`ifconfig|grep "inet addr"| grep -v "127.0.0.1"|awk '{print $2}'|awk -F ':' 'NR==1 {print $2}'` echo "" echo "You can run 3rdparty applications:" if [ $SRS_HTTP_CALLBACK = YES ]; then From 4242985b36a50f6ccb46534d2afa1893021217c0 Mon Sep 17 00:00:00 2001 From: runner365 Date: Sat, 7 Mar 2020 15:15:14 +0800 Subject: [PATCH 11/16] update only support h264+aac --- trunk/src/srt/srt_to_rtmp.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/trunk/src/srt/srt_to_rtmp.cpp b/trunk/src/srt/srt_to_rtmp.cpp index ec2d7d828..0d13c6733 100644 --- a/trunk/src/srt/srt_to_rtmp.cpp +++ b/trunk/src/srt/srt_to_rtmp.cpp @@ -624,8 +624,7 @@ void rtmp_client::on_data_callback(SRT_DATA_MSG_PTR data_ptr, unsigned int media } else if (media_type == STREAM_TYPE_AUDIO_AAC) { on_ts_audio(avs_ptr, dts, pts); } else { - srs_error("mpegts demux unkown stream type:0x%02x", media_type); - assert(0); + srs_error("mpegts demux unkown stream type:0x%02x, only support h264+aac", media_type); } return; } From a2839aacdf8582a2eda3f951d8ef1dffe6f9d0be Mon Sep 17 00:00:00 2001 From: runner365 Date: Sat, 7 Mar 2020 16:15:36 +0800 Subject: [PATCH 12/16] add h264 sei filter --- trunk/src/app/srs_app_config.cpp | 16 +++++++++++++++- trunk/src/app/srs_app_config.hpp | 2 ++ trunk/src/srt/srt_handle.cpp | 3 ++- trunk/src/srt/srt_to_rtmp.cpp | 6 ++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 5781d2f1b..f66ca5cec 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3530,7 +3530,7 @@ srs_error_t SrsConfig::check_normal_config() && n != "mss" && n != "latency" && n != "recvlatency" && n != "peerlatency" && n != "tlpkdrop" && n != "connect_timeout" && n != "sendbuf" && n != "recvbuf" && n != "payloadsize" - && n != "default_app" && n != "mix_correct") { + && n != "default_app" && n != "mix_correct" && n != "sei_filter") { return srs_error_new(ERROR_SYSTEM_CONFIG_INVALID, "illegal srt_stream.%s", n.c_str()); } } @@ -6838,6 +6838,20 @@ int SrsConfig::get_srto_peer_latency() { return atoi(conf->arg0().c_str()); } +bool SrsConfig::get_srt_sei_filter() { + static bool DEFAULT = true; + SrsConfDirective* conf = root->get("srt_server"); + if (!conf) { + return DEFAULT; + } + + conf = conf->get("sei_filter"); + if (!conf || conf->arg0().empty()) { + return DEFAULT; + } + return SRS_CONF_PERFER_TRUE(conf->arg0()); +} + bool SrsConfig::get_srto_tlpkdrop() { static bool DEFAULT = true; SrsConfDirective* conf = root->get("srt_server"); diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 4360c41da..c276b34db 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -613,6 +613,8 @@ public: virtual int get_srto_recv_latency(); // Get the srt SRTO_PEERLATENCY, peer latency, default is 0.. virtual int get_srto_peer_latency(); + // Get the srt h264 sei filter, default is on, it will drop h264 sei packet. + virtual bool get_srt_sei_filter(); // Get the srt SRTO_TLPKDROP, Too-late Packet Drop, default is true. virtual bool get_srto_tlpkdrop(); // Get the srt SRTO_CONNTIMEO, connection timeout, default is 3000ms. diff --git a/trunk/src/srt/srt_handle.cpp b/trunk/src/srt/srt_handle.cpp index 634376275..a6351548e 100644 --- a/trunk/src/srt/srt_handle.cpp +++ b/trunk/src/srt/srt_handle.cpp @@ -145,7 +145,8 @@ void srt_handle::add_newconn(SRT_CONN_PTR conn_ptr, int events) { srs_trace("srto SRTO_RCVBUF=%d", val_i); srt_getsockopt(conn_ptr->get_conn(), 0, SRTO_MAXBW, &val_i, &opt_len); srs_trace("srto SRTO_MAXBW=%d", val_i); - srs_trace("srt mix_correct is %s", _srs_config->get_srt_mix_correct() ? "enable" : "disable"); + srs_trace("srt mix_correct is %s.", _srs_config->get_srt_mix_correct() ? "enable" : "disable"); + srs_trace("srt h264 sei filter is %s.", _srs_config->get_srt_sei_filter() ? "enable" : "disable"); if (conn_ptr->get_mode() == PULL_SRT_MODE) { add_new_puller(conn_ptr, conn_ptr->get_subpath()); diff --git a/trunk/src/srt/srt_to_rtmp.cpp b/trunk/src/srt/srt_to_rtmp.cpp index 0d13c6733..0842a7e7f 100644 --- a/trunk/src/srt/srt_to_rtmp.cpp +++ b/trunk/src/srt/srt_to_rtmp.cpp @@ -459,6 +459,12 @@ srs_error_t rtmp_client::on_ts_video(std::shared_ptr avs_ptr, uint64_ if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) { continue; } + + if (_srs_config->get_srt_sei_filter()) { + if (nal_unit_type == SrsAvcNaluTypeSEI) { + continue; + } + } // for sps if (_avc_ptr->is_sps(frame, frame_size)) { From 41acf9ca8e37e6dfd0d4be6e8abfbcb2d14b152d Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 7 Mar 2020 22:25:19 +0800 Subject: [PATCH 13/16] For #1631, support sei_filter for SRT. 4.0.11 --- README.md | 4 ++++ trunk/src/core/srs_core_version4.hpp | 2 +- trunk/src/srt/srt_to_rtmp.cpp | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 87f6be55f..fffccb183 100755 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ For previous versions, please read: ## V4 changes +* v4.0, 2020-03-07, For [#1631][bug #1631], support sei_filter for SRT. 4.0.11 * v4.0, 2020-03-01, For [#1621][bug #1621], support mix_correct for aggregate aac for SRT. 4.0.10 * v4.0, 2020-02-25, For [#1615][bug #1615], support default app(live) for vmix SRT. 4.0.9 * v4.0, 2020-02-21, For [#1598][bug #1598], support SLB health checking by TCP. 4.0.8 @@ -1691,6 +1692,9 @@ Winlin [bug #1621]: https://github.com/ossrs/srs/issues/1621 [bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx +[bug #1631]: https://github.com/ossrs/srs/issues/1631 +[bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx + [exo #828]: https://github.com/google/ExoPlayer/pull/828 [r3.0b1]: https://github.com/ossrs/srs/releases/tag/v3.0-b1 diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index 548632cf5..45b47d69a 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -24,6 +24,6 @@ #ifndef SRS_CORE_VERSION4_HPP #define SRS_CORE_VERSION4_HPP -#define SRS_VERSION4_REVISION 10 +#define SRS_VERSION4_REVISION 11 #endif diff --git a/trunk/src/srt/srt_to_rtmp.cpp b/trunk/src/srt/srt_to_rtmp.cpp index 0842a7e7f..f36a353ee 100644 --- a/trunk/src/srt/srt_to_rtmp.cpp +++ b/trunk/src/srt/srt_to_rtmp.cpp @@ -460,6 +460,7 @@ srs_error_t rtmp_client::on_ts_video(std::shared_ptr avs_ptr, uint64_ continue; } + // TODO: FIXME: Should cache this config, it's better not to get it for each video frame. if (_srs_config->get_srt_sei_filter()) { if (nal_unit_type == SrsAvcNaluTypeSEI) { continue; From dcb0553cc8c3e495d3d3b4ecad676409954f3945 Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 7 Mar 2020 22:35:11 +0800 Subject: [PATCH 14/16] For #1612, fix crash bug for RTSP. 4.0.12 --- README.md | 2 ++ trunk/src/app/srs_app_rtsp.cpp | 1 + trunk/src/app/srs_app_server.cpp | 2 ++ trunk/src/core/srs_core_version4.hpp | 2 +- 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index fffccb183..dc6abcfb5 100755 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ For previous versions, please read: ## V4 changes +* v4.0, 2020-03-07, For [#1612][bug #1612], fix crash bug for RTSP. 4.0.12 * v4.0, 2020-03-07, For [#1631][bug #1631], support sei_filter for SRT. 4.0.11 * v4.0, 2020-03-01, For [#1621][bug #1621], support mix_correct for aggregate aac for SRT. 4.0.10 * v4.0, 2020-02-25, For [#1615][bug #1615], support default app(live) for vmix SRT. 4.0.9 @@ -1693,6 +1694,7 @@ Winlin [bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx [bug #1631]: https://github.com/ossrs/srs/issues/1631 +[bug #1612]: https://github.com/ossrs/srs/issues/1612 [bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx [exo #828]: https://github.com/google/ExoPlayer/pull/828 diff --git a/trunk/src/app/srs_app_rtsp.cpp b/trunk/src/app/srs_app_rtsp.cpp index 3dcf20213..c81c71c78 100644 --- a/trunk/src/app/srs_app_rtsp.cpp +++ b/trunk/src/app/srs_app_rtsp.cpp @@ -242,6 +242,7 @@ srs_error_t SrsRtspConn::serve() std::string SrsRtspConn::remote_ip() { + // TODO: FIXME: Implement it. return ""; } diff --git a/trunk/src/app/srs_app_server.cpp b/trunk/src/app/srs_app_server.cpp index 0a904d514..c35c27a42 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -179,6 +179,8 @@ SrsRtspListener::SrsRtspListener(SrsServer* svr, SrsListenerType t, SrsConfDirec srs_assert(type == SrsListenerRtsp); if (type == SrsListenerRtsp) { caster = new SrsRtspCaster(c); + + // TODO: FIXME: Must check error. caster->initialize(); } } diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index 45b47d69a..98f2899e1 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -24,6 +24,6 @@ #ifndef SRS_CORE_VERSION4_HPP #define SRS_CORE_VERSION4_HPP -#define SRS_VERSION4_REVISION 11 +#define SRS_VERSION4_REVISION 12 #endif From 48be5b6245651120ae02394ba0edd9977f35652a Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 7 Mar 2020 22:37:12 +0800 Subject: [PATCH 15/16] Update authors --- AUTHORS.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index 6755f273b..352376b94 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -53,4 +53,6 @@ CONTRIBUTORS ordered by first contribution. * alphonsetai * Michael.Ma * lam2003 -* runner365 \ No newline at end of file +* runner365 +* XiaofengWang +* XiaLixin \ No newline at end of file From 5586c2a128fa469263b8837ae2fc07f390c8ea97 Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 7 Mar 2020 22:42:23 +0800 Subject: [PATCH 16/16] For #1612, refactor return value for RTSP initialize. --- trunk/src/app/srs_app_rtsp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/trunk/src/app/srs_app_rtsp.cpp b/trunk/src/app/srs_app_rtsp.cpp index c81c71c78..8c6967115 100644 --- a/trunk/src/app/srs_app_rtsp.cpp +++ b/trunk/src/app/srs_app_rtsp.cpp @@ -712,6 +712,7 @@ srs_error_t SrsRtspCaster::initialize() if ((err = manager->start()) != srs_success) { return srs_error_wrap(err, "start manager"); } + return err; } srs_error_t SrsRtspCaster::alloc_port(int* pport)