Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 5th January 2014, 14:08   #1  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,085
1080p 4:2:0 to 540p 4:4:4 without resizing chroma?

Hi everyone,

I'm wondering if is possible to correctly downscale 1080p 4:2:0 to 540p 4:4:4 without resizing chroma?
Using the idea and example from here, this is what I have so far.
Code:
# 1920x1080p Source
DGSource("00042.dgi")

# Processing
Y = ConvertToY8(matrix="Rec709").Spline36Resize(width/2, height/2)
U = UToY8()
V = VToY8()
YToUV(U, V, Y)

ConvertToRGB24(matrix="Rec709")
To the eye it looks good but I don't know if it's technically correct.
Reel.Deel is offline   Reply With Quote
Old 5th January 2014, 14:21   #2  |  Link
feisty2
I'm Siri
 
feisty2's Avatar
 
Join Date: Oct 2012
Location: Los Angeles, California
Posts: 2,119
most yv12 clips are top left aligned so you shouldn't use a center aligned resizer to resize the luma and merge it to a top left aligned chroma
instead, using a top left aligned resizer should be correct, something like xxxresize (960,540,src_top=1,src_left=1)
feisty2 is offline   Reply With Quote
Old 14th January 2014, 06:21   #3  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,085
Okay, so I had some time and I did some test to try to figure out the correct offsets regarding chroma position. Since I want to leave the chroma untouched the alternative is to shift the luma when resizing.
I don't really know what I'm doing so I tried a handful of different offset values.

Just a sample:
Code:
# 1920x1080p Source
DGSource("00042.dgi")

# Processing
Y  = ConvertToY8(matrix="Rec709").Spline36Resize(width/2, height/2, src_left=0.00, src_top=0.00).Subtitle("Y")
Y2 = ConvertToY8(matrix="Rec709").Spline36Resize(width/2, height/2, src_left=0.25, src_top=0.00).Subtitle("Y2")
Y3 = ConvertToY8(matrix="Rec709").Spline36Resize(width/2, height/2, src_left=0.50, src_top=0.00).Subtitle("Y3")
Y4 = ConvertToY8(matrix="Rec709").Spline36Resize(width/2, height/2, src_left=0.50, src_top=0.75).Subtitle("Y4")
Y5 = ConvertToY8(matrix="Rec709").Spline36Resize(width/2, height/2, src_left=1.00, src_top=1.00).Subtitle("Y5")

U = UToY8()
V = VToY8()

Y  = YToUV(U, V, Y)
Y2 = YToUV(U, V, Y2)
Y3 = YToUV(U, V, Y3)
Y4 = YToUV(U, V, Y4)
Y5 = YToUV(U, V, Y5)

Interleave(Y, Y2, Y3, Y4, Y5)
PointResize(width*2, Height*2) # for testing only
ConvertToRGB24(matrix="Rec709")
After all that I think src_left=0.50, src_top=0.75 produced better results (at least to my eyes) although I think it's incorrect. In the end, I'm still left with uncertainty.

Does anyone know the math involved to calculate the correct offsets?

Quote:
Originally Posted by rean View Post
No. It is incorrect code. I tried this way some time ago and got color artifacts (chroma placement)...
To be honest I do not see any obvious color artifacts, if anything the incorrect offsets are hardly noticeable.
Reel.Deel is offline   Reply With Quote
Old 14th January 2014, 11:54   #4  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
The correct offsets are src_left=-0.50, src_top=0.

Avisynth resizers preserve the position of the image centre (treating the pixels as point samples).
For 4:2:0 with MPEG2 placement, the horizontal chroma centre is 0.5 luma pixels to the left of the luma centre.
Code:
                   luma centre
                       |
Luma:   L L L L ... L L L L ... L L L L
Chroma: C   C   ... C   C   ... C   C
                      |
                  chroma centre
Therefore, to make the resized luma coincide with the original chroma, you need src_left=-0.5.
Since the vertical centre positions are the same for luma and chroma, src_top=0.

