EasyPlayer渲染引擎D3DRender實現視頻圖像高效率渲染解決方案(附源碼)

EasyPlayer播放器以其低延時播放RTSP、RTMP等流而聞名,而低延時播放除了低延時的拉流庫以及高編解碼效率外,視頻圖像的高速渲染也尤爲重要;

本篇以及系列文章主要講解EasyPlayer播放器的渲染引擎D3DRender,該渲染引擎支持基於GDI和D3D兩種渲染方式,GDI方式也是我們熟知的windows圖像繪製接口,普遍應用於win32以及MFC界面編程,以及圖形元素的繪製;但是由於使用純軟的windows系統api接口進行繪製,其效率通常比較低,而D3D可以啓用硬件加速,所以,通常其效率會比較高,下面我們將詳細講解D3DRende視頻圖像渲染流程。

1. D3DRender初始化

D3DRender庫分別爲GDI和D3D兩種渲染模式提供不同API接口進行渲染初始化,調用如下代碼段實現其初始化:

		//創建D3dRender
		if (pThread->renderFormat == GDI_FORMAT_RGB24)
		{
			if (NULL == pThread->d3dHandle)	RGB_InitDraw(&pThread->d3dHandle);
		}
		else if ( (NULL == pThread->d3dHandle) && ((unsigned int)time(NULL)-deviceLostTime >= 2) )
		{
			D3D_FONT	font;
			memset(&font, 0x00, sizeof(D3D_FONT));
			font.bold	=	0x00;
			wcscpy(font.name, TEXT("Arial Black"));

			font.size	=	(int)(float)((width)*0.2f);// 32;
			if (pThread->showOSD)
			{
				font.size	=	pThread->osd.size;// 32;
			}
			font.width	=	(int)(float)((font.size)/2.5f);//13;
			if (NULL!=pThread->hWnd && (IsWindow(pThread->hWnd)) )
			{
				D3D_Initial(&pThread->d3dHandle, pThread->hWnd, width, height, 0, 1, pThread->renderFormat, &font);
		}

注意D3D_Initial初始化D3D渲染模式需要設置OSD疊加的相關參數,如OSD疊加文字的字體、大小等參數,OSD疊加詳細講解將在後續的文章中進行講解,本文不做過多贅述。

2. D3DRender渲染一幀視頻圖像

D3DRender渲染圖像支持多種圖像色彩格式,具體如下枚舉結構體所示:

//目前支持的格式
typedef enum
{
	D3D_FORMAT_YUY2		=	MAKEFOURCC('Y','U','Y','2'),	//844715353			-->decode output format:	PIX_FMT_YUYV422		1
	D3D_FORMAT_YV12		=	MAKEFOURCC('Y','V','1','2'),	//842094169
	D3D_FORMAT_UYVY		=	MAKEFOURCC('U', 'Y', 'V', 'Y'),	//1498831189		-->decode output format:	PIX_FMT_UYVY422		17
	D3D_FORMAT_A8R8G8B8	=	21,								//					-->decode output format:	PIX_FMT_BGRA		30
	D3D_FORMAT_X8R8G8B8	=	22,								//					-->decode output format:	PIX_FMT_BGRA		30
	D3D_FORMAT_RGB565	=	23,								//					-->decode output format:	PIX_FMT_RGB565LE	44
	D3D_FORMAT_RGB555	=	25,								//					-->decode output format:	PIX_FMT_RGB555LE	46

	GDI_FORMAT_RGB24,
}D3D_SUPPORT_FORMAT;

其中指定色彩格式RGB24爲GDI渲染,其他色彩格式均爲D3D渲染方式,具體視頻圖像渲染調用如下:

			if (pThread->renderFormat == GDI_FORMAT_RGB24)
			{
				RGB_DrawData(pThread->d3dHandle, pThread->hWnd, pThread->yuvFrame[iDispalyYuvIdx].pYuvBuf, width, height, &rcSrc, pThread->ShownToScale, RGB(0x3c,0x3c,0x3c), 0, osdLines, osd);
			}
			else if (NULL != pThread->d3dHandle)
			{

				D3D_UpdateData(pThread->d3dHandle, 0, (unsigned char*)pThread->yuvFrame[iDispalyYuvIdx].pYuvBuf, width, height, &rcSrc, NULL, osdLines, osd);
				ret = D3D_Render(pThread->d3dHandle, pThread->hWnd, pThread->ShownToScale, &rcDst);
				if (ret < 0)
				{
					deviceLostTime = (unsigned int)time(NULL);
					pThread->resetD3d = true;						//需要重建D3D
				}
			}

如上代碼段所示,GDI模式通過RGB_DrawData函數進行渲染,D3D模式通過D3D_UpdateData進行渲染,只需要傳入YUV或者RGB數據緩衝區以及視頻圖像長寬即可,如果需要疊加OSD文字信息,則填充osd信息即可,這在後續的系列文章中會講到。

3. D3DRender關閉渲染

當渲染流程走完後,我們需要關掉D3DRender渲染引擎,調用關閉渲染接口接口接口實現,如下代碼所示:

	if (pThread->renderFormat == GDI_FORMAT_RGB24)
	{
		RGB_DeinitDraw(&pThread->d3dHandle);
	}
	else
	{
		D3D_Release(&pThread->d3dHandle);
	}

歡迎大家下載EasyPlayer播放器源碼:
https://github.com/EasyDSS/EasyPlayer-RTMP-Win
https://github.com/EasyDSS/EasyPlayerPro-Win

有任何技術問題,歡迎大家和我進行技術交流:
[email protected]

大家也可以加入EasyPlayer流媒體播放器 QQ羣進行討論:
544917793

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章