Help with RGB Video Data
mynet43
Posts: 644
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
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
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...
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
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
Thanks for the info. I have to stare at it for a while.
I'll probably have a couple of questions.
Jim
I would be excited to see even the soft core version.
[noparse][[/noparse]EDIT]
Just to add - my terminology above is to indicate the number of bits per colour in each pixels. R:G:B
@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
can you tell some more details about your setup?
How's the board and the propeller linked to the SRAM?
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
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?
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
Floyd-Steinberg dithering
Error diffusion
I appreciate your effort. I'll read them.
Jim
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...
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
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
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.....
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