Prepare and cache desktop video codecs once at application startup

This commit is contained in:
evgeny committed 2026-10-20 01:10:44 +02:00
1 parent 0cd1955606
commit e3b74de7ef
3 files changed
+53 -5

No files matched your search

+33 -5
View File
@@ -9,6 +9,7 @@
#include "../../../src/call/call_audio.h"
#include "debug_config.h"
#include "mem.h"
#include <QThread>
#include <thread>
#include <mutex>
#include <condition_variable>
@@ -252,10 +253,26 @@ void CallVideoEngine::setVideo(bool enabled, const QByteArray& cameraId, int wid
#endif
}
void CallVideoEngine::transmit() {
call_video_caps caps = CallVideoDecoder::capabilities(&m->running);
call_video_caps CallVideoEngine::capabilities(const std::atomic<bool>* running) {
static std::mutex lock;
static call_video_caps verified{};
static bool initialized = false;
const int64_t started = nowUs();
auto cancelled = [running] {
if (!running || running->load()) return false;
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video codec preparation cancelled; completed cache retained"); return true;
};
std::unique_lock<std::mutex> guard(lock, std::defer_lock);
while (!guard.try_lock()) { if (cancelled()) return {}; QThread::usleep(1000); }
if (cancelled()) return {};
if (initialized) {
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video codec capabilities cache hit wait_us=%lld", (long long)(nowUs() - started));
return verified;
}
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video codec preparation begin; camera and network unused");
call_video_caps caps = CallVideoDecoder::capabilities(running);
// Не связываем приём с наличием собственного encoder.
for (unsigned codec = 1; codec <= 2 && m->running; ++codec) {
for (unsigned codec = 1; codec <= 2; ++codec) {
for (const QSize size : {QSize(1920, 1080), QSize(1280, 720)}) {
for (unsigned fps : {30u, 50u, 60u}) {
const bool fullhd = size.width() == 1920;
@@ -264,14 +281,15 @@ void CallVideoEngine::transmit() {
: (fullhd ? (fps > 30 ? 123 : 120) : (fps > 30 ? 120 : 93))), 4000000,
(uint8_t)(codec == 1 ? CALL_VIDEO_CONSTRAINED_BASELINE : CALL_VIDEO_MAIN)};
bool bothOrientations = true;
for (int portrait = 0; portrait <= 1 && bothOrientations && m->running; ++portrait) {
for (int portrait = 0; portrait <= 1 && bothOrientations; ++portrait) {
if (cancelled()) return {};
probe.width = portrait ? size.height() : size.width(); probe.height = portrait ? size.width() : size.height();
CallVideoEncoder encoder;
bothOrientations = encoder.open(probe, 1000000);
if (!bothOrientations) DEBUG_WARN(DEBUG_CATEGORY_CALL, "call codec probe unavailable codec=%u size=%ux%u: %s",
codec, probe.width, probe.height, qPrintable(encoder.error()));
}
if (bothOrientations && m->running) {
if (bothOrientations) {
auto& limit = caps.encode[codec - 1];
limit.width = std::max<int>(limit.width, size.width()); limit.height = std::max<int>(limit.height, size.height());
limit.fps = std::max<unsigned>(limit.fps, fps);
@@ -284,6 +302,16 @@ void CallVideoEngine::transmit() {
}
if (caps.encode[codec - 1].profiles && call_video_limit_orientations(&caps.encode[codec - 1], codec)) caps.encode[codec - 1] = {};
}
if (cancelled()) return {};
verified = caps; initialized = true;
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video codec preparation complete elapsed_us=%lld encode=%u/%u decode=%u/%u",
(long long)(nowUs() - started), caps.encode[0].profiles, caps.encode[1].profiles,
caps.decode[0].profiles, caps.decode[1].profiles);
return verified;
}
void CallVideoEngine::transmit() {
const call_video_caps caps = capabilities(&m->running);
if (!m->running) return;
if (call_video_port_open(m->id, &caps) < 0) { m->report(tr("Video transport is unavailable")); return; }
CallVideoEncoder encoder;