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 > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 30th November 2014, 02:25   #1  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,085
aWarpSharp4xx: a script similar to aWarpSharp2 but supports all planar colorspaces

I recently had to process a handful a pictures which where 4:2:2. Unfortunately aWarpSharp2 only works with YV12, so I came up with aWarpSharp4xx, a wrapper function that allows aWarpSharp2 to be used with any planar YUV colorspace.
Usage is almost identical, the only difference is that when processing YV16/YV24/YV411 chroma=1 is identical to chroma=0. When processing Y8 or YV12 aWarpSharp2() is used directly so it will be faster and more memory efficient than processing other colorspaces.
Obvious requirements are AviSynth 2.6 and aWarpSharp2. Hopefully someone will find this useful

One thing I'm unsure about is the scaling of the luma mask used to guide the chroma. Right now I'm just using BicubicResize() to scale the mask to the appropriate dimensions. Would interesting to know how aWarpSharp2() does this internally.

Code:
function aWarpSharp4xx (clip src, int "thresh", int "blur", int "type", int "depth", int "depthC", int "chroma", bool "lsb", string "cplace")
{
depth  = default(depth, 16)
depthC = default(depthC, src.IsYV24 ? depth : depth/2) #depth/3 is claimed to work better
chroma = default(chroma, 4)
lsb    = default(lsb, false)
cplace = default(cplace, "MPEG2")

Assert(IsPlanar(src), "aWarpSharp4xx: input clip must be planar YUV")
Assert(0 <= chroma <= 6, "aWarpSharp4xx: argument chroma must be an integer between 0 and 6.")
Assert(cplace == "MPEG2" || cplace == "MPEG1", "aWarpSharp4xx: chroma siting must be MPEG2 or MPEG1")

src8 = lsb ? src.DitherPost(mode=-1) : src

IsY8(src) || IsYV12(src) && (chroma != 4 && chroma != 6) ? \
Eval("""
warp   = ConvertToYV12(src8).aWarpSharp2(thresh=thresh, blur=blur, type=type, depth=depth, chroma=IsY8(src) ? 1 : chroma)
output = IsY8(src) ? ConvertToY8(warp) : warp
""") : \
Eval("""
y = ConvertToY8(src8).ConvertToYV12()
u = UtoY(src8).ConvertToYV12()
v = VtoY(src8).ConvertToYV12()

# warp each channel independently
y_warp = aWarpSharp2(y, thresh=thresh, blur=blur, type=type, depth=depth,  chroma=1)
u_warp = aWarpSharp2(u, thresh=thresh, blur=blur, type=type, depth=depthC, chroma=1)
v_warp = aWarpSharp2(v, thresh=thresh, blur=blur, type=type, depth=depthC, chroma=1)

# warp chroma by guiding it with the luma edge mask
cshift = cplace == "MPEG2" && !src.IsYV24 ? -0.5 : 0
y_mask  = aSobel(y, thresh=thresh).aBlur(blur=blur, type=type).BilinearResize(u.width(), v.height(), src_left=cshift)
u_warp2 = aWarp(u, y_mask, depth=depthC, chroma=1)
v_warp2 = aWarp(v, y_mask, depth=depthC, chroma=1)

# "fill with zeroes"
blank = BlankClip(u, pixel_type="Y8", color_yuv=$808080)

# luma/chroma processing
output = chroma==0 ||                                      \
         chroma==1 ? YtoUV( blank   , blank   , y_warp ) : \
         chroma==2 ? YtoUV( u       , v       , y_warp ) : \
         chroma==3 ? YtoUV( u_warp  , v_warp  , y_warp ) : \
         chroma==4 ? YtoUV( u_warp2 , v_warp2 , y_warp ) : \
         chroma==5 ? YtoUV( u_warp  , v_warp  , y      ) : \
         chroma==6 ? YtoUV( u_warp2 , v_warp2 , y      ) : \
         src8
""")
output8_16 = lsb==true ? output.Dither_convert_8_to_16() : output
y_ld  = chroma < 5 ? 3 : 2
uv_ld = Min(chroma, 3)
output16 = Dither_limit_dif16(src, output8_16, thr=1.0, elast=1.5, y=y_ld, u=uv_ld, v=uv_ld)
Return(lsb==true ? output16 : output8_16)
}
I'm not an expert at AviSynth scripting so if something can be done a bit more efficiently please let me know.

Last edited by Reel.Deel; 31st March 2015 at 18:40. Reason: add updated script
Reel.Deel is offline   Reply With Quote
Old 21st March 2015, 21:30   #2  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 1,036
I was thinking of good "warp chroma by guiding it with the luma" away from aWarpSharp2 to get better result

and never think I will get it with this script, but it better than aWarpSharp2

yes, your script result different from original aWarpSharp2 in yv12 after delete "IsYV12(src)" from "IsY8(src) || IsYV12(src) ? \" line

look like original aWarpSharp2 do the "warp chroma by guiding it with the luma" after aWarpSharp2 in luma even with chroma=6

so this is my little edition to make it work with yv12 too

*deleted*

edit: original one above now work with yv12 in some case, but if you want my edition it can be find below

edit: the different from original aWarpSharp2 is that the original use type=0 and aBlur use type=1, so if we use type=0 in aWarpSharp4xx it will be like the original one
__________________
My Avisynth Stuff

Last edited by real.finder; 24th October 2015 at 17:44.
real.finder is offline   Reply With Quote
Old 22nd March 2015, 15:59   #3  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,085
Quote:
Originally Posted by real.finder View Post
look like original aWarpSharp2 do the "warp chroma by guiding it with the luma" after aWarpSharp2 in luma even with chroma=6
If I'm understating you correctly you're saying that aWarpSharp2(chroma=6) warps the luma first and then uses it to guide the chroma channels? I'm not sure how aWarpSharp2 works internally but I did a little test that confirms the luma channel is simply copied from the input clip when chroma=6.
Code:
original = last
filtered = last.aWarpSharp2(chroma=6)
mt_lutxy(original,filtered, "x y - abs 255 *", u=-128, v=-128)
Reel.Deel is offline   Reply With Quote
Old 22nd March 2015, 16:18   #4  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: Los Angeles, California
Posts: 2,119
Quote:
Originally Posted by Reel.Deel View Post
If I'm understating you correctly you're saying that aWarpSharp2(chroma=6) warps the luma first and then uses it to guide the chroma channels? I'm not sure how aWarpSharp2 works internally but I did a little test that confirms the luma channel is simply copied from the input clip when chroma=6.
Code:
original = last
filtered = last.aWarpSharp2(chroma=6)
mt_lutxy(original,filtered, "x y - abs 255 *", u=-128, v=-128)
Warpsharp detects the "exact" edge, and pixels around the edge would move along to the edge by vectors, "guide by luma", that's telling you you are processing chroma planes but you get the vector and edge reference from luma plane
__________________
If I got new ideas, will post here: https://github.com/IFeelBloated
feisty2 is offline   Reply With Quote
Old 22nd March 2015, 16:22   #5  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,085
Sigh....Yes I know what "guide by luma" means. But that's not what we're discussing...
Reel.Deel is offline   Reply With Quote
Old 22nd March 2015, 16:30   #6  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: Los Angeles, California
Posts: 2,119
Yeah, you wanna know will warpsharp process luma if set "guide by luma", well, no, cuz you don't need to process it first to use it as a reference of detecting steps
__________________
If I got new ideas, will post here: https://github.com/IFeelBloated
feisty2 is offline   Reply With Quote
Old 22nd March 2015, 16:55   #7  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 1,036
Quote:
Originally Posted by Reel.Deel View Post
If I'm understating you correctly you're saying that aWarpSharp2(chroma=6) warps the luma first and then uses it to guide the chroma channels? I'm not sure how aWarpSharp2 works internally but I did a little test that confirms the luma channel is simply copied from the input clip when chroma=6.
Code:
original = last
filtered = last.aWarpSharp2(chroma=6)
mt_lutxy(original,filtered, "x y - abs 255 *", u=-128, v=-128)
the luma will copied from the input clip, yes. but I am talking about chroma, and just a wonder, not sure about that
__________________
My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 22nd March 2015, 17:12   #8  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,085
Quote:
Originally Posted by real.finder View Post
the luma will copied from the input clip, yes. but I am talking about chroma, and just a wonder, not sure about that
I tried guiding the chroma multiple ways but I cannot reproduce how aWarpSharp2(chroma=6) does it internally. I cannot get the same output, not even remotely.

With my script with chroma=6 it goes like this: source-->aSobel-->aBlur-->BicubicResize (to scale mask to appropriate dimensions) this edge mask is then used to guide the chroma.

From your first post I thought you meant that aWarpSharp2(chroma=6) does something like this (internally): source-->aWarpSharp2-->aSobel-->aBlur - this edge mask is then used to guide the chroma channels.
Reel.Deel is offline   Reply With Quote
Old 22nd March 2015, 17:54   #9  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 1,036
Quote:
Originally Posted by Reel.Deel View Post
I tried guiding the chroma multiple ways but I cannot reproduce how aWarpSharp2(chroma=6) does it internally. I cannot get the same output, not even remotely.

With my script with chroma=6 it goes like this: source-->aSobel-->aBlur-->BicubicResize (to scale mask to appropriate dimensions) this edge mask is then used to guide the chroma.

From your first post I thought you meant that aWarpSharp2(chroma=6) does something like this (internally): source-->aWarpSharp2-->aSobel-->aBlur - this edge mask is then used to guide the chroma channels.
waiting SEt to know how it work, but anyway, I like it now like this, Yet knowing how the original work is also interesting
__________________
My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 24th March 2015, 14:35   #10  |  Link
zero9999
Registered User
 
Join Date: Oct 2011
Posts: 52
here's a little modification of the script to enable stacked 16-bit support. I've also cleaned it up a bit and added a very minor optimization for yv12+chroma==1.

Requires AVS+ because eval blocks are nasty.

Oh and Reel.Deel, as for the differences you're seing, maybe consider this:
Code:
<_08> uh, line0, just remembered: original awarp uses half depth for chroma
<_08> though depth/3 works better
Edit: fixed for chroma shift and use faster resizer for the mask

Last edited by zero9999; 24th March 2015 at 15:20.
zero9999 is offline   Reply With Quote
Old 30th March 2015, 08:13   #11  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 1,036
according to http://avisynth.nl/images/Colorspace-subsampling.png

I make some changes on the script

Code:
# make aWarpSharp2 work on other planar, for avs 2.6
# v1.33

function aWarpSharp4xx (clip osrc, int "thresh", int "blur", int "type", int "depth", int "chroma", int "cdepth", string "cplace", bool "bic", bool "lsb")
{

lsb    = default(lsb, false)
src = lsb ? osrc.DitherPost(mode=-1) : osrc

depth  = default(depth, 16)
chroma = default(chroma, 4)
cplace = default(cplace, "MPEG2")
cdepth = default(cdepth, IsYV24(src) ? depth : depth/2)
bic    = default(bic, true)

Assert(IsPlanar(src), "aWarpSharp4xx: input clip must be planar YUV")
assert(0 <= chroma <= 6, "aWarpSharp4xx: argument chroma must be an integer between 0 and 6.")  
assert(cplace == "MPEG2" || cplace == "MPEG1", "aWarpSharp4xx: chroma siting must be MPEG2 or MPEG1") 

IsY8(src) || (IsYV12(src) && (chroma == 0 || chroma == 1 || chroma == 2)) ? \
Eval("""
warp   = ConvertToYV12(src).aWarpSharp2(thresh=thresh, blur=blur, type=type, depth=depth, chroma=IsY8(src) ? 1 : chroma)
output = IsY8(src) ? ConvertToY8(warp) : warp
""") : \
Eval("""
y = ConvertToY8(src).ConvertToYV12()
u = UtoY8(src).ConvertToYV12()
v = VtoY8(src).ConvertToYV12()

# warp each channel independently
y_warp = aWarpSharp2(y, thresh=thresh, blur=blur, type=type, depth=depth, chroma=1)
u_warp = aWarpSharp2(u, thresh=thresh, blur=blur, type=type, depth=cdepth, chroma=1)
v_warp = aWarpSharp2(v, thresh=thresh, blur=blur, type=type, depth=cdepth, chroma=1)

# warp chroma by guiding it with the luma edge mask
cshift = IsYV411(src) ? -1.5 : (cplace == "MPEG1" && IsYV12(src)) || IsYV24(src) ? 0 : -0.5
y_mask  = bic ? aSobel(y, thresh=thresh).aBlur(blur=blur, type=type).BicubicResize(u.width(), v.height(), src_left=cshift) : \
aSobel(y, thresh=thresh).aBlur(blur=blur, type=type).BilinearResize(u.width(), v.height(), src_left=cshift)
u_warp2 = aWarp(u, y_mask, depth=cdepth, chroma=1)
v_warp2 = aWarp(v, y_mask, depth=cdepth, chroma=1)

# "fill with zeroes"
blank = BlankClip(u, pixel_type="Y8", color_yuv=$808080)

# luma/chroma processing
output = chroma==0 ||                                      \
         chroma==1 ? YtoUV( blank   , blank   , y_warp ) : \
         chroma==2 ? YtoUV( u       , v       , y_warp ) : \
         chroma==3 ? YtoUV( u_warp  , v_warp  , y_warp ) : \
         chroma==4 ? YtoUV( u_warp2 , v_warp2 , y_warp ) : \
         chroma==5 ? YtoUV( u_warp  , v_warp  , y      ) : \
         chroma==6 ? YtoUV( u_warp2 , v_warp2 , y      ) : \
         src
""")
output8_16 = lsb==true ? output.Dither_convert_8_to_16() : output
y_ld  = chroma < 5 ? 3 : 2
uv_ld = Min(chroma, 3)
Return(lsb==true ? Dither_limit_dif16(osrc, output8_16, thr=1.0, elast=1.5, y=y_ld, u=uv_ld, v=uv_ld) : output8_16)
}
and here http://pastebin.com/aVGgz0f8 the one that will work like original one

and this will be faster http://pastebin.com/09sXzKfa work with last aWarpSharp2
__________________
My Avisynth Stuff

Last edited by real.finder; 28th January 2017 at 09:41.
real.finder is offline   Reply With Quote
Old 30th March 2015, 14:19   #12  |  Link
cretindesalpes
͡҉҉ ̵̡̢̛̗̘̙̜̝̞̟̠͇̊̋̌̍̎̏̿̿
 
cretindesalpes's Avatar
 
Join Date: Feb 2009
Location: No support in PM
Posts: 610
A few months ago I needed a 4:4:4 aWarpSharp2 for my toolchain and wrote a modification to the original plug-in:

awarpsharp2-2015.10.25.zip

I wrote this quickly so I’m not sure everything works well. If the plug-in is reported to work correctly, I’ll post the modification in the official aws2 thread.
__________________
dither 1.27.2 for AviSynth | avstp 1.0.3 for AviSynth development | fmtconv r19 for Vapoursynth | trimx264opt segmented encoding

Last edited by cretindesalpes; 25th October 2015 at 09:33. Reason: Recompiled with MSVC 2013
cretindesalpes is offline   Reply With Quote
Old 30th March 2015, 14:35   #13  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,085
Time for an update! See 1st post.
  • Add "depthC" parameter, independent depth for chroma, if this value is not specified it defaults to depth/2, except in YV24 where it defaults to just depth. Idea borrowed from _08.
  • Add "cplace" parameter, chroma placement, "MPEG2" for DVD, Blu-ray, web videos and just about any other 'consumer format'. "MPEG1" for some JPGs, MJPEG, and anything else that might use it .
  • Add "lsb" parameter, 16-bit processing - true: if input clip is stack16, false: input clip is a regular 8-bit clip. Output will always be the same format as the input. Dither is now required.
  • Luma mask used to warp chroma is now resized with BilinearResize.
  • YV12 optimization: if "chroma" does not equal 4 or 6 and cplace="MPEG1" then use aWarpSharp2 directly.
  • Note: chroma warp/output is different than aWarpSharp2 (really only when using chroma=4 or 6), I personally prefer aWarpSharp4xx. real.finder also showed me some examples where aWarpSharp4xx is indeed better but as always YMMV.
  • For those who use AviSynth+, script can be found here.
If you find any bugs or if you have any suggestions and or comments please don't hesitate.

Big thanks to line0 for all the help!

Quote:
Originally Posted by cretindesalpes View Post
A few months ago I needed a 4:4:4 aWarpSharp2 for my toolchain and wrote a modification to the original plug-in:

awarpsharp2-2015.01.29.zip

I wrote this quickly so Iím not sure everything works well. If the plug-in is reported to work correctly, Iíll post the modification in the official aws2 thread.
Thank you very much cretindesalpes! Will definitely test it out!

Last edited by Reel.Deel; 30th March 2015 at 18:53. Reason: corections
Reel.Deel is offline   Reply With Quote
Old 30th March 2015, 17:48   #14  |  Link
TheSkiller
Registered User
 
Join Date: Dec 2007
Location: Germany
Posts: 637
Thanks for the update. Not being limited to YV12 when you're working with a lossless analog 4:2:2 capture – and even stack16 support – is really a relief.


