From 2ad8a934e0ea0862f2c0a98e45efb3bfa811fd4c Mon Sep 17 00:00:00 2001 From: sladro Date: Tue, 6 Jan 2026 16:42:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=80=A7=E8=83=BD=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8Dmp4=E6=92=AD=E6=94=BE=E9=80=9F=E5=BA=A6?= =?UTF-8?q?=E4=B8=8D=E5=AF=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/alarm/actions/clip_action.cpp | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/plugins/alarm/actions/clip_action.cpp b/plugins/alarm/actions/clip_action.cpp index d95ff25..6fe25fb 100644 --- a/plugins/alarm/actions/clip_action.cpp +++ b/plugins/alarm/actions/clip_action.cpp @@ -251,8 +251,10 @@ std::string ClipAction::ProcessClipFromPackets(const std::vectortime_base = AVRational{1, 1000}; - stream->avg_frame_rate = AVRational{std::max(1, fps_), 1}; + const int fps_eff = std::max(1, (first->codec->fps > 0 ? first->codec->fps : fps_)); + // Use a stable timescale to avoid rounding drift and "fast playback" caused by bad source PTS. + stream->time_base = AVRational{1, 90000}; + stream->avg_frame_rate = AVRational{fps_eff, 1}; stream->r_frame_rate = stream->avg_frame_rate; stream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; stream->codecpar->codec_id = cid; @@ -312,10 +314,8 @@ std::string ClipAction::ProcessClipFromPackets(const std::vector 0) ? (1000LL / std::max(1, fps_)) : 40; + const int64_t frame_dur = av_rescale_q(1, AVRational{1, fps_eff}, stream->time_base); + int64_t frame_idx = 0; for (size_t i = start_idx; i < metas.size(); ++i) { const auto& m = metas[i]; @@ -323,14 +323,7 @@ std::string ClipAction::ProcessClipFromPackets(const std::vectorcodec || m->pkt.data.empty()) continue; if (m->pkt.pts_ms <= 0) continue; - if (!have_first) { - first_pts = m->pkt.pts_ms; - have_first = true; - } - int64_t pts = m->pkt.pts_ms - first_pts; - if (pts < 0) pts = 0; - if (pts <= last_pts) pts = last_pts + 1; - last_pts = pts; + const int64_t pts = av_rescale_q(frame_idx, AVRational{1, fps_eff}, stream->time_base); std::vector sample = m->pkt.data; if (cid == AV_CODEC_ID_H264 && HasAnnexBStartCode(sample.data(), sample.size())) { @@ -353,6 +346,8 @@ std::string ClipAction::ProcessClipFromPackets(const std::vector