Advertisement
Guest User

Advanced Denoising

a guest
Jul 21st, 2019
156
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Advanced Denoising and anime bob v1.62
  2.  
  3. # MotionThresh by mf, mod by A.SONY
  4. # Simple scenechange-proof motion threshold
  5. # Tile outputs 16x16 clip for speed
  6. # Use tile=true for conditional filtering, tile=false for masking
  7.  
  8. function MotionThresh(clip motinc, float thresh, bool "tile", bool "fast", int "cache") {
  9. fast = Default(fast, false)
  10. tile = Default(tile,  fast)
  11. cache= default(cache,10)
  12.  
  13. sisphbd = AvsPlusVersionNumber > 2294
  14.  
  15. sislumaonly = !(VersionNumber() < 2.60) ? sisphbd ? motinc.isy() : motinc.isy8() : nop()
  16.  
  17. motinc = fast && !sislumaonly ? sisphbd ? motinc.converttoy() : motinc.converttoy8() : motinc
  18. black  = !fast ? BlankClip(motinc, width=16, height=16               ) : BlankClip(motinc, width=16, height=16, Color_yuv=color_black)
  19. white  = !fast ? BlankClip(motinc, width=16, height=16, color=$FFFFFF) : BlankClip(motinc, width=16, height=16, Color_yuv=color_white)
  20. cond1  = fast ? nop() : ConditionalFilter(motinc, white, black, "YDifferenceFromPrevious()", "greaterthan", String(thresh))
  21. cond2  = fast ? nop() : ConditionalFilter(motinc, white, black, "YDifferenceToNext()", "greaterthan", String(thresh))
  22. fast ? eval("""
  23. global MotionThreshblack = black
  24. global MotionThreshthresh = thresh
  25. global MotionThreshmotinc = motinc
  26. global mtcav=0
  27. global mtnav=0
  28. """) : nop()
  29. fast ? white.ScriptClip("""
  30. MotionThreshwhite = last
  31. motinc = MotionThreshmotinc
  32. cfr=current_frame
  33.  
  34. mtpav=cfr<3 ? 0 : mtcav
  35. global mtcav=cfr<2 ? 0 : mtnav
  36. global mtnav=motinc.trim(1,0).AverageLuma()
  37.  
  38. cond1 = abs(mtcav-mtpav) > MotionThreshthresh ? MotionThreshwhite : MotionThreshblack
  39. cond2 = abs(mtcav-mtnav) > MotionThreshthresh ? MotionThreshwhite : MotionThreshblack
  40. Overlay(cond1, cond2, mode="darken")
  41. """) : nop()
  42. fast ? last : Overlay(cond1, cond2, mode="darken")
  43. tile ? last : Eval("try { PointResizemt(motinc.width, motinc.height) } catch(error_msg) { PointResize(motinc.width, motinc.height) }")
  44. fast ? cache<0 ? last : last.RequestLinear(8, cache, 5, false, false) : last
  45. }
  46.  
  47.  
  48. ######################################################################
  49. # MotionRamp by mf, mod for speed by A.SONY
  50. # Average motion soft-thresholding based on 5 thresholds
  51. # Dependancies: MotionThresh, ParameterisedBlend or Average if avs is 2.6 or up
  52.  
  53. function MotionRamp(clip morinc, int thresh1, int thresh2, int thresh3, int thresh4, int thresh5, int "min", int "max", int "floor", int "ceil", int "radius", bool "tile", bool "fast", int "cache") {
  54. min = Default(min, 0)
  55. max = Default(max, 255)
  56. floor = Default(floor, 0)
  57. ceil  = Default(ceil, 255)
  58. radius = Default(radius, 2)
  59. fast = Default(fast, false)
  60. tile = Default(tile,  fast)
  61. cache= default(cache,10)
  62.  
  63. sisphbd = AvsPlusVersionNumber > 2294
  64.  
  65. sislumaonly = fast ? sisphbd ? morinc.isy() : morinc.isy8() : false
  66.  
  67. fast && !(VersionNumber() < 2.60) && !sislumaonly ? sisphbd ? morinc.converttoy() : morinc.converttoy8() : morinc
  68.  
  69. fast ? eval("""
  70. white = BlankClip(last, width=16, height=16, Color_yuv=color_white)
  71. global MotionThreshblack = BlankClip(last, width=16, height=16, Color_yuv=color_black)
  72. global MotionThreshthresh1 = thresh1
  73. global MotionThreshthresh2 = thresh2
  74. global MotionThreshthresh3 = thresh3
  75. global MotionThreshthresh4 = thresh4
  76. global MotionThreshthresh5 = thresh5
  77. global MotionThreshmorinc = last
  78. global mtnav=0
  79. """) : last
  80. fast ? white.ScriptClip("""
  81. morinc = MotionThreshmorinc
  82. MotionThreshwhite = last
  83. cfr=current_frame
  84.  
  85. mtpav=cfr<1 ? 0 : mtnav
  86. global mtnav=morinc.YDifferenceToNext()
  87.  
  88. cond11 = mtpav > MotionThreshthresh1 ? MotionThreshwhite : MotionThreshblack
  89. cond21 = mtnav > MotionThreshthresh1 ? MotionThreshwhite : MotionThreshblack
  90. c1=Overlay(cond11, cond21, mode="darken")
  91.  
  92. cond12 = mtpav > MotionThreshthresh2 ? MotionThreshwhite : MotionThreshblack
  93. cond22 = mtnav > MotionThreshthresh2 ? MotionThreshwhite : MotionThreshblack
  94. c2=Overlay(cond12, cond22, mode="darken")
  95.  
  96. cond13 = mtpav > MotionThreshthresh3 ? MotionThreshwhite : MotionThreshblack
  97. cond23 = mtnav > MotionThreshthresh3 ? MotionThreshwhite : MotionThreshblack
  98. c3=Overlay(cond13, cond23, mode="darken")
  99.  
  100. cond14 = mtpav > MotionThreshthresh4 ? MotionThreshwhite : MotionThreshblack
  101. cond24 = mtnav > MotionThreshthresh4 ? MotionThreshwhite : MotionThreshblack
  102. c4=Overlay(cond14, cond24, mode="darken")
  103.  
  104. cond15 = mtpav > MotionThreshthresh5 ? MotionThreshwhite : MotionThreshblack
  105. cond25 = mtnav > MotionThreshthresh5 ? MotionThreshwhite : MotionThreshblack
  106. c5=Overlay(cond15, cond25, mode="darken")
  107.  
  108. VersionNumber() < 2.6 ? Interleave(c3, c2, c4, c1, c5).ParameterisedBlend(0.20, 0.20, 0.20, 0.20, 0.20, gamma=1, scaleweights=false).SelectEvery(5,0) : Average(c3, 0.20, c2, 0.20, c4, 0.20, c1, 0.20, c5, 0.20)
  109. """) : VersionNumber() < 2.6 ? Interleave(MotionThresh(thresh3, tile=true), MotionThresh(thresh2, tile=true), MotionThresh(thresh4, tile=true), MotionThresh(thresh1, tile=true), MotionThresh(thresh5, tile=true)).ParameterisedBlend(0.20, 0.20, 0.20, 0.20, 0.20, gamma=1, scaleweights=false).SelectEvery(5,0) : \
  110.                                Average(MotionThresh(thresh3, tile=true), 0.20, MotionThresh(thresh2, tile=true), 0.20, MotionThresh(thresh4, tile=true), 0.20, MotionThresh(thresh1, tile=true), 0.20, MotionThresh(thresh5, tile=true), 0.20)
  111. fast ? cache<0 ? last : last.RequestLinear(8, cache, 5, false, false) : last
  112. TemporalSoften(radius,255,0,255,2)
  113. fast ? last : Levels(floor, 1, ceil, min, max)
  114. fast ? last : ColorYUV(levels="TV->PC")
  115. tile ? last : Eval("try { PointResizemt(morinc.width, morinc.height) } catch(error_msg) { PointResize(morinc.width, morinc.height) }")
  116. }
  117.  
  118.  
  119. ##########
  120. function admfilter(clip oin, bool "mc", float "f", bool "DarkPreserve", float "rStr", float "amp", bool "lsb", bool "lsb_in", bool "lsb_out", bool "luma_rebuild", bool "u", bool "v", string "pp", string "dfttest_params", string "mcdfttest_params", string "custom_filter", clip "MotionRampadc", bool "mcf", clip "ppsuper", clip "super", clip "exmcclip") {
  121. d = default (DarkPreserve      , true)
  122. mc = default (mc      , true)
  123. sisphbd = AvsPlusVersionNumber > 2294
  124. f = Default(f, 16.0)
  125. lsb = default (lsb, sisphbd ? oin.BitsPerComponent() > 8 ? false : true : true)
  126. lsb_in = default (lsb_in      , false)
  127. oin8 = lsb_in ? oin.ditherpost(mode=7,slice=false,u=u ? 3 : 1,v=v ? 3 : 1) : oin
  128.     ox = oin8.width()
  129.     oy = oin8.height()
  130.     HD = (ox > 1099 || oy > 599)
  131. lsb_out = default (lsb_out      , lsb_in)
  132. lsb = lsb_in || lsb_out ? true : lsb
  133. luma_rebuild = default (luma_rebuild      , true)
  134. u = default (u      , true)
  135. v = default (v      , true)
  136. exmc = defined(exmcclip)
  137. mcf = default (mcf, exmc)
  138. dfttest_params = default(dfttest_params, "")
  139. mcdfttest_params = default(mcdfttest_params, "")
  140. pp = default (pp, "blur(1.53)")
  141.  
  142. pel = HD ? 1 : 2
  143.  
  144. super = defined(super) ? super : oin8.MSuper(pel=pel, levels=1, chroma=(U || V))
  145. ppsu = defined(ppsuper) ? ppsuper : oin8.spp_super(pp=oin8.Eval(pp),rStr=rStr,amp=amp,lsb_in=lsb_in,luma_rebuild=luma_rebuild,u=u,v=v,hd=hd)
  146. exmcclip = mcf ? exmc ? exmcclip : oin8.sMCclips(ppsu,super,hd=hd) : nop()
  147.  
  148. custom_filter = defined(custom_filter) ? custom_filter : \
  149.                             mcf ? "dfttestmc(pp=oin8,lsb=lsb, Sigma=adSigma+1.0/f,lsb_in=lsb_in,u=u,v=v,slices=false,super=super,input8=oin8,hd=hd,exmcclip=exmcclip,dfttest_params=dfttest_params" + mcdfttest_params + ")" : \
  150.                                                          mc ? "dfttestmc(pp=Eval(pp),lsb=lsb, Sigma=adSigma+1.0/f,rStr=rStr,amp=amp,lsb_in=lsb_in,luma_rebuild=luma_rebuild,u=u,v=v,dfttest_params=dfttest_params" + mcdfttest_params + ")" : \
  151.                                                               "dfttest(lsb=lsb, Sigma=adSigma+1.0/f, lsb_in=lsb_in,u=u,v=v" + dfttest_params + ")"
  152.  
  153. oin
  154. MotionRampadc = defined(MotionRampadc) ? MotionRampadc : last.MotionRamp(5,10,15,20,25,Max=255,fast=True)
  155. lsb_out && !lsb_in ? Dither_convert_8_to_16() : lsb_in && !lsb_out ? Ditherpost(mode=-1, y=1, u=1,v=1) : last
  156. return GScriptClip("""
  157.                     adfloat = AverageLuma(MotionRampadc)
  158.                     adSigmb = sisphbd ? BitsPerComponent() > 8 ? BitsPerComponent() == 10 ? 4 : BitsPerComponent() == 12 ? 8 : BitsPerComponent() == 14 ? 64 : nop() : nop() : nop()
  159.                     adSigma = sisphbd ? isvideofloat() ? adfloat*255.0 : BitsPerComponent() > 8 ? BitsPerComponent() < 16 ? adfloat/adSigmb : sqrt(adfloat) : adfloat : adfloat
  160.                     (lsb_out && !lsb_in) || (lsb_in && !lsb_out) ? oin : last
  161.                     adden = Eval(custom_filter)
  162.                     d ? DarkPreserve_function(filtered=adden, original=last, u=u ? 3 : 4, v=v ? 3 : 4, lsb=lsb, lsb_in=lsb_in, lsb_out=lsb_out) : adden
  163.                     !d && !lsb_out && lsb ? Ditherpost(mode=7, slice=false) : last
  164.                     """, args="MotionRampadc, f, d, rStr, amp, lsb_in, lsb_out, lsb, luma_rebuild, u, v,dfttest_params,mcdfttest_params,pp,oin,custom_filter,sisphbd,super,oin8,hd,exmcclip")
  165. }
  166.  
  167.  
  168. #######
  169. function DarkPreserve_function(clip "filtered", clip "original", bool "merge16_8", int "u", int "v", bool "lsb", bool "lsb_in", bool "lsb_out") {
  170. lsb_in    = default (lsb_in                       , false) #for original
  171. F_lsb_in  = lsb_in ? (Height(filtered)) == (Height(original)) : (Height(filtered)) == (Height(original)*2)
  172. lsb_out   = default (lsb_out         , F_lsb_in || lsb_in)
  173. lsb       = default (lsb ,  lsb_in || lsb_out || F_lsb_in)
  174. merge16_8 = default (merge16_8                     , true)
  175. sisphbd = AvsPlusVersionNumber > 2294
  176. sislumaonly = sisphbd ? original.isy() : VersionNumber() < 2.6 ? nop() : original.isy8()
  177. u         = default (u                                , VersionNumber() < 2.6 ? 3 : sislumaonly ? 1 : 3)
  178. v         = default (v                                , u)
  179. chroma    = !(u != 3 && v != 3)
  180.  
  181. F_lsb_in        ? Assert(lsb,                          "16stacked filtered clip requires: lsb=true")                : nop()
  182. lsb_in          ? Assert(lsb,                          "lsb_in  requires: lsb=true")                                : nop()
  183. lsb_out         ? Assert(lsb,                          "lsb_out requires: lsb=true")                                : nop()
  184.  
  185. dp_lut = lsb_in ? original.Dither_lut16("x 4096 < 65535 x 19200 > 0 65535 x 4096 - 4.338916843220339 * - ? ?",u=1,v=1) : VersionNumber() < 2.6 ? original.mt_lut("x 16 < 255 x 75 > 0 255 x 16 - 4.322033898305085 * - ? ?",u=1,v=1)
  186.                                                                  \             : original.mt_lut("x 16 scalef < range_max x 75 scalef > 0 range_max x 16 scalef - range_max 75 scalef 16 scalef - / * - ? ?",use_expr=2,u=1,v=1)
  187.  
  188. dp_lut = lsb_in && merge16_8 ? dp_lut.Ditherpost(mode=6, slice=false, u=1, v=1) : dp_lut
  189.  
  190. dp_merge = lsb ? merge16_8 ? Dither_merge16_8(F_lsb_in ? filtered : filtered.Dither_convert_8_to_16(), lsb_in ? original : original.Dither_convert_8_to_16(), dp_lut, luma=chroma, u=u,v=v) : \
  191.                              Dither_merge16(F_lsb_in ? filtered : filtered.Dither_convert_8_to_16(), lsb_in ? original : original.Dither_convert_8_to_16(), dp_lut, luma=chroma, u=u,v=v) : \
  192.                              mt_merge(filtered, original, dp_lut, luma=chroma, u=u,v=v)
  193. lsb ? lsb_out ? dp_merge : dp_merge.Ditherpost(mode=7, slice=false) : dp_merge
  194. }
  195.  
  196. function lightPreserve_function(clip "filtered", clip "original", bool "merge16_8", int "u", int "v", bool "lsb", bool "lsb_in", bool "lsb_out") {
  197. lsb_in    = default (lsb_in                       , false) #for original
  198. F_lsb_in  = lsb_in ? (Height(filtered)) == (Height(original)) : (Height(filtered)) == (Height(original)*2)
  199. lsb_out   = default (lsb_out         , F_lsb_in || lsb_in)
  200. lsb       = default (lsb ,  lsb_in || lsb_out || F_lsb_in)
  201. merge16_8 = default (merge16_8                     , true)
  202. sisphbd = AvsPlusVersionNumber > 2294
  203. sislumaonly = sisphbd ? original.isy() : VersionNumber() < 2.6 ? nop() : original.isy8()
  204. u         = default (u                                , VersionNumber() < 2.6 ? 3 : sislumaonly ? 1 : 3)
  205. v         = default (v                                , u)
  206. chroma    = !(u != 3 && v != 3)
  207.  
  208. F_lsb_in        ? Assert(lsb,                          "16stacked filtered clip requires: lsb=true")                : nop()
  209. lsb_in          ? Assert(lsb,                          "lsb_in  requires: lsb=true")                                : nop()
  210. lsb_out         ? Assert(lsb,                          "lsb_out requires: lsb=true")                                : nop()
  211.  
  212. dp_lut = lsb_in ? original.Dither_lut16("x 60160 > 65535 x 45056 < 0 65535 60160 x - 4.338916843220339 * - ? ?",u=1,v=1) : VersionNumber() < 2.6 ? original.mt_lut("x 235 > 255 x 176 < 0 255 235 x - 4.322033898305085 * - ? ?",u=1,v=1)
  213.                                                                    \                 : original.mt_lut("x 235 scalef > range_max x 176 scalef < 0 range_max x 235 scalef - range_max 176 scalef 235 scalef - / * - ? ?",use_expr=2,u=1,v=1)
  214.  
  215. dp_lut = lsb_in && merge16_8 ? dp_lut.Ditherpost(mode=6, slice=false, u=1, v=1) : dp_lut
  216.  
  217. dp_merge = lsb ? merge16_8 ? Dither_merge16_8(F_lsb_in ? filtered : filtered.Dither_convert_8_to_16(), lsb_in ? original : original.Dither_convert_8_to_16(), dp_lut, luma=chroma, u=u,v=v) : \
  218.                              Dither_merge16(F_lsb_in ? filtered : filtered.Dither_convert_8_to_16(), lsb_in ? original : original.Dither_convert_8_to_16(), dp_lut, luma=chroma, u=u,v=v) : \
  219.                              mt_merge(filtered, original, dp_lut, luma=chroma, u=u,v=v)
  220. lsb ? lsb_out ? dp_merge : dp_merge.Ditherpost(mode=7, slice=false) : dp_merge
  221. }
  222.  
  223.  
  224. ##########
  225. #edge side bleed
  226. #original idea by "colours", this function mod by A.SONY
  227. ##########
  228. function edgesidebleed(clip input, float "w32", float "w16", float "w8", float "w4", float "w2", bool "bleed", bool "chroma", int "mode") {
  229. w2     = Default(w2,     0.001)
  230. w4     = Default(w4,     0.055)
  231. w8     = Default(w8,     0.015)
  232. w16    = Default(w16,     0.02)
  233. w32    = Default(w32,    0.001)
  234. chroma = default(chroma, false)
  235. mode   = default(mode,       0)
  236. avs26  = !(VersionNumber() < 2.6)
  237. bleed  = default(bleed, avs26)
  238.  
  239. sisyuy2 = input.isyuy2()
  240. input = sisyuy2 && avs26 ? input.converttoyv16() : input
  241.  
  242. sisphbd = !chroma ? AvsPlusVersionNumber > 2294 : nop()
  243. sislumaonly = !chroma ? sisphbd ? input.isy() : !avs26 ? true : input.isy8() : nop()
  244. !chroma ? sislumaonly ? input : sisphbd ? input.converttoy() : input.converttoy8() : input
  245. w = bleed ?  Width() : nop()
  246. h = bleed ? Height() : nop()
  247.  
  248. shift32 = w32!=0 ? !bleed ? Crop(Width()-32,0,32,0,true).StackHorizontal(Crop(0,0,-32,0,true)) : nop() : nop()
  249. shift32 = w32!=0 ? bleed ? BicubicResize (w / 32, h, 1, 0,src_left=-32).BicubicResize (w, h, 1, 0) : shift32 : nop()
  250. w32==0 ? last : mode == 0 ? average(last,1+w32,shift32,-w32) : mode==1 ? lightPreserve_function(average(last,1+w32,shift32,-w32),last) : DarkPreserve_function(average(last,1+w32,shift32,-w32),last)
  251. shift16 = w16!=0 ? !bleed ? Crop(Width()-16,0,16,0,true).StackHorizontal(Crop(0,0,-16,0,true)) : nop() : nop()
  252. shift16 = w16!=0 ? bleed ? BicubicResize (w / 16, h, 1, 0,src_left=-16).BicubicResize (w, h, 1, 0) : shift16 : nop()
  253. w16==0 ? last : mode == 0 ? average(last,1+w16,shift16,-w16) : mode==1 ? lightPreserve_function(average(last,1+w16,shift16,-w16),last) : DarkPreserve_function(average(last,1+w16,shift16,-w16),last)
  254. shift8 = w8!=0 ? !bleed ? Crop(Width()-8,0,8,0,true).StackHorizontal(Crop(0,0,-8,0,true)) : nop() : nop()
  255. shift8 = w8!=0 ? bleed ? BicubicResize (w / 8, h, 1, 0,src_left=-8).BicubicResize (w, h, 1, 0) : shift8 : nop()
  256. w8==0 ? last : mode == 0 ? average(last,1+w8,shift8,-w8) : mode==1 ? lightPreserve_function(average(last,1+w8,shift8,-w8),last) : DarkPreserve_function(average(last,1+w8,shift8,-w8),last)
  257. shift4 = w4!=0 ? !bleed ? Crop(Width()-4,0,4,0,true).StackHorizontal(Crop(0,0,-4,0,true)) : nop() : nop()
  258. shift4 = w4!=0 ? bleed ? BicubicResize (w / 4, h, 1, 0,src_left=-4).BicubicResize (w, h, 1, 0) : shift4 : nop()
  259. w4==0 ? last : mode == 0 ? average(last,1+w4,shift4,-w4) : mode==1 ? lightPreserve_function(average(last,1+w4,shift4,-w4),last) : DarkPreserve_function(average(last,1+w4,shift4,-w4),last)
  260. shift2 = w2!=0 ? !bleed ? Crop(Width()-2,0,2,0,true).StackHorizontal(Crop(0,0,-2,0,true)) : nop() : nop()
  261. shift2 = w2!=0 ? bleed ? BicubicResize (w / 2, h, 1, 0,src_left=-2).BicubicResize (w, h, 1, 0) : shift2 : nop()
  262. w2==0 ? last : mode == 0 ? average(last,1+w2,shift2,-w2) : mode==1 ? lightPreserve_function(average(last,1+w2,shift2,-w2),last) : DarkPreserve_function(average(last,1+w2,shift2,-w2),last)
  263.  
  264. !chroma ? sislumaonly ? last : sisphbd ? CombinePlanes(last,input,planes="YUV",sample_clip=input) : ytouv(input.utoy8(),input.vtoy8(),last) : last
  265. sisyuy2 ? converttoyuy2() : last
  266. }
  267.  
  268.  
  269. ##########
  270. #chroma edge side bleed (aka pink artifacts) fix, by A.SONY
  271. ##########
  272. function chromasidebleed(clip input, int "diameter", float "sDev", float "iDev", float "cs", bool "bic", string "cplace", bool "d2", int "kernS", int "kernI", int "resType")
  273. {
  274. diameter  = default (diameter,    11)
  275. sDev      = default (sDev,      31.1)
  276. iDev      = default (iDev,      15.1)
  277. d2        = default (d2,        true)
  278. kernS     = default (kernS,        8)
  279. kernI     = default (kernI,        3)
  280. restype   = default (restype,      0)
  281. bic       = default (bic,       true)
  282. cplace    = default (cplace, "MPEG2")
  283.  
  284. avs25   = VersionNumber() < 2.6
  285. sisyuy2 = input.isyuy2()
  286. input = sisyuy2 && !avs25 ? input.converttoyv16() : input
  287.  
  288. chroma = false
  289.  
  290. sisphbd = AvsPlusVersionNumber > 2294
  291. sisfullchr = sisphbd ? input.is444() : avs25 ? false : input.isyv24()
  292. sislumaonly = sisphbd ? input.isy() : avs25 ? false : input.isy8()
  293. Assert(!sislumaonly, "why you use this on no chroma clip?!")
  294.  
  295. y=avs25 ? input : sisphbd ? input.converttoy() : input.converttoy8()
  296. u=avs25 ? input.utoy() : input.utoy8()
  297. v=avs25 ? input.vtoy() : input.vtoy8()
  298. cshift = (cplace == "MPEG1" && IsYV12(input)) || IsYV24(input) ? 0 : -0.5
  299. ych = sisfullchr ? y : bic ? input.BicubicResize(u.width(), v.height(), 1, 0, src_left=cshift) : input.BilinearResize(u.width(), v.height(), src_left=cshift)
  300. u=u.ConvertToYV12().TBilateral(diameterL=diameter, sDevL=sDev, iDevL=iDev, csL=cs, d2=d2, chroma=chroma, ppclip=ych.ConvertToYV12(), kernS=kernS, kernI=kernI, resType=resType)
  301. v=v.ConvertToYV12().TBilateral(diameterL=diameter, sDevL=sDev, iDevL=iDev, csL=cs, d2=d2, chroma=chroma, ppclip=ych.ConvertToYV12(), kernS=kernS, kernI=kernI, resType=resType)
  302. YToUV(u,v,y)
  303. sisyuy2 ? converttoyuy2() : last
  304. }
  305.  
  306.  
  307. #########
  308. # Comb wrapper function
  309.  
  310. function sComb(clip clip, bool "DeCrawing", bool "DeRainbowing", int "LRepair", int "CRepair", bool "ntsccombmask") {
  311. DeCrawing = default (DeCrawing, true)
  312. ntsccombmask = default (ntsccombmask, false)
  313. DeRainbowing = default (DeRainbowing, true)
  314. LRepair = default (LRepair, ntsccombmask ? 7 : DeCrawing ? 2 : 0)
  315. CRepair = default (CRepair, ntsccombmask ? 5 : 0)
  316. sisphbd = AvsPlusVersionNumber > 2294
  317. avs26   = !(VersionNumber() < 2.6)
  318. clip
  319. sis422  = avs26 ? isyv16() : false
  320. Assert((isyv12 || sis422), "sComb: only yv12 and yv16 is supported")
  321. prefil = ntsccombmask ? (VersionNumber() < 2.60) && isyv12(input) ? last.HQdn3d().FFT3DFilter().tweak(sat=1.5) : last.HQdn3d_2().FFT3DFilter().tweak(sat=1.5) : nop()
  322. iqchr  = ntsccombmask ? prefil.SwapUV().Tweak(hue=-33) : nop()
  323. I = ntsccombmask ? sisphbd ? iqchr.ExtractU().sypixsub(2,2) : avs26 ? iqchr.utoy8().sypixsub(2,2) : iqchr.utoy().sypixsub(2,2) : nop()
  324. Q = ntsccombmask ? sisphbd ? iqchr.ExtractV().sypixsub(2,2) : avs26 ? iqchr.Vtoy8().sypixsub(2,2) : iqchr.Vtoy().sypixsub(2,2) : nop()
  325. m = ntsccombmask ? ytouv(i,q,prefil).sypixsub(2).mt_edge("min/max", 0, 15, 0, 10,u=3,v=3).mt_expand(128,128,y=2,u=3,v=3).mt_expand(128,mode="horizontal",u=2,v=2).mt_inpand(128,mode="horizontal",u=2,v=2) : nop()
  326. mU = ntsccombmask ? sisphbd ? m.ExtractU() : avs26 ? m.utoy8() : m.utoy() : nop()
  327. mV = ntsccombmask ? sisphbd ? m.ExtractV() : avs26 ? m.vtoy8() : m.vtoy() : nop()
  328. y=ntsccombmask ? Overlay(mu,mv,mode="add").Spline36Resize(width(),Height(),0.5) : nop()
  329. m = ntsccombmask ? sisphbd ? m.ConvertToY() : avs26 ? m.ConvertToY8() : m : nop()
  330. uv=ntsccombmask ? m.Spline36Resize(mu.width(),mu.Height(),-0.5) : nop()
  331. m=ntsccombmask ? ytouv(uv,uv,y) : nop()
  332.  
  333. DeRainbowing && ntsccombmask ? TComb(mode=1) : last
  334. SeparateFields()
  335. oriFiel=last
  336. DeCrawing ? DDComb(static=true,strong=true,checkmate=ntsccombmask) : last
  337. DeRainbowing ? ASTDRmc(edgemprefil=oriFiel,chroma=true, nomask=ntsccombmask) : last
  338. ntsccombmask ? mt_merge(oriFiel,last,m.SeparateFields(),u=3,v=3) : last
  339. Weave()
  340. LRepair==0 && CRepair==0 ? last : last.Repair(clip,LRepair,CRepair)
  341. }
  342.  
  343.  
  344. # Padding by Didée
  345. function Padding(clip c, int left, int top, int right, int bottom, int "threads")
  346. {
  347. threads = Default(threads, 0)
  348. w = c.width()
  349. h = c.height()
  350. threads!=1 ? Eval("try { pointresizemt(w+left+right, h+top+bottom, -left, -top, w+left+right, h+top+bottom+0.0001, threads=threads) } catch(error_msg) { c.pointresize( w+left+right, h+top+bottom, -left, -top, w+left+right, h+top+bottom+0.0001 ) }") : c.pointresize( w+left+right, h+top+bottom, -left, -top, w+left+right, h+top+bottom+0.0001 )
  351. }
  352.  
  353.  
  354. # filtering with some borders by A.SONY
  355. Function filtering_wsb (clip src, string "filter", int "oneborder", clip "linesm", clip "clip4lines", int "mmy", bool "mmLuma", int "mmuv", bool "minflate", int "bordertype")
  356. {
  357. oneborder = Default (oneborder,   2)
  358. mmLuma    = Default (mmLuma,  false)
  359. minflate  = Default (minflate, true)
  360. mmuv      = Default (mmuv, mmLuma ? 3 : 2)
  361. mmy       = Default (mmy,         3)
  362. bordertyp = Default (bordertype,  1)
  363. filter    = Default (filter, defined(linesm) ? "yahr3.TBilateral(5,5,0.9,0.9,5,5,0.7,chroma=false)" : \
  364.                                              """FineDehaloanalog(exdehalo="VHSHaloremover(2,2,200,100,0.5).yahr2(32)")""")
  365. minf = defined(linesm) ? minflate ? linesm.mt_inflate(155,155,u=mmLuma || mmuv!=3 ? 1 : 3 ,v=mmLuma || mmuv!=3 ? 1 : 3) : linesm : nop()
  366.  
  367. src
  368. bordertyp==0 ? Padding(oneborder,oneborder,oneborder,oneborder) : AddBorders(oneborder,oneborder,oneborder,oneborder,bordertyp==1 ? undefined : bordertyp==2 ? color_white : bordertyp)
  369. eval(filter)
  370. Crop(oneborder, oneborder, -oneborder, -oneborder, align=true)
  371.  
  372. defined(linesm) ? mt_Merge(last, defined(clip4lines) ? clip4lines : src, minf,y=mmy,luma=mmLuma,u=mmuv,v=mmuv) : last
  373. }
  374.  
  375.  
  376. ###############
  377. # Hqdn3d_2
  378.  
  379. function Hqdn3d_2(clip clip, float "ls", float "cs", float "lt", float "ct", int "UV", bool "lsb", bool "lsb_in", bool "i16", int "Y") {
  380. cs        = default (cs              , 3.0)
  381. ct        = default (ct              , 4.5)
  382. UV        = default (UV               , 3)
  383. Y         = default (Y                , 3)
  384. UV        = !(VersionNumber() < 2.60) ? isY8(clip) ? 1 : UV : UV
  385. lsb_in    = default (lsb_in          , false)
  386. i16       = default (i16             , false)
  387. lsb_out   = default (lsb             , lsb_in)
  388.  
  389. i16b      = lsb_out || i16 || lsb_in
  390.  
  391. isrgb(clip) ? Assert(!i16b, "no 16bit for RGB, but you can use some trickes for that (see dither doc)") : nop()
  392.  
  393. yString = VersionNumber() < 2.60 ? "yv12" : "Y8"
  394.  
  395. pclip   = isYUV(clip) && i16b && isYUY2(clip) && !(VersionNumber() < 2.60) ? clip.ConvertToYV16() : clip
  396.  
  397. i16clip = isYUV(clip) ? i16b ? lsb_in ? pclip.Bitdepth(from=88, to=16) : i16 ? clip : pclip.Bitdepth(from=8, to=16) : nop() : nop()
  398.  
  399.     yclip = isYUV(clip) ? VersionNumber() < 2.60 ? i16b ? i16clip : clip : i16b ? ConvertToY8(i16clip) : ConvertToY8(clip) : nop()
  400.     u = isYUV(clip) && UV != 1 ? VersionNumber() < 2.60 ? i16b ? UToY(i16clip) : UToY(clip) : i16b ? UToY8(i16clip) : UToY8(clip) : nop()
  401.     v = isYUV(clip) && UV != 1 ? VersionNumber() < 2.60 ? i16b ? VToY(i16clip) : VToY(clip) : i16b ? VToY8(i16clip) : VToY8(clip) : nop()
  402.     yclip = isYUV(clip) ? Y == 3 ? VersionNumber() < 2.60 ? isclip(i16clip) ? yclip.converttoyv12().Hqdn3d16Y(sp=ls, tp=lt) : yclip.converttoyv12().Hqdn3dY(sp=ls, tp=lt) : isclip(i16clip) ? yclip.Hqdn3d16Y(sp=ls, tp=lt) : yclip.Hqdn3dY(sp=ls, tp=lt) : yclip : nop()
  403.     u = isYUV(clip) ? UV == 3 ? VersionNumber() < 2.60 ? isclip(i16clip) ? u.converttoyv12().Hqdn3d16Y(sp=cs, tp=ct) : u.converttoyv12().Hqdn3dY(sp=cs, tp=ct) : isclip(i16clip) ? u.Hqdn3d16Y(sp=cs, tp=ct) : u.Hqdn3dY(sp=cs, tp=ct) : u : nop()
  404.     v = isYUV(clip) ? UV == 3 ? VersionNumber() < 2.60 ? isclip(i16clip) ? v.converttoyv12().Hqdn3d16Y(sp=cs, tp=ct) : v.converttoyv12().Hqdn3dY(sp=cs, tp=ct) : isclip(i16clip) ? v.Hqdn3d16Y(sp=cs, tp=ct) : v.Hqdn3dY(sp=cs, tp=ct) : v : nop()
  405.     isYUV(clip) ? (VersionNumber() < 2.60) && isYUY2(clip) ? UV == 1 ? yclip : YToUV(u.converttoyuy2(),v.converttoyuy2(),yclip.converttoyuy2()) : UV == 1 ? yclip : YToUV(u,v,yclip) : nop()
  406.         isYUV(clip) ? i16b && !i16 && lsb_out ? Bitdepth(from=16, to=88) : last : last
  407.     isYUV(clip) ? !i16b || lsb_out || i16 ? last : Bitdepth(from=16, to=8) : last
  408.     isYUY2(clip) ? VersionNumber() < 2.60 ? last : converttoyuy2() : last
  409.  
  410.     A = isrgb32(clip) ? clip.ShowAlpha(yString) : nop()
  411.     r = isrgb(clip) ? clip.ShowRed(yString) : nop()
  412.     g = isrgb(clip) ? clip.ShowGreen(yString) : nop()
  413.     b = isrgb(clip) ? clip.ShowBlue(yString) : nop()
  414.     A = isrgb32(clip) ? A.Hqdn3dY(sp=ls, tp=lt) : nop()
  415.     r = isrgb(clip) ? r.Hqdn3dY(sp=ls, tp=lt) : nop()
  416.     g = isrgb(clip) ? g.Hqdn3dY(sp=ls, tp=lt) : nop()
  417.     b = isrgb(clip) ? b.Hqdn3dY(sp=ls, tp=lt) : nop()
  418.     isYUV(clip) ? last : isrgb32(clip) ? MergeARGB(A,r,g,b) : MergeRGB(r,g,b,"RGB24")
  419. }
  420.  
  421.  
  422. ###############
  423. #motion adaptive by A.SONY
  424.  
  425. function smam(clip input, clip "prefilter", val "filter", int "pel", int "blksize", clip "motionmask", float "Str", float "Amp", bool "TV_range", bool "qtgmc_lsb", int "tr2", int "usedaa3mod", bool "repblend", val "dslow", bool "qtgmc_n16") {
  426.  
  427. sisphbd = AvsPlusVersionNumber > 2294
  428. qtgmc_lsb = default(qtgmc_lsb, sisphbd ? false : true)
  429. qtgmc_n16 = default(qtgmc_n16, sisphbd ? input.BitsPerComponent() > 8 ? false : true : false)
  430. repblend  = default(repblend, false)
  431.  
  432. defined(filter) ? Assert((Isclip(filter) || IsString(filter)),        "'filter' only accepts clip or string") : nop()
  433.  
  434. Str             = default (Str, 1.5)
  435. exfilclp        = isclip(filter)
  436. sisbob          = round(framerate(input))==60 || framerate(input)==50
  437. tr2             = default (tr2, sisbob ? 3 : 1)
  438. usedaa3mod      = default (usedaa3mod, exfilclp ? 0 : sisbob ? 1 : 2)
  439.  
  440. infiltr = usedaa3mod == 1 ? input.daa3mod(dslow) : input
  441. filclip = defined(filter) ? exfilclp ? filter : eval("infiltr." + filter) : infiltr.QTGMC(InputType=1, tr0=0, tr1=sisbob ? undefined : 1, tr2=tr2, lsb=qtgmc_lsb, n16=qtgmc_n16, rep1=sisbob ? undefined : 11, rep2=sisbob ? undefined : 11, Sharpness=0.0, TV_range=TV_range, Str=Str, Amp=Amp)
  442. filclip = usedaa3mod == 2 ? filclip.daa3mod(dslow) : filclip
  443.  
  444. momask  = !defined(motionmask) ? input.smam_mask(prefilter,pel,blksize) : motionmask #if you deal with YUY2 then it should be Planar YUY2 in avs2.5 and yv16 in avs2.6
  445. isyuy2(input) && VersionNumber() < 2.60 ? mt_merge(input.Interleaved2Planar(),filclip.Interleaved2Planar(),momask,u=3,v=3).Planar2Interleaved() : isyuy2(input) ? mt_merge(input.converttoyv16(),filclip.converttoyv16(),momask,u=3,v=3).converttoyuy2() : mt_merge(input,filclip,momask,u=3,v=3)
  446. repblend ? isyuy2(input) && VersionNumber() < 2.60 ? Interleaved2Planar() : isyuy2(input) ? converttoyv16() : last : last
  447. repblend ? isyuy2(input) && VersionNumber() < 2.60 ? Repair(Repair(input.Interleaved2Planar(),16,Planar=true),12,Planar=true).Planar2Interleaved() : isyuy2(input) ? Repair(Repair(input.converttoyv16(),16),12).converttoyuy2() : Repair(Repair(input,16),12) : last
  448. }
  449.  
  450.  
  451. ###############
  452. #smam_mask
  453. # if input is YUY2 the output will be Planar YUY2 in avs 2.5 and yv16 in avs 2.6
  454.  
  455. function smam_mask(clip input, clip "prefilter", int "pel", int "blksize", bool "chroma", int "dct") {
  456.     ox = input.width()
  457.     oy = input.height()
  458.     HD = (ox > 1099 || oy > 599)
  459.     sisbob  = round(framerate(input))==60 || framerate(input)==50
  460.     pel = default( pel,     HD ? 1 : 2 )
  461.     dct = default( dct, sisbob ? 0 : 2 )
  462.     blksize = default(blksize,HD ? sisbob ? 8 : 16 : sisbob ? 4 : 8)
  463. preclip= defined(prefilter) ? prefilter : (VersionNumber() < 2.60) && isyv12(input) ? input.HQdn3d().FFT3DFilter() : input.HQdn3d_2().FFT3DFilter()
  464. sup    = preclip.MSuper(pel=pel,sharp=1)
  465. fv1    = sup.MAnalyse(isb=false,delta=1,DCT=dct,Truemotion=false,blksize=blksize,chroma=chroma)
  466. fv2    = sup.MAnalyse(isb=true,delta=1,DCT=dct,Truemotion=true,blksize=blksize,chroma=chroma)
  467.  
  468. momask1 = input.MMask(fv1, kind = 1, ml=2)
  469. momask2 = input.MMask(fv2, kind = 1, ml=3)
  470. momask1 =isyuy2(input) && VersionNumber() < 2.60 ? momask1.Interleaved2Planar() : isyuy2(input) ? momask1.converttoyv16() : momask1
  471. momask2 =isyuy2(input) && VersionNumber() < 2.60 ? momask2.Interleaved2Planar() : isyuy2(input) ? momask2.converttoyv16() : momask2
  472. mt_average(momask1,momask2,u=3,v=3)
  473. }
  474.  
  475.  
  476. ##############
  477. # sanimebob by A.SONY
  478.  
  479. function sanimebob(clip i, val "useqtgmc", val "bobpresmooth", float "Str", float "Amp", bool "TV_range", bool "qtgmc_lsb", bool "usedaa3mod", bool "usesmam", int "tr2", bool "repblend", val "dslow", bool "qtgmc_n16", bool "nnrep", bool "nnedi3pad") {
  480.  
  481. sisphbd = AvsPlusVersionNumber > 2294
  482. qtgmc_lsb = default(qtgmc_lsb, sisphbd ? false : true)
  483. qtgmc_n16 = default(qtgmc_n16, sisphbd ? i.BitsPerComponent() > 8 ? false : true : false)
  484.  
  485. useq                  = default (useqtgmc,                                                                                                           0)
  486. Stringuseq        = IsString(useq                                                                                                                 )
  487. bobpresmbool = default (isbool(bobpresmooth) ? bobpresmooth : !Stringuseq ? (useq==8 || defined(bobpresmooth)) : defined(bobpresmooth), false)
  488. Str                     = default (Str,                                                                                                              1.5)
  489. tr2                     = default (tr2,                                                                                !Stringuseq ? useq==8 ? 3 : 1 : 1)
  490. usedaa3mod   = default (usedaa3mod,                                            !Stringuseq ? useq==4 || useq==5 || useq==7 || useq==9 : false)
  491. usesmam        = default (usesmam,                                                       !Stringuseq ? !(useq==0 || useq==1 || useq==8) : false)
  492. nnrep               = default (nnrep, false)
  493. nnedi3pad       = default (nnedi3pad, false)
  494.  
  495. Assert(Isint(useq) || Stringuseq, "'useqtgmc' only accepts int or string")
  496.  
  497. prefiltered_i   = defined(bobpresmooth) ? isclip(bobpresmooth) ? bobpresmooth : IsString(bobpresmooth) ? Eval("i." + bobpresmooth) : undefined() : undefined()
  498.  
  499. nonyuy2=!(VersionNumber() < 2.6) && i.isyuy2()
  500. iforbob   = bobpresmbool ? defined(prefiltered_i) ? prefiltered_i : i.QTGMC_bob(0,0.5).nonyuy2clipin(nonyuy2).reduceflicker(strength=2).nonyuy2clipout(nonyuy2).interlaced60or50(BFF=!(GetParity(i))) : i
  501. iforbob   = bobpresmbool && !defined(prefiltered_i) ? isyuy2(i) ? iforbob.SeparateFields().Interleaved2Planar().Repair(i.SeparateFields().Interleaved2Planar(),Planar=true).Planar2Interleaved().weave() : iforbob.SeparateFields().Repair(i.SeparateFields()).weave() : iforbob
  502.  
  503. pyi       = i.Padding(0,4,0,4)
  504. pni       = nnedi3pad ? iforbob.Padding(2,4,2,4).nnedi3(-2).crop(2,4,-2,-4,true) : iforbob.nnedi3(-2)
  505. pei       = i.eedi3(-2,sclip=pni)
  506. pei       = nnrep ? isyuy2(i) ? pei.Interleaved2Planar().Repair(pni.Interleaved2Planar(),9,Planar=true).Planar2Interleaved().Padding(0,4,0,4) : pei.Repair(pni,9).Padding(0,4,0,4) : pei.Padding(0,4,0,4)
  507.  
  508. ymodclip  = VersionNumber() < 2.60 ? pyi.yadifmod(mode=3, edeint=pei).crop(0,4,-0,-4) : pyi.nonyuy2clipin(nonyuy2).yadifmod2(mode=3, edeint=pei.nonyuy2clipin(nonyuy2)).crop(0,4,-0,-4)
  509. yadifclip = isyuy2(i) && VersionNumber() < 2.60 ? ymodclip.Interleaved2Planar().Repair(i.TDeint(1,emask=iforbob.tmm2_ortmm1(1)).Interleaved2Planar(),Planar=true).Planar2Interleaved() : \
  510.                                                   ymodclip.Repair(i.TDeint(1,emask=iforbob.tmm2_ortmm1(1)).nonyuy2clipin(nonyuy2)).nonyuy2clipout(nonyuy2)
  511.  
  512. # for custom qtgmc, don't forget to put the input clip like this:- iforbob.QTGMC(... or yadifclip.QTGMC(... or i.QTGMC(...
  513. QTGMCclip = isstring(useq) ? eval(useq) : \
  514.                              useq==0 ? yadifclip : \
  515.        useq==1 || useq==2 || useq==4 ? iforbob.QTGMC(SourceMatch=3, Lossless=2, EdiExt=yadifclip, tr0=1, tr1=1, tr2=tr2, lsb=qtgmc_lsb, n16=qtgmc_n16, rep0=11, rep1=11, rep2=11, Sharpness=0.1, TV_range=TV_range, Str=Str, Amp=Amp) : \
  516.                   useq==3 || useq==5 ? yadifclip.QTGMC(InputType=1, tr0=1, tr1=1, tr2=tr2, lsb=qtgmc_lsb, n16=qtgmc_n16, rep0=11, rep1=11, rep2=11, Sharpness=0.1, TV_range=TV_range, Str=Str, Amp=Amp) : \
  517.                   useq==6 || useq==7 ? yadifclip.QTGMC(InputType=1, tr0=0, lsb=qtgmc_lsb, n16=qtgmc_n16, Sharpness=usedaa3mod ? 0.0 : 0.1, TV_range=TV_range, Str=Str, Amp=Amp) : \
  518.                                        i.QTGMC(SourceMatch=3, Lossless=2, EdiExt=yadifclip, useEdiExt=!(useq==9), tr0=useq==9 ? -1 : undefined(), rep0=useq==9 ? undefined() : 11, tr2=tr2, lsb=qtgmc_lsb, n16=qtgmc_n16, Sharpness=0.0, TV_range=TV_range, Str=Str, Amp=Amp)
  519.  
  520. daa3mclip = usedaa3mod ? QTGMCclip.daa3mod(dslow) : QTGMCclip
  521.  
  522. !usesmam ? daa3mclip : \
  523.            yadifclip.smam(filter=daa3mclip,repblend=repblend)
  524. }
  525.  
  526.  
  527. ##############
  528. # sypixsub 1.3, Subtracting one luma pixel with the neighboring pixel on the left or the top
  529. Function sypixsub(clip clip, int "left", int "top", bool "expr")
  530. {
  531. left=Default(left, 1) #set the "left" to 2 will make it 2 pass since the subtract mode in overlay ignore the negative result of subtracting, set it to -1 and will show the negative result only
  532. top=Default(top, 0) #same as "left" parameter
  533. expr=Default(expr, true)
  534. sisphbd = AvsPlusVersionNumber > 2294
  535. expr=sisphbd ? expr : false
  536.  
  537. Assert(!(left>2 || left<-1 || top>2 || top<-1), "sypixsub: left and top modes must be between -1 to 2")
  538. Assert(!(left==0 && top==0), "sypixsub: why you use sypixsub then?!!!!")
  539.  
  540. sislumaonly = sisphbd ? clip.isy() : VersionNumber() < 2.6 ? true : clip.isy8()
  541. c= sislumaonly ? clip : sisphbd ? clip.converttoy() : clip.converttoy8()
  542. lexp = left==-1 ? "x[-1,0] x -" : left==0 ? "" : "x x[-1,0] -" + string(left>1 ? " abs" : "")
  543. texp = top==-1 ? " x[0,-1] x -" : top==0 ? "" : " x x[0,-1] -" + string(top>1 ? " abs" : "")
  544. expr ? c.Expr(lexp + texp + (top != 0 && left != 0 ? " +" : "")) : eval("""
  545. c
  546. left != 0 ? PointResize(Width(), Height(), src_left=-1) : last
  547. leftsub1 = left != 0 ? overlay(c,last,mode="Subtract") : last
  548. leftsub2 = left == -1 || left > 1 ? overlay(last,c,mode="Subtract") : nop()
  549. left > 1 ? overlay(leftsub1,leftsub2,mode="add") : left == -1 ? leftsub2 : leftsub1
  550. h=last
  551. top != 0 ? c : last
  552. top != 0 ? PointResize(Width(), Height(), src_top=-1) : last
  553. topsub1 = top != 0 ? overlay(c,last,mode="Subtract") : last
  554. topsub2 = top == -1 || top > 1 ? overlay(last,c,mode="Subtract") : nop()
  555. top > 1 ? overlay(topsub1,topsub2,mode="add") : top == -1 ? topsub2 : topsub1
  556.  
  557. top != 0 && left != 0 ? overlay(h,last,mode="add") : last
  558. """)
  559. sislumaonly ? last : sisphbd ? CombinePlanes(last,clip,planes="YUV",sample_clip=clip) : YToUV(clip.UToY8(),clip.VToY8(),last)
  560. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement