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 Development

Reply
 
Thread Tools Search this Thread Display Modes
Old 18th February 2017, 21:28   #1  |  Link
pinterf
Registered User
 
Join Date: Jan 2014
Posts: 928
MaskTools2 - pfmod

MaskTools2, high bit depth support.

Forked from tp7's masktools2 repository.
Thanks to all earlier contributors.

Get the latest release from here

This fork incorporates tp7's abandoned initial work on 16 bit support (using stacked and interleaved 8 bit hacks back in 2013), which he has never released, but proved to be an invaluable help with my initial steps porting this basic plugin.

All filters are available for all bit depths. Avisynth+ color spaces with alpha (YUVA/RGBA) are not supported. XP version does not support mt_polish.

This release may have benefits for 8 bit users as well, see change log.

As always, report back bugs, regressions. Thank you.

Useful links:

Masktools2 info:
http://avisynth.nl/index.php/MaskTools2

Article by tp7
http://tp7.github.io/articles/masktools/

Project:
https://github.com/pinterf/masktools/tree/16bit/

Original version: tp7's MaskTools 2 repository.
https://github.com/tp7/masktools/

Masktools 2.0.a48 forum:
https://forum.doom9.org/showthread.php?t=98985

Last edited by pinterf; 2nd February 2018 at 11:02. Reason: new release
pinterf is offline   Reply With Quote
Old 18th February 2017, 21:52   #2  |  Link
Sparktank
47.952fps@71.928Hz
 
Sparktank's Avatar
 
Join Date: Mar 2011
Posts: 819
Amazing stuff! Thanks for the continued work on all the recent projects
__________________
Win10 (x64) | GPU Caps Viewer v1.38.2.1
Crucial M500 240GB SSD | Kingston SSDNow V300 (Marvell) 120GB | NVIDIA GeForce GTX 750 Ti 2GB | 391.01 (2-23-2018)
NTSC | DVD: R1 | BD: A
Sparktank is offline   Reply With Quote
Old 18th February 2017, 23:02   #3  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 979
Thanks

so we will need edit all old scripts that has lut for > 8 bit now (adding the new syntax)? or not?
__________________
My Avisynth Stuff

Last edited by real.finder; 18th February 2017 at 23:04.
real.finder is offline   Reply With Quote
Old 19th February 2017, 10:19   #4  |  Link
pinterf
Registered User
 
Join Date: Jan 2014
Posts: 928
There is no intuitive way deciding whether a constant is scalable or not.
I checked the idea on the examples here: http://avisynth.nl/index.php/MaskTools2/mt_lutspa
At some samples I could not tell for the first sight with 100% confidence which constants are to scale and which are not. An averager /2 is surely not scalable.
pinterf is offline   Reply With Quote
Old 19th February 2017, 11:00   #5  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 979
Quote:
Originally Posted by pinterf View Post
There is no intuitive way deciding whether a constant is scalable or not.
I checked the idea on the examples here: http://avisynth.nl/index.php/MaskTools2/mt_lutspa
At some samples I could not tell for the first sight with 100% confidence which constants are to scale and which are not. An averager /2 is surely not scalable.
The changes log are not clear for me, did you added new bitdepth parameter? and what the default of it? 8 bit?
__________________
My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 19th February 2017, 11:05   #6  |  Link
pinterf
Registered User
 
Join Date: Jan 2014
Posts: 928
Quote:
Originally Posted by real.finder View Post
The changes log are not clear for me, did you added new bitdepth parameter? and what the default of it? 8 bit?
You don't have to provide it, it is automatically passed when the expression is evaluated. It is used internally in #B and #F but you can check for it using variable name 'bitdepth'
pinterf is offline   Reply With Quote
Old 19th February 2017, 11:13   #7  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 979
Quote:
Originally Posted by pinterf View Post
You don't have to provide it, it is automatically passed when the expression is evaluated. It is used internally in #B and #F but you can check for it using variable name 'bitdepth'
I already get the idea of #B and #F, but my point is for the script that already existing which don't has #B and #F or any thing for bit depth, how will they work in more than 8 bit?
__________________
My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 19th February 2017, 11:32   #8  |  Link
pinterf
Registered User
 
Join Date: Jan 2014
Posts: 928
Existing 8 bit scripts will work as the expression arithmetic says and they will be incorrect on higher bit depths, unless you do only and "x y + 2 /" which means the same (x+y)/2 for all formats. So if you don't take care of the constants, it won't give proper results.

If you subtract N, it will subtract exactly N, even if N=128 and you know that in 8 bit world it means the half range. But in 16 bit this 128 can be a rounder or anything that is meant to be exactly 128.

I think we have no reason to intuitively guess from a constant that it should be scaled or not.
pinterf is offline   Reply With Quote
Old 19th February 2017, 11:43   #9  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 979
Quote:
Originally Posted by pinterf View Post
Existing 8 bit scripts will work as the expression arithmetic says and they will be incorrect on higher bit depths
so, that mean we will need to edit most existing scripts
__________________
My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 19th February 2017, 12:03   #10  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 979
another thing, let say that we want to write in 16 bit or float for some reason and in the same time we want it to work in 8 bit or 10 bit etc... too
__________________
My Avisynth Stuff

Last edited by real.finder; 20th February 2017 at 00:23.
real.finder is offline   Reply With Quote
Old 20th February 2017, 07:54   #11  |  Link
yup
Registered User
 
Join Date: Feb 2003
Location: Russia, Moscow
Posts: 854
Hi pinterf!

Please explain, all filter from Your rewritten plugin MT_NICE_FILTER?
Where I can find ready to use list? For example QTGMC script use a lot of function and any could declared before use (for better performance).
I think that if filter MT_NICE_FILTER one will be work better if declared like MT_NICE_FILTER, but not default MT_MULTI_INSTANCE.

yup.
yup is offline   Reply With Quote
Old 20th February 2017, 08:11   #12  |  Link
pinterf
Registered User
 
Join Date: Jan 2014
Posts: 928
They are auto registering themselves as nice filter.
EDIT:
info added to the first page

Last edited by pinterf; 20th February 2017 at 09:05.
pinterf is offline   Reply With Quote
Old 20th February 2017, 08:49   #13  |  Link
yup
Registered User
 
Join Date: Feb 2003
Location: Russia, Moscow
Posts: 854
pinterf!
Quote:
Originally Posted by pinterf View Post
They are auto registering themselves as nice filter.
And no need additional commands for this? All work from box?

yup.
yup is offline   Reply With Quote
Old 20th February 2017, 08:55   #14  |  Link
DJATOM
Registered User
 
Join Date: Sep 2010
Location: Ukraine, Bohuslav
Posts: 87
Quote:
Originally Posted by yup View Post
pinterf!

And no need additional commands for this? All work from box?

yup.
Yes, if filter is registering himself, your mt setting will be ignored unless you'll force it (force=true).
DJATOM is offline   Reply With Quote
Old 20th February 2017, 09:10   #15  |  Link
pinterf
Registered User
 
Join Date: Jan 2014
Posts: 928
Quote:
Originally Posted by real.finder View Post
another thing, let say that we want to write in 16 bit or float for some reason and in the same time we want it to work in 8 bit or 10 bit etc... too
We are at the very beginning of these questions, so you'd like an easy way to tell the expression evaluator the default bit depth of the used constants, which is now 8 bits to help the relatively painless transition of the next years.
And the autoscaler would take it into account, and it scaled up and down the numbers if the default bitdepth for scaling is e.g. set to 16 bit instead of 8

EDIT:
maybe the expression string would contain control mnemonics at the beginning, hinting the default bitdepth of the scalable constants if they are not meant to be 8-bit base.
e.g. expr = "i16 x 32768 #B -" where "i16" (in general: i8/i10/i12/i14/i16 for integer formats or f32 for 32 bit float) hints the expression evaluator that the base bit depth of the scalable constants is 16 bits and has to scale it accordingly with the #B or #F operator?

Last edited by pinterf; 20th February 2017 at 21:05.
pinterf is offline   Reply With Quote
Old 22nd February 2017, 14:29   #16  |  Link
kgrabs
Registered User
 
Join Date: Jan 2017
Posts: 26
Wow, thanks a lot for this! Just having the luts is fantastic, it's really a great thing you've got here

I tried porting over Dehalo_alpha but after about 2 hours it seemed to be a little beyond me. It looks kinda like Dehalo_alpha(darkstr=100, brightstr=100).
I'll post my (incorrect) work if someone feels like figuring it out, and to make it easier the mt_lutxy expressions of the original Dehalo_Alpha, via mt_infix, too:



Code:
#gives incorrect output
#assumes stack16 input
Function DeHalo_Alpha16(clip input, float "rx", float "ry", float "darkstr", float "brightstr", float "lowsens", float "highsens", float "ss", int "srad", bool "cs", bool "uv")
{
rx        = default( rx,        2.0 )
ry        = default( ry,        2.0 )
darkstr   = default( darkstr,   1.0 )
brightstr = default( brightstr, 1.0 )
lowsens   = default( lowsens,    50 )
highsens  = default( highsens,   50 )
ss        = default( ss,        1.5 )
srad      = default( srad,        1 ) # srad=3 is DeHalo_Alpha_2BD
cs        = default( cs,      false )
uv        = default( uv,       true )

assumeY = IsY(input)

clps = assumeY ? input
\	       : input.ConvertToY()
clp = clps.ConvertFromStacked(bits=16)

LOS = string(lowsens)
HIS = string(highsens/100.0)
DRK = string(darkstr * 256.0)
BRT = string(brightstr * 256.0)
ox  = input.width()
oy  = input.height()/2
ssx = Round(ox*ss)
ssy = Round(oy*ss)
dsx = Round(ox/rx)
dsy = Round(oy/ry)

halos  = clps.dither_resize16(dsx,dsy,kernel="bicubic",U=1,V=1).dither_resize16(ox,oy,1,0,kernel="bicubic",U=1,V=1).ConvertFromStacked(bits=16)
are    = mt_lutxy(clp.DHA16_expand(srad),clp.DHA16_inpand(srad),"x y -",U=1,V=1)
ugly   = mt_lutxy(halos.DHA16_expand(srad),halos.DHA16_inpand(srad),"x y -",U=1,V=1)
so     = mt_lutxy(ugly, are, "y x - y 0.256 + / 65535 * "+LOS+" - y 65535 + 131070 / "+HIS+" + *",U=1,V=1)
lets   = mt_merge(halos,clp,so,U=1,V=1)
remove = (ss==1.0) ? clps.dither_repair16(lets.ConvertToStacked(), 1, -1, -1).ConvertFromStacked(bits=16)
          \        : clps.dither_resize16(ssx,ssy,kernel="lanczos",taps=3,U=1,V=1).ConvertFromStacked(bits=16)
          \              .mt_logic(lets.mt_expand(U=1,V=1).ConvertToStacked().dither_resize16(ssx,ssy,kernel="bicubic",U=1,V=1).ConvertFromStacked(bits=16),"min",U=1,V=1)
          \              .mt_logic(lets.mt_inpand(U=1,V=1).ConvertToStacked().dither_resize16(ssx,ssy,kernel="bicubic",U=1,V=1).ConvertFromStacked(bits=16),"max",U=1,V=1)
          \              .ConvertToStacked().dither_resize16(ox,oy,kernel="lanczos",taps=3,U=1,V=1).ConvertFromStacked(bits=16)
them   = mt_lutxy(clp,remove,"x y < x x y - "+DRK+" * - x x y - "+BRT+" * - ?",U=1,V=1).ConvertToStacked()
them   = cs ? them.DHA16_contrasharp16(clps) : them
return  assumeY ? them : uv ? ytouv(DHA16_utoy(input), DHA16_vtoy(input), them)
\			    : them.DHA16_ConvertToX(input)
}

