兄弟我正在做个视频处理软件,把DVD上的视频解码,然后叠加文字,然后在以Mpeg2压缩。我的做法是mpeg2 dec(YUV420)-〉RGB24->图像处理(RGB24)->YUV420->mpeg2 enc(YUV420).
现在我想把图像处理后的RGB24格式转换成YUV420来压缩,但一直不成功,忘哪位朋友能给我一份windows下RGB24(RGB24even,RGB24odd)转YUV420的vc代码。非常感谢!
Email: [email protected]
现在我想把图像处理后的RGB24格式转换成YUV420来压缩,但一直不成功,忘哪位朋友能给我一份windows下RGB24(RGB24even,RGB24odd)转YUV420的vc代码。非常感谢!
Email: [email protected]
解决方案 »
- Microsoft Visual Studio 虚函数重载的问题
- 如何对异步方式创建的文件进行同步读写?
- 请问:如何实现截屏(全屏)并保存成Avi格式的文件?????????就这么多的分了,谢谢!
- 请问刚下的一个VC程序,不知为啥不能设断点,我想可能是作者有意设置的,不知道有没有办法让它断点调试先谢谢了
- 请教一个msdn的问题。
- 求救!为何我自定义的accelerator快捷键 ctrl+I 无效,自动被程序替换成了shift+I?
- 关机的函数怎么了??
- 多线程写文件的问题
- 已知一个窗口的句柄,如何取得该窗口的线程或进程的句柄
- 简单的问题
- 遍历某个文件夹下的*.txt 文件,并把这些文件的内容读出来。
- 为什么IDirectDraw7不能识别
CMxDDraw::RGB24_to_RGB32(BYTE * pRGB24, DWORD dwRGB24Len, PBYTE & pRGB32, DWORD & dwRGB32Len)
{
ASSERT(pRGB24);
ASSERT(!pRGB32); dwRGB32Len = ((m_nPosWidth * CLR_32BIT + 7) / 8) * m_nPosHeigh;
pRGB32 = new BYTE [dwRGB32Len];
if (pRGB32)
{
//Step through the 32bit buffer, copying the 3 Channels from
//the 24bit buffer. However, at the end of each channel, we
//have to write an extra byte for the 32bit image's alpha
//channel
ZeroMemory(pRGB32, dwRGB32Len);
for (DWORD i = 0, j = 0; i < dwRGB32Len; i += 4, j += 3)
{
memcpy(&pRGB32[i], &pRGB24[j], 3);
} return TRUE;
} return FALSE;
} void
CMxDDraw::DrawYUV420(BYTE * pYUVData, DWORD stride,BOOL is_interlaced)
{
DDSURFACEDESC ddsd;
LPBYTE lpY = pYUVData;
LPBYTE lpU = pYUVData + 1;
LPBYTE lpV = pYUVData + 2;
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
ddsd.dwWidth = m_nPosWidth;
ddsd.dwHeight = m_nPosHeigh;
ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC | DDPF_YUV;
ddsd.ddpfPixelFormat.dwFourCC = MAKEFOURCC('U','Y','V','Y');
ddsd.ddpfPixelFormat.dwYUVBitCount = 16; if (!CreateOffScrrenSurface(&ddsd))
{
return;
}
if(m_lpDDSOffScr->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL) != DD_OK)
{
return;
} LPBYTE lpSurf = (LPBYTE)ddsd.lpSurface;
//Fill Off-screen surface
if(lpSurf)
{
DWORD i = 0;
DWORD j = 0;
for(i = 0; i < ddsd.dwHeight && is_interlaced; i += 2)
{
lpSurf += i * ddsd.lPitch;
for (j = 0; j < ddsd.dwWidth; j += 2)
{
*lpSurf++ = *lpU++; //U
*lpSurf++ = *lpY++; //Y
*lpSurf++ = *lpV++; //V
*lpSurf++ = *lpY++; //Y
}
if (stride > ddsd.dwWidth)
{
lpU += (stride - ddsd.dwWidth) / 2;
lpV += (stride - ddsd.dwWidth) / 2;
lpY += (stride - ddsd.dwWidth);
} if (i % 4 == 0)
{
lpU -= stride / 2;
lpV -= stride / 2;
}
}
for(i = 1; i < ddsd.dwHeight && is_interlaced; i += 2)
{
lpSurf += i * ddsd.lPitch;
for (j = 0; j < ddsd.dwWidth; j += 2)
{
*lpSurf++ = *lpU++; //U
*lpSurf++ = *lpY++; //Y
*lpSurf++ = *lpV++; //V
*lpSurf++ = *lpY++; //Y
}
if (stride > ddsd.dwWidth)
{
lpU += (stride - ddsd.dwWidth) / 2;
lpV += (stride - ddsd.dwWidth) / 2;
lpY += (stride - ddsd.dwWidth);
}
if ((i - 1) % 4 == 0)
{
lpU -= stride / 2;
lpV -= stride / 2;
}
}
for(i = 0; i < ddsd.dwHeight && !is_interlaced; i += 2)
{
lpSurf += i * ddsd.lPitch;
for (j = 0; j < ddsd.dwWidth; j += 2)
{
*lpSurf++ = *lpU++; //U
*lpSurf++ = *lpY++; //Y
*lpSurf++ = *lpV++; //V
*lpSurf++ = *lpY++; //Y
}
if (stride > ddsd.dwWidth)
{
lpU += (stride - ddsd.dwWidth) / 2;
lpV += (stride - ddsd.dwWidth) / 2;
lpY += (stride - ddsd.dwWidth);
}
if (i % 2 == 0)
{
lpU -= ddsd.lPitch / 2;
lpV -= ddsd.lPitch / 2;
}
}
}
m_lpDDSOffScr->Unlock(NULL);
RecalculateDstRect();
m_lpDDClipper->SetHWnd(0, m_hVideoHWND);
m_lpDDSPrimary->Blt(&m_rcDst, m_lpDDSOffScr, &m_rcSrc, DDBLT_WAIT, NULL);
}上面的代码,给你参考一下。第二个函数实现了从YUV到RGB32的转化。
#define RGB_TO_YUV(rgb_color, yuv_color) { \
63 yuv_color[0] = ( 0.257 * rgb_color[0]) + (0.504 * rgb_color[1]) + (0.098 * rgb_color[2]) + 16; \
64 yuv_color[2] = ( 0.439 * rgb_color[0]) - (0.368 * rgb_color[1]) - (0.071 * rgb_color[2]) + 128; \
65 yuv_color[1] = (-0.148 * rgb_color[0]) - (0.291 * rgb_color[1]) + (0.439 * rgb_color[2]) + 128; \
66 }