Shop OBEX P1 Docs P2 Docs Learn Events
Help with RGB Video Data — Parallax Forums

Help with RGB Video Data

mynet43mynet43 Posts: 644
edited 2009-04-23 20:52 in Propeller 1
I have a new board that captures RGB camera data to an SRAM, which is then read by the Prop.

As part of debugging, I'm looking for a way to display the RGB data on a video monitor.

The RGB data is 16 bits per pixel, R=5, G=6, B=5 bits.

It's VGA 640 x 480 data, so I know a frame won't all fit in the Prop memory at one time.

My goal is to display part of a frame on a video monitor, just to make sure I'm processing the data correctly.

Is there available software that can be modified to display 16-bit RGB data like this? I didn't see any in the OBX.

If not, can someone recommend a way to approach this?

Thanks for the help.

Jim

Comments

  • RaymanRayman Posts: 14,826
    edited 2009-04-23 00:34
    I did a very crude preview with a camera here:
    http://www.rayslogic.com/propeller/Programming/Cameras/cameras.htm

    But, I'm working on a Prop based 320x240xRGB display module that would do a much better job...
  • mynet43mynet43 Posts: 644
    edited 2009-04-23 01:43
    Rayman,

    Thanks so much for the code. I'll take a look at it and try to make it work for what I'm doing.

    I'd be really interested in your 320x240xRGB code when you have it ready to try.

    Jim
  • tonyp12tonyp12 Posts: 1,951
    edited 2009-04-23 02:09
    The explanation·of the·four color VGA mode

    Waitvid #colors,#pixels

    These 32bits·are NOT shifted out·to any I/O pin.
    instead a pair of bits·is used·to pick one of the four bytes of the COLORS-register

    To emulate·the 5pins of ·a·VGA port that·have analog RGB, plus digital H_sync, V_sync.
    For·the 8·pins that Waitvid can effect,·they use·6 pins·for RrGgBb

    So the color data have to exclude some bits that is used·for H+V sync pins

    In this example I set up the 4 colors Red, Green, Blue and Gray that the 16 pixel group·can use:

    #%11000000001100000000110010101000

    The bits that represent the 6 pins are in bold (and unbold·are the·HV sync)

    The same, using colors to show pins
    #%11000000 00110000 00001100 10101000

    For the·32bits pixel data (starting with the LSB) it uses 2 bits at a time
    so you can use 11, 10, 01 or·00 to choose Red, Green, Blue or Gray.



    How to convert the·16bit (565) data down to hybrid·6bit (222) so·you·can evaluate it, could be tricky.
    Show a grayscale image maybe?
    Using this for the color #%11111100101010000101010000000000
    Will give you White, Light-gray, Dark-gray, Black. (aka $FCA85400)

    Some type of crude color>gray would be taking the most·4·MSBits of each 5-6-5 bits, add them up.
    If x< 12 then pixel=%00
    If x>=·12· and x<23·then pixel=%01
    If x>=·23 and x<34 then pixel=%10
    if x>=34·then pixel =%11


    Or could show a RGB Seperation?
    http://poorrichard.wordpress.com/2007/01/06/color-separation-whaddya-mean/



    P.S. Someone need to come up with a hardcore propeller tips and tricks video/vga·book.

    Post Edited (tonyp12) : 4/23/2009 5:34:54 AM GMT
  • mynet43mynet43 Posts: 644
    edited 2009-04-23 02:59
    TonyP,

    Thanks for the info. I have to stare at it for a while.

    I'll probably have a couple of questions.

    Jim
  • ElectricAyeElectricAye Posts: 4,561
    edited 2009-04-23 03:28
    tonyp12 said...
    ...
    Someone need to come up with a hardcore propeller tips and tricks video/vga book.

    I would be excited to see even the soft core version.
  • Brian FairchildBrian Fairchild Posts: 549
    edited 2009-04-23 06:49
    Take each 5:6:5 source pixel and map it to a 2x2 square of destination pixels. You then have an 8:8:8 display pixel when running the display in 2:2:2 mode.



    [noparse][[/noparse]EDIT]

    Just to add - my terminology above is to indicate the number of bits per colour in each pixels. R:G:B
  • mynet43mynet43 Posts: 644
    edited 2009-04-23 13:59
    You guys are giving me some good stuff.

    @Brian,

    Can you show me an example of mapping the data from 5:6:5 to a 2x2 square to get to an 8:8:8 display pixel? I understand your terminology but not the details of what you're thinking...

    When I get this, what's the best application to use to display it?

    I sure agree with everyone that wants to see a good manual/tutorial for this stuff on the Propeller. We have fantastic capability, but a lot of it seems to be hidden knowledge.

    Jim
  • MagIO2MagIO2 Posts: 2,243
    edited 2009-04-23 14:44
    @mynet43:
    can you tell some more details about your setup?

    How's the board and the propeller linked to the SRAM?
  • tonyp12tonyp12 Posts: 1,951
    edited 2009-04-23 14:45
    As you don't have true 2:2:2 choices for each pixels, there are tricks to get it.
    The tradeoff would be a lower pixel resolution.

    Instead of setting up a bitmap for the #pixels.
    By locking in the pixel order and change the colors instead.

    waitvid colordata,#%11111111101010100101010100000000 (aka $FFAA5500)

    The first 4 pixels will use LSByte of the color register,
    the second set of 4 pixels will use the second from·right color byte.

    As you see the tradeoff is 1/4 of horizontal·pixel resolution.


    trick2:
    If you manupilate the shift clock, so it only·output·8 pixels before resetting itself
    waitvid colordata,#%1111101001010000 (aka $FA50)

    You would have 1/2 of the resolution.


    Going down to a 4 pixel clock·is tricky as now there will be a time crunch to change data in time (can no longer afford loops etc)
    Linus VGA mode:
    http://forums.parallax.com/showthread.php?p=737311




    Post Edited (tonyp12) : 4/23/2009 4:47:08 PM GMT
  • Brian FairchildBrian Fairchild Posts: 549
    edited 2009-04-23 15:07
    My idea above overlooked the fact that, whilst the output to the DAC is 2:2:2, those values are derived from what amounts to a 2 x 6 LUT so we're stuck with a choice of just 4 output possibilities. I blame a) lack of coffee and b) still not having fully got my head around the video shifter.

    Had it have worked it would have worked like this...

    What you are doing is making a 'virtual' pixel which is in reality made up of an n x n square of real pixels. So, let's consider a real pixel when running your prop vga in 2:2:2, ie 4-colour mode. Each pixel can be off, at 1/3 brightness, at 2/3 brightness or at full brightness. Now let's make a 2x2 square of real pixels. We can now turn on just one of those at 1/3, we can turn on two at 1/3 to make a virtual 2/3 brightness pixel and so on until we turn on all four at full to make a virtual 4 brightness units pixel. So we've gone from 4 steps of brightness (2 bits) to 13 steps (3.5 bits). If you go to a 3x3 square then you go from 4 levels to 28 levels (nearly 5 bits). What you lose is resolution and if you're not careful you'll end up with odd patterns on the display based on how you decide which real pixels you turn on to make a virtual pixel. These can be minimised by the use of dithering and spatial error diffusion - you're going to have to google those - I'd need to draw lots of picture to explain!

    ...however, depending how many COGs you can devote to the task means things might work. If you have 3 COGs then you can do true 2:2:2 and use the idea above, each COG being R, G or B. With 6 COGs you can do true 4:4:4 which might be good enough without resorting to the above down-sampling. 6 COGs could also do 8:2:2 but in YUV space. You'd have a full 8-bit luminance space with lower resolution colour (just like TV).

    How are you at hardware? Use the prop to generate the timing signals for the VGA and take the video data straight from your SRAM?
  • mynet43mynet43 Posts: 644
    edited 2009-04-23 16:01
    @ Brian,

    Thanks for the really good explanation. By the time I get the VGA and i2c routines loaded, I don't have that many cogs left, so I'm still scratching my head. From my original post, my main goal here is to verify that I'm getting the right data from the camera, so I don't need super quality. I can see that I'm getting camera data, because when I display it on the screen I can see it change as the camera observes different stuff. It's a new circuit, so I'm trying to verify that I'm getting the 'right' data.

    I like your idea of doing it with hardware, which I can handle. The problem here is that the R:G:B is packed into two 8-bit bytes: RRRRRGGG GGGBBBBB, so it would be a challenge to separate it with the hardware.

    I have the unpacked data sitting there in memory. When I started this, it seemed like I should be able to just stuff the RGB data into some memory buffer and have it magically appear on the screen. So much for 'seemed like'...

    Any other thoughts?


    @MagIO2

    I knew someone would ask about how I'm using the SRAM[noparse]:)[/noparse]

    Actually it's a circuit that isn't that hard once I boiled it down.
    1. I send a master clock to the camera from the Prop, using CTRA and FRQA.
    2. The Prop gates the memory with a 74AHC244. This allows the camera to write directly to the SRAM with an 8-bit bus.
    3. I have two cascaded counters which increment the address lines on the memory.
    4. When the camera is writing to the memory, the counters are reset and then incremented by the clock sent from the Prop to the camera. The camera outputs frame and line signals which are read by the Prop and used to gate only the actual VGA data from the camera to the memory. It also allows selecting a range of lines to store from the camera.
    5. When the camera data is stored in the SRAM, then the Prop disables the buffer chip and takes direct control of the SRAM to read it. In this case, the Prop resets the counters and increments them from the Prop, as well as controlling the read signal to the SRAM. The data are input to 8 pins on the Prop.
    6. This is all done in assembly language, and seems to work very well.

    I'll be happy to supply more info to anyone interested.

    Thanks for asking.

    Jim
  • Brian FairchildBrian Fairchild Posts: 549
    edited 2009-04-23 16:03
    Might be worth reading...

    Floyd-Steinberg dithering

    Error diffusion
  • mynet43mynet43 Posts: 644
    edited 2009-04-23 16:06
    Thanks Brian!

    I appreciate your effort. I'll read them.

    Jim
  • RaymanRayman Posts: 14,826
    edited 2009-04-23 17:21
    Here's a cut an paste of my post from a previous thread:

    Here's a neat trick with SDRAM to get a VGA display:

    http://tinyvga.com/avr-sdram-vga

    Instead of using a RAMDAC, I think it'd be easier to use a 16-bit wide DRAM and a 3-channel RGB DAC directly...

    Looks to me like the hard part is sequencing the screen updates...
  • tonyp12tonyp12 Posts: 1,951
    edited 2009-04-23 17:29
    Fact, it probably would be impossible to read the 565 RGB data from SDRAM in real time.
    Let alone manipulate it to 222 data.

    So you would need to use the Hub Ram.

    Set up 160x120 pixel data buffer = 19kb

    Read a 565 16bit data.
    Now you would have to do a lot of masking using binary 'and'
    some bit-shifting and then 'or'/'mux' the right bits in to the place of a byte in the· pic buffer.

    %RRRRRGGGGGGBBBBB

    the Bold bits need to be arranged down this:

    %RRGGBB00

    You can now use this data directly·if you use the waitvid colorbitmap, 'fixed pixel' trick above.

    You would have to repeat each line 4 times to get square pixels.

    Post Edited (tonyp12) : 4/23/2009 5:48:07 PM GMT
  • mynet43mynet43 Posts: 644
    edited 2009-04-23 19:41
    @ Rayman,

    Interesting project. I'm not sure how I can use it for my debugging.

    @ tonyp12,

    Now it's getting interesting!

    I have no problem manipulating and storing the data as you described.

    Basically, take the two high bits of each of the R:G:B fields and pack them into the top 6 bits of a byte. Then store them sequentially in a 19.2KB buffer.

    I do have a question about the buffer size. What I'm trying to display is about 20 lines of VGA data = 640 x 20 pixels = 12.8KB. Should I structure it as 640 x 20 pixels, or does it matter? If we're talking less pixels per line, then I'll just store fewer pixels per line in the buffer.

    My only problem from here is that I've never used the waitvid colorbitmap processing.

    Can you elaborate on this a little, or give me an example showing how to get it from the buffer to the screen?

    Thanks again,

    Jim
  • tonyp12tonyp12 Posts: 1,951
    edited 2009-04-23 20:21
    640 pixels wide in the chunky pixel mode is harder, have to use unnested loops etc.

    320pixels x 20 pixels = 6.3kb

    Have to setup the shift register so it only output 8 pixels and restart.

    You can scroll the image though pretty easy, just start converting the 565pixel data 2 bytes in, next 4 bytes in.....
  • mynet43mynet43 Posts: 644
    edited 2009-04-23 20:52
    Hi Tony,

    The 320 x 20 pixels will work for me.

    Can you show me some code that shifts it out to the screen?

    Thanks for your help.

    Jim
Sign In or Register to comment.