您当前的位置: 首页 > 

qianbo_insist

暂无认证

  • 0浏览

    0关注

    399博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

播放视频中称比例的计算

qianbo_insist 发布时间:2022-02-26 21:41:26 ,浏览量:0

使用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);
}
关注
打赏
1663161521
查看更多评论
立即登录/注册

微信扫码登录

0.1580s