Guard capture-only image queue and test publication without Multimedia

This commit is contained in:
evgeny committed 2026-10-28 00:58:59 +01:00
1 parent fe7cd73646
commit 138f6071b0
2 files changed
+31 -5

No files matched your search

+7 -5
View File
@@ -91,11 +91,6 @@ struct StreamPublishEngine::Impl {
std::atomic<unsigned> audioDropped{0}, audioMissing{0};
std::atomic<int64_t> lastAudioAt{0};
AudioEventQueue<Audio, 32> audio;
std::condition_variable imageWake;
QVideoFrame imageInput;
uint64_t imageGeneration = 0;
int64_t imagePts = -1;
bool imagePending = false, imageStop = false, imageDrawCursor = false;
uint64_t id = 0, group = 0, generation = 0, sourceGeneration = 0, confirmedGeneration = 0, frameGeneration = 0, audioSequence = 0;
int64_t origin = 0, started = 0, framePts = -1, backendOrigin = -1, backendAnchor = -1;
int64_t audioAnchor = -1;
@@ -129,6 +124,12 @@ struct StreamPublishEngine::Impl {
QList<int> codecs;
stream_publisher_status stats{};
#ifdef HAVE_STREAM_CAPTURE
// Очередь преобразования принадлежит capture backend; без Qt Multimedia нет ни QVideoFrame, ни её worker.
std::condition_variable imageWake;
QVideoFrame imageInput;
uint64_t imageGeneration = 0;
int64_t imagePts = -1;
bool imagePending = false, imageStop = false, imageDrawCursor = false;
std::unique_ptr<QMediaCaptureSession> session;
std::unique_ptr<QVideoSink> sink;
std::unique_ptr<QCamera> camera;
@@ -209,6 +210,7 @@ StreamPublishEngine::StreamPublishEngine(QObject* parent) : QObject(parent), m(s
m->imageThread->start();
#else
m->imageJoined = true;
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "desktop stream capture unavailable in this build; image worker disabled");
#endif
}
StreamPublishEngine::~StreamPublishEngine() {
@@ -195,6 +195,30 @@ private slots:
sqlite3_finalize(statement); QVERIFY(group); QVERIFY(gui_stream_attach(inst)); uasync_mark_running(ua);
connect(&poll, &QTimer::timeout, this, [this] { uasync_poll(ua, 0); }); poll.start(1);
}
#ifndef HAVE_STREAM_CAPTURE
void captureUnavailableRefusesPublication() {
StreamPublishEngine engine;
QVERIFY(!StreamPublishEngine::supported()); QVERIFY(StreamPublishEngine::sources().isEmpty());
QVERIFY(engine.codecs().isEmpty()); QVERIFY(!engine.previewFrame().isValid());
StreamPublishWindow window(&engine, group); window.show();
auto* source = window.findChild<QComboBox*>(QStringLiteral("streamVideoSource"));
QVERIFY(source); QCOMPARE(source->count(), 0);
QPushButton* start = nullptr;
for (auto* button : window.findChildren<QPushButton*>())
if (button->text() == QCoreApplication::translate("ChatGui", "Start stream")) start = button;
QVERIFY(start); QVERIFY(!start->isEnabled());
QSignalSpy errors(&engine, &StreamPublishEngine::errorOccurred);
QSignalSpy states(&engine, &StreamPublishEngine::stateChanged);
QTest::mouseClick(start, Qt::LeftButton); QCOMPARE(errors.count(), 0);
QVERIFY(!engine.start(group, StreamPublishConfig{}));
QCOMPARE(errors.count(), 1); QVERIFY(!errors.front().front().toString().isEmpty());
QTest::qWait(120); QVERIFY(!engine.active()); QVERIFY(!engine.running()); QCOMPARE(engine.group(), uint64_t(0));
QCOMPARE(states.count(), 0); QCOMPARE(engine.videoBitrate(), uint64_t(0)); QCOMPARE(engine.videoMaxQp(), -1);
AudioCaptureLease microphone; QVERIFY(microphone.acquire()); microphone.release();
engine.stop(); engine.stop(); QVERIFY(!engine.active());
DEBUG_INFO(DEBUG_CATEGORY_STREAM, "disabled capture verified: UI start disabled, API refused, actor and microphone unowned");
}
#endif
void amfDriverDiagnosticsRespectCategoryFilter() {
#ifdef HAVE_FFMPEG
video_ffmpeg_init();