Log in

View Full Version : DirectShow filter as Avisynth source (other than ffdshow)?


Pages : [1] 2

CrendKing
25th February 2020, 03:50
I might be asking a dumb question since I'm very new to Avisynth world. I'm trying to use Avisynth to load some frame manipulation script in MPC-HC / MPC-BE, which allows me to add subtitle or change FPS. I'd done a lot of searches, but AFAIK ffdshow is the only DirectShow filter that can provide the video being played as an Avisynth clip (ffdshow_source), am I correct? One alternative is Daum PotPlayer, which basically has the ffdshow's Avisynth (AND VapourSynth, good job!) built in. Unfortunately it is closed source. All other Avisynth source filters requires a filename as parameter.

I'm asking because ffdshow has stopped development for years, and VapourSynth is not supported (by briefly looking at it (https://forum.doom9.org/showthread.php?p=1697685#post1697685)).

-----

Update: wrote my own filter at https://github.com/CrendKing/avisynth_filter. See this post (https://forum.doom9.org/showthread.php?p=1903403#post1903403).

Asmodian
25th February 2020, 16:11
What is wrong with using a filename?

PotPlayer is closed source while also using open source code... :devil:

CrendKing
25th February 2020, 18:26
Well, it is a tad more inconvenient to have to edit a text file every time watching a video than just double clicking or passing an argument to the executable from a batch. Well, technically I would write a simpler filter that automatically generate an avs script and feed to the player, but I just feel so dumb if I have to do that. It does not feel right.

I'm experimenting on implementing just the Avisynth loading logic from ffdshow on a filter. It seems pretty straight forward. If nobody has ever done this before, I guess there must be a good reason.

That's also why I refuse to use PotPlayer.

hello_hello
1st March 2020, 07:07
You can install just the ffdshow raw video filter and audio processor, At least the custom installer options suggest you can. I've never installed them without the rest of ffdshow, but it's worth a look. They can be added to MPC-HC as external filters.

To configure them, you can double click on each in MPC-HC's external filters section.

Or.... someone told me how to create shortcuts for opening the configurations as it's more convenient. They work on XP.

C:\WINDOWS\system32\rundll32.exe "C:\Program Files\ffdshow\ffdshow.ax",configureRaw

C:\WINDOWS\system32\rundll32.exe "C:\Program Files\ffdshow\ffdshow.ax",configureAudioRaw

Does ffdshow's Avisynth filter allow you to change the frame rate? I'm reasonably sure frame rate stuff in a script is ignored. Probably because it could mess with the audio sync.I tried AssumeFPS(50) in ffdshow but it had no effect.

CrendKing
9th March 2020, 21:06
Anyways, I wrote a filter to replace ffdshow. The project is at https://github.com/CrendKing/avisynth_filter . Comparing to ffdshow, I put NV12, P010 and P016 into support since they are more popular 4:2:0 formats than YV12. I've never seen 4:2:2 or 4:4:4 video, so I did not put effort into writing those transform code, yet.

I understand AviSynth has large amount of internal functions and plugins, 99% of which I have no idea what they do. I just tested against my own use cases and some simple internal functions. I've been running it for like a week without major problem.

If you are interested, feel free to give it a try, or fork it. Just remember, if you ever publish your own version, release it under GPL (since AviSynth is under GPL). Don't be another PotPlayer.

I've briefly studied VapourSynth C API. It largely resembles AviSynth+'s API. So with a few changes, I should be able to migrate the logic to VapourSynth.

CrendKing
9th March 2020, 21:14
Does ffdshow's Avisynth filter allow you to change the frame rate? I'm reasonably sure frame rate stuff in a script is ignored. Probably because it could mess with the audio sync.I tried AssumeFPS(50) in ffdshow but it had no effect.

Just tested it for you. You seems to be correct. With ffdshow, even though a following Info() shows the FPS of the clip is indeed changed, the play rate remains the same.

