SDL在windows下使用 - 显示YUV

SDL在windows下使用 – YUV图片显示在窗口。

1. 从SDK官网下载windows下SDL运行库,链接http://www.libsdl.org/download-2.0.php,网页下面有Development Libraries -> windows,下载对应的库。

2. 导入SDL到工程项目(当前使用vs2015)。

#include "./SDL2-devel-2.0.4-VC/SDL2-2.0.4/include/SDL.h"
#include "./SDL2-devel-2.0.4-VC/SDL2-2.0.4/include/SDL_main.h"
#pragma comment(lib,"./SDL2-devel-2.0.4-VC/SDL2-2.0.4/lib/x86/SDL2.lib") 

3.使用步骤,以MFC窗口为例

BOOL SDL_init_all(CVideoTestDlg *pDlg, int width, int height);
void SDL_Show_Image(unsigned char* buffer, int width, int height, CVideoTestDlg *pDlg);

BOOL SDL_init_all(CVideoTestDlg *pDlg, int width, int height)
{
    if (SDL_Init(SDL_INIT_VIDEO))
    {
        return false;
    }

//  pSDL_Win = SDL_CreateWindow("Simplest Video", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
//      800, 600, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);  //win32创建窗口方式

    pSDL_Win = SDL_CreateWindowFrom((void *)(pDlg->GetDlgItem(IDC_STATIC)->GetSafeHwnd()));

    if (!pSDL_Win)
        return false;
    pSDL_Renderer = SDL_CreateRenderer(pSDL_Win, -1, 0);

    Uint32 pixformat = 0;

#if LOAD_BGRA  
    //Note: ARGB8888 in "Little Endian" system stores as B|G|R|A  
    pixformat = SDL_PIXELFORMAT_ARGB8888;
#elif LOAD_RGB24  
    pixformat = SDL_PIXELFORMAT_RGB888;
#elif LOAD_BGR24  
    pixformat = SDL_PIXELFORMAT_BGR888;
#elif LOAD_YUV420P  
    //IYUV: Y + U + V  (3 planes)  
    //YV12: Y + V + U  (3 planes)  
    pixformat = SDL_PIXELFORMAT_IYUV;
#endif  

    pSDL_Texture = SDL_CreateTexture(pSDL_Renderer, pixformat, SDL_TEXTUREACCESS_STREAMING, width, height);
    return true;
}
void SDL_Show_Image(unsigned char* buffer, int width, int height, CVideoTestDlg *pDlg)
{
    SDL_UpdateTexture(pSDL_Texture, NULL, buffer, width);

    CRect rt;   //获取当前显示控件的大小
    pDlg->GetDlgItem(IDC_STATIC)->GetWindowRect(&rt);

    SDL_Rect sdlrect;
    sdlrect.x = 0;
    sdlrect.y = 0;
    sdlrect.w = rt.Width();
    sdlrect.h = rt.Width() * height / width;  //匹配窗口大小
    SDL_RenderClear(pSDL_Renderer);
    SDL_RenderCopy(pSDL_Renderer, pSDL_Texture, NULL, &sdlrect);
    SDL_RenderPresent(pSDL_Renderer);

    delete[] buffer;   //由于传过来的buffer是new的空间,用完释放。
    buffer = NULL;
}

ps: SDL直接贴YUV,在窗口显示缩放的时候效果较好。而YUV->RGB再用GDI(StretchDIBits)贴图,在缩放的时候画面上会出现水纹,猜测应该是缩放像素的处理问题,暂时没解决。

//YUV转成RGB以后使用GDI贴图

VOID RGB_Render(uint8_t *pRGBBuffer, int width, int height, CVideoTestDlg *pDlg)
{
    if (pRGBBuffer == NULL)
        return;
    //构建BMP Header  
    BITMAPINFO m_bmphdr = { 0 };
    DWORD dwBmpHdr = sizeof(BITMAPINFO); //24bit  
    m_bmphdr.bmiHeader.biBitCount = 24;
    m_bmphdr.bmiHeader.biClrImportant = 0;
    m_bmphdr.bmiHeader.biSize = dwBmpHdr;
    m_bmphdr.bmiHeader.biSizeImage = 0;
    m_bmphdr.bmiHeader.biWidth = width; 
    m_bmphdr.bmiHeader.biHeight = -height; //bmp数据是从下往上存储的
    m_bmphdr.bmiHeader.biXPelsPerMeter = 0;
    m_bmphdr.bmiHeader.biYPelsPerMeter = 0;
    m_bmphdr.bmiHeader.biClrUsed = 0;
    m_bmphdr.bmiHeader.biPlanes = 1;
    m_bmphdr.bmiHeader.biCompression = BI_RGB;

    HDC hdc = pDlg->GetDC()->GetSafeHdc();
    CRect rt ;
    pDlg->GetDlgItem(IDC_STATIC)->GetWindowRect(&rt);  //获取窗口大小

    int nResult = StretchDIBits(hdc,
        0, 0,
//      rt.Width(), rt.Width() * height / width,  //匹配窗口缩小图片
        width, height, // 按原图大小显示
        0, 0,
        width, height,
        pRGBBuffer,
        &m_bmphdr,
        DIB_RGB_COLORS,
        SRCCOPY);

    HWND hwn = pDlg->GetSafeHwnd();
    ReleaseDC(hwn, hdc);

    delete[] pRGBBuffer;  //由于传进来的buffer是new的空间,所以处理完需要释放。
    pRGBBuffer = NULL;
}

下载库链接:http://download.csdn.net/download/alger_magic/9669834

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值