View Single Post
Old 22nd April 2021, 21:31   #23  |  Link
Dogway
Registered User
 
Join Date: Nov 2009
Posts: 2,361
I have been trying to come up with solutions for longer variable lifetime set at runtime functions, like inside scriptclip, the next is a proof of concept:

Code:
function MatteCrop2(clip c, int "width", int "height", float "thr", bool "CropMore", bool "Moving", int "ScanW", int "ScanH", int "mode", string "kernel", float "SC_thr") {

c
w      = width(c)
h      = height(c)

sisphbd = AvsPlusVersionNumber > 2294
bdpth   = sisphbd ? pow(256.,c.BitsPerComponent()/8.)/256. : 1.
contoy  = sisphbd ? !isy() : !isy8()
fullchr = contoy ? sisphbd ? ExtractU().width() == w : UToY8().width() == w : true

nw     = Default(width,w)
nh     = Default(height,h)
addw   = Default(ScanW,int(round((w/5))))
addh   = Default(ScanH,int(round((h/4))))
Mot    = Default(Moving, False)                             # If the matte is moving (sliding) this enables pixel level accuracy.
CM     = Default(CropMore, Mot || fullchr ? True : False)  # In case of odd cropping, either crop 1 pixel out or leave 1 pixel of the border
thr    = Default(thr, Mot ? 16.3 : 16.0)                    # Threshold, pixel values above this will be considered borders
mode   = Default(mode, 2)                                   # 0: center+pad 1: crop to minimum (WIP) 2: resize to maximum
SC_thr = Default(SC_thr, 3.5)
kernel = Default(kernel, "spline36")                        # Kernel to use when resizing (mode=2)

thr    = thr*bdpth

avg  = contoy ? sisphbd ? converttoy() : converttoy8() : last

avg  = avg.RatioResize(640.0,"adjust2w",kernel="bicubic")

blk_b  = avg.blankclip(pixel_type="Y8",fps=framerate(c),color=$000000).killaudio()
blk_w  = avg.blankclip(pixel_type="Y8",fps=framerate(c),color=$FFFFFF).killaudio()

avg  = avg.TemporalSoften(10,255,255,10,2)
avg  = avg.TemporalSoften(10,255,255,10,2)
avgsc= RatioResize(float(w),"adjust2w",kernel="bicubic").converttoyv12()
SC   = SCSelect_HBD(avg,blk_w,blk_b,blk_b,dfactor=SC_thr,mindif=1.0)

ScriptClip("""

isSC=YPlaneMax(SC)>128

# Obviously Defined() doesn't work here
Defined(x1) || Defined(y1) ? Eval("
for (LB=0, 1440, 1) {
  if (YPlaneMax(trim(SC,current_frame-LB,current_frame-LB))>128) {
    LBF=current_frame-LB
    LB=1440
   }
}
") : nop()

trim(avgsc,LBF,LBF)


x1=0 x2=0
y1=0 y2=0

step = Mot ? 1 : 2

addw != 0 ? Eval("
for (li=step, addw, step) {
  if (AverageLuma(crop(li-step,0,-w+li,0))>thr) {
    global x1= CM ? li : li-step
    li=addw
   }
}

for (ri=step, addw, step) {
  if (AverageLuma(crop(w-ri,0,-ri+step,0))>thr) {
    global x2= CM ? ri : ri-step
    ri=addw
  }
}") : nop()


addh != 0 ? Eval("
for (ti=step, addh, step) {
  if (AverageLuma(crop(0,ti-step,0,-h+ti))>thr) {
    global y1= CM ? ti : ti-step
    ti=addh
  }
}

for (bi=step, addh, step) {
  if (AverageLuma(crop(0,h-bi,0 ,-bi+step))>thr) {
    global y2= CM ? bi : bi-step
    bi=addh
  }
}") : nop()

#subtitle(string(y2),x=30,y=10,align=5)

MotW = Mot ? round(w-x1-x2) : nop()
MotH = Mot ? round(h-y1-y2) : nop()
Mot ? spline36resizeMT(c,fullchr?MotW:MotW+MotW%2,fullchr?MotH:MotH+MotH%2,src_left=x1,src_width=-x2,src_top=y1,src_height=-y2) : \
      crop(c,x1,y1,-x2,-y2)

mode == 0 ? padresize(w,h) : \
mode == 1 ? padresize(w,h) : \
            RatioResize(float(w),"adjust2w", kernel=kernel).padresize(w,h,mirror=false)

""",args="c,SC,avgsc,addw,addh,w,h,thr,CM,Mot,w,h,fullchr,kernel,mode",local=true, after_frame=false)


padresize(nw,nh)
(!CM || Mot) && mode==2 ? ContinuityFixer(left=addw>0?2:0, top=addh>0?2:0, right=addw>0?2:0, bottom=addh>0?2:0, radius=CM && w>720?0:1) : last 
}
I'm having a hard time setting and holding x1,x2,y1 and y2 variables available as long as there's no a new scene change. Indeed Global doesn't cut it, so for the time being I'm shifting frames in a for loop until a scene change is detected but this is very slow. I tried Gavino's solution here without success though.

Last edited by Dogway; 22nd April 2021 at 22:03.
Dogway is offline   Reply With Quote