purple instead of back

8 views
Skip to first unread message

Carl Karsten

unread,
Jun 18, 2019, 12:15:43 AM6/18/19
to hdmi...@googlegroups.com
if there is no input signal, we get black.
I would like there to be something else, like purple.

is this the bit that needs changing?

framebuffer[i] = 0x80108010; /* black in YCbCr 4:2:2*/
https://github.com/timvideos/HDMI2USB-litex-firmware/blob/master/firmware/hdmi_in0.c#L170

--
Carl K

Tim 'mithro' Ansell

unread,
Jun 18, 2019, 3:39:47 AM6/18/19
to hdmi...@googlegroups.com
That seems pretty likely. Give it a go and see what happens?

Tim 'mithro' Ansell

--
You received this message because you are subscribed to the Google Groups "hdmi2usb - A HDMI capture solution" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hdmi2usb+u...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/hdmi2usb/CADmzSSjZ0t4vDaz5mc%2BnejY3Zdz_cQwA8t4gsX22Q%2Bjii0Hpnw%40mail.gmail.com.

Carl Karsten

unread,
Jun 18, 2019, 7:13:10 PM6/18/19
to hdmi...@googlegroups.com
I'm stuck on what constant to use.

framebuffer[i] = 0x80108010; /* black in YCbCr 4:2:2*/
Y: 16.000, Cb: 128.000, Cr: 128.000
hex: 10 80 80

somehow that is 80 10 80 10

I'm trying to do this:
YCbCr (84, 130, 213) = debian red https://encycolorpedia.com/d70a53
hex: 54 82 d5

framebuffer[i] = 0x ???
> To view this discussion on the web, visit https://groups.google.com/d/msgid/hdmi2usb/CAHLUNMyMhMUhndSUP2M8FhL4oxpnLRQwfaJWndVOaLbx8t%3DzPw%40mail.gmail.com.



--
Carl K

Ewen McNeill

unread,
Jun 18, 2019, 9:44:54 PM6/18/19
to hdmi...@googlegroups.com
On 2019-06-19 11:12, Carl Karsten wrote:
> I'm stuck on what constant to use.
> framebuffer[i] = 0x80108010; /* black in YCbCr 4:2:2*/

Ah, magic constants.

That particular magic constant matches the YCBCR422_BLACK define in:

https://github.com/timvideos/HDMI2USB-litex-firmware/blob/eaab51fd65f2c7276c32e6973ca2c86beb188fb0/firmware/pattern.h#L6-L14

so at least the constant is consistent with the comment....

> I'm trying to do this:
> YCbCr (84, 130, 213) = debian red https://encycolorpedia.com/d70a53
> hex: 54 82 d5

Debian red isn't exactly purple :-)

The pattern.h magic values (above) refer to:

https://github.com/timvideos/HDMI2USB-litex-firmware/blob/master/firmware/pattern.py

as how the values were calculated, and in particular:

https://github.com/timvideos/HDMI2USB-litex-firmware/blob/eaab51fd65f2c7276c32e6973ca2c86beb188fb0/firmware/pattern.py#L1-L12

seems to be the RGB -> Y Cb Cr -> packed Y Cb Cr calculations.

Hacking that script to put in the Debian Red RGB values, and some extra
print statements gives:

-=- cut here -=-
ewen@ashram:~$ python3 /tmp/pattern.py
215 10 83 RGB is 79 129 224 Y Cb Cr is 814fe04f
ewen@ashram:~$
-=- cut here -=-

So in theory something like:

framebuffer[i] = 0x814fe04f; // Debian Red

will get fairly close.

It looks like it's floor()ing the values in the RGB -> Y Cb Cr
conversion, rather than round()ing them, and assigning less to the Y
value than the online conversion, so you might want to finesse that a
bit more if the *exact* red matters to you as the colour model used
seems lightly different. But I suspect "colour temperature of the
projector" and "colour temperature of the room lighting" will probably
make more perceived difference.... :-)

From a glance at the code it looks like the pattern is:

Cb Y Cr Y

(in big endian format). Which means:

framebuffer[i] = 0x8254d554;

I think corresponds to the Y Cb Cr values you came up with.

Ewen

PS: I'm dubious about the accuracy of just repeating the 8-bit Y
component twice to give it 16 bits, as that seems like something that's
only really accurate at the extremes (Y = 0 / Y = 255). But off the top
of my head it's probably "close enough" to be recognisably like what you
were going for anyway.

Carl Karsten

unread,
Jun 19, 2019, 12:42:04 AM6/19/19
to hdmi...@googlegroups.com
why do my hacks get different numbers that yours?
and what to you get for Ubuntu Orange?

221 72 20
110 76 206
ubuntu orange: 4c6ece6e
ubuntu orange: 536fc56f
debian red: 8154d454



def rgb2ycbcr(r, g, b):
y = int(0.299*r + 0.587*g + 0.114*b)
cb = int(-0.1687*r - 0.3313*g + 0.5*b + 128)
cr = int(0.5*r - 0.4187*g - 0.0813*b + 128)
return y, cb, cr

def ycbcr_pack(y, cb, cr):
value = y
value |= cr << 8
value |= y << 16
value |= cb << 24
return value

