View Full Version : Bug in Histogram() display?
FlimsyFeet
23rd June 2011, 21:37
Just noticed something weird with Histogram().
Am I right in saying that for both YV12 and YUY2 video that the valid luma range is values from 16-235?
This script gives what I think is the correct output:
blankclip()
converttoyuy2()
histogram()
in that the orange "non-valid" regions are 0-15 and 236-255.
However try this:
blankclip()
converttoyv12()
histogram()
and the mid-rnage line and the right hand side orange region moves over to the left by 1px. (Meaning that valid luma values of 235 now fall in the orange out-of-range region).
Sorry if this seems a bit trivial - am I just being anal here? :o
Edit - Sorry, should have said I'm using 2.5.8.
jmac698
24th June 2011, 18:36
You can see it easier here:
blankclip(height=40)
a=converttoyuy2.histogram
b=converttoyv12.histogram.converttoyuy2
stackvertical(a,b)
Histogram is drawn wrong. The mid-range line (cyan) is drawn as one pixel in b but two pixels in a.
This is how is should be drawn:
640-655 undershoot
656 black
765,766 either side of midpoint (125.5+640)
876-895 overshoot
This is how it actually drawn:
YUY2
640-655 undershoot
656 black
764,765 either side of midpoint*
876-895 overshoot
YV12
640-655 undershoot
656 black
764 midpoint*
875-895 overshoot*
Where the * ones are wrong. It's even not self-consistent. The colorspace the histogram is displayed in reduces color resolution, but a proper graph can still be drawn (you can see the "hidden" color next to the mid-point in u,v).
jmac698
24th June 2011, 19:06
The brightness of the zero line also changes depending on width. Try this but change from width=40 to width=80:
blankclip(height=40,width=40)
a=converttoyuy2.histogram
b=converttoyv12.histogram.converttoyuy2
a
At 40 it's y=151, at 80 it's y=203. The difference is 52. I don't see any pattern to it.
Yellow_
24th June 2011, 19:07
Am I right in saying that for both YV12 and YUY2 video that the valid luma range is values from 16-235?
From my limited experience I suggest it's unhelpful and misleading to think of 'valid / invalid' as it's dependant on what was actually captured / generated and encoded into the source, what processing operations are intended to be done on the source after and what the intended delivery is to be.
For example video captured by certain HD DSLR's is full range 0 - 255 luma, xvYCC / BT1691 / IEC61966-2-4 spec is full range luma 1 - 254, DVD / BluRay / Vimeo / Youtube afaik is 16 - 235.
With regard to the histogram("classic") the brown/yellow areas are levels above and below 16 - 235.
jmac698
24th June 2011, 19:52
I'd have to disagree. If I had to give a simple recommendation to a non-expert, I'd have to say 16-235 is a safe choice. In reality, various playback programs and GPU drivers play it back wrong, which is why projects like MadVR were born.
There was an original reason for this, I'd have to check but in the history of electronics, levels too high caused problems so they were limited. I was curious if levels were ever exceeded in DVD/Bluray/TV and I think I found samples where they were.
FlimsyFeet
24th June 2011, 22:19
The brightness of the zero line also changes depending on width. Try this but change from width=40 to width=80:
blankclip(height=40,width=40)
a=converttoyuy2.histogram
b=converttoyv12.histogram.converttoyuy2
a
At 40 it's y=151, at 80 it's y=203. The difference is 52. I don't see any pattern to it.
I think the reason for this is that the brightness of the pixel in the graph depends on the frequency of pixels in the line that are that luma value. If most of the values are around a particular luma value for example, you get a bright white patch on the chart in that region, and conversely a few isolated luma values are shown as faint grey dots.
IanB
25th June 2011, 23:25
Don't guess, read the code!
YV12 histogram.cpp@1027 if (x<16 || x==124 || x>234) {
q[x] = exptab[min(E167, hist[x])] + 68;
} else {
q[x] = exptab[min(255, hist[x])];
} if (x<16 || x==124 || x>235) {
q[x] = exptab[min(E167, hist[x])] + 68;
} else {
q[x] = exptab[min(255, hist[x])];
}
YUY2 histogram.cpp@1074 } else if (x==124) {
q[x*2+0] = exptab[min(E167, hist[x])] + 68;
q[x*2+1] = 160;
q[x*2+2] = exptab[min(E167, hist[x+1])] + 68;
q[x*2+3] = 16;
} else { } else if (x==124) {
q[x*2+0] = exptab[min(E167, hist[x])] + 68;
q[x*2+1] = 160;
q[x*2+2] = exptab[min(255, hist[x+1])];
q[x*2+3] = 16;
} else {
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.