Thread priority, better debug overlay

This commit is contained in:
Niellune
2026-03-24 18:08:01 +02:00
parent 6001a0eb96
commit 929b613ab8
5 changed files with 187 additions and 17 deletions
+65 -6
View File
@@ -2,6 +2,7 @@
#include <SDL2/SDL_ttf.h>
#include <cstdio>
#include <sstream>
#include "struct/video_buffer.h"
#include "common/logger.h"
@@ -393,7 +394,7 @@ void Application::loop()
else
{
late = decoder.buffer.latestId() - latestFrameid > 1;
if(!late || ++skipEvents > Settings::eventsSkip)
if (!late || ++skipEvents > Settings::eventsSkip)
{
if (processFrameEvents(protocol.writeQueue, interface) && Settings::forceRedraw > 0)
{
@@ -405,18 +406,21 @@ void Application::loop()
if (_debug)
{
char debugBuffer[256];
char debugBuffer[512];
std::snprintf(debugBuffer, sizeof(debugBuffer),
"FRAME: %u / %u [%d] droped %d\n"
"TIME: %d delay %d\n"
"%s\n"
"FRAME: %u / %u [%d] dropped: %d render: %dms / %dms\n"
"VIDEO: %u\n"
"AUDIO-MAIN: %u\n"
"AUDIO-AUX: %u\n"
"OUT: %u",
status().c_str(),
latestFrameid,
decoder.buffer.latestId(),
decoder.buffer.latestId() - latestFrameid, dropframes,
frameTime, delay,
decoder.buffer.latestId() - latestFrameid,
dropframes,
frameTime,
delay,
protocol.videoStream.count(),
protocol.audioStreamMain.count(),
protocol.audioStreamAux.count(),
@@ -444,3 +448,58 @@ void Application::loop()
if (!Settings::isHeadless())
SDL_HideWindow(_window);
}
const std::string Application::status() const
{
std::ostringstream out;
SDL_version compiled{};
SDL_VERSION(&compiled);
SDL_version linked{};
SDL_GetVersion(&linked);
out << "SDL: v"
<< static_cast<int>(compiled.major) << '.'
<< static_cast<int>(compiled.minor) << '.'
<< static_cast<int>(compiled.patch) << " "
<< SDL_GetCurrentVideoDriver();
SDL_Window *window = SDL_GetKeyboardFocus();
if (window)
{
int width = 0;
int height = 0;
SDL_GetWindowSize(window, &width, &height);
out << " " << width << 'x' << height;
SDL_Renderer *renderer = SDL_GetRenderer(window);
if (renderer)
{
SDL_RendererInfo info{};
if (SDL_GetRendererInfo(renderer, &info) == 0)
{
out << " " << info.name
<< ((info.flags & SDL_RENDERER_ACCELERATED) != 0?" accelerated":"")
<< ((info.flags & SDL_RENDERER_PRESENTVSYNC) != 0?" vsync":"");
}
}
}
out << " " << SDL_GetCurrentAudioDriver();
int displayIndex = SDL_GetWindowDisplayIndex(window);
if (displayIndex >= 0)
{
out << "\nSCREEN:";
SDL_Rect bounds{};
SDL_DisplayMode mode{};
SDL_GetDisplayBounds(displayIndex, &bounds);
if (SDL_GetCurrentDisplayMode(displayIndex, &mode) == 0)
{
out << " [" << displayIndex << "] "
<< bounds.w << 'x' << bounds.h
<< '@' << mode.refresh_rate
<< " " << SDL_GetPixelFormatName(mode.format);
}
}
return out.str();
}
+1
View File
@@ -35,6 +35,7 @@ private:
int processKey(SDL_Keysym key);
bool processSystemEvent(const SDL_Event &e);
bool processFrameEvents(AtomicQueue<Message> &queue, Renderer &renderer);
const std::string status() const;
void loop();
+100 -9
View File
@@ -1,23 +1,114 @@
#ifndef SRC_HELPER_THREADING
#define SRC_HELPER_THREADING
#include <thread>
#if defined(__linux__) || defined(__APPLE__)
#include <pthread.h>
#include <pthread.h>
#endif
extern "C"
{
#include <libavutil/error.h>
}
#if defined(__linux__)
#include <sched.h>
#elif defined(_WIN32)
#include <windows.h>
#endif
inline void setThreadName(const char *name)
inline void setThreadName(const char* name)
{
#if defined(__linux__)
pthread_setname_np(pthread_self(), name); // Linux: OK (limit 16 chars including null)
pthread_setname_np(pthread_self(), name);
#elif defined(__APPLE__)
pthread_setname_np(name); // macOS: only current thread, OK
pthread_setname_np(name);
#elif defined(_WIN32)
// Windows 10+
using SetThreadDescriptionFunc = HRESULT(WINAPI*)(HANDLE, PCWSTR);
static auto func = (SetThreadDescriptionFunc)
GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetThreadDescription");
if (func)
{
wchar_t wname[64];
mbstowcs(wname, name, 63);
wname[63] = 0;
func(GetCurrentThread(), wname);
}
#else
(void)name; // suppress unused warning
(void)name;
#endif
}
enum class ThreadPriority
{
Low,
Normal,
High,
Realtime
};
inline bool setThreadPriority(ThreadPriority prio)
{
#if defined(__linux__)
int policy = SCHED_OTHER;
sched_param param{};
switch (prio)
{
case ThreadPriority::Low:
case ThreadPriority::Normal:
policy = SCHED_OTHER;
param.sched_priority = 0;
break;
case ThreadPriority::High:
policy = SCHED_FIFO;
param.sched_priority = 10;
break;
case ThreadPriority::Realtime:
policy = SCHED_FIFO;
param.sched_priority = 50;
break;
}
return pthread_setschedparam(pthread_self(), policy, &param) == 0;
#elif defined(__APPLE__)
qos_class_t qos = QOS_CLASS_DEFAULT;
switch (prio)
{
case ThreadPriority::Low: qos = QOS_CLASS_BACKGROUND; break;
case ThreadPriority::Normal: qos = QOS_CLASS_DEFAULT; break;
case ThreadPriority::High: qos = QOS_CLASS_USER_INITIATED; break;
case ThreadPriority::Realtime: qos = QOS_CLASS_USER_INTERACTIVE; break;
}
return pthread_set_qos_class_self_np(qos, 0) == 0;
#elif defined(_WIN32)
int winPrio = THREAD_PRIORITY_NORMAL;
switch (prio)
{
case ThreadPriority::Low: winPrio = THREAD_PRIORITY_BELOW_NORMAL; break;
case ThreadPriority::Normal: winPrio = THREAD_PRIORITY_NORMAL; break;
case ThreadPriority::High: winPrio = THREAD_PRIORITY_ABOVE_NORMAL; break;
case ThreadPriority::Realtime: winPrio = THREAD_PRIORITY_TIME_CRITICAL; break;
}
return SetThreadPriority(GetCurrentThread(), winPrio);
#else
(void)prio;
return false;
#endif
}
+20 -2
View File
@@ -24,7 +24,7 @@ Interface::~Interface()
bool Interface::render(AVFrame *frame)
{
if(!frame)
if (!frame)
return false;
if (_render == nullptr || frame->width != _textureWidth || frame->height != _textureHeight)
@@ -91,7 +91,14 @@ void Interface::drawDebug()
constexpr int padding = 8;
constexpr int lineSpacing = 2;
const SDL_Color debugColor = {255, 0, 255, 255};
const SDL_Color debugColor = {0, 255, 255, 255};
SDL_BlendMode previousBlendMode;
Uint8 previousR, previousG, previousB, previousA;
SDL_GetRenderDrawBlendMode(_renderer, &previousBlendMode);
SDL_GetRenderDrawColor(_renderer, &previousR, &previousG, &previousB, &previousA);
SDL_SetRenderDrawBlendMode(_renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(_renderer, 0, 0, 0, 150);
size_t lineStart = 0;
int y = padding;
@@ -100,7 +107,15 @@ void Interface::drawDebug()
size_t lineEnd = _debugText.find('\n', lineStart);
std::string line = _debugText.substr(lineStart, lineEnd - lineStart);
if (_textDebug.prepare(_renderer, line, debugColor))
{
SDL_Rect backgroundRect = {
0,
y,
static_cast<int>(_textDebug.width * Settings::aspectCorrection) + padding * 2,
_textDebug.height};
SDL_RenderFillRect(_renderer, &backgroundRect);
_textDebug.draw(_renderer, padding, y);
}
y += _textDebug.height + lineSpacing;
if (lineEnd == std::string::npos)
@@ -108,4 +123,7 @@ void Interface::drawDebug()
lineStart = lineEnd + 1;
}
SDL_SetRenderDrawColor(_renderer, previousR, previousG, previousB, previousA);
SDL_SetRenderDrawBlendMode(_renderer, previousBlendMode);
}
+1
View File
@@ -170,6 +170,7 @@ void ConnectionReader::onUsbRead(libusb_transfer *transfer)
void ConnectionReader::readLoop()
{
setThreadName("usb-read");
setThreadPriority(ThreadPriority::Realtime);
timeval timeout{0, 100000};
log_d("USB reading thread started");