"""
color_bars_rgb = [
[255, 255, 255],
[255, 255, 0],
[0, 255, 255],
[0, 255, 0],
[255, 0, 255],
[255, 0, 0],
[0, 0, 255],
[0, 0, 0],
]

color_bars_ycbcr = []
for color_bar_rgb in color_bars_rgb:
r, g, b = color_bar_rgb
y, cb, cr = rgb2ycbcr(r, g, b)
color_bars_ycbcr.append([y, cb, cr])

for color_bar_ycbcr in color_bars_ycbcr:
value = ycbcr_pack(*color_bar_ycbcr)
print("%08x" %value)
"""

r,g,b = (int(h,16) for h in ['dd','48','14'])
print(r,g,b)

y, cb, cr = rgb2ycbcr(r, g, b)
print(y, cb, cr)

value = ycbcr_pack(y, cb, cr)
print("ubuntu orange: %08x" %value)

# https://encycolorpedia.com/dd4814
# Y: 111.045, Cb: 83.120, Cr: 197.103
y, cb, cr = 111, 83, 197

value = ycbcr_pack(y, cb, cr)
print("ubuntu orange: %08x" %value)

# https://encycolorpedia.com/d70a53
# Y: 84.429, Cb: 129.707, Cr: 212.812
y, cb, cr = 84, 129, 212
value = ycbcr_pack(y, cb, cr)
print(" debian red: %08x" %value)
> --
> You received this message because you are subscribed to the Google Groups "hdmi2usb - A HDMI capture solution" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to hdmi2usb+u...@googlegroups.com.
> To view this discussion on the web, visit https://groups.google.com/d/msgid/hdmi2usb/7acc66c4-34ee-cd6a-fea3-03da40f62bf6%40mcneill.gen.nz.



--
Carl K

Ewen McNeill

unread,
Jun 19, 2019, 1:32:54 AM6/19/19
to hdmi...@googlegroups.com
On 2019-06-19 16:41, Carl Karsten wrote:
> why do my hacks get different numbers that yours?
> and what to you get for Ubuntu Orange?

As far as I can tell you get identical values if you convert from RGB
using the script, and then pack the values. But different values if you
start with your own Y Cb Cr values and just pack those values.

That says to me the two R G B to Y Cb Cr conversions are using different
colour models.

Starting with the R G B values you gave, I get:

-=- cut here -=-
ewen@ashram:~$ python /tmp/pattern.py
221 72 20 RGB is 110 76 206 Y Cb Cr is 4c6ece6e
ewen@ashram:~$
-=- cut here -=-

which exactly matches your first results. I'm sure if I were just to
pack your Y Cb Cr values I'd get the same results as your second answer.

As I noted in my previous message the colour model used for RGB to Y Cb
Cr conversion in:

https://github.com/timvideos/HDMI2USB-litex-firmware/blob/eaab51fd65f2c7276c32e6973ca2c86beb188fb0/firmware/pattern.py#L1-L12

is apparently *different* from the colour model you're using for RGB to
Y Cb Cr (eg https://encycolorpedia.com/dd4814).

Y Cb Cr system is a *family* of colour models (depending on the primary
reference colours chosen, and the ratios used):

https://en.wikipedia.org/wiki/YCbCr

The HDMI2USB pattern.py script is... under commented, so I'm guessing
which precise colour model it is trying to implement (there are several
of them depending on the precise choice of reference R / G / B used, and
the ratios used for calculating luma, ie Y). But it seems like, eg, the
colour model used for your conversion / https://encycolorpedia.com/
conversion is a different one (also... under documented).

Eyeballing it, it looks like pattern.py implements a close approximation
to ITU-R BT.601 (aka CCIR 601) which is a SD digital component video
television colour model:

https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.601_conversion

But, eg, the ITU-R BT.709 colour model (HDTV):

https://en.wikipedia.org/wiki/YCbCr#ITU-R_BT.709_conversion

is different ratios *and* different reference R / G / B, resulting in
different values. (Off the top of my head I think BT.709 was intended
to standardise across the world the reference colours used for the
model, whereas ISTR that BT.601 used different reference colours in NTSC
/ PAL / SECAM countries...)

If you want *precisely* a specific reference colour (eg, for client sign
off of "this is *exactly* Debian Red"), you'll want known colour
balanced (eg, precise Kelvin colour temperature) lighting in the room,
allowed to warm up and stablise (and all other light sources
eliminated), a printed guaranteed stable reference colour swatch to
compare with (eg, Pantone), and even then you'll probably have to tweak
it, eg per projector, display, screen, etc you're displaying on, and
perhaps per day. You'll probably also And possibly use need a colour
meter to measure the deviation.

If "yeah, that looks about right" is good enough, pick whichever values
of Y Cb Cr make you happiest :-)

At least now you know how to turn the Y Cb Cr values you choose into the
packed values that HDMI2USB's firmware / gateware expects.

Ewen

PS: Like most things, colour is as complicated as you want to make it!

PPS: Most television standards have a reference black / reference white,
which are actually greys, because of complicated television transmission
standards reasons. I suspect both the BT.601 and BT.709 colour models
are also taking that into account....

Tim 'mithro' Ansell

unread,
Jun 19, 2019, 12:57:08 PM6/19/19
to hdmi...@googlegroups.com
You might want to look at https://github.com/enjoy-digital/litevideo/tree/master/litevideo/csc (csc == Color Space Conversion).

Be careful with the YUV you need pixels pairs rather than individual pixels.



--
You received this message because you are subscribed to the Google Groups "hdmi2usb - A HDMI capture solution" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hdmi2usb+u...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages