Log in

View Full Version : vapoursynth.VideoNode object does not support item assignment


SilSinn9801
17th August 2022, 02:06
Three years ago (or maybe more), HolyWu had written some helper function for looping still images with RGB & alpha layers (https://forum.doom9.org/showthread.php?p=1873530#post1873530):
# HolyWu's helper function for looping an RGB+alpha still image
def loop_vfx(c, times):
c[0] = c[0] * times
c[1] = c[1] * times
return c

I used this code in four VapourSynth R45 projects & was now trying to use it in a R59 project when I now get these warnings & errors in VapourSynth Editor r19:

2022-08-16 20:45:59.749
setVideoInfo: Video filter Source has more than one output node but only the first one will be returned
setVideoInfo: Video filter Source has more than one output node but only the first one will be returned
2022-08-16 20:45:59.797
Failed to evaluate the script:
Python exception: 'vapoursynth.VideoNode' object does not support item assignment

Traceback (most recent call last):
File "src\cython\vapoursynth.pyx", line 2890, in vapoursynth._vpy_evaluate
File "src\cython\vapoursynth.pyx", line 2891, in vapoursynth._vpy_evaluate
File "D:\fakepath\TH09_07.VPY", line 54, in
ChanLabelLoop = loop_vfx(ChannelLabels,9156)
File "D:\fakepath\TH09_07.VPY", line 12, in loop_vfx
c[0] = c[0] * times
TypeError: 'vapoursynth.VideoNode' object does not support item assignment

2022-08-16 20:45:59.888
Core freed but 1 filter instance(s) still exist
Core freed but 1 filter instance(s) still exist

For context, this is part of the script I’m trying to run that uses HolyWu’s loop_vfx function:
import vapoursynth as vs
from vapoursynth import core
import vsutils as vsu
import havsfunc as haf
import functools
import sys
import math
vsufuncs = vsu.vsutils()

# HolyWu's helper function for looping an RGB+alpha still image
def loop_vfx(c, times):
c[0] = c[0] * times
c[1] = c[1] * times
return c

# corrscope oscilloscope video
Corrscope = core.ffms2.Source(r'E:\corrscope\TH09_07.MKV') # 60 fps, RGB
CorrscopeCrop = Corrscope[8626:17782] # total 9156 frames
# corrscope channel-label overlay (RGB+alpha)
ChannelLabels = core.ffms2.Source(r'E:\corrscope\5FM+3SSG+ADPCM+RHY.png',alpha=True)
ChanLabelLoop = loop_vfx(ChannelLabels,9156) #invoking here HolyWu’s function
ChanLabelRGB = ChanLabelLoop[0].std.AssumeFPS(fpsnum=60,fpsden=1)
ChanLabelMask = ChanLabelLoop[1].std.AssumeFPS(fpsnum=60,fpsden=1) # match frame rate to corrscope video
# Overlay channel labels onto corrscope segment
Loop2 = haf.Overlay(CorrscopeCrop,ChanLabelRGB,mask=ChanLabelMask)
Loop2.set_output()

This code above would’ve worked fine under VapourSynth R45, but under R59 it refuses to work now.

_Al_
17th August 2022, 03:14
ChannelLabels = core.ffms2.Source(r'E:\corrscope\5FM+3SSG+ADPCM+RHY.png',alpha=True)
ChanLabelLoop = loop_vfx(ChannelLabels,9156) #invoking here HolyWu’s function

loop_vfx() needs a tuple, that c variable. Looks like ffms2.Source returned a vs.VideoNode

SilSinn9801
17th August 2022, 09:13
loop_vfx() needs a tuple, that c variable. Looks like ffms2.Source returned a vs.VideoNode

OK so how do I now fix this? If ffms2.Source originally returned a two-element tuple whenever alpha=True but now returns vs.VideoNode instead, how do I now turn that VideoNode into a tuple? Or, how do I now extract the RGB & alpha masks from it to loop them like individual images?

Google-searching both FFMS2 & VideoNode terms together doesn’t give me anything meaningful.

EDIT: Even the current GitHub documentation (https://github.com/FFMS/ffms2/blob/master/doc/ffms2-vapoursynth.md) says nothing at all about Source putting out VideoNodes, it still says that an array of two clips is output with alpha=True.

SilSinn9801
17th August 2022, 10:07
setVideoInfo: Video filter Source has more than one output node but only the first one will be returned
setVideoInfo: Video filter Source has more than one output node but only the first one will be returned

This is probably key to this conundrum: it admits that Source is generating more than one output (the RGB output & the alpha output) but only the first output (RGB) is being returned to the variable ChannelLabels. Historically under R45, this ChannelLabels variable would become autodeclared a 2-element array (collecting both RGB & alpha outputs from Source) that could be indexed with [0] or [1] to get RGB or alpha, respectively. But now here under R59, the same variable is instead being forced to be declared as a single-element scalar storing only the RGB output, & the alpha is being mysteriously thrown away.

DJATOM
17th August 2022, 11:36
Alpha plane is now stored as frame property (_Alpha), use PropToClip (http://www.vapoursynth.com/doc/functions/video/proptoclip.html) for access.

SilSinn9801
18th August 2022, 08:13
Alpha plane is now stored as frame property (_Alpha), use PropToClip (http://www.vapoursynth.com/doc/functions/video/proptoclip.html) for access.

OK so I now rewrote the code as this (now discarding that obsoleted HolyWu helper function):
import vapoursynth as vs
from vapoursynth import core
import vsutils as vsu
import havsfunc as haf
import functools
import sys
import math
vsufuncs = vsu.vsutils()

# corrscope oscilloscope video (640×400p, 60 fps, FFV1, RGB)
Corrscope = core.ffms2.Source(r'E:\corrscope\TH09_07.MKV')
CorrscopeCrop = Corrscope[8626:17782] # total 9156 frames
# corrscope channel-label overlay (640×400, PNG, RGB+alpha)
ChannelLabels = core.ffms2.Source(r'E:\corrscope\5FM+3SSG+ADPCM+RHY.png',fpsnum=60,fpsden=1,alpha=True)
ChanLabelRGB = ChannelLabels.std.Loop(9156)
ChanLabelMask = ChannelLabels.std.PropToClip(prop='_Alpha').std.Loop(9156)
# Overlay channel text labels onto corrscope segment
Loop2 = haf.Overlay(CorrscopeCrop,ChanLabelRGB,mask=ChanLabelMask)
Loop2.set_output()
& now I get a different error message & still get the same warning about FFMS2.Source having two or more output nodes but only returning one:

2022-08-18 03:00:52.404
setVideoInfo: Video filter Source has more than one output node but only the first one will be returned
setVideoInfo: Video filter Source has more than one output node but only the first one will be returned
2022-08-18 03:00:52.409
Failed to evaluate the script:
Python exception: PropToClip: no frame stored in property: _Alpha

Traceback (most recent call last):
File "src\cython\vapoursynth.pyx", line 2890, in vapoursynth._vpy_evaluate
File "src\cython\vapoursynth.pyx", line 2891, in vapoursynth._vpy_evaluate
File "D:\fakepath\TH09_07.VPY", line 58, in
ChanLabelMask = ChannelLabels.std.PropToClip(prop='_Alpha').std.Loop(9156)
File "src\cython\vapoursynth.pyx", line 2636, in vapoursynth.Function.__call__
vapoursynth.Error: PropToClip: no frame stored in property: _Alpha

2022-08-18 03:00:52.430
Core freed but 1 filter instance(s) still exist
Core freed but 1 filter instance(s) still exist
Core freed but 768192 bytes still allocated in framebuffers
Core freed but 768192 bytes still allocated in framebuffers

What should I do now about this? I am now using PropToClip to get the alpha out of that transparent PNG image being read by FFMS2.Source (& I made sure the PNG –which is attached to this reply for reference– is saved in full RGB mode & not in palette-indexed mode) yet apparently the output from FFMS2.Source has no _Alpha property at all, & also for the record I am using the most recent version of FFMS2 found on its GitHub page (version 2.40 released almost two years ago).

SilSinn9801
18th August 2022, 09:11
OK so now I found this:
https://www.vapoursynth.com/2021/09/r55-audio-support-and-improved-performance/
Compatibility and breaking changes
The alpha handling has changed and attaching the alpha as an additional frame is now the preferred method.

What this means in practice is that 99% of all plugins works properly. The only known ones that don’t work well are FFMS2 and IMWRI when outputting alpha. Update your plugins and there shouldn’t be any surprises.
So the big change in how alpha is handled happened in R55 (September 2021) while the last published version of FFMS2 dates to August 2020. So, if FFMS2 is now useless to me for RGB+alpha PNG sources, then what should I use now in its place?

SilSinn9801
18th August 2022, 09:49
OK, nevermind, there was a newer, unofficial build dated April 2022:
https://forum.doom9.org/showthread.php?p=1967796#post1967796
This one does send alpha to the _Alpha property instead of making cliptuple. So my code above now works.