Browse Source

Keep desktop stream failure visible after draining

stream-multiview
evgeny 1 week ago
parent
commit
4e7b8f5c1a
  1. 5
      doc/stream.txt
  2. 10
      tools/chatgui/src/stream_publish_window.cpp

5
doc/stream.txt

@ -919,6 +919,8 @@ Desktop:
Callback копирует PCM в предвыделенную очередь; DSP/Opus в нём нет. Hardware PTS используется при
наличии, иначе шкала строится по количеству отсчётов. Очередь/возраст ограничены; при разрыве
сбрасываются только неполный PCM-пакет и история компрессора. Mute передаёт тишину.
Fatal ошибка audio encoder завершает публикацию по session ID, без отката видеонастроек;
причина сохраняется в окне управления после FIN. Поздняя ошибка старой сессии игнорируется.
Публикация эксклюзивно занимает микрофон: звонок/рация/запись и публикация запрещают друг другу новый
capture. Прежнее совместное владение микрофоном голосовыми функциями сохраняется.
- transport/stream_bridge владеет независимым stream_publisher; shared C actor выполняет uAV2/RS,
@ -957,7 +959,8 @@ test_stream_publish проверяет реальные encoder/decoder H.264/H.
с прежним decoder, общую публикацию/RS, смену revision, pressure/KEY recovery, FIN и concurrent detach
с балансом tracked allocations. Дополнительный Xvfb/private D-Bus сценарий проверяет реальный экран/окно,
стереомикрофон с двумя разными тонами, сырое превью, закрытие окна управления, неподвижный источник,
смену codec/bitrate/rotation и rollback без смены audio/source_epoch.
смену codec/bitrate/rotation и rollback без смены audio/source_epoch, затем отказ Opus после
подтверждённого KEY с завершением эфира и освобождением microphone lease.
Статистика отправки на экране публикации:
- Отдельный uasync timer общего stream_publisher каждые 100ms делает согласованный TX snapshot.

10
tools/chatgui/src/stream_publish_window.cpp

@ -80,6 +80,7 @@ StreamPublishWindow::StreamPublishWindow(StreamPublishEngine* engine, uint64_t g
m_stats = new QLabel(this); m_stats->setWordWrap(true); m_stats->setMinimumHeight(46); layout->addWidget(m_stats);
m_start = new QPushButton(text("Start stream"), this); layout->addWidget(m_start);
connect(m_start, &QPushButton::clicked, this, [this] {
if (!m_engine->active()) m_status->setProperty("streamError", QString());
if (m_engine->active()) m_engine->stop(); else m_engine->start(m_group, selection()); synchronize();
});
for (auto* box : {m_source, m_mode, m_codec, m_bitrate}) connect(box, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &StreamPublishWindow::apply);
@ -90,8 +91,13 @@ StreamPublishWindow::StreamPublishWindow(StreamPublishEngine* engine, uint64_t g
#endif
connect(engine, &StreamPublishEngine::codecsChanged, this, &StreamPublishWindow::refreshCodecs);
connect(engine, &StreamPublishEngine::configurationChanged, this, &StreamPublishWindow::synchronize);
connect(engine, &StreamPublishEngine::stateChanged, this, [this](const QString& value) { m_status->setText(value); synchronize(); });
connect(engine, &StreamPublishEngine::errorOccurred, this, [this](const QString& value) { m_status->setText(value); });
connect(engine, &StreamPublishEngine::stateChanged, this, [this](const QString& value) {
auto error = m_status->property("streamError").toString();
m_status->setText(error.isEmpty() ? value : value + "\n" + error); synchronize();
});
connect(engine, &StreamPublishEngine::errorOccurred, this, [this](const QString& value) {
m_status->setProperty("streamError", value); m_status->setText(value);
});
connect(engine, &StreamPublishEngine::audioChannelsChanged, this, [this](int channels) { m_inputChannels->setText(channels == 2 ? text("Stereo") : text("Mono")); });
connect(engine, &StreamPublishEngine::telemetryChanged, this, [this](const stream_publisher_status& stats) {
m_stats->setText(text("Video queue: %1 · Inflight: %2 · Send buffer: %3\nACK, all connections, last second: %4")

Loading…
Cancel
Save