SkeyePlayer播放器以其低延时播放RTSP、RTMP等流而闻名,而低延时播放除了低延时的拉流库以及高编解码效率外,视频图像的高速渲染也尤为重要;
本篇以及系列文章次要解说SkeyePlayer播放器的渲染引擎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); }