/************************************************************************ * * yuvrgb24.c, colour space conversion for tmndecode (H.263 decoder) * Copyright (C) 1996 Telenor R&D, Norway * Karl Olav Lillevold <[email protected]> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Karl Olav Lillevold <[email protected]> * Telenor Research and Development * P.O.Box 83 tel.: +47 63 84 84 00 * N-2007 Kjeller, Norway fax.: +47 63 81 00 76 * * Robert Danielsen e-mail: [email protected] * Telenor Research and Development www: http://www.nta.no/brukere/DVC/ * P.O.Box 83 tel.: +47 63 84 84 00 * N-2007 Kjeller, Norway fax.: +47 63 81 00 76 * ************************************************************************/#include "DGlobal.h" /* Data for ConvertYUVtoRGB*/ long int crv_tab[256]; long int cbu_tab[256]; long int cgu_tab[256];long int cgv_tab[256]; long int tab_76309[256]; /** * Init Routine... * This must be invoked only once before calling conversion routine */void init_dither_tab() { long int crv,cbu,cgu,cgv; int i;
crv = 104597; cbu = 132201; /* fra matrise i global.h */ cgu = 25675; cgv = 53279;
/********************************************************************** * * Name: ConvertYUVtoRGB * Description: Converts YUV image to RGB (packed mode) * * Input: pointer to source luma, Cr, Cb, destination, * image width and height * Returns: * Side effects: * * Date: 951208 Author: [email protected] * ***********************************************************************/void ConvertYUVtoRGB(unsigned char *src0,unsigned char *src1,unsigned char *src2,unsigned char *dst_ori,int width,int height) { extern long int crv_tab[]; extern long int cbu_tab[]; extern long int cgu_tab[]; extern long int cgv_tab[]; extern long int tab_76309[]; int y11,y21; int y12,y22; int y13,y23; int y14,y24; int u,v; int i,j; int c11, c21, c31, c41; int c12, c22, c32, c42; unsigned int DW; unsigned int *id1, *id2; unsigned char *py1,*py2,*pu,*pv; unsigned char *d1, *d2;
to : DentistryDoctor(My heart will fly,in the sky.) 呵呵,我按照你的方法做了,但不知为什么,OVERLAY表面始终无法建立成功,请问可能出现的原因是什么?我想问一下,建立OVERLAY表面的方式还需不需要先建立一个主表面?是不是只建立一个OVERLAY表面就可以正常显示YUV数据了?
to : DentistryDoctor(My heart will fly,in the sky.) 你能不能把你的DDRAW显示YUV数据的程序发给我参考一下,非常感谢!
{ return ((int) value) < 0 ? 0 : ((int) value) > 0xff00 ? 0xff00 : value; }
void CColorSpaceConvetor::YUV2RGB(BYTE * pDest, BYTE * pSrc, DWORD dwRGBBit,
DWORD dwDestPitch, DWORD dwSrcPitch,
int nHeight, UINT nWidth)
{
UINT nLength = nWidth * ((dwRGBBit + 7) / 8);
if (nHeight <= 0)
{
nHeight = -nHeight;
switch (dwRGBBit)
{
case 16:
{
for (UINT i = 0; i < (UINT) nHeight; i++)
{
for (UINT j = 0, k = 0; j < nLength; j += 4, k += 4)
{
UINT y = pSrc[k];
UINT u = pSrc[k+1];
UINT v = pSrc[k+3];
UINT n1=511*u-6*v-64522;
UINT n2=48838-125*u-255*v;
UINT n3=506*v-u-64522;
UINT b = Trunc((y << 8) + n1) >> 11;
UINT g = Trunc((y << 8) + n2) >> 10;
UINT r = Trunc((y << 8) + n3) >> 11;
*(WORD*)(pDest + j) = (WORD) ((r << 11) | (g << 5) | b);
y = pSrc[k+2];
b = Trunc((y << 8) + n1) >> 11;
g = Trunc((y << 8) + n2) >> 10;
r = Trunc((y << 8) + n3) >> 11;
*(WORD*)(pDest + j + 2) = (WORD) ((r << 11) | (g << 5) | b);
}
pSrc += dwSrcPitch;
pDest += dwDestPitch;
}
}
break; }
}
else
{
pDest += (nHeight - 1) * dwDestPitch;
switch (dwRGBBit)
{
case 16:
{
for (UINT i = 0; i < (UINT) nHeight; i++)
{
for (UINT j = 0, k = 0; j < nLength; j += 4, k += 4)
{
UINT y = pSrc[k];
UINT u = pSrc[k+1];
UINT v = pSrc[k+3];
UINT b = Trunc((y << 8) + 511 * u - 6 * v - 64522) >> 11;
UINT g = Trunc((y << 8) - 125 * u - 255 * v + 48838) >> 10;
UINT r = Trunc((y << 8) - u + 506 * v - 64522) >> 11;
*(WORD*)(pDest + j) = (WORD) ((r << 11) | (g << 5) | b);
y = pSrc[k+2];
b = Trunc((y << 8) + 511 * u - 6 * v - 64522) >> 11;
g = Trunc((y << 8) - 125 * u - 255 * v + 48838) >> 10;
r = Trunc((y << 8) - u + 506 * v - 64522) >> 11;
*(WORD*)(pDest + j + 2) = (WORD) ((r << 11) | (g << 5) | b);
}
pSrc += dwSrcPitch;
pDest -= dwDestPitch;
}
}
break; }
}}
还有你可以参考一下sf.net中的xine项目,里面专门有yuv播放的那块
*
* yuvrgb24.c, colour space conversion for tmndecode (H.263 decoder)
* Copyright (C) 1996 Telenor R&D, Norway
* Karl Olav Lillevold <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Karl Olav Lillevold <[email protected]>
* Telenor Research and Development
* P.O.Box 83 tel.: +47 63 84 84 00
* N-2007 Kjeller, Norway fax.: +47 63 81 00 76
*
* Robert Danielsen e-mail: [email protected]
* Telenor Research and Development www: http://www.nta.no/brukere/DVC/
* P.O.Box 83 tel.: +47 63 84 84 00
* N-2007 Kjeller, Norway fax.: +47 63 81 00 76
*
************************************************************************/#include "DGlobal.h"
/* Data for ConvertYUVtoRGB*/
long int crv_tab[256];
long int cbu_tab[256];
long int cgu_tab[256];long int cgv_tab[256];
long int tab_76309[256];
/**
* Init Routine...
* This must be invoked only once before calling conversion routine
*/void init_dither_tab()
{
long int crv,cbu,cgu,cgv;
int i;
crv = 104597; cbu = 132201; /* fra matrise i global.h */
cgu = 25675; cgv = 53279;
for (i = 0; i < 256; i++) {
crv_tab[i] = (i-128) * crv;
cbu_tab[i] = (i-128) * cbu;
cgu_tab[i] = (i-128) * cgu;
cgv_tab[i] = (i-128) * cgv;
tab_76309[i] = 76309*(i-16);
}
}
/**********************************************************************
*
* Name: ConvertYUVtoRGB
* Description: Converts YUV image to RGB (packed mode)
*
* Input: pointer to source luma, Cr, Cb, destination,
* image width and height
* Returns:
* Side effects:
*
* Date: 951208 Author: [email protected]
*
***********************************************************************/void ConvertYUVtoRGB(unsigned char *src0,unsigned char *src1,unsigned char *src2,unsigned char *dst_ori,int width,int height)
{
extern long int crv_tab[];
extern long int cbu_tab[];
extern long int cgu_tab[]; extern long int cgv_tab[];
extern long int tab_76309[]; int y11,y21;
int y12,y22;
int y13,y23;
int y14,y24;
int u,v;
int i,j;
int c11, c21, c31, c41;
int c12, c22, c32, c42;
unsigned int DW;
unsigned int *id1, *id2;
unsigned char *py1,*py2,*pu,*pv;
unsigned char *d1, *d2;
d1 = dst_ori;
d1 += width*height*3 - width*3;
d2 = d1 - width*3;
py1 = src0; pu = src1; pv = src2;
py2 = py1 + width;
id1 = (unsigned int *)d1;
id2 = (unsigned int *)d2; for (j = 0; j < height; j += 2) {
/* line j + 0 */
for (i = 0; i < width; i += 4) {
u = *pu++;
v = *pv++;
c11 = crv_tab[v];
c21 = cgu_tab[u];
c31 = cgv_tab[v];
c41 = cbu_tab[u];
u = *pu++;
v = *pv++;
c12 = crv_tab[v];
c22 = cgu_tab[u];
c32 = cgv_tab[v];
c42 = cbu_tab[u]; y11 = tab_76309[*py1++]; /* (255/219)*65536 */
y12 = tab_76309[*py1++];
y13 = tab_76309[*py1++]; /* (255/219)*65536 */
y14 = tab_76309[*py1++]; y21 = tab_76309[*py2++];
y22 = tab_76309[*py2++];
y23 = tab_76309[*py2++];
y24 = tab_76309[*py2++]; /* RGBR*/
DW = ((clp[(y11 + c41)>>16])) |
((clp[(y11 - c21 - c31)>>16])<<8) |
((clp[(y11 + c11)>>16])<<16) |
((clp[(y12 + c41)>>16])<<24);
*id1++ = DW; /* GBRG*/
DW = ((clp[(y12 - c21 - c31)>>16])) |
((clp[(y12 + c11)>>16])<<8) |
((clp[(y13 + c42)>>16])<<16) |
((clp[(y13 - c22 - c32)>>16])<<24);
*id1++ = DW; /* BRGB*/
DW = ((clp[(y13 + c12)>>16])) |
((clp[(y14 + c42)>>16])<<8) |
((clp[(y14 - c22 - c32)>>16])<<16) |
((clp[(y14 + c12)>>16])<<24);
*id1++ = DW; /* RGBR*/
DW = ((clp[(y21 + c41)>>16])) |
((clp[(y21 - c21 - c31)>>16])<<8) |
((clp[(y21 + c11)>>16])<<16) |
((clp[(y22 + c41)>>16])<<24);
*id2++ = DW; /* GBRG*/
DW = ((clp[(y22 - c21 - c31)>>16])) |
((clp[(y22 + c11)>>16])<<8) |
((clp[(y23 + c42)>>16])<<16) |
((clp[(y23 - c22 - c32)>>16])<<24);
*id2++ = DW; /* BRGB*/
DW = ((clp[(y23 + c12)>>16])) |
((clp[(y24 + c42)>>16])<<8) |
((clp[(y24 - c22 - c32)>>16])<<16) |
((clp[(y24 + c12)>>16])<<24);
*id2++ = DW;
}
id1 -= (9 * width)>>2;
id2 -= (9 * width)>>2;
py1 += width;
py2 += width;
}
}
static DDPIXELFORMAT ddpf = {sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','U','Y','V'),0,0,0,0,0};
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
ddsd.dwWidth = nWidth;
ddsd.dwHeight = nHeight;
ddsd.ddpfPixelFormat = ddpf;
ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY|DDSCAPS_HWCODEC;
CHECK_DDERR(m_pDD->CreateSurface(&ddsd, &m_pOverlay, NULL));
油箱:[email protected]
//Write data to Overlay surface(pDest) use CopyMemory
BYTE * pDest = (BYTE*) ddsd.lpSurface;
BYTE * pSrc = ...
if(pSrc!=NULL)
{
DWORD dwLength=nWidth*2;
for (UINT i = 0; i < dwHeight; i++)
{
CopyMemory(pDest, pSrc, dwLength);
pDest += ddsd.lPitch;
pSrc += dwLength;
}
}
m_pOverlay->Unlock(ddsd.lpSurface);
1.是否可以在不建立OVERLAY表面的情况下,也可以用DDRAW直接显示YUV数据?我最开始没有建立OVERLAY表面,只是建立了一个OFF SCREEN表面,向OFF SCREEN表面写数据,然后再BLT到主表面上,但不知为什么,做了很久都没有成功,图象总是不太正常,但有图象的轮廓和大致的图象效果,是不是我那个地方还没有操作正确,请问我这种不建立OVERLAY表面的方法可行吗?
2.我感到很奇怪,我把计算机的颜色位数分别设为16位和32位,显示出来的图象效果完全不一样,难道YUV数据的显示也跟RGB数据的显示一样与计算机颜色深度有关?请问有没有这种说法?如果有,那么YUV数据的显示在什么地方可以设置颜色深度?
2.可能问题出现在RGB2YUV(RGB转换成YUV).
呵呵,我按照你的方法做了,但不知为什么,OVERLAY表面始终无法建立成功,请问可能出现的原因是什么?我想问一下,建立OVERLAY表面的方式还需不需要先建立一个主表面?是不是只建立一个OVERLAY表面就可以正常显示YUV数据了?
你能不能把你的DDRAW显示YUV数据的程序发给我参考一下,非常感谢!
顶一下,高手继续解答!
假设我的计算机颜色位数是16位,我的YUV数据为4:2:0,请问我应该按照怎样的顺序或者怎样的规则将我的YUV数据存放到我建立的表面上?Y,U,V三个分量的位置是怎么样的?
谢谢,望高手点拔一下!
你只要看看显卡DDraw7的能力中有没有Blt FourCC一项就知道能不能这样做了。