Handle AMF periodic keyframes

This commit is contained in:
evgeny committed 2026-10-16 21:52:10 +02:00
1 parent 98d0040b27
commit a63af43e59
1 file changed
+20 -8
+20 -8
View File
@@ -17,6 +17,7 @@ extern "C" {
struct LiveVideoEncoder::Impl {
QString error, name;
LiveVideoConfig config;
int64_t submittedFrames = 0;
#ifdef HAVE_FFMPEG
AVCodecContext* codec = nullptr;
AVBSFContext* filter = nullptr;
@@ -258,12 +259,18 @@ bool LiveVideoEncoder::open(const LiveVideoConfig& config, Backend backend) {
name.constData(), qPrintable(m->error));
break;
}
output.clear();
const uint64_t forcedKeyPts = (1000000 / config.fps) * (maxDelayFrames + 2);
if (!probeKey(forcedKeyPts, output)) {
DEBUG_WARN(DEBUG_CATEGORY_VIDEO, "desktop encoder forced KEY probe failed name=%s error=%s",
name.constData(), qPrintable(m->error));
break;
if (name.endsWith("_amf")) {
DEBUG_INFO(DEBUG_CATEGORY_VIDEO,
"desktop AMF uses periodic IDR name=%s gop_frames=%d forced_key_requests=disabled",
name.constData(), c->gop_size);
} else {
output.clear();
const uint64_t forcedKeyPts = (1000000 / config.fps) * (maxDelayFrames + 2);
if (!probeKey(forcedKeyPts, output)) {
DEBUG_WARN(DEBUG_CATEGORY_VIDEO, "desktop encoder forced KEY probe failed name=%s error=%s",
name.constData(), qPrintable(m->error));
break;
}
}
if (constrained && !verifiedProfile(config, output)) {
m->error = "Encoder output violates the requested profile"; break;
@@ -305,8 +312,12 @@ bool LiveVideoEncoder::encode(const QImage& image, uint64_t pts, bool key, QList
int stride[4] = {static_cast<int>(canvas.bytesPerLine()), 0, 0, 0};
result = sws_scale(m->scale, input, stride, 0, canvas.height(), m->frame->data, m->frame->linesize);
}
m->frame->pts = static_cast<int64_t>(pts); m->frame->pict_type = key ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_NONE;
if (key) m->frame->flags |= AV_FRAME_FLAG_KEY; else m->frame->flags &= ~AV_FRAME_FLAG_KEY;
bool forceKey = key && (!m->name.endsWith("_amf") || m->submittedFrames == 0);
if (key && !forceKey) DEBUG_DEBUG(DEBUG_CATEGORY_VIDEO,
"desktop AMF ignores forced key request; periodic GOP IDR remains active name=%s submitted=%lld",
qPrintable(m->name), (long long)m->submittedFrames);
m->frame->pts = static_cast<int64_t>(pts); m->frame->pict_type = forceKey ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_NONE;
if (forceKey) m->frame->flags |= AV_FRAME_FLAG_KEY; else m->frame->flags &= ~AV_FRAME_FLAG_KEY;
AVFrame* hardware = nullptr;
if (result >= 0 && m->codec->hw_frames_ctx) {
hardware = av_frame_alloc();
@@ -315,6 +326,7 @@ bool LiveVideoEncoder::encode(const QImage& image, uint64_t pts, bool key, QList
if (result >= 0) result = av_frame_copy_props(hardware, m->frame);
}
if (result >= 0) result = avcodec_send_frame(m->codec, hardware ? hardware : m->frame);
if (result >= 0) m->submittedFrames++;
av_frame_free(&hardware);
AVPacket* packet = av_packet_alloc();
if (!packet) result = AVERROR(ENOMEM);