The visual difference when using the wrong offsets (or no offsets) is very small except where you have a sharp chroma transition.
__________________
GScript and GRunT - complex Avisynth scripting made easier

Last edited by Gavino; 14th January 2014 at 11:57.
Gavino is offline   Reply With Quote
Old 14th January 2014, 13:26   #5  |  Link
mastrboy
Registered User
 
Join Date: Sep 2008
Posts: 287
I have 2 generic questions about downscaling 1080p 4:2:0 to 540p 4:4:4 someone hopefully could answer:
- In a blind sample test would you actually be able to differentiate between a 540p 4:2:0 and a 540p 4:4:4 downscaled from a good BD source?
- For a generic source, how much would the filesize increase when using x264 and crf encoding at for example crf 16 ? (A guesstimate is good enough)
__________________
(i have a tendency to drunk post)
mastrboy is offline   Reply With Quote
Old 14th January 2014, 16:05   #6  |  Link
Reel.Deel
Registered User
 
Join Date: Mar 2012
Location: Texas
Posts: 1,085
Quote:
Originally Posted by Gavino View Post
The correct offsets are src_left=-0.50, src_top=0.
I'm not surprised that I was completely wrong (didn't even try negative values )
Thank you very much Gavino. Your illustration helps me understand the offsets a bit better...(Now I'm going to read this post multiple times )
Reel.Deel is offline   Reply With Quote
Old 14th January 2014, 17:34   #7  |  Link
davidhorman
I'm the Doctor
 
Join Date: Jan 2004
Posts: 1,509
Quote:
Originally Posted by mastrboy View Post
I have 2 generic questions about downscaling 1080p 4:2:0 to 540p 4:4:4 someone hopefully could answer:
- In a blind sample test would you actually be able to differentiate between a 540p 4:2:0 and a 540p 4:4:4 downscaled from a good BD source?
I think you'd have to run the test (since the point of a blind test is to get at what people can see, not what people say they can see). My answer would be an unequivocal "maybe"

In normal viewing conditions, with normal content, I'd say it's unlikely. That's 4:2:0's raison d'etre, after all.
davidhorman is offline   Reply With Quote
Old 14th January 2014, 22:36   #8  |  Link
DarkSpace
Registered User
 
Join Date: Oct 2011
Posts: 204
I'm just trying to grasp this logically, but wouldn't a left shift mean that you should use
Code:
in = BlankClip(pixel_type="YV12")# or any other YV12 source, really
Y = ConvertToY8().Spline36Resize(in.Width()/2, in.Height()/2, src_left=-0.5, src_width=-0.5)
U = UToY8()
V = VToY8()
YToUV(U, V, Y)
instead? As I understand it, all that src_left=-0.5 does by itself is "widen" the resolution to Width+0.5...
DarkSpace is offline   Reply With Quote
Old 15th January 2014, 00:22   #9  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
The default for src_width is the width of the input (not zero as in Crop()), so it can be omitted.
src_width=-0.5 has the same effect and is also correct.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 15th January 2014, 12:21   #10  |  Link
DarkSpace
Registered User
 
Join Date: Oct 2011
Posts: 204
Quote:
Originally Posted by Gavino View Post
The default for src_width is the width of the input (not zero as in Crop()), so it can be omitted.
src_width=-0.5 has the same effect and is also correct.
Thanks. I've been wondering how that fits for some time, but I always assumed Crop-like behavior. No wonder I was wrong.
DarkSpace is offline   Reply With Quote
Old 24th January 2014, 11:32   #11  |  Link
Divet
Registered User
 
Join Date: Dec 2007
Posts: 16
Quote:
Originally Posted by Gavino View Post
The correct offsets are src_left=-0.50, src_top=0.
May I ask another question here, would You advise me, please?
If I want to make 1280x720 4:4:4 bd-rip from 1920x1080 4:2:0 source blu-ray (Yes, I know it won't be "true" 4:4:4 color but It will be better than 4:2:0, because less source data will be lost) what code (or both) will be right (or not)?

Code:
Y = ConvertToY8().Spline36Resize(1280, 720, src_left=-0.5)
U = UToY8().Spline36Resize(1280, 720)
V = VToY8().Spline36Resize(1280, 720)
YToUV(U, V, Y)
Code:
Y = ConvertToY8().Spline36Resize(1280, 720)
U = UToY8().Spline36Resize(1280, 720, src_left=0.25)
V = VToY8().Spline36Resize(1280, 720, src_left=0.25)
YToUV(U, V, Y)

Last edited by Divet; 24th January 2014 at 11:39.
Divet is offline   Reply With Quote
Old 24th January 2014, 17:37   #12  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
Quote:
Originally Posted by Divet View Post
what code (or both) will be right (or not)?
Both are correct as far as chroma alignment is concerned.
The first one shifts the luma centre 0.5 pixels to the left so it lines up with the chroma centre. The second one shifts the chroma centre 0.25 chroma pixels (=0.5 luma pixels) to the right, again producing alignment.

I prefer the second one conceptually as it seems more consistent with normal resizing to preserve the luma centre.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 24th January 2014, 19:00   #13  |  Link
Divet
Registered User
 
Join Date: Dec 2007
Posts: 16
Quote:
Originally Posted by Gavino View Post
Both are correct as far as chroma alignment is concerned.
Thank You very much!
I got it! Now it is clear, when we have progressive blu-ray (1080p).
But I am interesting in 1080i too. Is it more complex? How to resize interlaced Y, U, V independently?
I am talking about true interlaced video, shooted by interlaced camera, such as documentary movies. Not about transferred cinema with pulldown, etc.

First, I do this:
Code:
SeparateFields()
then I do:
Code:
video1=SelectEven()
then I must do vertical shift correction! So is it correct to add src_top=0.5 to resizing each panel - Y, U and V? (And do not add src_top=0.5 to resizing Y, U and V from video2=SelectOdd().)

But I am not sure about chroma placement after SeparateFields()... Are both videos (made by SelectEven and SelectOdd) normal, common 4:2:0 progressive videos?

I am not planning to reconstruct interlaced video after resizing. The last lines of my avs scrypt will be:
Code:
Interleave(video1, video2)
AssumeFrameBased
so the result will be 4:4:4 progressive video with 50fps if pal (or 59.94fps if ntsc)

Last edited by Divet; 24th January 2014 at 21:17.
Divet is offline   Reply With Quote
Old 24th January 2014, 22:21   #14  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
Quote:
Originally Posted by Divet View Post
So is it correct to add src_top=0.5 to resizing each panel - Y, U and V? (And do not add src_top=0.5 to resizing Y, U and V from video2=SelectOdd().)

But I am not sure about chroma placement after SeparateFields()... Are both videos (made by SelectEven and SelectOdd) normal, common 4:2:0 progressive videos?
Top fields and bottom fields have different vertical chroma placement relative to luma, neither of which is the same as a progressive 4:2:0 frame - see here.

You need to use src_top=+0.25 when resizing each of Y, U and V for top fields, and src_top=-0.25 similarly for bottom fields.
For a TFF source, SelectEven() gives you the top fields and SelectOdd() the bottom fields. For BFF, it is the other way round.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 25th January 2014, 00:02   #15  |  Link
Divet
Registered User
 
Join Date: Dec 2007
Posts: 16
Quote:
Originally Posted by Gavino View Post
You need to use src_top=+0.25 when resizing each of Y, U and V for top fields, and src_top=-0.25 similarly for bottom fields.
I am surprised! This +0.25 and -0.25 I need for vertical shift compensation? I mean, shift between fields = half of one field line (pixel).

And if src_top is the same for Y, U and V, then I can figure out that there is no vertical shift between luma and chroma (in a field). Is it correct?

And what about horizontal shift between luma and chroma? I remember I need src_left=0.25 when resizing U and V! Is it correct for fields?
Divet is offline   Reply With Quote
Old 25th January 2014, 01:44   #16  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
Quote:
Originally Posted by Divet View Post
I am surprised! This +0.25 and -0.25 I need for vertical shift compensation? I mean, shift between fields = half of one field line (pixel).
Yes, since displacement between top field and bottom field is one original (full-frame) line, which is half of one field line. (You previously suggested +0.5 and zero, which is also a relative difference of 0.5.)

Quote:
And if src_top is the same for Y, U and V, then I can figure out that there is no vertical shift between luma and chroma (in a field). Is it correct?
Since chroma spacing is twice luma spacing, the offsets, though numerically equal, represent different distances. (Assuming you are still separating luma and chroma and resizing independently as before.)
So there is a vertical shift between luma and chroma, and that is necessary because (in a field, unlike a progressive frame) their vertical centres are in different places.

Quote:
And what about horizontal shift between luma and chroma? I remember I need src_left=0.25 when resizing U and V! Is it correct for fields?
Yes, horizontal chroma placement is the same for fields and frames.
__________________
GScript and GRunT - complex Avisynth scripting made easier

Last edited by Gavino; 25th January 2014 at 01:48.
Gavino is offline   Reply With Quote
Old 25th January 2014, 09:08   #17  |  Link
Divet
Registered User
 
Join Date: Dec 2007
Posts: 16
Quote:
Originally Posted by Gavino View Post
the offsets, though numerically equal, represent different distances.
Understood! Thanks!

Quote:
Originally Posted by Gavino View Post
(in a field, unlike a progressive frame) their vertical centres are in different places.
This is because different vertical chroma placement, is this?

Quote:
Originally Posted by Gavino View Post
Yes, horizontal chroma placement is the same for fields and frames.
So we can write this, for example:
Code:
Y = ConvertToY8().Spline36Resize(1280, 720, src_top=0.25)
U = UToY8().Spline36Resize(1280, 720, src_top=0.25, src_left=0.25)
V = VToY8().Spline36Resize(1280, 720, src_top=0.25, src_left=0.25)
YToUV(U, V, Y)
Divet is offline   Reply With Quote
Old 25th January 2014, 15:18   #18  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
Quote:
Originally Posted by Divet View Post
This is because different vertical chroma placement, is this?
Yes, see the reference I gave in post #15, which shows the layout of both progressive and interlaced YV12:
http://avisynth.nl/index.php/Sampling#YV12_color_format
Also the MPEG-2 section of this: http://www.mir.com/DMG/chroma.html

Quote:
So we can write this, for example:
Code:
Y = ConvertToY8().Spline36Resize(1280, 720, src_top=0.25)
U = UToY8().Spline36Resize(1280, 720, src_top=0.25, src_left=0.25)
V = VToY8().Spline36Resize(1280, 720, src_top=0.25, src_left=0.25)
YToUV(U, V, Y)
Yes, that's correct for the top fields. For bottom fields, you need src_top=-0.25 in all three places.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 25th January 2014, 21:58   #19  |  Link
Divet
Registered User
 
Join Date: Dec 2007
Posts: 16
Quote:
Originally Posted by Gavino View Post
Yes, that's correct for the top fields. For bottom fields, you need src_top=-0.25 in all three places.
Yes! Many thanks!

And if I don't resize something horizontally I don't need src_left=0.25. For example, if I resize chroma 960x270 (one field chroma) to 960x540 or to 960x360. Correct?

Last edited by Divet; 26th January 2014 at 16:03.
Divet is offline   Reply With Quote
Old 26th January 2014, 00:25   #20  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,380
Quote:
Originally Posted by Divet View Post
And if I don't resize something horizontally I don't need src_left=0.25. For example, if I resize chroma 960x270 (one field chroma) to 960x540 or to 960x360. Correct?
No, incorrect.
If you are still downsizing the luma (to match the chroma size and produce a 4:4:4 result), then you still need src_left=0.25 on the chroma, or alternatively src_left=-0.5 on the luma. The luma downsize shifts the luma sampling positions, so the chroma must be shifted to match, even when staying at its original size.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 22:19.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2018, vBulletin Solutions Inc.