mikeytown2
7th May 2008, 10:26
http://en.wikipedia.org/wiki/Split_screen_(film)
http://en.wikipedia.org/wiki/24_(TV_series)#Real_time
# SplitScreen() - May 8th, 2008
# Given 4 clips, resizes and arranges them. Similar to the TV show 24.
#
# Inputs
# Required
# int Width: output width.
# int Height: output height.
# int Border: size of black border padding the 4 clips.
# clip A,B,C,D: 4 input clips need the same frame rate and color space; Full Chroma - 4:4:4.
# A: Upper Left
# B: Upper Right
# C: Lower Left
# C: Lower Right
# Optional
# string ResizeMethod: name of resize function. Default = BilinearResize.
# bool AudioMix: mix audio from clips into a stereo signal. Default = true.
#
# Notes
# "Gravity" of the clips is towards the center of the screen.
# Clips can be different sizes.
# If AudioMix is false, sound is 8 channels. Assumes audio in clips is stereo.
function SplitScreen(int Width, int Height, int Border, clip A, clip B, clip C, clip D, string "ResizeMethod", bool "AudioMix")
{
#Check Clips For Full Chroma - 4:4:4
Assert((IsYV12(A) || IsYUY2(A)), "Clip A is not at full chroma (4:4:4). Convert to RGB")
Assert((IsYV12(B) || IsYUY2(B)), "Clip B is not at full chroma (4:4:4). Convert to RGB")
Assert((IsYV12(C) || IsYUY2(C)), "Clip C is not at full chroma (4:4:4). Convert to RGB")
Assert((IsYV12(D) || IsYUY2(D)), "Clip D is not at full chroma (4:4:4). Convert to RGB")
#Set Defaults
ResizeMethod = Default(ResizeMethod, "BilinearResize")
AudioMix = Default(AudioMix, true)
#Set Borders
BorderH = Border
BorderW = Border
#Set Width and Height of individual clips
NewW = Round(float(Width)/2.0 - float(BorderW)*1.5)
NewH = Round(float(Height)/2.0 - float(BorderH)*1.5)
#Process Video
A = A.ResizeKAR(NewW, NewH, ResizeMethod, NoBorders=True)
A = A.AddBorders(NewW-Width(A)+BorderW, NewH-Height(A) + BorderH, 0, 0)
B = B.ResizeKAR(NewW, NewH, ResizeMethod, NoBorders=True)
B = B.AddBorders(BorderW, NewH-Height(B) + BorderH, NewW-Width(B), 0)
C = C.ResizeKAR(NewW, NewH, ResizeMethod, NoBorders=True)
C = C.AddBorders(NewW-Width(C)+BorderW, BorderH, 0, NewH-Height(C))
D = D.ResizeKAR(NewW, NewH, ResizeMethod, NoBorders=True)
D = D.AddBorders(BorderW, BorderH, NewW-Width(D), NewH-Height(D))
#Merge Clips
X = StackHorizontal(A, B).AddBorders(0,0,BorderW,0)
Y = StackHorizontal(C, D).AddBorders(0,0,BorderW,0)
StackVertical(X, Y).AddBorders(0,0,0,BorderH).KillAudio()
#Fix Audio
LongestClip = Int(Max(Framecount(A), Framecount(B), Framecount(C), Framecount(D)))
A = (Framecount(A) <> LongestClip) ? A ++ BlankClip(A, LongestClip-Framecount(A)) : A
B = (Framecount(B) <> LongestClip) ? B ++ BlankClip(B, LongestClip-Framecount(B)) : B
C = (Framecount(C) <> LongestClip) ? C ++ BlankClip(C, LongestClip-Framecount(C)) : C
D = (Framecount(D) <> LongestClip) ? D ++ BlankClip(D, LongestClip-Framecount(D)) : D
#Mix Audio
Sound = (AudioMix) ? MergeChannels(MixAudio(ConvertToMono(A).Amplify(0.49), ConvertToMono(C).Amplify(0.49)), MixAudio(ConvertToMono(B).Amplify(0.49), ConvertToMono(D).Amplify(0.49))):
\ MergeChannels(GetLeftChannel(A), GetRightChannel(A), GetLeftChannel(B), GetRightChannel(B), GetLeftChannel(C), GetRightChannel(C), GetLeftChannel(D), GetRightChannel(D))
AudioDub(last, Sound)
}
function ResizeKAR(clip c, int maxW, int maxH, string "ResizeMethod", int "BackgroundColor", bool "NoBorders")
{
BackgroundColor = Default(BackgroundColor, $000000)
ResizeMethod = Default(ResizeMethod, "BilinearResize")
NoBorders = Default(NoBorders, False)
ratioS = Float(width(c))/Float(height(c))
ratioD = Float(maxW)/Float(maxH)
newW = Round(maxH*ratioS/2)*2
newH = Round(maxW/ratioS/2)*2
BorderH = (NoBorders==True) ? 0 : Round((maxH-newH)/2)
BorderW = (NoBorders==True) ? 0 : Round((maxW-newW)/2)
#Dest Higher Then Source; Dest Wider Then Source; Same Ratio
c =
\ (ratioS>ratioD) ?
\ Eval(ResizeMethod + "(c, " + String(maxW) + ", " + String(newH) + ")").
\ AddBorders(0, BorderH, 0, BorderH, BackgroundColor) :
\ (ratioS<ratioD) ?
\ Eval(ResizeMethod + "(c, " + String(newW) + ", " + String(maxH) + ")").
\ AddBorders(BorderW, 0, BorderW, 0, BackgroundColor) :
\ (ratioS==ratioD) ?
\ Eval(ResizeMethod + "(c, " + String(maxW) + ", " + String(maxH) + ")" ) :
\ nop()
#fix 1px changes, works only with 4:4:4
c =
\ IsInterleaved(c) && (maxW>width(c)) && (NoBorders==false) ? c.AddBorders(0, 0, 1, 0) :
\ IsInterleaved(c) && (maxH>height(c)) && (NoBorders==false) ? c.AddBorders(0, 0, 0, 1) :
\ c
return c
}
Examples:
A = ColorBars()
B = ColorBars().invert().FlipHorizontal()
C = ColorBars().FlipVertical()
D = ColorBars().invert().FlipVertical().FlipHorizontal()
SplitScreen(640, 200, 3, A, B, C, D)
http://img142.imageshack.us/img142/9049/splitscreenayx6.th.png (http://img142.imageshack.us/my.php?image=splitscreenayx6.png)
A = ColorBars()
B = ColorBars().invert().FlipHorizontal()
C = ColorBars().FlipVertical()
D = ColorBars().invert().FlipVertical().FlipHorizontal()
SplitScreen(640, 480, 3, A, B, C, D)
http://img142.imageshack.us/img142/5360/splitscreenbjw5.th.png (http://img142.imageshack.us/my.php?image=splitscreenbjw5.png)
A = ColorBars().Crop(10, 20, -30, -400)
B = ColorBars().invert().FlipHorizontal().Crop(10, 20, -300, -40)
C = ColorBars().FlipVertical().Crop(10, 200, -30, -40)
D = ColorBars().invert().FlipVertical().FlipHorizontal().Crop(100, 20, -30, -40)
SplitScreen(640, 480, 6, A, B, C, D)
http://img100.imageshack.us/img100/7105/splitscreendgt3.th.png (http://img100.imageshack.us/my.php?image=splitscreendgt3.png)
Modified ResizeKAR to not return a border
http://forum.doom9.org/showthread.php?t=135229
Other Posts/Functions on Subject:
http://forum.doom9.org/showthread.php?t=136375
http://forum.doom9.org/showthread.php?t=133883
http://avisynth.org/vcmohan/HollywoodSq/HollywoodSq.html
Edits:
May 7th 2008: Code cleanup and fixed potential rounding errors.
May 7th 2008: Got rid of Overlays and fixed a sound mixing issue. Eliminated border aspect ratio option since, it was already happening.
May 8th 2008: Checks for Full Chroma - 4:4:4.
http://en.wikipedia.org/wiki/24_(TV_series)#Real_time
# SplitScreen() - May 8th, 2008
# Given 4 clips, resizes and arranges them. Similar to the TV show 24.
#
# Inputs
# Required
# int Width: output width.
# int Height: output height.
# int Border: size of black border padding the 4 clips.
# clip A,B,C,D: 4 input clips need the same frame rate and color space; Full Chroma - 4:4:4.
# A: Upper Left
# B: Upper Right
# C: Lower Left
# C: Lower Right
# Optional
# string ResizeMethod: name of resize function. Default = BilinearResize.
# bool AudioMix: mix audio from clips into a stereo signal. Default = true.
#
# Notes
# "Gravity" of the clips is towards the center of the screen.
# Clips can be different sizes.
# If AudioMix is false, sound is 8 channels. Assumes audio in clips is stereo.
function SplitScreen(int Width, int Height, int Border, clip A, clip B, clip C, clip D, string "ResizeMethod", bool "AudioMix")
{
#Check Clips For Full Chroma - 4:4:4
Assert((IsYV12(A) || IsYUY2(A)), "Clip A is not at full chroma (4:4:4). Convert to RGB")
Assert((IsYV12(B) || IsYUY2(B)), "Clip B is not at full chroma (4:4:4). Convert to RGB")
Assert((IsYV12(C) || IsYUY2(C)), "Clip C is not at full chroma (4:4:4). Convert to RGB")
Assert((IsYV12(D) || IsYUY2(D)), "Clip D is not at full chroma (4:4:4). Convert to RGB")
#Set Defaults
ResizeMethod = Default(ResizeMethod, "BilinearResize")
AudioMix = Default(AudioMix, true)
#Set Borders
BorderH = Border
BorderW = Border
#Set Width and Height of individual clips
NewW = Round(float(Width)/2.0 - float(BorderW)*1.5)
NewH = Round(float(Height)/2.0 - float(BorderH)*1.5)
#Process Video
A = A.ResizeKAR(NewW, NewH, ResizeMethod, NoBorders=True)
A = A.AddBorders(NewW-Width(A)+BorderW, NewH-Height(A) + BorderH, 0, 0)
B = B.ResizeKAR(NewW, NewH, ResizeMethod, NoBorders=True)
B = B.AddBorders(BorderW, NewH-Height(B) + BorderH, NewW-Width(B), 0)
C = C.ResizeKAR(NewW, NewH, ResizeMethod, NoBorders=True)
C = C.AddBorders(NewW-Width(C)+BorderW, BorderH, 0, NewH-Height(C))
D = D.ResizeKAR(NewW, NewH, ResizeMethod, NoBorders=True)
D = D.AddBorders(BorderW, BorderH, NewW-Width(D), NewH-Height(D))
#Merge Clips
X = StackHorizontal(A, B).AddBorders(0,0,BorderW,0)
Y = StackHorizontal(C, D).AddBorders(0,0,BorderW,0)
StackVertical(X, Y).AddBorders(0,0,0,BorderH).KillAudio()
#Fix Audio
LongestClip = Int(Max(Framecount(A), Framecount(B), Framecount(C), Framecount(D)))
A = (Framecount(A) <> LongestClip) ? A ++ BlankClip(A, LongestClip-Framecount(A)) : A
B = (Framecount(B) <> LongestClip) ? B ++ BlankClip(B, LongestClip-Framecount(B)) : B
C = (Framecount(C) <> LongestClip) ? C ++ BlankClip(C, LongestClip-Framecount(C)) : C
D = (Framecount(D) <> LongestClip) ? D ++ BlankClip(D, LongestClip-Framecount(D)) : D
#Mix Audio
Sound = (AudioMix) ? MergeChannels(MixAudio(ConvertToMono(A).Amplify(0.49), ConvertToMono(C).Amplify(0.49)), MixAudio(ConvertToMono(B).Amplify(0.49), ConvertToMono(D).Amplify(0.49))):
\ MergeChannels(GetLeftChannel(A), GetRightChannel(A), GetLeftChannel(B), GetRightChannel(B), GetLeftChannel(C), GetRightChannel(C), GetLeftChannel(D), GetRightChannel(D))
AudioDub(last, Sound)
}
function ResizeKAR(clip c, int maxW, int maxH, string "ResizeMethod", int "BackgroundColor", bool "NoBorders")
{
BackgroundColor = Default(BackgroundColor, $000000)
ResizeMethod = Default(ResizeMethod, "BilinearResize")
NoBorders = Default(NoBorders, False)
ratioS = Float(width(c))/Float(height(c))
ratioD = Float(maxW)/Float(maxH)
newW = Round(maxH*ratioS/2)*2
newH = Round(maxW/ratioS/2)*2
BorderH = (NoBorders==True) ? 0 : Round((maxH-newH)/2)
BorderW = (NoBorders==True) ? 0 : Round((maxW-newW)/2)
#Dest Higher Then Source; Dest Wider Then Source; Same Ratio
c =
\ (ratioS>ratioD) ?
\ Eval(ResizeMethod + "(c, " + String(maxW) + ", " + String(newH) + ")").
\ AddBorders(0, BorderH, 0, BorderH, BackgroundColor) :
\ (ratioS<ratioD) ?
\ Eval(ResizeMethod + "(c, " + String(newW) + ", " + String(maxH) + ")").
\ AddBorders(BorderW, 0, BorderW, 0, BackgroundColor) :
\ (ratioS==ratioD) ?
\ Eval(ResizeMethod + "(c, " + String(maxW) + ", " + String(maxH) + ")" ) :
\ nop()
#fix 1px changes, works only with 4:4:4
c =
\ IsInterleaved(c) && (maxW>width(c)) && (NoBorders==false) ? c.AddBorders(0, 0, 1, 0) :
\ IsInterleaved(c) && (maxH>height(c)) && (NoBorders==false) ? c.AddBorders(0, 0, 0, 1) :
\ c
return c
}
Examples:
A = ColorBars()
B = ColorBars().invert().FlipHorizontal()
C = ColorBars().FlipVertical()
D = ColorBars().invert().FlipVertical().FlipHorizontal()
SplitScreen(640, 200, 3, A, B, C, D)
http://img142.imageshack.us/img142/9049/splitscreenayx6.th.png (http://img142.imageshack.us/my.php?image=splitscreenayx6.png)
A = ColorBars()
B = ColorBars().invert().FlipHorizontal()
C = ColorBars().FlipVertical()
D = ColorBars().invert().FlipVertical().FlipHorizontal()
SplitScreen(640, 480, 3, A, B, C, D)
http://img142.imageshack.us/img142/5360/splitscreenbjw5.th.png (http://img142.imageshack.us/my.php?image=splitscreenbjw5.png)
A = ColorBars().Crop(10, 20, -30, -400)
B = ColorBars().invert().FlipHorizontal().Crop(10, 20, -300, -40)
C = ColorBars().FlipVertical().Crop(10, 200, -30, -40)
D = ColorBars().invert().FlipVertical().FlipHorizontal().Crop(100, 20, -30, -40)
SplitScreen(640, 480, 6, A, B, C, D)
http://img100.imageshack.us/img100/7105/splitscreendgt3.th.png (http://img100.imageshack.us/my.php?image=splitscreendgt3.png)
Modified ResizeKAR to not return a border
http://forum.doom9.org/showthread.php?t=135229
Other Posts/Functions on Subject:
http://forum.doom9.org/showthread.php?t=136375
http://forum.doom9.org/showthread.php?t=133883
http://avisynth.org/vcmohan/HollywoodSq/HollywoodSq.html
Edits:
May 7th 2008: Code cleanup and fixed potential rounding errors.
May 7th 2008: Got rid of Overlays and fixed a sound mixing issue. Eliminated border aspect ratio option since, it was already happening.
May 8th 2008: Checks for Full Chroma - 4:4:4.