Closed BlackMickey closed 2 years ago
Yeah. I think it is the same problem as vapoursynth-mvtools, which tries to get frame 0 to access properties. Unfortunately, they decided to not change that.
The problem is introduced in this commit, which as you observed, is around v3.7.1. AviSynth+ has a related issue. And as the release note of their v3.7.2 says, if you specifies fulls
argument, it should work.
SVP works because it uses AviSynth+ 3.5.1.
Unless AviSynth+ and VapourSynth introduce the concept of clip properties, there is nothing this filter can do to fix this (i.e. there is no frame to get during initialization, since the playback hasn't started). You have to stay at an earlier version of AviSynth+.
@BlackMickey You could try https://github.com/CrendKing/avisynth_filter/actions/runs/2193657724 to see if AVS 3.7.1/2 works now. Also https://github.com/CrendKing/avisynth_filter/issues/70.
The player will no longer hang. However, when the script contains 2 functions (ConvertBits or ConvertToYUV420) to play YUV444 format video, the first frame is green. Other than that, everything is fine.
Avisynth: v3.7.2 Avisynth Filter: https://github.com/CrendKing/avisynth_filter/actions/runs/2207139952
Script:
input_m = AvsFilterSource() # YUV444P10
input_m = Is420(input_m) ? input_m : ConvertToYUV420(input_m) # YUV420P10
input_m = input_m.ConvertToYUV420() # YUV420P10
input_m.Subtitle(
\ "\nPixelType = " + String(PixelType(input_m))
\ + "\nIsPlanar = " + String(IsPlanar(input_m))
\ + "\nHasAlpha = " + String(HasAlpha(input_m))
\ + "\nBitsPerComponent = " + String(BitsPerComponent(input_m))
\ , font="courier", text_color=$ffffff, size=32, align=9, lsp=0) # YUV420P10
Tried your script on a YUV444P10 video and can't reproduce. Could you share the log? Potentially I will also need your video to hopefully repro.
Link: https://drive.google.com/file/d/19wowhkJZiOcTz1irKh6CaB9KslUzHOEH/view?usp=sharing
global threads = 4
input_m = AvsFilterSource() # YUV444P10 (Y410)
input_m = Is420(input_m) ? input_m : ConvertToYUV420(input_m) # YUV420P10
input_m = input_m.ConvertBits(8) # YUV420P8 (YV12)
input_m.Subtitle(
\ "\nPixelType = " + String(PixelType(input_m))
\ + "\nIsPlanar = " + String(IsPlanar(input_m))
\ + "\nHasAlpha = " + String(HasAlpha(input_m))
\ + "\nBitsPerComponent = " + String(BitsPerComponent(input_m))
\ , font="courier", text_color=$ffffff, size=32, align=9, lsp=0) # YUV420P8 (YV12)
Just to confirm, does the first green frame stay forever until you seek, or it's just a flash?
just a flash.
Same. I think it's the best we can do, because at the time ConvertBits requests that first frame, we don't have frame to give it. So I created dummy frame (with no data, which shows as green by default). If that filter actually passes that frame downstream, instead of request frame 0 later again, then you see green frame.
If you really don't like that one green frame, you still can change ConvertBits(8)
to something like ConvertBits(8, fulls=true)
. But it is specific to certain filters like ConvertBits. Not every filter has that kind of workaround. The best we can do, still, is either hope AviSynth+ stop doing this, or request them to formally introduce clip property.
I understand. Thank you for all your hard work.
I took some time to rethink about the filter's architecture, and I thought a way to actually fix the frame 0 problem instead of just working around it. You can find a test build at https://github.com/CrendKing/avisynth_filter/actions/runs/2211396382. This is experimental, so expect to have bug. Let me know if you still see green frame.
Also, if you can, also test the VapourSynth version. VapourSynth mvtools also requests frame 0.
If AviSynth Filter disable the logging, the player crashes when it is played.
Very interesting finding. The cause is that logging makes worker thread slightly slower, just enough to avoid a race condition. Because I never disable logging during development, I couldn't find this.
https://github.com/CrendKing/avisynth_filter/actions/runs/2212279321 should fix this.
It works fine.
Great. I'll give it some time. If nobody has found any problem, I'll merge and release this approach in the next version.
Just to document for future readers: The reason why I think the frame 0 is a problem was that because there used to be one frameserver, which is both used for media type negotiation and frame serving. Later we broke that into main and aux frameserver, where ideally the former is purely used for frame serving and the latter purely for negotiation. However, until now, the implementation doesn't follow that principle perfectly, i.e. some negotiation is still done in main, which happens earlier than the receiving of the first source frame. Because of that, I used to think this is a chicken-egg problem.
By moving all negotiation logic to aux, followed by delaying activation of the main until certain number of source frames have been stored, we can then properly solve the issue. The number of pre-buffered frames is currently hardcoded as 3. If needed, this can be increased, at the cost of delaying the first frame after start/seeking.
Hello.
Looks like 3 pre-buffered frames is not enough for some temporal filters. TemporalDegrain2() works fine but TemporalDegrain2(degrainTR=2) cause AVSF to stuck.
T 25792 @ 0: Filter version: 1.4.1 # 5cbac67
T 25792 @ 0: Configured script file: test.avs
T 25792 @ 0: Configured input format NV12: 1
T 25792 @ 0: Configured input format YV12: 1
T 25792 @ 0: Configured input format I420: 1
T 25792 @ 0: Configured input format IYUV: 1
T 25792 @ 0: Configured input format P010: 1
T 25792 @ 0: Configured input format P016: 1
T 25792 @ 0: Configured input format YUY2: 1
T 25792 @ 0: Configured input format P210: 1
T 25792 @ 0: Configured input format P216: 1
T 25792 @ 0: Configured input format YV24: 1
T 25792 @ 0: Configured input format Y410: 1
T 25792 @ 0: Configured input format Y416: 1
T 25792 @ 0: Configured input format RGB24: 0
T 25792 @ 0: Configured input format RGB32: 0
T 25792 @ 0: Loading process: mpc-hc64.exe
T 25792 @ 0: FrameServerCommon()
T 25792 @ 3: AviSynth version: AviSynth+ 3.7.2 (r3661, 3.7, x86_64)
T 25792 @ 3: AviSynth supports frame properties
T 25792 @ 5: CSynthFilter(): 0000017B78451610
T 25792 @ 5: ReloadScript from auxiliary frameserver
T 25792 @ 172: Source frame 0 is requested without the frame handler being linked
T 25792 @ 557: Source frame 0 is requested without the frame handler being linked
T 25792 @ 562: Source frame 0 is requested without the frame handler being linked
T 25792 @ 570: Source frame 1 is requested without the frame handler being linked
T 25792 @ 592: Source frame 2 is requested without the frame handler being linked
T 25792 @ 842: Source frame 3 is requested without the frame handler being linked
T 25792 @ 858: Source frame 0 is requested without the frame handler being linked
T 25792 @ 860: Source frame 2 is requested without the frame handler being linked
T 25792 @ 960: Source frame 4 is requested without the frame handler being linked
T 25792 @ 1400: New script clip: 0000017B7B1513C0
T 25792 @ 1400: Release script clip: 0000017B7B1513C0
T 25792 @ 1448: Add compatible formats: input NV12 output NV12
T 25792 @ 1448: Add compatible formats: input NV12 output YV12
T 25792 @ 1448: Add compatible formats: input NV12 output I420
T 25792 @ 1448: Add compatible formats: input NV12 output IYUV
T 25792 @ 1448: ReloadScript from auxiliary frameserver
T 25792 @ 1613: Source frame 0 is requested without the frame handler being linked
T 25792 @ 1989: Source frame 0 is requested without the frame handler being linked
T 25792 @ 1994: Source frame 0 is requested without the frame handler being linked
T 25792 @ 2002: Source frame 1 is requested without the frame handler being linked
T 25792 @ 2024: Source frame 2 is requested without the frame handler being linked
T 25792 @ 2312: Source frame 3 is requested without the frame handler being linked
T 25792 @ 2328: Source frame 0 is requested without the frame handler being linked
T 25792 @ 2331: Source frame 2 is requested without the frame handler being linked
T 25792 @ 2433: Source frame 4 is requested without the frame handler being linked
T 25792 @ 2860: New script clip: 0000017B4AD40400
T 25792 @ 2860: Release script clip: 0000017B4AD40400
T 25792 @ 2903: Add compatible formats: input YV12 output NV12
T 25792 @ 2903: Add compatible formats: input YV12 output YV12
T 25792 @ 2903: Add compatible formats: input YV12 output I420
T 25792 @ 2903: Add compatible formats: input YV12 output IYUV
T 25792 @ 2903: ReloadScript from auxiliary frameserver
T 25792 @ 3062: Source frame 0 is requested without the frame handler being linked
T 25792 @ 3062: Source frame 0 is requested without the frame handler being linked
T 25792 @ 3681: New script clip: 0000017B4CED1A10
T 25792 @ 3681: Release script clip: 0000017B4CED1A10
T 25792 @ 3711: Add compatible formats: input P010 output P010
T 25792 @ 3711: ReloadScript from auxiliary frameserver
T 25792 @ 3867: Source frame 0 is requested without the frame handler being linked
T 25792 @ 3868: Source frame 0 is requested without the frame handler being linked
T 25792 @ 4347: New script clip: 0000017B53F16EA0
T 25792 @ 4347: Release script clip: 0000017B53F16EA0
T 25792 @ 4375: Add compatible formats: input P016 output P016
T 25792 @ 4375: ReloadScript from auxiliary frameserver
T 25792 @ 4532: Source frame 0 is requested without the frame handler being linked
T 25792 @ 4533: Source frame 0 is requested without the frame handler being linked
T 25792 @ 5058: New script clip: 0000017B7AC11FF0
T 25792 @ 5058: Release script clip: 0000017B7AC11FF0
T 25792 @ 5087: Add compatible formats: input P216 output P216
T 25792 @ 5087: ReloadScript from auxiliary frameserver
T 25792 @ 5268: Source frame 0 is requested without the frame handler being linked
T 25792 @ 5268: Source frame 0 is requested without the frame handler being linked
T 25792 @ 5953: New script clip: 0000017B7AF17C00
T 25792 @ 5953: Release script clip: 0000017B7AF17C00
T 25792 @ 5981: Add compatible formats: input P210 output P210
T 25792 @ 5981: ReloadScript from auxiliary frameserver
T 25792 @ 6158: Source frame 0 is requested without the frame handler being linked
T 25792 @ 6159: New script clip: 0000017B790AFE20
T 25792 @ 6159: Release script clip: 0000017B790AFE20
T 25792 @ 6170: Add compatible formats: input YUY2 output YUY2
T 25792 @ 6170: Reject input format due to settings: RGB32
T 25792 @ 6170: Reject input format due to settings: RGB32
T 25792 @ 6170: Reject input format due to settings: RGB24
T 25792 @ 6170: Reject input format due to settings: RGB24
T 25792 @ 6170: ReloadScript from auxiliary frameserver
T 25792 @ 6349: Source frame 0 is requested without the frame handler being linked
T 25792 @ 6350: Source frame 0 is requested without the frame handler being linked
T 25792 @ 6759: New script clip: 0000017B79055DD0
T 25792 @ 6759: Release script clip: 0000017B79055DD0
T 25792 @ 6789: Add compatible formats: input Y416 output Y416
T 25792 @ 6789: ReloadScript from auxiliary frameserver
T 25792 @ 6950: Source frame 0 is requested without the frame handler being linked
T 25792 @ 6950: Source frame 0 is requested without the frame handler being linked
T 25792 @ 7496: New script clip: 0000017B7B34A8F0
T 25792 @ 7496: Release script clip: 0000017B7B34A8F0
T 25792 @ 7526: Add compatible formats: input Y410 output Y410
T 25792 @ 7526: ReloadScript from auxiliary frameserver
T 25792 @ 7690: Source frame 0 is requested without the frame handler being linked
T 25792 @ 8011: Source frame 0 is requested without the frame handler being linked
T 25792 @ 8020: Source frame 0 is requested without the frame handler being linked
T 25792 @ 8036: Source frame 1 is requested without the frame handler being linked
T 25792 @ 8075: Source frame 2 is requested without the frame handler being linked
T 25792 @ 8566: Source frame 3 is requested without the frame handler being linked
T 25792 @ 8592: Source frame 0 is requested without the frame handler being linked
T 25792 @ 8597: Source frame 2 is requested without the frame handler being linked
T 25792 @ 8783: Source frame 4 is requested without the frame handler being linked
T 25792 @ 9481: New script clip: 0000017B4B3505A0
T 25792 @ 9481: Release script clip: 0000017B4B3505A0
T 25792 @ 9539: Add compatible formats: input YV24 output YV24
T 25792 @ 9539: Pre pin connection CheckInputType(): input NV12 result 1
T 25792 @ 9618: GetMediaType() offers media type 0 with NV12
T 25792 @ 9618: GetMediaType() offers media type 1 with YV12
T 25792 @ 9618: GetMediaType() offers media type 2 with I420
T 25792 @ 9618: GetMediaType() offers media type 3 with IYUV
T 25792 @ 9618: GetMediaType() offers media type 4 with P010
T 25792 @ 9618: GetMediaType() offers media type 5 with P016
T 25792 @ 9618: GetMediaType() offers media type 6 with P216
T 25792 @ 9618: GetMediaType() offers media type 7 with P210
T 25792 @ 9618: GetMediaType() offers media type 8 with YUY2
T 25792 @ 9618: GetMediaType() offers media type 9 with Y416
T 25792 @ 9618: GetMediaType() offers media type 10 with Y410
T 25792 @ 9618: GetMediaType() offers media type 11 with YV24
T 25792 @ 9762: GetMediaType() offers media type 0 with NV12
T 25792 @ 9770: Pins are connected with media types: NV12 -> NV12
T 25792 @ 9770: Pin connections are settled
T 25792 @ 9770: Filter in graph: LAV Splitter Source (internal)
T 25792 @ 9770: Filter in graph: LAV Video Decoder (internal)
T 25792 @ 9770: Filter in graph: AviSynth Filter
T 25792 @ 9770: Filter in graph: madVR
T 25792 @ 9770: GetMediaType() offers media type 0 with NV12
T 27128 @ 9770: Start worker thread
T 25792 @ 10268: ReloadScript from auxiliary frameserver
T 25792 @ 10450: Source frame 0 is requested without the frame handler being linked
T 25792 @ 10830: Source frame 0 is requested without the frame handler being linked
T 25792 @ 10835: Source frame 0 is requested without the frame handler being linked
T 25792 @ 10843: Source frame 1 is requested without the frame handler being linked
T 25792 @ 10865: Source frame 2 is requested without the frame handler being linked
T 25792 @ 11118: Source frame 3 is requested without the frame handler being linked
T 25792 @ 11135: Source frame 0 is requested without the frame handler being linked
T 25792 @ 11138: Source frame 2 is requested without the frame handler being linked
T 25792 @ 11242: Source frame 4 is requested without the frame handler being linked
T 25792 @ 11681: New script clip: 0000017B56453140
T 25792 @ 11681: Release script clip: 0000017B56453140
T 18456 @ 11761: Stored source frame: 0 at 0 ~ 400000 duration(literal) 400000 max_requested 0 extra_buffer 0
T 18456 @ 11762: Stored source frame: 1 at 400000 ~ 800000 duration(literal) 400000 max_requested 0 extra_buffer 0
T 18456 @ 11764: Stored source frame: 2 at 800000 ~ 1200000 duration(literal) 400000 max_requested 0 extra_buffer 0
T 18456 @ 11764: ReloadScript from main frameserver
T 18456 @ 11940: Get source frame: frameNb 0 input queue size 3
T 18456 @ 11940: Return source frame 0
T 18456 @ 12350: Get source frame: frameNb 0 input queue size 3
T 18456 @ 12351: Return source frame 0
T 18456 @ 12355: Get source frame: frameNb 0 input queue size 3
T 18456 @ 12355: Return source frame 0
T 18456 @ 12363: Get source frame: frameNb 1 input queue size 3
T 18456 @ 12363: Return source frame 1
T 18456 @ 12387: Get source frame: frameNb 2 input queue size 3
T 18456 @ 12387: Return source frame 2
T 18456 @ 12658: Get source frame: frameNb 3 input queue size 3
Looks like 5 frames were requested. Since I can't test every single use case out there, I can either make the number really big, like 20, hoping nothing requests that much, or make it configurable.
I'm fine with either option, but making it configurable looks more versatile and flexible.
I would recommend making it configurable to make diagnosing of possible future issues easier; also would recommend defaulting to '5' for now and then if later someone reports a problem with a reasonably common filter requesting (for example) 7 frames, i think that should become new default (and so on).
I can make it configurable. But know that the trade off is that bigger pre-buffer equals longer seek time, meaning your player will only start to update after receiving all the pre-buffer frames. I certainly don't want to impose the (possibly unnecessary) 2-frame delay to EVERY user just because some of you use TemporalDegrain2(degrainTR=2).
UPDATE: Test build: https://github.com/CrendKing/avisynth_filter/actions/runs/2305758529 Wiki update: https://github.com/CrendKing/avisynth_filter/wiki/Configuration
I ran some quick tests on my over 15 years old hardware and the difference in seek times between InitialSrcBuffer of 2 & 128 is less than a second with FullHD footage being fed through SVPflow, leading to an average delay of <8ms/frame at most. My guess is that since the actual processing steps take so much longer than pre-buffering, there isn't going to be an observable difference while using sane values; not that i mind the current defaults.
Thanks for the new option, now temporal filters like TemporalDegrain2 or BM3D work much better!
actual processing steps take so much longer than pre-buffering
I'm not sure what you mean here. Pre-buffer is nothing special. It is the same processing, just with all the processed frames withheld without being showed. The delay is heavily influenced with the content of the script. I ran 128 with a VPSF mvtools script (which is less efficient than SVP) on a large 4:4:4 video, and it hangs for 10 seconds and almost killed my system because of the spike of memory usage. I still think responsiveness is important, because one of the original key factors I hate ffdshow about is its long seek delay.
I'm not sure what you mean here. Pre-buffer is nothing special. It is the same processing, just with all the processed frames withheld without being showed.
Ok, due to the naming i thought this buffer was withholding frames in between Source Filter and AviSynth, rather than AviSynth and Video Renderer.
The delay is heavily influenced with the content of the script. I ran 128 with a VPSF mvtools script (which is less efficient than SVP) on a large 4:4:4 video, and it hangs for 10 seconds and almost killed my system because of the spike of memory usage.
I guess the main bottle-neck then is host system's memory bandwidth... While some filters regulate buffer by size instead of frame count, i think that in this case that approach would only add unnecessary overhead as this buffer is only a workaround for technical problems in the first place.
Cache size of 128 was just for calculating a more reliable average; in real world i wouldn't recommend using a value higher than used renderer's buffer size (usually within 5-16 range); from what i've read, most implementations of EVR default to buffer size of 5 (...7 in PP's Custom Presenter), while MadVR can default to various values depending on the rendering mode used.
I still think responsiveness is important, because one of the original key factors I hate ffdshow about is its long seek delay.
I fully agree that responsiveness is important and that the value should be kept minimal; what i'm trying to figure out is whether there is a perfect balance between reliability and performance, as well as where that would be.
For example, most people who encounter stuttering issues when loading a new video or seeking, solve it by slightly increasing their renderer's buffer size, so after recalling these comments 1 & 2, i started wondering if the same phenomena was at play with AVSF.....
While testing this buffer i did notice some weak correlations with specific clips on EVR, but am still having trouble creating a minimal set of conditions for reliably replicating the issue to then tune InitialSrcBuffer for getting around it, likely due to my PC not being suitable for 4K+ playback where this problem would be more readily observable. All i can say with reasonable certainty is that increasing InitialSrcBuffer, appears to reduce the likelyhood of stutters occurring, at least up to used renderer's configured buffer size.
The way i see it, any value that avoids most usability and compatibility problems that people are likely to encounter while still minimizing overhead would be a good default to use. Whether that is something that can be to some extent optimized universally or has to be manually configured for each system, i'm not really sure.
Environment
v1.3.1 # fa809c3
v3.7.0
,v3.7.1_20211103_test23
,v3.7.1_20211104_test24
,v3.7.1_20211105_test25
,v3.7.1
,v3.7.2
Windows 10 x64
MPC-BE x64 v1.6.1
madVR
,EVR-CP
Describe the bug
AVSF with Avisynth+ released earlier than November 3, 2021, the player works fine. AVSF with Avisynth+ released later than November 5, 2021, the player does not respond. However, SVP's scripts using these two functions, the player has no playback problems.