From 053c1c0706ffb13a79bd7b999b2ad809ad2d9e4f Mon Sep 17 00:00:00 2001 From: sladro Date: Mon, 5 Jan 2026 17:32:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AEbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/alarm/actions/snapshot_action.cpp | 7 +++--- plugins/input_rtsp/input_rtsp_node.cpp | 27 ++++++++++++++++++----- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/plugins/alarm/actions/snapshot_action.cpp b/plugins/alarm/actions/snapshot_action.cpp index 17d20ed..11f4639 100644 --- a/plugins/alarm/actions/snapshot_action.cpp +++ b/plugins/alarm/actions/snapshot_action.cpp @@ -46,7 +46,7 @@ inline int PlaneStride(const Frame& f, int idx, int fallback) { bool FillYuv420pFromFrame(const Frame& src, AVFrame* dst) { if (!dst) return false; - if (dst->format != AV_PIX_FMT_YUV420P) return false; + if (dst->format != AV_PIX_FMT_YUV420P && dst->format != AV_PIX_FMT_YUVJ420P) return false; if (src.width <= 0 || src.height <= 0) return false; const int w = src.width; @@ -247,7 +247,8 @@ std::vector SnapshotAction::EncodeJpeg(const std::shared_ptr& fr ctx->width = frame->width; ctx->height = frame->height; ctx->time_base = AVRational{1, 25}; - ctx->pix_fmt = AV_PIX_FMT_YUV420P; + // Some embedded FFmpeg builds expose MJPEG encoder that only accepts YUVJ*. + ctx->pix_fmt = AV_PIX_FMT_YUVJ420P; ctx->color_range = AVCOL_RANGE_JPEG; // Set quality (1-31, lower is better for MJPEG) @@ -263,7 +264,7 @@ std::vector SnapshotAction::EncodeJpeg(const std::shared_ptr& fr AVFrame* av_frame = av_frame_alloc(); av_frame->width = frame->width; av_frame->height = frame->height; - av_frame->format = AV_PIX_FMT_YUV420P; + av_frame->format = AV_PIX_FMT_YUVJ420P; av_frame->color_range = AVCOL_RANGE_JPEG; if (av_frame_get_buffer(av_frame, 32) < 0) { diff --git a/plugins/input_rtsp/input_rtsp_node.cpp b/plugins/input_rtsp/input_rtsp_node.cpp index 28f3335..84130e6 100644 --- a/plugins/input_rtsp/input_rtsp_node.cpp +++ b/plugins/input_rtsp/input_rtsp_node.cpp @@ -650,6 +650,9 @@ private: int read_fail = 0; uint64_t pkt_count = 0; uint64_t decode_fail = 0; + const int64_t step_us = (fps_ > 0) ? (1000000LL / fps_) : 40000LL; + int64_t last_pts_us = 0; + bool have_last_pts = false; while (running_.load()) { if (av_read_frame(fmt_ctx, pkt) < 0) { if (++read_fail >= 50) break; @@ -663,18 +666,32 @@ private: } ++pkt_count; + int64_t raw_ts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts; + int64_t pts_us = 0; + if (raw_ts == AV_NOPTS_VALUE) { + pts_us = have_last_pts ? (last_pts_us + step_us) : 0; + } else { + pts_us = av_rescale_q(raw_ts, time_base, {1, 1000000}); + if (pts_us < 0) pts_us = 0; + if (have_last_pts && pts_us <= last_pts_us) pts_us = last_pts_us + step_us; + } + last_pts_us = pts_us; + have_last_pts = true; + if (pkt_count <= 3 || pkt_count % 300 == 0) { std::cout << "[input_rtsp] recv pkt#" << pkt_count << " size=" << pkt->size - << " pts=" << pkt->pts - << " dts=" << pkt->dts + << " pts="; + if (pkt->pts == AV_NOPTS_VALUE) std::cout << "NOPTS"; + else std::cout << pkt->pts; + std::cout << " dts="; + if (pkt->dts == AV_NOPTS_VALUE) std::cout << "NOPTS"; + else std::cout << pkt->dts; + std::cout << " pts_us=" << pts_us << " key=" << ((pkt->flags & AV_PKT_FLAG_KEY) ? 1 : 0) << "\n"; } - int64_t pts_us = pkt->pts == AV_NOPTS_VALUE ? 0 - : av_rescale_q(pkt->pts, time_base, {1, 1000000}); - if (IsAnnexB(pkt->data, static_cast(pkt->size))) { if (pkt_count <= 10) { int sc = GetAnnexBStartCodeSize(pkt->data, static_cast(pkt->size));