兄弟我正在做个视频处理软件,把DVD上的视频解码,然后叠加文字,然后在以Mpeg2压缩。我的做法是mpeg2 dec(YUV420)-〉RGB24->图像处理(RGB24)->YUV420->mpeg2 enc(YUV420).
   现在我想把图像处理后的RGB24格式转换成YUV420来压缩,但一直不成功,忘哪位朋友能给我一份windows下RGB24(RGB24even,RGB24odd)转YUV420的vc代码。非常感谢!
   Email: [email protected]

解决方案 »

  1.   

    直接那样转效率很底,我想速度快一点.我也可以将RGB24转到YUV2,但怎么从YUV2得到YUV420分离量,望指教.
      

  2.   

    BOOL 
    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的转化。
      

  3.   

    楼上的朋友,我怎么没有看出来你的代码有rgb32->yuv420的转换啊,你直接将yuv420仍给directX了,让显卡作转换了
      

  4.   

    确实如你所说。if(lpSurf)部分是将YUV数据填充到表面,只是给你参考一下,至于RGB-》YUV,是一个逆过程。
      

  5.   

    参考一下:
    #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 } 
      

  6.   

    http://dev.openwengo.com/trac/openwengo/trac.cgi/browser/softphone/branches/video/ffmpeg/vhook/drawtext.c?rev=404