Well, my filter does not have this problem. If you put AssumeFPS(50) on a 25fps video, every other frame will be a duplicate frame. If you put AssumeFPS(15) on a 30fps video, every other frame will be skipped. Maybe you could give it a try.

Milardo
10th March 2020, 02:57
Hi, i just tested your filter. Not sure if there is a problem with my system, but the audio is not in sync with video. Tried this with mpc-hc. Used something simple like ChangeFPS(23.976)

I did see that the player rate changed in mpc-hc.

By the way, as far as i know in ffdshow avisynth filters changing frame rate do work like the ChangeFPS() for example. But the buffer back/ahead sometimes have to be adjusted sometimes for it to work. However ffdshow reports in the info section the source's original frame rate. however whatever player i might be using reports the changed frame rate.

Also is there a buffer back/ahead option in your filter? Like the one in ffdshow or is this even needed? Does the filter work with capture cards as a source? It just crashed with an error when i tried that.

CrendKing
10th March 2020, 20:03
I tried AssumeFPS, ChangeFPS and ConvertFPS in MPC-HC. Did not see audio sync problem. I did mess up with the x64 release though (it had a wrong old version). I reuploaded the archive.

-------------

About ffdshow's buffer option. According to their wiki (http://ffdshow-tryout.sourceforge.net/wiki/video:avisynth#buffer_back_ahead), it is used to allow filters to access a configurable range of frame within the current position. I implemented a similar buffer in the filter. Here's the detail.

In DirectShow, the upstream filters usually process a few frames ahead of time (like prefetch), and send them down to the renderer with a "render timestamp". The renderer (e.g. madVR) caches whatever it receives and presents them when the time comes. The heavier the system is under load, the shorter the prefetch becomes (could even lag behind, where it starts to drop frames). This filter just saves all frames between the tip of the prefetch and the current play timestamp. Once a frame is "out of sight", it is discarded from buffer. Like ffdshow, if any frame is requested outside of the buffer range, the nearest one is returned.

Whenever a seeking happens, I just flush the buffer to avoid the "ghost frame" problem I had with ffdshow.

Because this mechanism totally relies on the upstream (or more specifically splitter), I do not provide any option for it. If anyone finds a use case where "out of sight" frames are needed, I could provide option to save those extra frames.

-------------

About the crash, first please try the current archive. If it still crashes, I need more information (e.g. frame rate, color format, duration, etc). I can upload a debug version if you'd like to help, because I do not have a capture card.

Milardo
11th March 2020, 02:45
It must be my computer that's having issues, tried a different pc and there was no audio sync problem.

However mpc-hc crashed again as soon as i tried to use a capture card.

I uploaded a screenshot of the error message. Let me know if you need more info and i would be glad to test a debug version thanks in advance.

Frame rate is at 29.97 original, YUY2 color format.

CrendKing
12th March 2020, 04:37
I did not have YUY2 video, so I did not implement that as input format. But if you use LAV Filters, they should convert it into some 4:2:0 format such as NV12. Should not be a crash. Unless something else is in the filter graph?

The attachment is still pending, so I can't tell for sure.

If there is not private in the video, I wonder if you could send me a sample for test?

Milardo
12th March 2020, 05:25
Actually the YUY2 format is the capture card itself-raw video.

That's where i get the crash and error message.

CrendKing
1st May 2020, 10:18
I've worked with Milardo to hunt down bugs and bring improvements. I released version 0.3 (https://github.com/CrendKing/avisynth_filter/releases/tag/0.3) a while ago and haven't found any problem with it. If you are interested in using AviSynth in a video player with DirectShow support (e.g. MPC-HC/BE), please give it a try.

Sparktank
6th June 2020, 06:06
Would this work in something like SVP?
Say, I threw in a hi10p encode to interpolate. This would accept P010 without reducing the quality in the flow chain to allow it to be interpolated, as if it were using FFDShow?

