|
|
|
|
@ -731,6 +731,29 @@ private slots:
|
|
|
|
|
if (initialFailure) { QVERIFY(requests.isEmpty()); QCOMPARE(hardwareOpens.load(), 0u); QCOMPARE(softwareOpens.load(), 0u); QCOMPARE(audioEncodes.load(), 0u); } |
|
|
|
|
#else |
|
|
|
|
QSKIP("Capture and encoder instrumentation unavailable"); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
void captureConversionFailure() { |
|
|
|
|
#if defined(HAVE_STREAM_CAPTURE) && defined(TEST_NULL_AUDIO) |
|
|
|
|
if (!qEnvironmentVariableIsSet("UTUN_TEST_SCREEN_CAPTURE")) QSKIP("Run under isolated Xvfb"); |
|
|
|
|
StreamPublishEngine engine; |
|
|
|
|
StreamPublishConfig config; config.audio = false; config.showCursor = false; |
|
|
|
|
config.video.width = 320; config.video.height = 180; config.video.fps = 15; |
|
|
|
|
for (const auto& source : engine.sources()) if (source.kind == StreamVideoSource::Screen) { config.source = source; break; } |
|
|
|
|
QVERIFY(!config.source.id.isEmpty()); |
|
|
|
|
QSignalSpy errors(&engine, &StreamPublishEngine::errorOccurred); |
|
|
|
|
QVERIFY(engine.start(group, config)); |
|
|
|
|
auto* sink = engine.findChild<QVideoSink*>(); QVERIFY(sink); |
|
|
|
|
// Валидная оболочка кадра, но повреждённый JPEG: ошибка image worker обязана остановить текущий source.
|
|
|
|
|
QVideoFrame frame(QVideoFrameFormat(QSize(16, 16), QVideoFrameFormat::Format_Jpeg)); |
|
|
|
|
QVERIFY(frame.isValid()); QVERIFY(frame.map(QVideoFrame::WriteOnly)); |
|
|
|
|
memset(frame.bits(0), 0, frame.mappedBytes(0)); frame.unmap(); |
|
|
|
|
sink->setVideoFrame(frame); |
|
|
|
|
QTRY_VERIFY_WITH_TIMEOUT(!errors.isEmpty(), 3000); |
|
|
|
|
QVERIFY(errors.front().front().toString().contains("Video frame conversion failed")); |
|
|
|
|
QTRY_VERIFY_WITH_TIMEOUT(!engine.active(), 5000); |
|
|
|
|
#else |
|
|
|
|
QSKIP("Capture fixture unavailable"); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
void screenAndWindowCapture() { |
|
|
|
|
|