diff --git a/app/streaming/video/ffmpeg-renderers/drm.cpp b/app/streaming/video/ffmpeg-renderers/drm.cpp index 6758ac71..4a7bb0e5 100644 --- a/app/streaming/video/ffmpeg-renderers/drm.cpp +++ b/app/streaming/video/ffmpeg-renderers/drm.cpp @@ -74,6 +74,7 @@ extern "C" { #include #include +#include #ifdef HAVE_DRM_MASTER_HOOKS extern "C" { @@ -1750,6 +1751,7 @@ bool DrmRenderer::addFbForFrame(AVFrame *frame, uint32_t* newFbId, bool testMode uint32_t offsets[4] = {}; uint64_t modifiers[4] = {}; uint32_t flags = 0; + std::unordered_set handleSet; // DRM requires composed layers rather than separate layers per plane SDL_assert(drmFrame->nb_layers == 1); @@ -1763,9 +1765,16 @@ bool DrmRenderer::addFbForFrame(AVFrame *frame, uint32_t* newFbId, bool testMode SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "drmPrimeFDToHandle() failed: %d", errno); + for (uint32_t handle : handleSet) { + drmCloseBufferHandle(m_DrmFd, handle); + } return false; } + // Handles aren't unique for calls with the same FD, so we need to + // keep track of only the unique handles to avoid double-closing. + handleSet.emplace(handles[i]); + pitches[i] = layer.planes[i].pitch; offsets[i] = layer.planes[i].offset; modifiers[i] = object.format_modifier; @@ -1784,6 +1793,12 @@ bool DrmRenderer::addFbForFrame(AVFrame *frame, uint32_t* newFbId, bool testMode handles, pitches, offsets, (flags & DRM_MODE_FB_MODIFIERS) ? modifiers : NULL, newFbId, flags); + + // Handles can be closed immediately after drmModeAddFB2WithModifiers() + for (uint32_t handle : handleSet) { + drmCloseBufferHandle(m_DrmFd, handle); + } + if (err < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "drmModeAddFB2[WithModifiers]() failed: %d",