SVP requires FFDShow and its limited support of formats.

I can use the Vapoursynth port to get it to play back 10bit with SVP's modified MPV player.
But, say, I want to use MPC-HC (madvr, et al) instead. Without having to reduce to 8bits.
Would this be the tool for me?

CrendKing
9th June 2020, 16:04
My filter is pretty much a replacement of ffdshow (regarding the AviSynth part). So if there is anything ffdshow can but my filter can't do, let me know.

More specifically, the filter should work with SVP. Also individually the filter supports P010 format. However, I remember SVP only works on YV12 input, so you need to either put something like ConvertBits(8) in your script to convert that 10 bit video to 8 bit, or simply uncheck P010 in the setting page (in this case, LAV Video Decoder will do the conversion, which could be more efficient).

Here is a simple script to use SVP (doubling framerate):


AvsFilterSource()

LoadPlugin("plugins\SysInfo\SysInfo64.dll")
LoadPlugin("plugins\SVPflow\windows\x64\svpflow1.dll")
LoadPlugin("plugins\SVPflow\windows\x64\svpflow2.dll")

super = SVSuper("{gpu: 1}")
vectors = SVAnalyse(super, "{}")
SVSmoothFps(super, vectors, "{rate: {num: 2"}}", mt=SI_LogicalCores())

Prefetch(SI_LogicalCores())

StainlessS
9th June 2020, 16:49
Prefetch(SI_LogicalCores())
It is my understanding that Prefetch(SI_PhysicalCores()) would be favourite.

Groucho2004
9th June 2020, 17:10
It is my understanding that Prefetch(SI_PhysicalCores()) would be favourite.Is it? Why?

StainlessS
9th June 2020, 17:17
Well I cant test, (I dont have hyperthreading), just 4 physical. [but for me Prefetch(4) or 3 or 2 near same when encoding, I now use 4, just recently started using Prefetch].
But has been suggested as best by Atak_Snajpera (I think) and others as performant, especially when also encoding, encode needs some CPU too.

Groucho2004
9th June 2020, 17:20
Well I cant test, (I dont have hyperthreading), just 4 physical.
But has been suggested as best by Atak_Snajpera (I think) and others as performant, especially when also encoding, encode need some CPU too.I see. I suppose that makes sense. :)

manolito
9th June 2020, 23:01
The following follows a recommendation from Myrsloik a while ago:
Prefetch(Min(Int(Value(GetSystemEnv("NUMBER_OF_PROCESSORS"))),8))

It basically uses the physical + virtual cores, but with a ceiling of 8.
For my CORE i5 (two physical cores plus HyperThreading) this means a prefetch value of 4, and this really works best for me - I did make extensive speed and stability tests.

Sparktank
10th June 2020, 02:25
I remember SVP only works on YV12 input

It works with YV12 because it depends on FFDShow which only has YV12. They'd use something else if it was available.

I'll let them know you made this and show this to them.

I'd rather not depend on MPV for 10bit SVP.
I'm looking for fidelity in the workflow and still keep MadVR.

CrendKing
10th June 2020, 07:46
It is my understanding that Prefetch(SI_PhysicalCores()) would be favourite.

According to https://superuser.com/a/740616/495087, hyperthreading provides 20%-40% improvement over physical cores, so yeah, using SI_LogicalCores() is a bit too optimistic. However, it would be nice if someone can do a benchmark on AviSynth use case specifically though. Who knows if HT is extremely beneficial here and making Prefetch(SI_LogicalCores()) the optimal choice.

It works with YV12 because it depends on FFDShow which only has YV12. They'd use something else if it was available.

I didn't know, because when I tried to load SVP I get error like in attachment. It makes sense because mvtools2 can operate on 10-bit content, and SVP is based on mvtools. Why does SVP self-restrict itself? If I'm the SVP developer, I wouldn't assume the only thing that can load my filter is something that has ceased development years ago. I have faith in humanity :)

