Giter VIP home page Giter VIP logo

vapoursynth-mvtools's Introduction

Description

MVTools is a set of filters for motion estimation and compensation.

This is a port of version 2.5.11.20 of the Avisynth plugin.

Some changes from version 2.5.11.9 of the SVP fork have been incorporated as well (http://www.svp-team.com/wiki/Download).

The filter DepanEstimate was ported from the Avisynth plugin DepanEstimate, version 1.10.

The filters DepanCompensate and DepanStabilise were ported from the Avisynth plugin Depan, version 1.13.1.

Differences

  • All:
    • Free multithreading, courtesy of VapourSynth.
    • Parameters are all lowercase now.
    • YUY2 is not supported.
    • Grayscale, 4:2:0, 4:2:2, 4:4:0, and 4:4:4 are supported, except for DepanCompensate and DepanStabilise, which don't support 4:4:0.
    • Up to 16 bits per sample are supported.
    • The audio is definitely not killed.
    • No "planar" parameter.
    • "isse" parameter renamed to "opt".
  • Analyse:
    • No "temporal" parameter, as it's sort of incompatible with multithreading.
    • No "outfile" parameter.
    • No "sadx264" parameter. If opt is True, the best functions imported from x264 will be selected automatically. Otherwise, only C functions will be used.
    • New parameters "fields" and "tff".
    • The optimised SAD, SATD, and SSD functions from x264 have been updated to the latest versions (as of September 2014).
    • Block sizes of 64x32, 64x64, 128x64, and 128x128 are supported.
    • The "dct" parameter can be 5..10 even with blocks larger than 16x16.
  • Recalculate:
    • Same as Analyse.
  • Compensate:
    • No "recursion" parameter. It was dodgy.
    • New parameter "tff".
  • Flow
    • New parameter "tff".
  • SCDetection:
    • No "ysc" parameter. The input frames are returned unchanged, with the _SceneChangePrev or _SceneChangeNext property attached.
    • No "isse" parameter. It wasn't used.
  • DepanAnalyse:
    • Formerly "MDepan".
    • New parameters "fields" and "tff".
    • No "log", "range", "isse" parameters.
  • DepanEstimate:
    • New parameters "fields" and "tff".
    • No "range", "log", "debug", "extlog" parameters.
  • DepanCompensate:
    • Formerly "DePan".
    • No "inputlog" parameter.
  • DepanStabilise:
    • Formerly "DePanStabilize".
    • No "inputlog" parameter.
    • Methods -1 and 2 unavailable.

Usage

mv.Super(clip clip[, int hpad=16, int vpad=16, int pel=2, int levels=0, bint chroma=True, int sharp=2, int rfilter=2, clip pelclip=None, bint opt=True])

mv.Analyse(clip super[, int blksize=8, int blksizev=blksize, int levels=0, int search=4, int searchparam=2, int pelsearch=0, bint isb=False, int lambda, bint chroma=True, int delta=1, bint truemotion=True, int lsad, int plevel, int global, int pnew, int pzero=pnew, int pglobal=0, int overlap=0, int overlapv=overlap, bint divide=False, int badsad=10000, int badrange=24, bint opt=True, bint meander=True, bint trymany=False, bint fields=False, bint tff, int search_coarse=3, int dct=0])

mv.Recalculate(clip super, clip vectors[, int blksize=8, int blksizev=blksize, int search=4, int searchparam=2, int lambda, bint chroma=True, bint truemotion=True, int pnew, int overlap=0, int overlapv=overlap, bint divide=False, bint opt=True, bint meander=True, bint fields=False, bint tff, int dct=0])

mv.Compensate(clip clip, clip super, clip vectors[, int scbehavior=1, int thsad=10000, bint fields=False, float time=100.0, int thscd1=400, int thscd2=130, bint opt=True, bint tff])

mv.Degrain1(clip clip, clip super, clip mvbw, clip mvfw[, int thsad=400, int thsadc=thsad, int plane=4, int limit=255, int limitc=limit, int thscd1=400, int thscd2=130, bint opt=True])

mv.Degrain2(clip clip, clip super, clip mvbw, clip mvfw, clip mvbw2, clip mvfw2[, int thsad=400, int thsadc=thsad, int plane=4, int limit=255, int limitc=limit, int thscd1=400, int thscd2=130, bint opt=True])

mv.Degrain3(clip clip, clip super, clip mvbw, clip mvfw, clip mvbw2, clip mvfw2, clip mvbw3, clip mvfw3[, int thsad=400, int thsadc=thsad, int plane=4, int limit=255, int limitc=limit, int thscd1=400, int thscd2=130, bint opt=True])

mv.Mask(clip clip, clip vectors[, float ml=100.0, float gamma=1.0, int kind=0, float time=100.0, int ysc=0, int thscd1=400, int thscd2=130, bint opt=True])

mv.Finest(clip super[, bint opt=True])

mv.Flow(clip clip, clip super, clip vectors[, float time=100.0, int mode=0, bint fields=False, int thscd1=400, int thscd2=130, bint opt=True, bint tff])

mv.FlowBlur(clip clip, clip super, clip mvbw, clip mvfw[, float blur=50.0, int prec=1, int thscd1=400, int thscd2=130, bint opt=True])

mv.FlowInter(clip clip, clip super, clip mvbw, clip mvfw[, float time=50.0, float ml=100.0, bint blend=True, int thscd1=400, int thscd2=130, bint opt=True])

mv.FlowFPS(clip clip, clip super, clip mvbw, clip mvfw[, int num=25, int den=1, int mask=2, float ml=100.0, bint blend=True, int thscd1=400, int thscd2=130, bint opt=True])

mv.BlockFPS(clip clip, clip super, clip mvbw, clip mvfw[, int num=25, int den=1, int mode=3, float ml=100.0, bint blend=True, int thscd1=400, int thscd2=130, bint opt=True])

mv.SCDetection(clip clip, clip vectors[, int thscd1=400, int thscd2=130])

mv.DepanAnalyse(clip clip, clip vectors[, clip mask, bint zoom=True, bint rot=True, float pixaspect=1.0, float error=15.0, bint info=False, float wrong=10.0, float zerow=0.05, int thscd1=400, int thscd2=130, bint fields=False, bint tff])

mv.DepanEstimate(clip clip[, float trust=4.0, int winx=0, int winy=0, int wleft=-1, int wtop=-1, int dxmax=-1, int dymax=-1, float zoommax=1.0, float stab=1.0, float pixaspect=1.0, bint info=False, bint show=False, bint fields=False, bint tff])

mv.DepanCompensate(clip clip, clip data[, float offset=0.0, int subpixel=2, float pixaspect=1.0, bint matchfields=True, int mirror=0, int blur=0, bint info=False, bint fields=False, bint tff])

mv.DepanStabilise(clip clip, clip data[, float cutoff=1.0, float damping=0.9, float initzoom=1.0, bint addzoom=False, int prev=0, int next=0, int mirror=0, int blur=0, float dxmax=60.0, float dymax=30.0, float zoommax=1.05, float rotmax=1.0, int subpixel=2, float pixaspect=1.0, int fitlast=0, float tzoom=3.0, bint info=False, int method=0, bint fields=False])

If fields is True, it is assumed that the clip named clip first went through std.SeparateFields.

For information about the other parameters, consult the Avisynth plugins' documentation at http://avisynth.org.ru/mvtools/mvtools2.html or http://www.avisynth.nl/users/fizick/depan/depan.html. This will not be necessary in the future.

Compilation

FFTW3 configured for 32 bit floats is required ("fftw3f").

mkdir build; cd build
meson ../
ninja

Or

./autogen.sh
./configure
make

Meson runs faster than autogen.sh and configure.

License

GPL 2, like the Avisynth plugins.

vapoursynth-mvtools's People

Contributors

adworacz avatar holywu avatar ifeelbloated avatar jymmysmcsubs avatar mystery-keeper avatar pyguy2 avatar q66 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vapoursynth-mvtools's Issues

New release?

any eta. for a new release with the latest changes?

Usage example seems broken and incomplete

Hi! I'm relatively new to using VapourSynth, but I see it as an incredible tool fro my video production work, as it has tools I don't see anywhere else.

I'm trying to do some camera movement smoothing (remove shaking, maybe remove motion blur if possible?), however I am having a hard time using mvtools plug-in Vapoursynth.

The usage section in in readme seems to error out and have some errors in the syntax:
https://github.com/dubhater/vapoursynth-mvtools/blob/master/readme.rst#usage

I'm probably doing something wrong, but maybe everyone using these is so familiar with it that they didn't really need to real in. I'm new and finding information about using VapourSynth and it's plug-ins seems difficult to find. Maybe plug-ins don't provide any usage information in their Git repos.

Is there anywhere a complete vapoursynth script that demonstrates using mvtools on a video file that I can just preview in VSedit and take apart to achieve what I want?

The best I managed to do so far using the example is this:

import vapoursynth as vs

clip = vs.core.ffms2.Source(source="my_video_clip.mkv")

super = vs.core.mv.Super(clip, hpad=16, vpad=16, pel=2, levels=0, chroma=True, sharp=2, rfilter=2, pelclip=None, opt=True)

vectors = vs.core.mv.Analyse(super)#, blksize=8, blksizev=blksize, levels=0, search=4, searchparam=2, pelsearch=0, isb=False, lambda, chroma=True, delta=1, truemotion=True, lsad, plevel, global, pnew, pzero=pnew, pglobal=0, overlap=0, overlapv=overlap, divide=False, badsad=10000, badrange=24, opt=True, meander=True, trymany=False, fields=False, tff, search_coarse=3, dct=0)

#clip = mv.Recalculate(super, vectors)#, blksize=8, blksizev=blksize, search=4, searchparam=2, lambda, chroma=True, truemotion=True, pnew, overlap=0, overlapv=overlap, divide=False, opt=True, meander=True, fields=False, tff, dct=0)
#
#mv.Compensate(clip, super, vectors)#, scbehavior=1, thsad=10000, bfields=False, time=100.0, thscd1=400, thscd2=130, bopt=True, btff)
#
#mv.Degrain1(clip, super, mvbw, mvfw, thsad=400, thsadc=thsad, plane=4, limit=255, limitc=limit, thscd1=400, thscd2=130, bopt=True)
#
#mv.Degrain2(clip, super, mvbw, mvfw, mvbw2, mvfw2, thsad=400, thsadc=thsad, plane=4, limit=255, limitc=limit, thscd1=400, thscd2=130, bopt=True)
#
#mv.Degrain3(clip, super, mvbw, mvfw, mvbw2, mvfw2, mvbw3, mvfw3, thsad=400, thsadc=thsad, plane=4, limit=255, limitc=limit, thscd1=400, thscd2=130, bopt=True)
#
mask = vs.core.mv.Mask(clip, vectors)#, ml=100.0, gamma=1.0, kind=0, time=100.0, ysc=0, thscd1=400, thscd2=130, bopt=True)
#
#mv.Finest(super, bopt=True)
#
#mv.Flow(clip, super, vectors, time=100.0, mode=0, bfields=False, thscd1=400, thscd2=130, bopt=True, btff)
#
#mv.FlowBlur(clip, super, mvbw, mvfw, blur=50.0, prec=1, thscd1=400, thscd2=130, bopt=True)
#
#mv.FlowInter(clip, super, mvbw, mvfw, time=50.0, ml=100.0, bblend=True, thscd1=400, thscd2=130, bopt=True)
#
#mv.FlowFPS(clip, super, mvbw, mvfw, num=25, den=1, mask=2, ml=100.0, bblend=True, thscd1=400, thscd2=130, bopt=True)
#
#mv.BlockFPS(clip, super, mvbw, mvfw, num=25, den=1, mode=3, ml=100.0, bblend=True, thscd1=400, thscd2=130, bopt=True)
#
#mv.SCDetection(clip, vectors, thscd1=400, thscd2=130)

clip = vs.core.mv.DepanAnalyse(clip, vectors, mask)#, bzoom=True, brot=True, pixaspect=1.0, error=15.0, binfo=False, wrong=10.0, zerow=0.05, thscd1=400, thscd2=130, bfields=False, btff)

data = vs.core.mv.DepanEstimate(clip)#, trust=4.0, winx=0, winy=0, wleft=-1, wtop=-1, dxmax=-1, dymax=-1, zoommax=1.0, stab=1.0, pixaspect=1.0, binfo=False, bshow=False, bfields=False, btff)

data = vs.core.mv.DepanCompensate(clip, data)#, offset=0.0, subpixel=2, pixaspect=1.0, bmatchfields=True, mirror=0, blur=0, binfo=False, bfields=False, btff)

clip = vs.core.mv.DepanStabilise(clip, data)#, cutoff=1.0, damping=0.9, initzoom=1.0, baddzoom=False, prev=0, next=0, mirror=0, blur=0, dxmax=60.0, dymax=30.0, zoommax=1.05, rotmax=1.0, subpixel=2, pixaspect=1.0, fitlast=0, tzoom=3.0, binfo=False, method=0, bfields=False)

clip.set_output()

I have managed to guess how to obtain various pieces of data like super, mask, vectors and data, but I have no idea how to get these: mvbw, mvfw, mvbw2, mvfw2, mvbw3, mvfw3.

crash when we do seek on mpv using mvtools

This comes from this issue: mpv-player/mpv#1168

I got this debug info, not sure if anything there is really useful:

#0  0x00007ffff240be89 in raise () from /lib64/libc.so.6
#1  0x00007ffff240d217 in abort () from /lib64/libc.so.6
#2  0x00007ffff2405226 in ?? () from /lib64/libc.so.6
#3  0x00007ffff24052d2 in __assert_fail () from /lib64/libc.so.6
#4  0x00007fffb3b77590 in getReadPtr (frame=<optimized out>, plane=<optimized out>) at ../src/core/vsapi.cpp:64
#5  0x00007fffb2697597 in MVClipBalls::Update (this=this@entry=0x7fff9bffecc0, fn=fn@entry=0x0) at src/MVClip.cpp:92
#6  0x00007fffb26b9b12 in mvflowinterGetFrame (n=<optimized out>, activationReason=<optimized out>, instanceData=<optimized out>, frameData=<optimized out>, frameCtx=<optimized out>, core=<optimized out>, vsapi=0x7fffb3da0800 <vsapi>)
    at src/MVFlowInter.cpp:288
#7  0x00007fffb3b80ece in VSNode::getFrameInternal (this=this@entry=0x21a2a90, n=<optimized out>, activationReason=activationReason@entry=2, frameCtx=...) at ../src/core/vscore.cpp:509
#8  0x00007fffb3b8e318 in VSThreadPool::runTasks (owner=0x1f6f470, stop=...) at ../src/core/vsthreadpool.cpp:165
#9  0x00007fffb3b8f826 in _M_invoke<0ul, 1ul> (this=<optimized out>) at /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/functional:1700
#10 operator() (this=<optimized out>) at /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/functional:1688
#11 std::thread::_Impl<std::_Bind_simple<void (*(VSThreadPool*, std::reference_wrapper<std::atomic<bool> >))(VSThreadPool*, std::atomic<bool>&)> >::_M_run() (this=<optimized out>)
    at /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/include/g++-v4/thread:115
#12 0x00007fffef9522c0 in ?? () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.9.1/libstdc++.so.6
#13 0x00007ffff70a51b3 in start_thread () from /lib64/libpthread.so.0
#14 0x00007ffff24bd0ed in clone () from /lib64/libc.so.6

This is a script for use with mpv that can reproduce the crash:

import vapoursynth as vs
core = vs.get_core()


clip = src = core.std.BlankClip(clip=video_in, fpsnum=24, fpsden=1, length=3) + \
             core.std.Trim(clip=video_in, first=0, length=500000)

if clip.format.bits_per_sample != 8:
    clip = core.fmtc.bitdepth(clip, bits=8)

sup  = core.mv.Super(clip)
bv   = core.mv.Analyse(sup, isb=True)
fv   = core.mv.Analyse(sup, isb=False)
clip = core.mv.FlowInter(clip, sup, bv, fv, blend=False)

if src.format.bits_per_sample != 8:
    clip = core.fmtc.bitdepth(clip, bits=src.format.bits_per_sample)

clip = core.std.Interleave(clips=[src, clip])
clip = core.std.AssumeFPS(clip=clip, fpsnum=clip.fps_num, fpsden=clip.fps_den)
clip = core.std.Trim(clip=clip, first=5, last=500000)

clip.set_output()

FlowFPS crashes when using overlaps in Analyse

Here's the script:

from vapoursynth import core

# http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4
clip = core.ffms2.Source("bbb_sunflower_1080p_30fps_normal.mp4")

mv = core.mv
sup = mv.Super(prefilter, sharp=1, rfilter=4)
bak = mv.Analyse(sup_filt, isb=True, blksize=32, overlap=8, search=3)
fwd = mv.Analyse(sup_filt, isb=False, blksize=32, overlap=8, search=3)
flow = mv.FlowFPS(clip, sup, bak, fwd, num=60, den=1, blend=False, ml=200.0, mask=2, thscd2=255)

FlowFPS crashes with this combination of parameters on my system (macOS 10.15.4, VapourSynth 49) with both mvtools v21 and v22. The same combination works fine with pinterf's mvtools in AviSynth.

Interpolated frames go wild with chroma=False

According to MVTool's documentation, it is possible to use chroma=False in the Super phase for frame interpolation. Below is the example from the webpage itself:

To double fps with MFlowFps for fastest (almost) real-time playing:

AVISource("c:\test.avi") # or MPEG2Source, DirectShowSource, some previous filter, etc
# assume progressive PAL 25 fps or NTSC Film 23.976 source
super = MSuper(pel=1,hpad=0,vpad=0,chroma=false)
backward_vec = MAnalyse(super, blksize=32, isb = true, chroma=false, searchparam=1,search=0)
forward_vec = MAnalyse(super, blksize=32, isb = false, chroma=false, searchparam=1,search=0)
MFlowFps(super, backward_vec, forward_vec, num=2*FramerateNumerator(last), \
   den=FramerateDenominator(last), mask=0)

I will show the results when a user puts chroma=False in MSuper or mv.Super


Example: Pinterf's MVTools 2.7.40

VirtualDub64_SB3qbiPKcM

source = FFmpegSource2("C:\Users\Paul\Desktop\vs\hob.mp4", atrack=-1)

s = MSuper(source, hpad=16, vpad=16, rfilter=4, pel=1, chroma=False)
bv = MAnalyse(s, isb=True, blksize=16, chroma=False, lsad=2400, pnew=128, pglobal=256)
fv = MAnalyse(s, blksize=16, chroma=False, lsad=2400, pnew=128, pglobal=256)
MBlockFPS(source, s, bv, fv, num=60, den=1, mode=0)

Example: vapoursynth-mvtools v21

VirtualDub64_rmjXNWcT33

import vapoursynth as vs
core = vs.core

source = core.ffms2.Source(r'C:\Users\Paul\Desktop\vs\hob.mp4')

s = core.mv.Super(source, hpad=16, vpad=16, rfilter=4, pel=1, chroma=False)
bv = core.mv.Analyse(s, isb=True, blksize=16, chroma=False, lsad=2400, pnew=128, pglobal=256)
fv = core.mv.Analyse(s, blksize=16, chroma=False, lsad=2400, pnew=128, pglobal=256)
c = core.mv.BlockFPS(source, s, bv, fv, num=60, den=1, mode=0)

c.set_output()

Notes:

  • In Block/FlowFPS, the non-interpolated frames do not have the distortion
  • Frames still get interpolated as they should (it's only the colors that get messed up)
  • This happens to
    • mv.FlowFPS and MFlowFPS
    • mv.FlowBlur and MFlowBlur

Building fails on Os X

I'm tring to build the git master of MVTools on Os X Yosemite, but it fails on the make stage, displaying the following error

$ make
YASM src/asm/const-a.o
YASM src/asm/cpu-a.o
YASM src/asm/pixel-a.o
YASM src/asm/sad-a.o
YASM src/asm/CopyCode.o
YASM src/asm/Interpolation.o
YASM src/asm/MVDegrains.o
YASM src/asm/Overlap.o
YASM src/asm/SAD.o
YASM src/asm/Variance.o
/Applications/Xcode.app/Contents/Developer/usr/bin/make all-am
CXX src/asm-placeholder.lo
CXX src/CopyCode.lo
CXX src/CPU.lo
CXX src/EntryPoint.lo
CXX src/FakeBlockData.lo
CXX src/FakeGroupOfPlanes.lo
CXX src/FakePlaneOfBlocks.lo
CXX src/GroupOfPlanes.lo
CXX src/Interpolation.lo
CXX src/MaskFun.lo
CXX src/MVAnalyse.lo
CXX src/MVClip.lo
src/MVClip.cpp:28:27: error: implicit instantiation of undefined template
'std::__1::basic_string<char, std::__1::char_traits,
std::__1::allocator >'
throw MVException(std::string("MVTools: failed to retrieve firs...
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iosfwd:188:33: note:
template is declared here
class _LIBCPP_TYPE_VIS_ONLY basic_string;
^
1 error generated.
make[1]: *** [src/MVClip.lo] Error 1
make: *** [all] Error 2

Same with the latest release version.

Compensate gives bogus output

The Compensate function returns green horizontal lines -- completely bogus output. This function works with the 32-bit plugin and gives crap output in 8-bit or 16-bit.

def SpotLess(c: vs.VideoNode, radt: int = 1, thsad: int = 10000, thsad2: Optional[int] = None, pel: int = 2, chroma: bool = True, blksize: int = 8, overlap: Optional[int] = None, truemotion: bool = True, pglobal: bool = True, blur: float = 0.0, ref: Optional[vs.VideoNode] = None) -> vs.VideoNode:
    if radt < 1 or radt > 3:
        raise ValueError("Spotless: radt must be between 1 and 3")
    if not pel in [1, 2, 4]:
        raise ValueError("Spotless: pel must be 1, 2 or 4")

    icalc = c.format.bits_per_sample < 32
    S = core.mv.Super if icalc else core.mvsf.Super
    A = core.mv.Analyse if icalc else core.mvsf.Analyse
    C = core.mv.Compensate if icalc else core.mvsf.Compensate
    pad = max(blksize, 8)

    sup = ref or (c.std.Convolution(matrix=[1, 2, 1, 2, 4, 2, 1, 2, 1]) if blur > 0.0 else c)
    sup = S(sup, hpad=pad, vpad=pad, pel=pel, sharp=2)
    sup_rend = S(c, hpad=pad, vpad=pad, pel=pel, sharp=2, levels=1) if ref or blur > 0.0 else sup

    th1 = thsad
    th2 = (thsad + thsad2)/2 if radt==3 else thsad2
    th3 = thsad2

    bv1 = A(sup, isb=True, delta=1, blksize=blksize, overlap=overlap, chroma=chroma, truemotion=truemotion, pglobal=pglobal)
    fv1 = A(sup, isb=False, delta=1, blksize=blksize, overlap=overlap, chroma=chroma, truemotion=truemotion, pglobal=pglobal)
    if radt >= 2:
        bv2 = A(sup, isb=True, delta=2, blksize=blksize, overlap=overlap, chroma=chroma, truemotion=truemotion, pglobal=pglobal)
        fv2 = A(sup, isb=False, delta=2, blksize=blksize, overlap=overlap, chroma=chroma, truemotion=truemotion, pglobal=pglobal)
    if radt >= 3:
        bv3 = A(sup, isb=True, delta=3, blksize=blksize, overlap=overlap, chroma=chroma, truemotion=truemotion, pglobal=pglobal)
        fv3 = A(sup, isb=False, delta=3, blksize=blksize, overlap=overlap, chroma=chroma, truemotion=truemotion, pglobal=pglobal)

    bc1 = C(c, sup_rend, bv1, thsad=th1)
    fc1 = C(c, sup_rend, fv1, thsad=th1)
    if radt >= 2:
        bc2 = C(c, sup_rend, bv2, thsad=th2)
        fc2 = C(c, sup_rend, fv2, thsad=th2)
    if radt >= 3:
        bc3 = C(c, sup_rend, bv3, thsad=th3)
        fc3 = C(c, sup_rend, fv3, thsad=th3)

    ic =          core.std.Interleave([bc1, c, fc1])           if radt == 1 else \
             core.std.Interleave([bc2, bc1, c, fc1, fc2])      if radt == 2 else \
        core.std.Interleave([bc3, bc2, bc1, c, fc1, fc2, fc3])

    output = core.tmedian.TemporalMedian(ic, radius=radt)
    return output.std.SelectEvery(radt*2+1, radt)  # Return middle frame

Also, any chance you could implement MultiVec features? Allowing radius greater than 3

This would allow writing SpotLess with much less code

Artifacts with bitdepth 16 and crash "float point exception"

It crashes with "float point exception".

I was not able to make it occur with a synthetic test. Is a dark scene whit some really brilliant lights, this lights get strange artifacts and then vapoursynth eventually crashes.

If you need a sample I will try to upload a small clip.

EDIT: This does not happen at 8/10/12 bits, I didn't test more combinations.

import vapoursynth as vs

core = vs.get_core()

#source
v = core.lsmas.LWLibavSource(r'/rule/6.m2ts')

#resize
v = core.fmtc.resample(v, 1280, 720)

tr = 1
thsad = None
overlap = None
blksize = None
plane = None
last = v

super_ = core.mv.Super(last)

mvbw3 = core.mv.Analyse(super_, isb=True, delta=3, overlap=overlap, blksize=blksize)
mvbw2 = core.mv.Analyse(super_, isb=True, delta=2, overlap=overlap, blksize=blksize)
mvbw1 = core.mv.Analyse(super_, isb=True, delta=1, overlap=overlap, blksize=blksize)
mvfw1 = core.mv.Analyse(super_, isb=False, delta=1, overlap=overlap, blksize=blksize)
mvfw2 = core.mv.Analyse(super_, isb=False, delta=2, overlap=overlap, blksize=blksize)
mvfw3 = core.mv.Analyse(super_, isb=False, delta=3, overlap=overlap, blksize=blksize)

if tr == 1:
    last = core.mv.Degrain1(clip=last, super=super_,
                            mvbw=mvbw1, mvfw=mvfw1, thsad=thsad, plane=plane)
elif tr == 2:
    last = core.mv.Degrain2(clip=last, super=super_,
                            mvbw=mvbw1, mvfw=mvfw1, mvbw2=mvbw2, mvfw2=mvfw2,
                            thsad=thsad, plane=plane)
elif tr == 3:
    last = core.mv.Degrain3(clip=last, super=super_,
                            mvbw=mvbw1, mvfw=mvfw1, mvbw2=mvbw2,
                            mvfw2=mvfw2, mvbw3=mvbw3, mvfw3=mvfw3,
                            thsad=thsad, plane=plane)

v = last

#output
v.set_output()

Fails to build, no "abs"

I get the following build error when calling make on OSX.

  CXX      src/GroupOfPlanes.lo
In file included from src/GroupOfPlanes.cpp:20:
In file included from src/GroupOfPlanes.h:21:
src/PlaneOfBlocks.h:208:66: error: use of undeclared identifier 'abs'
  ...sad = (SAD(dctSrc, dctpitch, dctRef, dctpitch) + abs(dctSrc[0]-dctRef[0]...
                                                      ^
src/PlaneOfBlocks.h:215:76: error: use of undeclared identifier 'abs'
  ...int dctsad = (SAD(dctSrc, dctpitch, dctRef, dctpitch)+ abs(dctSrc[0]-dct...
                                                            ^
src/PlaneOfBlocks.h:222:21: error: use of undeclared identifier 'abs'
                if (abs(srcLuma - refLuma) > (srcLuma + refLuma)>>5)
                    ^
src/PlaneOfBlocks.h:232:21: error: use of undeclared identifier 'abs'
                if (abs(srcLuma - refLuma) > (srcLuma + refLuma)>>5)
                    ^
src/PlaneOfBlocks.h:253:21: error: use of undeclared identifier 'abs'
                if (abs(srcLuma - refLuma) > (srcLuma + refLuma)>>5)
                    ^
src/PlaneOfBlocks.h:262:21: error: use of undeclared identifier 'abs'
                if (abs(srcLuma - refLuma) > (srcLuma + refLuma)>>5)
                    ^
src/PlaneOfBlocks.h:280:21: error: use of undeclared identifier 'abs'
                if (abs(srcLuma - refLuma) > (srcLuma + refLuma)>>4)
                    ^
7 errors generated.
make: *** [src/GroupOfPlanes.lo] Error 1

FlowInter: Artifacts at left borders when opt=True

super = core.mv.Super(clip)
mvbw = core.mv.Analyse(super, blksize=16, isb=True, overlap=8)
mvfw = core.mv.Analyse(super, blksize=16, isb=False, overlap=8)
clip = core.std.Interleave([core.mv.FlowInter(clip, super, mvbw, mvfw, opt=False), core.mv.FlowInter(clip, super, mvbw, mvfw, opt=True)])

opt=False
opt=False

opt=True
opt=True

"lambda" is unusable as a parameter in Analise and Recalculate

Since β€œlambda” is a reserved word in Python, I haven’t been able to change the default for this plugin in vapoursynth, I have played around with lsad and plevel, but I’m not getting even similar results as in avisynt. I use β€œlambda” in avisynth for lowering the β€œcoherency” of vectors in mvtools2, and many times I get a lot better results.

Could you please name it some other way, maybe like ilambda, klambda or whatever?

MFlowInter crashes with certain combination of hpad/vpad, pel, blksize, search, overlapv and divide

I found another crash, it happens with these parameters to MAnalyze and MFlowFPS:
hpad/vpad = 0
pel = 4
blksize = 64
search != 6
overlapv = 8
divide = 0

I'm not sure which of the issues I have filed to Avisynth MVTools is closest to this one, but it's possible some of them are related.

mvtools4_error.zip

Attached is a script which triggers the error on frame 7 of my test video which had frame size 720x680. If you have problems reproducing the error I can provide the source video as well. There are more detailed test results in the script comments.

My system is Windows 10, VapourSynth R45 64-bit (I'm using the portable FATPACK) and latest MVTools version (not released yet but provided by you in the previous issue).

A way to get motion vectors out of mvtools

I'd love to be able to use mvtools for analyzing image motion for my own postprocessing.

Would it be possible to get the results of mvtools' motion analysis out in some useful fashion? At the simplest, I'd be interested in a single β€œoverall motion” vector, but it would also be interesting to get motion vectors for each pixel (at a smaller resolution than the video, doesn't have to be fancy).

clang regression: caused by "Add ports of MDepan, DepanEstimate, and Depan"

On macOS, this no longer compiles with clang, though it does still compile with gcc. The regression occurred in 10c370e. When that commit is reverted, clang works again.

Here's what the build failure looks like:

==> make install
  CC       src/CopyCode.lo
  CC       src/CPU.lo
  CXX      src/DCTFFTW.lo
  CC       src/EntryPoint.lo
  CC       src/Fakery.lo
  CC       src/GroupOfPlanes.lo
  CC       src/Luma.lo
  CC       src/MaskFun.lo
  CC       src/MVAnalyse.lo
  CC       src/MVAnalysisData.lo
  CC       src/MVBlockFPS.lo
  CC       src/MVCompensate.lo
  CXX      src/MVDegrains.lo
  CXX      src/MVDepan.lo
  CC       src/MVFinest.lo
  CC       src/MVFlowBlur.lo
src/MVDepan.cpp:611:34: error: implicit instantiation of undefined template 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >'
            vsapi->setError(out, std::string("DepanAnalyse: failed to invoke text.FrameProps: ").append(vsapi->getError(out)).c_str());
                                 ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iosfwd:193:33: note: template is declared here
    class _LIBCPP_TYPE_VIS_ONLY basic_string;
                                ^
src/MVDepan.cpp:1485:30: error: implicit instantiation of undefined template 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >'
        vsapi->setError(out, std::string("DepanEstimate: failed to invoke std.Cache: ").append(vsapi->getError(ret)).c_str());
                             ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iosfwd:193:33: note: template is declared here
    class _LIBCPP_TYPE_VIS_ONLY basic_string;
                                ^
src/MVDepan.cpp:1514:30: error: implicit instantiation of undefined template 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >'
        vsapi->setError(out, std::string("DepanEstimate: failed to invoke std.Cache: ").append(vsapi->getError(ret)).c_str());
                             ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iosfwd:193:33: note: template is declared here
    class _LIBCPP_TYPE_VIS_ONLY basic_string;
                                ^
src/MVDepan.cpp:1536:34: error: implicit instantiation of undefined template 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >'
            vsapi->setError(out, std::string("DepanEstimate: failed to invoke text.FrameProps: ").append(vsapi->getError(out)).c_str());
                                 ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iosfwd:193:33: note: template is declared here
    class _LIBCPP_TYPE_VIS_ONLY basic_string;
                                ^
src/MVDepan.cpp:2921:34: error: implicit instantiation of undefined template 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >'
            vsapi->setError(out, std::string("DepanCompensate: failed to invoke text.FrameProps: ").append(vsapi->getError(out)).c_str());
                                 ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iosfwd:193:33: note: template is declared here
    class _LIBCPP_TYPE_VIS_ONLY basic_string;
                                ^
src/MVDepan.cpp:4254:34: error: implicit instantiation of undefined template 'std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >'
            vsapi->setError(out, std::string("DepanStabilise: failed to invoke text.FrameProps: ").append(vsapi->getError(out)).c_str());
                                 ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iosfwd:193:33: note: template is declared here
    class _LIBCPP_TYPE_VIS_ONLY basic_string;
                                ^
6 errors generated.
make: *** [src/MVDepan.lo] Error 1
make: *** Waiting for unfinished jobs....

Provide a simple example? Here: Degrain a ProRes File

Hi, I just wanted to share an example that gave me some headache as it was the first time I was using this software at all. At first, I just didn’t know where to start, there were so many unknown aspects at once. The problem is that most examples were either too short or relied on avisynth which doesn’t use Python and so has a different syntax. I also didn’t know when and how to load plugins etc. β€” Now, I have figured everything out. So, I would like to give a short and concise example on how to use the degrain function in vapoursynth-mvtools. If you like, feel free to include it somewhere or just leave it as a resolved issue so other people can find it. This is my way of expressing my gratitude for your excellent software. Thank you!

On my Macbook, I have Homebrew installed. Using this, I just installed vapoursynth-mvtools including vapoursynth itself using brew install mvtools ffms2. ffms2 is used to load the video. I put together the following Python script and saved it to a file degrain2.vpy:

from vapoursynth import core
core.std.LoadPlugin(path="/usr/local/lib/libmvtools.dylib")
core.std.LoadPlugin(path="/usr/local/lib/libffms2.dylib")
video = core.ffms2.Source(source="my_prores_video.mov")
super = core.mv.Super(video)
mvbw2 = core.mv.Analyse(super, isb=True, delta=2, overlap=4)
mvbw = core.mv.Analyse(super, isb=True, delta=1, overlap=4)
mvfw = core.mv.Analyse(super, isb=False, delta=1, overlap=4)
mvfw2 = core.mv.Analyse(super, isb=False, delta=2, overlap=4)
out = core.mv.Degrain2(clip=video, super=super, mvbw=mvbw, mvfw=mvfw, mvbw2=mvbw2, mvfw2=mvfw2, thsad=400)
out.set_output()

I then ran it using vspipe -y degrain2.vpy my_prores_video.raw. The -y is important so it can be converted using ffmpeg afterwards; the output could also be piped using - | and then the ffmpeg command instead of an output filename, but I didn’t take the time to work out how I would have to change in the ffmpeg command to make that work.

I then converted back to ProRes: ffmpeg -i my_prores_video.raw -c:v prores_ks -profile:v 4 my_prores_video-out.mov

I have omitted audio output because I was not using audio on this clip. To include audio, you could add e. g. -c:a pcm_s16le to the ffmpeg command, before the output file name.

Now that I know how to input, process and output, I can play with the options to achieve even better results. The original page seems to be down at the moment, but you can easily find it, e. g., on the Internet Archive.

typo in meson.build

meson.build says PlaneOfBlocks.c instead of PlaneOfBlocks.cpp
building fails due to this and succeeds when this is corrected
I tried to push a commit but got permission denied

FlowFPS segfault with pel=4

Linux, gcc 5.2.1 x64, current git vs & mvtools.

VS Script and stack trace follows. Only crashes if FlowFPS is used in conjuction with pel=4

import vapoursynth as vs
#import pprint as pp
import functools

# get the core instance
core = vs.get_core()

# open a video file; ret is now a clip object
source = core.raws.Source(source='/dev/stdin')

pel_         = 4
blksize_     = 8
search_      = 5
searchparam_ = 32
flow_        = False
enable_      = True

if source.width >= 2560:
    enable_ = False

elif source.width >= 1920:
    pel_     = 1
    blksize_ = 16
    searchparam_ = 16

elif source.width >= 1024:
    pel_         = 2
    blksize_     = 8
    searchparam_ = 12

elif source.width >= 640:
    pel_         = 4
    blksize_     = 8
    searchparam_ = 16

else:
    pel_         = 4
    blksize_     = 8
    searchparam_ = 16
    flow_        = True

#def animator(n, clip):
#   if n % 2 == 0:
#      return clip
#   else:
#      return core.std.ShufflePlanes(clips=clip, planes=[0, 2, 1], colorfamily=vs.YUV)

def frameInfo(n, clip):
    return core.text.Text(clip, 'frame=%d pel=%d blk=%d srchp=%d flow=%d' % (n, pel_, blksize_, searchparam_, flow_), alignment=9 );


if enable_:
    super_ = core.mv.Super(source, pel=pel_, hpad=8, vpad=8)

    back1 = core.mv.Analyse(super_, isb=True, chroma=True, blksize=blksize_,
        search=search_, searchparam=searchparam_)

    fwd1 = core.mv.Analyse(super_, isb=False, chroma=True, blksize=blksize_,
        search=search_, searchparam=searchparam_)

    #back2 = core.mv.Recalculate(super_, back1, chroma=False, blksize=8, blksizev=8, searchparam=0, search=3)

    #fwd2 = core.mv.Recalculate(super_, fwd1, chroma=False, blksize=8, blksizev=8, searchparam=0, search=3)

    # double the fps
    fpsNum = source.fps_num*2
    fpsDen = source.fps_den

    if flow_:
        out = core.mv.FlowFPS(source, super_, back1, fwd1, num=fpsNum, den=fpsDen, mask=2)
    else:
        out = core.mv.BlockFPS(source, super_, back1, fwd1, num=fpsNum, den=fpsDen, mode=3,
            blend=False,thres=0)

    out = core.std.FrameEval(out, functools.partial(frameInfo, clip=out))

    # set the clip to be output
    out.set_output()

else:
    source.set_output()
#0  0x00007f9f9e999b4f in RealMerge16PlanesToBig_uint8_t (pitch=<optimized out>, height=<optimized out>, width=<optimized out>,
    pPlane15_u8=0x7f9f75197fa0 "", pPlane14_u8=0x7f9f7518a3a0 '\200' <repeats 200 times>...,
    pPlane13_u8=0x7f9f7517c7a0 '\200' <repeats 200 times>..., pPlane12_u8=0x7f9f7516eba0 '\200' <repeats 200 times>...,
    pPlane11_u8=0x7f9f75160fa0 '\200' <repeats 200 times>..., pPlane10_u8=0x7f9f751533a0 '\200' <repeats 200 times>...,
    pPlane9_u8=0x7f9f751457a0 '\200' <repeats 200 times>..., pPlane8_u8=0x7f9f75137ba0 '\200' <repeats 200 times>...,
    pPlane7_u8=0x7f9f75129fa0 '\200' <repeats 200 times>..., pPlane6_u8=0x7f9f7511c3a0 '\200' <repeats 200 times>...,
    pPlane5_u8=0x7f9f7510e7a0 '\200' <repeats 200 times>..., pPlane4_u8=0x7f9f75100ba0 '\200' <repeats 200 times>...,
    pPlane3_u8=0x7f9f750f2fa0 '\200' <repeats 200 times>..., pPlane2_u8=0x7f9f750e53a0 '\200' <repeats 200 times>...,
    pPlane1_u8=0x7f9f750d77a0 '\200' <repeats 200 times>..., pPlane0_u8=<optimized out>, pel4Pitch=<optimized out>,
    pel4Plane_u8=0x7f9f95260280 "\200\200\200") at src/MaskFun.c:244
#1  Merge16PlanesToBig (pel4Plane=<optimized out>, pel4Pitch=2560, pPlane0=<optimized out>,
    pPlane1=pPlane1@entry=0x7f9f750b79a0 '\200' <repeats 200 times>..., pPlane2=pPlane2@entry=0x7f9f750c55a0 '\200' <repeats 200 times>...,
    pPlane3=pPlane3@entry=0x7f9f750d31a0 '\200' <repeats 200 times>..., pPlane4=<optimized out>, pPlane5=<optimized out>,
    pPlane6=<optimized out>, pPlane7=<optimized out>, pPlane8=<optimized out>, pPlane9=0x7f9f751259a0 '\200' <repeats 200 times>...,
    pPlane10=0x7f9f751335a0 '\200' <repeats 200 times>..., pPlane11=<optimized out>, pPlane12=0x7f9f7514eda0 '\200' <repeats 200 times>...,
    pPlane13=0x7f9f7515c9a0 '\200' <repeats 200 times>..., pPlane14=0x7f9f7516a5a0 '\200' <repeats 200 times>...,
    pPlane15=0x7f9f751781a0 '\200' <repeats 200 times>..., width=640, height=352, pitch=640, bitsPerSample=8) at src/MaskFun.c:255
#2  0x00007f9f9e9b9831 in mvfinestGetFrame (n=<optimized out>, activationReason=<optimized out>, instanceData=<optimized out>,
    frameData=<optimized out>, frameCtx=<optimized out>, core=<optimized out>, vsapi=0x7f9fa00e4fc0 <vsapi>) at src/MVFinest.c:103
#3  0x00007f9f9feb17eb in VSNode::getFrameInternal(int, int, VSFrameContext&) () from /usr/local/lib/libvapoursynth.so
#4  0x00007f9f9fec99f4 in VSThreadPool::runTasks(VSThreadPool*, std::atomic<bool>&) () from /usr/local/lib/libvapoursynth.so
#5  0x00007f9fa205f030 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007f9fa0e756aa in start_thread (arg=0x7f9f9c9b1700) at pthread_create.c:333
#7  0x00007f9fa1acbe9d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109

MFlowInter crashes with certain combination of blksize, overlapv, divide and thscd1

The crash occurs with a certain combination of parameters:
MAnalyze with blksize=16, overlapv=4 and divide=1 or 2.
MFlowInter with thscd1=200 or larger.

The source video affects which thscd1 threshold triggers the bug. Changing the overlapv to any other valid value 0, 2, 6 or 8 makes the bug disappear. Using divide=0 makes it go away too. It's possible to trigger the bug with other block sizes, for example using blksize=32 and overlapv=8.

This bug is basically identical to one I reported to Pinterf's Avisynth MVTools. He mentioned that the bug was fixed in this update.

I have attached a small script which triggers the crash, just change the source video.
My system is Windows 10, VapourSynth R45 64-bit (I'm using the portable FATPACK) and latest MVTools version.

mvtools_error.zip

Weird randomness

When running MvTools in VapourSynth, I run the script twice and the mask is slightly different. There's a weird randomness to it. What's causing this?

You can test this with the latest FrameRateConverter beta with Debug=true, raw values vary between instances.

Fails to build with gcc 4.9.1 (commit 6f5d0134fd3c2322da23b53f8f770eda9f2700f9)

Commit 6f5d013 makes gcc versiΓ³n 4.9.1 abort with the following error:

src/MVAnalyse.cpp: In function 'const VSFrameRef* mvanalyseGetFrame(int, int, void**, void**, VSFrameContext*, VSCore*, const VSAPI*)':
src/MVAnalyse.cpp:238:311: error: 'struct MVAnalyseData' has no member named 'coarseSearchType'
  d->nPelSearch, d->nLambda, d->lsad, d->pnew, d->plevel, d->global, d->analysisData.nFlags, reinterpret_cast<int*>(pDst), NULL, fieldShift, DCTc, d->pzero, d->pglobal, d->badSAD, d->badrange, d->meander, NULL, d->tryMany, d->coarseSearchType);

EDIT: Also clang version 3.5.0 throws the same error.

Depan frame properties

Could you briefly explain the frame properties used in Depan, so that I could implement something other than simply adding black borders? Thanks.

Compilation on FreeBSD

I've been trying to get this to compile on FreeBSD (I'm trying to get QTGMC working in vapoursynth in a freebsd jail).

It seems like the assembler code needs some changes to have it compile on freebsd - nasm has to make a.out code rather than elf code for freebsd.

I've tried to make the required changes, and the assembler compiles now, but the object files it produces aren't right and c++ can't create libmvtools.so - it errors out with:

mvtools@sha/const-a.o: file not recognized: File format not recognized
c++: error: linker command failed with exit code 1 (use -v to see invocation)

Here's what I've changed so far:
master...drphilth:master

I was hoping someone who understands this a bit better might be able to take a look at why the object files are truncated / corrupted?

Super doesn't pass a proper clip to Analyse

Or something like that.

Vapoursynth's commit vapoursynth/vapoursynth@3557742 breaks mvtools:

Python exception: Analyse: required properties not found in first frame of super clip. Maybe clip didn't come from mv.Super? Was the first frame trimmed away?
Traceback (most recent call last):
  File "vapoursynth.pyx", line 1488, in vapoursynth.vpy_evaluateScript (src/cython/vapoursynth.c:25136)
  File "/home/dani/.mpv/mvtools.py", line 18, in <module>
    bvec = core.mv.Analyse(sup, blksize=16, isb=True , chroma=True, search=3, searchparam=1)
  File "vapoursynth.pyx", line 1387, in vapoursynth.Function.__call__ (src/cython/vapoursynth.c:23631)
vapoursynth.Error: Analyse: required properties not found in first frame of super clip. Maybe clip didn't come from mv.Super? Was the first frame trimmed away?

Test case:

import vapoursynth as vs
core = vs.get_core()

v = core.std.BlankClip(format=vs.YUV420P8)

super = core.mv.Super(v)
mvbw = core.mv.Analyse(super, isb=True, delta=1, overlap=0)
mvfw = core.mv.Analyse(super, isb=False, delta=1, overlap=0)
v = core.mv.BlockFPS(clip=v, super=super, mvbw=mvbw, mvfw=mvfw, den=0, num=0)

v.set_output()

Myrsloik really likes to make my life exciting and interesting. :(

MBlockFPS/MFlowFPS crash if FPS information is missing

This is mentioned in #4 but the only suggested fix is to use AssumeFPS as a work-around, but that relies on knowing the FPS beforehand, which isn't always the case.

Since VapourSynth is based on per-frame durations, wouldn't it be better to query those durations instead of using a hard-coded FPS? Alternatively, it would suffice for most content to auto-detect the framerate based on the first frame's duration or something.

My use case is embedding MVTools as a filter in mpv, which means the script has to work for all possible input files.

Request for MScaleVect port

Would it be possible to have the smart MScaleVect functionality in Vapoursynth's MVTools as well? It can be used to speedup analysing by doing analysis on the original 8-bit clip and then using the vectors in high bit depth degraining etc. It would also make dct=5 usable, which helps with the quality of the vectors. In 16-bit analysis, it tends to slow things down quite a lot.

https://forum.doom9.org/showthread.php?p=1826390#post1826390

Overlap at half the blksize causes color change a bit

import vapoursynth as vs
core = vs.get_core()

clip = a YUV420P8 video

super = core.mv.Super(clip)
bv1 = core.mv.Analyse(super, blksize=16, isb=True, delta=1, overlap=8, truemotion=False)
fv1 = core.mv.Analyse(super, blksize=16, isb=False, delta=1, overlap=8, truemotion=False)
clip = core.mv.Degrain1(clip, super, bv1, fv1, isse=True)

clip.set_output()

Example1
Unprocessed frame
Processed frame with the above script
Processed frame with the above script but set isse=False in Degrain1

Example2
Unprocessed frame
Processed frame with the above script
Processed frame with the above script but set isse=False in Degrain1

If you view the picture in 1:1, you should easily discover the color change of the forest in the right bottom area for example1. For example2 it should be more obvious to see the difference. The issue seems to happen only when overlap is half the blksize. If I set overlap to 2, 4 or 6 in above script, the result seems fine. Using the binary you provided in v6 release or I compile from the latest git both have this problem.

Suggestion: generative outpainting in MVdepan / video stabilization

With recent advances in generative image outpainting would it be possible to have the corners "filled" in alpha channel instead of black?

Of course if everything was handled inside vapoursynth it would be even better. There are many open source outpainting options on github:
https://github.com/Udit9654/Outpainting-Images-and-Videos-using-GANs
https://github.com/basilevh/image-outpainting
https://github.com/nanjingxiaobawang/SieNet-Image-extrapolation
https://github.com/lkwq007/stablediffusion-infinity/
https://github.com/taabata/LCM_Inpaint_Outpaint_Comfy

I think the biggest possible drawback vs current mirroring/blurring method is that consistency/movement between frames might not be great, as usually is the case in generative video models thus far.

Models trained on each video (or at least a couple of neighboring frames) would perform much better, but it would be incredibly slow and complex

Motion-blur effect through blending?

Hello, I've been looking into different ways to produce motion-blur to apply on high FPS (120-360) gameplay footage, and have been making a CLI wrapper for VapourSynth with a "config system" for convenience

The main ways I've found are:

  • Using AverageFrames on high FPS clips and havsfunc.ChangeFPS to "reasonable" framerates (30/60)
  • Using frame interpolation like SVP before doing previously mentionned step (artifacts are minimal due to high FPS content being equivalent to slow-mo footage)
  • FlowBlur, commonly presented as ""a free alternative to RSMB""

One of the ways that would be interesting to try is

  • To do some interpolation convolution-based (literally only reason I mention it is because I saw "good with slow-mo" and "blended")
  • Mix interpolation and blending (if I recall correctly sometimes frame interp algos can fall back to blending when there is too much movement), then cut the FPS down to 60/30
  • Edit: Mix Blend and FlowBlur (if that is even a thing), or use Super & vectors from high FPS footage on same footage changed to 60/30

I'm just throwing ideas without really knowing what I'm talking about, do you have any suggestions or things that came in mind I should try out? Thank you πŸ‘

mv.Recalculate performs incorrectly for high bitdepth

import vapoursynth as vs
core = vs.get_core()

clip = any 16-bit clip

sup = core.mv.Super(clip)
mvbw = core.mv.Analyse(sup, blksize=16, isb=True, overlap=8)
mvfw = core.mv.Analyse(sup, blksize=16, isb=False, overlap=8)
#mvbw = core.mv.Recalculate(sup, mvbw, blksize=8, overlap=4)
#mvfw = core.mv.Recalculate(sup, mvfw, blksize=8, overlap=4)
clip = core.mv.Degrain1(clip, sup, mvbw, mvfw)
clip = core.fmtc.nativetostack16(clip)

clip.set_output()

If you uncomment the two lines, you will see the LSB part becomes all zero.

FlowBlur: Padding distortion when using pelclip

My script:

c = core.ffms2.Source(r'input.mp4')
pel = core.resize.Bilinear(c, 1280, 720)

s = core.mv.Super(c, 16, 16, rfilter=3, pelclip=pel)
bv = core.mv.Analyse(s, isb=True, blksize=16, plevel=2, dct=5)
fv = core.mv.Analyse(s, blksize=16, plevel=2, dct=5)
c = core.mv.FlowBlur(c, s, bv, fv)

Output:

virtualdub64_2018-06-19_15-21-05

There is green distortion on the edges when using pelclip and FlowBlur (Zimg and nnedi3cl produce the same artifacts). The workaround is to disable padding. BlockFPS and FlowFPS are also affected by this.

Is this a bug or is there something about Zimg/nnedi3cl or MVTools I do not know about? This also happens on Pinterf's MVTools. Thanks

MVShow support

The Avisynth ver of mvtools has a number of functions that never made it to the vapoursynth port, such as MVShow which is used to provide debug information from analyse.

super = MSuper(pel=1, mt=false)
forward_vec1 = MAnalyse(super, isb = false, chroma=false, delta = 1, mt=false)
MShow(super, showsad=true, forward_vec1, thSCD1=2000, thSCD2=2000)

How to display the true FPS in the mpv?

I have made the video played at 60fps, but it still shows "23.976".

Here is my "mvtools.vpy":

import vapoursynth as vs
core = vs.get_core()
clip = video_in

dst_fps = display_fps

while (dst_fps > 60):
dst_fps /= 2

if not (clip.width > 1920 or clip.height > 1080 or container_fps > 59):
src_fps_num = int(container_fps * 1e8)
src_fps_den = int(1e8)
dst_fps_num = int(dst_fps * 1e4)
dst_fps_den = int(1e4)
clip = core.std.AssumeFPS(clip, fpsnum = src_fps_num, fpsden = src_fps_den)
print("Reflowing from ",src_fps_num/src_fps_den," fps to ",dst_fps_num/dst_fps_den," fps.")

sup  = core.mv.Super(clip, pel=2, hpad=16, vpad=16)
bvec = core.mv.Analyse(sup, blksize=16, isb=True , chroma=True, search=3, searchparam=1)
fvec = core.mv.Analyse(sup, blksize=16, isb=False, chroma=True, search=3, searchparam=1)
clip = core.mv.BlockFPS(clip, sup, bvec, fvec, num=dst_fps_num, den=dst_fps_den, mode=3, thscd2=12)

clip.set_output()

Makefile performs no installation

Makefile doesn't seem to do any installation and resulting binary is static instead of shared, so vapoursynth doesn't seem to be able to find it. How is it supposed to be installed ?

MVFrame.cpp:HorizontalWiener_sse2() writes to memory protected by VS_FRAME_GUARD

HorizontalWiener_sse2() contains this snippet:

for (int x = 2; x < nWidth - 4; x += 8) { ... _mm_storel_epi64((__m128i *)&pDst[x], m0); }

Since _mm_storel_epi64() writes 8 bytes, this overwrites pDst[nWidth], pDst[nWidth + 1], and pDst[nWidth + 2], which may overwrite VS_FRAME_GUARD_PATTERN which is stored before the beginning and after the end of the pixel buffer. This write is caught by VSFrame::verifyGuardPattern() in the src/core/vscore.cpp in the VapourSynth R44 sources and makes VSNode::getFrameInternal() in the same file SIGABRT.

The following is the backtrace when gdb catches (via β€œwatch”) when someone writes into the protected memory:

#0 HorizontalWiener_sse2 (pDst=..., pSrc=..., nPitch=736, nWidth=736, nHeight=592, bitsPerSample=...)
at /var/tmp/portage/media-plugins/vapoursynth-mvtools-20/work/vapoursynth-mvtools-20/src/MVFrame.cpp:443
#1 0x00001554c1291365 in mvpRefine (mvp=..., sharp=...)
at /var/tmp/portage/media-plugins/vapoursynth-mvtools-20/work/vapoursynth-mvtools-20/src/MVFrame.cpp:1463
#2 0x00001554c129297d in mvpRefine (sharp=..., mvp=...)
at /var/tmp/portage/media-plugins/vapoursynth-mvtools-20/work/vapoursynth-mvtools-20/src/MVFrame.cpp:1792
#3 mvfRefine (mvf=..., nMode=..., sharp=...)
at /var/tmp/portage/media-plugins/vapoursynth-mvtools-20/work/vapoursynth-mvtools-20/src/MVFrame.cpp:1790
#4 0x00001554c1292e71 in mvgofRefine (mvgof=..., nMode=..., sharp=...)
at /var/tmp/portage/media-plugins/vapoursynth-mvtools-20/work/vapoursynth-mvtools-20/src/MVFrame.cpp:1891
#5 0x00001554c1296f14 in mvsuperGetFrame (n=..., activationReason=..., instanceData=..., frameData=..., frameCtx=..., core=..., vsapi=...)
at /var/tmp/portage/media-plugins/vapoursynth-mvtools-20/work/vapoursynth-mvtools-20/src/MVSuper.c:110
#6 0x0000155551f22a3e in VSNode::getFrameInternal (this=..., n=..., activationReason=..., frameCtx=...) at src/core/vscore.cpp:849
#7 0x0000155551f3b7b7 in VSThreadPool::runTasks (owner=..., stop=...) at src/core/vsthreadpool.cpp:186
#8 0x0000155554e0026f in std::execute_native_thread_routine (__p=...)
at /var/tmp/portage/sys-devel/gcc-7.3.0-r3/work/gcc-7.3.0/libstdc++-v3/src/c++11/thread.cc:83
#9 0x0000155553d01a15 in start_thread (arg=...) at pthread_create.c:465
#10 0x000015555484568f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

The above is from a commercial DVD, so I cannot easily post a video source. I’m in fact surprised that I only encounter his bug now since it seems to have been present since at least Oct 2016.

I’m not suggesting a patch because the SSE2 trickery is beyond me (like, six loads are more efficient than one load and five shifts and masks?).

VS-MVTools compared to InterFrame (SVPFlow)

How do they compare? (My use-case for context)

I haven't looked into either much, I just sticked with what blur has been using for a while.

The main reason (which I haven't checked in much depth, gotta admit) is that SVPFlow had better GPU acceleration..?

Let me know if anyone has aggregated a list of differences, thank you πŸ‘

[Cosmetic] dctmode in PlaneOfBlocks.c

In lines 136 to 144, it is:

} else if (pob->dctmode == 5) { // dct SAD (SATD)
    sad = pob->SATD(pob->pSrc[0], pob->nSrcPitch[0], pRef0, pob->nRefPitch[0]);
} else if (pob->dctmode == 6) { //  globally (lumaChange) weighted spatial and DCT (better estimate)
    sad = pob->SAD(pob->pSrc[0], pob->nSrcPitch[0], pRef0, pob->nRefPitch[0]);
    if (pob->dctweight16 > 0) {
        int64_t dctsad = pob->SATD(pob->pSrc[0], pob->nSrcPitch[0], pRef0, pob->nRefPitch[0]);
        sad = (sad * (16 - pob->dctweight16) + dctsad * pob->dctweight16) / 16;

Should "dctmode == 5" and "dctmode == 6" be separated like the other DCT modes?

build fails with msys2 mingw64 in r296

commit: 545d16c

build folder files:

build.zip

meson log

The Meson build system
Version: 0.51.1
Source dir: E:/Source Code/VapourSynth/vapoursynth-mvtools
Build dir: E:/Source Code/VapourSynth/vapoursynth-mvtools/build
Build type: native build
Project name: MVTools
Project version: 21
C compiler for the build machine: cc (gcc 9.2.0 "cc (Rev2, Built by MSYS2 project) 9.2.0")
C++ compiler for the build machine: c++ (gcc 9.2.0 "c++ (Rev2, Built by MSYS2 project) 9.2.0")
C compiler for the host machine: cc (gcc 9.2.0 "cc (Rev2, Built by MSYS2 project) 9.2.0")
C++ compiler for the host machine: c++ (gcc 9.2.0 "c++ (Rev2, Built by MSYS2 project) 9.2.0")
Build machine cpu family: x86_64
Build machine cpu: x86_64
Found pkg-config: C:\msys64\mingw64\bin/pkg-config.EXE (0.29.2)
Run-time dependency vapoursynth found: YES 47
Program nasm found: YES (C:\msys64\mingw64\bin/nasm.EXE)
Run-time dependency fftw3f found: YES 3.3.8
Library m found: YES
Build targets in project: 2
Found ninja.EXE-1.9.0 at 'C:\msys64\mingw64\bin/ninja.EXE'

ninja log

[1/37] Compiling C object mvtools@sha/src_MVFlowFPSHelper.c.obj.
[2/37] Generating 'mvtools@sha/cpu-a.obj'.
[3/37] Compiling C object mvtools@sha/src_MVSCDetection.c.obj.
[4/37] Compiling C object mvtools@sha/src_EntryPoint.c.obj.
[5/37] Compiling C object mvtools@sha/src_MVAnalysisData.c.obj.
[6/37] Compiling C object mvtools@sha/src_CPU.c.obj.
[7/37] Compiling C object mvtools@sha/src_MVSuper.c.obj.
[8/37] Compiling C object mvtools@sha/src_MVFinest.c.obj.
[9/37] Generating 'mvtools@sha/const-a.obj'.
[10/37] Compiling C object mvtools@sha/src_Fakery.c.obj.
[11/37] Compiling C object mvtools@sha/src_MVRecalculate.c.obj.
[12/37] Compiling C object mvtools@sha/src_GroupOfPlanes.c.obj.
[13/37] Compiling C object mvtools@sha/src_MVFlowBlur.c.obj.
[14/37] Compiling C object mvtools@sha/src_MVFlowInter.c.obj.
[15/37] Compiling C object mvtools@sha/src_MVMask.c.obj.
[16/37] Compiling C++ object mvtools@sha/src_SimpleResize.cpp.obj.
[17/37] Compiling C object mvtools@sha/src_MVFlowFPS.c.obj.
[18/37] Compiling C object mvtools@sha/src_MVAnalyse.c.obj.
[19/37] Compiling C object mvtools@sha/src_MVCompensate.c.obj.
[20/37] Compiling C++ object mvtools@sha/src_MVFlow.cpp.obj.
[21/37] Compiling C++ object mvtools@sha/src_DCTFFTW.cpp.obj.
[22/37] Compiling C++ object mvtools@sha/src_CopyCode.cpp.obj.
[23/37] Compiling C++ object mvtools@sha/src_MaskFun.cpp.obj.
[24/37] Compiling C++ object avx2@sta/src_SimpleResize_AVX2.cpp.obj.
[25/37] Compiling C object mvtools@sha/src_MVBlockFPS.c.obj.
[26/37] Compiling C++ object mvtools@sha/src_Luma.cpp.obj.
[27/37] Compiling C++ object avx2@sta/src_MaskFun_AVX2.cpp.obj.
[28/37] Linking static target libavx2.a.
[29/37] Compiling C++ object mvtools@sha/src_Overlap.cpp.obj.
[30/37] Compiling C++ object mvtools@sha/src_MVDepan.cpp.obj.
[31/37] Compiling C++ object mvtools@sha/src_MVFrame.cpp.obj.
[32/37] Generating 'mvtools@sha/sad-a.obj'.
[33/37] Compiling C++ object mvtools@sha/src_SADFunctions.cpp.obj.
[34/37] Compiling C++ object mvtools@sha/src_MVDegrains.cpp.obj.
[35/37] Generating 'mvtools@sha/pixel-a.obj'.
[36/37] Compiling C++ object mvtools@sha/src_PlaneOfBlocks.cpp.obj.
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 5; int nLogPel = 0]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
849 | int64_t nMinCostMany[8];
| ^~~~~~~~~~~~
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 0; int nLogPel = 0]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 6; int nLogPel = 0]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 9; int nLogPel = 0]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 7; int nLogPel = 0]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 10; int nLogPel = 0]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 8; int nLogPel = 0]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 3; int nLogPel = 0]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 1; int nLogPel = 0]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 4; int nLogPel = 0]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 2; int nLogPel = 0]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 10; int nLogPel = 2]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 10; int nLogPel = 1]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 9; int nLogPel = 2]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 9; int nLogPel = 1]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 8; int nLogPel = 2]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 8; int nLogPel = 1]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 7; int nLogPel = 2]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 7; int nLogPel = 1]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 6; int nLogPel = 2]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 6; int nLogPel = 1]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 5; int nLogPel = 2]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 5; int nLogPel = 1]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 4; int nLogPel = 2]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 4; int nLogPel = 1]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 3; int nLogPel = 2]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 3; int nLogPel = 1]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 1; int nLogPel = 2]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 1; int nLogPel = 1]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 0; int nLogPel = 2]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp: In function 'void doPobSearchMVs(PlaneOfBlocks*, MVFrame*, MVFrame*, SearchType, int, int, int, int, int, uint8_t*, VECTOR*, int, DCTFFTW*, int, int*, int, int, int64_t, int, int, int) [with int dctmode = 0; int nLogPel = 1]':
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[2]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[1]' may be used uninitialized in this function [-Wmaybe-uninitialized]
../src/PlaneOfBlocks.cpp:849:13: warning: 'nMinCostMany[0]' may be used uninitialized in this function [-Wmaybe-uninitialized]
[37/37] Linking target libmvtools.dll.
FAILED: libmvtools.dll
c++ @libmvtools.dll.rsp
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_MVDegrains.cpp.obj:MVDegrains.cpp:(.text+0x40b8a): undefined reference to selectDegrainFunctionAVX2(unsigned int, unsigned int, unsigned int, unsigned int)' C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_MVFrame.cpp.obj:MVFrame.cpp:(.text+0x18133): undefined reference to VerticalBilinear_avx2(unsigned char*, unsigned char const*, long long, long long, long long, long long)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_MVFrame.cpp.obj:MVFrame.cpp:(.text+0x1813a): undefined reference to HorizontalBilinear_avx2(unsigned char*, unsigned char const*, long long, long long, long long, long long)' C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_MVFrame.cpp.obj:MVFrame.cpp:(.text+0x18229): undefined reference to Average2_avx2(unsigned char*, unsigned char const*, unsigned char const*, long long, long long, long long)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_MVFrame.cpp.obj:MVFrame.cpp:(.text+0x182bc): undefined reference to VerticalWiener_avx2(unsigned char*, unsigned char const*, long long, long long, long long, long long)' C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_MVFrame.cpp.obj:MVFrame.cpp:(.rdata$.refptr._Z19VerticalWiener_avx2PhPKhxxxx[.refptr._Z19VerticalWiener_avx2PhPKhxxxx]+0x0): undefined reference to VerticalWiener_avx2(unsigned char*, unsigned char const*, long long, long long, long long, long long)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_MVFrame.cpp.obj:MVFrame.cpp:(.rdata$.refptr._Z21HorizontalWiener_avx2PhPKhxxxx[.refptr._Z21HorizontalWiener_avx2PhPKhxxxx]+0x0): undefined reference to HorizontalWiener_avx2(unsigned char*, unsigned char const*, long long, long long, long long, long long)' C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_MVFrame.cpp.obj:MVFrame.cpp:(.rdata$.refptr._Z21DiagonalBilinear_avx2PhPKhxxxx[.refptr._Z21DiagonalBilinear_avx2PhPKhxxxx]+0x0): undefined reference to DiagonalBilinear_avx2(unsigned char*, unsigned char const*, long long, long long, long long, long long)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_MVFrame.cpp.obj:MVFrame.cpp:(.rdata$.refptr._Z23HorizontalBilinear_avx2PhPKhxxxx[.refptr._Z23HorizontalBilinear_avx2PhPKhxxxx]+0x0): undefined reference to HorizontalBilinear_avx2(unsigned char*, unsigned char const*, long long, long long, long long, long long)' C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_MVFrame.cpp.obj:MVFrame.cpp:(.rdata$.refptr._Z21VerticalBilinear_avx2PhPKhxxxx[.refptr._Z21VerticalBilinear_avx2PhPKhxxxx]+0x0): undefined reference to VerticalBilinear_avx2(unsigned char*, unsigned char const*, long long, long long, long long, long long)'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_MVFrame.cpp.obj:MVFrame.cpp:(.rdata$.refptr._Z13Average2_avx2PhPKhS1_xxx[.refptr._Z13Average2_avx2PhPKhS1_xxx]+0x0): undefined reference to Average2_avx2(unsigned char*, unsigned char const*, unsigned char const*, long long, long long, long long)' C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_Overlap.cpp.obj:Overlap.cpp:(.text+0x9bf): undefined reference to selectOverlapsFunctionAVX2'
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: mvtools@sha/src_SADFunctions.cpp.obj:SADFunctions.cpp:(.text+0x150a0): undefined reference to `selectSADFunctionAVX2'
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

Some filters request frames during "create" function

Some filters such as Analyse or FlowFPS request the first frame during the "create" function. This is assuming the source filter is available to provide the source frame at any time. However, I don't think it's true because some source filters might need the metadata (e.g. video info) of the output clip to be available. In that case, there is a dead lock: mvtools blocks the return of the clip, and the unavailability of the clip blocks source filter to provide frame to mvtools.

The AviSynth version of mvtools does not have this problem, e.g. MAnalyse.

Disclaimer: I'm the author of DirectShow VapourSynth Filter. In order to provide source frame, our filter needs to know the video info to correctly connect to the DirectShow graph.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.