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 > Announcements and Chat > General Discussion

Reply
 
Thread Tools Search this Thread Display Modes
Old 21st December 2024, 21:15   #41  |  Link
Z2697
Registered User
 
Join Date: Aug 2024
Posts: 319
May I ask why it's so important to keep legal range? Are the industrial equipments that picky?
Z2697 is offline   Reply With Quote
Old 21st December 2024, 23:15   #42  |  Link
rwill
Registered User
 
Join Date: Dec 2013
Location: Berlin, Germany
Posts: 408
Quote:
Originally Posted by Z2697 View Post
May I ask why it's so important to keep legal range? Are the industrial equipments that picky?
It is a requirement of the broadcast people. It just has to be that way. I guess the 'why' has been lost in time...
__________________
My github...
rwill is offline   Reply With Quote
Old 21st December 2024, 23:19   #43  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 4,040
Quote:
Originally Posted by Z2697 View Post
May I ask why it's so important to keep legal range? Are the industrial equipments that picky?
Simply speaking, illegal YUV will produce upon conversion out-of-gamut RGB (depending on matrix), means for example:
- color distortions because out-of-gamut RGB components are typically just clipped at 255 or 0 (8 bit realm).
- loss of details, loss of fine structures due to the clipping
See my uploaded example. While the YUV components are within allowed range each (see the histogram), the bad red pixels are "red" represented by clipped red component 255 but fine red details are totally lost in that area. Same for the dark areas with bad pixels where the blue component is clipped at 0.

On the other hand legalizing can be a pita as the fully legalized picture may look desaturated or "milky". For home use one may prefer to live with a compromise.

Last edited by Sharc; 22nd December 2024 at 00:15.
Sharc is online now   Reply With Quote
Old 22nd December 2024, 02:21   #44  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,145
Quote:
Originally Posted by rwill View Post
I guess the 'why' has been lost in time...
I'm unfortunately way too young and this story should be narrated by those who were there, but I'm gonna try to put things together and narrate the tale of those people I met before they retired.

Quote:
Originally Posted by Z2697 View Post
May I ask why it's so important to keep legal range? Are the industrial equipments that picky?
It's not about industrial equipments being "picky" but rather the fact that you can't physically carry a full pc range signal via SDI cables. Actually, to be entirely true, you couldn't carry full pc range signals via SDI cables back when the first revision was introduced. Those cables carry an uncompressed A/V stream along with some metadata to keep the signal synced like the timecode, the TTX (Teletext subtitles) etc. Unfortunately, because of this, some bits are reserved for metadata, which means that you can't possibly carry a Full PC Range signal as you don't have quite as many bits available.

Some of you may be familiar with VideoTek() the function I made (alongside StainlessS, magiblot and algie) to have a Tektronix-like waveform monitor back in 2018.

Although I've introduced other scales (especially for HDR) like nits, by default if you don't specify anything, VideoTek() defaults to "volts" as a scale rather than bits or nits, just like in the actual Tektronix waveform monitor. In an SDR Limited TV Range signal you have the signal going from 16 to 235 and this corresponds to 0.0V-0.7V or 700 mV. Now, an SDI cable can carry signals up to 0.8V or 800 mV however due to the fact that you need to have some parts reserved and that you can't use the whole available range for video (also think about audio, teletext subtitles etc, not just the timecode and other syncing stuff), you can't truly carry a full pc range signal.



Now, let's forget about millivolt and let's focus on bandwidth, which is a good way to measure what a cable can carry. After all, we use that for all other kind of cables like USB, Thunderbolt etc, so we can use the same method for SDI cables as well. SDI cables went through quite a bit of a journey and, just like other cables that have been around for a very long time, there are several different revisions:

1) 270 Mbit/s
2) 540 Mbit/s
3) 1.4 Gbit/s
4) 2.9 Gbit/s
5) 6 Gbit/s
6) 12 Gbit/s
7) 24 Gbit/s
8) 48 Gbit/s

Those revision are more commonly named by the bandwidth they carry, for instance revision 4 is also called 3G-SDI as it carries almost 3 Gbit/s, revision 5 is called 6G-SDI as it carries 6 Gbit/s and so on for all the other revisions, namely 12G-SDI, 24G-SDI, 48G-SDI. The most skilled of you would have realized by now that 48G-SDI has the same bandwidth as the latest HDMI revision, namely HDMI 2.1b, as they can both carry 48 Gbit/s, although nobody calls the latter 48G-HDMI which would have made much more sense than the "2.1b" revision number they went for (I'm looking at you, HDMI consortium!). Anyway, while 48 Gbit/s may sound a lot, when you consider the fact that the signals are uncompressed (both video and audio) and that you also need additional bandwidth for syncing purposes, they aren't really much at all. Anyway, while the initial SDI revision allowed for enough bandwidth to carry only SD streams, as we moved on with revisions we were able to carry larger resolution, larger bit depth and more fps, but we're still limited.

The first revision was introduced in 1989, I wasn't even born, let alone being in the broadcast world (I started working at Sky on January 6th, 2016), but to get a sense of the limitation our ancestors faced, let's take 48G-SDI, the latest revision, as an example.

If we were to try to display an 8K signal - which is what revision 8, 48G-SDI, is for - we would have a bit of a problem.

To perform the calculations, we can use the following formula:

(Width * Height) * (Bit Depth) * (Planes) * (frames per second) = video bitrate

Calculation 1
7680x4320 4:4:4 Full PC Range 10bit 60fps

(7680 * 4320) * (10) * (3) * (60) = 59,719,680,000 bits per second

In other words, 59.7 Gbit/s, so we're out of luck.
What if we try Limited TV Range, though?

Calculation 2
7680x4320 4:2:2 Limited TV Range 10bit 60fps

(7680 * 4320) * (10) * (2) * (60) = 39,813,120,000 bits per second

In other words, 39.8 Gbit/s.

Here the 2 for the planes comes from the fact that in 4:2:2 we have 1 luma channel at full resolution (Y) and 2 subsampled chroma channels (Cb and Cr) by a factor of two, so it would be:

1 + 2/2 = 1 + 1 = 2.

Anyway, we've finally got to a feasible bitrate!
Do we wanna include 8 stereo 2ch PCM 24bit 48000Hz audio tracks in the mix as well carrying the various languages (i.e Dub) for the movie/tv series? No problem, that would be:

(Channels) * (Sample Rate) * (Bit Depth)

(16) * (48000) * (24) = 18,432,000 bits per second

so, just 18.4 Mbit/s or 0.0184 Gbit/s which, when added to our 39.8 Gbit/s video, makes it still insignificant and way below the 48 Gbit/s threshold. Wanna add subtitles? No problem, that would be around 300 kbit/s (294 kbit/s if we wanna be picky). For 8 subtitles, one per audio language, we would have 8 * 300 = 2400 kbit/s or 0.0024 Gbit/s. That still leaves us with plenty of room for the timecode and other syncing stuff that can be carried through.


Obviously one could say "oh, well, but if we can carry a 7680x4320 4:2:2 Limited TV Range 10bit 60fps with 8 Stereo PCM 48000Hz 24bit tracks and 8 subtitles on modern cables, then we could totally use those modern ones to carry Full PC Range FULL HD 10bit 4:4:4 60fps video instead as that would just be 3.7 Gbit/s!".

The answer is... yes, yes we could, given that the calculation for

1920x1080 4:4:4 Full PC Range 10bit 60fps

would be

(1920 * 1080) * (10) * (3) * (60) = 3,732,480,000 bits per second

or 3.7 Gbit/s just for the video (excluding audio), but that's not the point. You see, back when FULL HD was a thing, revision 4 was in place, so the overall bandwidth was 2.9 Gbit/s (3G-SDI, basically 3 Gbit/s), so we couldn't. This is to say that just like engineers were limited by the things available at their time back in 1989, 35 years later we're still limited by what we have available in our time. Even now, 48G-SDI is really targeted to be the standard for 8K not 4K, so before we could even dare to attempt to move to something like 4:4:4 Full PC Range, the "next big thing / next hot thing" comes along and we're limited again. This is why, realistically, I don't see 4:4:4 Full PC Range ever becoming a standard, unfortunately. It's just not possible.

Last edited by FranceBB; 22nd December 2024 at 19:02.
FranceBB is online now   Reply With Quote
Old 22nd December 2024, 09:43   #45  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 4,040
In analog TV broadcast times there were no bits, no bitdepth, no bitrate, no x:y:z subsampling, but there were spectral bandwidth constraints, backward compatibility issues with existing B&W TV systems, and amplitude constraints to prevent overmodulation (clipping) of analog transmitters. That's when and why "YUV" was born as a technical solution to cope with these constraints. YUV (or component Y, Pb, Pr) is basically an analog concept which later became Y,Cb,Cr in the course of digitization.
Secondly, with respect to analog signal levels and signal excursions ("swing"), analog gear required some headroom/footroom to accommodate signal over- and undershoots due to filtering (ringing, Gibb's phenomenon) and analog circuitry imperfections to prevent clipping.
Sharc is online now   Reply With Quote
Old 22nd December 2024, 16:12   #46  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 4,040
Quote:
Originally Posted by poisondeathray View Post
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) ....
You mean as amended here:
https://forum.doom9.org/showthread.p...96#post1405496 ?
Or change the equations for "Studio Matrix" ?

Last edited by Sharc; 22nd December 2024 at 17:06.
Sharc is online now   Reply With Quote
Old 22nd December 2024, 17:43   #47  |  Link
Z2697
Registered User
 
Join Date: Aug 2024
Posts: 319
That's a nice reading, thanks!
Is it the cable can't evolve fast enough, or people always want to squeeze more pixels into that poor cable... well, maybe both

The naming after speed is like a dream, in consumer grade cables / ports they probably just want to confuse consumers and profit from information asymmetry.

By the way, somehow the Limited Range signal uses less bandwidth is not making sense to me, I mean, in digital domain, that's still 10 or 8 bits each plane pixel?
Z2697 is offline   Reply With Quote
Old 22nd December 2024, 19:09   #48  |  Link
FranceBB
Broadcast Encoder
 
FranceBB's Avatar
 
Join Date: Nov 2013
Location: Royal Borough of Kensington & Chelsea, UK
Posts: 3,145
Quote:
Originally Posted by Z2697 View Post
Is it the cable can't evolve fast enough, or people always want to squeeze more pixels into that poor cable... well, maybe both
A little bit of both, but mostly the fact that businesses want to jump on the "next big thing" all the time, where the "next big thing" now is 8K. I really wanted the 8K standard to be 12bit, but it looks like we're gonna be constrained to 10bit once again...

Quote:
Originally Posted by Z2697 View Post
The naming after speed is like a dream
I know, right? If only everything could be like this...

Quote:
Originally Posted by Z2697 View Post
By the way, somehow the Limited Range signal uses less bandwidth is not making sense to me, I mean, in digital domain, that's still 10 or 8 bits each plane pixel?
Yes, I should stop writing posts at 1AM, but what my head wanted to try to show was the original motivation, so the fact that you could only carry 800mV and a signal in limited tv range peaked at 700mV (0.7V) so you had enough headroom. In digital when carrying a signal as uncompressed both 8bit and 10bit full pc range and limited tv range would use the same bandwidth in the cable. After all, those cables are now mostly fiber based, they're not 75-ohm coaxial cables any longer, but yeah, back when I wasn't even born (and then for a while afterwards) they were and limiting the signal was a must, which is why we're stuck with it. I wish I could have some other people from that time here, but they all retired. Even algie, whose real name is Livio Aloja, one of the people I mentioned in VideoTek and one of my colleagues, retired in 2021. He had some incredible stories to tell. Unfortunately there's no one from the old generation any longer...

(no, they're not dead, they're just retired and 64+ miles away from where I work)
FranceBB is online now   Reply With Quote
Old 22nd December 2024, 20:42   #49  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,598
Quote:
Originally Posted by Sharc View Post
You mean as amended here:
https://forum.doom9.org/showthread.p...96#post1405496 ?
Or change the equations for "Studio Matrix" ?
The latter;

Those amendments were for Rec709 , PC.709 and they map to full range RGB ; limited range RGB is not included there

It would need an option for the "bad RGB" range for r103, which is different than the "bad RGB" range for other scenarios
poisondeathray is offline   Reply With Quote
Old 22nd December 2024, 20:53   #50  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 4,040
Quote:
Originally Posted by poisondeathray View Post
The latter;

Those amendments were for Rec709 , PC.709 and they map to full range RGB ; limited range RGB is not included there

It would need an option for the "bad RGB" range for r103, which is different than the "bad RGB" range for other scenarios
Ah, mapping to limited range RGB is missing there. Some food for thought. Thanks.

Last edited by Sharc; 22nd December 2024 at 22:01.
Sharc is online now   Reply With Quote
Old 24th December 2024, 09:56   #51  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 4,040
Quote:
Originally Posted by Sharc View Post
Ah, mapping to limited range RGB is missing there. Some food for thought. Thanks.
Hmmm..., if I understand this correctly from
https://avisynthplus.readthedocs.io/...nversions.html
the part "YUV [0,255] <-> RGB [0,255] (0 <= [r,g,b] <= 255, 0 <= y <= 255, 0 < [u,v] < 255)" would apply for adding the missing mapping to limited range RGB in the script?
I know the various matrix conversions but I am not really familiar with this notation.

Last edited by Sharc; 24th December 2024 at 10:02.
Sharc is online now   Reply With Quote
Old 24th December 2024, 16:18   #52  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,598
Quote:
Originally Posted by Sharc View Post
Hmmm..., if I understand this correctly from
https://avisynthplus.readthedocs.io/...nversions.html
the part "YUV [0,255] <-> RGB [0,255] (0 <= [r,g,b] <= 255, 0 <= y <= 255, 0 < [u,v] < 255)" would apply for adding the missing mapping to limited range RGB in the script?
I know the various matrix conversions but I am not really familiar with this notation.

The studio RGB /limited range RGB equations were posted in another thread, I don't have them handy. They are also listed in "video demystified" , I can dig them up later if you want

***But at this point in avs+, I would just replace everything with avsresize - you have control over source/destination ranges , matrix/transfer/primaries, optimized SIMD (waaay faster) - and it does limited range RGB correctly - I verified the results with other programs

"When done correctly " ... Not specifically for the YUV "bad RGB case", but people should be aware that AVS+ internal functions do not perform the RGB to YUV to RGB roundtrip ideally . Matlab / spreadsheet models etc... predict that +2 bits is enough for the YUV step. (ie. 10bit should be enough precision for 8bit RGB to 10bit YUV to 8bit RGB) - but there were unexpected errors in AVS+ internal functions. I investigated this a few years ago, pinterf's reply

Quote:
But Avisynth resizer is not capable to chain bit depth conversion with rgb->yuv conversion so I'd say it'll never give such losslessness.
poisondeathray is offline   Reply With Quote
Old 25th December 2024, 09:53   #53  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 4,040
Quote:
Originally Posted by poisondeathray View Post
The studio RGB /limited range RGB equations were posted in another thread, I don't have them handy. They are also listed in "video demystified" , I can dig them up later if you want
Got it, thanks. So these are the matrices (equations) as defined in ITU-R BT.601-7 and ITU-R BT.709-6 recommendations.

Quote:
***But at this point in avs+, I would just replace everything with avsresize - you have control over source/destination ranges , matrix/transfer/primaries, optimized SIMD (waaay faster) - and it does limited range RGB correctly - I verified the results with other programs.

"When done correctly " ... Not specifically for the YUV "bad RGB case", but people should be aware that AVS+ internal functions do not perform the RGB to YUV to RGB roundtrip ideally . Matlab / spreadsheet models etc... predict that +2 bits is enough for the YUV step. (ie. 10bit should be enough precision for 8bit RGB to 10bit YUV to 8bit RGB) - but there were unexpected errors in AVS+ internal functions. I investigated this a few years ago, pinterf's reply
Thanks for the hints. Will try with avsresize.

Last edited by Sharc; 25th December 2024 at 15:07.
Sharc is online now   Reply With Quote
Old 26th December 2024, 16:35   #54  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,598
Quote:
Originally Posted by Sharc View Post
Got it, thanks. So these are the matrices (equations) as defined in ITU-R BT.601-7 and ITU-R BT.709-6 recommendations.
Yes, derived from the ITU BT.601/709 documents, expressed as equations for the "YUV <=> studio RGB (limited range RGB)" scenario ( and "YUV <=> computer RGB (full range RGB)" scenario)
poisondeathray is offline   Reply With Quote
Old 29th December 2024, 17:53   #55  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 4,040
So here a proposal for showing Bad RGB, based on a roundtrip YUV->RGB->YUV, using avsresize (fast).
Matrix and range can be set. Bad pixels are shown as color in the grey video.
Example for limited range RGB ("studio") scenario.


Code:
######################################################################################
# Analyzes the source video for Out-Of-Gamut RGB by YUV->RGB conversion  
# Requires avs+ and avsresize     
# v0.91          2024-12-30  
######################################################################################


source=<source filter here>


## options 
matrix="601"                 #601 or 709 matrix
YUVrange="limited"           #limited or full, (normally limited)
RGBrange="limited"           #limited for TV (studio) or full for PC
interlaced=false             #true for interlaced, false for progressive sources
histogram_mode="levels"      #levels (for histogram) or classic (for waveform)
color_badRGB=color_cyan      #pixel color for Bad RGB
##

source=source.converttoYV24(interlaced=interlaced) #convert to planar for avsresize
cs1=matrix+":auto:auto:"+YUVrange+"=>rgb:same:same:"+RGBrange
cs2="rgb:auto:auto:"+RGBrange+"=>"+matrix+":same:same:"+YUVrange

return stackhorizontal(source.histogram(histogram_mode).subtitle("source"),
\BadRGB(source,color_badRGB,cs1,cs2,interlaced).subtitle("Bad RGB = color pixels (cyan)"))


## Function based on "HighlightBadRGB" by jagabo@VideoHelp 
## Added % of Bad RGB indication and options for matrix, range and interlaced; using avsresize
function BadRGB(clip vid, int "color",string "cs1",string "cs2",bool "interlaced")
{
  color = default(color, $ff0000)
  cs1=default(cs1,"601:auto:auto:limited=>rgb:same:same:full")
  cs2=default(cs2,"rgb:auto:auto:full=>601:same:same:limited")
  interlaced=default(interlaced,false)
  badcolor = BlankClip(vid, color=color)  
  subtract(vid,vid.z_ConvertFormat(pixel_type="RGBP10",interlaced=interlaced,colorspace_op=cs1,use_props=0)
\.z_ConvertFormat(pixel_type="YV24",interlaced=interlaced,colorspace_op=cs2,use_props=0))
  absY = Overlay(ColorYUV(off_y=-126), Invert().ColorYUV(off_y=-130), mode="add")
  absU = Overlay(UtoY().ColorYUV(off_y=-128), UtoY().Invert().ColorYUV(off_y=-128), mode="add")
  absV = Overlay(VtoY().ColorYUV(off_y=-128), VtoY().Invert().ColorYUV(off_y=-128), mode="add")
  Overlay(absU,absV, mode="add")
  Overlay(last,absY, mode="add")
  mask=ColorYUV(gain_y=65000)
  avg=mask.ScriptClip("Subtitle(String(AverageLuma/255*100),align=9)").crop(width()-90,0,-0,-(height()-20)).addborders(0,0,0,height()-20)
  Overlay(vid.grayscale().coloryuv(cont_y=-0),badcolor,0,0,mask)
  stackhorizontal(last,avg)
}

Last edited by Sharc; 31st December 2024 at 14:15. Reason: added % indication
Sharc is online now   Reply With Quote
Old 30th December 2024, 16:21   #56  |  Link
poisondeathray
Registered User
 
Join Date: Sep 2007
Posts: 5,598
Nice sharc

Some suggestions - consider adding :

- adjustable "bad" RGB range, or a specific r103 broadcast scenario - because of the reserved code values for sync. Any of R,G,B values <=0 or >=255 would be flagged as "out of gamut" for 8bit in a r103 checker .

- user adjustable chroma resampling algorithm. eg. bilinear vs. spline16 etc....

- % of "bad RGB/out of gamut" pixels estimation. Because r103 has a 1% leeway, it 's nice to know where you approximately stand as a %

The way it's done in the vapoursynth calculation is a mask calculation on black BG - where white pixels are "illegal" according to the configured min/max settings. PlanestatsAverage *100 to express as a percentage. I think in avs+, perhaps the AverageLuma runtime function on a Y8/Y10 mask clip, or maybe RT_Stats

eg. ScriptClip sucks, but for a Y8 clip it might look something like
ScriptClip(last, "Subtitle(String(AverageLuma / 255 * 100))")

- perhaps an aggregate /average stats calculation for the total video , not sure how, maybe RT_stats ?
poisondeathray is offline   Reply With Quote
Old 31st December 2024, 14:02   #57  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 4,040
Thank you pdr for your suggestions. I added the % of Bad RGB indication (per frame) to the script in post#55 as per your proposal. Seems to be reasonably accurate.
For the "1% leeway r103 broadcast assessment" one would probably have to revisit the absolute accuracy of the fast algo for the bad RGB discovery. Maybe using synthesized YCbCr sources as reference. Currently it's quite handy for a quick check of my tape captures though even though it might not be perfectly accurate.

Last edited by Sharc; 31st December 2024 at 14:09.
Sharc is online now   Reply With Quote
Old 9th January 2025, 00:01   #58  |  Link
Sharc
Registered User
 
Join Date: May 2006
Posts: 4,040
Quote:
Originally Posted by poisondeathray View Post
Nice sharc

Some suggestions - consider adding :

- adjustable "bad" RGB range, or a specific r103 broadcast scenario - .
- % of "bad RGB/out of gamut" pixels estimation.
Here a new version with a function added for adjustable bad RGB range, also supporting an EBU r103 scenario. Color pixels indicate out-of-gamut RGB for the various scenarios.
Code:
################################################################################
# Analyzes YUV video sources for Out-Of-Gamut RGB 
# Scenarios: PC, TV, EBU r103, or user defined
# Requires avs+ and avsresize     
# v2.0          2025-01-14    
################################################################################

## SOURCE
source=<source_filter_here>
source=source.crop(18,8,-16,-8)   # !! crop any borders to prevent biased statistics !!

## SETTINGS  ##
matrix="601"                      # 601 (=470bg) or 709  source matrix (or any supported by avsresize)
interlaced=true                   # set true for interlaced sources, false for progressive sorces
scenario=1                        # 1=standard PC (limited->full),    2= standard TV (limited->limited),     3=EBU r103 Table 1,    4=custom settings as defined below
histogram_mode=1                  # 1=histogram,   2=waveform on side,    3= waveform on top,   4=vectorscope
reduceby2=false                   # if set true: reduce output size
color_badRGB=color_cyan           # pixel color for Bad RGB

# custom settings for scenario 4:
YUVrange="limited"                # "limited" or "full", (normally limited!)
RGBrange="full"                   # "limited" for TV (studio RGB) or "full"  for PC
thr_high=1023                     # upper threshold for scenario 4 , 0 ..... 1023 10bit scale
thr_low=0                         # lower threshold (10bit scale) for scenario 4 only, <thr_high
PCtoTV=false                      # if set true: shrink full range source to limited range; for source tweaking only
TVtoPC=false                      # if  set true: expand limited range source to full range; for source tweaking only       
##
resample_filter="bilinear"        # "point" or "bilinear" or "bicubic" or "spline16" or "spline36 or "spline64" or "lanczos" 
## 

source=source.converttoYV24(interlaced=interlaced)    #convert to planar for avsresize
source=source.z_ConvertFormat(pixel_type="YUV444P10",interlaced=interlaced,resample_filter=resample_filter)    #convert to 10bits

if (scenario==1) {YUVrange="limited" RGBrange="full" thr_high=1023 thr_low=0   PCtoTV=false TVtoPC=false    text="  out-of-gamut RGB; standard PC"} else {}
if (scenario==2) {YUVrange="limited" RGBrange="limited" thr_high=1023 thr_low=0   PCtoTV=false TVtoPC=false    text="  out-of-gamut RGB; standard TV"} else {}
if (scenario==3) {YUVrange="limited" RGBrange="limited" thr_high=984 thr_low=20   PCtoTV=false TVtoPC=false    text="  out-of-gamut RGB; EBU r103"} else {}
if (scenario>=4) {text=" out-of-gamut RGB; customized"} else {}

if (PCtoTV==true) {source=source.ColorYUV(levels="PC->TV")} else {}
if (TVtoPC==true) {source=source.ColorYUV(levels="TV->PC")} else {}
if(reduceby2==true) {source=source.z_bilinearresize(width(source)/2,max(256,height(source)/2), interlaced=interlaced)} else {}

cs1=matrix+":auto:auto:"+YUVrange+"=>rgb:same:same:"+RGBrange
OOG=ShowBadRGB(source,color_badRGB,cs1,thr_high,thr_low,interlaced,resample_filter)


## LAYOUT
if (histogram_mode==1) {stackhorizontal(source.histogram("levels").subtitle("   source"),
\OOG.subtitle(text))}
else if (histogram_mode==2) {stackhorizontal(source.histogram("classic").subtitle("   source"),
\OOG.subtitle(text))}
else if (histogram_mode==3) {stackhorizontal(source.turnright().histogram().turnleft().subtitle("   source"),
\OOG.subtitle(text).addborders(0,256,0,0))}
else {stackhorizontal(source.histogram("color2").subtitle("   source"),
\OOG.subtitle(text))}



function ShowBadRGB(clip vid, int "color", string "cs1", int "thr_high",int "thr_low",bool "interlaced", string "resample_filter")
{
  cs1=default(cs1,"601:auto:auto:limited=>rgb:same:same:full")
  thr_high=default(thr_high,984) #10bit
  thr_low=default(thr_low,20) #10bit
  badcolor = BlankClip(vid, color=color)
  interlaced=default(interlaced,false)
  resample_filter=default(resample_filter,"bicubic")
  rgb=vid.z_ConvertFormat(pixel_type="RGBP10",interlaced=interlaced,colorspace_op=cs1,resample_filter=resample_filter,use_props=0)
  downshift_high=rgb.RGBadjust(rb=-thr_high+1,gb=-thr_high+1,bb=-thr_high+1)
  amp_high=downshift_high.levels(0,1,1023-thr_high,0,1023) #10bit  
  upshift=rgb.RGBadjust(rb=(1023-thr_low-1),gb=(1023-thr_low-1),bb=(1023-thr_low-1))
  downshift_low=upshift.RGBadjust(rb=-(1023-thr_low-1),gb=-(1023-thr_low-1),bb=-(1023-thr_low-1))
  amp_low=downshift_low.levels(0,1,thr_low,0,1023)  
  overlay(amp_high,amp_low,opacity=0.5,mode="blend")
  mask_high=z_ConvertFormat(pixel_type="YUV444P10",interlaced=interlaced,use_props=0).mt_binarize(upper=false)
  mask_low=invert().z_ConvertFormat(pixel_type="YUV444P10",interlaced=interlaced,use_props=0).mt_binarize(upper=false)
  mask=overlay(mask_high,mask_low,opacity=0.5).colorYUV(gain_y=10000)
  overlay(vid.grayscale(),badcolor,0,0,mask)
  avg=mask.ScriptClip("Subtitle(String(AverageLuma/1024*100),align=9)").crop(width()-90,0,-0,-(height()-20)).addborders(0,0,0,height()-20)
  stackhorizontal(last,avg)
}

Last edited by Sharc; 14th January 2025 at 11:04. Reason: v2.0
Sharc is online now   Reply With Quote
Reply

Tags
colorspace, colorspace conversion, ffmpeg

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 14:19.


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