View Full Version : Vapoursynth
06_taro
7th May 2013, 17:15
Myrsloik, I met some strange results from Lut and Expr for YUV420P16.
I used a simple script to reproduce it:
import vapoursynth as vs
core = vs.Core()
std = core.std
avs = core.avs
avs.LoadPlugin('DGDecodeNV.dll')
dgi = 'test.dgi'
clip = avs.DGSource(dgi)
clip = core.fmtc.bitdepth(clip, bits=16)
lut = []
for x in range(2**clip.format.bits_per_sample):
lut.append( x )
res = std.Lut(clip, lut, [0, 1, 2])
or I changed the last line to:
res = std.Expr( clip, 'x' )
It is expected that Lut / Expr should return exactly the original value of pixel, and is same as clip. However, with Lut, I got a nearly blank (0, 0, 0) msb, and few information in lsb related to the original clip; while with Expr, the whole picture turned pink, and looked as if it was the input clip horizontally interleaved a full (65535, 65535, 65535) clip.
Some other filters which support YUV420P16 like generic.Blur gives expected results, so I suppose something went wrong in Lut and Expr, or in my script. Naturally, Expr(clip, '') works as it should, so does specifying planes[] to preserve data in certain planes. Using a const in expression like lut.append(32768) or Expr(clip, '32768') also works well. Did I make any mistakes, or do these two functions need special workaround like re-order bytes, or is there any regression in the filters?
Env:
Win Server 2012 Datacenter (x64)
python 3.3 win32
vapoursynth r18
Any video, any source filter, any resizer for 8->16 conversion, and any other pre-filters, as long as the input clip for Lut/Expr is YUV420P16.
Viewed by vfw dithered by fmtc.bitdepth, or encoded by FFmpeg/x264 with y4m or raw with specified format/input-depth/csp, or raw yuv generated by clip.output() function.
Didn't test other csps, as I'm still using masktools for 8-bit stuffs :P
Hmm, good spot, 06_taro.
Just looking at the code, with no testing done what so ever, it may be due to the fact that the srcp pointer is not being cast to uint16_t when being read in LUT.
Ex:
((uint16_t *)dstp)[x] = lut[srcp[x]];
should be
((uint16_t *)dstp)[x] = lut[((const uint16_t *)srcp)[x]];
As for Expr, the C-code looks fine, but the plugin normally runs with the ASM code, which I don't read well/at all. I assume something similar may be happening.
It might be good to add a regression test in the Python tests, just for good maintenance sake. Hell, I can write one when I get home.
Edit: Looks like the same issue exists in LUT2:
((uint16_t *)dstp)[x] = lut[(srcpy[x] << shift) + srcpx[x]];
Here's a patch to simplefilters.c which should fix LUT and LUT2
diff --git a/src/core/simplefilters.c b/src/core/simplefilters.c
index 9ea2a97..738c337 100644
--- a/src/core/simplefilters.c
+++ b/src/core/simplefilters.c
@@ -1885,7 +1885,7 @@ static const VSFrameRef *VS_CC lutGetframe(int n, int activationReason, void **i
for (hl = 0; hl < h; hl++) {
for (x = 0; x < w; x++)
- ((uint16_t *)dstp)[x] = lut[srcp[x]];
+ ((uint16_t *)dstp)[x] = lut[((uint16_t *)srcp)[x]];
dstp += dst_stride;
srcp += src_stride;
@@ -2052,7 +2052,7 @@ static const VSFrameRef *VS_CC lut2Getframe(int n, int activationReason, void **
for (hl = 0; hl < h; hl++) {
for (x = 0; x < w; x++)
- ((uint16_t *)dstp)[x] = lut[(srcpy[x] << shift) + srcpx[x]];
+ ((uint16_t *)dstp)[x] = lut[(((uint16_t *)srcpy)[x] << shift) + ((uint16_t *)srcpx)[x]];
dstp += dst_stride;
srcpx += src_stride;
And a new regression test framework under test/test_regression.py
import unittest
import vapoursynth as vs
class RegressionTestSequence(unittest.TestCase):
def setUp(self):
self.core = vs.Core()
def checkDifference(self, cpu, gpu):
diff = self.core.std.PlaneDifference([cpu, gpu], 0, prop="PlaneDifference0")
diff = self.core.std.PlaneDifference([diff, gpu], 1, prop="PlaneDifference1")
diff = self.core.std.PlaneDifference([diff, gpu], 2, prop="PlaneDifference2")
for i in range(diff.num_frames):
frame = diff.get_frame(i)
self.assertEqual(frame.props.PlaneDifference0[0], 0)
self.assertEqual(frame.props.PlaneDifference1[0], 0)
self.assertEqual(frame.props.PlaneDifference2[0], 0)
def testLUT16Bit(self):
clip = self.core.std.BlankClip(format=vs.YUV420P16, color=[69, 242, 115])
lut = []
for x in range(2 ** clip.format.bits_per_sample):
lut.append(x)
ret = self.core.std.Lut(clip, lut, [0, 1, 2])
self.checkDifference(clip, ret)
if __name__ == '__main__':
unittest.main()
sl1pkn07
8th May 2013, 12:04
one little fix
https://code.google.com/p/vapoursynth/source/browse/trunk/include/VSScript.h#21
is "#include VapourSynth.h" (#include "vapoursynth.h" fail build in linux (case sensitive))
Here's what I tried to get Vapoursynth working in my Linux Mint 64bit 13.04 (inside a Virtualbox) working:
1. Installing a bunch of dependencies.
sudo apt-get install build-essential libqtcore4 python3 python3-dev wget subversion yasm libswscale-dev libavcodec-dev libass-dev autoconf libavformat-dev mplayer
2. Extracting and installing Cython (http://pypi.python.org/packages/source/C/Cython/Cython-0.19.zip):
sudo python3 setup.py install
3. Checkout, build and install Vapoursynth:
3.1 checkout
svn checkout http://vapoursynth.googlecode.com/svn/trunk vapoursynth
cd vapoursynth
3.2 fixing typo in include/VSScript.h:
[code]#include "vapoursynth.h"
to#include "VapourSynth.h"
3.3 installing
./bootstrap.py && ./waf configure && ./waf build && sudo ./waf install
sudo ./setup.py install
sudo ldconfig
4. checking out, extracting and building latest libav (https://libav.org/releases/libav-9.5.tar.gz), since Ubuntu 13.04 is missing libavresample
5. checking out and building ffms2
svn checkout http://ffmpegsource.googlecode.com/svn/trunk ffms2
cd ffms2
./autogen.sh
./configure --enable-shared
make
5. creating an example script named vstestscrpt.vpy:
#!/usr/bin/python3
import vapoursynth as vs
import sys
core = vs.Core()
core.std.LoadPlugin("/usr/local/lib/libffms2.so")
ret = core.ffms2.Source("/home/selur/Desktop/test.avi")
ret.output(sys.stdout, y4m=True)
6. making the script excecuteable
chmod +x vstestscrpt.vpy
7. calling mplayer to test the whole thing:
$ ./vstestscript.vpy | mplayer
Problem is the last step gives me:
Traceback (most recent call last):
File "./vstestscript.vpy", line 7, in <module>
ret.output(sys.stdout, y4m=True)
File "vapoursynth.pyx", line 676, in vapoursynth.VideoNode.output (build/src/cython/vapoursynth.c:10747)
vapoursynth.Error: 'write() call returned error'
-> Does anyone have an idea what is doing wrong? (or is this a bug?)
Cu Selur
sneaker_ger
8th May 2013, 13:37
Is mplayer set to y4m input via pipe? Because that's what you've set your VapourSynth output to.
doh, I was missing a '-', needs to be 'mplayer -'
sl1pkn07
8th May 2013, 14:07
for Archlinux users: https://aur.archlinux.org/packages/?O=0&K=vapoursynth
one little question, cpython is dependency for run or only for build?
greetings
gnaggnoyil
8th May 2013, 14:39
can i use avisynth runtime functions in a vapoursynth script? i.e., can i let core.avs.IsCombedTIVTC() work in vapoursynth, either using it in core.std.SelectClip(), or just return a boolean list, or do anything else?
if can't, what else could be used to replace IsCombedTIVTC for above usage?
@Selur,
Just a heads up, Mplayer/MPV might prefer that you disable the "y4m" setting on output, as setting it to true outputs an extended Y4M format that requires specific support by the reader, such as X264. Setting y4m=False still outputs standard y4m, and should be quite compatible with any command line player.
qyot27
8th May 2013, 22:09
@Selur,
Just a heads up, Mplayer/MPV might prefer that you disable the "y4m" setting on output, as setting it to true outputs an extended Y4M format that requires specific support by the reader, such as X264. Setting y4m=False still outputs standard y4m, and should be quite compatible with any command line player.
So long as mplayer* or mpv were actually built against FFmpeg and not the fork, the extended formats should work fine. At least the first time, maybe (I still haven't figured that part out; I think something's going wonky in Python or Cython so that subsequent attempts don't work). Alternately, always make sure to thread it through ffmpeg first to standardize the headers. It's always do-able that way.
./script.vpy | ffmpeg -i - -f yuv4mpegpipe -strict -1 - | mpv -
*for mplayer there's no guarantee that the repository version was (well, referring to mplayer2 here; mplayer-svn's situation is out of my realm of experience, but I think it uses an internal copy of FFmpeg unless there's some way of forcing that off); there is no mpv build in the repositories yet, so unless there's some PPA floating around, the user is in total control over which one they build into it (as they also are if they decide to build mplayer from source, but personally I see no reason not to use mpv if that's what you're going to do anyway).
Myrsloik
8th May 2013, 23:05
Here's a patch to simplefilters.c which should fix LUT and LUT2
It's not quite right for lut2. Consider the case where clip1 is 8bit and clip2 is 16bit and you'll see why. I applied the fix for lut and added the testcase.
If you want to compile from svn then I I suggest you revert r444-445 if you see any issues. That's the unfinished stuff.
06_taro
9th May 2013, 17:09
Thanks Adub & Myrsloik for the fix! Not really eager to get a fixed 16-bit LUT2, since even 8bit + 16bit LUT2 with 16bit output seems to need 2^8*2^16*2=32MB table, which is still too large for my CPU cache.
Any further idea about the regression in Expr?
It's not quite right for lut2. Consider the case where clip1 is 8bit and clip2 is 16bit and you'll see why. I applied the fix for lut and added the testcase.
If you want to compile from svn then I I suggest you revert r444-445 if you see any issues. That's the unfinished stuff.
Ahh, I see your point then. Okay, well good to see that LUT got fixed!
@qyot27
Ahh, yeah my mpv is built against libav I believe (Ubuntu default these days), so I ran into strange issues when using the extended format. Granted, this was a few months ago, so things might have cleared up since then.
qyot27
9th May 2013, 23:22
@qyot27
Ahh, yeah my mpv is built against libav I believe (Ubuntu default these days), so I ran into strange issues when using the extended format. Granted, this was a few months ago, so things might have cleared up since then.
It most probably won't have cleared up, since a search of libav's git repo shows absolutely nothing related to the extended format. It looks like they still don't support >10 <16 bit YUV (so those 12- and 14-bit H.264 samples wouldn't be treated correctly either).
If only it weren't intrinsically tied to VFW (which would sort of defeat the purpose of the name) and 2.6's colorspaces, it'd be interesting if the HBVFWSource plugin could be ported to AvxSynth, as that would at least avoid having to pipe into either x264 or FFmpeg (or mplayer/mpv by extension). Not really a long-term solution, but possibly less of a hassle in the short term until a discrete demuxer for VapourSynth coalesces in one or both of them.
Myrsloik
10th May 2013, 14:04
Ahh, I see your point then. Okay, well good to see that LUT got fixed!
@qyot27
Ahh, yeah my mpv is built against libav I believe (Ubuntu default these days), so I ran into strange issues when using the extended format. Granted, this was a few months ago, so things might have cleared up since then.
I didn't fix lut2 though. I still have far too much other programming to do.
Hmm, if I get some free time from writing my thesis, I'll see if I can come up with a solution for LUT2. No guarantees on that one though.
The mixed use case of 8-bit and 16-bit inputs is a bit of a problem.
digitall.h
14th May 2013, 16:19
@digitall.h
Is there something missing from Vapoursynth that you'd like to see? I ask because you speak of the project being promising, which just sounds to me personally like it's missing something you want.
...
Adub, sorry me for the delay in my answer, that probably doesn't make sense at this point of the discussion... :scared:
As I said no programming skills here (beginning with python, just 'Hello world!', just a hobby). I stated I find it promising for us end users, waiting for the point when Vapoursynth becomes more user friendly.
I mean, standard Vapoursynth 'scripts' to carry out those filter chains we used with avisynth under Windows. Some were already suggested in previous posts. As an example, the last avisynth scripts I was using was:
LoadPlugin("C:\Filtro25\DGDecode.dll")
LoadPlugin("C:\Filtro25\RemoveGrainSSE2.dll")
LoadPlugin("C:\Filtro25\SSE2Tools.dll")
LoadPlugin("C:\Filtro25\RepairSSE2.dll")
LoadPlugin("C:\Filtro25\mt_masktools.dll")
Import("C:\Filtro25\LRDLSFs.avsi")
Import("C:\Filtro25\Soothe.avsi")
Mpeg2Source("C:\test.d2v",idct=4)
Crop(0,74,720,428,true)
LRemoveDust_YV12(17,2)
dull = last.BilinearResize(672,400)
sharp = last.LimitedSharpenFaster(dest_x=672,dest_y=400)
Soothe(sharp,dull,18)
Addborders(16,88,16,88)
Where function Soothe.avsi was:
function Soothe(clip sharp, clip orig, int "keep")
{
keep = default(keep, 24)
keep = (keep>100) ? 100 : (keep<0) ? 0 : keep
KP = string(keep)
diff = mt_lutxy(orig,sharp,"x y - 128 +", U=1,V=1)
diff2 = diff.temporalsoften(1,255,255,32,2)
diff3 = mt_lutxy(diff,diff2, "x 128 - y 128 - * 0 < x 128 - 100 / " + KP
\ + " * 128 + x 128 - abs y 128 - abs > x " + KP
\ + " * y 100 " + KP + " - * + 100 / x ? ?", U=1,V=1)
return( mt_lutxy(orig,diff3,"x y 128 - -",U=2,V=2) )
}
And function LRDLSFs.avsi was:
function LRemoveDust_YV12(clip input, int clmode, int "limit")
{
limit=default(limit,2)
clmode=default(clmode,17)
repmode = 2
clensed = Clense(input)
rep = Repair(clensed, input, mode=repmode)
rg = RemoveGrain(rep, mode=clmode)
return LimitChange(rg, input, limit)
}
function LimitedSharpenFaster( clip clp,
\ float "ss_x", float "ss_y",
\ int "dest_x", int "dest_y",
\ int "Smode" , int "strength", int "radius",
\ int "Lmode", bool "wide", int "overshoot", int "undershoot",
\ int "soft", int "edgemode", bool "special",
\ int "exborder" )
{
ox = clp.width
oy = clp.height
Smode = default( Smode, 3 )
ss_x = (Smode==4)
\ ? default( ss_x, 1.25)
\ : default( ss_x, 1.5 )
ss_y = (Smode==4)
\ ? default( ss_y, 1.25)
\ : default( ss_y, 1.5 )
dest_x = default( dest_x, ox )
dest_y = default( dest_y, oy )
strength = (Smode==1)
\ ? default( strength, 160 )
\ : default( strength, 100 )
strength = (Smode==2&&strength>100) ? 100 : strength
radius = default( radius, 2 )
Lmode = default( Lmode, 1 )
wide = default( wide, false )
overshoot = default( overshoot, 1)
undershoot= default( undershoot, overshoot)
softdec = default( soft, 0 )
soft = softdec!=-1 ? softdec : sqrt( (((ss_x+ss_y)/2.0-1.0)*100.0) ) * 10
soft = soft>100 ? 100 : soft
edgemode = default( edgemode, 0 )
special = default( special, false )
exborder = default( exborder, 0)
#radius = round( radius*(ss_x+ss_y)/2) # If it's you, Mug Funky - feel free to activate it again
xxs=round(ox*ss_x/8)*8
yys=round(oy*ss_y/8)*8
smx=exborder==0?dest_x:round(dest_x/Exborder/4)*4
smy=exborder==0?dest_y:round(dest_y/Exborder/4)*4
clp.isYV12() ? clp : clp.converttoyv12()
ss_x != 1.0 || ss_y != 1.0 ? last.spline36resize(xxs,yys) : last
tmp = last
edge = mt_logic( tmp.mt_edge(thY1=0,thY2=255,"8 16 8 0 0 0 -8 -16 -8 4")
\ ,tmp.mt_edge(thY1=0,thY2=255,"8 0 -8 16 0 -16 8 0 -8 4")
\ ,"max") .mt_lut("x 128 / 0.86 ^ 255 *")
tmpsoft = tmp.removegrain(11,-1)
dark_limit1 = tmp.mt_inpand()
bright_limit1 = tmp.mt_expand()
dark_limit = (wide==false) ? dark_limit1 : dark_limit1 .removegrain(20,-1).mt_inpand()
bright_limit = (wide==false) ? bright_limit1 : bright_limit1.removegrain(20,-1).mt_expand()
minmaxavg = special==false
\ ? mt_average(dark_limit1, bright_limit1)
\ : mt_merge(dark_limit,bright_limit,tmp.removegrain(11,-1),Y=3,U=-128,V=-128)
Str=string(float(strength)/100.0)
normsharp = Smode==1 ? unsharpmask(strength,radius,0)
\ : Smode==2 ? sharpen(float(strength)/100.0)
\ : Smode==3 ? mt_lutxy(tmp,minmaxavg,yexpr="x x y - "+Str+" * +")
\ : mt_lutxy(tmp,tmpsoft,"x y == x x x y - abs 16 / 1 2 / ^ 16 * "+Str+
\ " * x y - 2 ^ x y - 2 ^ "+Str+" 100 * 25 / + / * x y - x y - abs / * + ?")
OS = string(overshoot)
US = string(undershoot)
mt_lutxy( bright_limit, normsharp, yexpr="y x "+OS+" + < y x y x - "+OS+" - 1 2 / ^ + "+OS+" + ?")
mt_lutxy( dark_limit, last, yexpr="y x "+US+" - > y x x y - "+US+" - 1 2 / ^ - "+US+" - ?")
Lmode==1 ? mt_clamp(normsharp, bright_limit, dark_limit, overshoot, undershoot) : last
normal = last
zero = mt_clamp(normsharp, bright_limit, dark_limit, 0,0)
Lmode==3 ? mt_merge(normal,zero,edge.mt_inflate()) : normal
edgemode==0 ? last
\ : edgemode==1 ? mt_merge(tmp,last,edge.mt_inflate().mt_inflate().removegrain(11,-1),Y=3,U=1,V=1)
\ : mt_merge(last,tmp,edge.mt_inflate().mt_inflate().removegrain(11,-1),Y=3,U=1,V=1)
AMNT = string(soft)
AMNT2 = string(100-soft)
sharpdiff=mt_makediff(tmp,last)
sharpdiff2=mt_lutxy(sharpdiff,sharpdiff.removegrain(19,-1),
\ "x 128 - abs y 128 - abs > y "+AMNT+" * x "+AMNT2+" * + 100 / x ?")
soft==0 ? last : mt_makediff(tmp,sharpdiff2)
(ss_x != 1.0 || ss_y != 1.0)
\ || (dest_x != ox || dest_y != oy) ? spline36resize(dest_x,dest_y) : last
ex=blankclip(last,width=smx,height=smy,color=$FFFFFF).addborders(2,2,2,2).coloryuv(levels="TV->PC")
\.blur(1.3).mt_inpand().blur(1.3).spline36resize(dest_x,dest_y,1.0,.0)
tmp = clp.spline36resize(dest_x,dest_y)
clp.isYV12() ? ( exborder==0 ? tmp.mergeluma(last)
\ : mt_merge(tmp,last,ex,Y=3,U=1,V=1) )
\ : ( exborder==0 ? tmp.mergeluma(last.converttoyuy2())
\ : tmp.mergeluma( mt_merge(tmp.converttoyv12(),last,ex,Y=3,U=1,V=1)
\ .converttoyuy2()) )
(edgemode!= -1) ? last : edge.spline36resize(dest_x,dest_y).greyscale
return last
}
Of course I did not create these scripts, where created by skilled people in Doom9. I don't know if at this point this filter chain (or something equivalent) can be translated into Vapoursynth syntax, and make it understandable for us end-users.
:)
kolak
14th May 2013, 17:11
Hmm, if I get some free time from writing my thesis, I'll see if I can come up with a solution for LUT2. No guarantees on that one though.
The mixed use case of 8-bit and 16-bit inputs is a bit of a problem.
Can't you convert all source to one format (regardless source precision)? It would be easier than.
LUT's are a fast solution to complex problems, but you must be mindful of the size of the table.
Two 16-bit inputs for a 16-bit output requires a table of 2*65536*65536 = 8,589,934,592 bytes (8GB), clearly that's not going to work in a 32 bit address space. Even in x64 there is the start up time to calculate 4 billion table entries and the slow access to such a huge table, contrast a 1920x1080 frame has only 2,073,600 pixels so raw mode you only do 1/2000 the number of calculations. Horse for courses.
Now an 8-bit input across a 16-bit input for a 16-bit output requires a table of 2*256*65536 = 33,554,432 bytes (32MB), gee that even fit's in the L3-cache of a top end machine.
And if you know your two 16-bit inputs are actually only 10-bit, then you can sneak by with a table of 2*1024*1024 = 2,097,152 (2MB) and that fits in the L2-cache of many machines.
kolak
15th May 2013, 00:13
Not sure how it relates to this case by in pro software LUTs are simplified and use only eg 4096 entries, like LOG to 709 LUT. Is this the same thing?
There are 100's of algorithms to do partial LUT acceleration. That is where the LUT only contains a small fraction of the total lookup space.
One clever algorithm I have seen had "values" and "1st derivative values" in a pair of sparse LUT's. You used the 2 LUT values to calculate quadratic approximation, ax^2+bx+c, in the local region between 2 LUT points.
Mug Funky
16th May 2013, 05:17
i believe most colour grading software uses that approach - you define a 16x16x16 colour cube and the GPU does the work. this gives you better than realtime processing of very big frames in 32 bit float (values are often only 10 bit because they're based off densitometer measurements of printed film compared against 10-bit scans of the print's original neg counterpart).
Question:
For Lut2, do we assume that clips must always be passed in in order of their bits-per-sample?
Ex:
clips=[cilpP9, clipP10],
not
clips=[clipsP10, clipsP9]
I ask because I'm looking at fixing Lut2 and judging by the example below, I see issues with the [10-bit, 9-bit] input:
lut = []
for y in range(2**clipx.format.bits_per_sample):
for x in range(2**clipy.format.bits_per_sample):
lut.append(x)
Lut2(clips=[clipx, clipy], lut=lut, planes=[0, 1, 2])
The above example with stunted values for a 10-bit output clip since the LUT never goes above 2^9 = 512 values.
However, if we assume that clipx must ALWAYS be the lesser bit clip, then it should work just fine.
If this is the case, I think it would be good to make a note in the documentation.
Edit:
I suppose a second question is format the output clip format. If we pass in an 8-bit and a 10-bit clip, then do we want an 8-bit output clip or a 10-bit output clip?
I'm thinking the latter at this point, but Lut2's current behaviour is to output an 8-bit clip (assuming it's the first clip passed in).
Hmm, after looking at Lut2's code for a while, I came to a few conclusions.
The current Lut2 code does not properly handle > 8-bit inputs, which we already knew. But, even more so, the example script in the documentation is a bit misleading.
The reason being that Lut2 uses the first clip's values for the column, or x, lookup in the LUT. It uses the second clip's values for the row, or y, lookup in the LUT.
The example provided in the documentation (see url) is slightly misleading.: http://vapoursynth.com/doc/functions/lut2.html
Repeated here for brevity:
lut = []
for y in range(2**clipx.format.bits_per_sample):
for x in range(2**clipy.format.bits_per_sample):
lut.append((x + y)//2)
Lut2(clips=[clipx, clipy], lut=lut, planes=[0, 1, 2])
I have highlighted a few key parts of the script.
The clips themselves don't really matter, they could be called clipA and clipB for all I care, but the manner in which they generate the LUT is import.
Specifically, in the above example clipy generates the LUT's x values in the inner loop, and clipx generates the LUT's y values in the outer loop. If the clips are the same bits per sample, that's okay, but otherwise issues can occur.
Now here's one more problem. The script passes the clips to Lut2 as [clipx, clipy]. According to the code, that would be correct if clipx corresponded to the x values of the LUT, and clipy the y values. Only, as I described above, they are actually flipped.
Now, I have a patch and associated regression tests that correctly fixes Lut2 and it's handling of different bit-depth clips, including > 8-bits. However, I'd like to clear up my questions in the previous post before I submit it, as it does make a difference which inputs are legal and the desired clip output format.
06_taro
18th May 2013, 07:49
I think it is reasonable to add an argument to indicates output bit depth such as 'bits' or 'format'. It is useful to tell Lut which integer type to be used to store output value. If we limits the output bit depth to input depth, or even highest input depth in Lut2, it is another pain to use some wrappers like the method Dither_lut8 uses to get higher depth output. Though with this argument one need to be careful to handle the values when building lookup table, I don't think it is a problem for users who know what lut is.
To make things easier, maybe we can make a limitation that output 'bits' must be either 8, 16, or the highest input bit depth, as 9~15 bit depth of output value won't save any space of memory compared to 16 bits, and we won't run into the mess if the output format isn't natively supported by VS. I'm even thinking of supporting only 8 or 16 bits output, so that the logic is clearer, and it is already fast enough to do rounding in fmtconv. But in this way we might loss convenience when dealing with simple calculation like Lut2([clipXp10, clipYp10], lut=simple_lut) in which simple_lut is something like (x-y).
gnaggnoyil
24th May 2013, 06:45
Another memory leak problem:
vapoursynth seems to have a rapid memory request when a script request every frame. for example, the script below:
import vapoursynth
import sys
core=vapoursynth.Core()
video1=SOMECLIP;
video2=SOMECLIP
video3=core.std.PlaneDifference([video1,video2],0,prop="YPlaneDifference")
l=[]
for i in range(video3.num_frames):
l.append(video3.get_frame(i).props.YPlaneDifference[0])
and this kind of script using vapoursynth r18 would result a rapid memory request in my win7 x64 system and finally cause an avisynth crash error. I guess that vapoursynth would allocate a piece of memory to save the video frame raw data each time when get_frame() is called, but I am very puzzled that how videoNode.output() method wouldn't cause such a crash if the above statement is true. Is there anyone who can point out the reason, or give a solution to this problem?
Myrsloik
24th May 2013, 10:22
Another memory leak problem:
vapoursynth seems to have a rapid memory request when a script request every frame. for example, the script below:
import vapoursynth
import sys
core=vapoursynth.Core()
video1=SOMECLIP;
video2=SOMECLIP
video3=core.std.PlaneDifference([video1,video2],0,prop="YPlaneDifference")
l=[]
for i in range(video3.num_frames):
l.append(video3.get_frame(i).props.YPlaneDifference[0])
and this kind of script using vapoursynth r18 would result a rapid memory request in my win7 x64 system and finally cause an avisynth crash error. I guess that vapoursynth would allocate a piece of memory to save the video frame raw data each time when get_frame() is called, but I am very puzzled that how videoNode.output() method wouldn't cause such a crash if the above statement is true. Is there anyone who can point out the reason, or give a solution to this problem?
There is a reference leak that's been fixed in svn that's causing it. I really should do a round of debugging and release r19 soon...
Have a new vapoursynth.pyd file without the leak (https://dl.dropboxusercontent.com/u/73468194/vapoursynth.pyd)
Tell me if it still leaks after this.
IsoaSFlus
25th May 2013, 10:15
sorry
when i executed "./waf build"
igot some errors:
Waf: Entering directory `/root/src/vapoursynth-read-only/build' Waf: Leaving directory `/root/src/vapoursynth-read-only/build' File /root/src/vapoursynth-read-only/src/core/asm/expr.asm has no ma pping in ['.c', '.o', '.obj', '.ts', '.C', '.qrc', '.c++', '.cpp', ' .ui', '.pyx', '.cc', '.pc.in', '.cxx'] (did you forget to load a waf tool?)
how can i solve this problem?
tks
(i use Ubuntu 13.04 32bit)
jackoneill
27th May 2013, 17:48
sorry
when i executed "./waf build"
igot some errors:
Waf: Entering directory `/root/src/vapoursynth-read-only/build' Waf: Leaving directory `/root/src/vapoursynth-read-only/build' File /root/src/vapoursynth-read-only/src/core/asm/expr.asm has no ma pping in ['.c', '.o', '.obj', '.ts', '.C', '.qrc', '.c++', '.cpp', ' .ui', '.pyx', '.cc', '.pc.in', '.cxx'] (did you forget to load a waf tool?)
how can i solve this problem?
tks
(i use Ubuntu 13.04 32bit)
Please paste all the commands you ran and their output, if possible.
@Myrsloik
Can I get your input on the bitdepth behavior of Lut2, as described above?
I'd like to get a patch for a working version of Lut2 submitted, but I'm just not sure about the desired handling behavior.
Myrsloik
27th May 2013, 20:31
@Myrsloik
Can I get your input on the bitdepth behavior of Lut2, as described above?
I'd like to get a patch for a working version of Lut2 submitted, but I'm just not sure about the desired handling behavior.
What I want:
A lut with a maximum of 20 bits input and selectable 8-16 bit output.
The two input clips can be between 8 and 12 bits in any combination that's less than 20 bits total.
I think that's all. This is probably a bit annoying to do without templates since you need to make several functions the different combinations of 8/16bit input.
IsoaSFlus
28th May 2013, 08:58
Please paste all the commands you ran and their output, if possible.
sorry,but what i posted is all info
@IsoaSFlus
No, it's not. You did not post your "./waf configure" step and any of the corresponding output, nor all output from the build step.
There should be a significant amount of terminal output from the configure and build steps. Be sure to use something like the forum formatting for easier reading.
IsoaSFlus
29th May 2013, 08:57
@IsoaSFlus
No, it's not. You did not post your "./waf configure" step and any of the corresponding output, nor all output from the build step.
There should be a significant amount of terminal output from the configure and build steps. Be sure to use something like the forum formatting for easier reading.
i see,tks a lot and
this is my config.log
hiso.comoj.com/something/config.log
and then,i built it
root@localhost:~/src/vapoursynth-read-only# ./waf build
Waf: Entering directory `/root/src/vapoursynth-read-only/build'
Waf: Leaving directory `/root/src/vapoursynth-read-only/build'
File /root/src/vapoursynth-read-only/src/core/asm/expr.asm has no ma
pping in ['.c', '.o', '.obj', '.ts', '.C', '.qrc', '.c++', '.cpp', '
.ui', '.pyx', '.cc', '.pc.in', '.cxx'] (did you forget to load a waf
tool?)
root@localhost:~/src/vapoursynth-read-only#
i think that ia the all,what should i do?
sl1pkn07
29th May 2013, 09:39
you uses root for build?
NEVER build with root. only use root to install (waf install)
Well, build is complaining it can't build asm files, you are on arm platform, and your log does not show any yasm/nasm check. I guess arm is not supported anyway.
Myrsloik
29th May 2013, 13:46
Only x86 is supported for now. Mostly because I don't have any arm stuff to test it on but porting should be a quick thing to do. Zor said that he'll try to port it to both arm and powerpc soon.
The real question is, why are you trying to run this on arm at all?
IsoaSFlus
29th May 2013, 15:28
@Myriloik
the answer is:
my senior high school doesn't allow us to bring pc to school...so,i only have a Android mobile.TAT.(i study at a boarding school )
A fixed version of Lut2 is available as a diff on the Google Code tracker.
Myrsloik
30th May 2013, 20:34
#!/usr/bin/env python3
import vapoursynth as vs
import sys
core = vs.Core()
std = core.std
def ivtc(clip, offsets, cycle=10, tff=True):
clip = std.SeparateFields(clip, tff)
clip = std.DoubleWeave(clip, tff)
return std.SelectEvery(clip, cycle, offsets)
def show_progress(c, t):
print('%i / %i' % (c, t), end='\r', file=sys.stderr, flush=True)
src = std.BlankClip(width=1920, height=1080, format=vs.YUV420P8, length=50000)
clips = []
for f in range(200):
clips.append(ivtc(src[f * 100: f * 100 + 30], [1, 4, 6, 9]))
clips.append(ivtc(src[f * 100 + 30: f * 100 + 60], [0, 2, 5, 7]))
clips.append(ivtc(src[f * 100 + 60: f * 100 + 100], [1, 3, 6, 8]))
last = std.Splice(clips)
#print(last, file=sys.stderr)
last.output(sys.stdout, False, 0, show_progress)
When I ran this script, the speed falls at about 6000th frame and the amount of the memory used continued increasing.
Is this bug or limitation ?
Definitely a bug. I'll see if I can find the leak...
I can confirm that r498 fixed the memleak issues with caching and Splice. Just ran it on my Ubuntu 13.04 machine.
Myrsloik
5th June 2013, 10:36
The next version is getting closer but I still want to add some easy way to access frame data from python. Currently you can use ctypes to get the raw data but I was thinking about maybe adding support for getting a frame as a numpy array or something similar. Any suggestions or alternative idea on how to do this?
LoRd_MuldeR
5th June 2013, 13:03
Any chance for an improved CLI front-end, which external programs could use to query the frame rate, size and count for user-provided VapourSynth scripts?
Myrsloik
5th June 2013, 13:07
Any chance for an improved CLI front-end, which external programs could use to query the frame rate, size and count?
That would be easy to add. How do you want the output?
Format: YUV422
Width: 100
Height: 200
Frames: 2344
FPS: 30000/1001
I could easily add something like that to my new cli output thing if that's what you need. And tell me if you need any other information to be in there.
LoRd_MuldeR
5th June 2013, 13:12
I would say that looks fine :)
Though I can imagine that an "interlaced vs. progressive" flag could be helpful for some applications too.
mastrboy
5th June 2013, 19:37
Maybe add bitdepth also?
If vapoursynth could signal for example 8/10bit to x264, that could perhaps spare us for the --input-depth parameter?
Myrsloik
5th June 2013, 19:44
Maybe add bitdepth also?
If vapoursynth could signal for example 8/10bit to x264, that could perhaps spare us for the --input-depth parameter?
I'll add it to the info, but it already can with y4m headers added.
Myrsloik
6th June 2013, 20:15
If someone wants to contribute a small patch to improve the lut/lut2 filters:
https://code.google.com/p/vapoursynth/issues/detail?id=52
tin3tin
7th June 2013, 13:05
If you haven't noticed it, I would just like to mention the great things happening with the Magic Lantern hack for Canon http://www.eoshd.com/content/10324/big-news-hands-on-with-continuous-raw-recording-on-canon-5d-mark-iii
The hack opens up for the possibility to shoot 14 bit raw with a camera within the consumer price range. Do you think an friendship between vapoursynth and ML RAW could evolve? (I mean import of RAW)
Here is a description of the current workflow and raw2dng code:
http://www.magiclantern.fm/forum/index.php?topic=5404.msg34757#msg34757
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.