Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > VapourSynth

Reply
 
Thread Tools Search this Thread Display Modes
Old 27th April 2020, 17:09   #3821  |  Link
tuanden0
Registered User
 
Join Date: Oct 2016
Posts: 111
Quote:
Originally Posted by Myrsloik View Post
R50-RC1. It's a pure bugfix release so if you use R48 or R49 you should definitely give it a try.
Code:
r50:
updated zimg to latest v2.9 so grayscale colorspace are supported
fixed crash in textfilter line wrapping introduced in r49 (sekrit-twc)
fixed regression introduced in r48 where sobel and prewitt wouldn't clamp 9-15 bit output to valid range (sekrit-twc)
fixed crash due to null pointer dereference when instantiation many vapoursynth classes directly in python
fixed regression in r49 where the python dll could only be located when in the PATH on windows
It still show R49 instead of 50
Quote:
→ C:\Users\Home› vspipe --version
VapourSynth Video Processing Library
Copyright (c) 2012-2020 Fredrik Mellbin
Core R49
API R3.6
Options: -
tuanden0 is offline   Reply With Quote
Old 1st May 2020, 19:20   #3822  |  Link
HuBandiT
Registered User
 
Join Date: Dec 2017
Posts: 12
misc.AverageFrames() silently darkens vs.RGBS clip when weights[] is longer than 31

Greetings,

I noticed that when I AverageFrames() a clip in vs.RGBS format, when weights[] is longer than the documented - but not enforced - maximum of 31, AverageFrames() darkens the result - the longer weights[] is, the more darkening.

I am on x86.

Looking at the source I see averageFramesFloatSSE2() computes the weighted sum of only 31 frames, but then - incorrectly - multiplies the result with the scale computed for the entire weights[] array.

Desired result #1 (preferred): allow arbitrary length averaging. (I hope for this, because this is the only codepath where I saw this 31 hardcoded - the others might actually allow unlimited?)

Desired result #2 (not preferred): prevent incorrect usage by giving a hard error message

Rationale: I am working on modernizing "talking head" type of instructional videos from DVD MPEG-2, with lots of static background (for minutes), where it would not be unreasonable to frame average the background areas over 5-10 seconds to attempt to average out camera photon noise distorted by MPEG-2. The source is 50i PAL, I deinterlace it to 50p, then comes the noise reduction. But 31 frames is limiting, since at 50p coming from 50i it is about 15-16 original interlaced frames, which is about the length of a single GOP so this precludes me from averaging over GOPs, also it is only about 0.6 seconds. When I diff the resulting frames, even truncated to 8 bit depth, I still have too many artifacts.

Thank you in advance. VapourSynth is awesome.

PS: For this type of filtering, I always use "weights = [1] * number", so a performance optimization could be to omit the multiplications when all the weights are equal and factor them into the scaler.

Last edited by HuBandiT; 1st May 2020 at 19:33.
HuBandiT is offline   Reply With Quote
Old 1st May 2020, 19:49   #3823  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,554
Quote:
Originally Posted by HuBandiT View Post
Greetings,

I noticed that when I AverageFrames() a clip in vs.RGBS format, when weights[] is longer than the documented - but not enforced - maximum of 31, AverageFrames() darkens the result - the longer weights[] is, the more darkening.

I am on x86.

Looking at the source I see averageFramesFloatSSE2() computes the weighted sum of only 31 frames, but then - incorrectly - multiplies the result with the scale computed for the entire weights[] array.

Desired result #1 (preferred): allow arbitrary length averaging. (I hope for this, because this is the only codepath where I saw this 31 hardcoded - the others might actually allow unlimited?)

Desired result #2 (not preferred): prevent incorrect usage by giving a hard error message

Rationale: I am working on modernizing "talking head" type of instructional videos from DVD MPEG-2, with lots of static background (for minutes), where it would not be unreasonable to frame average the background areas over 5-10 seconds to attempt to average out camera photon noise distorted by MPEG-2. The source is 50i PAL, I deinterlace it to 50p, then comes the noise reduction. But 31 frames is limiting, since at 50p coming from 50i it is about 15-16 original interlaced frames, which is about the length of a single GOP so this precludes me from averaging over GOPs, also it is only about 0.6 seconds. When I diff the resulting frames, even truncated to 8 bit depth, I still have too many artifacts.

Thank you in advance. VapourSynth is awesome.

PS: For this type of filtering, I always use "weights = [1] * number", so a performance optimization could be to omit the multiplications when all the weights are equal and factor them into the scaler.
Doh, found the typo in the weights check so please verify that it's really fixed in the next RC.

Arbitrary length averaging will never be supported because for float you'll at some point accumulate a huge rounding error or for integer formats you'll overflow.

If you need longer averaging you can simply do something like
Code:
clip.misc.AverageFrames(weights=[1]*31)[::31].misc.AverageFrames(weights=[1]*31)
The multiply is probably so fast it doesn't matter compared to all the memory access.
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 1st May 2020, 21:37   #3824  |  Link
HuBandiT
Registered User
 
Join Date: Dec 2017
Posts: 12
Quote:
Originally Posted by Myrsloik View Post
Doh, found the typo in the weights check so please verify that it's really fixed in the next RC.
Thank you, will do.

Quote:
Originally Posted by Myrsloik View Post
Arbitrary length averaging will never be supported because for float you'll at some point accumulate a huge rounding error or for integer formats you'll overflow.
Indeed, I did not actually mean "arbitrary". But maybe a higher than the current 31 frame limit then? At least for higher precision formats? Maybe set the limit based on some analysis of the numerical precision of the format chosen? 32 bit float RGBS has a 24 bit significand. Reserving two bits from those 24 for the 4.5 multiplier near the foot of rec.601/rec.709, I have about 22 bits of linear precision left. So when I target rec.709 YUV420P8, YUV420P10 or YUV420P12, I have 22-8=14, 22-10=12, 22-12=10 bits of headroom in precision before rounding errors show up in the output; it seems that even in the worst case I could use those bits to average 2^14=16384, 2^12=4096 and 2^10=1024 frames respectively? The current 31 frame limit limits me to use only 5 of those extra bits meaningfully, leaving me with 9, 7 and 5 "unusable" bits of headroom.

Quote:
Originally Posted by Myrsloik View Post
The multiply is probably so fast it doesn't matter compared to all the memory access.
The very point is reducing memory access: if all the weights are the same (and with integer formats - although it probably will also work just well enough with floats on real material), you could simply update the running average by subtracting the sample falling out the window and adding the sample newly entering the window, instead of calculating the entire sum from scratch anew each time; in fact one could just add the difference between the falling out sample and the newly entering sample, to be one small step farther away from overflow. Not frame parallelizable for sure (although it would be parallelizable spatially with frame slices), but it might still end up being a huge win for long averages because of the drastically reduced memory access from O(n) to about O(4): read from 2 source frames, read/modify/store the running average; and should the internal running average use higher precision - say double for float inputs, or 32 bit integer for 16 bit inputs, which might make sense - finally downconverting the running average into the desired output precision. Not great for simplistic benchmarks perhaps, but my hunch is that if there is any meaningfully heavy processing happening after the average, the runtime contribution of the averaging operation will be negligible compared to that. It would be nice to at least have the option.

Quote:
Originally Posted by Myrsloik View Post
If you need longer averaging you can simply do something like
Code:
clip.misc.AverageFrames(weights=[1]*31)[::31].misc.AverageFrames(weights=[1]*31)
Yes, I, too, was pondering a hierarchical approach like this. I'll have think about this, as at first sight I don't think it would give equivalent results. Plus boundary issues (scene detection).

Last edited by HuBandiT; 1st May 2020 at 22:52.
HuBandiT is offline   Reply With Quote
Old 1st May 2020, 22:33   #3825  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,554
You do have a point with most things but that's an extremely specialized filter. Feel free to write it.

In regards to the bits of headroom you kinda want a general filter to be able to support equivalent settings for all formats. It simply makes sense for the users. That's why the limit is 31 frames. At some point all the ifs and buts of a filter become too complicated.
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 1st May 2020, 23:47   #3826  |  Link
HuBandiT
Registered User
 
Join Date: Dec 2017
Posts: 12
Quote:
Originally Posted by Myrsloik View Post
You do have a point with most things but that's an extremely specialized filter. Feel free to write it.
Alright. Pointers to how to write VapourSynth filters in C++ are welcome. Also how to decide on a namespace? Can I piggyback onto an existing namespace, or do I need to pick a separate one?

Quote:
Originally Posted by Myrsloik View Post
In regards to the bits of headroom you kinda want a general filter to be able to support equivalent settings for all formats. It simply makes sense for the users. That's why the limit is 31 frames. At some point all the ifs and buts of a filter become too complicated.
I don't think this is conceptually different from, say, the limitations of the crop filters: they do have limitations based on the format: subsampled formats can only be cropped by multiples of the subsampling factors; otherwise things would get difficult - but when there is no subsampling, the limitations don't apply, so not enforced.
HuBandiT is offline   Reply With Quote
Old 2nd May 2020, 17:09   #3827  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: void
Posts: 2,633
Quote:
Originally Posted by HuBandiT View Post
Alright. Pointers to how to write VapourSynth filters in C++ are welcome. Also how to decide on a namespace? Can I piggyback onto an existing namespace, or do I need to pick a separate one?
you could take a look at vsFilterScript if ur compiler supports most of C++20 core language features, it is the easiest way to get started.

the namespace must be unique, you must define ur own namespace.
feisty2 is offline   Reply With Quote
Old 2nd May 2020, 21:59   #3828  |  Link
LoRd_MuldeR
Software Developer
 
LoRd_MuldeR's Avatar
 
Join Date: Jun 2005
Location: Last House on Slunk Street
Posts: 13,248
Quote:
Originally Posted by Myrsloik View Post
Code:
r50:
fixed regression in r49 where the python dll could only be located when in the PATH on windows
I can confirm it's fixed now. Thanks!
__________________
Go to https://standforukraine.com/ to find legitimate Ukrainian Charities 🇺🇦✊
LoRd_MuldeR is offline   Reply With Quote
Old 3rd May 2020, 03:34   #3829  |  Link
HuBandiT
Registered User
 
Join Date: Dec 2017
Posts: 12
Quote:
Originally Posted by feisty2 View Post
you could take a look at vsFilterScript if ur compiler supports most of C++20 core language features, it is the easiest way to get started.

the namespace must be unique, you must define ur own namespace.
Thank you, I started doing my own thing from scratch to practice some C++, I took a short look at yours, but I'll look more closely later. It does look very script-y though.
HuBandiT is offline   Reply With Quote
Old 3rd May 2020, 20:40   #3830  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,554
R50-RC2

Code:
r50:
updated zimg to latest v2.9 so grayscale colorspace are supported
added __version__ and __api_version__ to python module to make detecting version mismatches easier
improved rounding in averageframes (sekrit-twc)
fixed averageframes not properly rejecting more than 31 weights or nodes
fixed crash in textfilter line wrapping introduced in r49 (sekrit-twc)
fixed regression introduced in r48 where expr, sobel and prewitt wouldn't clamp 9-15 bit output to valid range (sekrit-twc)
fixed crash due to null pointer dereference when instantiation many vapoursynth classes directly in python
fixed regression in r49 where the python dll could only be located when in the PATH on windows
If someone on linux can confirm or deny this bug https://github.com/vapoursynth/vapoursynth/issues/503 it'd be helpful.
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 7th May 2020, 05:01   #3831  |  Link
l33tmeatwad
Registered User
 
