diff --git a/app/streaming/video/ffmpeg-renderers/eglvid.cpp b/app/streaming/video/ffmpeg-renderers/eglvid.cpp index 5aced8de..5bf5a2d0 100644 --- a/app/streaming/video/ffmpeg-renderers/eglvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/eglvid.cpp @@ -627,8 +627,6 @@ bool EGLRenderer::setupVideoRenderingState() { glGenTextures(EGL_MAX_PLANES, m_Textures); for (size_t i = 0; i < EGL_MAX_PLANES; ++i) { glBindTexture(GL_TEXTURE_EXTERNAL_OES, m_Textures[i]); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } @@ -682,8 +680,8 @@ bool EGLRenderer::setupOverlayRenderingState() { for (size_t i = 0; i < Overlay::OverlayMax; ++i) { // Set up the overlay texture glBindTexture(GL_TEXTURE_2D, m_OverlayTextures[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -786,6 +784,16 @@ void EGLRenderer::renderFrame(AVFrame* frame) } } + int drawableWidth, drawableHeight; + SDL_GL_GetDrawableSize(m_Window, &drawableWidth, &drawableHeight); + SDL_Rect src, dst; + src.x = src.y = dst.x = dst.y = 0; + src.w = frame->width; + src.h = frame->height; + dst.w = drawableWidth; + dst.h = drawableHeight; + StreamUtils::scaleSourceToDestinationSurface(&src, &dst); + ssize_t plane_count = m_Backend->exportEGLImages(frame, m_EGLDisplay, imgs); if (plane_count < 0) return; @@ -793,6 +801,16 @@ void EGLRenderer::renderFrame(AVFrame* frame) glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_EXTERNAL_OES, m_Textures[i]); m_glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, imgs[i]); + + // Use GL_NEAREST to reduce sampling if the video region is a multiple of the frame size + if (dst.w % frame->width == 0 && dst.h % frame->height == 0) { + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + else { + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } } // We already called glClear() after last frame's SDL_GL_SwapWindow() @@ -801,17 +819,7 @@ void EGLRenderer::renderFrame(AVFrame* frame) glClear(GL_COLOR_BUFFER_BIT); } - int drawableWidth, drawableHeight; - SDL_GL_GetDrawableSize(m_Window, &drawableWidth, &drawableHeight); - // Set the viewport to the size of the aspect-ratio-scaled video - SDL_Rect src, dst; - src.x = src.y = dst.x = dst.y = 0; - src.w = frame->width; - src.h = frame->height; - dst.w = drawableWidth; - dst.h = drawableHeight; - StreamUtils::scaleSourceToDestinationSurface(&src, &dst); glViewport(dst.x, dst.y, dst.w, dst.h); glUseProgram(m_ShaderProgram); diff --git a/app/streaming/video/ffmpeg-renderers/sdlvid.cpp b/app/streaming/video/ffmpeg-renderers/sdlvid.cpp index 0c681fc3..4fbeff89 100644 --- a/app/streaming/video/ffmpeg-renderers/sdlvid.cpp +++ b/app/streaming/video/ffmpeg-renderers/sdlvid.cpp @@ -417,6 +417,9 @@ ReadbackRetry: goto Exit; } + // Never alpha blend this texture when rendering + SDL_SetTextureBlendMode(m_Texture, SDL_BLENDMODE_NONE); + #ifdef HAVE_CUDA if (frame->format == AV_PIX_FMT_CUDA) { SDL_assert(m_CudaGLHelper == nullptr); @@ -567,6 +570,11 @@ ReadbackRetry: // Ensure the viewport is set to the desired video region SDL_RenderSetViewport(m_Renderer, &dst); + // Use nearest pixel sampling if the video region size is a multiple of the frame size + SDL_SetTextureScaleMode(m_Texture, + dst.w % frame->width == 0 && dst.h % frame->height == 0 ? + SDL_ScaleModeNearest : SDL_ScaleModeLinear); + // Draw the video content itself SDL_RenderCopy(m_Renderer, m_Texture, nullptr, nullptr);