|
|
|
|
@ -176,10 +176,10 @@ StreamPublishEngine::StreamPublishEngine(QObject* parent) : QObject(parent), m(s
|
|
|
|
|
}); |
|
|
|
|
#ifdef HAVE_STREAM_CAPTURE |
|
|
|
|
m->imageThread.reset(QThread::create([this] { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "desktop image worker started tid=%llu", (unsigned long long)(quintptr)QThread::currentThreadId()); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "desktop image worker started tid=%llu", (unsigned long long)(quintptr)QThread::currentThreadId()); |
|
|
|
|
imageLoop(); |
|
|
|
|
m->imageProgress("release-thread-resources"); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "desktop image loop returned; releasing thread resources frames=%llu tid=%llu", |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "desktop image loop returned; releasing thread resources frames=%llu tid=%llu", |
|
|
|
|
(unsigned long long)m->imageFrames.load(), (unsigned long long)(quintptr)QThread::currentThreadId()); |
|
|
|
|
})); |
|
|
|
|
m->imageThread->start(); |
|
|
|
|
@ -189,7 +189,7 @@ StreamPublishEngine::StreamPublishEngine(QObject* parent) : QObject(parent), m(s
|
|
|
|
|
} |
|
|
|
|
StreamPublishEngine::~StreamPublishEngine() { |
|
|
|
|
const int64_t destroyAt = monotonicUs(); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "desktop publisher destruction begin id=%llu running=%d stopping=%d image_stage=%s image_frames=%llu", |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "desktop publisher destruction begin id=%llu running=%d stopping=%d image_stage=%s image_frames=%llu", |
|
|
|
|
(unsigned long long)m->id, m->running.load(), m->stopping, m->imageStage.load(), (unsigned long long)m->imageFrames.load()); |
|
|
|
|
m->destroying = true; blockSignals(true); |
|
|
|
|
stop(); m_timer.stop(); m_previewTimer.stop(); |
|
|
|
|
@ -204,17 +204,13 @@ StreamPublishEngine::~StreamPublishEngine() {
|
|
|
|
|
m->stopping, m->imageJoined.load(), m->imageStage.load()); |
|
|
|
|
QEventLoop loop; QTimer timer; |
|
|
|
|
int64_t reportAt = destroyAt; |
|
|
|
|
bool firstPoll = true; |
|
|
|
|
connect(&timer, &QTimer::timeout, &loop, [this, &loop, destroyAt, &reportAt, &firstPoll] { |
|
|
|
|
if (firstPoll) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "desktop publisher destruction GUI timer active"); firstPoll = false; |
|
|
|
|
} |
|
|
|
|
connect(&timer, &QTimer::timeout, &loop, [this, &loop, destroyAt, &reportAt] { |
|
|
|
|
const bool imageDone = finishImageStop(); |
|
|
|
|
if (finishStop() && imageDone) { loop.quit(); return; } |
|
|
|
|
const int64_t now = monotonicUs(); |
|
|
|
|
if (now - reportAt < 5000000) return; |
|
|
|
|
reportAt = now; |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "desktop publisher destruction waiting elapsed_ms=%lld stopping=%d workers_joined=%d " |
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_STREAM, "desktop publisher destruction waiting elapsed_ms=%lld stopping=%d workers_joined=%d " |
|
|
|
|
"video_stage=%s image_joined=%d image_stage=%s image_stage_age_ms=%lld image_frames=%llu microphone_closing=%d", |
|
|
|
|
(long long)((now - destroyAt) / 1000), m->stopping, m->workersJoined.load(), m->videoStage.load(), |
|
|
|
|
m->imageJoined.load(), m->imageStage.load(), (long long)((now - m->imageStageAt.load()) / 1000), |
|
|
|
|
@ -222,12 +218,12 @@ StreamPublishEngine::~StreamPublishEngine() {
|
|
|
|
|
}); |
|
|
|
|
timer.start(10); |
|
|
|
|
const int result = loop.exec(QEventLoop::ExcludeUserInputEvents); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "desktop publisher destruction GUI loop exited result=%d stopping=%d image_joined=%d", |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "desktop publisher destruction GUI loop exited result=%d stopping=%d image_joined=%d", |
|
|
|
|
result, m->stopping, m->imageJoined.load()); |
|
|
|
|
if (m->stopping || !m->imageJoined) |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_DEBUG, "desktop publisher destruction GUI loop exited before worker cleanup completed"); |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop publisher destruction GUI loop exited before worker cleanup completed"); |
|
|
|
|
} |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "desktop publisher destruction complete elapsed_ms=%lld", (long long)((monotonicUs() - destroyAt) / 1000)); |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "desktop publisher destruction complete elapsed_ms=%lld", (long long)((monotonicUs() - destroyAt) / 1000)); |
|
|
|
|
} |
|
|
|
|
bool StreamPublishEngine::supported() { |
|
|
|
|
#ifdef HAVE_STREAM_CAPTURE |
|
|
|
|
@ -721,13 +717,13 @@ bool StreamPublishEngine::finishStop() {
|
|
|
|
|
bool StreamPublishEngine::finishImageStop() { |
|
|
|
|
if (m->imageJoined) return true; |
|
|
|
|
if (!m->imageThread) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_DEBUG, "desktop image worker missing before native thread completion"); |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop image worker missing before native thread completion"); |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
if (!m->imageThread->wait(0)) return false; |
|
|
|
|
m->imageThread.reset(); |
|
|
|
|
m->imageJoined = true; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "desktop image native thread cleanup completed frames=%llu", |
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_STREAM, "desktop image native thread cleanup completed frames=%llu", |
|
|
|
|
(unsigned long long)m->imageFrames.load()); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|