Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory not properly freed between changes an preview refresh #55

Closed
Selur opened this issue May 2, 2024 · 11 comments
Closed

Memory not properly freed between changes an preview refresh #55

Selur opened this issue May 2, 2024 · 11 comments

Comments

@Selur
Copy link

Selur commented May 2, 2024

Build latest version from git to test.

Using:

# Imports
import vapoursynth as vs
# getting Vapoursynth core
import ctypes
import sys
import os
core = vs.core
# Import scripts folder
scriptPath = 'F:/Hybrid/64bit/vsscripts'
sys.path.insert(0, os.path.abspath(scriptPath))
# Loading Support Files
Dllref = ctypes.windll.LoadLibrary("F:/Hybrid/64bit/vsfilters/Support/libfftw3f-3.dll")
# loading plugins
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/libsangnom.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/EEDI2.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/SharpenFilter/AWarpSharp2/libawarpsharp2.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DebandFilter/Neof3kdb/neo-f3kdb.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/TTempSmooth/TTempSmooth.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/DCTFilter.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DeblockFilter/Deblock/Deblock.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/FFT3DFilter/fft3dfilter.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/CTMF/CTMF.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/libmvtools_sf_em64t.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/TCanny.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/FluxSmooth/libfluxsmooth.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DerainbowFilter/BiFrost/libbifrost.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/DePan.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/GrainFilter/RemoveGrain/RemoveGrainVS.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/GrainFilter/AddGrain/AddGrain.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/DFTTest/DFTTest.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/NEO_FFT3DFilter/neo-fft3d.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/EEDI3m.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/ResizeFilter/nnedi3/vsznedi3.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/libmvtools.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/scenechange.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/Support/fmtconv.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/MiscFilter/MiscFilters/MiscFilters.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DeinterlaceFilter/Bwdif/Bwdif.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DerainbowFilter/DeCross/libdecross.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/SourceFilter/d2vSource/DGDecode.dll")
# Import scripts
import mvsfunc
import muvsfunc
import G41Fun
import lostfunc
import adjust
import havsfunc
import validate
# Source: 'C:\Users\Selur\Desktop\Sample\Sample.mpg'
# Current color space: YUV420P8, bit depth: 8, resolution: 720x480, frame rate: 29.97fps, scanorder: top field first, yuv luminance scale: limited, matrix: 470bg
# Loading C:\Users\Selur\Desktop\Sample\Sample.mpg using DGDecode
clip = core.dgdecode.MPEG2Source("J:/tmp/mpg_65ef6c100374fd10d8d2d894338abe7e_853323747.d2v",info=3)# 29.97 fps, scanorder: top field first
frame = clip.get_frame(0)
# Setting detected color matrix (470bg).
clip = core.std.SetFrameProps(clip=clip, _Matrix=5)
# setting color transfer (170), if it is not set.
if validate.transferIsInvalid(clip):
  clip = core.std.SetFrameProps(clip=clip, _Transfer=6)
# setting color primaries info (to 470), if it is not set.
if validate.primariesIsInvalid(clip):
  clip = core.std.SetFrameProps(clip=clip, _Primaries=5)
# setting color range to TV (limited) range.
clip = core.std.SetFrameProps(clip=clip, _ColorRange=1)
# making sure frame rate is set to 29.97fps
clip = core.std.AssumeFPS(clip=clip, fpsnum=30000, fpsden=1001)
# making sure the detected scan type is set (detected: top field first)
clip = core.std.SetFrameProps(clip=clip, _FieldBased=2) # tff
# rainbow removal using DeCross
clip = core.decross.DeCross(clip=clip)
# Deinterlacing using QTGMC
clip = havsfunc.QTGMC(Input=clip, Preset="Fast", TFF=True) # new fps: 29.97
# Making sure content is preceived as frame based
clip = core.std.SetFrameProps(clip=clip, _FieldBased=0) # progressive
clip = clip[::2] # selecting previously even frames
# adjusting color using Tweak
clip = adjust.Tweak(clip=clip, hue=0.01, sat=1.00, cont=1.00, coring=True)
# Fixing chroma bleeding using FixChromaBleedingMod
clip = havsfunc.FixChromaBleedingMod(input=clip)
clip = havsfunc.Vinverse(clp=clip)
# stabilizing using Stab
clip = lostfunc.Stab(clp=clip,range=0,mirror=15)
# rainbow removal using BiFrost
clip = core.bifrost.Bifrost(clip=clip, variation=3, interlaced=False)
# removing grain using STPresso
clip = havsfunc.STPresso(clp=clip, planes=[0])
# removing grain using TemporalDegrain2
clip = G41Fun.TemporalDegrain2(clip=clip, degrainPlane=4, meAlgPar=False, postFFT=0, fftThreads=1)
# denoising using MCTemporalDenoise
clip = havsfunc.MCTemporalDenoise(i=clip, settings="medium", ncpu=1)
# debanding using f3kdb
clip = core.neo_f3kdb.Deband(clip, y=45, cb=44, cr=45, grainy=35, grainc=44, dither_algo=1, keep_tv_range=True, output_depth=8)
# sharpening using AWarpSharp2
clip = core.warp.AWarpSharp2(clip=clip, thresh=64, blur=2, chroma=True, planes=[1,2])
clip = muvsfunc.BlindDeHalo3(clip, strength=25, sharpness=0.01, interlaced=False)
# deringing using HQDeringmod
clip = havsfunc.HQDeringmod(clip, nrmode=2, darkthr=3.0)
# line darkening using Toon
clip = havsfunc.Toon(input=clip,str=0.25)
# applying anti aliasing using santiag
clip = havsfunc.santiag(c=clip, nns=3, pscrn=2, aa=34)
# adding Grain using AddGrain
clip = core.grain.Add(clip=clip, var=0.00, uvar=0.30, constant=True)
# adjusting output color from: YUV420P8 to YUV420P10 for NVEncModel
clip = core.resize.Bicubic(clip=clip, format=vs.YUV420P10, range_s="limited")
# set output frame rate to 29.97fps (progressive)
clip = core.std.AssumeFPS(clip=clip, fpsnum=30000, fpsden=1001)
# output
clip.set_output()

