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.

Domains: forum.doom9.org / forum.doom9.net / forum.doom9.se

 

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

Reply
 
Thread Tools Search this Thread Display Modes
Old 26th February 2015, 00:39   #1  |  Link
kolak
Registered User
 
Join Date: Nov 2004
Location: Poland
Posts: 2,869
out of gamut fix

Is it possible to use avisynth as out of gamut filter?
Some YUV signals produce illegal RGB values once converted over Rec.601/Rec.709 inverse matrixes. Could avisynth help?

More about the problem:

http://www.vidcheck.com/support/white-papers.php
kolak is offline   Reply With Quote
Old 26th February 2015, 04:55   #2  |  Link
colours
Registered User
 
colours's Avatar
 
Join Date: Mar 2014
Posts: 308
Slightly inefficient, but one way you can check for YUV exceeding the gamut is to first reduce the range then convert to RGB as usual, after which we can apply some sort of fancy soft limiting for out-of-gamut values. Maybe something like this (entirely untested):

Code:
source
Dither_lut8(expr="x 128 - 3 / 128 + 256 *",yexpr="x 125.5 - 3 / 125.5 + 256 *",u=3,v=3)
# replace 128 and 125.5 with 127.5 if working with a full-range source
Dither_convert_yuv_to_rgb(matrix="709",lsb_in=true,output="rgb48y")
r = SelectEvery(3,0)
g = SelectEvery(3,1)
b = SelectEvery(3,2)
undershoot = cl_exprxyz(r,g,b,"21760 x y z min min -",lsb=true).SelectEvery(1,0,0,0)
overshoot = cl_exprxyz(r,g,b,"x y z max max 43520 -",lsb=true).SelectEvery(1,0,0,0)
rgb_fixed = cl_exprxyz(last,undershoot,overshoot,"x 21760 y - - 21760 y z + + / 65280 *",lsb=true)
# the above is not exactly "fancy" soft limiting, but derp.
rgb_fixed.DitherPost(mode=6)
MergeRGB(SelectEvery(3,0),SelectEvery(3,1),SelectEvery(3,2))
Edit: now actually tested; forgot the lsb_in=true earlier.
__________________
Say no to AviSynth 2.5.8 and DirectShowSource!

Last edited by colours; 28th February 2015 at 08:20.
colours is offline   Reply With Quote
Old 26th February 2015, 09:19   #3  |  Link
kolak
Registered User
 
Join Date: Nov 2004
Location: Poland
Posts: 2,869
Will try, thx.

So whole difficultly is to have fancy soft clipping method?

I assume first step (or maybe not necessarily 1st) is to limit luma and chroma to YUV values, which is also part of the whole legalisation process.

Another thing, which seams to be easier is to report out of gamut frames. This has some threasholds, described in EBU R103 standard. This has details:

https://www.google.co.uk/url?sa=t&so...KyKP5DGXFzNgFA

They mention low pass filtering, before checking, is this possible?

Last edited by kolak; 26th February 2015 at 09:27.
kolak is offline   Reply With Quote
Old 26th February 2015, 10:42   #4  |  Link
kolak
Registered User
 
Join Date: Nov 2004
Location: Poland
Posts: 2,869
Quote:
Originally Posted by colours View Post
Slightly inefficient, but one way you can check for YUV exceeding the gamut is to first reduce the range then convert to RGB as usual, after which we can apply some sort of fancy soft limiting for out-of-gamut values. Maybe something like this (entirely untested):

Code:
source
Dither_lut8(expr="x 128 - 3 / 128 + 256 *",yexpr="x 125.5 - 3 / 125.5 + 256 *",u=3,v=3)
# replace 128 and 125.5 with 127.5 if working with a full-range source
Dither_convert_yuv_to_rgb(matrix="709",output="rgb48y")
r = SelectEvery(3,0)
g = SelectEvery(3,1)
b = SelectEvery(3,2)
undershoot = cl_exprxyz(r,g,b,"21760 x y z min min -",lsb=true).SelectEvery(1,0,0,0)
overshoot = cl_exprxyz(r,g,b,"x y z max max 43520 -",lsb=true).SelectEvery(1,0,0,0)
rgb_fixed = cl_exprxyz(last,undershoot,overshoot,"x 21760 y - - 21760 y z + + / 65280 *",lsb=true)
# the above is not exactly "fancy" soft limiting, but derp.
rgb_fixed.DitherPost(mode=6)
MergeRGB(SelectEvery(3,0),SelectEvery(3,1),SelectEvery(3,2))