StainlessS
10th June 2020, 11:40
Prefetch(Min(Int(Value(GetSystemEnv("NUMBER_OF_PROCESSORS"))),8))

Above GetSystemEnv("NUMBER_OF_PROCESSORS") can be used on XP for logical processor count [W2K unklnown],
and is same as Groucho2004 SystemInfo SI_LogicalCores().
There is no equivalent in system environment (at least on XP/W7) for physical processor count but SystemInfo SI_PhysicalCoress() does that.

[Just for anyone not aware of G2K4 SystemInfo plug, and to save people looking in system environment for something that dont exist]

Groucho2004
10th June 2020, 12:36
There is no equivalent in system environment (at least on XP/W7) for physical processor count but SystemInfo SI_PhysicalCoress() does that.The physical processor count is actually "SI_NumberOfCPUs()". The physical core count (number of CPUs * Physical cores/CPU) is "SI_PhysicalCores()".

StainlessS
10th June 2020, 14:14
Oops, thats what I mean't.

Boulder
10th June 2020, 15:59
According to https://superuser.com/a/740616/495087, hyperthreading provides 20%-40% improvement over physical cores, so yeah, using SI_LogicalCores() is a bit too optimistic. However, it would be nice if someone can do a benchmark on AviSynth use case specifically though. Who knows if HT is extremely beneficial here and making Prefetch(SI_LogicalCores()) the optimal choice.


I did some tests quite recently with Avs+ v3.6 on my 3900X which has 12 cores and 24 threads. The script is my basic process:
1) Source decoding with DGSource
2) Motion-compensated denoising (some preprocessing + MAnalyse + MRecalculate n times depending on the source resolution + MDegrain)
3) Converting to RGB in linear light (32bit float precision), downscaling, converting back to YV12 in high bitdepth
4) Debanding with neo_f3kdb

Then encoded with x265 at Main10 profile, --preset slower and slight tweaks. These were the results:

threads=24, frames default 2.53 fps
threads=24, frames 12 2.57 fps
threads=24, frames 24 2.51 fps
threads=24, frames 8 2.56 fps
threads=24, frames 10 2.57 fps
threads=24, frames 16 2.55 fps
threads=22, frames 16 2.55 fps
threads=20, frames 12 2.58 fps
threads=16, frames 12 2.57 fps
threads=12, frames 12 2.55 fps

So not so much of a difference, the number of prefetched frames played a bigger part. I'm now using threads=24, frames=12 as my default settings.

Groucho2004
10th June 2020, 19:12
Then encoded with x265 at Main10 profile, --preset slower and slight tweaks. These were the results:

threads=24, frames default 2.53 fps
threads=24, frames 12 2.57 fps
threads=24, frames 24 2.51 fps
threads=24, frames 8 2.56 fps
threads=24, frames 10 2.57 fps
threads=24, frames 16 2.55 fps
threads=22, frames 16 2.55 fps
threads=20, frames 12 2.58 fps
threads=16, frames 12 2.57 fps
threads=12, frames 12 2.55 fps

So not so much of a difference, the number of prefetched frames played a bigger part. I'm now using threads=24, frames=12 as my default settings.
It looks like the encoder is the main bottleneck in this case. Can you run just the script with AVSMeter and the same parameters?

Boulder
11th June 2020, 06:01
Here are some test results (threads, frames, fps, cpu%)

24, 48 - 13.94 / 80,8%
24, 28 - 15.82 / 82,9%
24, 24 - 15.97 / 82,7%
24, 20 - 15.42 / 69,9%
24, 16 - 14.41 / 56,0%
24, 12 - 13.08 / 43,9%
20, 40 - 12.75 / 66,1%
20, 24 - 15.46 / 70,7%
20, 20 - 15.34 / 69,9%
18, 22 - 15.22 / 63,8%
16, 20 - 14.72 / 56,4%

