Log in

View Full Version : R68 color range issues (or I'm losing my mind)


hello_hello
25th July 2024, 15:58
I'm confused. I recall someone telling me the Vapoursynth color range values are the opposite of those used for Avisynth, so Limited=0 and Full=1. Is that correct?

clip = core.std.BlankClip(format=vs.YUV420P8).resize.Spline36(600,304)
clip = core.text.Text(clip, 'ColorRange ' + str(clip.get_frame(0).props.get("_ColorRange", None)))
clip.set_output()

https://imgur.com/frAa9yP.png

Aside from not being sure if the value is correct, why does the resize function always write a color range to frame properties? It'd be fair enough after a conversion between YUV and RGB etc as assumptions are required, but when only resizing?

Although what seems to be happening is the value going in isn't the one coming out.

clip = core.std.BlankClip(format=vs.YUV420P8).resize.Spline36(600,304, range=1, range_in=1)
clip = core.text.Text(clip, 'ColorRange ' + str(clip.get_frame(0).props.get("_ColorRange", None)))
clip.set_output()

https://imgur.com/f0FPEPb.png

And either because there's something wrong with the color range assumption or I'm losing the plot, AddBorders appears to be adding full range borders when they should be limited. They're okay if I specify the border color via this function (https://forum.doom9.org/showthread.php?t=185022) though (histogram showing the black level on the right side of the screenshots).

BClip = core.std.BlankClip(format=vs.YUV420P8)
Color = rgb.RGBColor(BClip, "green")
clip = core.std.BlankClip(BClip, format=vs.YUV420P8, color=Color).std.AddBorders(40,40,40,40)
clip = core.text.Text(clip, 'ColorRange ' + str(clip.get_frame(0).props.get("_ColorRange", None)))
clip = core.hist.Classic(clip)
clip.set_output()

https://imgur.com/WUB4acV.png

BClip = core.std.BlankClip(format=vs.YUV420P8)
ColorA = rgb.RGBColor(BClip, "green")
ColorB = rgb.RGBColor(BClip, "black")
clip = core.std.BlankClip(BClip, color=ColorA, format=vs.YUV420P8).std.AddBorders(40,40,40,40, color=ColorB)
clip = core.hist.Classic(clip)
clip = core.text.Text(clip, 'ColorRange ' + str(clip.get_frame(0).props.get("_ColorRange", None)))
clip.set_output()

https://imgur.com/LYi4ius.png

_Al_
26th July 2024, 04:06
the opposite of those used for Avisynth, Limited=0 and Full=1. Is that correct?
It is the opposite to zimg library syntax, where range arguments are the opposite to vapoursynth prop flag.

vapoursynth props:
https://www.vapoursynth.com/doc/apireference.html#reserved-frame-properties

When you set in vapoursynth resizer (zimg library) argument range=1, it is going to be _ColorRange 0 in props.

kwarg that sets a string rather than integer could be used instead to avoid this issue, to make a mistake, like range_s = "full" or range_s = "limited"

AddBorders appears to be adding full range borders when they should be limited
It looks color needs to be specified with color argument, even for default black.
If using RGBColor function it ends up with limited black. Maybe if clip props do not have a range in RGBColor function and YUV format is created from that BlankRGBClip, limited is used as a default to get luma 16 for 8bit.

It just looks like a color for AddBorders should be always specified.

hello_hello
26th July 2024, 17:00
Thanks for the info.

I couldn't find anything in the VapourSynth docs that mentioned specifying 0 and 1 for the resizer function wouldn't produce the expected result. It seems like something that should be made clear. As you said though, specifying color range as a string causes the expected value to be written to frame properties, and yes it appears AddBorders will always add full range borders unless you tell it what color black should be, which is probably something else that might be worth a mention in the docs. At least I understand what's happening now, although I wonder if it'd be possible for VapourSynth to convert 0 to 1 and 1 to 0 for the resizer function so there's no ambiguity.

Cheers.

Tiramisu
30th July 2024, 18:31
I personally just use vs enums whenever I can

For example:
vs.ColorRange.RANGE_FULL, vs.MATRIX_BT709, vs.PRIMARIES_BT709, vs.TRANSFER_LINEAR

Selur
1st August 2024, 17:39
didn't even know these existed *gig*

hello_hello
3rd August 2024, 10:10
If using RGBColor function it ends up with limited black. Maybe if clip props do not have a range in RGBColor function and YUV format is created from that BlankRGBClip, limited is used as a default to get luma 16 for 8bit.

For the record, BlankClip(format=vs.YUV420P8) also creates a blank clip with a black value of 0 rather than 16.
But yes. the reason for the RGBColor function outputting a value of 16 for black is due to the conversion from an RGB blank clip to YUV near the end of the function (for a YUV source), which by default is full to limited range, and the YUV clip is the one the function takes the color values from.

Mind you I realized that because I was using the color range frame properties for the resize function's range argument, and because the values are the opposite for the resize function, the wrong color range was being specified when there was a value in frame properties, so I'll have to fix that.

_Al_
4th August 2024, 06:09
Basically rangeProp_kwarg function came up with {} for outgoing range kwarg, because no range was in clip's props, so vapoursynth defaulted in resize function.
I would not expect that also. Though a regular user might appreciate it, that his default YUV420P8 black is like that :-), hard to say. Or user would just set black YUV with color (16,128,128), as I was doing lots of times to specify 16 black, knowing black should never be below that in video for fade-in or fade-out for YUV limited.

So if wanting YUV with zero black for tat RGBcolor function, range_s="full" would need to be passed and be involved as well. To the contrary I perhaps said somewhere before, that it is not needed.
But for clip with YUV444PS format, float, it sets zero black, that you probably know, I just tested that.

_Al_
14th August 2024, 16:29
I got to this (https://github.com/vapoursynth/vapoursynth/pull/1012/commits/48203b0ebb20e2a752db0220df12a6cb5bc786de) by a chance to see value_zimg was added to vapoursynth on the top of regular prop value:
print(vs.RANGE_FULL.value) # or print(vs.RANGE_FULL)
print(vs.RANGE_LIMITED.value) # print(vs.RANGE_LIMITED)
this could be used also:
print(vs.RANGE_FULL.value_zimg)
print(vs.RANGE_LIMITEDL.value_zimg)

So that value_zimg could be used in resize function as an argument.
It was updated around December 2023, so it might be available since R66 version or so.