SDL 显示 内存中的JPG图片

本文介绍了一个基于SDL库的视频渲染类CVideoRender的实现细节,包括窗口创建、纹理处理及图像渲染等关键步骤。
#ifndef __XH_VIDEORENDERIMP_H
#define __XH_VIDEORENDERIMP_H
#include <SDL.h>
#include <map>
#include <mutex>
#include "SDL_image.h"
#pragma comment(lib,"SDL2.lib")
#pragma comment(lib,"SDL2_image.lib")
/*
#pragma comment(lib,"SDL2main.lib")
#pragma comment(lib,"SDL2.lib")
*/
struct ST_AvDecFrameInfo
{
 unsigned char * pVideoBuffer;
 int             iLineSize;
 int             iWidth;
 int             iHeight;
};

#if 1
class CVideoRender
{
public:
    CVideoRender();
    ~CVideoRender();
public:
    int SetPlayWin(void *hPlay);
    int StartRender();
    int StopRender();
 int RenderImg(char *pJpgData, int nSize);

public:
 static int add_window(void *_sdl_window,void *windows);
 static void * find_sdl_windows(void *_windows);
 static std::map<void *,void *> m_map_sdl_windows;
 static std::mutex   m_vist_windows_map_mutex;
 std::mutex      m_vist_render_mutex;
private:
    void *m_hplayer;
    SDL_Window *m_pWindow;
    SDL_Renderer *m_pRender;
    SDL_Texture *m_pTexture;
    SDL_Rect dstRT;
};
#endif
#endif // __XH_VIDEORENDERIMP_H

cpp 文件

#include "stdafx.h"
#include "VideoRender.h"

#if 1
std::map<void *,void *> CVideoRender::m_map_sdl_windows;
std::mutex CVideoRender::m_vist_windows_map_mutex;
CVideoRender::CVideoRender()
{
 
 SDL_Init(SDL_INIT_VIDEO);
    m_hplayer = NULL;
    m_pWindow = NULL;
    m_pRender = NULL;
    m_pTexture = NULL;
 
}
CVideoRender::~CVideoRender()
{
}
int CVideoRender::SetPlayWin(void *hPlay)
{
 
    m_hplayer = hPlay;
 return 0;
}
int CVideoRender::StartRender()
{

//  RECT rect;
//  GetWindowRect((HWND)m_hplayer,&rect);
//  m_pWindow = SDL_CreateWindow("",rect.left,rect.top,rect.right - rect.left,rect.bottom - rect.top,SDL_WINDOW_OPENGL);
 std::lock_guard<std::mutex> lock(m_vist_render_mutex);
 m_pWindow = (SDL_Window *)find_sdl_windows(m_hplayer);
 if (m_pWindow == NULL)
 {
  m_pWindow = SDL_CreateWindowFrom(m_hplayer);
//   m_pWindow = SDL_CreateWindow("linuxplayer",
//    SDL_WINDOWPOS_UNDEFINED,
//    SDL_WINDOWPOS_UNDEFINED,
//    1280,                               // width, in pixels
//    720,
//    SDL_WINDOW_OPENGL
//    );

  if (m_pWindow)
  {
   add_window((void *)m_pWindow,m_hplayer);
  }
 }
 if (m_pWindow == NULL)
 {
  return false;
 }
     printf("SDL_CreateWindowFrom suc!\r\n");
//   int iW = nwidth;
//   int iH = nheight;
//     int iWidth = 0;
//     int iHeight = 0;
//     SDL_GetWindowSize( m_pWindow, &iWidth, &iHeight );
//     dstRT.h = iHeight;
//     dstRT.w = iWidth;
//     dstRT.x = 0;
//     dstRT.y = 0;
    //获取当前可用画图驱动 window中有3个,第一个为d3d,第二个为opengl,第三个为software
      int iii = SDL_GetNumRenderDrivers();
      printf("renderdrivers=%d\r\n",iii);
    //创建渲染器,第二个参数为选用的画图驱动,0代表d3d
     printf("SDL_CreateRenderer!\r\n");
   // m_pRender = SDL_CreateRenderer( m_pWindow, -1, SDL_RENDERER_ACCELERATED);zcj
 m_pRender = SDL_CreateRenderer(m_pWindow, -1, 0);
 SDL_RendererInfo info; 
 SDL_GetRendererInfo(m_pRender, &info); 
 SDL_GetRenderDriverInfo(0, &info);    //d3d 
 SDL_GetRenderDriverInfo(1, &info);    //opgl 
 SDL_GetRenderDriverInfo(2, &info);    //opgles
 SDL_GetRenderDriverInfo(3, &info);
    printf("SDL_CreateRenderer suc!\r\n");
#if 0
 //SDL_PIXELFORMAT_ARGB8888,
 //SDL_TEXTUREACCESS_STREAMING,
 m_pTexture = SDL_CreateTexture(m_pRender,/*SDL_PIXELFORMAT_YV12*/ /*SDL_PIXELFORMAT_IYUV*/SDL_PIXELFORMAT_ARGB8888\
  , SDL_TEXTUREMODULATE_COLOR, iW, iH);
    printf("SDL_CreateTexture suc!\r\n");
#endif
 return 0;
}
int CVideoRender::StopRender()
{

 std::lock_guard<std::mutex> lock(m_vist_render_mutex);
    if(m_pTexture)
    {
        SDL_DestroyTexture(m_pTexture);
        m_pTexture = NULL;
    }
    if(m_pRender)
    {
        SDL_DestroyRenderer(m_pRender);
        m_pRender = NULL;
    }
//  if(m_pWindow)
//  {
//   SDL_DestroyWindow(m_pWindow);
//   m_pWindow = NULL;
//  }

 return 0;
}
SDL_Surface *load_image(char *filename)
{
 if (filename == NULL) {
  return NULL;
 }
 char *tmp = strstr(filename, ".");
 if (tmp == NULL) {
  return NULL;
 }
 tmp++;
//     /* 将图象暂时存储在这里 */
 SDL_Surface *loadedImage;
//     /* 存储最佳的图象 */
 SDL_Surface* optimizedImage = NULL;
 loadedImage = IMG_Load(filename);
 /*
 if (loadedImage != NULL) {
  //建立最佳的图象
  optimizedImage = SDL_DisplayFormat(loadedImage);
  //释放老的图象
  SDL_FreeSurface(loadedImage);
 }
 */
 optimizedImage = loadedImage;
 return optimizedImage;
}

int CVideoRender::RenderImg(char *pJpgData,int nSize)
{
 std::lock_guard<std::mutex> lock(m_vist_render_mutex);
 if (NULL == pJpgData)
 {
  return FALSE;
 }
 //SDL_Surface *pSurface  = load_image("c:\\1.jpg");
 SDL_RWops * src;
 SDL_Surface *pImageSurface;
 //SDL_RWFromConstMem  //SDL_RWFromMem
 src = SDL_RWFromConstMem(pJpgData, nSize);
// /* 将BMP文件加载到一个surface*/    
 pImageSurface = IMG_Load_RW(src, 1);
 if(pImageSurface == NULL)
 {
  return FALSE;
 }
 if (NULL != m_pTexture)
 {
  SDL_DestroyTexture(m_pTexture);
  m_pTexture = NULL;
 }
 m_pTexture = SDL_CreateTextureFromSurface(m_pRender, pImageSurface);
 SDL_FreeSurface(pImageSurface);
 if (NULL == m_pTexture)
 {
  return FALSE;
 }
 ////
 int iWidth = 0;
 int iHeight = 0;
 SDL_GetWindowSize( m_pWindow, &iWidth, &iHeight );
 dstRT.h = iHeight;
 dstRT.w = iWidth;
 dstRT.x = 0;
 dstRT.y = 0;
    SDL_Rect sdlRT;
  
 sdlRT.w = pImageSurface->w;
 sdlRT.h = pImageSurface->h;
    sdlRT.x = 0;
    sdlRT.y = 0;
   
    SDL_RenderClear( m_pRender );
    SDL_RenderCopy( m_pRender, m_pTexture, &sdlRT, &dstRT );
    SDL_RenderPresent( m_pRender );
 SDL_DestroyTexture(m_pTexture);
 m_pTexture = NULL;
 return 0;
}
int CVideoRender::add_window( void *_sdl_window,void *windows )
{
 
 std::lock_guard<std::mutex> lock(m_vist_windows_map_mutex);
 if (m_map_sdl_windows[windows] == NULL)
 {
  m_map_sdl_windows[windows] = _sdl_window;
  return 0;
 }
//  std::map<void *,void *>::iterator iter = m_map_sdl_windows.find(windows);
//  if (iter == m_map_sdl_windows.end())
//  {
//   m_map_sdl_windows[windows] = _sdl_window;
//   return DMS_ERROR_SUCCESS;
//  }
 return 1;
}
void * CVideoRender::find_sdl_windows( void *_windows )
{
 
 std::lock_guard<std::mutex> lock(m_vist_windows_map_mutex);
 return m_map_sdl_windows[_windows];
 
}
#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wumingqilin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值