View Full Version : How to scale 2160p i420 to 1080p i444 without rescaling chroma (UV) components?
K.i.N.G
17th July 2019, 16:07
So, since the UV components in a YUV i420 source are half the resolution of the full-res luma (Y′) component:
How does one re-scale a i420 2160p source to a i444 1080p source without re-scaling the UV components thus keeping their original quality/resolution/detail/...?
StainlessS
17th July 2019, 18:15
This is it in avisynth, but methinks that it might need some kind of chroma shift to be properley standard.
ColorBars(pixel_Type="YV12")
U=UToY8
V=VToY8
Y=Spline36Resize(Width/2,Height/2) # Some Resizer
YtoUV(U,V,Y) # Just uses Y channel from Y clip
info
https://i.postimg.cc/dDRVbwFJ/KING-00.png (https://postimg.cc/dDRVbwFJ)
K.i.N.G
17th July 2019, 19:46
This is it in avisynth, but methinks that it might need some kind of chroma shift to be properley standard.
ColorBars(pixel_Type="YV12")
U=UToY8
V=VToY8
Y=Spline36Resize(Width/2,Height/2) # Some Resizer
YtoUV(U,V,Y) # Just uses Y channel from Y clip
info
https://i.postimg.cc/dDRVbwFJ/KING-00.png (https://postimg.cc/dDRVbwFJ)
Hey StainlessS,
Thanks for the reply and helping me out (again)!
Just to be sure, this supports 10 and 12bit sources?
Also, is it possible to do this with vapoursynth? Since I've read it has better support for high bitrates (I've configured staxrip to use vapoursynth).
StainlessS
17th July 2019, 20:32
Sorry, no idea how to do it in vapoursynth, me never tried it.
but
ColorBars(width=1440,height=1080,pixel_Type="YV12")
BITS=16 # Or 10, or 12, or 14, dont work with 32 for some reason. EDIT: Yes it does. VDub2 loads ok.
ConvertBits(BITS)
U=UToY # EDIT: Changed UToY8 to UToY, still worked for some strange reason, probably should have thrown error @ YtoUV()
V=VToY # EDIT: Changed VToY8 to VToY
Y=Spline36Resize(Width/2,Height/2) # Some Resizer
YtoUV(U,V,Y) # Just uses Y channel from Y clip
info
https://i.postimg.cc/tYwQ93fd/King-01.png (https://postimg.cc/tYwQ93fd)
EDIT: I imagine that the function names to do similar are not so very different.
EDIT: Works with BITS=32, was the player that failed, VDub2 loads ok.
DJATOM
17th July 2019, 20:44
The approach is the same, but core.std.ShufflePlanes is used for plane extraction, and if you don't want to do something with colors, there is no need to extract UV planes at all.
source = <some source filter>
Y = core.std.ShufflePlanes(source, 0, vs.GRAY)
Y = core.resize.Spline36(Y, 1920, 1080)
clip1080 = core.std.ShufflePlanes([Y, source], [0,1,2], vs.YUV)
K.i.N.G
17th July 2019, 22:29
Thanks to the both of you :)
I got it working in StaxRip with some very minor editing. (Had to change the name of source clip variable... just added a '1' behind it and rename 'clip1080' to 'clip' so that StaxRip sees it correctly as the output).
Just posting it here in case if someone else gets into the same StaxRip error I had without the adjustment. (this is assuming you use a ffms2 source)
clip1 = core.ffms2.Source(r"%source_file%", cachefile = r"%source_temp_file%.ffindex")
source = clip1
Y = core.std.ShufflePlanes(source, 0, vs.GRAY)
Y = core.resize.Spline36(Y, 1920, 1080)
clip = core.std.ShufflePlanes([Y, source], [0,1,2], vs.YUV)
K.i.N.G
17th July 2019, 23:13
Comparison of result with saturation boosted (to better show the difference).
https://i.imgur.com/7pdkb41.png
Can make quite a noticeable difference especially with HDR.
PoeBear
30th December 2020, 14:39
Was curious about doing this, and this seemed the most recent thread...
Trying out StainlessS' second AVS script, it seems to work well:
https://thumbs2.imagebam.com/05/10/a6/ebd18f1364466953.jpg (http://www.imagebam.com/image/ebd18f1364466953) https://thumbs2.imagebam.com/a2/5d/0d/b16c341364466956.jpg (http://www.imagebam.com/image/b16c341364466956) https://thumbs2.imagebam.com/cd/3c/93/fed42e1364466960.jpg (http://www.imagebam.com/image/fed42e1364466960)
Here's a 1080p 4:4:4 script scaled back up to 2160p (with a slight zoom) for comparison's sake. It keeps more of the reds (very noticeable in the shirt), while a simple z.lib resizer (https://forum.doom9.org/showthread.php?t=173986) kills a lot of it, and merges them with the surrounding colors. It's even keeping a tiny bit of the red on the makeup pen
Script:
DGSource("Test.dgi")
U=UToY
V=VToY
Y=z_Spline36Resize(Width/2,Height/2)
YtoUV(U,V,Y)
Source file: 2160p/HEVC/8-bit/BT.709
...it might need some kind of chroma shift to be properley standard.
I was curious about this comment though, wanted to make sure I'm doing it right. Should we be shifting the chroma/chromaloc at some point? My sources are all top-left chroma
poisondeathray
31st December 2020, 17:28
W
Trying out StainlessS' second AVS script, it seems to work well:
Here's a 1080p 4:4:4 script scaled back up to 2160p (with a slight zoom) for comparison's sake. It keeps more of the reds (very noticeable in the shirt), while a simple z.lib resizer (https://forum.doom9.org/showthread.php?t=173986) kills a lot of it, and merges them with the surrounding colors. It's even keeping a tiny bit of the red on the makeup pen
Script:
DGSource("Test.dgi")
U=UToY
V=VToY
Y=z_Spline36Resize(Width/2,Height/2)
YtoUV(U,V,Y)
Source file: 2160p/HEVC/8-bit/BT.709
I see the difference in your screenshots, but I cannot reproduce that difference on some random camera UHD source. There are negligible difference using subtract(a,b) for me. It might be different versions of plugins, or avs version, not sure
If there was a material difference between the methods, you should be able to use subtract(a,b) and see difference on a synthetic test like colorbarshd
Can you reproduce it on this
ColorBarsHD(3840, 2160)
ConvertToYV12()
U=UToY
V=VToY
Y=z_Spline36Resize(Width/2,Height/2)
YtoUV(U,V,Y)
a=last
ColorBarsHD(3840, 2160)
ConvertToYV12()
BITS=16 # Or 10, or 12, or 14, dont work with 32 for some reason. EDIT: Yes it does. VDub2 loads ok.
ConvertBits(BITS)
U=UToY # EDIT: Changed UToY8 to UToY, still worked for some strange reason, probably should have thrown error @ YtoUV()
V=VToY # EDIT: Changed VToY8 to VToY
Y=Spline36Resize(Width/2,Height/2) # Some Resizer
YtoUV(U,V,Y)
ConvertBits(8)
b=last
subtract(a,b)
vBulletin® v3.8.11, Copyright ©2000-2025, vBulletin Solutions Inc.