l33tmeatwad's Avatar
 
Join Date: Jun 2007
Posts: 414
If I could make a recommendation, it would be nice if the Linux setup automatically detected if dist-packages exists and then use that instead of site-packages considering Debian based Linux distros and a few others use that instead of site-packages for Python. Either that or updating the current guide on the main site to recommend checking for that and creating a symbolic link to redirect files from site-packages to dist-packages would be nice considering this affects quite a few popular Linux distros, such as Ubuntu. Side note, most of the distros that have that issue also need the end user to run ldconfig or it will fail to load as well so it would be nice to include that in the documentation as well.
l33tmeatwad is offline   Reply With Quote
Old 8th May 2020, 02:21   #3832  |  Link
HuBandiT
Registered User
 
Join Date: Dec 2017
Posts: 12
Low priority question:

Is queryCompletedFrame() still "This function has several issues and may or may not return the actual node or frame number."? Even in an fmSerial filter?

If yes, how much work would be needed to fix it? (Or is there another way to query the new frame when VSFilterGetFrame() is called with arFrameReady?)
HuBandiT is offline   Reply With Quote
Old 8th May 2020, 07:22   #3833  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,554
Quote:
Originally Posted by HuBandiT View Post
Low priority question:

Is queryCompletedFrame() still "This function has several issues and may or may not return the actual node or frame number."? Even in an fmSerial filter?

If yes, how much work would be needed to fix it? (Or is there another way to query the new frame when VSFilterGetFrame() is called with arFrameReady?)
The frame number is always correct in more recent versions. It's just the node pointer you can't trust. Modes and other things have nothing to do with it and change nothing.

This much work needed to fix it:
|--------------------|
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 8th May 2020, 16:17   #3834  |  Link
Myrsloik
Professional Code Monkey
 
Myrsloik's Avatar
 
Join Date: Jun 2003
Location: Kinnarps Chair
Posts: 2,554
R50 is released. Bug fixes only so everyone should update.
Code:
r50:
updated zimg to latest v2.9 so grayscale colorspace are supported
fixed several minor issues related to path handling in vsrepo
added __version__ and __api_version__ to python module to make detecting version mismatches easier
improved rounding in averageframes (sekrit-twc)
fixed averageframes not properly rejecting more than 31 weights or nodes
fixed crash in textfilter line wrapping introduced in r49 (sekrit-twc)
fixed regression introduced in r48 where expr, sobel and prewitt wouldn't clamp 9-15 bit output to valid range (sekrit-twc)
fixed crash due to null pointer dereference when instantiation many vapoursynth classes directly in python
fixed regression in r49 where the python dll could only be located when in the PATH on windows
__________________
VapourSynth - proving that scripting languages and video processing isn't dead yet
Myrsloik is offline   Reply With Quote
Old 9th May 2020, 10:11   #3835  |  Link
Boulder
Pig on the wing
 
Boulder's Avatar
 
Join Date: Mar 2002
Location: Finland
Posts: 5,729
Thank you for the new release
__________________
And if the band you're in starts playing different tunes
I'll see you on the dark side of the Moon...
Boulder is offline   Reply With Quote
Old 12th May 2020, 00:29   #3836  |  Link
Txico
Registered User
 
