Skip to content

Add transform with motion blur effect - #1301

Draft
RocketJannis wants to merge 5 commits into
mltframework:masterfrom
RocketJannis:transform_blur
Draft

RocketJannis wants to merge 5 commits into
mltframework:masterfrom
RocketJannis:transform_blur

Conversation

@RocketJannis

@RocketJannis RocketJannis commented Sep 16, 2026

Copy link
Copy Markdown

Hello, I did an implementation of a new video effect which does a similar thing as filter_qtblend but adding motion blur to the transform. I did this primarily because I miss a motion blur transform filter in Kdenlive.

How it works conceptually: It samples the animated image multiple times with alpha onto itself resulting in an image blurred correctly by its motion

How it works technically:

  1. calculate the transform delta between the last and current mlt frame for the animated rect/rotation
  2. decide, if blur is needed (if no delta -> no motion/animation -> no motion blur needed)
  3. calculate the contribution of one image sample (build_weighted_source)
  4. sample the weighted source image multiple times onto the target image (render_motion_blur / sliced_blur_proc)

Optimizations: both step 3 and 4 are parallelized individually via mlt_slices_run_normal to improve performance

I use this XML to integrate it into kdenlive: transformblur.xml

A question I had: Would it be better to integrate this into the qtblend effect? When using it with shutter lengh = 0, it does just a simple transform like qtblend. I thought it would bloat this standard and highly used filter too much so I decided to put it into an extra file first and ask here. Also qtblend does some handling for different compositions/alpha/scaling edge cases which this effect currently does not have. Integrating it into qtblend would require having both.

Alternative concepts I explored:

  1. Using ffmpeg's dblur (directional blur) filter also used in Kdenlive in "Directional blur". By calculating the angle and blur amount from the translation, it can blur the source image. I didn't choose it as the sampling blur was faster and has a better blur. dblur uses a gaussian kernel which doesn't look as good as a "linear blur" which I think is physically more accurate. This is especially visible in animated text - I can give examples if anyone is interested. Also dblur works with a uniform direction/amount per frame so it can't support scaling/rotation at all.
  2. Instead of sampling the whole image multiple times, calculate the motion on a per-pixel basis and calculate the blurred color per pixel sampling from the source image. In theory this sounds better than drawing the whole image multiple times as it has only one write operation while heaving multiple read samples on the source image. But it also has N * samples complexity (where N is pixel count). On the other hand it would also allow adaptive sampling by choosing the sample count per pixel (good for rotation). However it turns out to be VERY slow compared to the approach in this PR probably because QImage drawing seems much more optimized than my manual loops so I discarded this early and optimized the multi image drawing further.

AI Notice: I used Claude Sonnet 5 to help me with the build setup, getting to know the codebase and also implementing and optimizing the effect in large parts. I didnt find an AI policy and assumed that's okay. I'm an experienced programmer but have only little knowledge about the QT, MLT or kdenlive codebase which is why I used AI to help me get this implemented.

It's a draft PR because I didn't test with different resolutions yet. It also may need additional optimization / edge case hardening as qtblend does. It currently only supports 8 bit color space.

Demo:

grafik
test2.mp4

This filter is based on the same concept as qtblend but with added motion blur. Motion blur is achieved by sampling the source image multiple times.

The filter supports the basic transforms: rect translation, rotation, opacity. It also supports changing the shutter angle (changes blur amount) and used sample count.

Flow:
1. compute whether blur is necessary (only transform when if is no motion in the current frame or shutter angle is set to 0)
2. compute the contribution of one sample (build_weighted_source)
3. sample weighted source multiple times to build the blurred image
4. apply opacity to the final image if set below 1

mlt_slices_run_normal is used to parallelize the expensive sampling step
build_weighted_source was the primary performance bottleneck in the implementation
@ddennedy

Copy link
Copy Markdown
Member

It is a great idea and prototype! People have longed for this. However, a couple of things. If separate, users will expect it to be as functional as the regular transform. So, it will grow to approach parity with qtblend. Secondly, I am not accepting many new effects into MLT and prefer people to contribute to FFmpeg or to port it to frei0r or OpenFX plugin APIs to maintain it independently. I strongly encourage to support >8-bit and OpenFX supports this as well as integration with MLT slices. You do not need to make a custom UI in an OpenFX implementation, and MLT does not support that yet anyway. It will be better for Kdenlive users if integrated into qtblend. Even when Kdenlive adds support for OpenFX, it is less convenient.

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.

2 participants