From a9fe5d6f4252825bab0f2cfda920ebf58ad0701a Mon Sep 17 00:00:00 2001 From: xia-chu <771730766@qq.com> Date: Mon, 21 Apr 2025 11:07:38 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=B8=A7=E5=90=88=E5=B9=B6?= =?UTF-8?q?=E5=BC=80=E5=85=B3=EF=BC=8C=E4=BC=98=E5=8C=96=E5=9B=BD=E6=A0=87?= =?UTF-8?q?=E6=B5=81=E7=A7=92=E5=BC=80=E9=80=9F=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- conf/config.ini | 2 ++ src/Common/config.cpp | 2 ++ src/Common/config.h | 2 ++ src/Rtp/Decoder.cpp | 10 +++++++++- src/Rtp/Decoder.h | 3 ++- 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/conf/config.ini b/conf/config.ini index e7bf91c3..80455f4e 100644 --- a/conf/config.ini +++ b/conf/config.ini @@ -342,6 +342,8 @@ rtp_g711_dur_ms = 100 #udp接收数据socket buffer大小配置 #4*1024*1024=4196304 udp_recv_socket_buffer=4194304 +#ps/ts解析后是否等待下一帧以判断本帧是否完整,开启后提高兼容性,但是可能增加延时 +merge_frame=1 [rtc] #rtc播放推流、播放超时时间 diff --git a/src/Common/config.cpp b/src/Common/config.cpp index 6a9c4c45..2b2f716f 100644 --- a/src/Common/config.cpp +++ b/src/Common/config.cpp @@ -366,6 +366,7 @@ const string kOpusPT = RTP_PROXY_FIELD "opus_pt"; const string kGopCache = RTP_PROXY_FIELD "gop_cache"; const string kRtpG711DurMs = RTP_PROXY_FIELD "rtp_g711_dur_ms"; const string kUdpRecvSocketBuffer = RTP_PROXY_FIELD "udp_recv_socket_buffer"; +const std::string kMergeFrame = RTP_PROXY_FIELD "merge_frame"; static onceToken token([]() { mINI::Instance()[kDumpDir] = ""; @@ -378,6 +379,7 @@ static onceToken token([]() { mINI::Instance()[kGopCache] = 1; mINI::Instance()[kRtpG711DurMs] = 100; mINI::Instance()[kUdpRecvSocketBuffer] = 4 * 1024 * 1024; + mINI::Instance()[kMergeFrame] = 1; }); } // namespace RtpProxy diff --git a/src/Common/config.h b/src/Common/config.h index 301592e4..7fb85d4a 100644 --- a/src/Common/config.h +++ b/src/Common/config.h @@ -563,6 +563,8 @@ extern const std::string kGopCache; extern const std::string kRtpG711DurMs; // udp recv socket buffer size extern const std::string kUdpRecvSocketBuffer; +// ps/ts解析后是否等待下一帧以判断本帧是否完整,开启后提高兼容性,但是可能增加延时 +extern const std::string kMergeFrame; } // namespace RtpProxy /** diff --git a/src/Rtp/Decoder.cpp b/src/Rtp/Decoder.cpp index 61cbdd7c..dec48958 100644 --- a/src/Rtp/Decoder.cpp +++ b/src/Rtp/Decoder.cpp @@ -11,6 +11,7 @@ #include "Decoder.h" #include "PSDecoder.h" #include "TSDecoder.h" +#include "Common/config.h" #include "Extension/Factory.h" #if defined(ENABLE_RTPPROXY) || defined(ENABLE_HLS) @@ -122,11 +123,18 @@ void DecoderImp::onDecode(int stream, int codecid, int flags, int64_t pts, int64 WarnL << "Unsupported codec :" << getCodecName(codec); return; } + GET_CONFIG(bool, merge_frame, RtpProxy::kMergeFrame) auto frame = Factory::getFrameFromPtr(codec, (char *)data, bytes, dts, pts); - if (getTrackType(codec) != TrackVideo) { + if (getTrackType(codec) != TrackVideo || !merge_frame) { onFrame(stream, frame); + if (_last_is_keyframe && _video_merge) { + // 上次是关键帧,收到音频后,说明帧收齐了 + _video_merge->flush(); + } return; } + _last_is_keyframe = frame->keyFrame() || frame->configFrame(); + _video_merge = &ref.second; ref.second.inputFrame(frame, [this, stream, codec](uint64_t dts, uint64_t pts, const Buffer::Ptr &buffer, bool) { onFrame(stream, Factory::getFrameFromBuffer(codec, buffer, dts, pts)); }); diff --git a/src/Rtp/Decoder.h b/src/Rtp/Decoder.h index 4902157c..8a8b90a1 100644 --- a/src/Rtp/Decoder.h +++ b/src/Rtp/Decoder.h @@ -59,13 +59,14 @@ private: private: bool _finished = false; bool _have_video = false; + bool _last_is_keyframe = false; Decoder::Ptr _decoder; MediaSinkInterface *_sink; - class FrameMergerImp : public FrameMerger { public: FrameMergerImp() : FrameMerger(FrameMerger::none) {} }; + FrameMergerImp *_video_merge = nullptr; std::unordered_map > _tracks; };