diff --git a/app/streaming/video/ffmpeg-renderers/drm.cpp b/app/streaming/video/ffmpeg-renderers/drm.cpp index c2a345ac..e3846a1d 100644 --- a/app/streaming/video/ffmpeg-renderers/drm.cpp +++ b/app/streaming/video/ffmpeg-renderers/drm.cpp @@ -75,6 +75,13 @@ extern "C" { #include +#ifdef HAVE_DRM_MASTER_HOOKS +extern "C" { +void lockDrmMaster(); +void unlockDrmMaster(); +} +#endif + // This map is used to lookup characteristics of a given DRM format // // All DRM formats that we want to try when selecting a plane must @@ -1653,8 +1660,8 @@ bool DrmRenderer::addFbForFrame(AVFrame *frame, uint32_t* newFbId, bool testMode drmFrame = (AVDRMFrameDescriptor*)frame->data[0]; } - // If we're testing, check the IN_FORMATS property or legacy plane formats - if (testMode) { + // For non-atomic drivers, check the IN_FORMATS property or legacy plane formats + if (testMode && !m_PropSetter.isAtomic()) { bool formatMatch = false; uint64_t maskedModifier = drmFrame->objects[0].format_modifier; @@ -1785,6 +1792,75 @@ bool DrmRenderer::addFbForFrame(AVFrame *frame, uint32_t* newFbId, bool testMode return false; } + // For atomic drivers, we'll use a test-only commit to confirm this plane+FB works + if (testMode && m_PropSetter.isAtomic()) { + SDL_Rect src, dst; + src.x = src.y = 0; + src.w = frame->width; + src.h = frame->height; + + // This isn't a completely accurate test since SDL hasn't modeset to the new + // display resolution that we'll actually be using for streaming (since we're + // still not committed to even using DrmRenderer for rendering yet). Hopefully, + // it will be good enough though. + dst.x = dst.y = 0; + drmModeCrtc* crtc = drmModeGetCrtc(m_DrmFd, m_Crtc.objectId()); + if (crtc != nullptr) { + dst.w = crtc->width; + dst.h = crtc->height; + drmModeFreeCrtc(crtc); + } + else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "drmModeGetCrtc() failed: %d", + errno); + + // We'll just hope for the best here + dst.w = frame->width; + dst.h = frame->height; + } + + StreamUtils::scaleSourceToDestinationSurface(&src, &dst); + + // Temporarily take DRM master if we dropped it after initialization + if (!m_DrmStateModified) { +#ifdef HAVE_DRM_MASTER_HOOKS + lockDrmMaster(); +#endif + drmSetMaster(m_DrmFd); + } + bool testResult = m_PropSetter.testPlane(m_VideoPlane, + m_Crtc.objectId(), + *newFbId, + dst.x, dst.y, + dst.w, dst.h, + 0, 0, + frame->width << 16, + frame->height << 16); + if (!m_DrmStateModified) { + drmDropMaster(m_DrmFd); +#ifdef HAVE_DRM_MASTER_HOOKS + unlockDrmMaster(); +#endif + } + + if (testResult) { + SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, + "Selected DRM plane supports chosen decoding format and modifier: " FOURCC_FMT " %016" PRIx64, + FOURCC_FMT_ARGS(drmFrame->layers[0].format), + drmFrame->objects[0].format_modifier); + } + else { + SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, + "Selected DRM plane doesn't support chosen decoding format and modifier: " FOURCC_FMT " %016" PRIx64, + FOURCC_FMT_ARGS(drmFrame->layers[0].format), + drmFrame->objects[0].format_modifier); + drmModeRmFB(m_DrmFd, *newFbId); + *newFbId = 0; + return false; + } + } + return true; }