由于工作需要,最近在研究YUV420P格式的视频的渲染,决定采用vlc的渲染机制进行,这里记录d3d的流程
大的流程如下:
打开和关闭定义:
static int Open(vlc_object_t *); static void Close(vlc_object_t *);
设置完之后可以调用:
set_callbacks(Open, Close)
其他函数在vout_display_t函数指针设置如下:
vd->pool = Pool; vd->prepare = Prepare; vd->display = Display; vd->control = Control; vd->manage = Manage;
--------------------********Open部分**************-------------------------------
1、加载d3d9库
sys->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL"));
2、得到Direct3D9函数指针
OurDirect3DCreate9 = (LPDIRECT3D9 (__stdcall *)(UINT))GetProcAddress(sys->hd3d9_dll, "Direct3DCreate9");
3、创建Direct3D9对象
LPDIRECT3D9 d3dobj = OurDirect3DCreate9(D3D_SDK_VERSION);4、检测设备是否支持HAL设备(HAL需要的是硬件支持,速度快)
HRESULT hr = IDirect3D9_GetDeviceCaps(d3dobj, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &sys->d3dcaps);
5、测试设备能力,选择正确的渲染函数
if (!(sys->d3dcaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) || !(sys->d3dcaps.TextureFilterCaps & (D3DPTFILTERCAPS_MAGFLINEAR)) || !(sys->d3dcaps.TextureFilterCaps & (D3DPTFILTERCAPS_MINFLINEAR))) { msg_Err(vd, "Device does not support stretching from textures."); return VLC_EGENERIC; }
6、获取显示模式
D3DDISPLAYMODE d3ddm; HRESULT hr = IDirect3D9_GetAdapterDisplayMode(sys->d3dobj, D3DADAPTER_DEFAULT, &d3ddm);
7、获取适配器描述
IDirect3D9_GetAdapterIdentifier(d3dobj,AdapterToUse,0, &d3dai)
8、创建一个设备
HRESULT hr = IDirect3D9_CreateDevice(d3dobj, AdapterToUse, DeviceType, sys->hvideownd, D3DCREATE_SOFTWARE_VERTEXPROCESSING| D3DCREATE_MULTITHREADED, &sys->d3dpp, &d3ddev);
9、检测设备支持格式
hr = IDirect3D9_CheckDeviceFormat(d3dobj, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, dst, 0, D3DRTYPE_SURFACE, src);
hr = IDirect3D9_CheckDeviceFormatConversion(d3dobj, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, src, dst);
10、创建一个Surface(离屏表面。所谓的“离屏”指的是永远不在屏幕上显示)
LPDIRECT3DSURFACE9 surface; HRESULT hr = IDirect3DDevice9_CreateOffscreenPlainSurface(d3ddev, fmt->i_width, fmt->i_height, d3dfmt->format, D3DPOOL_DEFAULT, &surface, NULL);
11、填充黑色
IDirect3DDevice9_ColorFill(d3ddev, surface, NULL, D3DCOLOR_ARGB(0xFF, 0, 0, 0));
12、创建纹理
LPDIRECT3DTEXTURE9 d3dtex; hr = IDirect3DDevice9_CreateTexture(d3ddev, fmt->i_width, fmt->i_height, 1, D3DUSAGE_RENDERTARGET, sys->d3dpp.BackBufferFormat, D3DPOOL_DEFAULT, &d3dtex, NULL);
13、创建缓存
LPDIRECT3DVERTEXBUFFER9 d3dvtc; hr = IDirect3DDevice9_CreateVertexBuffer(d3ddev, sizeof(CUSTOMVERTEX)*4, D3DUSAGE_DYNAMIC|D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &d3dvtc, NULL);
14、设置纹理采样属性
// Texture coordinates outside the range [0.0, 1.0] are set // to the texture color at 0.0 or 1.0, respectively. IDirect3DDevice9_SetSamplerState(d3ddev, 0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); IDirect3DDevice9_SetSamplerState(d3ddev, 0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); // Set linear filtering quality if (sys->d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MINFLINEAR) { msg_Dbg(vd, "Using D3DTEXF_LINEAR for minification"); IDirect3DDevice9_SetSamplerState(d3ddev, 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); } else { msg_Dbg(vd, "Using D3DTEXF_POINT for minification"); IDirect3DDevice9_SetSamplerState(d3ddev, 0, D3DSAMP_MINFILTER, D3DTEXF_POINT); } if (sys->d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFLINEAR) { msg_Dbg(vd, "Using D3DTEXF_LINEAR for magnification"); IDirect3DDevice9_SetSamplerState(d3ddev, 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); } else { msg_Dbg(vd, "Using D3DTEXF_POINT for magnification"); IDirect3DDevice9_SetSamplerState(d3ddev, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); } // set maximum ambient light IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_AMBIENT, D3DCOLOR_XRGB(255,255,255)); // Turn off culling IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_CULLMODE, D3DCULL_NONE); // Turn off the zbuffer IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ZENABLE, D3DZB_FALSE); // Turn off lights IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_LIGHTING, FALSE); // Enable dithering IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_DITHERENABLE, TRUE); // disable stencil IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_STENCILENABLE, FALSE); // manage blending IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHABLENDENABLE, FALSE); IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); if (sys->d3dcaps.AlphaCmpCaps & D3DPCMPCAPS_GREATER) { IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHATESTENABLE,TRUE); IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHAREF, 0x00); IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHAFUNC,D3DCMP_GREATER); } // Set texture states IDirect3DDevice9_SetTextureStageState(d3ddev, 0, D3DTSS_COLOROP,D3DTOP_SELECTARG1); IDirect3DDevice9_SetTextureStageState(d3ddev, 0, D3DTSS_COLORARG1,D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); IDirect3DDevice9_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAARG1,D3DTA_TEXTURE); IDirect3DDevice9_SetTextureStageState(d3ddev, 0, D3DTSS_ALPHAARG2,D3DTA_DIFFUSE);--------------------********Prepare部分**************-------------------------------
1、释放锁定surface
HRESULT hr = IDirect3DSurface9_UnlockRect(picture->p_sys->surface);
2、测试设备是否可用
HRESULT hr = IDirect3DDevice9_TestCooperativeLevel(sys->d3ddev);
3、得到surface级别
hr = IDirect3DTexture9_GetSurfaceLevel(sys->d3dtex, 0, &destination);
4、拷贝图像到渲染surface
hr = IDirect3DDevice9_StretchRect(sys->d3ddev, source, NULL, destination, NULL, D3DTEXF_LINEAR);
5、IDirect3DDevice9_Clear
hr = IDirect3DDevice9_Clear(d3ddev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
6、IDirect3DDevice9_BeginScene
hr = IDirect3DDevice9_BeginScene(d3ddev);
7、IDirect3DVertexBuffer9_Lock
hr = IDirect3DVertexBuffer9_Lock(d3dvtc, 0, 0, &vertex, D3DLOCK_DISCARD);
8、IDirect3DVertexBuffer9_Unlock
hr = IDirect3DVertexBuffer9_Unlock(d3dvtc);
9、IDirect3DDevice9_SetTexture
hr = IDirect3DDevice9_SetTexture(d3ddev, 0, (LPDIRECT3DBASETEXTURE9)d3dtex);
10、IDirect3DDevice9_SetStreamSource
hr = IDirect3DDevice9_SetStreamSource(d3ddev, 0, d3dvtc, 0, sizeof(CUSTOMVERTEX));
11、IDirect3DDevice9_SetFVF
hr = IDirect3DDevice9_SetFVF(d3ddev, D3DFVF_CUSTOMVERTEX);
12、IDirect3DDevice9_DrawPrimitive
hr = IDirect3DDevice9_DrawPrimitive(d3ddev, D3DPT_TRIANGLEFAN, 0, 2);
13、IDirect3DDevice9_SetRenderState
IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHABLENDENABLE, TRUE);
14、IDirect3DDevice9_SetRenderState
IDirect3DDevice9_SetRenderState(d3ddev, D3DRS_ALPHABLENDENABLE, FALSE);
15、IDirect3DDevice9_EndScene
hr = IDirect3DDevice9_EndScene(d3ddev);
16、释放
IDirect3DSurface9_Release(destination);
--------------------********Display部分**************-------------------------------
1、后台缓存内容渲染出来
HRESULT hr = IDirect3DDevice9_Present(d3ddev, &src, &dst, NULL, NULL);
2、锁定surface以获得指向图片缓冲区的有效指针
D3DLOCKED_RECT d3drect; HRESULT hr = IDirect3DSurface9_LockRect(picture->p_sys->surface, &d3drect, NULL, 0);