Have an error that mt_lut supports only planar color spaces - fixed

but...

cl_exprxyz fails due to my card being old/not supported probably. Is there work around?

Last edited by kolak; 26th February 2015 at 13:11.
kolak is offline   Reply With Quote
Old 14th October 2018, 11:15   #5  |  Link
Soulnight
Registered User
 
Join Date: Jan 2017
Location: Germany
Posts: 21
Quote:
Originally Posted by colours View Post
Slightly inefficient, but one way you can check for YUV exceeding the gamut is to first reduce the range then convert to RGB as usual, after which we can apply some sort of fancy soft limiting for out-of-gamut values. Maybe something like this (entirely untested):

Code:
source
Dither_lut8(expr="x 128 - 3 / 128 + 256 *",yexpr="x 125.5 - 3 / 125.5 + 256 *",u=3,v=3)
# replace 128 and 125.5 with 127.5 if working with a full-range source
Dither_convert_yuv_to_rgb(matrix="709",lsb_in=true,output="rgb48y")
r = SelectEvery(3,0)
g = SelectEvery(3,1)
b = SelectEvery(3,2)
undershoot = cl_exprxyz(r,g,b,"21760 x y z min min -",lsb=true).SelectEvery(1,0,0,0)
overshoot = cl_exprxyz(r,g,b,"x y z max max 43520 -",lsb=true).SelectEvery(1,0,0,0)
rgb_fixed = cl_exprxyz(last,undershoot,overshoot,"x 21760 y - - 21760 y z + + / 65280 *",lsb=true)
# the above is not exactly "fancy" soft limiting, but derp.
rgb_fixed.DitherPost(mode=6)
MergeRGB(SelectEvery(3,0),SelectEvery(3,1),SelectEvery(3,2))
Edit: now actually tested; forgot the lsb_in=true earlier.
Hi,

interesting post. I understand only partially the code what you wrote but would like to do something similar.

My target is to analyse 4k HDR REC2020 clips to see what pixel lies outside REC709.

For this, If I understood correctly,

I need to:
1) Convert YUV to RGB
2) Convert non linear RGB to linear RGB
3) Convert REC2020 RGB to REC709 RGB

I have created the matrix for the step 3, and everything which is outside REC709 should then get illegal RGB triplet.

And I would like to give those illegal RGB triplet a certain value, like (0,0,0) to paint them black.

Could you help me?


My current code:

Code:
loadplugin("C:\Users\flole\Downloads\ManualColorMatrix\ManualColorMatrix_26.dll")
loadplugin("C:\Users\flole\Videos\AviSynth\HDRTools\x86\Release_W7\HDRTools.dll")
Directshowsource("F:\Kodi\Demo 4k HDR\The World In HDR 4K Demo.mkv")
ConvertYUVtoLinearRGB(Color=1)
#isRGB()
ManualColorMatrix(1, 1.66049, -0.58764, -0.07285, -0.12455, 1.13290, -0.00835, -0.01815, -0.10058, 1.11873)
Thank you.


Florian
Soulnight is offline   Reply With Quote
Old 26th February 2015, 14:39   #6  |  Link
hanfrunz
Registered User
 
hanfrunz's Avatar
 
Join Date: Feb 2002
Location: Germany
Posts: 541
a very brutal method is to use converttorgb32() and then converttoyuy2(), but if you need broadcast safe colors better use a plugin or a hardware legalizer (eyeheight is a good brand)
hanfrunz is offline   Reply With Quote
Old 26th February 2015, 16:26   #7  |  Link
kolak
Registered User
 
