From fe16509293be0209acf8ff07c552497eda3effb3 Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 14 Oct 2026 23:12:15 +0200 Subject: [PATCH] Advertise desktop decoder capabilities independently of encoders --- tools/chatgui/src/call_video_decoder.cpp | 23 +++++++++++++++++++++++ tools/chatgui/src/call_video_decoder.h | 1 + tools/chatgui/src/call_video_engine.cpp | 6 +++--- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/tools/chatgui/src/call_video_decoder.cpp b/tools/chatgui/src/call_video_decoder.cpp index c9082308..49c619f7 100644 --- a/tools/chatgui/src/call_video_decoder.cpp +++ b/tools/chatgui/src/call_video_decoder.cpp @@ -24,6 +24,29 @@ void CallVideoDecoder::close() { #endif m->format = {}; } +call_video_caps CallVideoDecoder::capabilities() { + call_video_caps caps{}; + for (unsigned codec = 1; codec <= 2; ++codec) { + unsigned profiles = 0; + for (unsigned profile = 1; profile <= (codec == 1 ? 2u : 1u); ++profile) { + uint8_t bytes[8192]; int size = call_video_probe_key(codec, profile, bytes, sizeof(bytes)); + if (size < 0) continue; + call_video_frame f{}; f.call_id = 1; f.flags = CALL_VIDEO_KEY; f.data = bytes; f.size = f.length = size; + f.format = {1, 1280, 720, 30, 0, (uint8_t)codec, (uint8_t)(codec == 1 ? 31 : 93), 4000000, (uint8_t)profile}; + CallVideoDecoder decoder; bool valid = true; + for (unsigned i = 0; i < 4 && valid; ++i) { + f.frame_id = i + 1; f.pts_us = 1000000 + i * 33333; + QImage image; valid = decoder.decode(f, image); + } + if (valid) profiles |= profile; + else DEBUG_WARN(DEBUG_CATEGORY_CALL, "video independent decoder probe failed codec=%u profile=%u", codec, profile); + } + if (profiles) caps.decode[codec - 1] = {1280, 720, 30, 1280 * 720 * 30, 4000000, + (uint8_t)profiles, (uint8_t)(codec == 1 ? 31 : 93)}; + DEBUG_INFO(DEBUG_CATEGORY_CALL, "video decoder probe codec=%u profiles=%u", codec, profiles); + } + return caps; +} bool CallVideoDecoder::decode(const call_video_frame& f, QImage& image) { #ifdef HAVE_FFMPEG auto failed = [this, &f](const char* reason) { diff --git a/tools/chatgui/src/call_video_decoder.h b/tools/chatgui/src/call_video_decoder.h index 437d343d..ac938171 100644 --- a/tools/chatgui/src/call_video_decoder.h +++ b/tools/chatgui/src/call_video_decoder.h @@ -10,6 +10,7 @@ public: ~CallVideoDecoder(); bool decode(const call_video_frame& frame, QImage& image); void close(); + static call_video_caps capabilities(); private: struct Impl; std::unique_ptr m; diff --git a/tools/chatgui/src/call_video_engine.cpp b/tools/chatgui/src/call_video_engine.cpp index 92c94afe..51ed72e3 100644 --- a/tools/chatgui/src/call_video_engine.cpp +++ b/tools/chatgui/src/call_video_engine.cpp @@ -130,15 +130,15 @@ void CallVideoEngine::setVideo(bool enabled, const QByteArray& cameraId, int wid } void CallVideoEngine::transmit() { - call_video_caps caps{}; - // Каждый объявленный codec проверяется реальным encoder + независимым decoder при open. + call_video_caps caps = CallVideoDecoder::capabilities(); + // Не связываем приём с наличием собственного encoder. for (unsigned codec = 1; codec <= 2 && m->running; ++codec) { call_video_format probe{1, 1280, 720, 30, 0, (uint8_t)codec, (uint8_t)(codec == 1 ? 31 : 93), 4000000, (uint8_t)(codec == 1 ? CALL_VIDEO_CONSTRAINED_BASELINE : CALL_VIDEO_MAIN)}; CallVideoEncoder encoder; if (encoder.open(probe, 1000000)) { call_video_limit limit{1280, 720, 30, 1280 * 720 * 30, 4000000, probe.profile, probe.level}; - caps.encode[codec - 1] = caps.decode[codec - 1] = limit; + caps.encode[codec - 1] = limit; } else DEBUG_WARN(DEBUG_CATEGORY_CALL, "call codec probe unavailable codec=%u: %s", codec, qPrintable(encoder.error())); } if (!m->running) return;