由于工作需要,最近在研究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);