Aric Stewart : quartz: Implement a Default Presenter in VMR9.
Alexandre Julliard
julliard at winehq.org
Tue May 22 14:21:28 CDT 2012
Module: wine
Branch: master
Commit: 38c31973d47c0711c1d32a71ab77fb1e906ac776
URL: http://source.winehq.org/git/wine.git/?a=commit;h=38c31973d47c0711c1d32a71ab77fb1e906ac776
Author: Aric Stewart <aric at codeweavers.com>
Date: Mon May 21 07:53:44 2012 -0500
quartz: Implement a Default Presenter in VMR9.
---
dlls/quartz/vmr9.c | 254 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 252 insertions(+), 2 deletions(-)
diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c
index 809ee0f..fc04269 100644
--- a/dlls/quartz/vmr9.c
+++ b/dlls/quartz/vmr9.c
@@ -123,6 +123,28 @@ static inline VMR9Impl *impl_from_IVMRSurfaceAllocatorNotify9( IVMRSurfaceAlloca
return CONTAINING_RECORD(iface, VMR9Impl, IVMRSurfaceAllocatorNotify9_iface);
}
+typedef struct
+{
+ IVMRImagePresenter9 IVMRImagePresenter9_iface;
+
+ LONG refCount;
+
+ IDirect3DDevice9 *d3d9_dev;
+ IDirect3D9 *d3d9_ptr;
+ IDirect3DVertexBuffer9 *d3d9_vertex;
+
+ VMR9AllocationInfo info;
+
+ VMR9Impl* pVMR9;
+} VMR9DefaultAllocatorPresenterImpl;
+
+static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRImagePresenter9( IVMRImagePresenter9 *iface)
+{
+ return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRImagePresenter9_iface);
+}
+
+static HRESULT VMR9DefaultAllocatorPresenterImpl_create(VMR9Impl *parent, LPVOID * ppv);
+
static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample)
{
VMR9Impl *This = (VMR9Impl *)iface;
@@ -886,10 +908,21 @@ static HRESULT WINAPI VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 *iface
{
case VMR9Mode_Windowed:
case VMR9Mode_Windowless:
- This->allocator = NULL;
- This->presenter = NULL;
This->allocator_is_ex = 0;
This->cookie = ~0;
+
+ hr = VMR9DefaultAllocatorPresenterImpl_create(This, (LPVOID*)&This->presenter);
+ if (SUCCEEDED(hr))
+ hr = IVMRImagePresenter9_QueryInterface(This->presenter, &IID_IVMRSurfaceAllocatorEx9, (LPVOID*)&This->allocator);
+ if (FAILED(hr))
+ {
+ ERR("Unable to find Presenter interface\n");
+ IVMRSurfaceAllocatorEx9_Release(This->presenter);
+ This->allocator = NULL;
+ This->presenter = NULL;
+ }
+ else
+ hr = IVMRSurfaceAllocator9_AdviseNotify(This->allocator, &This->IVMRSurfaceAllocatorNotify9_iface);
break;
case VMR9Mode_Renderless:
break;
@@ -1262,3 +1295,220 @@ fail:
CoTaskMemFree(pVMR9);
return hr;
}
+
+
+
+static HRESULT WINAPI VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID riid, LPVOID * ppv)
+{
+ VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+ TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
+
+ *ppv = NULL;
+
+ if (IsEqualIID(riid, &IID_IUnknown))
+ *ppv = (LPVOID)&(This->IVMRImagePresenter9_iface);
+ else if (IsEqualIID(riid, &IID_IVMRImagePresenter9))
+ *ppv = &This->IVMRImagePresenter9_iface;
+
+ if (*ppv)
+ {
+ IUnknown_AddRef((IUnknown *)(*ppv));
+ return S_OK;
+ }
+
+ FIXME("No interface for %s\n", debugstr_guid(riid));
+
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 *iface)
+{
+ VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+ ULONG refCount = InterlockedIncrement(&This->refCount);
+
+ TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
+
+ return refCount;
+}
+
+static ULONG WINAPI VMR9_ImagePresenter_Release(IVMRImagePresenter9 *iface)
+{
+ VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+ ULONG refCount = InterlockedDecrement(&This->refCount);
+
+ TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
+
+ if (!refCount)
+ {
+ TRACE("Destroying\n");
+ IUnknown_Release(This->d3d9_ptr);
+
+ if (This->d3d9_vertex)
+ {
+ IUnknown_Release(This->d3d9_vertex);
+ This->d3d9_vertex = NULL;
+ }
+ CoTaskMemFree(This);
+ return 0;
+ }
+ return refCount;
+}
+
+static HRESULT WINAPI VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
+{
+ VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+
+ TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
+ return S_OK;
+}
+
+static HRESULT WINAPI VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
+{
+ VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+
+ TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
+ return S_OK;
+}
+
+#define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
+struct VERTEX { float x, y, z, rhw, u, v; };
+
+static HRESULT VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
+{
+ IDirect3DTexture9 *texture = NULL;
+ HRESULT hr;
+
+ hr = IDirect3DDevice9_SetFVF(This->d3d9_dev, USED_FVF);
+ if (FAILED(hr))
+ {
+ FIXME("SetFVF: %08x\n", hr);
+ return hr;
+ }
+
+ hr = IDirect3DDevice9_SetStreamSource(This->d3d9_dev, 0, This->d3d9_vertex, 0, sizeof(struct VERTEX));
+ if (FAILED(hr))
+ {
+ FIXME("SetStreamSource: %08x\n", hr);
+ return hr;
+ }
+
+ hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **) &texture);
+ if (FAILED(hr))
+ {
+ FIXME("IDirect3DSurface9_GetContainer failed\n");
+ return hr;
+ }
+ hr = IDirect3DDevice9_SetTexture(This->d3d9_dev, 0, (IDirect3DBaseTexture9 *)texture);
+ IDirect3DTexture9_Release(texture);
+ if (FAILED(hr))
+ {
+ FIXME("SetTexture: %08x\n", hr);
+ return hr;
+ }
+
+ hr = IDirect3DDevice9_DrawPrimitive(This->d3d9_dev, D3DPT_TRIANGLESTRIP, 0, 2);
+ if (FAILED(hr))
+ {
+ FIXME("DrawPrimitive: %08x\n", hr);
+ return hr;
+ }
+
+ return S_OK;
+}
+
+static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR id, VMR9PresentationInfo *info)
+{
+ VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
+ HRESULT hr;
+ RECT output;
+ BOOL render = FALSE;
+
+ TRACE("(%p/%p/%p)->(...) stub\n", iface, This, This->pVMR9);
+ GetWindowRect(This->pVMR9->baseControlWindow.baseWindow.hWnd, &output);
+ TRACE("Output rectangle: starting at %dx%d, up to point %dx%d\n", output.left, output.top, output.right, output.bottom);
+
+ /* This might happen if we don't have active focus (eg on a different virtual desktop) */
+ if (!This->d3d9_dev)
+ return S_OK;
+
+ /* Display image here */
+ hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
+ if (FAILED(hr))
+ FIXME("hr: %08x\n", hr);
+ hr = IDirect3DDevice9_BeginScene(This->d3d9_dev);
+ if (SUCCEEDED(hr))
+ {
+ if (This->d3d9_vertex)
+ hr = VMR9_ImagePresenter_PresentTexture(This, info->lpSurf);
+ else
+ hr = E_NOTIMPL;
+ render = SUCCEEDED(hr);
+ }
+ else
+ FIXME("BeginScene: %08x\n", hr);
+ hr = IDirect3DDevice9_EndScene(This->d3d9_dev);
+ if (render && SUCCEEDED(hr))
+ {
+ hr = IDirect3DDevice9_Present(This->d3d9_dev, NULL, NULL, This->pVMR9->baseControlWindow.baseWindow.hWnd, NULL);
+ if (FAILED(hr))
+ FIXME("Presenting image: %08x\n", hr);
+ }
+
+ return S_OK;
+}
+
+static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter =
+{
+ VMR9_ImagePresenter_QueryInterface,
+ VMR9_ImagePresenter_AddRef,
+ VMR9_ImagePresenter_Release,
+ VMR9_ImagePresenter_StartPresenting,
+ VMR9_ImagePresenter_StopPresenting,
+ VMR9_ImagePresenter_PresentImage
+};
+
+static HRESULT VMR9DefaultAllocatorPresenterImpl_create(VMR9Impl *parent, LPVOID * ppv)
+{
+ HRESULT hr = S_OK;
+ int i;
+ VMR9DefaultAllocatorPresenterImpl* This;
+
+ This = CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl));
+ if (!This)
+ return E_OUTOFMEMORY;
+
+ This->d3d9_ptr = NULL;
+ if (!This->d3d9_ptr)
+ {
+ WARN("Could not initialize d3d9.dll\n");
+ CoTaskMemFree(This);
+ return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
+ }
+
+ i = 0;
+ do
+ {
+ D3DDISPLAYMODE mode;
+
+ hr = IDirect3D9_EnumAdapterModes(This->d3d9_ptr, i++, D3DFMT_X8R8G8B8, 0, &mode);
+ } while (FAILED(hr));
+ if (FAILED(hr))
+ ERR("HR: %08x\n", hr);
+ if (hr == D3DERR_NOTAVAILABLE)
+ {
+ ERR("Format not supported\n");
+ IUnknown_Release(This->d3d9_ptr);
+ CoTaskMemFree(This);
+ return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
+ }
+
+ This->IVMRImagePresenter9_iface.lpVtbl = &VMR9_ImagePresenter;
+
+ This->refCount = 1;
+ This->pVMR9 = parent;
+ This->d3d9_dev = NULL;
+ This->d3d9_vertex = NULL;
+
+ *ppv = This;
+ return S_OK;
+}
More information about the wine-cvs
mailing list