Handle AMF periodic keyframes
This commit is contained in:
1 parent
98d0040b27
commit
a63af43e59
1 file changed
+20
-8
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user