Join Date: Nov 2004
Location: Poland
Posts: 2,869
Quote:
Originally Posted by hanfrunz View Post
a very brutal method is to use converttorgb32() and then converttoyuy2(), but if you need broadcast safe colors better use a plugin or a hardware legalizer (eyeheight is a good brand)
Yes, eyeheight is good, but they have only NLE plugins.

I want something which I can chain, script using pipes etc.
I believe it's way easier to do than some other avisynth plugins, scripts, just not needed by many people.
kolak is offline   Reply With Quote
Old 26th February 2015, 16:02   #8  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
I believe Wilbert and Gavino might have been involved with something along those lines a few years ago.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 27th February 2015, 11:26   #9  |  Link
Gavino
Avisynth language lover
 
Join Date: Dec 2007
Location: Spain
Posts: 3,442
Quote:
Originally Posted by StainlessS View Post
I believe Wilbert and Gavino might have been involved with something along those lines a few years ago.
You're probably thinking of the thread U and V ranges for valid RGB.
In post #14 of that thread, I gave a function ShowBadRGB() that shows the areas of a YUV clip that contain 'invalid' RGB values.
(Note: it takes a long time to load because of the mt_lutxyz function.)

It doesn't correct the problem, but it does show whether the problem exists and which areas need attention.
__________________
GScript and GRunT - complex Avisynth scripting made easier
Gavino is offline   Reply With Quote
Old 27th February 2015, 12:30   #10  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 11,406
Yes Gavino, that was the thread I was thinking of although was wrong about Wilbert being involved (I think that was another thread).
I mainly remembered the animation which I still find fascinating.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 27th February 2015, 13:25   #11  |  Link
kolak
Registered User
 
Join Date: Nov 2004
Location: Poland
Posts: 2,869
Can anything be developed in this area- maybe sponsored (but probably rather for vapourysnth)?
kolak is offline   Reply With Quote
Old 28th February 2015, 01:46   #12  |  Link
raffriff42
Retried Guesser
 
raffriff42's Avatar
 
Join Date: Jun 2012
Posts: 1,371
Limiter is the gamut filter you are looking for (I think).
[EDIT wrong, see next post]

Also, subtracting Limiter's output from the source shows the out-of-range pixels.
Something like this:

On the right-hand "Diff" image, luma < 16 shows as black, white > 235 shows as white, etc
(note source contrast is exaggerated to show the effect)
Code:
Assert(IsYUV(Last), "YUV source required")

## for demo purposes, exaggerate contrast
#ColorYUV(levels="TV->PC")

return Last.ShowOutOfGamut()

##################################
### Show out-of-gamut pixels. 
##
## @ diff_scale - exaggerate the diff signal (range 1..128, default 32)
##
function ShowOutOfGamut(clip C, int "diff_scale")
{
    diff_scale = Min(Max(1, Default(diff_scale, 32)), 128)

    C ## Last==C
    Diff=Subtract(Last, Limiter())
    \ .ColorYUV(
    \  off_y=2*diff_scale, 
    \  cont_y=f2cuv(diff_scale), 
    \  cont_u=f2cuv(diff_scale), 
    \  cont_v=f2cuv(diff_scale))

    return StackHorizontal(
    \  Last, 
    \  Diff.Subtitle("Diff x "+String(Round(diff_scale)), size=Last.Height/8))
    \ .BilinearResize(Last.Width, Last.Height)
}

## scale "normal" float arguments to suit ColorYUV
function f2cuv(float f) { return Round((f - 1.0) * 256.0) }

Last edited by raffriff42; 17th March 2017 at 23:57. Reason: (fixed image link)
raffriff42 is offline   Reply With Quote
Old 28th February 2015, 09:41   #13  |  Link
colours
Registered User
 
colours's Avatar
 
Join Date: Mar 2014
Posts: 308
Limiter only limits the YUV values to [16,235] or [16,240], which is not enough to guarantee that the resulting RGB values are in [0,255].

I fixed the script I posted earlier, and it seems to work exactly as expected now. The test image is a U/V gradient with Y set to 168. The Mach bands are annoying, but I can't think of any obvious way to deal with them at the moment.

