怎么这么久了还没结束啊? 该结束了吧!!!
给你一个代码,我正在用的。
输入为 YUV420P 的数据。
先转化为 rgb24
#define LIMIT(x) (BYTE)(((x>0xffffff)?0xff0000
(x<=0xffff)?0:x&0xff0000))>>16)
BOOL CVideo_inputDlg::Yuv420pToRgb(const void * yuv_buffer)
{
const void* frame = yuv_buffer;
unsigned int size = width * height;
bool rgbReverseOrder = true;
// get pointers to the data
const BYTE * yplane = (BYTE *)frame;
const BYTE * uplane = yplane + size;
const BYTE * vplane = yplane + size + (size >> 2);
// get temporary buffers
PBYTEArray rgbLine(width*3);
// draw 2 lines at once
PBYTEArray rgbLine2(width*3);
// draw 2 lines at once
unsigned x, y;
for (y = 0;
y < height;
y+=2) {
const BYTE * yline = yplane + (y * width);
const BYTE * yline2 = yline + width;
const BYTE * uline = uplane + ((y >> 1) * (width >> 1));
const BYTE * vline = vplane + ((y >> 1) * (width >> 1));
BYTE * rgb = rgbLine.GetPointer();
BYTE * rgb2 = rgbLine2.GetPointer();
for (x = 0;
x < width;
x+=2) {
long Cr = *uline++ - 128;
// calculate once for 4 pixels
long Cb = *vline++ - 128;
long lrc = 104635 * Cb;
long lgc = -25690 * Cr + -53294 * Cb;
long lbc = 132278 * Cr;
if (rgbReverseOrder)
{
long tmp;
// exchange red component and blue component
tmp=lrc;
lrc=lbc;
lbc=tmp;
}
long Y = *yline++ - 16;
// calculate for every pixel
if (Y < 0)
Y = 0;
long l = 76310 * Y;
long lr = l + lrc;
long lg = l + lgc;
long lb = l + lbc;
*rgb++ = LIMIT(lr);
*rgb++ = LIMIT(lg);
*rgb++ = LIMIT(lb);
Y = *yline++ - 16;
// calculate for every pixel
if (Y < 0)
Y = 0;
l = 76310 * Y;
lr = l + lrc;
lg = l + lgc;
lb = l + lbc;
*rgb++ = LIMIT(lr);
*rgb++ = LIMIT(lg);
*rgb++ = LIMIT(lb);
Y = *yline2++ - 16;
// calculate for every pixel
if (Y < 0)
Y = 0;
l = 76310 * Y;
lr = l + lrc;
lg = l + lgc;
lb = l + lbc;
*rgb2++ = LIMIT(lr);
*rgb2++ = LIMIT(lg);
*rgb2++ = LIMIT(lb);
Y = *yline2++ - 16;
// calculate for every pixel
if (Y < 0)
Y = 0;
l = 76310 * Y;
lr = l + lrc;
lg = l + lgc;
lb = l + lbc;
*rgb2++ = LIMIT(lr);
*rgb2++ = LIMIT(lg);
*rgb2++ = LIMIT(lb);
}
if (!WriteLineSegment(0, y, width, rgbLine))
return FALSE;
if (!WriteLineSegment(0, y+1, width, rgbLine2))
return FALSE;
}
return TRUE;
}
BOOL CVideo_inputDlg::WriteLineSegment(int x, int y, unsigned int len, const BYTE *data)
{
if (m_bFlip)
y = (height-1) - y;
int offset = (y*width + x) * 3;
const int maxYOffset = height - 1;
ASSERT(rgb_buffer != NULL);
memcpy(rgb_buffer + offset, data, len*3);
return TRUE;
}
然后:
binfo.bmiHeader.biSize = sizeof(BITMAPINFO);
binfo.bmiHeader.biWidth = width;
binfo.bmiHeader.biHeight = height;
binfo.bmiHeader.biPlanes = 1;
binfo.bmiHeader.biBitCount = 24;
binfo.bmiHeader.biCompression = BI_RGB;
binfo.bmiHeader.biSizeImage = 0;
binfo.bmiHeader.biXPelsPerMeter = 0;
binfo.bmiHeader.biYPelsPerMeter = 0;
binfo.bmiHeader.biClrUsed = 0;
binfo.bmiHeader.biClrImportant = 0;
SetDIBitsToDevice(hDC, rect.left, rect.top, width, height, 0, 0, 0, height, rgb_buffer, &binfo, DIB_RGB_COLORS);