End desktop publication on fatal audio worker failure
This commit is contained in:
1 parent
b25070acbd
commit
470001bbab
2 files changed
+16
-5
No files matched your search
@@ -250,7 +250,7 @@ bool StreamPublishEngine::start(uint64_t group, const StreamPublishConfig& confi
|
||||
try {
|
||||
m->videoThread = std::thread(&StreamPublishEngine::videoLoop, this);
|
||||
if (config.audio) m->audioThread = std::thread(&StreamPublishEngine::audioLoop, this);
|
||||
} catch (const std::system_error& error) { sourceFailed(m->generation, QString::fromUtf8(error.what())); return false; }
|
||||
} catch (const std::system_error& error) { publicationFailed(m->id, QString::fromUtf8(error.what())); return false; }
|
||||
if (!openSource(config) || (config.audio && !openMicrophone())) {
|
||||
sourceFailed(m->generation, text("Could not open the selected capture device")); return false;
|
||||
}
|
||||
@@ -288,6 +288,13 @@ void StreamPublishEngine::sourceFailed(uint64_t generation, const QString& error
|
||||
if (rollback) reconfigure(restore); else stop();
|
||||
}
|
||||
|
||||
/* Ошибку общего audio worker нельзя исправить заменой только video encoder. */
|
||||
void StreamPublishEngine::publicationFailed(uint64_t id, const QString& error) {
|
||||
if (id != m->id || !m->running) return;
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop publication failed id=%llu reason=%s", (unsigned long long)id, qPrintable(error));
|
||||
emit errorOccurred(error); stop();
|
||||
}
|
||||
|
||||
/* Сначала callbacks, затем workers; FIN не обгоняет уже принятые access units. */
|
||||
void StreamPublishEngine::stop() {
|
||||
if (!m->running.exchange(false)) return;
|
||||
@@ -303,9 +310,11 @@ bool StreamPublishEngine::openMicrophone() {
|
||||
m_capture.close();
|
||||
m->audioAnchor = -1; m->audioFrames = 0;
|
||||
auto config = this->config(); auto* context = SoundManager::instance()->context();
|
||||
if (!context) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop stream audio context unavailable"); return false; }
|
||||
if (!context) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop stream audio context unavailable"); m_capture.retryLater(); return false; }
|
||||
ma_device_id device; bool selected = SoundManager::deviceId(config.microphone, &device);
|
||||
if (!config.microphone.isEmpty() && !selected) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop selected microphone ID is unavailable"); return false; }
|
||||
if (!config.microphone.isEmpty() && !selected) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop selected microphone ID is unavailable"); m_capture.retryLater(); return false;
|
||||
}
|
||||
for (int channels : {2, 1}) {
|
||||
ma_device_config capture = ma_device_config_init(ma_device_type_capture);
|
||||
capture.capture.format = ma_format_s16; capture.capture.channels = channels; capture.sampleRate = 48000;
|
||||
@@ -347,12 +356,13 @@ void StreamPublishEngine::captureAudio(const void* input, unsigned frames) {
|
||||
}
|
||||
|
||||
void StreamPublishEngine::audioLoop() {
|
||||
const uint64_t id = m->id;
|
||||
auto* encoder = opus_codec_encoder_create(48000, 2); auto* compressor = audio_compressor_create();
|
||||
int result = encoder && compressor ? opus_codec_encoder_application_set(encoder, OPUS_CODEC_APP_AUDIO) : -1;
|
||||
if (result >= 0) result = opus_codec_encoder_bitrate_set(encoder, 128000);
|
||||
if (result < 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "desktop stream audio encoder initialization failed");
|
||||
QMetaObject::invokeMethod(this, [this] { sourceFailed(m->generation, text("Audio encoder initialization failed")); });
|
||||
QMetaObject::invokeMethod(this, [this, id] { publicationFailed(id, text("Audio encoder initialization failed")); });
|
||||
} else {
|
||||
int16_t pcm[1920]{}; unsigned used = 0; uint64_t sequence = 0;
|
||||
int64_t pts = 0, expected = -1, lastSent = -1; int settings[3] = {-1, -1, -1};
|
||||
@@ -396,7 +406,7 @@ void StreamPublishEngine::audioLoop() {
|
||||
used = 0;
|
||||
}
|
||||
if (result < 0) {
|
||||
QMetaObject::invokeMethod(this, [this] { sourceFailed(m->generation, text("Audio encoding failed")); }); break;
|
||||
QMetaObject::invokeMethod(this, [this, id] { publicationFailed(id, text("Audio encoding failed")); }); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user