Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Realtime motion interpolating 60fps playback in mpv

Realtime motion interpolating playback in mpv

Edit 2016-09: SVP now has a free (but proprietary) version of their software, which includes a GPU port of the MVTools functions, making this much less resource intense: https://www.svp-team.com/wiki/SVP:Linux (AUR)


run this for SVP-like motion interpolation:

cd ~/.config/mpv # or ~/.mpv

wget https://gist.githubusercontent.com/phiresky/4bfcfbbd05b3c2ed8645/raw/motioninterpolation.vpy

echo 'I vf toggle format=yuv420p,vapoursynth=~~/motioninterpolation.vpy:4:4' >> input.conf

# to enable it by default
echo 'vf=format=yuv420p,vapoursynth=~~/motioninterpolation.vpy:4:4' >> mpv.conf

now press shift+i while mpv is playing a video to toggle beautiful motion vector interpolation of the video framerate to your display refresh rate.

You need mpv compiled with VapourSynth support. Not sure what distributions do this, in Arch Linux you can get mpv-git or mpv-vapoursynth (AUR) and vapoursynth-plugin-mvtools.

It should also be possible to make this work through SMPlayer.

Warning: This is CPU intensive. The settings work on a i5-2500k cpu. If it lags you will have to change some parameters, look for 2500k in the script. If your CPU is faster remove that block.

If your CPU is really fast, try removing the 'mode' parameter and changing BlockFPS to FlowFPS, this gives much better results.

See the reddit post for more information

Encoding video to a higher framerate

Run this:

vspipe --arg in_filename=input.mkv --arg display_fps=60 --y4m motioninterpolation.vpy -|ffmpeg -i - -crf 18 output.mkv
# vim: set ft=python:
# see the README at https://gist.github.com/phiresky/4bfcfbbd05b3c2ed8645
# source: https://github.com/mpv-player/mpv/issues/2149
# source: https://github.com/mpv-player/mpv/issues/566
# source: https://github.com/haasn/gentoo-conf/blob/nanodesu/home/nand/.mpv/filters/mvtools.vpy
import vapoursynth
core = vapoursynth.get_core()
# ref: http://avisynth.org.ru/mvtools/mvtools2.html#functions
# default is 400, less means interpolation will only happen when it will work well
ignore_threshold=140
# if n% of blocks change more than threshold then don't interpolate at all (default is 51%)
scene_change_percentage=15
dst_fps = display_fps
# Interpolating to fps higher than 60 is too CPU-expensive, smoothmotion can handle the rest.
# while (dst_fps > 60):
# dst_fps /= 2
if "video_in" in globals():
# realtime
clip = video_in
# Needed because clip FPS is missing
src_fps_num = int(container_fps * 1e8)
src_fps_den = int(1e8)
clip = core.std.AssumeFPS(clip, fpsnum = src_fps_num, fpsden = src_fps_den)
else:
# run with vspipe
clip = core.ffms2.Source(source=in_filename)
dst_fps=float(dst_fps)
# resolution in megapixels. 1080p ≈ 2MP, 720p ≈ 1MP
mpix = clip.width * clip.height / 1000000
# Skip interpolation for >1080p or 60 Hz content due to performance
if not (mpix > 2.5 or clip.fps_num/clip.fps_den > 59):
analParams = {
'overlap': 0,
'search': 3,
'truemotion': True,
#'chrome': True,
#'blksize':16,
#'searchparam':1
}
blockParams = {
'thscd1': ignore_threshold,
'thscd2': int(scene_change_percentage*255/100),
'mode': 3,
}
if mpix > 1.5:
# can't handle these on Full HD with Intel i5-2500k
# see the description of these parameters in http://avisynth.org.ru/mvtools/mvtools2.html#functions
analParams['search'] = 0
blockParams['mode'] = 0
quality = 'low'
else:
quality = 'high'
dst_fps_num = int(dst_fps * 1e4)
dst_fps_den = int(1e4)
print("Reflowing from {} fps to {} fps (quality={})".format(clip.fps_num/clip.fps_den,dst_fps_num/dst_fps_den,quality))
sup = core.mv.Super(clip, pel=2)
bvec = core.mv.Analyse(sup, isb=True, **analParams)
fvec = core.mv.Analyse(sup, isb=False, **analParams)
clip = core.mv.BlockFPS(clip, sup, bvec, fvec,
num=dst_fps_num, den=dst_fps_den,
**blockParams)
clip.set_output()
@Cellane

This comment has been minimized.

Copy link

Cellane commented Jan 8, 2017

When re-encoding the video to higher framerate, is there an easy way to preserve audio and subtitle tracks as well?

@phiresky

This comment has been minimized.

Copy link
Owner Author

phiresky commented Jun 26, 2018

@Cellane not sure. But you could add other tracks to the ffmpeg command (see here).

@mc4man

This comment has been minimized.

Copy link

mc4man commented Jul 5, 2018

2 small things, Shift+I by default now toggles stats, there are numerous undefined shift+'s you could use.
Also this warning is printed, not an issue yet (given current development pace may be a long time till removed?
"Passing more than 1 argument to vf-toggle is deprecated!"

@mc4man

This comment has been minimized.

Copy link

mc4man commented Nov 3, 2018

script is currently a no go with recent vapoursynth -
[vapoursynth] Script evaluation failed:
[vapoursynth] Python exception: No attribute with the name mv exists. Did you mistype a plugin namespace?
[vapoursynth]
[vapoursynth] Traceback (most recent call last):
[vapoursynth] File "src/cython/vapoursynth.pyx", line 1847, in vapoursynth.vpy_evaluateScript
[vapoursynth] File "/home/doug/.config/mpv/motioninterpolation.vpy", line 61, in
[vapoursynth] sup = core.mv.Super(clip, pel=2)
[vapoursynth] File "src/cython/vapoursynth.pyx", line 1416, in vapoursynth.Core.getattr
[vapoursynth] AttributeError: No attribute with the name mv exists. Did you mistype a plugin namespace?
[vapoursynth]
[vapoursynth] could not init VS
Disabling filter vapoursynth.00 because it has failed.

@mc4man

This comment has been minimized.

Copy link

mc4man commented Nov 3, 2018

Ignore above, forgot to install a mvtools plugin ...

@ArcAngelRyse

This comment has been minimized.

Copy link

ArcAngelRyse commented Dec 22, 2018

I actually need help settings this up correctly on windows 10. anytime I enabled or attempt to enable the filter it fails and If i try to enabled it again it locks up mpv and force closes it. I have mvtools plugin, and mvtools.vpy (never actually installed it though i dont know how) but honestly I don't know what to do with either of these or where to place them. I'm really new to the whole script thing with mpv.

I do have vapoursynth with mpv compiled already. I just really want to get this filter to work but know little to nothing about how to do this.

I believe similar issue to above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.