Route desktop codec diagnostics through the shared log

Quiet capability probes, preserve runtime errors, and register the desktop portal application. Add logging and desktop launcher regression coverage.
This commit is contained in:
evgeny committed 2026-10-21 15:45:40 +02:00
1 parent 9ba78c084b
commit 7c814f5cb9
17 files changed
+349 -44

No files matched your search

+19 -10
View File
@@ -1,6 +1,6 @@
#include "call_video_decoder.h"
#include "video_frame_image.h"
#include "debug_config.h"
#include "video_codec_log.h"
#include "../../../src/call/call_video_bitstream.h"
#include "../../../src/call/call_video_playout.h"
#include <QTransform>
@@ -43,16 +43,17 @@ struct CallVideoDecoder::Impl {
static AVPixelFormat getFormat(AVCodecContext* codec, const AVPixelFormat* formats) {
auto* self = static_cast<Impl*>(codec->opaque);
for (const auto* p = formats; *p != AV_PIX_FMT_NONE; ++p) if (*p == self->pixel) return *p;
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video GPU decoder pixel format unavailable expected=%d", self->pixel);
CODEC_LOG(DEBUG_LEVEL_ERROR, DEBUG_CATEGORY_CALL, "video GPU decoder pixel format unavailable expected=%d", self->pixel);
return AV_PIX_FMT_NONE;
}
int failed(const char* stage, int result) {
error = QString("Video decoder %1: %2").arg(stage, ffError(result));
DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video decoder failed stage=%s backend=%s pending=%zu generation=%llu result=%d error=%s",
CODEC_LOG(DEBUG_LEVEL_ERROR, DEBUG_CATEGORY_CALL, "video decoder failed stage=%s backend=%s pending=%zu generation=%llu result=%d error=%s",
stage, gpu ? av_hwdevice_get_type_name(DeviceType) : "cpu", pending.size(),
(unsigned long long)format.generation, result, qPrintable(error)); return -1;
}
bool open(const call_video_format& f) {
video_ffmpeg_init();
format = f;
const AVCodec* implementation = avcodec_find_decoder(f.codec == CALL_VIDEO_H265 ? AV_CODEC_ID_HEVC : AV_CODEC_ID_H264);
codec = implementation ? avcodec_alloc_context3(implementation) : nullptr;
@@ -84,7 +85,8 @@ struct CallVideoDecoder::Impl {
int result = avcodec_open2(codec, implementation, nullptr);
if (result < 0) { failed("open", result); return false; }
error.clear();
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video decoder opened codec=%u name=%s backend=%s threads=%d thread_type=%d level=%u generation=%llu",
CODEC_LOG(DEBUG_LEVEL_INFO, DEBUG_CATEGORY_CALL,
"video decoder opened codec=%u name=%s backend=%s threads=%d thread_type=%d level=%u generation=%llu",
f.codec, implementation->name, gpu ? av_hwdevice_get_type_name(DeviceType) : "cpu", codec->thread_count,
codec->active_thread_type, f.level, (unsigned long long)f.generation); return true;
}
@@ -97,7 +99,7 @@ unsigned CallVideoDecoder::pipelineFrames() const { return m->pipeline; }
bool CallVideoDecoder::hardware() const { return m->gpu; }
QString CallVideoDecoder::error() const { return m->error; }
void CallVideoDecoder::useSoftware() {
DEBUG_WARN(DEBUG_CATEGORY_CALL, "video decoder switching to CPU after device failure pending=%zu; next input must be KEY",
CODEC_LOG(DEBUG_LEVEL_WARN, DEBUG_CATEGORY_CALL, "video decoder switching to CPU after device failure pending=%zu; next input must be KEY",
m->pending.size());
close(); m->backend = Backend::SoftwareOnly;
}
@@ -155,7 +157,7 @@ int CallVideoDecoder::submit(const call_video_frame& f) {
m->pending.push_back(f); m->pending.back().data = nullptr;
return 1;
#else
Q_UNUSED(f); DEBUG_ERROR(DEBUG_CATEGORY_CALL, "video decoder unavailable: no FFmpeg"); return -1;
Q_UNUSED(f); CODEC_LOG(DEBUG_LEVEL_ERROR, DEBUG_CATEGORY_CALL, "video decoder unavailable: no FFmpeg"); return -1;
#endif
}
@@ -238,15 +240,16 @@ call_video_caps CallVideoDecoder::capabilities(const std::atomic<bool>* running)
static bool initialized = false;
auto cancelled = [running] {
if (!running || running->load()) return false;
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video decoder capability probe cancelled by stop"); return true;
CODEC_LOG(DEBUG_LEVEL_INFO, DEBUG_CATEGORY_CALL, "video decoder capability probe cancelled by stop"); return true;
};
std::unique_lock<std::mutex> guard(lock, std::defer_lock);
while (!guard.try_lock()) { if (cancelled()) return {}; QThread::usleep(1000); }
if (initialized) {
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video decoder capabilities cache hit wait_us=%lld",
CODEC_LOG(DEBUG_LEVEL_INFO, DEBUG_CATEGORY_CALL, "video decoder capabilities cache hit wait_us=%lld",
(long long)(call_video_playout_now_us() - started));
return caps;
}
VideoCodecProbe diagnostics;
call_video_caps probed{};
for (unsigned codec = 1; codec <= 2; ++codec) {
call_video_limit limit{};
@@ -293,7 +296,7 @@ call_video_caps CallVideoDecoder::capabilities(const std::atomic<bool>* running)
if (valid && received < 8) QThread::usleep(1000);
}
valid = valid && received == 8 && outputBeforeEos;
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video decoder probe codec=%u profile=%u size=%ux%u fps=%u backend=%d "
CODEC_LOG(DEBUG_LEVEL_INFO, DEBUG_CATEGORY_CALL, "video decoder probe codec=%u profile=%u size=%ux%u fps=%u backend=%d "
"valid=%d inputs=%u outputs=%u pipeline=%u elapsed_us=%lld",
codec, profile, w, h, fps, int(backend), valid, sent, received, decoder.pipelineFrames(),
(long long)(call_video_playout_now_us() - start));
@@ -317,12 +320,18 @@ call_video_caps CallVideoDecoder::capabilities(const std::atomic<bool>* running)
}
}
}
unsigned gpu = 0;
#ifdef HAVE_FFMPEG
for (unsigned tier = 0; tier < 2; ++tier) for (unsigned rate = 0; rate < 3; ++rate)
gpu |= gpuProfiles[codec - 1][tier][rate].load();
#endif
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video decoder capabilities codec=%u available_profiles=%u gpu_profiles=%u", codec, limit.profiles, gpu);
if (limit.profiles) {
if (!call_video_limit_orientations(&limit, codec)) probed.decode[codec - 1] = limit;
}
}
caps = probed; initialized = true;
DEBUG_INFO(DEBUG_CATEGORY_CALL, "video decoder capabilities verified elapsed_us=%lld",
CODEC_LOG(DEBUG_LEVEL_INFO, DEBUG_CATEGORY_CALL, "video decoder capabilities verified elapsed_us=%lld",
(long long)(call_video_playout_now_us() - started));
return caps;
}