View Full Version : ImageBorders & FrostyBorders Scripts
hello_hello
14th November 2017, 23:59
FrostyBorders
In addition to the Avisynth version, FrostyBorders now comes in a VapourSynth flavour.
Support for resizing based on a sample aspect ratio in frame properties has been added to both versions.
FrostyBorders 2025-12-20.zip (https://files.videohelp.com/u/210984/FrostyBorders%202025-12-20.zip)
For anyone who experienced the FastBlur bug (occasional flashes of blocky color in the borders) FastBlur has been updated to version 0.3.2 and the bug should be fixed. Links: FastBlur 0.3.2 (https://forum.doom9.org/showthread.php?p=2013443#post2013443) / FastBlur 4.0 (https://forum.doom9.org/showthread.php?p=2028170#post2028170)
Post #2 here (https://forum.videohelp.com/threads/393762-ImageBorders-FrostyBorders-Scripts#post2555438) contains instructions for running either the Avisynth or VapourSynth version of FrostyBorders automatically while watching any video in MPC-HC or MPC-BE.
Post #3 here (https://forum.videohelp.com/threads/393762-ImageBorders-FrostyBorders-Scripts#post2555451) contains instructions for running the VapourSynth version of FrostyBorders automatically while watching any video in SMPlayer or MPV Player.
The simplest way to use FrostyBorders is to specify a width and height, and the script resizes and adds FrostyBorders as required.
FrostyBorders(832,468)
You can also specify cropping, and for anamorphic sources, the appropriate input display aspect ratio or sample aspect ratio.
ie FrostyBorders(960,540, 6,4,-8,-2, InDAR=4.0/3.0)
The original and default frosty borders.
FrostyBorders(832,468)
https://i.postimg.cc/x8QY9yYY/Frosty-true.jpg
Feathering.
FrostyBorders(832,468, Feather=24)
https://i.postimg.cc/c4sZjmXB/Feather-24.jpg
Clone borders (type 1).
FrostyBorders(832,468, Clone=1)
https://i.postimg.cc/d39F3ktC/Clone-1.jpg
Clone borders (type 3) with border divider.
FrostyBorders(832,468, Clone=3, BDivider=2)
(Sides of picture heavily cropped to demonstrate)
https://i.postimg.cc/FFbNDqgK/Clone-3-BDivider-2.jpg
Static frosty borders.
FrostyBorders(832,468, FrostyStatic=8756)
https://i.postimg.cc/FHqpT5zj/Static-Frosty2.jpg
Color borders with gradient.
FrostyBorders(720,540, FrostyGradient=true, BColor=color_teal)
https://i.postimg.cc/nc30QQtS/Frosty-Color.jpg
Frosty border thumbnails
https://i.postimg.cc/nzSzFkMg/Frosty-Borders-1.jpg
https://i.postimg.cc/yNPx5BKV/Frosty-Borders-2.jpg
https://i.postimg.cc/tT4JGfRF/Frosty-Borders-3.jpg
ImageBorders
ImageBorders 2021-12-09.zip (https://files.videohelp.com/u/210984/ImageBorders%202021-12-09.zip)
A function for adding images as borders to a video, rather than plain black borders.
Standard usage is to specify a width and height, and the image(s) to be used for the borders, and the script resizes and adds the image borders as required.
Border = ImageSource("Border.bmp")
ImageBorders(640,360, Border)
https://i.postimg.cc/JzH96Cm2/Pillarbox.jpg
A = AVISource("Video.avi").Trim(476,476)
ImageBorders(640,360, A, Stretch=false)
https://i.postimg.cc/RVNP3tRK/Letter-Box.jpg
A = ImageSource("Elvis1.png")
B = ImageSource("Elvis2.png")
ImageBorders(640,360, A, B, InDAR=4.0/3.0)
Picture courtesy of amaipaipai (https://forum.videohelp.com/threads/393752-CropResize-Cropping-resizing-script/page4#post2576283).
https://i.postimg.cc/xjsxT5K9/Elvis.jpg
Sparktank
15th November 2017, 03:47
Nifty! Thanks for this.
hello_hello
15th November 2017, 10:25
My pleasure. If you follow the link at the top of the script referring to raffriff42, you'll find his version of the script with more options, and a second version around post #29, I think. Mine is also a little configurable, but the borders it creates are mainly configured to my taste, so raffriff42's scripts would also be worth a look.
raffriff42
16th November 2017, 14:51
If you follow the link at the top of the script referring to raffriff42, you'll find his version of the script with more options, and a second version around post #29, I think. Mine is also a little configurable, but the borders it creates are mainly configured to my taste, so raffriff42's scripts would also be worth a look.Thanks hello_hello; likewise I'm sure. The newest link is here (https://forum.videohelp.com/threads/385341-avisynth-how-to-add-borders#post2498883), and here (https://youtu.be/pvrjKZWFCmM) is a short video clip. These effects don't encode well (due to the fixed-pattern noise); they're for live viewing.
And before somebody says it, yes, there is nothing wrong with plain black borders. These effects are just for fun - a little ambient light surround when viewing shows that aren't as widescreen as your monitor.
hello_hello
16th November 2017, 18:08
And before somebody says it, yes, there is nothing wrong with plain black borders. These effects are just for fun - a little ambient light surround when viewing shows that aren't as widescreen as your monitor.
Actually for Plasma owners such as myself, the coloured borders have a practical purpose. They should prevent the "burnt-in" look after watching a lot of video with black borders. It's not really burnt-in, as the effect disappears fairly quickly, but coloured borders will help the screen to age more evenly. The TV has a 4:3 mode with an option to create light grey borders itself, but they're fugly.
Previously I've zoomed to 16:9 and now I won't have to. I probably still will much of the time, but it's not compulsory any more. ;)
hello_hello
22nd November 2017, 15:00
Well it turns out I'm too stupid to use a computer.
When I fixed the resizing problem for the last version of the script I must have had a stupid and broke the ability to set a pixel aspect ratio. The script worked perfectly for square pixel sources, but for anamorphic sources it was stretching and squishing them.
While I was at it I also blatantly stole an idea from raffriff42 for checking the size of the borders, although rather than not add them, the script will add black borders instead until they reach 16 pixels wide each side, or top and bottom, when they'll turn frosty. Thanks raffriff42 :)
The new version of my script it in the opening post.
hello_hello
15th February 2018, 01:43
I made quite a few changes to the script and fixed a bug. Hopefully I didn't introduce any new ones.
- Fixed a silly that sometimes caused the script to throw an error when large top/bottom borders were added.
- Added "InDAR" option. For anamorphic sources a display aspect ratio can be specified for correct resizing rather than a pixel aspect ratio (although the latter option can still be used).
- Improved handling of anamorphic sources. The default width is now the width after resizing to square pixel dimensions and the default height is the source height, so the script can be used for resizing anamorphic sources simply by not specifying a width or height (or specifying zero for both).
- Added "Frosty" option. Frosty=false adds plain black or colored borders instead of FrostyBorders.
- Added a wrapper function called Borders() for adding plain borders. It has the same options as FrostyBorders().
Borders() is the same as FrostyBorders(Frosty=false)
- Added "BColor" option for specifying the color of borders when the script is adding plain black or colored borders.
- Increased the sensitivity to scene changes. The frosty borders should change instantly on most scene changes now.
- Removed the "Gradient" option as it didn't look very good.
When resizing, the script still uses the Avisynth resizer (Spline36Resize) to apply any sub-pixel cropping required for zero aspect error.
There's a link for the new version (2018-02-15) in the opening post.
hello_hello
18th July 2019, 01:45
As I discovered the FastBlur (https://forum.doom9.org/showpost.php?p=1878232&postcount=1) plugin the other day, I thought I'd give it a spin blurring for the FrostyBorders function, and it was a big improvement. When the edges of the picture are "busy", the new version looks like this:
https://i.postimg.cc/7LDbmhps/Frosty-Borders-New.jpg
Whereas the old version looked like this:
https://i.postimg.cc/kX02Rfwd/Frosty-Borders-Old.jpg
The new version is also more configurable, giving more control over how the borders look. It's now also possible to specify a resizer rather than only being able to use the default.
For anyone who's downloaded it recently, I'll update the CropResize (https://forum.doom9.org/showthread.php?t=176667) script again with the new version of FrostyBorders. Sometime soonish. The new version will be dated 2019-07-20 or later.
FranceBB
18th July 2019, 05:03
Works like a charm. Thanks.
https://i.imgur.com/R3Bz2nR.jpg
4 : 3 original footage (https://i.imgur.com/DYKeiXR.jpg)
16 : 9 frostyborders resize (https://i.imgur.com/R3Bz2nR.jpg)
Sparktank
18th July 2019, 05:16
nice update!
"I love it when a plan comes together." ~Liam Neeson (the original was before my time)
hello_hello
19th July 2019, 02:00
Does FastBlur() crash for anyone else when the width isn't mod8 for YV12 video? I think it's a bug because the height mod doesn't seem to matter.
Here's a version that enforces a mod8 output width and resizes the picture width to mod8 (cropping if required). That seemed the easiest way to ensure mod8 borders. There'll only be an error message if FrostyBorders are actually being added and the output width isn't mod8. the output width isn't restricted when plain borders are added. If the output width isn't mod16 the picture mightn't be centred as the borders have to be mod8 both sides. It depends if the picture itself ends up mod8 or mod16.
ie 104 left border and 112 right border, rather than 108 each side, as they could be for mod4 borders.
Link removed
hello_hello
19th July 2019, 12:29
Well my OCD kicked in and I changed the "mod8" fix version a little. When FrostyBorders are being added to the sides the output width can be any mod and the script will adjust the borders and cropping as required to keep them mod8.
When FrostyBorders are being added top and bottom the output width needs to be mod8.
None of the above applies when adding plain borders.
I also tweaked a couple of things so there's a new version of the script without the mod8 width fix too. Hopefully the FastBlur bug will be fixed and the "normal" version of the script can be used again. Both new versions are dated 2019-07-19.
Link removed
BetA13
20th July 2019, 02:23
ok, please dont laugh... :)
Could someone point me to an tutorial or have an short explonation how i would use this with, lets say mpchc or potplayer?
i tried via ffdshow´s avisynth but that one does not reconize AVSI files.. and if i force select it, nothing happens...
i really think this is a very cool solution for people having 16:10 monitors...
Thanks..
hello_hello
20th July 2019, 12:11
So it turns out the FastBlur mod8 width problem only effects CPUs that don't support SSE4.1 (FastBlur 0.1).
I don't know why I didn't do it originally, but the "mod8 width fix" version of FrostyBorders now pads the borders to mod8 if need be, blurs them, then crops them back to the original width. The output should be the same as the standard version of the script and there's no longer any output width or height restrictions.
Both versions of the script are in the zip file in the opening post, now dated 2019-07-20.
hello_hello
20th July 2019, 12:45
ok, please dont laugh... :)
Could someone point me to an tutorial or have an short explonation how i would use this with, lets say mpchc or potplayer?
i tried via ffdshow´s avisynth but that one does not reconize AVSI files.. and if i force select it, nothing happens...
i really think this is a very cool solution for people having 16:10 monitors...
Thanks..
Put FrostyBorders.avsi in the Avisynth plugins folder, along with FastBlur.dll and AddGrainC.dll. It's somewhere like
C:\Program Files\AviSynth\plugins
Add the following to ffdshow's Avisynth filter.
#Crop(0, 0, 0, 0)
HMax = 720
H = min(HMax, height(last))
W = floor(H * 16.0 / 9.0 / 4.0) * 4
FrostyBorders(W, H)
HMax is the maximum height. If the video height exceeds that, it'll be resized down. Set it to whatever you prefer.
Change "9.0" in the 4th line to "10.0" if you have a 16:10 monitor.
If the edges of the video aren't clean (there's a bit of black at the sides etc), remove "#" from the Crop line and add the required cropping to clean the edges. Something like Crop(4, 0, -4, 0), or whatever it needs.
Use the version dated 2019-07-20. Not long ago I changed it so the borders are created after the video is resized (if it's resized) so if you reduce the resolution it should be a bit faster. Previously the script created the borders from the source (at least partly), then did the resizing. I can't remember exactly when I changed it off the top of my head, so use the latest one.
BetA13
20th July 2019, 15:26
Thank you very much Sir...
Will try that as soon as i get back to my PC..
Have a wonderull evening...
FranceBB
21st July 2019, 09:32
ok, please dont laugh... :)
Could someone point me to an tutorial or have an short explonation how i would use this with, lets say mpchc or potplayer?
i tried via ffdshow´s avisynth but that one does not reconize AVSI files.. and if i force select it, nothing happens...
i really think this is a very cool solution for people having 16:10 monitors...
Thanks..
It's gonna work with MPC and similar, but I'm not sure whether it's gonna work with PotPlayer or not, 'cause if I remember correctly PotPlayer rendering engine doesn't like when Avisynth resizes the picture before it outputs it, making the whole program crash, which was the reason why my VideoTek (https://forum.doom9.org/showthread.php?p=1832846) was unusable live on PotPlayer. :(
BetA13
21st July 2019, 23:49
Using it with Mpc hc anyway :)
And it works really well, looks nice and fills all the screen perfectly..
Screen:
Top / Bottom
https://i.imgur.com/CE3nxCU.jpg
Sides
https://i.imgur.com/2dPGEUU.png
Performance wise? Well, for an i5 or i7 it should be unsicnificant.
But for me, with an ancient Q9550 Core2Quad (@4Ghz), it uses about 20% CPU when activated. I guess its time for an Upgrade.. maybe an cheap mid range intel if they drop prices, also the AMD 3600 looks pretty decent..
Anyway, youtube videos never looked this nice on my little 16:10 Monitor..
Thanks again for the Help ;)
@FranceBB
nice tool from what it looks like...
wonkey_monkey
22nd July 2019, 00:31
Sides
https://i.imgur.com/2dPGEUU.png
What is that?
BetA13
22nd July 2019, 02:02
haha...
That my dear Sir is: "The Thing From Another World (1951)"
The Original "The Thing"..
Sadly in an bad Quality, i know.. :(
Greetz
StainlessS
22nd July 2019, 02:29
Performance wise? Well, for an i5 or i7 it should be unsicnificant.
But for me, with an ancient Q9550 Core2Quad (@4Ghz)
I got a Q9550 @ 2.83 GHz, you must be overclocking a little. [EDIT: liquid cooled ?]
EDIT: To below, yep looks like you musta got lucky,
dont scrap it if you get a new one, keep it as rendering machine, then you dont care how long it takes.
Cheers.
BetA13
22nd July 2019, 02:38
I got a Q9550 @ 2.83 GHz, you must be overclocking a little.
jup, quite a little ;) Tweaked it the first Day i got it, its still doing its job at that OC...(dialing in the right voltages and stuff did take me a good junk of Time.)
That Thing is 11 years old allready but still a good Chip for most stuff.. i guess i was lucky in the silicon lottery (for once) since i manage that OC at 1.26 vcore under full load.. Stays under 60C° no matter what i throw at him.
anyway, im off topic :)
greetz
EDIT:
nope, all AIR cooled..
And i should mention that im using a modded Bios.
Good old times...
hello_hello
26th March 2020, 07:37
Updated the FrostyBorders function and added the ImageBorders function to the thread. Both are dated 2020-03-26. There's links in the opening post.
FranceBB
9th March 2021, 09:38
Hi Hello Hello, what happened to Frosty Borders? The links are gone, as it redirects to Video Help saying that the file no longer exists.
Anyway, in case anyone is looking for this script, here is my backup copy from 26-03-2020:
function FrostyBorders(clip Source, int "OutWidth", int "OutHeight", val "InDAR", val "InSAR", int "Mod", \
float "Bright", float "BrightL", float "Cont", float "ContL", float "Sat", float "SatL", \
float "Blend", float "BlendL", float "Blur", float "BlurL", float "VBlur", float "VBlurL", \
Int "Iterations", Int "IterationsL", float "Texture", float "TextureL", val "BColor", val "BColorL", \
string "Resizer", bool "Frosty", bool "Info") {
Source_Width = width(Source)
F_Source_Width = float(Source_Width)
Source_Height = height(Source)
F_Source_Height = float(Source_Height)
assert(HasVideo(Source) && (Source_Width > 48), " ImageBorders " + chr(10) + " No video found " + chr(10))
IsAvisynthPlus = \
(FindStr(LCase(VersionString), "avisynth+") > 0) || (FindStr(LCase(VersionString), "avisynth neo") > 0)
Color_Format = PixelType(Source)
Chroma420 = IsAvisynthPlus ? Is420(Source) : IsYV12(Source)
Chroma422 = IsAvisynthPlus ? Is422(Source) : IsYV16(Source)
Chroma444 = IsAvisynthPlus ? Is444(Source) : IsYV24(Source)
ModTwoWidth = Chroma420 || Chroma422 || IsYUY2(Source)
ModFourWidth = IsYV411(Source)
ModTwoHeight = Chroma420
Crop_WMod = ModFourWidth ? 4 : ModTwoWidth ? 2 : 1
Crop_HMod = ModTwoWidth ? 2 : 1
InDAR = default(InDAR, 0.0)
InSAR = default(InSAR, 0.0)
Bright = default(Bright, 0.0)
BrightL = default(BrightL, -25.0)
Cont = default(Cont, 1.0)
ContL = default(ContL, 0.66)
Sat = default(Sat, 0.85)
SatL = default(SatL, 0.66)
Blend = default(Blend, 0.20)
BlendL = default(BlendL, Blend)
Blur = default(Blur, 50)
BlurL = default(BlurL, Blur)
VBlur = default(VBlur, Blur)
VBlurL = default(VBlurL, BlurL)
Iterations = default(Iterations, 3)
IterationsL = default(IterationsL, Iterations)
Texture = default(Texture, 5.0)
TextureL = default(TextureL, Texture)
BColor = default(BColor, $000000)
BColorL = default(BColorL, BColor)
Resizer = default(Resizer, "Spline36")
Frosty = default(Frosty, true)
Info = default(Info, false)
WidthTest = false
HeightTest = false
WMod = default(Mod, (Crop_WMod == 2) ? 4 : (Crop_WMod == 4) ? 8 : 2)
HMod = default(Mod, (Crop_HMod == 2) ? 4 : 2)
F_WMod = float(WMod)
F_HMod = float(HMod)
IsResizeAppended = (RightStr(Resizer, 6) == "Resize")
Resizer = !IsResizeAppended ? Resizer : LeftStr(Resizer, StrLen(Resizer) - 6)
IsAvisynthResizer = (Resizer == "Bilinear") || (Resizer == "Bicubic") || (Resizer == "Blackman") || \
(Resizer == "Gauss") || (Resizer == "Lanczos") || (Resizer == "Lanczos4") || (Resizer == "Point") || \
(Resizer == "Spline16") || (Resizer == "Spline36") || (Resizer == "Spline64") || (Resizer == "Sinc")
Resizer = IsAvisynthResizer || (!IsAvisynthResizer && IsResizeAppended) ? Resizer + "Resize" : Resizer
Source_Sample_Aspect = (InSAR > 0) ? InSAR : (InDAR > 0) ? (F_Source_Height * InDAR / F_Source_Width) : 1.0
Source_Display_Aspect = (Source_Sample_Aspect == 1.0) ? F_Source_Width / F_Source_Height : \
(InDAR > 0) ? InDAR : (F_Source_Width * Source_Sample_Aspect / F_Source_Height)
Mod_Source_Width = \
(Source_Sample_Aspect == 1.0) ? floor(F_Source_Width / F_WMod) * WMod : \
(InDAR > 0) ? floor(F_Source_Height * InDAR / F_WMod) * WMod : \
floor(F_Source_Width * Source_Sample_Aspect / F_WMod) * WMod
Mod_Source_Storage_Aspect = float(Mod_Source_Width) / F_Source_Height
OutWidth = default(OutWidth, 0)
OutWidth = (OutWidth == 0) ? Mod_Source_Width : OutWidth
OutHeight = default(OutHeight, 0)
OutHeight = (OutHeight == 0) ? Source_Height : OutHeight
F_OutWidth = float(OutWidth)
F_OutHeight = float(OutHeight)
Output_Storage_Aspect = (F_OutWidth / F_OutHeight)
assert((InDAR == 0) || ((InDAR > 0) && !IsInt(InDAR) && IsFloat(InDAR)), " FrostyBorders " + chr(10) + \
" InDAR must be a positive floating point number " + chr(10) + " (15.0/11.0 or 1.363636 etc) " + chr(10))
assert((InSAR == 0) || ((InSAR > 0) && !IsInt(InSAR) && IsFloat(InSAR)), " FrostyBorders " + chr(10) + \
" InSAR must be a positive floating point number " + chr(10) + " (10.0/11.0 or 0.909091 etc) " + chr(10))
assert((InDAR == 0) || (InSAR == 0), \
" FrostyBorders " + chr(10) + " InDAR & InSAR can't be specified at the same time " + chr(10))
assert((WMod == 1) || (WMod == 2) || (WMod == 4) || (WMod == 8) || (WMod == 16), \
" ImageBorders " + chr(10) + " Mod must be 1, 2, 4, 8 or 16 " + chr(10))
(abs(Output_Storage_Aspect - Source_Display_Aspect) >= 0.000033) ? Eval("""
assert(!ModTwoWidth || (WMod % 2 == 0) || (Output_Storage_Aspect < Mod_Source_Storage_Aspect), \
" ImageBorders " + chr(10) + " " + Color_Format + " requires mod2 picture width resizing " + chr(10))
assert(!ModFourWidth || (WMod % 4 == 0) || (Output_Storage_Aspect < Mod_Source_Storage_Aspect), \
" ImageBorders " + chr(10) + " " + Color_Format + " requires mod4 picture width resizing " + chr(10))
assert(!ModTwoHeight || (HMod % 2 == 0) || (Output_Storage_Aspect >= Mod_Source_Storage_Aspect), \
" ImageBorders " + chr(10) + " " + Color_Format + " requires mod2 picture height resizing " + chr(10))
""", "Mod Eval") : nop()
assert(-255 <= Bright <= 255, " FrostyBorders " + chr(10) + " The valid range for Bright is -255 thru 255 ")
assert(-255 <= BrightL <= 255, " FrostyBorders " + chr(10) + " The valid range for BrightL is -255 thru 255 ")
assert(0 <= Cont <= 10, " FrostyBorders " + chr(10) + " The valid range for Cont is 0.0 thru 10.0 ")
assert(0 <= ContL <= 10, " FrostyBorders " + chr(10) + " The valid range for ContL is 0.0 thru 10.0 ")
assert(0 <= Sat <= 10, " FrostyBorders " + chr(10) + " The valid range for SatL is 0.0 thru 10.0 ")
assert(0 <= SatL <= 10, " FrostyBorders " + chr(10) + " The valid range for Sat is 0.0 thru 10.0 ")
assert(0 <= Blend <= 1, " FrostyBorders " + chr(10) + " The valid range for Blend is 0.0 to 1.0 ")
assert(0 <= BlendL <= 1, " FrostyBorders " + chr(10) + " The valid range for BlendL is 0.0 to 1.0 ")
(abs(Output_Storage_Aspect - Source_Display_Aspect) < 0.000033) ? Eval("""
Resized_Picture = (OutWidth == Source_Width) && (OutHeight == Source_Height) ? Source : \
Eval("Source." + Resizer + "(OutWidth, OutHeight)")
""", "Resizing 1 Eval") : (Output_Storage_Aspect >= Mod_Source_Storage_Aspect) ? Eval("""
F_New_Width = \
(Source_Sample_Aspect == 1.0) ? (F_OutHeight * F_Source_Width / F_Source_Height) : \
(InDAR > 0) ? (F_OutHeight * InDAR) : \
(F_OutHeight * F_Source_Width * Source_Sample_Aspect / F_Source_Height)
Resizing_Width = floor(F_New_Width / F_WMod) * WMod
F_Resizing_Width = float(Resizing_Width)
F_Width_Cropping = \
max(0, (Source_Width - (F_Source_Height * F_Resizing_Width / F_OutHeight / Source_Sample_Aspect)) / 2.0)
Resizer_Crop_LR = max(0, F_Width_Cropping - (floor(F_Width_Cropping / F_WMod) * WMod))
Crop_LR = max(0, round(F_Width_Cropping - Resizer_Crop_LR))
Resized_Picture = \
Eval("Source.Crop(Crop_LR, 0, -Crop_LR, 0)." + Resizer + "(Resizing_Width, OutHeight, \
src_left=Resizer_Crop_LR, src_top=0, src_width=-Resizer_Crop_LR, src_height=0)")
Additional_Width = OutWidth - Resizing_Width
BL = min(Additional_Width, floor(float(Additional_Width) / 2.0 / float(Crop_WMod)) * Crop_WMod)
BR = Additional_Width - BL
WidthTest = (BL >= 16) && (BR >= 16) && Frosty
""", "Resizing 2 Eval") : Eval("""
F_New_Height = (Source_Sample_Aspect == 1.0) ? (F_OutWidth * F_Source_Height / F_Source_Width) : \
(InDAR > 0) ? (F_OutWidth / InDAR) : \
(F_OutWidth * F_Source_Height / F_Source_Width / Source_Sample_Aspect)
Resizing_Height = floor(F_New_Height / F_HMod) * HMod
F_Resizing_Height = float(Resizing_Height)
F_Height_Cropping = \
max(0, (Source_Height - (F_Source_Width * F_Resizing_Height * Source_Sample_Aspect / F_OutWidth)) / 2.0)
Resizer_Crop_TB = max(0, F_Height_Cropping - (floor(F_Height_Cropping / F_HMod) * HMod))
Crop_TB = max(0, round(F_Height_Cropping - Resizer_Crop_TB))
Resized_Picture = \
Eval("Source.Crop(0, Crop_TB, 0, -Crop_TB)." + Resizer + "(OutWidth, Resizing_Height, \
src_left=0, src_top=Resizer_Crop_TB, src_width=0, src_height=-Resizer_Crop_TB)")
Additional_Height = OutHeight - Resizing_Height
BT = min(Additional_Height, floor(float(Additional_Height) / 2.0 / float(Crop_HMod)) * Crop_HMod)
BB = Additional_Height - BT
HeightTest = (BT >= 16) && (BB >= 16) && Frosty
""", "Resizing 3 Eval")
(abs(Output_Storage_Aspect - Source_Display_Aspect) < 0.000033) ? Eval("""
Output = Resized_Picture
""", "Add Borders 1 Eval") : WidthTest && (Output_Storage_Aspect >= Mod_Source_Storage_Aspect) ? Eval("""
W_Crop = Resizing_Width - 64
PillarBox_Background = \
StackHorizontal(Resized_Picture.crop(0, 0, -W_Crop, 0), Resized_Picture.crop(W_Crop, 0, 0, 0))\
.TemporalSoften(7, 255, 255, 20, 2).Tweak(bright=Bright, cont=Cont, sat=Sat)
PB_Crop = width(PillarBox_Background) - 16
Left = PillarBox_Background.crop(0, 0, -PB_Crop, 0)
Right = PillarBox_Background.crop(PB_Crop, 0, 0, 0)
Blend_Left = \
(Blend == 0) ? Left : (Blend == 1) ? FlipHorizontal(Right) : Overlay(Left, FlipHorizontal(Right), Opacity=Blend)
Blend_Right = \
(Blend == 0) ? Right : (Blend == 1) ? FlipHorizontal(Left) : Overlay(Right, FlipHorizontal(Left), Opacity=Blend)
Frosty_Left = Blend_Left.GaussResize(BL, OutHeight)\
.FastBlur(Blur, y_blur=VBlur, iterations=Iterations, dither=true).AddGrain(var=Texture, constant=true)
Frosty_Right = Blend_Right.GaussResize(BR, OutHeight)\
.FastBlur(Blur, y_blur=VBlur, iterations=Iterations, dither=true).AddGrain(var=Texture, constant=true)
Output = StackHorizontal(StackHorizontal(Frosty_Left, Resized_Picture), Frosty_Right)
""", "Add Borders 2 Eval") : (Output_Storage_Aspect >= Mod_Source_Storage_Aspect) ? Eval("""
Output = Resized_Picture.AddBorders(BL, 0, BR, 0, color=BColor)
""", "Add Borders 3 Eval") : HeightTest && (Output_Storage_Aspect < Mod_Source_Storage_Aspect) ? Eval("""
H_Crop = Resizing_Height - 64
LetterBox_Background = \
StackVertical(Resized_Picture.crop(0, 0, 0, -H_Crop), Resized_Picture.crop(0, H_Crop, 0, 0))\
.TemporalSoften(5, 255, 255, 20, 2).Tweak(bright=BrightL, cont=ContL, sat=SatL)
LB_Crop = height(LetterBox_Background) - 16
Top = LetterBox_Background.crop(0, 0, 0, -LB_Crop)
Bottom = LetterBox_Background.crop(0, LB_Crop, 0, 0)
Blend_Top = \
(BlendL == 0) ? Top : (BlendL == 1) ? FlipVertical(Bottom) : Overlay(Top, FlipVertical(Bottom), Opacity=BlendL)
Blend_Bottom = \
(BlendL == 0) ? Bottom : (BlendL == 1) ? FlipVertical(Top) : Overlay(Bottom, FlipVertical(Top), Opacity=BlendL)
Frosty_Top = Blend_Top.GaussResize(OutWidth, BT)\
.FastBlur(BlurL, y_blur=VBlurL, iterations=IterationsL, dither=true).AddGrain(var=TextureL, constant=true)
Frosty_Bottom = Blend_Bottom.GaussResize(OutWidth, BB)\
.FastBlur(BlurL, y_blur=VBlurL, iterations=IterationsL, dither=true).AddGrain(var=TextureL, constant=true)
Output = StackVertical(StackVertical(Frosty_Top, Resized_Picture), Frosty_Bottom)
""", "Add Borders 4 Eval") : Eval("""
Output = Resized_Picture.AddBorders(0, BT, 0, BB, color=BColor)
""", "Add Borders 5 Eval")
Info ? Eval("""
Info_Text = \
((abs(Output_Storage_Aspect - Source_Display_Aspect) < 0.000033) ? \
string(OutWidth, "Output Dimensions\n%.0f x ") + string(OutHeight, "%.0f\n\nNo Borders") : \
(Output_Storage_Aspect >= Mod_Source_Storage_Aspect) ? \
string(Resizing_Width, "Picture Dimensions\n%.0f x ") + string(OutHeight, "%.0f") + \
string(BL, "\n\nLeft Border %.0f") + string(BR, "\nRight Border %.0f") + \
string(OutWidth, "\n\nOutput Dimensions\n%.0f x ") + string(OutHeight, "%.0f") : \
string(OutWidth, "Picture Dimensions\n%.0f x ") + string(Resizing_Height, "%.0f") + \
string(BT, "\n\nTop Border %.0f") + string(BB, "\nBottom Border %.0f") + \
string(OutWidth, "\n\nOutput Dimensions\n%.0f x ") + string(OutHeight, "%.0f")) + \
"\n\n" + Resizer
Sub_Size = min(OutWidth * 0.04, OutHeight * 0.042)
Sub_Y = (OutHeight * 0.5) - (Sub_Size * 4.75)
Output = Output.subtitle(Info_Text, y=Sub_Y, size=Sub_Size, text_color=$F0FFFF, align=5, lsp=20)
""", "Info Eval") : nop()
return Output }
function iFrostyBorders(clip Source, int "OutWidth", int "OutHeight", val "InDAR", val "InSAR", int "Mod", \
float "Bright", float "BrightL", float "Cont", float "ContL", float "Sat", float "SatL", \
float "Blend", float "BlendL", float "Blur", float "BlurL", float "VBlur", float "VBlurL", \
Int "Iterations", Int "IterationsL", float "Texture", float "TextureL", val "BColor", val "BColorL", \
string "Resizer", bool "Frosty", bool "Info") {
Info = default(Info, true)
return Source.FrostyBorders(OutWidth, OutHeight, InDAR, InSAR, Mod, \
Bright, BrightL, Cont, ContL, Sat, SatL, \
Blend, BlendL, Blur, BlurL, VBlur, VBlurL, \
Iterations, IterationsL, Texture, TextureL, BColor, BColorL, \
Resizer, Frosty, Info) }
function Borders(clip Source, int "OutWidth", int "OutHeight", val "InDAR", val "InSAR", int "Mod", \
float "Bright", float "BrightL", float "Cont", float "ContL", float "Sat", float "SatL", \
float "Blend", float "BlendL", float "Blur", float "BlurL", float "VBlur", float "VBlurL", \
Int "Iterations", Int "IterationsL", float "Texture", float "TextureL", val "BColor", val "BColorL", \
string "Resizer", bool "Frosty", bool "Info") {
Frosty = default(Frosty, false)
return Source.FrostyBorders(OutWidth, OutHeight, InDAR, InSAR, Mod, \
Bright, BrightL, Cont, ContL, Sat, SatL, \
Blend, BlendL, Blur, BlurL, VBlur, VBlurL, \
Iterations, IterationsL, Texture, TextureL, BColor, BColorL, \
Resizer, Frosty, Info) }
function iBorders(clip Source, int "OutWidth", int "OutHeight", val "InDAR", val "InSAR", int "Mod", \
float "Bright", float "BrightL", float "Cont", float "ContL", float "Sat", float "SatL", \
float "Blend", float "BlendL", float "Blur", float "BlurL", float "VBlur", float "VBlurL", \
Int "Iterations", Int "IterationsL", float "Texture", float "TextureL", val "BColor", val "BColorL", \
string "Resizer", bool "Frosty", bool "Info") {
Frosty = default(Frosty, false)
Info = default(Info, true)
return Source.FrostyBorders(OutWidth, OutHeight, InDAR, InSAR, Mod, \
Bright, BrightL, Cont, ContL, Sat, SatL, \
Blend, BlendL, Blur, BlurL, VBlur, VBlurL, \
Iterations, IterationsL, Texture, TextureL, BColor, BColorL, \
Resizer, Frosty, Info) }
hello_hello
5th April 2021, 21:10
FranceBB,
Sorry, I missed your post. I stumbled across it just now while I was looking for something else.
I updated the function and meant to update the opening post, but I had to update the help file first which apparently led to forgetting.....
I'm not sure what happened to the old link but anyway......
FrostyBorders 2020-08-26 is the previous version so the one you posted above is the version before it. I can't remember what the difference is. Edit: Comparing the scripts there doesn't seem to be much difference, so maybe I just made a typo with the date or something..
The current version is FrostyBorders 2021-04-06 (dated today).
- The argument names have been simplified. There's no longer separate arguments for pillarbox and letterbox borders. For example, previously there were arguments named "Bright" and "BrightL", but now there's only "Bright".
- Added TextureC argument for enabling chroma texture over the borders. It's disabled by default. The Texture argument for adding luma texture remains unchanged.
- Added GPlugin argument (Grain Plugin). The default is GPlugin=1, which uses AddGrainC to add the border texture as before. GPlugin=2 uses neo_f3kdb. The Texture and TextureC arguments should produce roughly the same result for either plugin. Actually they're so similar I'm not sure why I added neo_f3kdb now. Oh well.....
I'll update the links in the opening post shortly.
hello_hello
6th April 2021, 01:41
I just added an update to FrostyBorders 2021-04-06 to ensure the borders are the same size when possible.
There was a bug causing the wrapper functions to not work. It's fixed.
I left the version number the same.
FranceBB
6th April 2021, 02:21
Thanks! I've downloaded the updated version now. :)
As a side note, have you considered opening a GitHub account?
It's very easy to deal with versioning, so that it allows you not only to keep the scripts there, but also to go "back in time" and check the commits the developers have made.
(just a "hint" to avoid links to disappear again in the future if the host closes).
Anyway, thanks for the new version.
hello_hello
6th April 2021, 05:29
I'm pretty sure I have a GitHub account. I've just never used it. I'll try to do something about that soon.
Cheers.
hello_hello
6th April 2021, 22:14
Sorry about a quick update, but I reverted back to the old behaviour for FrostyBorders when a picture mod is specified. It once again only effects the picture mod, not the borders, so the script is free to make the size of the borders even, whenever possible. The new version is dated 2021-04-07. There's a link in the opening post.
StainlessS
6th April 2021, 22:33
I just added an update to FrostyBorders 2021-04-06 to ensure the borders are the same size when possible.
With RT_QueryBorderCrop() [template for RoboCrop, but slightly different functionality], I had about 3 or 4 goes at equalizing borders before I got it right.
[Accounting for xmod, ymod [and interlacing] and WMod, HMod, CropMore, CropLess, and actual detected border coords].
Its a bit tricky.
hello_hello
6th April 2021, 23:09
The equalizing part wasn't hard for this script, but I tried to be more clever for the newer version, and it turned out not to be.
All I did was subtract the cropped width from the original width and divide the result by 2, then round it down to the appropriate mod if need be (ie mod2 for YV12). That's used for the left border and the right border is just the original width minus the cropped width minus the left border. I made the default cropped picture mod twice the minimum (ie mod4 for YV12), so as long as the total width is at least mod4 the borders have to be even (for YV12). The script can't "crop less" because it's purpose is to add borders to an already cropped source. It resizes too, so I get to assume the source is progressive.
I just thought I was being clever by applying the mod argument to the initial left border calculation as well as the picture, until I realised that'd be more likely to make them uneven.
hello_hello
7th April 2021, 06:03
I fixed one problem and caused another. It hasn't been uploaded long so I haven't changed the version date, but I've fixed an oversight preventing the script from checking that any specified mod is correct for the source. If anyone has downloaded FrostyBorders 2021-04-07 before reading this post, please download it again.
hello_hello
18th August 2021, 11:33
I've used the FrostyBorders function a bit myself lately, which made me aware of some areas that could be improved, most importantly ensuring the borders are fairly consistent regardless of resolution. Or to put it another way, the borders added to HD and SD versions of the same video should now look much the same.
There's also new arguments for adding plain borders with a dark to light gradient and a "frosty" look, for picking a frame from a video with normal FrostyBorders and using those borders for the entire video, and for adding a black 2 pixel divider between the picture and the borders.
Edit: Forget to mention, the multithreaded resizers from the ResampleMT plugin are supported and there's a "RStr" argument for specifying resizer options.
There's a link for the new version dated 2021-08-18 in the opening post.
FranceBB
18th August 2021, 13:24
Thanks for the update. :)
hello_hello
18th August 2021, 18:30
No worries, but I always manage to find a problem after I've uploaded a function no matter how thoroughly I think I've checked it. Sigh....
Now Info=true displays the correct border dimensions when BDiviser=true
FrostyBorders will work with YV411.
New version dated 2021-08-19 in the opening post.
FranceBB
19th August 2021, 02:12
Oh, so another version, dang it, I've just replaced the other one ehehehehe
Anyway it's 2AM, I think I'm just gonna go to bed and I'll try it tomorrow ;)
hello_hello
26th August 2021, 15:24
Well.... here's another new one. There's a link for FrostyBorders 2021-08-27 in the opening post.
Someone at VideoHelp requested an option for "feathering" the borders, (there's two arguments for that and I added a pic of what it looks like in the opening post), along with some other minor improvements. It'll be slower than the standard borders though because the blurring and temporal something has to be applied to the full size borders and part of the picture, then overlaid, rather than being applied to the borders before they're resized to the correct dimensions.
The feathering can be applied to plain black/colored borders as well as the frosty borders.
FranceBB
26th August 2021, 18:43
Thanks. :)
hello_hello
5th September 2021, 05:01
And another update... although not exactly my choice.
Someone at VideoHelp requested the type of borders the "Frosty" look was designed to avoid, but it wasn't hard to do, so....
The new version is dated 2021-09-05. There's a link in the opening post.
The "Clone" argument takes picture from the sides or top/bottom of the frame to use as borders without stretching or resizing (unless the border width/height exceeds half the picture width/height). They're blurred and a little texture added (configurable as for FrostyBorders) but by default there's no temporal smoothing. The "Mirror" argument adds the same borders, only flipped.
There's now a "TSoft" argument for specifying the number of frames used for temporal smoothing. Fewer frames = Faster.
Info=true displays the correct border dimensions now. I'm certain this time. I thought I'd fixed that, but apparently I'm an idiot.
Clone=true
https://i.postimg.cc/mz4hQsHY/Clone1.png (https://postimg.cc/mz4hQsHY)
Clone=true, Feather2=true
https://i.postimg.cc/21JZLMGG/Clone2.jpg (https://postimg.cc/21JZLMGG)
FranceBB
5th September 2021, 19:58
Well it's nice to have, so thanks, but I'll stick with the original settings ehehehehehe
hello_hello
6th September 2021, 20:04
Damn.... always something.
I broke the Blur and VBlur arguments. The link for the fixed version is in the opening post and dated 2021-09-07.
hello_hello
6th September 2021, 23:26
I've fixed the blending for StaticFrosty borders when either of the feathering options are enabled. They're supposed to be identical by default, but with feathering enabled they weren't. I haven't changed the date again because the new version has only been was only uploaded for about an hour. The new version is still dated 2021-09-07.
FranceBB
7th September 2021, 06:13
Ah ok, I'll update it again then. :)
hello_hello
12th October 2021, 19:55
And another update. Obviously at this point it's primarily to annoy FranceBB. :)
This version should function the same as previous versions when adding the original FrostyBorders, but I've changed and/or consolidated some argument names and/or argument types to clean up what was becoming a bit of a mess. The help file has been updated.
FranceBB, I've added a new border type that might interest you. It's similar to the borders broadcasters like to add to cell-phone footage. The borders are cut from the video but they're enlarged and cropped as required rather than stretched. See the Clone=3 pic in the opening post.
The new version is dated 2021-10-11 and the link is in the opening post.
hello_hello
10th December 2021, 16:35
FrostyBorders was producing an error when feathering was enabled for the original frosty borders.
That's fixed and there's a new version dated 2021-12-09 in the opening post.
BetA13
29th December 2021, 04:25
Hi, its me again :)
after a while i came back to use this nice script..
just got one quick question, cause i forgot what i did the last time.
how can i make the "noise" finer? it looks to raw if you know what i mean^^
https://i.imgur.com/cjv3Zw9.png
im talking about the dithering/noise in the frosty border.
hope everything is well and you all had a nice Christmas :)
greetings
hello_hello
30th December 2021, 03:54
im talking about the dithering/noise in the frosty border.
Hi.
I think you're after the Texture argument. It's the amount of grain added by AddGrainC.
It can be anywhere from Texture=0 to whatever the limit is for AddGrainC (it normally requires a small amount to hide any banding the dithering after blurring doesn't hide).
Texture can also have a negative value, and the amount of grain is increased or decreased according to the resolution, the hope being it'll have roughly the same look regardless of the resolution. A positive value for Texture is the same as the AddGrainC "var" argument.
Texture=-5 doesn't necessarily correspond to Texture=5, as for a negative value it's adjusted according to the resolution, but the help file explains how it works.
hello_hello
9th July 2022, 02:32
There's a link for a new version of FrostyBorders dated 2022-07-08 in the opening post.
Added the ability to crop, so for an anamorphic source, you can specify the original display aspect ratio before cropping, rather than have to crop prior to FrostyBorders and calculate the new DAR yourself.
FrostyBorders(960,540, 6,4,-8,-2, InDAR=4.0/3.0)
The default texture applied to the borders has a fixed value now, rather than being increased or decreased according to the resolution of the video as it was previously..
FranceBB
10th July 2022, 21:44
Thanks for the new version. :)
hello_hello
25th September 2022, 07:56
There's new version of FrostyBorders dated 2022-09-23 in the opening post. I think the only difference is a little change to what's displayed when Info=true, but I updated it ages ago and I can't actually remember. :) I'm sure there's no functionality changes though....
hello_hello
2nd June 2023, 05:05
There's a link to a new version of FrostyBorders dated 2023-06-02 in the opening post.
- Added a StaticT argument for changing the texture of FrostyBorders to non-static (grain). The default is StaticT=true, the same as for previous versions (grain is added as a static texture). StaticT=false only works for non-static borders, as static borders always have a static texture.
- Fixed an error when neo_f3kdb was specified for adding border texture (GPlugin=2) instead of AddGrainC.
- Fixed an error when no output width/height were specified, or when FrostyBorders was cropping and/or resizing without needing to add borders.
hello_hello
25th September 2023, 16:03
There's a link to a new version of FrostyBorders dated 2023-09-25 in the opening post.
- There's now a native VapourSynth version of the FrostyBorders function.
- Support for resizing based on a sample aspect ratio in frame properties has been added to both versions.
- A CropDAR argument has been added (Cropping Display Aspect Ratio).
- A TCRatio argument has been added (Top Cropping Ratio).
CropDAR can be used to ensure the picture is cropped to a certain DAR to minimize the size of any borders being added.
When CropDAR is causing the video height to be cropped, TCRatio determines how much of the height cropping is taken from the top in relation to the bottom.
The new CropDAR and TCRatio arguments should make it possible to control the cropping in a way that previously required a separate function (making it easier to add FrostyBorders via ffdshow's Avisynth filter or as a video filter for MPV player (Vapoursynth version).
hello_hello
1st October 2023, 18:03
There's a link for a new version dated 2023-10-02 in the opening post.
Hopefully I've stomped on the gremlins that made their way into into the last update.
FranceBB
1st October 2023, 18:09
Thanks for the new version!
Having it automatically scaling based on the aspect ratio in the frame properties is also a nice addition.
I'm really looking forward to testing it tomorrow! :D
hello_hello
1st October 2023, 18:20
Thanks for the thank you!
hello_hello
5th October 2023, 14:34
Avisynth FrostyBorders:
Fixed a "no function named CR_IsEqual" error. It's a helper function and I forgot to change the function name after copying and pasting some syntax from the CropResize script, but if the CropResize function was loaded, there was no error.
The new version is dated 2023-10-06. The VapourSynth version hasn't changed at all, but I changed it's version date too so they're the same.
FranceBB
11th October 2023, 17:45
I've been busy, but I noticed that you already fixed the issue.
Version 2022-07-08 - works
Version 2023-10-02 - Script error: there is no function named CR_IsEqual
https://i.imgur.com/IoXKO0i.png
Version 2023-10-06 works
I made a few tests to try out frame properties and they indeed seem to work.
Barsnote in 720x576 with SAR 16:15 (i.e anamorphic 4:3) correctly becomes a 1.33 PB with frosty borders on the left and right:
https://i.imgur.com/1JvI8mg.png
https://i.imgur.com/V6tZ9iw.png
while forcing the SAR to 64:45 (i.e anamorphic 16:9) makes it correctly just resize it to 1.77 FF without borders:
LWLibavVideoSource("\\miomnsp7\fs0\clip.dir\BARS_NERO_SD.mxf")
propSet("_SARNum", 64)
propSet("_SARDen", 45)
FrostyBorders(1024, 576, frosty=true)
https://i.imgur.com/M8A5n3T.png
Very well done. :)
Moving this to production tonight.
hello_hello
11th October 2023, 19:00
Excellent!
By the way, I assume you're not using my CropResize function (because if the new version of CropResize was loaded you wouldn't have experienced that error) but FYI...
CropResize can add the same borders as the standalone FrostyBorders function but it's not restricted to a non-anamorphic output, in case you have the need for an anamorphic output with FrostyBorders at some stage. In fact I've been wondering why I'm still updating FrostyBorders, given CropResize can do the same thing and more. The main difference is CropResize itself doesn't include arguments for configuring the borders. They're configured using a separate function that creates global variables.
Edit: And for some borders, the FrostyBorders function crops the pixels used to create the borders from the source before it's upscaled, or it crops the pixels from the resized video when downscaling, whereas CropResize always takes the pixels from the clip after it's resized, so when upscaling the FrostyBorders function might be a bit faster. Hopefully that makes sense.
Anyway... in case you ever need to do silly stuff that FrostyBorders can't do....
ColorBars()
ConvertToYV12()
Spline36Resize(720,576)
propSet("_SARNum", 16)
propSet("_SARDen", 15)
FrostyB(Feather=32)
iCropResize(720,576, OutDAR=16.0/9.0, Frosty=true)
N = string(propGetAny("_SARNum"))
D = string(propGetAny("_SARDen"))
Subtitle("Frame Properties SAR " + N + ":" + D, align=2)
https://imgur.com/65IkRpF.png
hello_hello
28th October 2023, 22:04
New version of FrostyBorders dated 2023-10-28 in the opening post.
The Avisynth version hasn't changed.
Fixed some mistakes in the syntax of the VapourSynth version and added a "FrostyResizeWrappers.py" script containing two resizer wrapper functions. The wrapper functions are examples of how to use a non-native VapourSynth resizer. The FrostyResizeWrappers.py script is not required.
hello_hello
16th November 2024, 01:16
There's a new version of FrostyBorders dated 2024-11-16 in the opening post. It fixes a few minor bugs, mainly for the VapourSynth version (I don't use the VapourSynth version much so they went unnoticed until now). The way a border color is specified for VapourSynth has also been simplified. Details in the "Changes" text file.
(For anyone using the FrostyBorders function included with CropResize (https://forum.doom9.org/showthread.php?t=176667), I'll be updating it to match the changes to the standalone FrostyBorders function in the near future).
flossy_cake
21st December 2024, 20:58
There's a new version of FrostyBorders dated 2024-11-16 in the opening post. It fixes a few minor bugs, mainly for the VapourSynth version (I don't use the VapourSynth version much so they went unnoticed until now). The way a border color is specified for VapourSynth has also been simplified. Details in the "Changes" text file.
(For anyone using the FrostyBorders function included with CropResize (https://forum.doom9.org/showthread.php?t=176667), I'll be updating it to match the changes to the standalone FrostyBorders function in the near future).
Just wanted to say a HUGE thank you for this script, it really has put my mind at ease having bought a new OLED and watching a lot of 4:3 stuff :thanks::thanks::thanks::thanks::thanks::thanks:
I had one issue but was able to easily work around it
My video is 768x576 square pixels 4:3 which is a PAL DVD source of 720x576 which I did a LanczosResize(768,576) to make square pixels 4:3
I put FrostyBorders(1024,576) and the result is the 4:3 active image area is stretched wide slightly, fat faces
If I do FrostyBorders(1024, 576, InDAR=4.0/3.0)
or FrostyBorders(1024, 576, InDAR=0.0)
then it works perfectly
I think because it's reading the SAR frame props which lwlibavvideosource is setting as SARNum=16 SARDen=15 , btw I thought SAR = storage aspect ratio and PAR = pixel aspect ratio? That confused me a little
hello_hello
22nd December 2024, 11:32
flossy_cake,
Yeah, the function seems to be mainly used by people with OLED TVs, although I still have a Plasma so I use it with that TV for 4:3 content.
Info=true will show you the input aspect ratio the function is using, or prefixing the function name with an "i" will do the same thing. iFrostyBorders()
The last version I uploaded has an issue displaying the whole text though. I don't know how that happened, but it's not centered, so I think the SAR info is missing.
Someone also recently discovered there's an issue with FastBlur and AMD CPUs. There's intermittent flashing of blocky color in the borders. I found away to work around it so it rarely happens now, but there's also a second version of the function that can use one of Dogway's functions for blurring. The Dogway function isn't required as I copied it to the FrostyBorders script, but the BoxBlur version does require Avisynth+ 3.7.3. I haven't uploaded them here yet as I haven't had a chance to check something in the VapourSynth version, but if you want to give them a try they're attached to this post (https://forum.videohelp.com/threads/393762-ImageBorders-FrostyBorders-Scripts/page6#post2760868). Both versions convert the borders to 16 bit, blur them, then dither back to the original bitdepth, so there should be less banding in the borders (not that it was terribly noticeable anyway). Info=true has been fixed.
flossy_cake
22nd December 2024, 15:07
Thanks yeah I saw on videohelp you were saying threads=1 fixed the flashing? I did see a couple flashes in my testing with 2024-11-16 but they were always near the beginning of playback or shortly after seeking
After a bit of playback it seemed to settle down. I'm guessing it's cause avisynth isn't totally threadsafe or something like that? Realtime avisynth usage can be a bit janky in my experience with frames being processed out of order and memory leaks. Single threading always resolved my issues too. There is also this Preroll function that can help with linear processing when multi threading. Another thing I find helps is putting each filter in its own single thread like eg Filter1.Prefetch(1), Filter2.Prefetch(1) instead of doing say Prefetch(2) at the end of the script. I am using LAV for opening my .avs files in MPC-HC whereas others are using ffdshow or Crendking's directshow filter so maybe that affects things as well. Anyway FrostyBorders uses such little CPU I guess it doesn't really need multithreading anyway?
My Samsung plasma that I had been using 10+ years recently died and I didn't care about burnin on it anyway cause it was so old and cheap but I just got a LG G4 and it was a expensive so I want to play it safe and watch 4:3 stuff with FrostyBorders. Avisynth is such a godsend, being able to write video processing scripts and having this level of control is the best thing ever. Even just little things like having precise control over the aspect ratio and cropping, no DVD/bluray player gives you this level of control. With Avisynth and Autohotkey anything is possible!
hello_hello
22nd December 2024, 18:12
wonkey_monkey said he thought it might be some sort of memory alignment problem, but he doesn't have an AMD CPU PC himself to diagnose the problem.
Threads=1 is only for FastBlur's internal multithreading. I did all my testing with Avisynth's multithreading disabled so it's not the cause, although I guess it could make it worse. The BoxBlur version is fine though, so if the blocking happens enough with FastBlur to be annoying, there's always another option (to be clear for anyone else reading this, FastBlur is fine with Intel CPUs).
By the way, in case you're not aware, the reason for using ffdshow is because you can add a script with FrostyBorders included in ffdshow's Avisynth filter and so long as it's processing the video in some way, you don't need to open video files with a script, you can just open videos directly with MPC-HC as you normally would. You don't have to install ffdshow completely, just it's RAW video filter, and add that to MPC-HC as an external filter. That way LAV can still do the decoding, and ffdshow can apply the script to the decoded video. Unfortunately ffdshow is limited to 8 bit video. The VapourSynth FrostyBorders can be run as an filter for MPV and supports any bitdepth. I add it as a filter to SMPlayer to run it that way. There's instruction for running it via ffdshow in post #2 (https://forum.videohelp.com/threads/393762-ImageBorders-FrostyBorders-Scripts#post2555438) of the VideoHelp thread, and instruction for using it with SMPlayer in post #3.
Cheers.
flossy_cake
24th December 2024, 01:42
Oh I am using an old i7-4790k and got some flashes so I guess it's not necessarily AMD exclusive...maybe instruction set related? Like AVX vs SSE? I could try different compilation options for fastblur as I have visual studio set up for that on my other machine.
Inserting an avisynth directshow filter inline is very cool but I like having it all modular so I dont have to run two MPC-HC configs and a single huge script for all my per-series/per-season/per-episode processing.
In my case when opening .AVS files I believe it's using LAV Splitter to open the .AVS file with system32\Avisynth.dll and then the resulting avi stream is processed by LAV Video filter.
If you're wondering how it's convenient for me to be making all these .avs files the answer is I use an AHK script to generate my avs scrips. So I just point it to the top level folder for a particular series and it creates a clone of that folder structure alongside it with .avs files instead of .mkv files, and the .avs files contain whatever payload I specify In the ahk script for that series, including exceptions for certain seasons or episodes (using the path of the script file to determine which season/episode it is)
I was trying to write a black bar detection script in AVS and had it working pretty well except on night time scenes there would sometimes be black pixels along the entire edges that would make a false positive for borders . If I can get something reliable then I could automate adding frosty borders without having to do any manual calculations per series/episode. Just a one liner that automatically adds frostyborders to fill out 16:9 regardless of the content. Even 4:3 DVDs as you would know sometimes have those 8px borders down the sides and sometimes just for certain episodes in a series...trying to automate my way around that with black bar detection.
flossy_cake
24th December 2024, 07:06
Just been playing around with TSoft=7 and Cont=0.66 to try and subdue rapid luminance changes in the borders when the active picture area changes such as during pans or characters moving around the scene near the edges.
Ideally I'd like to emulate something like what "ambient mode" on Youtube does. I'd prefer something that just glows softly and doesn't change too rapidly. Just gently pulses to keep burn-in at bay but without grabbing attention. I think I'd like to go a bit higher with TSoft to make the borders change very slowly but it doesn't have to blend across more frames it just needs to have a slower update rate if that's possible?
hello_hello
24th December 2024, 08:10
Oh I am using an old i7-4790k and got some flashes so I guess it's not necessarily AMD exclusive...maybe instruction set related? Like AVX vs SSE? I could try different compilation options for fastblur as I have visual studio set up for that on my other machine.
That'd be great, if it can fix the problem.
If you're wondering how it's convenient for me to be making all these .avs files the answer is I use an AHK script to generate my avs scrips.
I was wondering, because having to create a script manually for each video seemed like it'd get pretty old quite quickly.
I was trying to write a black bar detection script in AVS and had it working pretty well except on night time scenes there would sometimes be black pixels along the entire edges that would make a false positive for borders.
There's the AutoCrop plugin. It works pretty well but it's limited to 8 bit video and only a couple of YUV color formats.
flossy_cake
24th December 2024, 18:20
There's the AutoCrop plugin. It works pretty well but it's limited to 8 bit video and only a couple of YUV color formats.
Thanks that looks like exactly what I'm after.
Cause some of these 4:3 shows like eg. season 2 of sliders have random amounts of black pixels down the sides like for one episode it'll be 10 pixel border on the left and 2 pixels on the right, then the next episode has 8&8, then the next will be 0&0.
Then there's the mod 2 issue, my current solution is "convert to square pixels 4:3 (or 2% wider/narrower), then crop any edge junk using increments of 2 pixels, then derive the 16:9 width from the height, round that value to nearest int, then if mod2 remainder isn't zero, add 1, then feed those dimensions to frostyborders with custom CL and CR values for the particular season/episode ". I do it this way cause it's easier for my brain to understsnd what's going on, it's probably better to crop first then use pixel aspect ratio to figure out how to scale that to 16:9, or just let frostyborers do it based on SAR frame props. The analogue nonsquare world is such a mess, that's kinda why I like making my first step to convert to square pixels, then I am always in square pixel land from that point onwards and it's smooth sailing, I can calculate everything from the raster size alone, don't need to worry about pixel aspect and anamorphic.
hello_hello
25th December 2024, 01:03
Just been playing around with TSoft=7 and Cont=0.66 to try and subdue rapid luminance changes in the borders when the active picture area changes such as during pans or characters moving around the scene near the edges.
Ideally I'd like to emulate something like what "ambient mode" on Youtube does. I'd prefer something that just glows softly and doesn't change too rapidly. Just gently pulses to keep burn-in at bay but without grabbing attention. I think I'd like to go a bit higher with TSoft to make the borders change very slowly but it doesn't have to blend across more frames it just needs to have a slower update rate if that's possible?
I has a look at YouTube's ambient mode. It's an interesting effect but I've no idea how it's done.
What if I changed the borders to something like this. You should be able to use any video as the source. FrostyBorders at the beginning is just there to crop to the correct aspect ratio. It's not adding borders.
Blurring the entire video first smooths things out and reduces the flashing effect, if not eliminates it. And it appears the FastBlur problem is somehow related to the size of the video. Blurring the entire video instead of just the borders hasn't produced a single flash of blocky color so far, and dithering the borders to 6 bit seems to work okay and means it's not necessary to do anything in 16 bit. The temporal softening is by far the slowest part of the process, but for a 720p source at least, this still seems fast enough.
Video = FrostyBorders(0,720, CropDAR=1024.0/720.0)
Borders = Video.FastBlur(200,100,3, dither=true)
Borders.Overlay(FlipHorizontal(Borders), Opacity=0.5)
StackHorizontal(Crop(0,0,-860,0), Crop(860,0,0,0))
TemporalSoften(255,255,7)
TemporalSoften(255,255,7)
TemporalSoften(255,255,7)
Tweak(Cont=0.95)
ConvertBits(dither_bits=6)
AddGrainc(16, constant=true)
StackHorizontal(Crop(0,0,-200,0), Video, Crop(200,0,0,0))
hello_hello
25th December 2024, 02:03
Then there's the mod 2 issue, my current solution is "convert to square pixels 4:3 (or 2% wider/narrower), then crop any edge junk using increments of 2 pixels, then derive the 16:9 width from the height, round that value to nearest int, then if mod2 remainder isn't zero, add 1, then feed those dimensions to frostyborders with custom CL and CR values for the particular season/episode ". I do it this way cause it's easier for my brain to understsnd what's going on, it's probably better to crop first then use pixel aspect ratio to figure out how to scale that to 16:9, or just let frostyborers do it based on SAR frame props. The analogue nonsquare world is such a mess, that's kinda why I like making my first step to convert to square pixels, then I am always in square pixel land from that point onwards and it's smooth sailing, I can calculate everything from the raster size alone, don't need to worry about pixel aspect and anamorphic.
All that is making my head hurt.
When you use AutoCrop with CropResize, any cropping you specify happens after the auto-cropping, so you can increase the auto-cropping that way if AutoCrop tends not to crop the borders perfectly cleanly. It also has a CThresh argument for adjusting AutoCrop's threshold. FrostyBorders is included, but it hasn't been updated to match the stand-alone version yet, however hopefully I'll have a chance to do that soon (the output should still look the same). I've also updated CropResize a bit but I haven't uploaded that version yet as I still have to check a few things. The resizing is the same as the current version. CropResize will ensure it crops whatever it needs to (in addition to the auto-cropping) so it can resize the video to mod4 dimensions before adding borders. It'll use the resizer to crop less than mod2 or a fraction of a pixel if need be. FrostyBorders does the same thing. The final cropping doesn't need to be mod2, it just has to be cropped so it can be resized to mod2 (or mod4 is the CropResize default).
Here's an example:
# Creating a fake 4:3 PAL DVD.
CropResize(720,576, OutDAR=15.0/11.0)
Crop(10,2,-14,-4)
AddBorders(10,2,14,4)
# Global function for adjusting the frosty borders
FrostyB(Cont=0.5, Bright=10)
# I crop to at least 1.45 to reduce the border size, but it's personal preference
CropResize(1280,720, 4,0,-4,0, InDAR=15.0/11.0, CropDAR=1.45, AutoC=true, TCRatio=0.3, Frosty=true)
Here's the final output. As with FrostyBorders, the CropDAR argument specifies a display cropping aspect ratio independent of the pixel aspect ratio (you use it as though the source has square pixels). The CropDAR may be adjusted by a small amount if the video can't be resized to mod4 dimensions using the exact DAR specified.
https://i.postimg.cc/KYGFVWqb/4-Final-Output.png
Working backwards, CPreview=1 will show you the extra cropping the function is applying. I told it to crop an extra 4 pixels each side simply to demonstrate what the preview looks like. The blue lines show the extra cropping being applied for a DAR of 1.45.
CropResize(1280,720, 4,0,-4,0, InDAR=15.0/11.0, CropDAR=1.45, AutoC=true, TCRatio=0.3, Frosty=true, CPreview=1)
https://i.postimg.cc/rwCMfT9g/3-Crop-Resize-cropping-preview.png
CPreview=7 will show you what AutoCrop is cropping.
CropResize(1280,720, 4,0,-4,0, InDAR=15.0/11.0, CropDAR=1.45, AutoC=true, TCRatio=0.3, Frosty=true, CPreview=7)
https://i.postimg.cc/QdrjgCcH/2-Auto-Crop-preview.png
With CropResize commented out this is what the fake source looked like.
https://i.postimg.cc/CL8FfkB3/1-Fake-PAL-DVD.png
Info=true will give you all the gory details.
CropResize(1280,720, 4,0,-4,0, InDAR=15.0/11.0, CropDAR=1.45, AutoC=true, TCRatio=0.3, Frosty=true, Info=true)
https://i.postimg.cc/s2TyRJqh/5-Crop-Resize-Info.png
Without the CropDAR argument, the script will only crop a tiny bit extra if necessary to resize without distorting the picture. The borders will be wider in this case though, as the source would be cropped to a DAR of 1.33 (without the unnecessary extra 4 pixels being cropped each side).
CropResize(1280,720, InDAR=15.0/11.0, AutoC=true, Frosty=true, Info=true)
https://i.postimg.cc/G3GL4vsZ/6-Crop-Resize-Info.png
flossy_cake
25th December 2024, 08:43
Cheers, the flashing I was referring to in the last post was not due to the memory misalignment thing, I meant it's just by the nature of what Clone=0 does when the camera pans any high contrast areas as they pan through the blur zone can rapidly fluctuate bright/dark/bright/dark in the borders and I find it distracting. Clone=3 seems to resolve it for me, combined with Cont=0.5 to dim them down a bit. Can also set Bright=10.0 or 20.0 to keep luminance levels more consistent. I find Clone=0 looks by far the best on still scenes but camera panning through high contrast objects is a whole different story. Played with Blur and VBlur too.
hello_hello
25th December 2024, 21:17
Do you mean Clone=1 or Clone=0? The latter disables the Clone borders so you're probably using the original frosty borders with Clone=0. They're the ones I was thinking of changing to something like the example in post #69.
flossy_cake
25th December 2024, 22:28
What if I changed the borders to something like this. You should be able to use any video as the source. FrostyBorders at the beginning is just there to crop to the correct aspect ratio. It's not adding borders.
Blurring the entire video first smooths things out and reduces the flashing effect, if not eliminates it.
Video = FrostyBorders(0,720, CropDAR=1024.0/720.0)
Borders = Video.FastBlur(200,100,3, dither=true)
Borders.Overlay(FlipHorizontal(Borders), Opacity=0.5)
StackHorizontal(Crop(0,0,-860,0), Crop(860,0,0,0))
TemporalSoften(255,255,7)
TemporalSoften(255,255,7)
TemporalSoften(255,255,7)
Tweak(Cont=0.95)
ConvertBits(dither_bits=6)
AddGrainc(16, constant=true)
StackHorizontal(Crop(0,0,-200,0), Video, Crop(200,0,0,0))
I really like this! The luminance of the borders is very stable and doesn't distract me when there is motion in the active picture area. The only issue is it's now too CPU heavy to make it my daily driver, and I'm thinking there's no way around that as temporal softening is just a lot of processing. Maybe giving temporalsoften a lower framerate clip and then padding it with dupes with ChangeFPS to match the source clip?
flossy_cake
25th December 2024, 22:30
Do you mean Clone=1 or Clone=0? The latter disables the Clone borders so you're probably using the original frosty borders with Clone=0. They're the ones I was thinking of changing to something like the example in post #69.
Yes I meant Clone=0 the default.
hello_hello
26th December 2024, 00:39
I really like this! The luminance of the borders is very stable and doesn't distract me when there is motion in the active picture area. The only issue is it's now too CPU heavy to make it my daily driver, and I'm thinking there's no way around that as temporal softening is just a lot of processing. Maybe giving temporalsoften a lower framerate clip and then padding it with dupes with ChangeFPS to match the source clip?
Okay, I'll change it to something like that.
The flashing you were referring to happens when something that's a different color or brightness moves to the edge of the picture and the color/brightness affects the entire border, because it was only the edge of the picture being used for the borders. That'll still be the case, but by doing the blurring first, and by blurring quite a bit, it averages out what ends up in the borders.
I'll try applying the temporal softening to just the borders themselves rather than the whole blurred clip. It should help as there'll be less video to temporal soften, but it might make scene change detection less accurate.
So far it's also fixed the FastBlur flashing problem. That must be due to the blurring being applied to a narrow width clip... for some reason. Applies to a wider clip it doesn't seem to happen. I'll try to upload a new version fairly soon.
flossy_cake
26th December 2024, 01:45
That'll still be the case, but by doing the blurring first, and by blurring quite a bit, it averages out what ends up in the borders.
Yes, it seems your technique is to first blur the entire frame, then flip it horizontally and do a 50% blend of that with itself, then crop out the left and right sides to use as borders, stitch them together, temporally soften, then chop it down the middle and use each half as the frostyborders. Not bad, I like the result.
flossy_cake
26th December 2024, 03:08
I'm quite liking Clone=1, Blur=height/25, VBlur=height/25 (ie the same blur values as Clone=3), Cont=0.5
For me this is a good alternative in the meantime
Because when the camera pans over high contrast objects, yes those objects move in the borders causing bright/dark/bright changes in the borders, but the motion of it is in the same direction as the camera and my brain kind of puts it together as an extension of the active image.
Whereas when the borders are completely blurry, there is no sense of object movement in the borders, it's just random bright/dark/bright flashes that don't have any context to the scene
So what I'm saying is there can be bright/dark/bright flashes as long as they have some kind of resemblance to the scene, otherwise they need to be subdued with extra smoothing like in your new code. That's just how my brain works, YMMV
hello_hello
27th December 2024, 04:36
New version dated 2024-12-27 in the opening post.
flossy_cake,
The default borders ended up being slightly more lively than the test example I posted earlier, but they should still be a lot calmer and not prone to changing drastically (flashing) when something with a different color or brightness than the rest of the picture is close to the edge.
There's still only one instance of TemporalSoften being applied to the borders by default. It's not possible to do something like SelectEven().TemporalSoften().ConvertFPS() as SelectEven puts the borders out of sync with the video. I did add a new argument named TSoftx2 though. TSoftx2=true will chain two instances of TemporalSoften together for more softening, although with the way the borders are now, one instance is probably enough anyway. Let me know what you think.
hello_hello
30th December 2024, 05:53
New version FrostyBorders dated 2024-12-30 in the opening post.
Just a tweak to the way the default borders are created. They should look the same as the version uploaded a few days ago, but creating them should also be faster.
flossy_cake
30th December 2024, 08:05
Thanks for all your work on this, it is much appreciated.
Really the OLED engineers should have something like this built in. They've already got a "logo detection" algorithm which detects static logos, scoreboards and HUDs and dims them down, you'd think they would have an option to detect borders too - nope. Looks like I'll be watching everything through your plugin for the next few years :rolleyes:
hello_hello
31st December 2024, 03:16
You're welcome.
I've been watching some 4:3 animation with the updated borders and they're much better for that. Because animation has lots of areas of a single color, they were prone to changing too quickly when something with a sold color got too close to the edge of the picture, but they're much better now. Changing them was a good idea, and something I should have thought of myself, although the way they were created was left-over from the days before FastBur existed and the blurring was done with a resizer.
flossy_cake
6th January 2025, 16:32
In the end I still found myself subjectively preferring
FrostyBorders(Clone=1, Blur=height/18, VBlur=height/18, Cont=0.5, TSoft=7, InDAR=0.0)
But then I came up with this based on your previous code and now it is my new favourite - brightness stability and no temporal softening required
Video = last.LanczosResize(720,540)
FastBlur(200,100,3,dither=true)
Overlay(FlipHorizontal(), Opacity=0.5)
StackHorizontal(Crop(0,0,-600,0), Crop(600,0,0,0))
ConvertBits(dither=1, dither_bits=6)
AddGrainC(8, constant=true) # can be reduced to 4/2 or removed if desired - still minimal posterisation
Tweak(Cont=0.5, dither_strength=10.0)
CLR = 8 # pixels to crop off left and right
StackHorizontal(Crop(0,0,-120+CLR,0), Video.Crop(CLR,0,-CLR ,0), Crop(120-CLR ,0,0,0))
I reckon the above would be worth having as a separate Clone mode like maybe Clone=4 or something like that, cause I really like the result it's just so brightness stable and no posterisation
flossy_cake
11th January 2025, 19:48
But then I came up with this based on your previous code and now it is my new favourite - brightness stability and no temporal softening required
Video = last.LanczosResize(720,540)
FastBlur(200,100,3,dither=true)
Overlay(FlipHorizontal(), Opacity=0.5)
StackHorizontal(Crop(0,0,-600,0), Crop(600,0,0,0))
ConvertBits(dither=1, dither_bits=6)
AddGrainC(8, constant=true) # can be reduced to 4/2 or removed if desired - still minimal posterisation
Tweak(Cont=0.5, dither_strength=10.0)
CLR = 8 # pixels to crop off left and right
StackHorizontal(Crop(0,0,-120+CLR,0), Video.Crop(CLR,0,-CLR ,0), Crop(120-CLR ,0,0,0))
Nope, turns out that was just a fluke and the borders are only stable when the source clip already has these thin 8px pillarbox on either side. If I crop them off first and use that as the source for the blurred borders then I get too much brightness fluctuations in the borders again. No idea why that is happening, but maybe it can be exploited
hello_hello
14th January 2025, 06:37
The brightness fluctuations, at least for the default borders, are caused by something brighter than the majority of the picture getting too close to one of the sides. The only way to settle it down is to blur more of the picture into the borders so it averages out more, or limit the contrast etc, as the picture cropped from the sides for the borders isn't very wide, maybe only 16 pixels worth for a SD source. Those 16 pixels are then stretched to the border width, so if the edge of the picture changes it can potentially change the border brightness quite a lot.
For your script above, line 4 should give you a 240 pixel wide video.
StackHorizontal(Crop(0,0,-600,0), Crop(600,0,0,0))
The last line really just splits the borders in half and joins them back together, if you ignore the 8 pixels of cropping.
By that I mean.... this:
StackHorizontal(Crop(0,0,-600,0), Video, Crop(600,0,0,0))
produces the same output as this:
StackHorizontal(Crop(0,0,-600,0), Crop(600,0,0,0))
StackHorizontal(Crop(0,0,-120,0), Video, Crop(120 ,0,0,0))
So you know, there was only one reason to crop the video for the borders twice, and that was to apply temporal softening, because TemporalSoften can't detect scene changes accurately when it's only softening the borders. The more of the picture it sees, the more accurate it's scene change detection can be. So, the idea was to crop enough for TemporalSoften to detect scene changes accurately without it having to soften the entire picture, as that's the slow part of the process, and then crop again to take the pixels for the borders. In other words, if you're not temporal softening you probably only need to crop once.
This is probably closer to the amount of picture actually used for the default borders (assuming the source width is 720). I only cropped each border once as I didn't include TemporalSoften. Thinking about it, if you blend with Opacity=0.5 there's no need to crop both left and right borders because they'll be the same anyway. You could just crop one side of the picture and resize it appropriately for each border, assuming they're not always the same width.
Video = last.LanczosResize(720,540)
Video.FastBlur(30,54,3,dither=true)
Overlay(FlipHorizontal(), Opacity=0.2)
Left = Crop(0,0,-704,0).Tweak(Cont=1.0, dither_strength=10.0).ConvertBits(dither=1, dither_bits=6)
Right = Crop(704,0,0,0).Tweak(Cont=1.0, dither_strength=10.0).ConvertBits(dither=1, dither_bits=6)
Left = Left.GaussResize(120,540).AddGrainC(8, constant=true)
Right = Right.GaussResize(120,540).AddGrainC(8, constant=true)
StackHorizontal(Left, Video, Right)
https://i.postimg.cc/KYK7nNvL/A.png
Also, if there's pixels of black at the sides that need to be cropped, it's probably easier/safer to crop them first. That way they can't be blurred into the borders. Something like this would be similar to what the function does when it's cropping.
Video = last.LanczosResize(720,540).Crop(8,0,-8,0)
Video.FastBlur(200,100,3,dither=true)
Overlay(FlipHorizontal(), Opacity=0.2)
Left = Crop(0,0,-696,0).Tweak(Cont=1.0, dither_strength=10.0).ConvertBits(dither=1, dither_bits=6)
Right = Crop(696,0,0,0).Tweak(Cont=1.0, dither_strength=10.0).ConvertBits(dither=1, dither_bits=6)
Left = Left.GaussResize(128,540).AddGrainC(8, constant=true)
Right = Right.GaussResize(128,540).AddGrainC(8, constant=true)
StackHorizontal(Left, Video, Right)
Taking more picture to create the borders (cropping more) probably won't fix the brightness fluctuation problem though, because it'll just move the picture edge that can potentially cause fluctuations closer to the center. Increasing the blurring does the same thing to a certain extent too, so there's not really a perfect solution, although at least lots of blurring averages out the color a fair bit.
Same as the first script, only with a bucket load of blurring.
Video = last.LanczosResize(720,540)
Video.FastBlur(200,100,3,dither=true)
Overlay(FlipHorizontal(), Opacity=0.2)
Left = Crop(0,0,-704,0).Tweak(Cont=1.0, dither_strength=10.0).ConvertBits(dither=1, dither_bits=6)
Right = Crop(704,0,0,0).Tweak(Cont=1.0, dither_strength=10.0).ConvertBits(dither=1, dither_bits=6)
Left = Left.GaussResize(120,540).AddGrainC(8, constant=true)
Right = Right.GaussResize(120,540).AddGrainC(8, constant=true)
StackHorizontal(Left, Video, Right)
https://i.postimg.cc/jSS4jTpM/2.png
I'm not a fan of blending the borders together completely. I think it looks a bit more natural if they're a little independent, but that's just me. It's why I changed the default for Blend to 0.1 for the last version, to help compensate for the extra blurring making the borders less dynamic.
For the record, not everyone was excited about the changes to the border defaults. :)
https://forum.videohelp.com/threads/393762-ImageBorders-FrostyBorders-Scripts/page7#post2762998
I completely forgot that Tweak() was given the ability to dither. I should have been using it.
Anyway, if you find something else you like I'm happy to try it.
Cheers.
flossy_cake
14th January 2025, 22:22
TemporalSoften can't detect scene changes accurately when it's only softening the borders. The more of the picture it sees, the more accurate it's scene change detection can be.
Yeah I noticed that too. Lowering the scenechange thresh to 10 seems to help but I think it's going to have some false negatives and temporally soften over the scene change making it visually distracting, although this would tend to happen on scenechanges where there isn't much luma diff to the next scene so the distraction factor was less than anticipated.
It seems that doing the temporal soften on the blurred borders suppresses brightness fluctuations the most though, versus doing it to the whole frame before the blur.
hello_hello
26th January 2025, 21:53
There's a link for FrostyBorders 2025-01-26 in the opening post.
The main change is the addition of a Gamma argument for adjusting the gamma of the borders (reducing the gamma to darken the borders seems to work better than reducing the brightness and contrast, at least to me).
For the VapourSynth version the Bright argument now auto-scales according to bitdepth (I had foolishly assumed the Tweak function I borrowed from adjust.py would auto-scale as Avisynth's Tweak does).
hello_hello
27th March 2025, 13:20
There's a link to a new version of FrostyBorders dated 2025-03-25 in the opening post.
Added a couple of additional "is equal to" sanity checks to the resizing calculations as the latest Avisynth+ and Vapoursynth both do float calculations in 64 bit rather than 32 bit, and while 64 bit float should be more precise as a rule, I found a couple of instances where it wasn't, causing FrostyBorders to crop a few extra pixels from the width and/or height than necessary and to adjust the resizing to compensate.
VapourSynth version:
The SubText plugin is now used by default for displaying text when Info=True, however it's not a strict requirement as FrostyBorders will fall back to using VapourSynth's Text function if the SubText plugin isn't loaded.
hello_hello
31st March 2025, 15:10
I've replaced the FrostyBorders zip file dated 2025-03-25 in the opening post as I'd updated the help file but included the old version. The function itself hasn't changed.
legend2k
9th April 2025, 18:04
Hi,
Thank you for sharing this,
I've installed FrostyBorders 2025-03-25 and using AviSynth it shows this error:
Script error: There is no function named 'CR_IsEqual'.
hello_hello
14th April 2025, 20:16
Sorry for the slow reply, but thanks for letting me know.
I copied some syntax from CropResize containing the CR_IsEqual() helper function and changed the name of each instance in FrostyBorders, except one. With the CropResize function auto-loading there's no error because CR_IsEqual would exist, so I missed it.
There's a fixed version dated 2025-04-14 In the opening post. No change to the VapourSynth version, but I've updated the version date for both.
hello_hello
20th December 2025, 12:56
There's a new version of FrostyBorders dated 2025-12-20 in the opening post.
Avisynth version:
No change in functionality.
Formatted the function syntax to make it a little more readable.
VapourSynth version:
Added the ability to use the ZSmooth plugin for temporal softening.
FrostyBorders now looks for the following plugins in the following order (only one is required):
ZSmooth, TemporalSoften2 and TemporalSoften.
ZSmooth and TemporalSoften2 also require the Miscellaneous Filters plugin, therefore it also needs to be
loaded before either of those plugins will be used. The help file contains a link for each plugin.
StainlessS
14th February 2026, 20:54
Hi HH,
I remembered that somebody (turned out to be you) mentioned being a fan of "Blake 7" some time ago,
well I came across this (or similar) a few weeks ago and today found out it was you who was the fan.
Shock BLAKE’S 7 Reboot plan confirmed :- https://www.youtube.com/watch?v=Bv92P-HH4aw
Can I hear celebration in S.Africa.
I've never seen Voyager (I probably should one day) but that's why I'd take Blake's 7 over Star Trek any day. It's a pity Blake's 7 was never re-made. I know everybody "getting along" was part of Gene Roddenberry's grand design, but it never quite sat with me. I'd probably like Voyager more.
I think I remember something like that, except someone was holding it (and I'm pretty sure it was Babylon 5), but I couldn't put my finger on what it was. I thought it might have been some sort of caulking gun but I don't think it had a handle for squeezing so my brain never put it in the "case closed" department which is probably why I remember it. A solder sucker could very well have been what it was, but I probably have no hope of finding the scene, short of watching the entire series.
The zig zag shape of all the doors in Bablyon 5 always bothered me, now I think about it. Made for tripping over because their shape meant the doorway width decreased towards the bottom, and not that I'm an engineer, but I couldn't get my head around why those doors would make better airlocks or withstand blasts better than a doorway not made to trip you up.
(sorry for the short sidetrack)
I was watching some old Doctor Who the other day and after admiring the fact they use reel to reel tape on space stations in the future,
https://s14.postimg.org/5ce38uze5/DW3.jpg (https://postimg.org/image/5ce38uze5/)
I wondered.....
The door opening mechanism is a transistor on a heatsink isn't it?
https://s22.postimg.org/h9bgjapbx/DW1.jpg (https://postimg.org/image/h9bgjapbx/) https://s12.postimg.org/sz0o9nn95/DW2.jpg (https://postimg.org/image/sz0o9nn95/)
I take hope from the fact I've never seen a Sci-Fi show set in the future where computers run Windows. I don't know what OS they use, but wouldn't it be nice if they got that right?
EDIT: The solder sucker in question, (similar to mine)
https://i.postimg.cc/Y2g29xsf/shopping.jpg (https://postimages.org/)
EDIT: And from the post following the above quote
Solder Sucker, started looking for it (then thought, maybe Google would do it faster),
EDIT: Ep002 : S01E02. Soul hunter. (about 31:48 PAL time)
https://s20.postimg.cc/c1ftpzerh/Solder_Sucker_zpsepzjguds.png (https://postimg.cc/image/mo9mvemwp/)
EDIT: Solder Sucker, you press the plunger and it locks fully depressed, then press button when solder liquid, and spring loaded
plunger flies out creating vacuum sucking solder inside. Unscrew metal and heat resistant silicone plastic tip assembly, and empty out solder fragments.
hello_hello
15th February 2026, 03:37
Hi HH,
I remembered that somebody (turned out to be you) mentioned being a fan of "Blake 7" some time ago,
well I came across this (or similar) a few weeks ago and today found out it was you who was the fan.
Shock BLAKE’S 7 Reboot plan confirmed :- https://www.youtube.com/watch?v=Bv92P-HH4aw
Can I hear celebration in S.Africa.
Yeah, I read about it somewhere on the web a few days ago.
I'm in two minds about it. On one hand it's possibly something that should remain a BBC si-fi classic from the past, while on the other hand I'm interested to see what it'll be like. And I'm very curious to see if they'll end the reboot the same way the original ended. I won't spoil the ending here, just in case they do, but I still remember sitting dumbfounded looking at the TV after the end of the final episode. I think its probably the only TV series that's ever ended the way Blake's 7 did.
Chances are though, the reboot won't follow the same story-line as the original, and head off in it's own direction instead.
EDIT: The solder sucker in question, (similar to mine)
I'd completely forgotten about that. Your memory is obviously better than mine.
StainlessS
15th February 2026, 03:53
but I still remember sitting dumbfounded looking at the TV after the end of the final episode.
I'll take a guess at it,
All of the rickety scenery fell down and crushed the entire cast to death ?
hello_hello
15th February 2026, 04:38
I'll take a guess at it,
All of the rickety scenery fell down and crushed the entire cast to death ?
You've never watched Blakes 7?
I can't remember and I'm too lazy to go back and re-read the whole thread.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.