I've noticed that a high prefetched frames amount causes occasional stalls in the process, maybe the GPU decoder gets overwhelmed there. I have a 1050Ti GTX which is not the fastest card around.

Groucho2004
11th June 2020, 07:57
Here are some test results (threads, frames, fps, cpu%)

24, 48 - 13.94 / 80,8%
24, 28 - 15.82 / 82,9%
24, 24 - 15.97 / 82,7%
24, 20 - 15.42 / 69,9%
24, 16 - 14.41 / 56,0%
24, 12 - 13.08 / 43,9%
20, 40 - 12.75 / 66,1%
20, 24 - 15.46 / 70,7%
20, 20 - 15.34 / 69,9%
18, 22 - 15.22 / 63,8%
16, 20 - 14.72 / 56,4%

I've noticed that a high prefetched frames amount causes occasional stalls in the process, maybe the GPU decoder gets overwhelmed there. I have a 1050Ti GTX which is not the fastest card around.Oddly similar results, it looks as if your CPU is already saturated at 16 threads. Do you have avstp.dll in your plugin directory? Also, can you post your complete script?

Boulder
11th June 2020, 09:07
Oddly similar results, it looks as if your CPU is already saturated at 16 threads. Do you have avstp.dll in your plugin directory? Also, can you post your complete script?

In my opinion, 20 and 24 threads are quite close to each other which is probably due to the logical cores making the mark there. The big difference comes from the amount of prefetched frames -- I don't know if the script "startup" time is what skews the results a bit. In this test, I had 2000 frames output to compensate.

I don't have avstp.dll and all the internal multithreading settings in filters are disabled. I can post the script, but my internal functions are messy :D

Groucho2004
11th June 2020, 09:13
I can post the script, but my internal functions are messy :DNever mind, I only have 4 cores (no HT) so I can't really test under similar conditions.

CrendKing
9th July 2020, 21:13
Came across a post about physical cores vs logical cores: https://medium.com/data-design/destroying-the-myth-of-number-of-threads-number-of-physical-cores-762ad3919880 . According to the result, on average scaling the number of threads to the logical core number is the best. Of course, actual performance is dependent on specific workload and the program's ability to scale.

chainik_svp
6th August 2020, 11:00
Any chance adding a remote control to make this filter usable as a ffdshow replacement for SVP?

> If I'm the SVP developer, I wouldn't assume the only thing that can load my filter is something that has ceased development years ago. I have faith in humanity

- it is a good thing as we don't have to test every new build of ffdshow if it breaks something (which is the common case for open-source projects :D). It just works.
- we always have Vapoursynth/mpv as a backup ;)

BTW, what about passing HDR meta-data between LAV and madVR? is it possible?

----
Doesn't work correctly when the frame size is changed by the script (resize / crop). The frame size in the video player remains the same.

butterw2
6th August 2020, 13:29
@CrendKing
I'm currently looking at Avisynth+ to play video files with .avs processing. cpu usage is bit high but it can still be useful in some cases. It's simple enough, but you need a video file path in the avs file and you need a source plugin to load the video/audio.

My understanding is that your DS filter takes the frame at the video player input and allows you to process it with a specified external avs script.
Can you provide a .ax x64 build for trying it out ?

CrendKing
9th August 2020, 05:57
Any chance adding a remote control to make this filter usable as a ffdshow replacement for SVP?

> If I'm the SVP developer, I wouldn't assume the only thing that can load my filter is something that has ceased development years ago. I have faith in humanity

- it is a good thing as we don't have to test every new build of ffdshow if it breaks something (which is the common case for open-source projects :D). It just works.
- we always have Vapoursynth/mpv as a backup ;)

BTW, what about passing HDR meta-data between LAV and madVR? is it possible?

----
Doesn't work correctly when the frame size is changed by the script (resize / crop). The frame size in the video player remains the same.


I'm not sure what kind of remote control you need/ffdshow provides. Is it like API to change the script file path or reload script? Just FYI, the .avs file path is stored in registry, so you can change it and next time it will load that file. However, currently there is no way to instantly reload that file when there is playback in process (other than go into the settings page and click the button). It is easy to add some form of trigger for that, but I need to know what kind of trigger you need. For example, some Windows message? IPC? Named event?
Again FYI, as I mentioned very early in this thread, I'm working on a VapourSynth version of the filter, so you can load VS scripts into any DirectShow player. Currently the basic frame processing is working, but I need to figure out how to flush cache and fixup environment for seeking to work.
As you mention, this is a WIP, so expect bugs (and fixes).


@CrendKing
I'm currently looking at Avisynth+ to play video files with .avs processing. cpu usage is bit high but it can still be useful in some cases. It's simple enough, but you need a video file path in the avs file and you need a source plugin to load the video/audio.

My understanding is that your DS filter takes the frame at the video player input and allows you to process it with a specified external avs script.
Can you provide a .ax x64 build for trying it out ?

You can go to https://github.com/CrendKing/avisynth_filter. Download and instructions are all there.

chainik_svp
9th August 2020, 10:49
> Is it like API to change the script file path or reload script?

- set script path
- turn processing on / off
- get various info: media path, basic media info (frame size, frame rate, color format), real-time source frame rate, playback state (playing / paused)

> For example, some Windows message? IPC? Named event?

Doesn't matter, which way is simplest... ffdshow and PotPlayer work via windows messages, mpv and VLC via named pipes. IMO Windows messages are much easier to implement.

butterw2
9th August 2020, 20:58
@CrendKing
I'm currently looking at Avisynth+ to play video files with .avs processing. cpu usage is bit high but it can still be useful in some cases. It's simple enough, but you need a video file path in the avs file and you need a source plugin to load the video/audio.

My understanding is that your DS filter takes the frame at the video player input and allows you to process it with a specified external avs script.
Can you provide a .ax x64 build for trying it out ?

https://github.com/CrendKing/avisynth_filter/releases

You need to run install.bat as Admin.

For me: Works good for mp4/x264.
Some sluggishness with larger mkv after seeking.
tested on win10 with mpc-hc + evr-cp

limitation: the avs receives the frame from Lav Video Decoder. It cannot resize the frame displayed by the player.

If there is syntax error in the script, it displays the error msg (instead of just: "cannot render the frame").

CrendKing
10th August 2020, 02:08
> Is it like API to change the script file path or reload script?

- set script path
- turn processing on / off
- get various info: media path, basic media info (frame size, frame rate, color format), real-time source frame rate, playback state (playing / paused)


