Сохранять выдачу старого GPU до первого IDR замены
This commit is contained in:
1 parent
ae8eeab490
commit
2facdb6949
3 files changed
+13
-1
No files matched your search
@@ -121,6 +121,14 @@ bool CallVideoEncoder::encode(const QImage& image, uint64_t pts, bool forceKey,
|
|||||||
(unsigned long long)m_request, m_switchInputs, (long long)frames.size(), qPrintable(m_replacement->error()));
|
(unsigned long long)m_request, m_switchInputs, (long long)frames.size(), qPrintable(m_replacement->error()));
|
||||||
completion = {m_format.generation, m_request, 0}; m_request = 0; m_pendingBitrate = 0;
|
completion = {m_format.generation, m_request, 0}; m_request = 0; m_pendingBitrate = 0;
|
||||||
m_replacement.reset(); frames.clear(); key = true; m_keyPending = false;
|
m_replacement.reset(); frames.clear(); key = true; m_keyPending = false;
|
||||||
|
} else if (m_replacement && frames.isEmpty()) {
|
||||||
|
// До первого нового IDR продолжаем выдавать только старые кадры с PTS раньше границы замены.
|
||||||
|
// Уже выданный PTS не может обогнать ожидаемый IDR и сделать его устаревшим.
|
||||||
|
QList<LiveEncodedFrame> previous;
|
||||||
|
if (m_encoder->encode(image, pts, false, previous)) {
|
||||||
|
for (auto& frame : previous) if (frame.pts < m_switchPts) frames.push_back(std::move(frame));
|
||||||
|
} else DEBUG_WARN(DEBUG_CATEGORY_CALL, "old GPU failed while replacement is pending request=%llu: %s",
|
||||||
|
(unsigned long long)m_request, qPrintable(m_encoder->error()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!encoded) encoded = m_encoder->encode(image, pts, key, frames);
|
if (!encoded) encoded = m_encoder->encode(image, pts, key, frames);
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ bool LiveVideoEncoder::open(const LiveVideoConfig& config, Backend backend) {
|
|||||||
if (m->forcedKeys) av_dict_set(&options, "forced_idr", "1", 0);
|
if (m->forcedKeys) av_dict_set(&options, "forced_idr", "1", 0);
|
||||||
if (constrained) {
|
if (constrained) {
|
||||||
av_dict_set(&options, "rc", "cbr", 0);
|
av_dict_set(&options, "rc", "cbr", 0);
|
||||||
|
av_dict_set(&options, "skip_frame", "0", 0);
|
||||||
av_dict_set(&options, "profile", config.codec == STREAM_MEDIA_H264 ? "constrained_baseline" : "main", 0);
|
av_dict_set(&options, "profile", config.codec == STREAM_MEDIA_H264 ? "constrained_baseline" : "main", 0);
|
||||||
if (config.codec == STREAM_MEDIA_H265) av_dict_set(&options, "profile_tier", "main", 0);
|
if (config.codec == STREAM_MEDIA_H265) av_dict_set(&options, "profile_tier", "main", 0);
|
||||||
}
|
}
|
||||||
@@ -282,6 +283,9 @@ bool LiveVideoEncoder::open(const LiveVideoConfig& config, Backend backend) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
verified = {frame};
|
verified = {frame};
|
||||||
|
if (constrained) DEBUG_DEBUG(DEBUG_CATEGORY_VIDEO,
|
||||||
|
"call GPU probe name=%s pts=%llu pipeline_frames=%d time_base=%d/%d",
|
||||||
|
name.constData(), (unsigned long long)pts, attempt, c->time_base.num, c->time_base.den);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
output.clear();
|
output.clear();
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ private slots:
|
|||||||
QVERIFY(output.front().key); pts += 1000000;
|
QVERIFY(output.front().key); pts += 1000000;
|
||||||
if (!completion.request) QTest::qWait(33);
|
if (!completion.request) QTest::qWait(33);
|
||||||
} while (!completion.request && deadline.elapsed() < 3000);
|
} while (!completion.request && deadline.elapsed() < 3000);
|
||||||
QCOMPARE(completion.request, uint64_t(2)); QCOMPARE(completion.bitrate, 300000u); QVERIFY(output.key);
|
QCOMPARE(completion.request, uint64_t(2)); QCOMPARE(completion.bitrate, 300000u); QVERIFY(output.front().key);
|
||||||
encoder.close(); QVERIFY(!encoder.requestBitrate(9, 3, 500000));
|
encoder.close(); QVERIFY(!encoder.requestBitrate(9, 3, 500000));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in new issue
Block a user