Join Date: Nov 2017
Posts: 8
Hello there.
Last time I posted here was in august because I had trouble with the environment variables, python 3.7 and Ubuntu. Gladly solved.
Now Ubuntu 20.04 is out and I'm not any longer capable of compiling the sources to build.
After installing all the packages in the documentation for Linux compilation I got through the ./autogen.sh and ./configure, but now make give me this error:
CXXLD vspipe
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `Py_InitializeEx'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyDict_GetItemString'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyObject_GetAttrString'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `_Py_Dealloc'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyImport_ImportModule'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyCapsule_GetPointer'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyCapsule_IsValid'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyEval_SaveThread'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyGILState_Ensure'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `Py_IsInitialized'
collect2: error: ld returned 1 exit status
make: *** [Makefile:1318: vspipe] Error 1

At least the first error, the one with Py_InitializeEx, I get is threads related. But I don't know what I'm missing and documentation doesn't give me any clue.
Anybody? Please?
Txico is offline   Reply With Quote
Old 12th May 2020, 17:09   #3837  |  Link
jackoneill
unsigned int
 
jackoneill's Avatar
 
Join Date: Oct 2012
Location: 🇪🇺
Posts: 760
Quote:
Originally Posted by Txico View Post
Hello there.
Last time I posted here was in august because I had trouble with the environment variables, python 3.7 and Ubuntu. Gladly solved.
Now Ubuntu 20.04 is out and I'm not any longer capable of compiling the sources to build.
After installing all the packages in the documentation for Linux compilation I got through the ./autogen.sh and ./configure, but now make give me this error:
CXXLD vspipe
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `Py_InitializeEx'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyDict_GetItemString'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyObject_GetAttrString'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `_Py_Dealloc'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyImport_ImportModule'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyCapsule_GetPointer'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyCapsule_IsValid'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyEval_SaveThread'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `PyGILState_Ensure'
/usr/bin/ld: ./.libs/libvapoursynth-script.so: undefined reference to `Py_IsInitialized'
collect2: error: ld returned 1 exit status
make: *** [Makefile:1318: vspipe] Error 1

At least the first error, the one with Py_InitializeEx, I get is threads related. But I don't know what I'm missing and documentation doesn't give me any clue.
Anybody? Please?
It's because of a change in Python 3.8, but this is supposed to work now with VapourSynth R50. What version are you trying to compile?

A temporary solution is to run make again like this:
Code:
make LIBS="$(python3-config --libs --embed)"
(It has nothing to do with threads.)
__________________
Buy me a "coffee" and/or hire me to write code!
jackoneill is offline   Reply With Quote
Old 12th May 2020, 17:59   #3838  |  Link
Txico
Registered User
 
Join Date: Nov 2017
Posts: 8
Thanks a lot! That did the trick. And thanks for the quick response.
I was trying to compile the latest release R50, now it works.
I know it was nothing related to threads. It was related to standard libraries not been found, but I didn't know how to solved it.
An official documentation update could be really nice ...
Txico is offline   Reply With Quote
Old 14th May 2020, 10:11   #3839  |  Link
Txico
Registered User
 
Join Date: Nov 2017
Posts: 8
And now I'm having trouble loading plug-ins ...
I tried to set the UserPluginDir variable on compile time with "configure --with-plugindir='/home/myuser/vapoursynth-plugins'", creating a vapoursynth.conf file with "UserPluginDir=/home/myuser/vapoursynth-plugins" and setting an incorrect value for the folders or change the name folder: Autoloading the user plugin dir '/home/myuser/vapoursynth-plugins' failed. Directory doesn't exist?
So the variable is working.
So, why I'm having trouble doing something as easy as "import havsfunc as haf" when the file havsfunc.py is there?
ModuleNotFoundError: No module named 'havsfunc'

Any clue? Anything else I need to know?
Txico is offline   Reply With Quote
Old 14th May 2020, 10:44   #3840  |  Link
Are_
Registered User
 
Join Date: Jun 2012
Location: Ibiza, Spain
Posts: 321
Because .py files are not plugins but python modules. You need to place them inside your root protected site-packages directory (ore whatever is called in your distro).

If you don't want to mess with that you can create a .pth file there with the path to de directory you want to put your python modules inside. Like for example:
Code:
$ cat /usr/lib64/python3.6/site-packages/vapoursynth-autoload.pth
/home/youruser/vapoursynth-python-modules
Are_ is offline   Reply With Quote
Reply

Tags
speed, vaporware, vapoursynth

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 04:55.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.