Skip to content

Comments

Moving Background Blur to GPU#5891

Open
rapterjet2004 wants to merge 2 commits intomasterfrom
improving-background-blur-2
Open

Moving Background Blur to GPU#5891
rapterjet2004 wants to merge 2 commits intomasterfrom
improving-background-blur-2

Conversation

@rapterjet2004
Copy link
Contributor

@rapterjet2004 rapterjet2004 commented Feb 21, 2026

🖼️ Screenshots

Before After
Screenshot 2026-02-02 at 10 51 34 AM Screenshot 2026-02-02 at 10 28 43 AM
Demo (foreground original / background blurred) Mask (foreground white / background black)
Screenshot 2026-02-20 at 7 57 46 PM Screenshot 2026-02-20 at 8 04 26 PM

This PR addresses an issue with the previous implementation of Background Blurring. It used too much memory space, as openCV contains huge builds for every possible memory architecture supported on Android. This leads to duplicate files, large amounts of unnecessary code, and a larger download size. The MediaPipe library and the .tflite file used for foreground-background detection was trivial in comparison.

This is fixed by moving the entire blurring operation to openGL ES, a graphics framework that is built into Android, cutting out 100 MB from the build size while also increasing performance. This is done by the implementing Gaussian Blur algorithm from scratch in GLSL, the openGL Shader language.

This adds

  • BackgroundBlurGPUProcessor a file that handles the openGL logic, and acts as an abstraction over the inner workings of the image processing. OpenGL's logic is ... very unclear. I tried my best to document as much as possible, including any linear algebra that I had to perform.
  • background_blur_vertex the required vertex shader, needed to identify the position of each pixel on the screen, before the geometry, rasterization, and fragment shader steps of the openGL pipeline.
  • gaussian_blur_frag_shader the Gaussian Blur implementation, this is what actually performs the logic on the image pixels. The code is also somewhat unclear if you're not familiar with shaders or gaussian blur. It helps to read the technical article I commented from Intel.
  • seg_mask_frag_shader the masking operation implementation, very simple, just checking if the pixel should be blurred or retain it's original unblurred value
  • testing_frag_shader a simple fragment shader used for quick testing
  • libyuv_android a light weight helper lib for converting between image formats without the overhead of OpenCV

Copied over from old PR

  • BackgroundBlurFrameProcessor A WebRTC VideoProcessor object, this handles the video frame conversions and processing. Holds references to the ImageSegmenterHelper and the BackgrounBlurGPUProcessor. It now holds it's own dedicated Thread and Handler for running OpenGL's GPU operations. It also takes in a reference to the surfaceTextureHelper from CallActivity to send the VideoFrame objects to the WebRTC VideoSink on the appropriate capture thread. Failing to do both of these causes a crash.
  • BlurBackgroundViewModel
  • ImageSegmenterHelper uses MediaPipe to perform the segmentation mask (foreground / background separation). Really just a wrapper over the MediaPipe API
  • background_replace_24px
  • 2 new strings

🚧 TODO

  • rebase + solve merge conflicts
  • analyze for memory leaks
  • linter

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed
  • 🔖 Capability is checked or not needed
  • 🔙 Backport requests are created or not needed: /backport to stable-xx.x
  • 📅 Milestone is set
  • 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)

This adds
- `BackgroundBlurGPUProcessor` a file that handles the openGL logic, and acts as an abstraction over the inner workings of the image processing. OpenGL's logic is ... very unclear. I tried my best to document as much as possible, including any linear algebra that I had to perform.
- `background_blur_vertex.glsl` the required vertex shader, needed to identify the position of each pixel on the screen, before the geometry, rasterization, and fragment shader steps of the openGL pipeline.
- `gaussian_blur_frag_shader.glsl` the Gaussian Blur implementation, this is what actually performs the logic on the image pixels. The code is also somewhat unclear if you're not familiar with shaders or gaussian blur. It helps to read the technical article I commented from Intel.
- `seg_mask_frag_shader.glsl` the masking operation implementation, very simple, just checking if the pixel should be blurred or retain it's original unblurred value
- `testing_frag_shader` a simple fragment shader used for quick testing
- `libyuv_android` a light weight helper lib for converting between image formats without the overhead of OpenCV

Significant changes
- `BackgroundBlurFrameProcessor` now holds it's own dedicated Thread and Handler for running OpenGL's GPU operations. It also takes in a reference to the `surfaceTextureHelper` from `CallActivity` to send the `VideoFrame` objects to the WebRTC `VideoSink` on the appropriate capture thread. Failing to do both of these causes a crash.

Signed-off-by: rapterjet2004 <juliuslinus1@gmail.com>
@rapterjet2004 rapterjet2004 self-assigned this Feb 21, 2026
Signed-off-by: rapterjet2004 <juliuslinus1@gmail.com>
@rapterjet2004 rapterjet2004 force-pushed the improving-background-blur-2 branch from 0e3b310 to 471db97 Compare February 21, 2026 02:11
@github-actions
Copy link
Contributor

APK file: https://www.kaminsky.me/nc-dev/android-artifacts/5891.apk

qrcode

To test this change/fix you can simply download above APK file and install and test it in parallel to your existing Nextcloud app.

@github-actions
Copy link
Contributor

Codacy

Lint

TypemasterPR
Warnings9899
Errors00

SpotBugs

CategoryBaseNew
Bad practice66
Correctness1010
Dodgy code5454
Internationalization33
Malicious code vulnerability33
Performance44
Security11
Total8181

Lint increased!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant