SHOW:
|
|
- or go back to the newest paste.
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 or Decomb for decimating (external) |
15 | + | ## - TIVTC (for cache>-1, not default. or for decimating (external)) |
16 | ## - Decomb (if you want to use the function decimate for decimating) | |
17 | - | ## - v0.9b - 29.08.2016 for new Average |
17 | + | |
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 | - | ## The (s)ingle(b)lend(d)etection value is a boolean, Set it true for 12fps animations and so on. [bool ->false] |
56 | + | |
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 | - | Function FixBlendIVTC(clip input, "post", float "bthresh", "mthresh", bool "sbd", clip "dclip") |
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 | - | global thresh = 1.01 |
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 | - | last.changefps(rate*2).changefps(rate,linear=true).addborders(8,0,0,0).crop(8,0,-0,-0) |
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 | } |