Don't set the output rect until after modesetting

It's possible that modesetting will also change the resolution
not just the refresh rate. This can happen in cases where the
CRTC is currently set to 4K 30 Hz and we choose 1080p 60 Hz as
a better mode match for displaying a 1080p 60 FPS stream.
This commit is contained in:
Cameron Gutman 2024-09-19 22:43:34 -05:00
parent 5a1ef55767
commit 6b11f43302

View File

@ -166,6 +166,7 @@ DrmRenderer::DrmRenderer(AVHWDeviceType hwDeviceType, IFFmpegRenderer *backendRe
m_ColorspaceProp(nullptr),
m_Version(nullptr),
m_HdrOutputMetadataBlobId(0),
m_OutputRect{},
m_SwFrameMapper(this),
m_CurrentSwFrameIdx(0)
#ifdef HAVE_EGL
@ -297,6 +298,30 @@ void DrmRenderer::prepareToRender()
"SDL_CreateRenderer() failed: %s",
SDL_GetError());
}
// Set the output rect to match the new CRTC size after modesetting
m_OutputRect.x = m_OutputRect.y = 0;
drmModeCrtc* crtc = drmModeGetCrtc(m_DrmFd, m_CrtcId);
if (crtc != nullptr) {
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"CRTC size after modesetting: %ux%u",
crtc->width,
crtc->height);
m_OutputRect.w = crtc->width;
m_OutputRect.h = crtc->height;
drmModeFreeCrtc(crtc);
}
else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"drmModeGetCrtc() failed: %d",
errno);
SDL_GetWindowSize(m_Window, &m_OutputRect.w, &m_OutputRect.h);
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
"Guessing CRTC is window size: %dx%d",
m_OutputRect.w,
m_OutputRect.h);
}
}
bool DrmRenderer::getPropertyByName(drmModeObjectPropertiesPtr props, const char* name, uint64_t *value) {
@ -523,12 +548,7 @@ bool DrmRenderer::initialize(PDECODER_PARAMETERS params)
int crtcIndex = -1;
for (int i = 0; i < resources->count_crtcs; i++) {
if (resources->crtcs[i] == m_CrtcId) {
drmModeCrtc* crtc = drmModeGetCrtc(m_DrmFd, resources->crtcs[i]);
crtcIndex = i;
m_OutputRect.x = m_OutputRect.y = 0;
m_OutputRect.w = crtc->width;
m_OutputRect.h = crtc->height;
drmModeFreeCrtc(crtc);
break;
}
}
@ -1240,6 +1260,8 @@ void DrmRenderer::renderFrame(AVFrame* frame)
int err;
SDL_Rect src, dst;
SDL_assert(m_OutputRect.w > 0 && m_OutputRect.h > 0);
src.x = src.y = 0;
src.w = frame->width;
src.h = frame->height;