请给出具体的方法,最好有相关的源代码或者相关资料网页,谢谢!我的油箱是[email protected]

解决方案 »

  1.   

    RGB 2 YUV"? 不明白,顶帖
      

  2.   

    inline UINT Trunc(UINT value)
    { 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; }
    }}
      

  3.   

    我这有个yuv的播放器,但没有源码
    还有你可以参考一下sf.net中的xine项目,里面专门有yuv播放的那块
      

  4.   

    /************************************************************************
     *
     *  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;
      }           
    }  
      

  5.   

    感谢各位高手的赐教,可能是我没说清楚,我想大家可能没有明白我的意思,我的意思是如何利用DDRAW直接播放YUV数据,而不是先转换为RGB格式再播放,请各位再赐教!谢谢!
      

  6.   

    创建一个Overlay平面,Lock/将数据写到Overlay平面/Unlock
      

  7.   

    DDSURFACEDESC ddsd;
    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));
      

  8.   

    谢谢上面的仁兄,请问有没有具体的参考例子或者网页之类的,谢谢!
    油箱:[email protected]
      

  9.   

    if(FAILED(m_pOverlay->Lock((LPRECT)rc, &ddsd, DDLOCK_WRITEONLY | DDLOCK_SURFACEMEMORYPTR, 0)))return FALSE;
    //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);
      

  10.   

    谢谢上面仁兄的解答,我先按照你说的方法试一下,还有两个问题向你请教一下:
    1.是否可以在不建立OVERLAY表面的情况下,也可以用DDRAW直接显示YUV数据?我最开始没有建立OVERLAY表面,只是建立了一个OFF SCREEN表面,向OFF SCREEN表面写数据,然后再BLT到主表面上,但不知为什么,做了很久都没有成功,图象总是不太正常,但有图象的轮廓和大致的图象效果,是不是我那个地方还没有操作正确,请问我这种不建立OVERLAY表面的方法可行吗?
    2.我感到很奇怪,我把计算机的颜色位数分别设为16位和32位,显示出来的图象效果完全不一样,难道YUV数据的显示也跟RGB数据的显示一样与计算机颜色深度有关?请问有没有这种说法?如果有,那么YUV数据的显示在什么地方可以设置颜色深度?
      

  11.   

    1.不创建Overlay平面的情况显示YUV?没做过,估计不能。
    2.可能问题出现在RGB2YUV(RGB转换成YUV).
      

  12.   

    哦,我的问题二是说用DDRAW直接显示YUV数据时,图象的显示效果是否与计算机的颜色深度有关?我的YUV数据是直接通过摄像头拿到的YUV数据,是正确的,而不是由RGB数据转换过来的,所以不存在转换错误的情况。如果有关,那么在什么地方可以设置?
      

  13.   

    to : DentistryDoctor(My heart will fly,in the sky.)
    呵呵,我按照你的方法做了,但不知为什么,OVERLAY表面始终无法建立成功,请问可能出现的原因是什么?我想问一下,建立OVERLAY表面的方式还需不需要先建立一个主表面?是不是只建立一个OVERLAY表面就可以正常显示YUV数据了?
      

  14.   

    to : DentistryDoctor(My heart will fly,in the sky.)
    你能不能把你的DDRAW显示YUV数据的程序发给我参考一下,非常感谢!
      

  15.   

    我觉得不创建OVERLAY表面,用OFF SCREEN表面也可以,但关键需要注意YUV数据格式应该与计算机的颜色位数配对,还需要注意你的显卡支持那些YUV格式,这只是我个人认为,呵呵,不知说得对不?
    顶一下,高手继续解答!
      

  16.   

    谢谢pf1685大哥的回答,但是我现在就是不知道YUV数据在OVERLAY或者OFF SCREEN表面上应该怎样放置.
    假设我的计算机颜色位数是16位,我的YUV数据为4:2:0,请问我应该按照怎样的顺序或者怎样的规则将我的YUV数据存放到我建立的表面上?Y,U,V三个分量的位置是怎么样的?
    谢谢,望高手点拔一下!
      

  17.   

    yuv格式在ddraw当中必须是overlay表面上才能直接显示,否则就要经过到rgb的转换才行能够直接显示yuv的必须是支持它的设备,内部或者显存当中的表面不行
      

  18.   

    目前的硬件都支持直接把YUV的数据直接blt到主表面,或者Overlay表面。支持的格式最起码有YUY2和UYVY。
    你只要看看显卡DDraw7的能力中有没有Blt FourCC一项就知道能不能这样做了。