Use DT files to get status of FKMS and rpivid

This commit is contained in:
Cameron Gutman 2022-01-09 16:44:20 -06:00
commit 808933cd70
2 changed files with 52 additions and 38 deletions

View file

@ -5,9 +5,14 @@
#include <Limelight.h> #include <Limelight.h>
// HACK: Avoid including X11 headers which conflict with QDir
#ifdef SDL_VIDEO_DRIVER_X11
#undef SDL_VIDEO_DRIVER_X11
#endif
#include <SDL_syswm.h> #include <SDL_syswm.h>
#include <QProcess> #include <QDir>
#include <QTextStream> #include <QTextStream>
MmalRenderer::MmalRenderer() MmalRenderer::MmalRenderer()
@ -234,6 +239,34 @@ void MmalRenderer::InputPortCallback(MMAL_PORT_T*, MMAL_BUFFER_HEADER_T* buffer)
mmal_buffer_header_release(buffer); mmal_buffer_header_release(buffer);
} }
// MMAL rendering will silently fail in Full KMS mode. We'll see if that's
// enabled by reading sysfs. It's gross but it works.
bool MmalRenderer::getDtDeviceStatus(QString name, bool ifUnknown)
{
QDir dir("/sys/firmware/devicetree/base/soc");
QStringList matchingDir = dir.entryList(QStringList(name + "@*"), QDir::Dirs);
if (matchingDir.length() != 1) {
Q_ASSERT(matchingDir.isEmpty());
return ifUnknown;
}
if (!dir.cd(matchingDir.first())) {
return ifUnknown;
}
QFile statusFile(dir.filePath("status"));
if (!statusFile.open(QFile::ReadOnly)) {
// Per Device Tree docs, missing 'status' means enabled
return true;
}
QByteArray statusData = statusFile.readAll();
QString statusString(statusData);
// Per Device Tree docs, 'okay' and 'ok' are both acceptable
return statusData == "okay" || statusData == "ok";
}
bool MmalRenderer::isMmalOverlaySupported() bool MmalRenderer::isMmalOverlaySupported()
{ {
if (qgetenv("MMAL_DISABLE_SUPPORT_CHECK") == "1") { if (qgetenv("MMAL_DISABLE_SUPPORT_CHECK") == "1") {
@ -252,45 +285,25 @@ bool MmalRenderer::isMmalOverlaySupported()
return mmalOverlayCheckResult; return mmalOverlayCheckResult;
} }
// MMAL rendering will silently fail in Full KMS mode. We'll see if that's // vc4-fkms-v3d - firmwarekms is 'okay', hvs is 'disabled'
// enabled by reading kernel log messages. It's gross but it works. // vc4-kms-v3d - firmwarekms is 'disabled', hvs is 'okay' <- this is the bad one
QProcess dmesgProc; // none - firmwarekms is 'disabled', hvs is 'disabled'
dmesgProc.setReadChannel(QProcess::StandardOutput); if (!getDtDeviceStatus("firmwarekms", true) && getDtDeviceStatus("hvs", true)) {
dmesgProc.start("dmesg"); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
dmesgProc.waitForFinished(); "Full KMS Mode is enabled! Hardware accelerated H.264 decoding will be unavailable!");
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
if (dmesgProc.exitStatus() == QProcess::NormalExit && dmesgProc.exitCode() == 0) { "Change 'dtoverlay=vc4-kms-v3d' to 'dtoverlay=vc4-fkms-v3d' in /boot/config.txt to fix this!");
QTextStream textStream(&dmesgProc); mmalOverlayCheckResult = false;
bool foundRpiVid = false;
QString line;
do {
line = textStream.readLine();
if (line.contains("vc4_crtc_ops")) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Full KMS Mode is enabled! H.264 video decoding/rendering performance will be degraded!");
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Remove 'dtoverlay=vc4-kms-v3d' from your /boot/config.txt to fix this!");
mmalOverlayCheckResult = false;
}
if (line.contains("rpivid")) {
foundRpiVid = true;
}
} while (!line.isNull());
if (!foundRpiVid) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Raspberry Pi HEVC decoder is not enabled! Add 'dtoverlay=rpivid-v4l2' to your /boot/config.txt to fix this!");
}
else if (strcmp(SDL_GetCurrentVideoDriver(), "KMSDRM") != 0) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Raspberry Pi HEVC decoder cannot be used from within a desktop environment. H.264 will be used instead.");
}
} }
else {
// /dev/video19 is the rpivid stateless HEVC decoder
if (!QFile::exists("/dev/video19")) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION, SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Unable to check for Full KMS mode and HEVC decoding support (error %d)", "Raspberry Pi HEVC decoder is not enabled! Add 'dtoverlay=rpivid-v4l2' to your /boot/config.txt to fix this!");
dmesgProc.exitCode()); }
else if (strcmp(SDL_GetCurrentVideoDriver(), "KMSDRM") != 0) {
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Raspberry Pi HEVC decoder cannot be used from within a desktop environment. H.264 will be used instead.");
} }
SDL_MemoryBarrierRelease(); SDL_MemoryBarrierRelease();

View file

@ -20,6 +20,7 @@ public:
private: private:
static void InputPortCallback(MMAL_PORT_T* port, MMAL_BUFFER_HEADER_T* buffer); static void InputPortCallback(MMAL_PORT_T* port, MMAL_BUFFER_HEADER_T* buffer);
bool getDtDeviceStatus(QString name, bool ifUnknown);
bool isMmalOverlaySupported(); bool isMmalOverlaySupported();
void setupBackground(PDECODER_PARAMETERS params); void setupBackground(PDECODER_PARAMETERS params);