Hi
Can anybody tell me what is wrong with this C language function to convert YUV422 to YUV411? The image has the right definition but the colors are all mess up.
static int conv422to411(char * src,char * dst, int width, int height)
{
int y1,y2, y3, y4,u,v;
char * dst_inicial=dst;
int rgb1, rgb2, rgb3, rgb4;
int i=0;
char buffer_yuv[12];
unsigned char *clp=NULL;
{
/* intra frame */
for (i=0; i< width*height*2; i+=8)
{
u=src[i];
y1=src[i+1];
v =src[i+2];
y2=src[i+3];
y3=src[i+5];
y4=src[i+7];
// move to YUV 411 buffer
*dst++ = u; // move U
*dst++ = y1; // move Y1
*dst++ = v; // move V
*dst++ = y2; // move y2
*dst++ = y3; // move y3
*dst++ = y4; // move y4
}
}
Thanks
Try StreamFab Downloader and download from Netflix, Amazon, Youtube! Or Try DVDFab and copy Blu-rays! or rip iTunes movies!
+ Reply to Thread
Results 1 to 11 of 11
Thread
-
-
What is your YUV 4:2:2 format? YUY2? UYVY? And the 4:1:1 format? You intend to point sample U and Y?
-
Thanks for your reply.
The YUV 4:2:2's format is UYVY..
The YUV 4:1:1's format is UYVYYY
I didn't understand this question : You intend to point sample U and Y? -
Are you sure the 4:1:1 format is YUVYYY, not UYYVYY?
Sorry, I made a typo. I meant to ask if you wanted to point sample U and V (not Y). You're reducing two U values to one U value, and two V values to one V value. You're code is doing so by throwing away one U and one V. -
Sorry the 4:1:1 format is UYVYYY. I included the code for the 4:1:1 to RGB decoder in C# below.
I just want to make the 411 image to be as close to the original 422 is.
To be honest I just throw U and V because I don't know to think a better procedure.
namespace YUYDecoder
{
public class YUYDecoder
{
private int clip(int x){
if (x>255) x=255;
else if (x<0) x=0;
return x;
}
private int get_pixel_yuv(byte y, sbyte u, sbyte v, sbyte x){
int r, g, b;
r=clip(((y<<12) + v*5743 + 2048)>>12);
g=clip(((y<<12) - u*1411 - v*2925 + 2048)>>12);
b=clip(((y<<12) + u*7258 + 2048)>>12);
r = clip(r + x);
g = clip(g + x);
b = clip(b + x);
return (r<<16)|(g<<8)|b;
}
public unsafe byte[] Decode(int width, int height, byte[] buffer, sbyte brightness)
{
byte[] acol = new byte[width * height * 4];
fixed (byte* pcol = acol, pbuf1 = buffer) {
int* col = (int *)pcol;
byte* buf1 = (byte*)pbuf1;
// Stopwatch sw = Stopwatch.StartNew();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x += 4, buf1 += 6)
{ UYVYYY
if (x < width)
{
*col++ = get_pixel_yuv(buf1[1], (sbyte)buf1[0], (sbyte)buf1[2], brightness);
*col++ = get_pixel_yuv(buf1[3], (sbyte)buf1[0], (sbyte)buf1[2], brightness);
*col++ = get_pixel_yuv(buf1[4], (sbyte)buf1[0], (sbyte)buf1[2], brightness);
*col++ = get_pixel_yuv(buf1[5], (sbyte)buf1[0], (sbyte)buf1[2], brightness);
}
}
}
// sw.Stop();
// long milliSec = sw.ElapsedMilliseconds;
}
return acol;
}
public bool Brighten(Bitmap b, int nBrightness)
{
// GDI+ return format is BGR, NOT RGB.
BitmapData bmData
= b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
int stride = bmData.Stride;
System.IntPtr Scan0 = bmData.Scan0;
unsafe
{
int nVal;
byte* p = (byte*)(void*)Scan0;
int nOffset = stride - b.Width * 3;
int nWidth = b.Width * 3;
for (int y = 0; y < b.Height; ++y)
{
for (int x = 0; x < nWidth; ++x)
{
nVal = (int)(p[0] + nBrightness);
if (nVal < 0) nVal = 0;
if (nVal > 255) nVal = 255;
p[0] = (byte)nVal;
++p;
}
p += nOffset;
}
}
b.UnlockBits(bmData);
return true;
}
}
} -
So your code basically works but the colors are wrong? If you replace u and v with 128 (ie replace u=src[i]; with u=128;, and the same for v) do you get a perfect greyscale image?
I would start by changing your "char" definitions for the YUV values to "unsigned char". And the same for the "int y1,y2, y3, y4,u,v". That will prevent possible automatic sign extension problems.
Why don't you get rid of all the temp variables and change the inner loop to:
Code:for (i=0; i< width*height*2; i+=8) { // move UYVY(*2) to UYVYYY buffer *dst++ = src[i]; // move U *dst++ = src[i+1]; // move Y1 *dst++ = src[i+2]; // move V *dst++ = src[i+3]; // move y2 *dst++ = src[i+5]; // move y3 *dst++ = src[i+7]; // move y4 }
Last edited by jagabo; 3rd Apr 2014 at 11:09.
-
Hi
I modify the code as your instruction and the image now is entirely green.
Thanks -
It worked on a small 4x2 image when I tested it. Time for the debugger, I guess.
-
Thanks a lot for your attention. I will make some testing and post the result.
-
Make sure your UYVY image has a mod 4 width. If you're building 16 bit code you will run into overflow problems with larger images.
Similar Threads
-
Getting an error with converting with AVStoDVD
By Complete Novice in forum Authoring (DVD)Replies: 3Last Post: 24th Aug 2013, 23:00 -
FFMpeg: YUV422 and MPEG4 Video Codec
By HypnoBeard in forum LinuxReplies: 6Last Post: 26th Sep 2011, 23:10 -
Does Theora Decoder in libavcodec (FFMPEG V0.5) support YUV422 YUV444 modes
By goldenmean in forum Newbie / General discussionsReplies: 0Last Post: 15th Feb 2010, 22:35 -
Where can i get YUV444 & YUV422 raw Video sequences?
By goldenmean in forum Newbie / General discussionsReplies: 5Last Post: 15th Feb 2010, 12:51 -
Error with Xvid4PSP when converting MKV to AVI (VirtualDub Error)
By Peter25 in forum Newbie / General discussionsReplies: 1Last Post: 9th Apr 2009, 18:10