Quote:
Originally Posted by Reel.Deel View Post
"MPEG1" for some JPGs, DV, and anything else that might use it .
Wait! DV does not use MPEG1 chroma placement. It uses it's own placement where Cb and Cr samples (for interlaced PAL DV) are vertically placed between luma samples by half a luma pixel. Where for interlaced MPEG2 the placing has different offsets for both fields (don't know the numbers though).
TheSkiller is offline   Reply With Quote
Old 30th March 2015, 18:49   #15  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,085
Quote:
Originally Posted by TheSkiller View Post
Wait! DV does not use MPEG1 chroma placement.
You're indeed correct, must of been too early in the morning .
I don't know too much about interlaced chroma placement and I don't think many people use DV nowadays anyways. Regardless this script is meant for progressive input only.

Edit: reel.finder added this: cshift = IsYV411(src) ? 1.5
src_left=1.5, would that be correct for progressive DV (NTSC)?

Last edited by Reel.Deel; 30th March 2015 at 19:01.
Reel.Deel is offline   Reply With Quote
Old 27th September 2015, 17:29   #16  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,085
Quote:
Originally Posted by cretindesalpes View Post
A few months ago I needed a 4:4:4 aWarpSharp2 for my toolchain and wrote a modification to the original plug-in:

awarpsharp2-2015.01.29.zip

I wrote this quickly so Iím not sure everything works well. If the plug-in is reported to work correctly, Iíll post the modification in the official aws2 thread.
I see you only mentioned YV24, does it work correctly with the other planar colorspaces also? I tried with YV16 and didn't notice anything wrong but I just wanna be sure.
Reel.Deel is offline   Reply With Quote
Old 27th September 2015, 21:44   #17  |  Link
cretindesalpes
͡҉҉ ̵̡̢̛̗̘̙̜̝̞̟̠͇̊̋̌̍̎̏̿̿
 
cretindesalpes's Avatar
 
Join Date: Feb 2009
Location: No support in PM
Posts: 610
4:1:1 is not supported.
__________________
dither 1.27.2 for AviSynth | avstp 1.0.3 for AviSynth development | fmtconv r19 for Vapoursynth | trimx264opt segmented encoding
cretindesalpes is offline   Reply With Quote
Old 24th October 2015, 18:35   #18  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 1,036
Quote:
Originally Posted by cretindesalpes View Post
A few months ago I needed a 4:4:4 aWarpSharp2 for my toolchain and wrote a modification to the original plug-in:

awarpsharp2-2015.01.29.zip

I wrote this quickly so I’m not sure everything works well. If the plug-in is reported to work correctly, I’ll post the modification in the official aws2 thread.
Code:
ColorBars(width=720, height=480, pixel_type="RGB32")
ConvertToYV12()
aWarpSharp2()
I got in avspmod

Code:
Traceback (most recent call last):
  File "avsp.pyo", line 9061, in OnMenuVideoToggle
  File "avsp.pyo", line 13855, in ShowVideoFrame
  File "avisynth.pyo", line 462, in GetFrame
WindowsError: exception: access violation reading 0xFFFFFFFF
__________________
My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 24th October 2015, 23:56   #19  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 1,036
I edit this post http://forum.doom9.org/showpost.php?...03&postcount=2

aWarpSharp4xx(type=0,cplace="mpeg1") in yv12 will be like aWarpSharp2()

so this mean that aWarpSharp2 warp in mpeg1 right? Is the cretindesalpes aWarpSharp2 fix this?
__________________
My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 25th October 2015, 09:37   #20  |  Link
cretindesalpes
͡҉҉ ̵̡̢̛̗̘̙̜̝̞̟̠͇̊̋̌̍̎̏̿̿
 
cretindesalpes's Avatar
 
Join Date: Feb 2009
Location: No support in PM
Posts: 610
real.finder:

I could reproduce the bug once, but after upgrading the projects to MSVC 2013 and recompiling it, I couldn’t show it anymore. So I updated the version in my previous post. Could you try it again?

And regarding your second question, yes, awarpsharp2 uses MPEG-1 chroma placement, and no, I didn’t fix anything about this issue.
__________________
dither 1.27.2 for AviSynth | avstp 1.0.3 for AviSynth development | fmtconv r19 for Vapoursynth | trimx264opt segmented encoding
cretindesalpes is offline   Reply With Quote
Reply

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 19:12.


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