Function DHA16_utoy(clip c){
try {
   utoy(c)
	} catch ( error_msg ) {
	   utoy8(c)
	}
}
Function DHA16_vtoy(clip c){
try {
   vtoy(c)
	} catch ( error_msg ) {
	   vtoy8(c)
	}
}
Function DHA16_ConvertToX(clip output, clip input){return Is420(input) ? output.ConvertToYUV420() : Is422(input) ? output.ConvertToYUV422(): Is444(input) ? output.ConvertToYUV444() : output.ConvertToYV411()}
function DHA16_contrasharp16(clip after, clip before){return after.Dither_add16(Dither_sub16(after, after.Dither_RemoveGrain16(mode=11, modeU=-1, modeV=-1), U=1, V=1, dif=true).Dither_Repair16(Dither_sub16(before, after, U=1, V=1, dif=true), mode=13, modeU=-1, modeV=-1), U=1, V=1, dif=true)}
function DHA16_expand(clip c, int expand){return expand > 0 ? DHA16_expand(c.mt_expand(U=1, V=1), expand-1) : c}
function DHA16_inpand(clip c, int inpand){return inpand > 0 ? DHA16_inpand(c.mt_inpand(U=1, V=1), inpand-1) : c}

Last edited by kgrabs; 22nd February 2017 at 14:53. Reason: meesed up the Y8 input
kgrabs is offline   Reply With Quote
Old 22nd February 2017, 16:11   #17  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 979
Quote:
Originally Posted by kgrabs View Post
I tried porting over Dehalo_alpha but after about 2 hours it seemed to be a little beyond me. It looks kinda like Dehalo_alpha(darkstr=100, brightstr=100).
I'll post my (incorrect) work if someone feels like figuring it out, and to make it easier the mt_lutxy expressions of the original Dehalo_Alpha, via mt_infix, too:

I already intend to port dehalo_alpha and other scripts but wait for pinterf to made the final decisions, no need to hurry
__________________
My Avisynth Stuff
real.finder is offline   Reply With Quote
Old 22nd February 2017, 16:29   #18  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 979
Quote:
Originally Posted by pinterf View Post
We are at the very beginning of these questions, so you'd like an easy way to tell the expression evaluator the default bit depth of the used constants, which is now 8 bits to help the relatively painless transition of the next years.
And the autoscaler would take it into account, and it scaled up and down the numbers if the default bitdepth for scaling is e.g. set to 16 bit instead of 8

EDIT:
maybe the expression string would contain control mnemonics at the beginning, hinting the default bitdepth of the scalable constants if they are not meant to be 8-bit base.
e.g. expr = "i16 x 32768 #B -" where "i16" (in general: i8/i10/i12/i14/i16 for integer formats or f32 for 32 bit float) hints the expression evaluator that the base bit depth of the scalable constants is 16 bits and has to scale it accordingly with the #B or #F operator?
why just not add new exprBit parameter? with 8 bit default

edit: but your one is ok too
__________________
My Avisynth Stuff

Last edited by real.finder; 22nd February 2017 at 16:42.
real.finder is offline   Reply With Quote
Old 23rd February 2017, 15:07   #19  |  Link
pinterf
Registered User
 
Join Date: Jan 2014
Posts: 928
New release, full high bit depth support (10-16, float) for all filters, new flavour in expression syntax.

For details, see first post.

Enjoy Masktools2 v2.2.2 (20170223)

Change list from v2.2.1

Code:
-All filters work in 10,12,14,16 bits and float (except mt_logic which is 8-16 only)
- mt_lutxyza 4D lut available with realtime=false!
(4 GBytes LUT table, slower initial lut table calculation) 
Allowed only on x64. Be warned, it would take minutes.
- mt_gradient 10-16 bit / float
- mt_convolution 10-16 bit / float
- mt_motion 10-16 bit / float
- mt_xxpand and mt_xxflate to float
- mt_clamp to float
- mt_merge to float
- mt_binarize to float
- mt_invert to float
- mt_makediff and mt_adddiff to float
- mt_average to float
- Expression syntax supporting bit depth independent expressions: 
Added configuration keywords i8, i10, i12, i14, i16 and f32 in order to inform the 
expression evaluator about bit depth of the values that are to scale by #B and #F operators.
pinterf is offline   Reply With Quote
Old 23rd February 2017, 17:55   #20  |  Link
real.finder
Registered User
 
Join Date: Jan 2012
Location: Mesopotamia
Posts: 979
ok, just did small port to DeHalo_alpha, I think we need IsVideoFloat() in avs+

Code:
# 2017.02.25 1st release
# DeHalo_alpha with high bit support (now only up to 16, no float yet), need masktools 2.2.2, avs25 dropped by now
# modified dehalo_alpha: here with increased search-radius for validation

function DeHalo_alpha_2BD(clip input, float "rx", float "ry", float "darkstr", float "brightstr", float "lowsens", float "highsens", float "ss", bool "cs", int "search_rade", int "search_radi")
{
rx        = default( rx,        2.0 )
ry        = default( ry,        2.0 )
darkstr   = default( darkstr,   1.0 )
brightstr = default( brightstr, 1.0 )
lowsens   = default( lowsens,    50 )
highsens  = default( highsens,   50 )
ss        = default( ss,        1.5 )
cs        = default( cs,      false )
sre       = default( search_rade,  max(round(max(rx,ry)),3) )
sri       = default( search_radi, sre )

ssispmt   = Findstr(VersionString(), "AviSynth+") != 0 && Findstr(VersionString(), "r1576") == 0

sislumaonly = ssispmt ? input.isy() : input.isy8()

clp = sislumaonly ? input : ssispmt ? input.converttoy() : input.converttoy8()

LOS = string(lowsens)
HIS = string(highsens/100.0)
DRK = string(darkstr)
BRT = string(brightstr)
ox  = clp.width()
oy  = clp.height()

halos  = clp.bicubicresize(round(ox/rx),round(oy/ry)).bicubicresize(ox,oy,1,0)
are    = mt_lutxy(clp  .srdha2e(sre,1),clp  .srdha2i(sri,1),"x y -",U=1,V=1)
ugly   = mt_lutxy(halos.srdha2e(sre,1),halos.srdha2i(sri,1),"x y -",U=1,V=1)
so     = mt_lutxy( ugly, are, "y x - y 0.001 #F + / range_max * "+LOS+" #F - y range_size + 512 #F / "+HIS+" + *" )
lets   = mt_merge(halos,clp,so,U=1,V=1)
remove = (ss==1.0) ? clp.repair(lets,1,0) 
          \        : clp.lanczosresize(round(ox*ss),round(oy*ss))
          \             .mt_logic(lets.mt_expand(U=1,V=1).bicubicresize(round(ox*ss),round(oy*ss)),"min",U=2,V=2)
          \             .mt_logic(lets.mt_inpand(U=1,V=1).bicubicresize(round(ox*ss),round(oy*ss)),"max",U=2,V=2)
          \             .lanczosresize(ox,oy)
them   = mt_lutxy(clp,remove,"x y < x x y - "+DRK+" * - x x y - "+BRT+" * - ?",U=2,V=2)

bb   = cs ? them.removegrain(11) : nop()
xD   = cs ? mt_makediff(bb,bb.repair(bb.repair(bb.medianblur(2,-333,-333),1),1)).mt_lut("x range_half - 2.49 #F * range_half +") : nop()
xDD  = cs ? mt_lutxy(xD,mt_makediff(clp,them),"x range_half - y range_half - * 0 < range_half x range_half - abs y range_half - abs < x y ? ?") : nop()
them = cs ? them.mt_adddiff(xDD,U=2,V=2) : them

them   = sislumaonly ? them : ssispmt ? CombinePlanes(them,input,planes="YUV",sample_clip=input) : ytouv(input.utoy8(),input.vtoy8(),them)

return( them )
}

Function srdha2e(clip i, int dr_rad, int count)
{
return count > dr_rad ? i : srdha2e(i.mt_expand(), dr_rad, count+1)
}

Function srdha2i(clip i, int dr_rad, int count)
{
return count > dr_rad ? i : srdha2i(i.mt_inpand(), dr_rad, count+1)
}
__________________
My Avisynth Stuff

Last edited by real.finder; 26th February 2017 at 00:38.
real.finder 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 10:11.


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