Author Topic: what is the Y1CbY2Cr memory arrangement in the wii all about?  (Read 3956 times)

0 Members and 1 Guest are viewing this topic.

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1667
  • Karma: 133
    • View Profile
ive had a little play about with coding for my wii today and on the 3d side things are going well.

but then i went to have a mess around with the frame buffer and ive run into Y1CbY2Cr which packs two rgb values into a single 32bit integer now i can understand that...for systems with low memory , but i was wondering if someone could tell me how the data gets packed into the integer i mean i have an example that does it like so.
Code: [Select]
/****************************************************************************
* CvtRGB
*
* This function simply returns two RGB pixels as one Y1CbY2Cr.
*****************************************************************************/
u32
CvtRGB (u8 r1, u8 g1, u8 b1, u8 r2, u8 g2, u8 b2)
{
  int y1, cb1, cr1, y2, cb2, cr2, cb, cr;
 
  y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000;
  cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000;
  cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000;
 
  y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000;
  cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000;
  cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000;
 
  cb = (cb1 + cb2) >> 1;
  cr = (cr1 + cr2) >> 1;
 
  return (y1 << 24) | (cb << 16) | (y2 << 8) | cr;
}

but i dont really get that at all.

i take it that y is green cb blue and cr red?

and won't it be very slow working under this format especialy for finding/plotting single pixels.
« Last Edit: October 25, 2008 by ninogenio »
Challenge Trophies Won:

Offline stormbringer

  • Time moves by fast, no second chance
  • Amiga 1200
  • ****
  • Posts: 453
  • Karma: 73
    • View Profile
    • www.retro-remakes.net
YCbCr is a colorspace used for television.

analog television signals were initially black & white only (or grayscale if you prefer). When color television appeared, there was a need to encode color signals. However the new signals should not interfere with B&W televisions and people owning old TV sets should get the signal too.

As a consequence, the main B&W signal was called the carrier signal and given the letter Y (standard letter used for luminance or B&W signal). The color was encoded as two sub-signals that modulate the carrier signal. Granted some sync values (I skip the details here), the color signals were decoded in the new TV sets (those that were capable of color).

Because of signal badwidth reasons, the color signals were sub-sampled in order to fit in the available bandwidth then. The new colo signals are generally called Cb & Cr for component blue and component red.

They are basically color differences from the luminance signal, i.e. Y

Now of course, color is defined better using a colorspace that is well adapted to electronic components that generate coloured light. Usually these components work with RGB colorspace.

The conversion from RGB to YCbCr involves a transformation to luminance first (main signal, carrier signal).

The classic transfromation for PAL & NTSC television signals is

Y = 0.299 * red + 0.587 * green + 0.114 * blue

it's basically an averaged sum of the RGB components. Since the human eye is more sensitive to the green color, green enters up to 60% in the play, red comes next with almost 30% and finally blue (the color the human eye is the less sensitive to) for about 10%.

The Cb value is simply Y-Blue and the Cr value is simply Y-Red

Now about the subsampling... this really depends on the hardware your work for.

in your case it seems that you have 2 Y samples and 1 Cb sample and 1 Cr sample. So your signal would be 2:1:1

This means that you may have to subsample your RGB values and split the result across more than 1 pixel. I have no information about the layout of the WII framebuffer, but I suggest that you have a look here:

http://www.fourcc.org/

You may find the right layout for you.

I hope this helps a bit..

let me know
We once had a passion
It all seemed so right
So young and so eager
No end in sight
But now we are prisoners
In our own hearts
Nothing seems real
It's all torn apart

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1667
  • Karma: 133
    • View Profile
thank you very much stormbringer k+ :goodpost:,

that clears a lot up for me. i dont fully know the vram on the wii yet but from what i gather the wii upscales the Y1CrY2Cb buffer as it treats each 32int as two pixels. so you only need to flush a buffer of 320*480*4.

i could be wrong here though, i will have to experiment to find out.

cheers.
Challenge Trophies Won:

Offline stormbringer

  • Time moves by fast, no second chance
  • Amiga 1200
  • ****
  • Posts: 453
  • Karma: 73
    • View Profile
    • www.retro-remakes.net
