Browse Source

Use four CPU encoder workers and retain GPU priority with software fallback

stream-multiview
evgeny 5 days ago
parent
commit
dc22014bcc
  1. 2
      tools/chatgui/src/call_video_encoder.cpp
  2. 4
      tools/chatgui/src/call_video_encoder.h
  3. 17
      tools/chatgui/src/live_video_encoder.cpp

2
tools/chatgui/src/call_video_encoder.cpp

@ -17,7 +17,7 @@ bool CallVideoEncoder::open(const call_video_format& format, uint32_t bitrate, c
config.bitrate = bitrate; config.references = 1; config.backend = backend;
config.profile = format.codec == CALL_VIDEO_H264 ? LiveVideoProfile::H264ConstrainedBaseline : LiveVideoProfile::H265Main;
auto candidate = std::make_unique<LiveVideoEncoder>();
if (!candidate->open(config, backend.isEmpty() ? LiveVideoEncoder::Backend::HardwareOnly : LiveVideoEncoder::Backend::Automatic)) {
if (!candidate->open(config, LiveVideoEncoder::Backend::Automatic)) {
m_error = candidate->error(); DEBUG_ERROR(DEBUG_CATEGORY_CALL, "call video open failed: %s", qPrintable(m_error)); return false;
}
close(); m_encoder = std::move(candidate); m_config = config; m_config.backend = m_encoder->name(); m_format = format;

4
tools/chatgui/src/call_video_encoder.h

@ -1,7 +1,7 @@
/* Кодер видеотрека звонка; только video worker, без камеры, транспорта и таймеров.
* Смена bitrate ожидает ближайший IDR (период <= 1с по capture PTS). Новый encoder
* получает поток после полного drain старого; completion выдаётся после проверки нового IDR. Выбирается GPU;
* явный backend позволяет отдельно проверять software в тестах. Completion передаётся в uasync
* получает поток после полного drain старого; completion выдаётся после проверки нового IDR. Приоритет GPU, затем CPU;
* явный backend фиксирует выбор для теста/замены. Completion передаётся в uasync
* независимо от admission видео. PTS, generation и frame_id принадлежат владельцу.
* open получает согласованный call_video_format; соответствие level/размера/FPS
* проверяет общий модуль, фактический bitstream — LiveVideoEncoder. CAPS проверяет владелец. */

17
tools/chatgui/src/live_video_encoder.cpp

@ -166,7 +166,7 @@ bool LiveVideoEncoder::open(const LiveVideoConfig& config, Backend backend) {
c->bit_rate = config.bitrate; c->rc_max_rate = config.bitrate;
if (config.maxQp >= 0) { c->qmin = 0; c->qmax = config.maxQp; }
c->rc_buffer_size = config.vbvBits ? config.vbvBits : config.bitrate / 4;
c->gop_size = config.fps; c->max_b_frames = 0; c->thread_count = 2;
c->gop_size = config.fps; c->max_b_frames = 0; c->thread_count = 4;
if (config.references) c->refs = config.references;
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER | AV_CODEC_FLAG_CLOSED_GOP;
if (constrained) {
@ -195,14 +195,12 @@ bool LiveVideoEncoder::open(const LiveVideoConfig& config, Backend backend) {
if (name == "libx264" || name == "libx265") {
av_dict_set(&options, "preset", "ultrafast", 0); av_dict_set(&options, "tune", "zerolatency", 0);
av_dict_set(&options, "forced-idr", "1", 0);
const int workers = std::clamp(av_cpu_count(), 1, 4);
QByteArray params = name == "libx264" ? "scenecut=0:open-gop=0:repeat-headers=0"
const int workers = 4;
QByteArray params = name == "libx264" ? "threads=4:sliced-threads=1:scenecut=0:open-gop=0:repeat-headers=0"
: "bframes=0:rc-lookahead=0:open-gop=0:frame-threads=1:wpp=1:log-level=error:pools=" + QByteArray::number(workers);
if (name == "libx265")
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "live HEVC parallelism workers=%d frame_threads=1 wpp=1 cpu_count=%d",
workers, av_cpu_count());
DEBUG_INFO(DEBUG_CATEGORY_VIDEO, "live CPU parallelism encoder=%s workers=%d mode=%s cpu_count=%d",
name.constData(), workers, name == "libx264" ? "sliced" : "wpp/frame-threads=1", av_cpu_count());
if (constrained) {
c->thread_count = 1;
av_dict_set(&options, "profile", name == "libx264" ? "baseline" : "main", 0);
// Оба encoder принимают level × 10 целым: дробный разбор зависит от LC_NUMERIC.
QByteArray level = QByteArray::number(name == "libx264" ? config.level : config.level / 3);
@ -360,9 +358,10 @@ bool LiveVideoEncoder::open(const LiveVideoConfig& config, Backend backend) {
}
DEBUG_INFO(DEBUG_CATEGORY_VIDEO,
"desktop encoder ready name=%s codec=%d size=%dx%d fps=%d bitrate=%d level=%d refs=%d vbv=%d profile_verified=%d "
"forced_keys=%d max_qp=%d dynamic_qp=%d",
"forced_keys=%d max_qp=%d dynamic_qp=%d threads=%d thread_type=%d",
name.constData(), config.codec, config.width, config.height, config.fps, config.bitrate,
config.level, config.references, c->rc_buffer_size, constrained, m->forcedKeys, config.maxQp, canSetMaxQp());
config.level, config.references, c->rc_buffer_size, constrained, m->forcedKeys, config.maxQp, canSetMaxQp(),
c->thread_count, c->active_thread_type);
return true;
}
}

Loading…
Cancel
Save