Fix AMF live encoder startup probe
This commit is contained in:
1 parent
2a439754ba
commit
98d0040b27
1 file changed
+44
-6
@@ -181,6 +181,15 @@ bool LiveVideoEncoder::open(const LiveVideoConfig& config, Backend backend) {
|
||||
av_dict_set(&options, "preset", "p1", 0); av_dict_set(&options, "tune", "ull", 0);
|
||||
av_dict_set(&options, "zerolatency", "1", 0); av_dict_set(&options, "rc-lookahead", "0", 0);
|
||||
av_dict_set(&options, "forced-idr", "1", 0);
|
||||
} else if (name.endsWith("_amf")) {
|
||||
av_dict_set(&options, "usage", "ultralowlatency", 0);
|
||||
av_dict_set(&options, "quality", "speed", 0);
|
||||
av_dict_set(&options, "async_depth", "1", 0);
|
||||
bool forceIdr = config.codec == STREAM_MEDIA_H264 || config.codec == STREAM_MEDIA_H265;
|
||||
if (forceIdr) av_dict_set(&options, "forced_idr", "1", 0);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_VIDEO,
|
||||
"desktop AMF low latency settings name=%s usage=ultralowlatency quality=speed async_depth=1 forced_idr=%d",
|
||||
name.constData(), forceIdr);
|
||||
} else if (name == "libvpx-vp9" || name == "libaom-av1") {
|
||||
av_dict_set(&options, "deadline", "realtime", 0); av_dict_set(&options, "cpu-used", "8", 0);
|
||||
av_dict_set(&options, "lag-in-frames", "0", 0); av_dict_set(&options, "row-mt", "1", 0);
|
||||
@@ -215,16 +224,45 @@ bool LiveVideoEncoder::open(const LiveVideoConfig& config, Backend backend) {
|
||||
}
|
||||
if (!pass) {
|
||||
QImage probe(config.width, config.height, QImage::Format_RGB32); probe.fill(Qt::black);
|
||||
constexpr int maxDelayFrames = 4;
|
||||
auto probeKey = [&](uint64_t pts, QList<LiveEncodedFrame>& verified) {
|
||||
const uint64_t frameDuration = 1000000 / config.fps;
|
||||
QList<LiveEncodedFrame> output;
|
||||
int received = 0;
|
||||
for (int attempt = 0; attempt <= maxDelayFrames; attempt++) {
|
||||
if (!encode(probe, pts + frameDuration * attempt, attempt == 0, output)) return false;
|
||||
received += static_cast<int>(output.size());
|
||||
for (const auto& frame : output) {
|
||||
if (frame.pts != pts) continue;
|
||||
if (!frame.key) {
|
||||
m->error = "Encoder did not honor the requested key frame";
|
||||
DEBUG_WARN(DEBUG_CATEGORY_VIDEO,
|
||||
"desktop encoder probe returned non-key name=%s pts=%llu attempt=%d received=%d",
|
||||
name.constData(), (unsigned long long)pts, attempt, received);
|
||||
return false;
|
||||
}
|
||||
verified = {frame};
|
||||
return true;
|
||||
}
|
||||
output.clear();
|
||||
}
|
||||
m->error = "Encoder did not produce a key frame within the startup probe limit";
|
||||
DEBUG_WARN(DEBUG_CATEGORY_VIDEO,
|
||||
"desktop encoder probe key delayed beyond limit name=%s pts=%llu max_delay_frames=%d received=%d",
|
||||
name.constData(), (unsigned long long)pts, maxDelayFrames, received);
|
||||
return false;
|
||||
};
|
||||
QList<LiveEncodedFrame> output;
|
||||
if (!encode(probe, 0, true, output) || output.isEmpty() || !output.front().key) {
|
||||
if (m->error.isEmpty()) m->error = "Encoder did not produce an immediate key frame";
|
||||
DEBUG_WARN(DEBUG_CATEGORY_VIDEO, "desktop encoder probe lacks immediate KEY name=%s error=%s", name.constData(), qPrintable(m->error));
|
||||
if (!probeKey(0, output)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_VIDEO, "desktop encoder initial KEY probe failed name=%s error=%s",
|
||||
name.constData(), qPrintable(m->error));
|
||||
break;
|
||||
}
|
||||
output.clear();
|
||||
if (!encode(probe, 1000000 / config.fps, true, output) || output.isEmpty() || !output.front().key) {
|
||||
if (m->error.isEmpty()) m->error = "Encoder cannot produce an independent key frame on request";
|
||||
DEBUG_WARN(DEBUG_CATEGORY_VIDEO, "desktop encoder cannot force an independent KEY name=%s error=%s", name.constData(), qPrintable(m->error));
|
||||
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)) {
|
||||
|
||||
Reference in new issue
Block a user