Advertisement
Guest User

FixBlendIVTC

a guest
Nov 10th, 2017
1,144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ################################
  2. ## FixBlendIVTC  by MOmonster ##
  3. ################################
  4.  
  5.  
  6. ## FixBlendIVTC is a blend replacing / frame restoring function for doubleblends, caused by blenddeinterlacing
  7. ## of telecined sources. It will only work for this special case and is not created for any other conversions.
  8. ##
  9. ## Use import("FixBlendIVTC.avs") in your script and load the necessary filters to be able using this function
  10. ##
  11. ## required filters:
  12. ##      - Average
  13. ##      - mt_masktools
  14. ##      - removegrain
  15. ##      - TIVTC (for cache>-1, not default. or for decimating (external))
  16. ##      - Decomb (if you want to use the function decimate for decimating)
  17. ## version:
  18. ##      - v0.91b  - 11.11.2017
  19. ##
  20. ## Thanks to Manao, Clouded and Kassandro for the really useful plugins,
  21. ## and of course also to foxyshadis, who gives me the idea and many inspirations.
  22.  
  23.  
  24.  
  25. ## sample1: source              #progressive
  26. ##      FixBlendIVTC(sbd=true)
  27. ##      decimate(cycle=5,quality=0) #recommed decimating
  28. ##
  29. ## sample2: source
  30. ##      FixBlendIVTC(post="""pp2.deen("a2d")""")
  31. ##      tdecimate(rate=23.976,mode=7)
  32.  
  33.  
  34. ## parameter description:
  35. ##  post
  36. ##      It's the parameter for the postprocessing. These are the modes:
  37. ##          0 ->    the fastest mode, no postprocessing
  38. ##          1 ->    like post=0 but with chromablurring
  39. ##          2 ->    use difference masking, higher quality and still good speed         [0...6  ->2]
  40. ##          3 ->    like post=2 but with chromablurring
  41. ##          4 ->    use a special blurring mask on luma and chroma that reduces artefacts
  42. ##          5 ->    combines post 2 and 4 but without chromapostprocessing
  43. ##          6 ->    like post=5 but with extra chromaprocessing (slowest)
  44. ##      If these postprocessing modes aren't strong or individual enough for you you can also use your own
  45. ##      favourit filter on the restored frames. Therefore set a string with your setted filters.
  46. ##      Use pp0 till pp6 for the postprocessing mode and add your filter like this:
  47. ##          post="pp4.blur(1)"      #post=4 + blurring
  48. ##      If you want to use a filter with inputstrings use three quotation marks like in the second example.
  49. ##  bthresh
  50. ##      The blendthreshold can be used to make the blenddetection less aggressive if there are some wrong detections.
  51. ##                                                      [0...2.0  ->0.1]
  52. ##  mthresh
  53. ##      It´s used for (m)otion (thresh)olding. It regulates the blenddetection of frames with small pixelvaluedifferences.
  54. ##      A better quality of the source allows lower values and a more accurate detection. Don´t change this parameter too
  55. ##      much. It has a high influence on the double and single blenddetection.              [0...1.0  ->0.1]
  56. ##  sbd
  57. ##      The (s)ingle(b)lend(d)etection value is a boolean, Set it true for 12fps animations.    [bool  ->false]
  58. ##  chroma
  59. ##      With chroma=true you enable the processing of the chroma. This cost some speed, but depending on the source it
  60. ##      can improve the blend and motion detection.                                         [bool  ->false]
  61. ##  cache
  62. ##      With cache>=0 FixBlendIVTC use the RequestLinear function to be more compatible with non-linear requesting (codec or other functions).
  63. ##      You can set the number of frames you want to have cached. If cache is negative FixBlendIVTC doesn´t use RequestLinear
  64. ##      (can be useful if you have problems with the memory usage).                         [-1...50  ->5]
  65. ##  dclip
  66. ##      The (d)etection(clip) you can set to improve the blenddetection (cleaning the clip before).
  67. ##      This clip is only used for the blenddetection and not for output.
  68.  
  69.  
  70.  
  71.  
  72. Function FixBlendIVTC(clip input, "post", float "bthresh", "mthresh", bool "sbd", clip "dclip", bool "chroma", int "cache")
  73. {
  74. avs26 = !(VersionNumber() < 2.6)
  75. ssispmt = Findstr(VersionString(), "AviSynth+") != 0 && Findstr(VersionString(), "r1576") == 0
  76. ###### PREPARATION ######
  77. global pp   = default(post, 6)                      #(p)ost(p)rocessing string
  78. global mthresh  = default(mthresh, 0.1)                     #(m)otion(thresh)old
  79. global thresh   = 1+default(bthresh, 0.01)
  80. global sbd  = default(sbd,false)                        #(s)ingle(b)lend(d)etection
  81.  
  82.        cache    = default(cache,-1)                         #caching for non-linear request
  83.  
  84. rate    = framerate(input)
  85.  
  86.  
  87. ###### DETECTION CLIPS ######
  88. dclip   = default(dclip,input)                          #(d)etection clip
  89. sis420  = ssispmt ? dclip.is420() : dclip.isyv12()
  90. sislumaonly = ssispmt ? dclip.isy() : !avs26 ? false : dclip.isy8()
  91. dclip   = default(chroma,false)==false || !sislumaonly ? dclip : \
  92.                                                                  sis420 ? stackvertical(stackhorizontal(ssispmt ? dclip.ExtractU() : avs26 ? dclip.utoy8() : dclip.UtoY(),ssispmt ? dclip.ExtractV() : avs26 ? dclip.vtoy8() : dclip.VtoY()), ssispmt ? dclip.converttoy() : avs26 ? dclip.converttoy8() : dclip) : \
  93.                                                                         stackhorizontal(stackhorizontal(ssispmt ? dclip.ExtractU() : avs26 ? dclip.utoy8() : dclip.UtoY(),ssispmt ? dclip.ExtractV() : avs26 ? dclip.vtoy8() : dclip.VtoY()), ssispmt ? dclip.converttoy() : avs26 ? dclip.converttoy8() : dclip)
  94.  
  95. o_diff  = mt_makediff(dclip.trim(1,0), dclip.trim(4,0))
  96. c_diff  = mt_makediff(dclip.trim(2,0), dclip.trim(3,0))
  97. global re_lut   = mt_lutxy(o_diff, c_diff, yexpr="x 128 - abs 126 > y 128 - abs 63 > & 0 x 128 + y 2 * - 2 ^ x 128 + y 2 * - abs 0.8 ^ - y 128 - abs 1 + 0.5 ^ / ?", uexpr="x", vexpr="x")
  98. global sdiff    = mt_lut(c_diff, yexpr="x 128 - 2 ^ 12 -", uexpr="x", vexpr="x").mt_inpand()
  99.  
  100.  
  101. ###### POSTPROCESSING ######
  102. unblend1 = Average(input, 2.0, input.duplicateframe(0), -1.0)
  103. unblend2 = Average(input.trim(2,0), -1.0, input.trim(1,0), 2.0)
  104.  
  105. qmask1  = mt_makediff(unblend1.RemoveGrain(mode=19, modeU=-1, modeV=-1), unblend1)
  106. qmask2  = mt_makediff(unblend2.RemoveGrain(mode=19, modeU=-1, modeV=-1), unblend2)
  107. bmask   = mt_lutxy(qmask1, qmask2, yexpr="x 128 - abs y 128 - abs == 128 x 128 - abs 3 + y 128 - abs < 0 y 128 - abs 3 + x 128 - abs < 255 x 128 - abs y 128 - abs < 1 254 ? ? ? ?", uexpr="x", vexpr="x")
  108.  
  109. diff    = mt_lutxy(input.duplicateframe(0), input, yexpr="x y - abs", uexpr="x", vexpr="x").mt_expand()
  110. dmask   = mt_lutxy(diff,diff.trim(2,0), yexpr="x 2 * y < x 4 < & 0 y 2 * x < y 4 < & 255 x x y + / 200 * 28 + ? ?", uexpr="x", vexpr="x")
  111. pmask   = mt_lutxy(dmask, bmask, yexpr="y 0 > y 255 < & x 0 == x 255 == | & x y ?", uexpr="x", vexpr="x")
  112.  
  113. pp0     = Average(input.trim(2,0), -0.5, input.trim(1,0), 1.0, input, 1.0, input.duplicateframe(0), -0.5)
  114. pp1     = pp0.RemoveGrain(mode=0, modeU=12, modeV=12)
  115. pp2     = mt_merge(unblend1, unblend2, dmask.RemoveGrain(mode=12, modeU=-1, modeV=-1).greyscale(), Y=3, U=3, V=3)
  116. pp3     = pp2.RemoveGrain(mode=0, modeU=12, modeV=12)
  117. pp4     = mt_merge(unblend1, unblend2, bmask.RemoveGrain(mode=12, modeU=-1, modeV=-1), luma=true)
  118. pp5     = mt_merge(unblend1, unblend2, pmask.RemoveGrain(mode=12, modeU=-1, modeV=-1).greyscale(), Y=3, U=3, V=3)
  119. pp6 = mt_merge(pp5, unblend2, bmask.RemoveGrain(mode=12, modeU=-1, modeV=-1), Y=3, U=2, V=2).RemoveGrain(mode=0, modeU=12, modeV=12)
  120.  
  121.  
  122. ###### OUTPUT ######
  123. global source   = input
  124. global final    = IsString(pp) ? Eval(pp) : pp==1 ? pp1 : pp==2 ? pp2 : pp==3 ? pp3 : pp==4 ? pp4 : pp==5 ? pp5 : pp==6 ? pp6 : pp0
  125.  
  126.  
  127. ###### VAR.. ######
  128. global fdc0 = 1.0                               #(f)rame(d)ifference
  129. global fdn1     = 1.0
  130. global fdn2     = 1.0
  131.  
  132. global rvp1 = 1.0                               #(r)estore(v)alue
  133. global rvc0     = 1.0
  134. global rvn1     = 1.0
  135. global rvn2     = 1.0
  136.  
  137. global counter  = 2                             #pattern count variable
  138.  
  139.  
  140. ###### Conditional Function Chain, evaluated from bottom to top (!) ######
  141. #ScriptClip(source, " source.subtitle(string(rvc0)) ")
  142. ScriptClip(source, " counter==0 ? final : counter==1 ? source.trim(1,0) : source ")
  143.  
  144. FrameEvaluate(last, "
  145.     global fdp1 = fdc0
  146.     global fdc0 = fdn1
  147.     global fdn1 = fdn2
  148.     global fdn2 = AverageLuma(sdiff)
  149.  
  150.     global rvp2 = rvp1
  151.     global rvp1 = rvc0
  152.     global rvc0 = rvn1
  153.     global rvn1 = rvn2
  154.     global rvn2     = AverageLuma(re_lut)
  155.  
  156.     bcalc   = rvc0<rvp2 && rvc0<rvp1 && rvc0<rvn1 && rvc0<rvn2 ?
  157.         \ (rvp2<rvp1 && rvp2<rvn1 && rvp2<rvn2 ? rvp2 : rvp1<rvn1 && rvp1<rvn2 ? rvp1 : rvn1<rvn2 ? rvn1 : rvn2) / rvc0 :
  158.         \ rvc0<0.25*rvp1 && rvc0<0.25*rvn1 && (rvc0<0.5*rvp2 || rvc0<0.5*rvn2) ?
  159.         \ -0.25 * (2*rvp2<rvp1 && 2*rvp2<rvn1 && rvp2>rvn2 ? 2*rvp2 : 2*rvn2<rvp1 && 2*rvn2<rvn1 && rvn2>rvp2 ? 2*rvn2 : rvp1<rvn1 ? rvp1 : rvn1) / rvc0 : 0
  160.  
  161.     global counter  = counter==-1 ? 1 : (abs(bcalc)>1.0 && rvc0<10*mthresh || abs(bcalc)>thresh) &&
  162.             \ (counter>3 || bcalc>0) && (fdp1>mthresh || fdn1>mthresh || fdp1>0.5*fdc0 || fdn1>0.5*fdc0) ? 0 : counter+1
  163.  
  164.     global counter  = counter!=0 || sbd==false ? counter : fdp1<fdn1 && fdp1<mthresh ? -1 : fdn1<mthresh || fdc0<mthresh ? 1 : 0
  165.         ")
  166.            
  167. cache==-1 ? last.changefps(rate*2).changefps(rate,linear=true).addborders(8,0,0,0).crop(8,0,-0,-0) : \
  168.             cache<0 ? last : last.RequestLinear(8, cache, 5, false, false)
  169.  
  170. return(last)  
  171. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement