使用sdl来播放
使用sdl来播放,封装
class SDLPlayer
{
private:
SDL_Renderer * _pRender = NULL;
SDL_Texture* _pTexture = NULL;
int _pixelW = 0;
int _pixelH = 0;
int _iPitch = 0;
SDL_Rect _sdlRect;
SDL_Window * _pWindow = NULL;
int _DrawMode = SDL_PIXELFORMAT_IYUV;
void Calculate(int cx, int cy, int &retx, int &rety);
public:
static void Init()
{
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_EVENTS) == -1)
{
fprintf(stderr, "SDL_Init() %s\n", SDL_GetError());
exit(-1);
}
}
static void UnInit()
{
SDL_Quit();
}
SDLPlayer();
~SDLPlayer();
//准备内存画布
int Prepare(HWND hWnd, int pixelW, int pixelH, uint32_t mode = SDL_PIXELFORMAT_IYUV);
void Draw(uint8_t *buffer,int len);
void unPrepare();
};
画面的比例问题
如果画面和实际窗口不成比例,有时候拉伸会很难看,所以可以使用计算来画出画面,下面给出计算方法:
//cx,cy原始大小,retx,rety调整后的大小
void SDLPlayer::Calculate(int cx, int cy, int &retx, int &rety)
{
double rate = (float)_pixelW / _pixelH;
if (cx >= _pixelW) //宽度大于实际像素
{
if (cy > _pixelH) //同时高度大于实际像素
{
//取宽度,截取高度
retx = cx;
rety = cx / rate;
}
else //但是高度小于实际像素
{
//取全部高度,截取宽度
rety = cy;
retx = cy * rate;
}
}
else //宽度小于实际像素
{
if (cy > _pixelH) //同时高度大于实际像素
{
//取宽度,截取高度
retx = cx;
rety = cx / rate;
}
else //高度也小于实际像素
{
//取
rety = cy;
retx = cy * rate;
}
}
float f1 = (float)cx / (float)cy;
float f2 = (float)_pixelW / (float)_pixelH;
if (f1 > f2) //实际画布比例 较为宽
{
rety = cy;
retx = cy * rate;
}
else //实际画布比例 较为z
{
retx = cx;
if (cx / rate > cy)
{
rety = cy;
retx = cy * rate;
}
else{
rety = cx / rate;
}
}
}
这样展示画面时画面比较正常,不会拉伸,下面是cpp文件,仅仅供参考。
#include "SDLPlayer.h"
SDLPlayer::SDLPlayer()
{
//_hWnd = NULL;
}
SDLPlayer::~SDLPlayer()
{
}
int SDLPlayer::Prepare(HWND hWnd, int pixelW, int pixelH, uint32_t mode)
{
if (hWnd == NULL)
return -1;
_pWindow = SDL_CreateWindowFrom(hWnd);
if (!_pWindow) return -1;
int windowx;
int windowy;
SDL_GetWindowSize(_pWindow, &windowx, &windowy);
_sdlRect.x = 0;
_sdlRect.y = 0;
_sdlRect.w = windowx;
_sdlRect.h = windowy;
_pRender = SDL_CreateRenderer(_pWindow, 0, SDL_RENDERER_ACCELERATED);
_pixelW = pixelW;
_pixelH = pixelH;
_DrawMode = mode;
// _DrawMode = SDL_PIXELFORMAT_BGR24;
//else
// _DrawMode = SDL_PIXELFORMAT_IYUV;
_pTexture = SDL_CreateTexture(_pRender,
_DrawMode,
SDL_TEXTUREACCESS_STREAMING,
pixelW,
pixelH);
if (_pTexture == NULL)
return -1;
_iPitch = pixelW *SDL_BYTESPERPIXEL(_DrawMode);
return 0;
}
//cx,cy原始大小,retx,rety调整后的大小
void SDLPlayer::Calculate(int cx, int cy, int &retx, int &rety)
{
double rate = (float)_pixelW / _pixelH;
if (cx >= _pixelW) //宽度大于实际像素
{
if (cy > _pixelH) //同时高度大于实际像素
{
//取宽度,截取高度
retx = cx;
rety = cx / rate;
}
else //但是高度小于实际像素
{
//取全部高度,截取宽度
rety = cy;
retx = cy * rate;
}
}
else //宽度小于实际像素
{
if (cy > _pixelH) //同时高度大于实际像素
{
//取宽度,截取高度
retx = cx;
rety = cx / rate;
}
else //高度也小于实际像素
{
//取
rety = cy;
retx = cy * rate;
}
}
float f1 = (float)cx / (float)cy;
float f2 = (float)_pixelW / (float)_pixelH;
if (f1 > f2) //实际画布比例 较为宽
{
rety = cy;
retx = cy * rate;
}
else //实际画布比例 较为z
{
retx = cx;
if (cx / rate > cy)
{
rety = cy;
retx = cy * rate;
}
else{
rety = cx / rate;
}
}
}
void SDLPlayer::Draw(uint8_t *buffer,int len)
{
#if 0
SDL_Event event;
SDL_bool done = SDL_FALSE;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_WINDOWEVENT:
if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
//_sdlRect.w = event.window.data1;
//_sdlRect.h = event.window.data2;
//SDL_RenderSetViewport(_pRender, &_sdlRect);
SDL_GetWindowSize(_pWindow, &_w, &_h);
_sdlRect.x = 1;
_sdlRect.y = 1;
_sdlRect.w = _w-2;
_sdlRect.h = _h -2;
}
break;
case SDL_KEYDOWN:
if (event.key.keysym.sym == SDLK_ESCAPE) {
done = SDL_TRUE;
}
break;
case SDL_QUIT:
done = SDL_TRUE;
break;
}
//SDL_Delay(1);
}
#endif
#if 1
int w, h;
SDL_GetWindowSize(_pWindow, &w, &h);
if (w!= _sdlRect.w || h!= _sdlRect.h)
{
Calculate(w, h, _sdlRect.w, _sdlRect.h);
_sdlRect.x =abs(w- _sdlRect.w)/ 2;
_sdlRect.y =abs(h- _sdlRect.h)/ 2;
/*_sdlRect.w = w-2;
_sdlRect.h = h-2;
_sdlRect.x = 1;
_sdlRect.y = 1;*/
}
#endif
SDL_UpdateTexture(_pTexture, NULL, buffer, _iPitch);
SDL_RenderClear(_pRender);
if (_DrawMode == SDL_PIXELFORMAT_IYUV)
SDL_RenderCopy(_pRender, _pTexture, NULL, &_sdlRect);
else if(_DrawMode == SDL_PIXELFORMAT_BGR24)
SDL_RenderCopyEx(_pRender, _pTexture, NULL, &_sdlRect, 0, 0, SDL_FLIP_VERTICAL);
SDL_RenderPresent(_pRender);
}
void SDLPlayer::unPrepare()
{
if (_pWindow)
{
SDL_DestroyWindow(_pWindow);
//SDL_ShowWindow(_pWindow);
//if (_hWnd!=NULL)
// ShowWindow(_hWnd, 1);
_pWindow = NULL;
}
if (_pRender)
SDL_DestroyRenderer(_pRender);
if (_pTexture)
SDL_DestroyTexture(_pTexture);
}