Chronic YUV411 -> RGB24 conversion trouble

G

Guest

Guest
Archived from groups: comp.sys.ibm.pc.hardware.video (More info?)

Hi folks,

I've been following the info on:

http://www.fourcc.org/index.php

but am not having much luck. I'm reading data from a Sony TVR27 (NTSC)
digital video camera via ieee1394 port. But my attempts to translate
bits are failing. I've tried pretty much everything. My latest attempt
was to scan even / odd groups of 6 bytes each (eg., 4+1+1) perform the
conversion via the suggested formulas, then render RGB image. No dice.
Even with sequential reading (eg., no even/odd consideration) I get a
garbled image. Here's my basic loop. If anyone has some input, I'd
really appreciate it. I suspect I'm just not grasping what format
YUV411 data is in ... and hence decoding it wrong.

My image, btw, is pretty much noise with some mildly sloping diagonal
lines. So I'm obviously scanning wrong. I'm doing this on a Slackware
9.1 Linux box with the latest libdv libraries, reading directly from
/dev/dv1394 ... but the technique should be platform independent, no?

*buf has the raw dv data
*temp_buf is what I hope to be a valid RGB image

/* Even */

for (pix=0;pix<(ROWS*COLS*6);pix+=12) {

u = buf[pix];
y = buf[pix+1];
v = buf[pix+3];
y1 = buf[pix+2];
y2 = buf[pix+4];
y3 = buf[pix+5];

tempr = (1.164*(y-16))+ (1.596 * (v - 128));
tempg = (1.164*(y - 16)) - (0.813*(v - 128)) - (0.391*(u - 128));
tempb = (1.164*(y - 16)) + (2.018*(u - 128));

r=CLIPPED(tempr);
g=CLIPPED(tempg);
b=CLIPPED(tempb);

/* Next pixel */

tempr = (1.164*(y1 - 16))+ (1.596 * (v - 128));
tempg = (1.164*(y1 - 16)) - (0.813*(v - 128)) - (0.391*(u - 128));
tempb = (1.164*(y1 - 16)) + (2.018*(u - 128));

r=CLIPPED(tempr);
g=CLIPPED(tempg);
b=CLIPPED(tempb);

/* Next pixel */

tempr = (1.164*(y2 - 16))+ (1.596 * (v - 128));
tempg = (1.164*(y2 - 16)) - (0.813*(v - 128)) - (0.391*(u - 128));
tempb = (1.164*(y2 - 16)) + (2.018*(u - 128));

r=CLIPPED(tempr);
g=CLIPPED(tempg);
b=CLIPPED(tempb);

/* Next pixel */

tempr = (1.164*(y3 - 16))+ (1.596 * (v - 128));
tempg = (1.164*(y3 - 16)) - (0.813*(v - 128)) - (0.391*(u - 128));
tempb = (1.164*(y3 - 16)) + (2.018*(u - 128));

r=CLIPPED(tempr);
g=CLIPPED(tempg);
b=CLIPPED(tempb);

/* track_buf[j] = r+(256+g)+(65536+b); */
*(temp_buf+18) = r;
*(temp_buf+19) = g;
*(temp_buf+20) =b;

temp_buf +=24;
}


--
Technical Director - Virginia Center for Computer Music
http://www.virginia.edu/music/vccm.html
 
G

Guest

Guest
Archived from groups: comp.sys.ibm.pc.hardware.video (More info?)

"David Topper" <topper@virginia.edu> wrote in message
news:c8irkh$6h4$1@murdoch.acc.Virginia.EDU...
> but am not having much luck. I'm reading data from a Sony TVR27 (NTSC)
> digital video camera via ieee1394 port. But my attempts to translate
> bits are failing. I've tried pretty much everything. My latest attempt
> was to scan even / odd groups of 6 bytes each (eg., 4+1+1) perform the
> conversion via the suggested formulas, then render RGB image.

I don't speak any programming language that's in common use
in the current geologic era, but perhaps I can help you out a
bit. The "411" here - more commonly written "4:1:1" does not
refer to the number of bytes, but rather the relative sampling
rates of the Y, U, and V components - and all it really means is
that you have four samples of Y for each sample of U and V.
(The numbers actually derive from multiples of the base sampling
rate, but...well, skip it.) In most common digital video standards,
each of these samples would be 8 bits, but I can't tell you how
these things would be arranged in the data stream you happen to
dealing with. By the way, in digital video systems, the components
are more commonly referred to as "YCrCb" (the "r" and "b" here
should actually be subscripts, not lower-case) instead of "YUV" -
you may be able to find some info via a search on "4:1:1 YCbCr".

Bob M.



No dice.
> Even with sequential reading (eg., no even/odd consideration) I get a
> garbled image. Here's my basic loop. If anyone has some input, I'd
> really appreciate it. I suspect I'm just not grasping what format
> YUV411 data is in ... and hence decoding it wrong.
>
> My image, btw, is pretty much noise with some mildly sloping diagonal
> lines. So I'm obviously scanning wrong. I'm doing this on a Slackware
> 9.1 Linux box with the latest libdv libraries, reading directly from
> /dev/dv1394 ... but the technique should be platform independent, no?
>
> *buf has the raw dv data
> *temp_buf is what I hope to be a valid RGB image
>
> /* Even */
>
> for (pix=0;pix<(ROWS*COLS*6);pix+=12) {
>
> u = buf[pix];
> y = buf[pix+1];
> v = buf[pix+3];
> y1 = buf[pix+2];
> y2 = buf[pix+4];
> y3 = buf[pix+5];
>
> tempr = (1.164*(y-16))+ (1.596 * (v - 128));
> tempg = (1.164*(y - 16)) - (0.813*(v - 128)) - (0.391*(u - 128));
> tempb = (1.164*(y - 16)) + (2.018*(u - 128));
>
> r=CLIPPED(tempr);
> g=CLIPPED(tempg);
> b=CLIPPED(tempb);
>
> /* Next pixel */
>
> tempr = (1.164*(y1 - 16))+ (1.596 * (v - 128));
> tempg = (1.164*(y1 - 16)) - (0.813*(v - 128)) - (0.391*(u - 128));
> tempb = (1.164*(y1 - 16)) + (2.018*(u - 128));
>
> r=CLIPPED(tempr);
> g=CLIPPED(tempg);
> b=CLIPPED(tempb);
>
> /* Next pixel */
>
> tempr = (1.164*(y2 - 16))+ (1.596 * (v - 128));
> tempg = (1.164*(y2 - 16)) - (0.813*(v - 128)) - (0.391*(u - 128));
> tempb = (1.164*(y2 - 16)) + (2.018*(u - 128));
>
> r=CLIPPED(tempr);
> g=CLIPPED(tempg);
> b=CLIPPED(tempb);
>
> /* Next pixel */
>
> tempr = (1.164*(y3 - 16))+ (1.596 * (v - 128));
> tempg = (1.164*(y3 - 16)) - (0.813*(v - 128)) - (0.391*(u - 128));
> tempb = (1.164*(y3 - 16)) + (2.018*(u - 128));
>
> r=CLIPPED(tempr);
> g=CLIPPED(tempg);
> b=CLIPPED(tempb);
>
> /* track_buf[j] = r+(256+g)+(65536+b); */
> *(temp_buf+18) = r;
> *(temp_buf+19) = g;
> *(temp_buf+20) =b;
>
> temp_buf +=24;
> }
>
>
> --
> Technical Director - Virginia Center for Computer Music
> http://www.virginia.edu/music/vccm.html
>