AviSynth / AviSynthPlus

AviSynth with improvements
http://avs-plus.net
972 stars 75 forks source link

Problem with the frame properties and prefetch #254

Open gispos opened 2 years ago

gispos commented 2 years ago

If the frame properties are read immediately after a get_frame, avisynth gets stuck when prefetch is used.

Sequences when initializing a new clip, for illustration:

clip = env.invoke('Eval', args) frame = clip.get_frame(nr) re = env.props_get_matrix(frame)

That still worked up to 3.71 test 22 version, the 3.71 final 3593 stuck. With the final version, a waiting time must be set after get_frame, which is 0.1 to 1.0 seconds, depending on the filters used.

clip = env.invoke('Eval', args) frame = clip.get_frame(nr) time.sleep(1.0) re = env.props_get_matrix(frame)

And then there is another problem, but it is probably related to the first one, and also affects version 3.71 test 22. UsharpMask() does not pass properties, but sometimes I get the properties before the filter (only with prefetch).

pinterf commented 2 years ago

I suppose props_get_matrix is your own function which calls get frame props ro? The second one can occur when frame property is set but there is no preceding MakeWritable or MakePropertyWritable or NewVideoFrame before obtaining RW-type access to the properties... I'm going to check how it can happen.

Could you provide a script that shows these errors? Last time you mentioned the 3.7.1 test22 changes I was not able to reproduce the issues.

gispos commented 2 years ago

Yes, props_get_matrix calls get frame props ro and returns the integer value.

The 3.71 test 22 is the last version that has no problems with prefetch. All of the following cause problems with different filter prefetch combinations. And that is mostly when only a single filter with a low load is used. e.g. Spline36Resize

Prefetch(6) works with a filter, but prefetch(4) causes Avisynth to hang. With another filter, prefetch(2) will work, but prefetch(4) will not work, and prefetch(8) will work again.

The whole thing is just thought, don't hit me: ;) The thread synchronization got mixed up. When I request a frame, avisynth returns the frame even though a thread has not yet ended, I call up the frame properties and the last thread cannot terminate and avisynth hangs.

That would at least explain why there are no problems when I use a waiting period.

An error in the thread synchronization would also explain the different frame properties. Once the thread that works before UnsharpMask() returns the properties and another time the thread that works after UnsharpMask().

For me and for others, a simple resize filter with prefetch doesn't work with Versions greater 3.71 test 22, but with the final version I didn't test it properly because there were already problems with prefetch and the properties.

Spline36Resize (1920, 1080) prefetch(2) And then change the prefetch value, for you maybe prefetch(2) does work, but 4 does not.

pinterf commented 2 years ago

1.) I'm not able to reproduce hang. Does it hang from avsmeter64 or during an ffmpeg/x264 encoding or when loaded to avspmod when and step-by-step or run continously?

I need the exact script which hangs for you.

2.) Using this script:

lsmashvideosource("13HoursCUT.mp4", format="YUV420P8")
propSet("_Matrix",2)
UnsharpMask(strength=64, radius=3, threshold=8)
PropShow()
prefetch(8)

I can see frame properties appear / not passed randomly. The possible reason is that my UnsharpMask is from warpsharp.dll which is an ancient AviSynth 2.5 plugin, with "baked" code interface elements. It may not even use AviSynth interface calls, instead does things hardcoded from the actual avisynth header it was built with in 2011.

Asd-g commented 2 years ago

For me - the hanging happens with ffms2/lsmash and release version of avs+ (avspmod 2.7.02). Using colorbars/blankclip is fine. Using debug version of avs+ and ffms2/lsmash + avspmod 2.7.0.2 doesn't hang. Maybe something is uninitialized? Script:

FFVideoSource()
Tweak(sat=2)
prefetech(2)

Also the following script crash avspmod without any message (both release and debug versions of avs+*):

FFVideoSource()
prefetech(1)

* avs+ r3593

pinterf commented 2 years ago

Thank you all,

so far my only finding that the last life-sign of avspmod when it calls into ConvertToRGB32. I could not find so far how the env pointer is handled inside avspmod. Is a saved env reused from a different thread?

gispos commented 2 years ago

Hello Ferenc, have created a small video to bring the problem closer to you visually. And also created a test version of AvsPmod. With Help > 'Test 1 second wait' a delay of 1 second can be set between get_frame and get_properties (matrix).

Download: https://www.mediafire.com/file/e3s53mn861rdyep/AvsPmod_test_package.7z/file

The result of the video, unfortunately you can't see the mouse pointer, but I think it should also be recognizable what I'm choosing.

Avisynth 3.71 final 3593

  1. run: with prefetch and read matrix = Failed
  2. run: without prefetch but with read matrix = Ok
  3. run: with prefetch and read matrix and 1 second waiting beetwen get frame and get matrix = Ok
  4. run: with prefetch but without read matrix = Ok
  5. run: again with prefetch and read matrix = Failed
  6. run: again with prefetch and read matrix and 1 second waiting beetwen get frame and get matrix = Ok

In the 3.71 final version there is a problem with prefetch and the frame properties. If I run the same script in 3.71 test 22 there are no problems.

That is the function that sets a delay of 1 second between get_frame and get_matrix.

    def _get_matrix():
        re = -1
        try:
            if self.current_frame > -1:
                nr = min(self.current_frame, self.Framecount-1)
            else: nr = 0
            global prop_wait_time
            frame = self.clip.get_frame(nr)
            time.sleep(prop_wait_time) # avisynth bug in 3.71 final
            if self.clip.get_error() is None:
                re = self.env.props_get_matrix(frame)
        except:
            pass
        frame = None
        return re

PS: the env is always created new.

Totally forgot:

Spline36Resize(1920, 1080) McDegrainSharp(frames=2, bblur=0.6, csharp=0.6, bsrch=true) prefetch(4)

pinterf commented 2 years ago

Thank you. As for the hang: I've found where it stalls: source filter's MT_SERIALIZED mutex. But the situation is unclear for me. It happens when creating ConvertToRGB32, it calls first ConvertToYUV444, which in turn calls child filter chain GetFrame #0 for getting frame properties to initialize the filter upon (this is the change what test22 build introduced). When it reaches to an MT_SERIALIZED filter in the filter chain (the beginning source filter in my case) it stops as if its mutex guard were already used. And this is what I'm inspecting now.

EDIT: I've found something, and try to arrange a build by tomorrow.

gispos commented 2 years ago

Ok, (I was still heard). Thank you.

pinterf commented 2 years ago

3.7.2 test 1 build https://drive.google.com/uc?export=download&id=1A2Jb2OSYzGI0tBFEmvlT0RxxLwVoCiP_

gispos commented 2 years ago

Considered good. No problems realized. The only minor drawback: when out of date? Filters like UnsharpMask (my favorite sharpness filter) do not pass the properties on but then sometimes they are still displayed. But I don't mind that!

It would be nice if the 3.72 would soon be public, for all the users who are not in Doom9.

Thanks a lot.

realfinder commented 2 years ago

Considered good. No problems realized. The only minor drawback: when out of date? Filters like UnsharpMask (my favorite sharpness filter) do not pass the properties on but then sometimes they are still displayed. But I don't mind that!

It would be nice if the 3.72 would soon be public, for all the users who are not in Doom9.

Thanks a lot.

you can use UnsharpMask_avsi https://github.com/realfinder/AVS-Stuff/blob/Community/avs%202.5%20and%20up/UnsharpMask_avsi.avsi or UnsharpMask_HBD https://github.com/Dogway/Avisynth-Scripts/blob/41f12a8652915d55837c46e1916736d8678a994d/MIX%20mods/SharpenersPack.avsi#L590

pinterf commented 2 years ago

Download link is published in doom9 topic. UnsharpMask: was it a closed source (warpsharp.dll)? If it is based on VirtualDub's one, its source - at least the core implementation of this specific filter- would be usable. (If this filter is so specific that it has no replacement which looks the same as the original one)

realfinder commented 2 years ago

it's in WarpSharp yes, (not aWarpSharp), it's GPLv2 BUT no C code I think only Inline assembler

Reel-Deal commented 2 years ago

UnsharpMask: was it a closed source (warpsharp.dll)? If it is based on VirtualDub's one, its source - at least the core implementation of this specific filter- would be usable.

Maybe BoxBlur from VS would be just as usable: https://github.com/myrsloik/WarpSharpSupport/blob/master/wss.py

Pinterf, did you forget your "quick and dirty UnsharpMask replacement for Avs+" :) ?

I'm not sure which of the 4 implementations is faster...


BUT no C code I think only Inline assembler

Correct me if I'm wrong but I don't think UnsharpMask and XSharpen are assembly only, unlike most of the other filters in the WarpSharp plugin.

See here: https://github.com/nekopanda/warpsharp/blob/master/warpsharp/src/unsharp.h https://github.com/nekopanda/warpsharp/blob/master/warpsharp/src/xsharpen.h

The filter WarpSharp() exist as a standalone plugin for AviUtil and is not assembly: https://github.com/makiuchi-d/warpsharp-aviutl/blob/master/warpsharp.cpp

Maybe others exist just like that but I have not looked around.

Edit: found some more links Unsharp Mask Filter for VirtualDub Xsharpen Filter for VirtualDub WarpSharp YV12 - this one does include asm

pinterf commented 2 years ago

I've not reverse engineered warpsharp.dll but (as it's done by Nekopanda) I suppose the UnsharpMask() implementation in https://github.com/nekopanda/warpsharp/blob/master/warpsharp/src/unsharp.h must be the very similar to the one that exists in warpsharp.dll. So if someone would take the job then this source is a good candidate to replace warpsharp.dll's Avisynth 2.5 style source-less UnsharpMask. Then it can further be developed to support other than YV12/YUY2.

pinterf commented 2 years ago

Pinterf, did you forget your "quick and dirty UnsharpMask replacement for Avs+" :) ?

I faintly remembered on it... :)

It's not only the speed but also the quality can be different between them.

Reel-Deal commented 2 years ago

I've not reverse engineered warpsharp.dll but (as it's done by Nekopanda) I suppose the UnsharpMask() implementation in https://github.com/nekopanda/warpsharp/blob/master/warpsharp/src/unsharp.h must be the very similar to the one that exists in warpsharp.dll. So if someone would take the job then this source is a good candidate to replace warpsharp.dll's Avisynth 2.5 style source-less UnsharpMask. Then it can further be developed to support other than YV12/YUY2.

The original WarpSharp plugin was not sourceless. Nekopanda's fork should be identical to the original. Looking at the original source it seems that Nekopanda did not do much to UnsharpMask() or any of the other filters that are not ASM. As for the rest of the filters that were asm only, he did convert them to intrinsics to make it x64 compatible.


Pinterf, did you forget your "quick and dirty UnsharpMask replacement for Avs+" :) ?

I faintly remembered on it... :)

It's not only the speed but also the quality can be different between them.

Gotcha, have not tested out the visual output between all of the script implementations. Myrsloik said he checked the source when he implemented his script version. That was the initial version, latest is here.

realfinder commented 2 years ago

BUT no C code I think only Inline assembler

Correct me if I'm wrong but I don't think UnsharpMask and XSharpen are assembly only, unlike most of the other filters in the WarpSharp plugin.

See here: https://github.com/nekopanda/warpsharp/blob/master/warpsharp/src/unsharp.h https://github.com/nekopanda/warpsharp/blob/master/warpsharp/src/xsharpen.h

The filter WarpSharp() exist as a standalone plugin for AviUtil and is not assembly: https://github.com/makiuchi-d/warpsharp-aviutl/blob/master/warpsharp.cpp

Maybe others exist just like that but I have not looked around.

Edit: found some more links Unsharp Mask Filter for VirtualDub Xsharpen Filter for VirtualDub WarpSharp YV12 - this one does include asm

well, I didn't check, and since it old plugin I assumed it got no c code :) anyway UnsharpMask_avsi visual output is same as UnsharpMask, and I assume dogway UnsharpMask_HBD is the same

my UnsharpMask_avsi based on Myrsloik code btw, same for Xsharpen_avsi

Asd-g commented 2 years ago
FFVideoSource(yv12)
blur(1) #any filter
prefetch(1)

With r3620 this script (using prefetch(1)) is still crashing AvsPmod (Video > Display > YUV -> RGB > 'Read from source or script' enabled).

Edit: avsmeter also crashes.

pinterf commented 2 years ago

Thanks for noticing Prefetch(1), I think I fixed this case as well, still testing a bit. (I was not able to reproduce it with avsmeter, only from avspmod)

gispos commented 2 years ago

Thanks for noticing Prefetch(1), I think I fixed this case as well, still testing a bit. (I was not able to reproduce it with avsmeter, only from avspmod)

I think that AvsMeter does not read frame properties.

Asd-g commented 2 years ago

Thanks for noticing Prefetch(1), I think I fixed this case as well, still testing a bit. (I was not able to reproduce it with avsmeter, only from avspmod)

The avsmeter crash was reproducible with :

FFVideoSource(yv12)
blur(1) #any filter
prefetch(1)
tweak(sat=2)
prefetch(2)

r3622 is ok. Thanks.

magiblot commented 2 years ago

Regarding 3bddee21394fd6c1ae8236dd1be2592b1e8e3bc5, could it be that GetAudio needs the same fix?