whenever I change something (for example the values of neo_f3kdb.Deband ) and refresh the preview, ram usage increases by ~450MB

@YomikoR
Copy link
Owner

YomikoR commented May 2, 2024

Thanks for reporting. I can reproduce since the commit bfc002e . Could you check if the latest commit helps, especially when using a CUDA filter with fixed size VRAM allocation?

@Selur
Copy link
Author

Selur commented May 3, 2024

That does seem to help, I also noticed, that this only happens when
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DerainbowFilter/BiFrost/libbifrost.dll")
from https://github.com/dubhater/vapoursynth-bifrost is used.

@YomikoR
Copy link
Owner

YomikoR commented May 3, 2024

The bifrost plugin looks good to me without a memory issue. I checked with a clip with big dimensions so that the memory change is evident enough.

@Selur
Copy link
Author

Selur commented May 3, 2024

Strange, if I remove BiFrost from my script the memory leak from refreshing basically goes away.

@YomikoR
Copy link
Owner

YomikoR commented May 4, 2024

Just now on another PC I confirmed that VRAM allocated by filters is freed in the release build (6.6). This means filters are correctly freed on F5 refresh. But possibly, due to an unknown issue, the core is not freed. BiFrost is a temporal filter that relies on frame caches, which is managed by the core. Maybe that explains what you found.

@Selur
Copy link
Author

Selur commented May 4, 2024

Hmm,.. so it might be a bug in Vapoursynth itself?
Even when using a simple script as:

import vapoursynth as vs
core = vs.core
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/SourceFilter/LSmashSource/LSMASHSource.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DerainbowFilter/BiFrost/libbifrost.dll")
clip = core.lsmas.LWLibavSource(source="G:/TestClips&Co/files/test.avi")
clip = core.bifrost.Bifrost(clip=clip, interlaced=False)

clip.set_output()

I see the RAM usage of vedit increase by ~18MB per refresh.

@YomikoR
Copy link
Owner

YomikoR commented May 4, 2024

If it's merely 18MB then nobody else would think it's a problem..

@Selur
Copy link
Author

Selur commented May 4, 2024

With this script sure, but my initial script it's 450mb per reload, which might be more concerning for most users. ;)

@myrsloik
Copy link

myrsloik commented May 4, 2024

Replace bifrost with some other stupid temporal filter like the widely despised temporalsoften2. See if it still leaks. It may be one of gazillion filters before or after.

@Selur
Copy link
Author

Selur commented May 4, 2024

@myrsloik :
it happens with:

import vapoursynth as vs
core = vs.core
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/SourceFilter/LSmashSource/LSMASHSource.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DerainbowFilter/BiFrost/libbifrost.dll")
clip = core.lsmas.LWLibavSource(source="G:/TestClips&Co/files/test.avi")
clip = core.bifrost.Bifrost(clip=clip, interlaced=False)
clip.set_output()

(no gazillion filters before or after)
with:

import vapoursynth as vs
core = vs.core
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/SourceFilter/LSmashSource/LSMASHSource.dll")
core.std.LoadPlugin(path="F:/Hybrid/64bit/vsfilters/DenoiseFilter/TemporalSoften2/libtemporalsoften2.dll")
clip = core.lsmas.LWLibavSource(source="G:/TestClips&Co/files/test.avi")
clip = core.focus2.TemporalSoften2(clip=clip)
clip.set_output()

it does not happen.

@YomikoR
Copy link
Owner

YomikoR commented May 5, 2024

Core freed but 2 filter instance(s) still exist

I did miss interlaced=False in my tests. Now I can reproduce the memory leak from the plugin. Otherwise there's a ~2MB memory increment on each F5 refresh (which I thought was referring to your 18MB claim).

@YomikoR YomikoR closed this as completed May 5, 2024
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

No branches or pull requests

3 participants