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. |
10th December 2024, 18:29 | #21 | Link | ||
Registered User
Join Date: Sep 2007
Posts: 5,591
|
Quote:
eg. Your point of reference is is 8bit RGB. If you convert to 10bit YUV, you can get back the original 8bit RGB values 8bit RGB => 10bit YUV => 8bit RGB can be lossless if done properly Quote:
If the 8bit YUV is considered the "source" or starting point - after you do a conversion, can you get back the same values or not ? That's what "lossless" means - you have the same values. 8bit YUV => 8bit RGB is not lossless because you cannot get back the 8bit YUV values Similarly, all these steps are lossy and not reversible, you cannot get back any of the original values from a preceding step 8bit RGB original, original source => 8bit YUV (already lossy compared to previous step) => 8bit RGB (2 generation lossy steps) Last edited by poisondeathray; 10th December 2024 at 18:43. |
||
10th December 2024, 20:41 | #22 | Link | ||
Registered User
Join Date: Oct 2012
Posts: 8,237
|
you can easily see that error
Quote:
Quote:
|
||
11th December 2024, 02:02 | #23 | Link | |
Registered User
Join Date: Aug 2024
Posts: 299
|
Quote:
I keep saying my reference point is YUV (originated from RGB, but the loss is done, doesn't matter at all now), and you just keep saying my reference point is RGB. What can I say. You have your "if done properly", I have mine. Let's not bother it too much. |
|
11th December 2024, 03:16 | #24 | Link | |
Registered User
Join Date: Sep 2007
Posts: 5,591
|
Quote:
ie. 8bit YUV (from a 8bit RGB source) to 8bit RGB is still lossy, when using 8bit YUV as the reference point - for the reasons already mentioned. If you want definitive proof, you can test with all 16777216 8bit RGB color combinations as a pre starting point (A) - all "out of gamut values" are culled by definition Make your 8bit YUV444 starting point (B), and convert to 8bit RGB (C) - There is no way you can get back the YUV444 (B) , (or original RGB colors (A) ), from (C) You can generate the pattern see this thread , or use ffmpeg allrgb https://forum.doom9.org/showthread.php?t=183816 https://ffmpeg.org/ffmpeg-filters.ht...02c-yuvtestsrc For (C) - the attempt to convert back to YUV444P8 to achieve (B) "your" original values, the PSNR is about 86db. It would have been infinity if it was lossless for ffmpeg psnr. Now slightly different methods will give slightly higher or lower, but it's always expected to be lossy (unless you have some weird source with 1 color that just happens to map correctly) |
|
11th December 2024, 07:59 | #25 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,145
|
Yes but the scenario you're describing has more to do with the fact that you have out of range values than it has to do with RGB in general, but I understand your logic.
One however could therefore argue that scaling YUV to Studio RGB (that is, RGB in limited TV range) is therefore lossy 'cause both of them are limited. In other words: YUV Limited TV range to Studio RGB limited TV range = lossless YUV Full PC range to RGB full PC range = lossless YUV Limited TV range to RGB Full PC Range = lossless as long as the original YUV stays within 0.0-0.7V, as it should. In general, even when you're receiving a feed from your favourite TV station, letting anything get to out of range values, so above 0.7V (i.e 700 mV) or 235 for those who prefer the 8bit value reference is a sin 'cause all customer's TV are RGB anyway, so they would lose whatever is above 235 as that value is expanded to 255 and you run out of room. One of the things that is generally done is the soft highlights rollback to basically dim down the highlights of the elements going out of range to make them get back within the limited TV range. Even during live events, where you have potentially fast and unpredictable movement compared to interviews, you generally regulate the thing and then you put hardware clipping on the signal in anyway. This is checked using real time hardware waveform monitors like the ones from Tektronix https://imgur.com/HRLItw3 and is what led me to create VideoTek() in Avisynth https://forum.doom9.org/showthread.php?p=1832846 - https://github.com/FranceBB/VideoTek Last edited by FranceBB; 11th December 2024 at 08:06. |
11th December 2024, 15:43 | #26 | Link | ||
Registered User
Join Date: Sep 2007
Posts: 5,591
|
Quote:
"out of gamut" is a separate topic than "legal range" , "full range" . You can produce out of gamut values, even when you have legal range YUV values Quote:
Prove it to yourself. Start with that RGB image in the post above and run through these 3 scenarios . Make sure you use YUV444P8 so we avoid discussing subsampling issues for now Even if you remove out of gamut values - 8bit YUV => 8bit RGB does not have enough precision to map to a specific RGB value - there are multiple YUV values that map to a single RGB value that is within gamut. You end up with +/- 3 errors , and rounding errors. This is one of the contributing reasons behind 8bit "banding" . With 10bit YUV, there is enough precision to map exactly to each 8bit RGB 16777216 values |
||
12th December 2024, 19:10 | #28 | Link | |
Registered User
Join Date: Aug 2024
Posts: 299
|
Quote:
The real problem is rounding. Take 8bit RGB value (210,87,0) as example. When converted to full range 8bit YUV using BT.709 matrix you get (107,70,193), the "floting point" result is (0.419092,-0.225852,0.256818). When this 8bit YUV value takes a roundtrip, the 8bit RGB value is (209,87,0), the 8bit YUV value is (107,71,193), fp result is (0.418258,-0.225403,0.254858) (which if +0.5*255 is (106.65579,70.022235,192.48624) I don't know why zimg (vapoursynth core.resize) rounds the 8bit value this way, or I'm doing the math wrong, but you get the point, I guess) There's only a small fraction of this kind of values, most of them in "extreme values" like the Blue being 0 in the example, so if the image does not contain such pixels or some special treatment is done to the image, the 8bit YUV to RGB converion can be lossless. You don't need very special "1 color" image to achieve that. 10bit YUV lossless"ness" is much easier to achieve. But if any postprocessing including encoding is done to the image the lossless"ability" will likely be ruined even for 10bit. |
|
12th December 2024, 20:36 | #29 | Link | ||||
Registered User
Join Date: Sep 2007
Posts: 5,591
|
Quote:
The analogy would be like a 3 different YUV pixel "mail delivery addresses" to 3 different RGB pixel "house numbers" 101,102,103 (simplified example, consider just 1 channel for now, not a RGB triplet). Because 8bit YUV precision isn't high enough you end up getting something like RGB 101,101,103 - which is one of the reasons you get 8bit "banding " - multiple YUV values can map to the same RGB number. From that RGB 101,101,103 , there is no way you can go back to 3 different original YUV numbers using standard methods from 2 duplicate, 1 unique RGB pixels (maybe using "AI" or guessing) Quote:
Quote:
The fact is 99.99% of of type "regular" YUV sources for a YUV starting point will not be lossless for 8bit YUV to 8bit RGB conversion , and have many pixel values that become "lossy", changing from the original values Because in real life , many more "problematic" YUV values occur naturally : - chroma resampling . Chroma resampling to generate the YUV 4:2:0 "source" can produce millions of values that were "good" YUV values that will become "bad" YUV values and lossy in the round trip when tested against the YUV 4:2:0 source. (I'm not referring to duplicating and discarding using nearest neighbor for the RGB step, I'm referring to generating different YUV values due to resampling a pre non subsampled source to the 420 source by resampling say, a 4x4 grid of pixels using bicubic ). Most "sources" will be 4:2:0, and that is hardly considered "special treatment" - lossy compression (most sources you start with are going to have lossy compression), multiple generations. Even if a value is slightly off due to lossy compression in a channel from "good" YUV triplet from a prior lossless conversion, that can cause next RGB conversion step to go out of gamut , which makes it irreversible Millions of "bad" YUV values occur within "legal range" Y 16-235 CbCr 16-240 that can produce out of gamut RGB and clip (and therefore not reversible, not lossless) . There are fewer that occur in a full range conversion but they still potentially in the number of millions. Quote:
To be clear - 10bit YUV "losslessness" refers to 8bit RGB => 10bit YUV. By definition , all the "illegal" , out of gamut such as negative RGB values are already "culled" from 8bit RGB source. ie. all 8bit RGB 16777216 values can be properly and precisely coded for with 10bit YUV. It should be always lossless for all 8bit RGB values (when done properly ) Last edited by poisondeathray; 12th December 2024 at 21:17. |
||||
12th December 2024, 22:36 | #30 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,437
|
Quote:
|
|
13th December 2024, 03:13 | #31 | Link | |
Registered User
Join Date: Sep 2007
Posts: 5,591
|
Quote:
Last edited by poisondeathray; 13th December 2024 at 03:16. |
|
13th December 2024, 20:42 | #32 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,437
|
Quote:
I have long thought that your detailed knowledge and understanding of these issues is second to none on these forums, so I'm humbled to learn that my own curiosity about them helped to inspire your journey down that path. |
|
15th December 2024, 19:02 | #33 | Link |
Broadcast Encoder
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,145
|
I see! I've actually been having this doubt for a very long time! One of the things that always baffled me was that I could have a completely perfect limited tv range source and even insert like
Code:
Limiter(min_luma=16, max_luma=235, min_chroma=16, max_chroma=240) I'm asking 'cause this would finally clarify one of the doubts I've been having for a very, very, very long time. That would also explain why Limiter() is able to always bring luma in the legal range, but not chroma. This would then lead to the question: what do I do in those cases? I mean, when the QC guys occasionally got back to me with a FAIL due to out of range chroma (they never got back to me with a failure in luma given that Limiter always worked), the only thing I could do was something like Tweak(sat=0.80, dither=true) to reduce the saturation of the colors and make the program pass, but this always seemed like a drastic approach. |
15th December 2024, 20:16 | #34 | Link | |
Registered User
Join Date: Dec 2013
Location: Berlin, Germany
Posts: 408
|
Quote:
As it is quite possible to generate YUV values that point outside the valid RGB space this should be fixed in RGB space. I am not going to go into details here but when you have a YUV that has this problem you can fix it by converting to RGB, clip the RGB values to the valid range, and convert back to YUV again. If you want to be pedantic clip YUV to legal before converting to RGB. This way YUV and RGB are both in legal range. I know you sometimes like to do things with ffmpeg, a possible filter chain would maybe look like this: "format=<somergbformat>,lutrgb=r=clipval:g=clipval:b=clipval,format=<someyuvformat>. Note that ffmpeg needs the correct colorspace information for the YUV->RGB->YUV conversation to work - one might need to specify "colorspace" as well at the start of the filter chain as well.
__________________
My github... |
|
15th December 2024, 22:42 | #35 | Link |
Registered User
Join Date: Sep 2007
Posts: 5,591
|
Yes, clipping in RGB is usually what is done, and the simplest solution
"Auto" QC software for EBU r103 compliance has a RGB gamut check portion - and usually there is a 1% allowed margin of error Important to note that SDI full range Y,RGB is being used (Y and limited range RGB 16-235 reference black to white, but 1-254 max for 8bit; for 10bit Y and limited range RGB 64-940, 4-1019 max) . Translation for avisynth/vapoursynth/ffmpeg - it would be limited range RGB conversion, clipped to [1,254] (or [4,1019] for 10bit) for the "base" RGB conversion. Usually broadcast signals are lowpassed and go through a band filter - so many of the "bad, but legal range YUV" values that were generated are already reduced before QC check. As an alternative or complimentary route you can apply a convolution filter if you wanted to - EBU have some recommended values for filter coefficients There are various "legalizer" software and plugins - and they usually have various options besides clipping like reduce saturation, reduce luminance. "Auto" legalizing/clipping can sometimes look bad with patchy artifacts - compared to a colorist doing it - but "auto" software is way faster and cheaper. In general, the less you clip, the "less bad" the potential artifacts - so it would be useful to be guided by a visualizer to get away with the least amount of "damage". For freeware, _Al_ wrote a vapoursynth script where you can toggle a visualizer node to colorize the problem areas red, within a configurable range and it reports a percentage of out of range (also configurable). So you can adjust clipping or whatever filter on the fly and get feedback. You'd have to PM him for the most recent version, I don't think he put it on github yet. Another feature improvement would be to write accumulated/aggregate stats for analyzing a whole video, the version I tested in the past did it per frame The preferred min/max range for EBU is [5,246] - clipping to those values in SDI full range RGB will get rid of most of problems for most sources automatically, and you can clip farther if you needed to. Converting back to YUV and subsampling can bring back new "legal range bad YUV values" , but rarely >1% |
16th December 2024, 14:19 | #36 | Link | |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,437
|
Quote:
Take a look a the thread I referred to above (and even run the script to see for yourself). It shows that most of the YUV space is in fact unused (ie does not correspond to a valid RGB color), especially for low and high values of Y, and that for no value of Y is the entire range of U or V valid. For Y=0 or Y=255 of course, it shrinks to a single point (black or white) with U=V=128. Ah, you might say, but if we start with the YUV values limited to 'TV range'... ? That cuts out the extreme values, but still leave a large part of the YUV space that corresponds to out-of-range RGB. |
|
17th December 2024, 11:10 | #37 | Link |
Avisynth language lover
Join Date: Dec 2007
Location: Spain
Posts: 3,437
|
@FranceBB, with your broadcasting background, you might find interesting this old BBC paper on 'Limiting of YUV digital video signals' (also cited in my 2010 thread).
http://downloads.bbc.co.uk/rd/pubs/reports/1987-22.pdf |
17th December 2024, 12:45 | #38 | Link |
Big Bit Savings Now !
Join Date: Feb 2007
Location: close to the wall
Posts: 1,796
|
From that BBC paper page8/22 Fig.2 shows beautifully how hairy it gets if one attempts to manipulate YUV.
And many thanks, Gavino, for making that classic valid range script back then. As I started to correct analog hue shifts in YUV it helped me understanding those intricacies. It became a must-see-before-work.
__________________
"To bypass shortcuts and find suffering...is called QUALity" (Die toten Augen von Friedrichshain) "Data reduction ? Yep, Sir. We're that issue working on. Synce invntoin uf lingöage..." Last edited by Emulgator; 17th December 2024 at 13:39. |
21st December 2024, 13:39 | #39 | Link | |
Registered User
Join Date: May 2006
Posts: 4,040
|
Quote:
This classic has been an eye-opener to me, together with the "RGB block in the YUV cube" discussions in this and the Videohelp forum. Many thanks Gavino ! I am still using the extended version (including 709 and real sources) to visualize "hot pixels" in my VHS sources - eventually trying to legalize the same. Edit: FWIW here an example how I use it https://mega.nz/file/eIEBSKrK#_41-za...pb1eqAVTn-ATX0 Last edited by Sharc; 21st December 2024 at 14:14. Reason: Link added |
|
21st December 2024, 20:16 | #40 | Link |
Registered User
Join Date: Sep 2007
Posts: 5,591
|
For AVS+, you could probably modify gavino's original "ShowBadRGB" function for the "broadcast" case .
The main differences for the "broadcast" r103 gamut check 1) "limited range YUV" to "limited range RGB" equations are used (not the same thing as "PC" matrix) - possible with avsresize or fmtc directly, not with internal "Convert" functions directly (but you could apply additional offset to achieve similar result) . There was a "studio RGB" function by Trevlac way back, but otherwise limited range RGB was not really used in avisynth back then 2) for 8bit data , 0 and 255 are reserved code values and placed in the "illegal gamut" definition for broadcast But in the non broadcast delivery, "computer RGB" case, 0,255 are "legal" and actually important required values e.g.masks, compositing, keying/alpha channel. 0,255 are also important for some types of intermediate calculations, some types of filters for accuracy. Pure rounding errors for 8bit YUV444<=>RGB only account for +/-3 delta code values. But chroma subsampling can push min/max deltas much larger , over 20 code values (!) with typical resamplers such as bicubic when using commonly used b,c values. A group of pixels with YUV values that would have passed as YUV444P8 can become "legal range YUV, but out of gamut" when they are in proximity to certain other pixels when chroma resampling is applied. It also depends on the kernel used. eg. bicubic/cubic resamplers use a 4x4 grid. "bilinear" uses 2x2. "Sharper" kernels, "negative lobe" resamplers - tend to generate more problematic YUV combinations with larger magnitude over/undershoots - they can create larger max, lower min values. People tend to "turn their nose up" at bilinear for chroma subsampling, but bilinear is safer for broadcast scenario . So you can have something legal in the RGB legalization/check step, but once it's converted back to YUV422P8 or YUV420P8, you can generate new illegal values, again - hence that 1% leeway is important, otherwise there would be a lot of back and forth vicious cycle checking |
Tags |
colorspace, colorspace conversion, ffmpeg |
Thread Tools | Search this Thread |
Display Modes | |
|
|