The first two are doable. The third one, are you talking about something like image below? It does not sound to me specific to the avs filter. For example, media path is something only a source filter can provide, rather than a transformation filter. Other media info could change between filters. Do you need pre-transform info or post-transform or both? Should we isolate into a separate filter (like the ol' deprecated ISampleGrabber)?

Also, for HDR passthrough, I need to read about it. Never done anything like that before.

https://i.imgur.com/NALncgn.jpg

https://github.com/CrendKing/avisynth_filter/releases

You need to run install.bat as Admin.

For me: Works good for mp4/x264.
Some sluggishness with larger mkv after seeking.
tested on win10 with mpc-hc + evr-cp

limitation: the avs receives the frame from Lav Video Decoder. It cannot resize the frame displayed by the player.

If there is syntax error in the script, it displays the error msg (instead of just: "cannot render the frame").

> Some sluggishness with larger mkv after seeking.

It is because after each seeking, the filter has to recreate the whole AviSynth environment just to flush stale cache. DirectShow requires filters to flush cache after seeking, and there is no API from AviSynth to do so. AviSynth is not designed to handle "seeking", but rather process the whole source in streamline fashion. I have an issue at https://github.com/AviSynth/AviSynthPlus/issues/180, but I doubt the dev would care to cater for a non-intended use case.

I could disable the cache flushing logic, but then you will get some ghost frames every time you seek.

> It cannot resize the frame displayed by the player.

You are correct. I have not implemented video dimension change from avs script. I believe it is doable.

> If there is syntax error in the script, it displays the error msg

Is this bad or you are saying it should be like this?

butterw2
10th August 2020, 09:20
> It cannot resize the frame displayed by the player.

You are correct. I have not implemented video dimension change from avs script. I believe it is doable.

It would be a nice feature to have (use fullscreen black bars space, resizers)


> If there is syntax error in the script, it displays the error msg

Is this bad or you are saying it should be like this?

It very much is a good thing.

Mpc-hc/be gives you no info about the problem when you open .avs with a syntax error.

chainik_svp
10th August 2020, 11:29
> are you talking about something like image below?

Yep

> It does not sound to me specific to the avs filter. For example, media path is something only a source filter can provide, rather than a transformation filter.

And yet SVP need to know these values somehow, and ffdshow transform filter is able to provide them

> Do you need pre-transform info or post-transform or both?

Pre-transform only

> Should we isolate into a separate filter (like the ol' deprecated ISampleGrabber)?

I don't think so...

> I have not implemented video dimension change from avs script.

BTW there's another side of this - _source_ frame size may change in runtime too. As an example - BD3D playback in MPC-BE.

clsid
10th August 2020, 13:49
You can get filename yourself.

Enumerate filters in the graph, until you find first one that implements IFileSourceFilter interface. Then use that to query filename.

https://docs.microsoft.com/en-us/windows/win32/api/strmif/nn-strmif-ifilesourcefilter

CrendKing
13th August 2020, 07:53
It would be a nice feature to have (use fullscreen black bars space, resizers)

It very much is a good thing.

Mpc-hc/be gives you no info about the problem when you open .avs with a syntax error.

Just added the support for size change. https://github.com/CrendKing/avisynth_filter/releases/tag/0.5.2.

In order to correctly recognize the size change, you need to put the new AvsFilterSizeChanged() in the script. Please read the Readme and check the example. Let me know if there's problem.

chainik_svp
13th August 2020, 11:00
> AvsFilterSizeChanged()

why? o_O can you imagine the situation when you should ignore the output clip dimensions?

CrendKing
13th August 2020, 11:34
Just added the support for size change. https://github.com/CrendKing/avisynth_filter/releases/tag/0.5.2.

In order to correctly recognize the size change, you need to put the new AvsFilterSizeChanged() in the script. Please read the Readme and check the example. Let me know if there's problem.

Just made an automatic size change detection, so no need for AvsFilterSizeChanged(). Try https://github.com/CrendKing/avisynth_filter/releases/tag/0.5.3.

> AvsFilterSizeChanged()

why? o_O can you imagine the situation when you should ignore the output clip dimensions?

There are two sources of size change, one from the avs script, and one from DirectShow upstream. If I don't make it unambiguous, the filter wouldn't know which size to use for the output pin if both sources are changing.

In the filter, there are two phases that output pin type could change. One is during type negotiation. The other is during transform. For type negotiation, the filter used to simply copy the input dimension to generate the output type. For the dynamic type change during transform, it was also copied.

In 0.5.2, AvsFilterSizeChanged() determines if upstream input or avs output dimension is used for both phases.

In 0.5.3, the filter detects if the upstream input dimension equals the avs output dimension in negotiation phase. If changed, it will use avs output dimension from then on. If not, it will use upstream input dimension from then on (which means if the dynamic change happens during transform, it will correctly update).

Note the detection does not happen in transform phase. So it is not supported to load a non-size-changing script at beginning, change the script to size changing then click the "Reload" button and expect the whole player window change. It is probably possible with some dynamic renegotiation logic, but I feel overengineering to support such a rare case.

chainik_svp
13th August 2020, 11:55
> if the dynamic change happens during transform, it will correctly update

in my understanding:
1. the filter must always use AVS output clip dimensions
2. "if the dynamic change happens during transform" the filter MUST reload AVS script and update the output dimensions according to the updated AVS output clip

in any case the situation when filter's output dimension is different from AVS output dimension is _wrong_

CrendKing
13th August 2020, 13:59
> if the dynamic change happens during transform, it will correctly update

in my understanding:
1. the filter must always use AVS output clip dimensions
2. "if the dynamic change happens during transform" the filter MUST reload AVS script and update the output dimensions according to the updated AVS output clip

in any case the situation when filter's output dimension is different from AVS output dimension is _wrong_

You are correct. FYI, currently the filter does reload avs if dynamic type change happens. I did not put any extra logic around that code block because I assumed most size changing logic from avs script should be unconditional towards the "upstream size changing". What I mean is, remember there is already a detection at negotiation phase. If the script replaces the clip with a ColorBars(), the changing is already picked. The output type is already guaranteed to be the same as avs from then on (thanks to the mark I mentioned). The only thing there would be an off is when the avs script would conditionally replaces the clip with ColorBars() if the input video size does not match the original size but matches the dynamically changed one.

For example, suppose I'm playing a 640x480 video. There is dynamic change during transform to 630x470. The following avs script should work correctly:


return ColorBars(320, 240, "YV12")


This script would fail with 0.5.3:

AvsFilterSource()

if (Width == 630) {
return ColorBars(320, 240, "YV12")
}
return last


Your suggestion should work in both cases, so I probably should use that instead.

Hmm, when trying the example, I noticed that the filter does not handle pixel type change either (the "YV12" is necessary). I should fix that too.

chainik_svp
13th August 2020, 14:08
> The following avs script should work correctly:

replace ColorBars() with Crop() and even the simple "return Crop(...)" will fail with the current approach
so you definitely have to reload script and re-init the output in case the input was changed

CrendKing
14th August 2020, 07:11
Can you post the full script? I tried this and seems OK:


AvsFilterSource()
return Crop(10, 20, 320, 240)


I ask because ColorBars() is a source function but Crop() is a transformation function. Simply replacing one with the other will not work.

I'm gonna rework the code anyways. Just want more test cases to verify once done. Thanks.

CrendKing
15th August 2020, 18:50
Release https://github.com/CrendKing/avisynth_filter/releases/tag/0.5.4 for better handling of the format change. Please read the note and test. Thanks.

chainik_svp
15th August 2020, 20:34
I'd also expect it to update the output format after changing the script and pressing "reload".

---
Doesn't work correctly when input format changed in runtime.

Easy (well, probably not that "easy" :D) way to reproduce: MPC-BE + any BD3D ISO + Intel's MVC decoder.
Start playback, switch modes in View -> Stereo 3D modes between "Mono" (1920*1080) and "OverUnder" (1920*2160).
mono -> overunder = crash
overunder -> mono = image distortion

CrendKing
15th August 2020, 23:36
It is expected because currently all format change is dynamic changes, as explained in https://docs.microsoft.com/en-us/windows/win32/directshow/queryaccept--downstream, you can't "drastic changes to the format, such as changing the bit depth". The downstream filter may not be able to handle the format change without completely stopping the stream and reconnect the pins with new media type. Some filters/renderers support "dynamic pin reconnection", but not all of them. My thought process was "these players already have a key bind or button for reopening the current file, which does exactly the stop-reload-play thing. Why should I repeat the whole process in a transform filter?"

If anyone has code that can make what you described work and easy to implement (in case I'm missing some obvious tricks), I'm all ears as long as their license allows me to copy of course. I just don't want to put 1000 lines of code to a piece of software that is 1500 lines in total for maybe less than 1% of usage.