diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index ce5b58d22..8ecfff760 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -7,6 +7,7 @@ The changelog for SRS. ## SRS 5.0 Changelog +* v5.0, 2022-09-22, Fix [#3164](https://github.com/ossrs/srs/issues/3164): SRT: Choppy when audio ts gap is too large. v5.0.65 * v5.0, 2022-09-16, APM: Support distributed tracing by Tencent Cloud APM. v5.0.64 * v5.0, 2022-09-16, For [#3179](https://github.com/ossrs/srs/issues/3179): WebRTC: Make sure the same m-lines order for offer and answer. v5.0.63 * v5.0, 2022-09-10, For [#3174](https://github.com/ossrs/srs/issues/3174): WebRTC: Support Unity to publish or play stream. v5.0.62 diff --git a/trunk/src/app/srs_app_srt_source.cpp b/trunk/src/app/srs_app_srt_source.cpp index 2afdb0c17..b66d80418 100644 --- a/trunk/src/app/srs_app_srt_source.cpp +++ b/trunk/src/app/srs_app_srt_source.cpp @@ -18,6 +18,7 @@ using namespace std; #include #include #include +#include SrsSrtPacket::SrsSrtPacket() { @@ -250,14 +251,21 @@ SrsRtmpFromSrtBridge::SrsRtmpFromSrtBridge(SrsLiveSource* source) : ISrsSrtSourc sps_ = ""; pps_ = ""; - live_source_ = source; req_ = NULL; + live_source_ = source; + + video_streamid_ = 1; + audio_streamid_ = 2; + + pp_audio_duration_ = new SrsAlonePithyPrint(); } SrsRtmpFromSrtBridge::~SrsRtmpFromSrtBridge() { srs_freep(ts_ctx_); srs_freep(req_); + + srs_freep(pp_audio_duration_); } srs_error_t SrsRtmpFromSrtBridge::on_publish() @@ -450,7 +458,7 @@ srs_error_t SrsRtmpFromSrtBridge::check_sps_pps_change(SrsTsMessage* msg) } SrsMessageHeader header; - header.initialize_video(nb_flv, dts, 1); + header.initialize_video(nb_flv, dts, video_streamid_); SrsCommonMessage rtmp; if ((err = rtmp.create(&header, flv, nb_flv)) != srs_success) { return srs_error_wrap(err, "create rtmp"); @@ -488,7 +496,7 @@ srs_error_t SrsRtmpFromSrtBridge::on_h264_frame(SrsTsMessage* msg, vectorpts / 90); int frame_idx = 0; + int duration_ms = 0; // send each frame. while (!avs->empty()) { @@ -567,6 +576,7 @@ srs_error_t SrsRtmpFromSrtBridge::on_ts_audio(SrsTsMessage* msg, SrsBuffer* avs) default: sample_rate = 44100; break; } uint32_t frame_pts = (double)pts + (frame_idx * (1024.0 * 1000.0 / sample_rate)); + duration_ms += 1024.0 * 1000.0 / sample_rate; ++frame_idx; if ((err = check_audio_sh_change(msg, frame_pts)) != srs_success) { @@ -577,6 +587,15 @@ srs_error_t SrsRtmpFromSrtBridge::on_ts_audio(SrsTsMessage* msg, SrsBuffer* avs) return srs_error_wrap(err, "audio frame"); } } + + pp_audio_duration_->elapse(); + + if ((duration_ms >= 200) && pp_audio_duration_->can_print()) { + // MPEG-TS always merge multi audio frame into one pes packet, may cause high latency and AV synchronization errors + // @see https://github.com/ossrs/srs/issues/3164 + srs_warn("srt to rtmp, audio duration=%dms too large, audio frames=%d, may cause high latency and AV synchronization errors, " + "read https://ossrs.io/lts/en-us/docs/v5/doc/srt-codec#ffmpeg-push-srt-stream", duration_ms, frame_idx); + } return err; } @@ -595,7 +614,7 @@ srs_error_t SrsRtmpFromSrtBridge::check_audio_sh_change(SrsTsMessage* msg, uint3 int rtmp_len = audio_sh_.size() + 2; SrsCommonMessage rtmp; - rtmp.header.initialize_audio(rtmp_len, pts, 1); + rtmp.header.initialize_audio(rtmp_len, pts, audio_streamid_); rtmp.create_payload(rtmp_len); rtmp.size = rtmp_len; @@ -619,7 +638,7 @@ srs_error_t SrsRtmpFromSrtBridge::on_aac_frame(SrsTsMessage* msg, uint32_t pts, int rtmp_len = frame_size + 2/* 2 bytes of flv audio tag header*/; SrsCommonMessage rtmp; - rtmp.header.initialize_audio(rtmp_len, pts, 2/*streamid*/); + rtmp.header.initialize_audio(rtmp_len, pts, audio_streamid_); rtmp.create_payload(rtmp_len); rtmp.size = rtmp_len; diff --git a/trunk/src/app/srs_app_srt_source.hpp b/trunk/src/app/srs_app_srt_source.hpp index afb4eca97..7417e8500 100644 --- a/trunk/src/app/srs_app_srt_source.hpp +++ b/trunk/src/app/srs_app_srt_source.hpp @@ -20,6 +20,7 @@ class SrsSharedPtrMessage; class SrsRequest; class SrsLiveSource; class SrsSrtSource; +class SrsAlonePithyPrint; // The SRT packet with shared message. class SrsSrtPacket @@ -136,6 +137,13 @@ private: SrsRequest* req_; SrsLiveSource* live_source_; + + // SRT to rtmp, video stream id. + int video_streamid_; + // SRT to rtmp, audio stream id. + int audio_streamid_; + // Cycle print when audio duration too large because mpegts may merge multi audio frame in one pes packet. + SrsAlonePithyPrint* pp_audio_duration_; }; class SrsSrtSource diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp index a8748cd84..cc23bf0c0 100644 --- a/trunk/src/core/srs_core_version5.hpp +++ b/trunk/src/core/srs_core_version5.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 5 #define VERSION_MINOR 0 -#define VERSION_REVISION 64 +#define VERSION_REVISION 65 #endif