View Full Version : Hold and fade out pixels by an specified amount?
Reel.Deel
16th December 2022, 22:55
Does anyone know if it would be possible to hold and fade out pixels by an specified amount with Expr? For example, let's say that the current pixel value is 100 and I want to hold and fade it out in 4 frames (n=100, n+1=75, n+2=50, n+3=25, n+4=0). I think FFmpeg has a filter like that named LagFun (docs (https://ffmpeg.org/ffmpeg-filters.html#lagfun)| source (https://github.com/FFmpeg/FFmpeg/blob/master/libavfilter/vf_lagfun.c)) but I have not tried it out. Is this possible with Expr or does it need to be a plugin? Thanks in advance for any replies or help :)
Julek
17th December 2022, 15:55
I don't use AVS much, but something like this should work.
src = LWLibavVideoSource("xx")
blk = BlankClip(src) # you can change the fade colors here
fstart = 101 # n frame to start
length = 4 # n frame with fade
p1 = Trim(src, 0, fstart-2)
p2 = Trim(src, fstart-1, 0)
p3 = Trim(blk, fstart+length, 0)
expr = Expr([p2, blk], Format("frameno {length} / F@ y * 1 F - x * +")).Trim(0, length)
fade = p1 + expr + p3
fade
Reel.Deel
17th December 2022, 19:02
Hi Julek,
Thanks for the reply. I tried out your suggestion but it just fades out the given frames, and does not "hold" the pixels. Here's an animation that shows the effect I'm trying to achieve:
https://i.ibb.co/x56nnWy/pixeldelay.png
So this would be for the entire length of the video, not just a few frames.
wonkey_monkey
17th December 2022, 20:40
What about:
function pad1(clip a) {
return a.BlankClip(length = 1) + a.trim(0,a.framecount-1)
}
v = [source]
a = v.pad1
b = a.pad1
c = a.pad1
a = a.levels(0,1,255,0,192)
b = b.levels(0,1,255,0,128)
c = c.levels(0,1,255,0,64)
v = layer(v, a, op="lighten")
v = layer(v, b, op="lighten")
v = layer(v, c, op="lighten")
v
Reel.Deel
18th December 2022, 01:57
Thanks wonkey_monkey, that essentially does what I was looking for. I guess it can't be done with Expr. Performance wise it takes a big hit when doing it on an RGB source. Fortunately I'm able to do it on a Y8 clip so it's not that bad, but if I wanted to do 10 or so frames, I'm sure it will be slow. I replaced layer(x, x, op="lighten") with mt_logic(x, x, "max") for speed. And here's what the result looks like when using it on a custom Histogram("StereoY8") script I'm working on:
https://i.ibb.co/jJT6YRK/avs-oscilloscope.png
The result looks drastic here since it's 5fps but in real time it's not that noticeable.
wonkey_monkey
18th December 2022, 18:48
You can use Feedback (https://forum.doom9.org/showthread.php?t=182910) to send each frame of the video into the "future" to be used in an Expr against the next frame:
v = [source]
expr(v, v.FeedbackInput, "x y 0.9 * max").FeedbackOutput
which will give you a geometric fade, but there's no cut-off and you'll have to request frames in sequence from 0, otherwise it'll crash (I should fix that).
Reel.Deel
18th December 2022, 23:05
I'll see if I give Feedback a try. For now I have this:
function coolname1(clip input, int times)
{
t = times
l = Round(255/(t+1))
a = (t>0) ? coolname2(input, FramePadX(input, 1), 255-l) : NOP()
b = (t>1) ? coolname2(a, FramePadX(input, 2), 255-(l*2)) : NOP()
c = (t>2) ? coolname2(b, FramePadX(input, 3), 255-(l*3)) : NOP()
d = (t>3) ? coolname2(c, FramePadX(input, 4), 255-(l*4)) : NOP()
e = (t>4) ? coolname2(d, FramePadX(input, 5), 255-(l*5)) : NOP()
Return((t==1) ? a : (t==2) ? b : (t==3) ? c : (t==4) ? d : (t>=5) ? e : input)
}
function coolname2(clip input, clip input2, int level)
{
Return(mt_lutxy(input, input2, Format("x y 255 / {level} * max")))
}
function FramePadX(clip input, int frames)
{
Return(BlankClip(input, length=frames, colors=[0]) + Trim(input, 0, input.Framecount-frames))
}
Doing 5 frames on a Y8 512*512 clip, I'm getting about 525fps (single threaded) so I'm happy. Original script without any blending was about 1300 fps. Thanks again for the help.
If anyone ever writes a dedicated filter, you have a user right here :D
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.