It shouldn't be too difficult to port this directly to a C/C++ filter for Avisynth or VapourSynth, though it might not be useful as is.
__________________
Say no to AviSynth 2.5.8 and DirectShowSource!
colours is offline   Reply With Quote
Old 28th February 2015, 15:44   #14  |  Link
kolak
Registered User
 
Join Date: Nov 2004
Location: Poland
Posts: 2,869
Thanks a lot. It doesn't look very bad. I think it lacks some soft roll-off.
Do you know what are the requirements for cl_expr plugin in terms of GPU?
Any CPU replacement for it?

I've checked and it looks quite good- in gamut are is practically untouched. Here is a difference (boosted):




I assume we just don't want this hard borders?
How/can it be "smoothed"?

Last edited by kolak; 1st March 2015 at 00:14.
kolak is offline   Reply With Quote
Old 1st March 2015, 12:51   #15  |  Link
colours
Registered User
 
colours's Avatar
 
Join Date: Mar 2014
Posts: 308
Quote:
Originally Posted by kolak View Post
I think it lacks some soft roll-off.
Probably because it's actually still hard limiting the colours, albeit in a way different from limiting the red/green/blue channels individually. What I'm doing preserves hue while sacrificing luma and saturation accuracy.

Quote:
Originally Posted by kolak View Post
Do you know what are the requirements for cl_expr plugin in terms of GPU?
Not sure, but it works with my laptop's integrated graphics (Intel).

Quote:
Originally Posted by kolak View Post
I've checked and it looks quite good- in gamut are is practically untouched. [snip] I assume we just don't want this hard borders?
How/can it be "smoothed"?
The problem is, to implement soft limiting, it's necessary to sacrifice accuracy even for in-gamut YCbCr values. I have a rough idea on how to do this, but CLExpr likes to error out when I use it too many times in a single script (tp7 says this is probably because Intel's OpenCL drivers are bad) so I'm not particularly interested in implementing it at the moment.
__________________
Say no to AviSynth 2.5.8 and DirectShowSource!

Last edited by colours; 1st March 2015 at 12:53.
colours is offline   Reply With Quote
Old 1st March 2015, 14:04   #16  |  Link
kolak
Registered User
 
Join Date: Nov 2004
Location: Poland
Posts: 2,869
I may have more interesting news tomorrow, once I test your image with pro solution. It may end up that your script is actually very good

As far as I know you have to change correct values also in order to have some soft clipping. I think this is exactly the case for pro solutions, so please carry on with your ideas
kolak is offline   Reply With Quote
Old 3rd March 2015, 23:50   #17  |  Link
Asmodian
Registered User
 
Join Date: Feb 2002
Location: San Jose, California
Posts: 4,484
My understanding is that this "Intelligent Auto Correction" legalization is only useful if you want to keep the out of gamut details visible. Of course, this requires you to change in-gamut values as well or you are simply clipping.

It is the difference between perceptual gamut mapping and absolute gamut mapping. IMO small differences in gamut should use absolute (clipped) while large differences in gamut need a perceptual method or you get banding. There are really a lot of possible perceptual methods developed for the graphic design field that are applicable to video, I do not know why Vidcheck thinks they are special.

It did have more sense for analog but when using perceptual methods it isn't clipped even in the digital world. I suppose legalization could also be important if dealing with a bad/non-standard YCbCr to RGB converter that was willing to output RGB values below 0 or above 255.
Asmodian is offline   Reply With Quote
Old 4th March 2015, 00:17   #18  |  Link
kolak
Registered User
 
Join Date: Nov 2004
Location: Poland
Posts: 2,869
Well, yes. I assume it's for more advaced than simple clipping conversion, so actual look of the frame changes as little as possible.
Do they think they are special? Hmmm...maybe because their algorythm tries to preserve 'the look' as you mentioned. For example if you have some pure black frames (16) and auto correction happens than this may be raised to eg 20. They say this is desired, some place reject such a files, where 'pure' black is not at 16
kolak 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 15:10.


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