diff --git a/tools/chatgui/src/mainwindow.cpp b/tools/chatgui/src/mainwindow.cpp index b73d9c6d..b4e9ff9f 100644 --- a/tools/chatgui/src/mainwindow.cpp +++ b/tools/chatgui/src/mainwindow.cpp @@ -783,7 +783,7 @@ void MainWindow::onCallAccepted(quint64 callId) { if (request) { request->inst = gui_bridge_get_inst(); request->call_id = callId; gui_bridge_post_uasync_fn(call_hangup_trampoline, request); } else DEBUG_ERROR(DEBUG_CATEGORY_CALL, "desktop failed call hangup allocation failed"); closeCallWindow(callId); - QMessageBox::information(this, QStringLiteral("vibechat"), QCoreApplication::translate("ChatGui", "The microphone is used by a call, radio or recording")); + QMessageBox::information(this, QStringLiteral("vibechat"), QCoreApplication::translate("ChatGui", "The microphone is used by another operation")); } } diff --git a/tools/chatgui/src/stream_publish_engine.cpp b/tools/chatgui/src/stream_publish_engine.cpp index aac5af6b..b84ba8b3 100644 --- a/tools/chatgui/src/stream_publish_engine.cpp +++ b/tools/chatgui/src/stream_publish_engine.cpp @@ -194,7 +194,7 @@ bool StreamPublishEngine::start(uint64_t group, const StreamPublishConfig& confi if (!supported() || !codecs().contains(config.video.codec)) { emit errorOccurred(text("Video capture or encoder is unavailable")); return false; } if (config.audio && !m_microphone.acquire()) { DEBUG_WARN(DEBUG_CATEGORY_STREAM, "desktop publication blocked: microphone owned by another operation"); - emit errorOccurred(text("The microphone is used by a call, radio or recording")); return false; + emit errorOccurred(text("The microphone is used by another operation")); return false; } { std::lock_guard guard(m->lock); m->wanted = config; m->good = {}; m->hasGood = m->rollingBack = false; m->generation++; m->confirmedGeneration = 0; @@ -214,7 +214,8 @@ bool StreamPublishEngine::start(uint64_t group, const StreamPublishConfig& confi if (!openSource(config) || (config.audio && !openMicrophone())) { sourceFailed(m->generation, text("Could not open the selected capture device")); return false; } - emit stateChanged(text("Starting stream…")); emit configurationChanged(); return true; + emit stateChanged(config.source.id == "portal" ? text("Select a screen or window in the system dialog") : text("Starting stream…")); + emit configurationChanged(); return true; } bool StreamPublishEngine::reconfigure(const StreamPublishConfig& config) { @@ -453,9 +454,11 @@ void StreamPublishEngine::tick() { emit stateChanged(text("Stopped")); emit configurationChanged(); return; } if (m->running) { - bool confirmed; int64_t started; - { std::lock_guard guard(m->lock); confirmed = m->confirmedGeneration == m->generation; started = m->started; } - if (!confirmed && monotonicUs() - started > 8000000) sourceFailed(m->generation, text("Timed out waiting for the first video frame")); + bool confirmed, waitingSelection; int64_t started; + { std::lock_guard guard(m->lock); confirmed = m->confirmedGeneration == m->generation; started = m->started; + waitingSelection = m->wanted.source.id == "portal" && m->framePts < 0; } + if (!confirmed && !waitingSelection && monotonicUs() - started > 8000000) + sourceFailed(m->generation, text("Timed out waiting for the first video frame")); if (m->wanted.audio && m_capture.needsRecovery()) { m_capture.close(); m_capture.retryLater(); } if (m->wanted.audio && m_capture.retryReady()) openMicrophone(); } diff --git a/tools/chatgui/src/stream_publish_window.cpp b/tools/chatgui/src/stream_publish_window.cpp index f625ae0d..f6130a66 100644 --- a/tools/chatgui/src/stream_publish_window.cpp +++ b/tools/chatgui/src/stream_publish_window.cpp @@ -59,7 +59,7 @@ StreamPublishWindow::StreamPublishWindow(StreamPublishEngine* engine, uint64_t g for (int angle : {0, 90, 270}) { auto* button = new QPushButton(QStringLiteral("%1°").arg(angle), settings); button->setCheckable(true); button->setFixedSize(66, 34); QPixmap icon(20, 20); icon.fill(Qt::transparent); QPainter painter(&icon); - painter.translate(10, 10); painter.rotate(angle); painter.setPen(QPen(QColor("#e53935"), 3)); painter.drawLine(-6, -6, 6, -6); + painter.translate(10, 10); painter.rotate(-angle); painter.setPen(QPen(QColor("#e53935"), 3)); painter.drawLine(-6, -6, 6, -6); painter.setPen(QPen(palette().color(QPalette::Text), 1)); painter.drawLine(-6, -4, -6, 6); painter.drawLine(6, -4, 6, 6); painter.drawLine(-6, 6, 6, 6); painter.end(); button->setIcon(QIcon(icon)); button->setToolTip(text("The red edge marks the top for viewers")); button->setStyleSheet("QPushButton:checked { background: #1976d2; color: white; }"); @@ -137,6 +137,13 @@ void StreamPublishWindow::synchronize() { && m_sources[i].id == config.source.id && m_sources[i].window == config.source.window) m_source->setCurrentIndex(i); for (int i = 0; i < m_mode->count(); i++) if (m_mode->itemData(i).toList() == QVariantList{config.video.width, config.video.height, config.video.fps}) m_mode->setCurrentIndex(i); m_codec->setCurrentIndex(m_codec->findData(config.video.codec)); + int automatic = std::clamp(config.video.width * config.video.height * config.video.fps / 11, 250000, 16000000); + int bitrateIndex = config.video.bitrate == automatic && m_bitrate->currentData().toInt() == 0 ? 0 : m_bitrate->findData(config.video.bitrate); + if (bitrateIndex < 0) { + m_bitrate->addItem(QStringLiteral("%1 Mbit/s").arg(config.video.bitrate / 1000000.0, 0, 'f', 2), config.video.bitrate); + bitrateIndex = m_bitrate->count() - 1; + } + m_bitrate->setCurrentIndex(bitrateIndex); if (auto* button = m_rotation->button(config.video.rotation)) button->setChecked(true); m_audio->setChecked(config.audio); m_microphone->setCurrentIndex(m_microphone->findData(config.microphone)); }