you are welcome mate!

from what I understand, your Y1CbY2Cr layout seems to be like this

[Y1][Cb][Y2][Cr]

that means that you have a Cb value every 2 pixels on the horizontal axis and a Cr value every other 2 pixels on the horizontal axis. That's clearly a 2:1:1 packing

Converting a RGB picture to this layout will involve 2 steps

1) convert your RGB buffer to YCbCr buffer 8bits
2) from your YCbCr buffer , take all the Y values and pack them in the appropiate manner in your 32 bits. Then average your Cb values for every 2 pixels and store the resulting Cb value. Do the same for the Cr values.

This should work..

let me know how it goes.

Before you get headaches with packing the Y1CbY2Cr values, try to get a grayscale image in you wii framebuffer. For this, just set the Cb and Cr values to zero and pack your Y1 and Y2 values in an appropriate manner.
We once had a passion
It all seemed so right
So young and so eager
No end in sight
But now we are prisoners
In our own hearts
Nothing seems real
It's all torn apart

Offline stormbringer

  • Time moves by fast, no second chance
  • Amiga 1200
  • ****
  • Posts: 453
  • Karma: 73
    • View Profile
    • www.retro-remakes.net
to be more specific:

if you have the following pair of pixels

[R1][G1][B1][R2][G2][B2]

convert them to YCbCr to obtain

[Y1][Cb1][Cr1][Y2][Cb2][Cr2]

then store in your final buffer

[Y1] [(Cb1+Cb2)/2] [Y2] [(Cr1+Cr2)/2]

I hope this will work fine
We once had a passion
It all seemed so right
So young and so eager
No end in sight
But now we are prisoners
In our own hearts
Nothing seems real
It's all torn apart

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1667
  • Karma: 133
    • View Profile
yeah that works! i just tryed it out,

with cr and cb set to 0 i get a greyscale image y1 being the even pixel and y2 being odd then averaging cb gives y1 the final color and cr gives y2 the final color.

thanks very much mate that would have taken me quite a while to figure out without your help!
Challenge Trophies Won:

Offline stormbringer

  • Time moves by fast, no second chance
  • Amiga 1200
  • ****
  • Posts: 453
  • Karma: 73
    • View Profile
    • www.retro-remakes.net
glad to know it works fine!

I can't understand why the framebuffer is in YCbCr though.... is this a special mode? It would have been so much easier to have a little prgram running on a small FPGA to convert RGB to YCbCr in the box directly.... I guess Nintendo made an unusual choice again (as always)

Anyway... there are a few tricks you can play with in this colorspace though...

some quick color correction tricks for you frambuffer (to be applied to your YCbCr values before you pack into Y1CbY2Cr:

1) Lift/Gamma/Gain control (classic TV set bightness/contrast)

Y=Lift + (Y^Gamma)*Gain

2) saturation control

Cb = Cb * saturation
Cr = Cr * saturation

3) hue control

consider your <Cb;Cr> pair as a 2d vector. apply a simple 2D rotation to this vector to change the hue

NOTE: you can work in the final buffer as well (although you will have less precision). Also if you look at the equations, you can easily replace the computation with some lookup tables. Again I have no idea if the Wii hardware allows you to process the framebuffer at a decent speed or if you need to do that beforehand
We once had a passion
It all seemed so right
So young and so eager
No end in sight
But now we are prisoners
In our own hearts
Nothing seems real
It's all torn apart

Offline ninogenio

  • Pentium
  • *****
  • Posts: 1667
  • Karma: 133
    • View Profile
cool this is all great info,

i was a bit baffled about the framebuffer being y1cby2cr too but i think the wii/gamecube is a bit limited in the amount of vram available so being able too pack two pixels into a 32bit int expesially in 3d games where there are a lot of textures in vram is probably going to be worth the hasstle.

im going to try out some of your color correction tips but i think im going too run into speed issuses as just a simple full screen conversion to ycbcr is really hurting performace.

i think nintedo expect people to work directly in the ycbcr format without using rgb maybe with a color pallete already computed.
Challenge Trophies Won: