vdi-cloud/terminal/moonlight/experiments/0004-vdi-egl-exact-size-sampling.patch

50 lines
2.1 KiB
Diff

--- a/app/streaming/video/ffmpeg-renderers/eglvid.h
+++ b/app/streaming/video/ffmpeg-renderers/eglvid.h
@@ -57,6 +57,8 @@
int m_GlesMajorVersion;
int m_GlesMinorVersion;
bool m_HasExtUnpackSubimage;
+ bool m_VdiNearestOneToOne;
+ int m_VdiTextureFilter;
#define NV12_PARAM_YUVMAT 0
#define NV12_PARAM_OFFSET 1
--- a/app/streaming/video/ffmpeg-renderers/eglvid.cpp
+++ b/app/streaming/video/ffmpeg-renderers/eglvid.cpp
@@ -75,7 +75,9 @@
m_eglClientWaitSync(nullptr),
m_GlesMajorVersion(0),
m_GlesMinorVersion(0),
- m_HasExtUnpackSubimage(false)
+ m_HasExtUnpackSubimage(false),
+ m_VdiNearestOneToOne(qEnvironmentVariableIntValue("VDI_EGL_NEAREST_1TO1") == 1),
+ m_VdiTextureFilter(GL_LINEAR)
{
SDL_assert(backendRenderer);
SDL_assert(backendRenderer->canExportEGL());
@@ -812,6 +814,24 @@
dst.w = drawableWidth;
dst.h = drawableHeight;
StreamUtils::scaleSourceToDestinationSurface(&src, &dst);
+
+ // At exact pixel size no resampling is needed. Keep linear filtering for
+ // scaled video and all other backends. Never change overlay filtering.
+ if (m_VdiNearestOneToOne && m_EGLImagePixelFormat == AV_PIX_FMT_DRM_PRIME) {
+ const int filter = dst.w == frame->width && dst.h == frame->height ? GL_NEAREST : GL_LINEAR;
+ if (filter != m_VdiTextureFilter) {
+ for (ssize_t i = 0; i < plane_count; ++i) {
+ glActiveTexture(GL_TEXTURE0 + i);
+ glBindTexture(GL_TEXTURE_EXTERNAL_OES, m_Textures[i]);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, filter);
+ }
+ m_VdiTextureFilter = filter;
+ EGL_LOG(Info, "VDI video texture filter: %s (%dx%d -> %dx%d)",
+ filter == GL_NEAREST ? "nearest" : "linear",
+ frame->width, frame->height, dst.w, dst.h);
+ }
+ }
glViewport(dst.x, dst.y, dst.w, dst.h);
glUseProgram(m_ShaderProgram);