diff --git a/tools/chatgui/src/call_video_encoder.cpp b/tools/chatgui/src/call_video_encoder.cpp index d30c8b16..7d98b9bf 100644 --- a/tools/chatgui/src/call_video_encoder.cpp +++ b/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(); - 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; diff --git a/tools/chatgui/src/call_video_encoder.h b/tools/chatgui/src/call_video_encoder.h index b5842021..65fcb852 100644 --- a/tools/chatgui/src/call_video_encoder.h +++ b/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 проверяет владелец. */ diff --git a/tools/chatgui/src/live_video_encoder.cpp b/tools/chatgui/src/live_video_encoder.cpp index 00cbcd01..8a170682 100644 --- a/tools/chatgui/src/live_video_encoder.cpp +++ b/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; } }