修bug
Some checks are pending
CI / host-build (push) Waiting to run
CI / rk3588-cross-build (push) Waiting to run

This commit is contained in:
sladro 2026-01-05 17:32:06 +08:00
parent 359d523dbb
commit 053c1c0706
2 changed files with 26 additions and 8 deletions

View File

@ -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<uint8_t> SnapshotAction::EncodeJpeg(const std::shared_ptr<Frame>& 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<uint8_t> SnapshotAction::EncodeJpeg(const std::shared_ptr<Frame>& 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) {

View File

@ -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<size_t>(pkt->size))) {
if (pkt_count <= 10) {
int sc = GetAnnexBStartCodeSize(pkt->data, static_cast<size_t>(pkt->size));