iphlpapi: Remove unnecessary memcpy from build_udp6_table.
[wine.git] / dlls / quartz / vmr9.c
blobbd92416e492f5ac2fa7a3ad300e090b2521ed00b
1 /*
2 * Video Mixing Renderer for dx9
4 * Copyright 2004 Christian Costa
5 * Copyright 2008 Maarten Lankhorst
6 * Copyright 2012 Aric Stewart
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "quartz_private.h"
25 #include "uuids.h"
26 #include "vfwmsgs.h"
27 #include "amvideo.h"
28 #include "windef.h"
29 #include "winbase.h"
30 #include "dshow.h"
31 #include "evcode.h"
32 #include "strmif.h"
33 #include "ddraw.h"
34 #include "dvdmedia.h"
35 #include "d3d9.h"
36 #include "vmr9.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
42 struct quartz_vmr
44 struct strmbase_renderer renderer;
45 BaseControlWindow baseControlWindow;
46 BaseControlVideo baseControlVideo;
48 IAMCertifiedOutputProtection IAMCertifiedOutputProtection_iface;
49 IAMFilterMiscFlags IAMFilterMiscFlags_iface;
50 IVMRFilterConfig IVMRFilterConfig_iface;
51 IVMRFilterConfig9 IVMRFilterConfig9_iface;
52 IVMRMonitorConfig IVMRMonitorConfig_iface;
53 IVMRMonitorConfig9 IVMRMonitorConfig9_iface;
54 IVMRSurfaceAllocatorNotify IVMRSurfaceAllocatorNotify_iface;
55 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface;
56 IVMRWindowlessControl IVMRWindowlessControl_iface;
57 IVMRWindowlessControl9 IVMRWindowlessControl9_iface;
59 IOverlay IOverlay_iface;
61 IVMRSurfaceAllocatorEx9 *allocator;
62 IVMRImagePresenter9 *presenter;
63 BOOL allocator_is_ex;
66 * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed
67 * What I do is implement windowless as a special case of renderless, and then
68 * windowed also as a special case of windowless. This is probably the easiest way.
70 VMR9Mode mode;
71 BITMAPINFOHEADER bmiheader;
73 HMODULE hD3d9;
75 /* Presentation related members */
76 IDirect3DDevice9 *allocator_d3d9_dev;
77 HMONITOR allocator_mon;
78 DWORD num_surfaces;
79 DWORD cur_surface;
80 DWORD_PTR cookie;
82 /* for Windowless Mode */
83 HWND hWndClippingWindow;
85 RECT source_rect;
86 RECT target_rect;
87 LONG VideoWidth;
88 LONG VideoHeight;
90 HANDLE run_event;
93 static inline struct quartz_vmr *impl_from_BaseWindow(BaseWindow *wnd)
95 return CONTAINING_RECORD(wnd, struct quartz_vmr, baseControlWindow.baseWindow);
98 static inline struct quartz_vmr *impl_from_BaseControlVideo(BaseControlVideo *cvid)
100 return CONTAINING_RECORD(cvid, struct quartz_vmr, baseControlVideo);
103 static inline struct quartz_vmr *impl_from_IAMCertifiedOutputProtection(IAMCertifiedOutputProtection *iface)
105 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMCertifiedOutputProtection_iface);
108 static inline struct quartz_vmr *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
110 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMFilterMiscFlags_iface);
113 static inline struct quartz_vmr *impl_from_IVMRFilterConfig(IVMRFilterConfig *iface)
115 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig_iface);
118 static inline struct quartz_vmr *impl_from_IVMRFilterConfig9(IVMRFilterConfig9 *iface)
120 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig9_iface);
123 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig(IVMRMonitorConfig *iface)
125 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig_iface);
128 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig9(IVMRMonitorConfig9 *iface)
130 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig9_iface);
133 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify(IVMRSurfaceAllocatorNotify *iface)
135 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify_iface);
138 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify9(IVMRSurfaceAllocatorNotify9 *iface)
140 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify9_iface);
143 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl(IVMRWindowlessControl *iface)
145 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl_iface);
148 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl9(IVMRWindowlessControl9 *iface)
150 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl9_iface);
153 typedef struct
155 IVMRImagePresenter9 IVMRImagePresenter9_iface;
156 IVMRSurfaceAllocatorEx9 IVMRSurfaceAllocatorEx9_iface;
158 LONG refCount;
160 IDirect3DDevice9 *d3d9_dev;
161 IDirect3D9 *d3d9_ptr;
162 IDirect3DSurface9 **d3d9_surfaces;
163 IDirect3DVertexBuffer9 *d3d9_vertex;
164 HMONITOR hMon;
165 DWORD num_surfaces;
167 BOOL reset;
168 VMR9AllocationInfo info;
170 struct quartz_vmr* pVMR9;
171 IVMRSurfaceAllocatorNotify9 *SurfaceAllocatorNotify;
172 } VMR9DefaultAllocatorPresenterImpl;
174 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRImagePresenter9( IVMRImagePresenter9 *iface)
176 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRImagePresenter9_iface);
179 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRSurfaceAllocatorEx9( IVMRSurfaceAllocatorEx9 *iface)
181 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRSurfaceAllocatorEx9_iface);
184 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv);
186 static inline struct quartz_vmr *impl_from_IBaseFilter(IBaseFilter *iface)
188 return CONTAINING_RECORD(iface, struct quartz_vmr, renderer.filter.IBaseFilter_iface);
191 static DWORD VMR9_SendSampleData(struct quartz_vmr *This, VMR9PresentationInfo *info, LPBYTE data,
192 DWORD size)
194 AM_MEDIA_TYPE *amt;
195 HRESULT hr = S_OK;
196 int width;
197 int height;
198 BITMAPINFOHEADER *bmiHeader;
199 D3DLOCKED_RECT lock;
201 TRACE("%p %p %d\n", This, data, size);
203 amt = &This->renderer.sink.pin.mt;
205 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
207 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
209 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
211 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
213 else
215 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
216 return VFW_E_RUNTIME_ERROR;
219 width = bmiHeader->biWidth;
220 height = bmiHeader->biHeight;
222 TRACE("Src Rect: %s\n", wine_dbgstr_rect(&This->source_rect));
223 TRACE("Dst Rect: %s\n", wine_dbgstr_rect(&This->target_rect));
225 hr = IDirect3DSurface9_LockRect(info->lpSurf, &lock, NULL, D3DLOCK_DISCARD);
226 if (FAILED(hr))
228 ERR("IDirect3DSurface9_LockRect failed (%x)\n",hr);
229 return hr;
232 if (height > 0) {
233 /* Bottom up image needs inverting */
234 lock.pBits = (char *)lock.pBits + (height * lock.Pitch);
235 while (height--)
237 lock.pBits = (char *)lock.pBits - lock.Pitch;
238 memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8);
239 data = data + width * bmiHeader->biBitCount / 8;
242 else if (lock.Pitch != width * bmiHeader->biBitCount / 8)
244 WARN("Slow path! %u/%u\n", lock.Pitch, width * bmiHeader->biBitCount/8);
246 while (height--)
248 memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8);
249 data = data + width * bmiHeader->biBitCount / 8;
250 lock.pBits = (char *)lock.pBits + lock.Pitch;
253 else memcpy(lock.pBits, data, size);
255 IDirect3DSurface9_UnlockRect(info->lpSurf);
257 hr = IVMRImagePresenter9_PresentImage(This->presenter, This->cookie, info);
258 return hr;
261 static HRESULT WINAPI VMR9_DoRenderSample(struct strmbase_renderer *iface, IMediaSample *pSample)
263 struct quartz_vmr *This = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
264 const HANDLE events[2] = {This->run_event, This->renderer.flush_event};
265 LPBYTE pbSrcStream = NULL;
266 long cbSrcStream = 0;
267 REFERENCE_TIME tStart, tStop;
268 VMR9PresentationInfo info;
269 HRESULT hr;
271 TRACE("%p %p\n", iface, pSample);
273 /* It is possible that there is no device at this point */
275 if (!This->allocator || !This->presenter)
277 ERR("NO PRESENTER!!\n");
278 return S_FALSE;
281 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
282 if (FAILED(hr))
283 info.dwFlags = VMR9Sample_SrcDstRectsValid;
284 else
285 info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid;
287 if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
288 info.dwFlags |= VMR9Sample_Discontinuity;
290 if (IMediaSample_IsPreroll(pSample) == S_OK)
291 info.dwFlags |= VMR9Sample_Preroll;
293 if (IMediaSample_IsSyncPoint(pSample) == S_OK)
294 info.dwFlags |= VMR9Sample_SyncPoint;
296 /* If we render ourselves, and this is a preroll sample, discard it */
297 if (info.dwFlags & VMR9Sample_Preroll)
299 return S_OK;
302 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
303 if (FAILED(hr))
305 ERR("Cannot get pointer to sample data (%x)\n", hr);
306 return hr;
309 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
311 info.rtStart = tStart;
312 info.rtEnd = tStop;
313 info.szAspectRatio.cx = This->bmiheader.biWidth;
314 info.szAspectRatio.cy = This->bmiheader.biHeight;
316 hr = IVMRSurfaceAllocatorEx9_GetSurface(This->allocator, This->cookie, (++This->cur_surface)%This->num_surfaces, 0, &info.lpSurf);
318 if (FAILED(hr))
319 return hr;
321 VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream);
322 IDirect3DSurface9_Release(info.lpSurf);
324 if (This->renderer.filter.state == State_Paused)
326 LeaveCriticalSection(&This->renderer.csRenderLock);
327 WaitForMultipleObjects(2, events, FALSE, INFINITE);
328 EnterCriticalSection(&This->renderer.csRenderLock);
331 return hr;
334 static HRESULT WINAPI VMR9_CheckMediaType(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt)
336 const VIDEOINFOHEADER *vih;
338 if (!IsEqualIID(&mt->majortype, &MEDIATYPE_Video) || !mt->pbFormat)
339 return S_FALSE;
341 if (!IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo)
342 && !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo2))
343 return S_FALSE;
345 vih = (VIDEOINFOHEADER *)mt->pbFormat;
347 if (vih->bmiHeader.biCompression != BI_RGB)
348 return S_FALSE;
349 return S_OK;
352 static HRESULT VMR9_maybe_init(struct quartz_vmr *This, BOOL force)
354 VMR9AllocationInfo info;
355 DWORD buffers;
356 HRESULT hr;
358 TRACE("my mode: %u, my window: %p, my last window: %p\n", This->mode, This->baseControlWindow.baseWindow.hWnd, This->hWndClippingWindow);
359 if (This->num_surfaces)
360 return S_OK;
362 if (This->mode == VMR9Mode_Windowless && !This->hWndClippingWindow)
363 return (force ? VFW_E_RUNTIME_ERROR : S_OK);
365 TRACE("Initializing\n");
366 info.dwFlags = VMR9AllocFlag_TextureSurface;
367 info.dwHeight = This->source_rect.bottom;
368 info.dwWidth = This->source_rect.right;
369 info.Pool = D3DPOOL_DEFAULT;
370 info.MinBuffers = 2;
371 FIXME("Reduce ratio to least common denominator\n");
372 info.szAspectRatio.cx = info.dwWidth;
373 info.szAspectRatio.cy = info.dwHeight;
374 info.szNativeSize.cx = This->bmiheader.biWidth;
375 info.szNativeSize.cy = This->bmiheader.biHeight;
376 buffers = 2;
378 switch (This->bmiheader.biBitCount)
380 case 8: info.Format = D3DFMT_R3G3B2; break;
381 case 15: info.Format = D3DFMT_X1R5G5B5; break;
382 case 16: info.Format = D3DFMT_R5G6B5; break;
383 case 24: info.Format = D3DFMT_R8G8B8; break;
384 case 32: info.Format = D3DFMT_X8R8G8B8; break;
385 default:
386 FIXME("Unknown bpp %u\n", This->bmiheader.biBitCount);
387 hr = E_INVALIDARG;
390 This->cur_surface = 0;
391 if (This->num_surfaces)
393 ERR("num_surfaces or d3d9_surfaces not 0\n");
394 return E_FAIL;
397 hr = IVMRSurfaceAllocatorEx9_InitializeDevice(This->allocator, This->cookie, &info, &buffers);
398 if (SUCCEEDED(hr))
400 SetRect(&This->source_rect, 0, 0, This->bmiheader.biWidth, This->bmiheader.biHeight);
402 This->num_surfaces = buffers;
404 return hr;
407 static void vmr_start_stream(struct strmbase_renderer *iface)
409 struct quartz_vmr *This = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
411 TRACE("(%p)\n", This);
413 if (This->renderer.sink.pin.peer)
414 VMR9_maybe_init(This, TRUE);
415 IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie);
416 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
417 This->source_rect.left,
418 This->source_rect.top,
419 This->source_rect.right - This->source_rect.left,
420 This->source_rect.bottom - This->source_rect.top,
421 SWP_NOZORDER|SWP_NOMOVE|SWP_DEFERERASE);
422 ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_SHOW);
423 GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->target_rect);
424 SetEvent(This->run_event);
427 static void vmr_stop_stream(struct strmbase_renderer *iface)
429 struct quartz_vmr *This = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
431 TRACE("(%p)\n", This);
433 if (This->renderer.filter.state == State_Running)
434 IVMRImagePresenter9_StopPresenting(This->presenter, This->cookie);
435 ResetEvent(This->run_event);
438 static HRESULT WINAPI VMR9_ShouldDrawSampleNow(struct strmbase_renderer *iface,
439 IMediaSample *pSample, REFERENCE_TIME *start, REFERENCE_TIME *end)
441 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
442 if (IMediaSample_IsPreroll(pSample) == S_OK)
443 return E_FAIL;
444 return S_FALSE;
447 static HRESULT vmr_connect(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt)
449 struct quartz_vmr *filter = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
450 HRESULT hr;
452 if (IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
454 VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)mt->pbFormat;
456 filter->bmiheader = format->bmiHeader;
457 filter->VideoWidth = format->bmiHeader.biWidth;
458 filter->VideoHeight = format->bmiHeader.biHeight;
459 SetRect(&filter->source_rect, 0, 0, filter->VideoWidth, filter->VideoHeight);
461 else if (IsEqualIID(&mt->formattype, &FORMAT_VideoInfo2))
463 VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)mt->pbFormat;
465 filter->bmiheader = format->bmiHeader;
466 filter->VideoWidth = format->bmiHeader.biWidth;
467 filter->VideoHeight = format->bmiHeader.biHeight;
468 SetRect(&filter->source_rect, 0, 0, filter->VideoWidth, filter->VideoHeight);
471 if (filter->mode
472 || SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&filter->IVMRFilterConfig9_iface, VMR9Mode_Windowed)))
473 hr = VMR9_maybe_init(filter, FALSE);
475 return hr;
478 static HRESULT WINAPI VMR9_BreakConnect(struct strmbase_renderer *This)
480 struct quartz_vmr *pVMR9 = impl_from_IBaseFilter(&This->filter.IBaseFilter_iface);
481 HRESULT hr = S_OK;
483 if (!pVMR9->mode)
484 return S_FALSE;
485 if (This->sink.pin.peer && pVMR9->allocator && pVMR9->presenter)
487 if (pVMR9->renderer.filter.state != State_Stopped)
489 ERR("Disconnecting while not stopped! UNTESTED!!\n");
491 if (pVMR9->renderer.filter.state == State_Running)
492 hr = IVMRImagePresenter9_StopPresenting(pVMR9->presenter, pVMR9->cookie);
493 IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9->allocator, pVMR9->cookie);
494 pVMR9->num_surfaces = 0;
496 return hr;
499 static void vmr_destroy(struct strmbase_renderer *iface)
501 struct quartz_vmr *filter = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
503 BaseControlWindow_Destroy(&filter->baseControlWindow);
505 if (filter->allocator)
506 IVMRSurfaceAllocatorEx9_Release(filter->allocator);
507 if (filter->presenter)
508 IVMRImagePresenter9_Release(filter->presenter);
510 filter->num_surfaces = 0;
511 if (filter->allocator_d3d9_dev)
513 IDirect3DDevice9_Release(filter->allocator_d3d9_dev);
514 filter->allocator_d3d9_dev = NULL;
517 CloseHandle(filter->run_event);
518 FreeLibrary(filter->hD3d9);
519 BaseControlWindow_Destroy(&filter->baseControlWindow);
520 strmbase_renderer_cleanup(&filter->renderer);
521 CoTaskMemFree(filter);
524 static HRESULT vmr_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out)
526 struct quartz_vmr *filter = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
528 if (IsEqualGUID(iid, &IID_IVideoWindow))
529 *out = &filter->baseControlWindow.IVideoWindow_iface;
530 else if (IsEqualGUID(iid, &IID_IBasicVideo))
531 *out = &filter->baseControlVideo.IBasicVideo_iface;
532 else if (IsEqualGUID(iid, &IID_IAMCertifiedOutputProtection))
533 *out = &filter->IAMCertifiedOutputProtection_iface;
534 else if (IsEqualGUID(iid, &IID_IAMFilterMiscFlags))
535 *out = &filter->IAMFilterMiscFlags_iface;
536 else if (IsEqualGUID(iid, &IID_IVMRFilterConfig))
537 *out = &filter->IVMRFilterConfig_iface;
538 else if (IsEqualGUID(iid, &IID_IVMRFilterConfig9))
539 *out = &filter->IVMRFilterConfig9_iface;
540 else if (IsEqualGUID(iid, &IID_IVMRMonitorConfig))
541 *out = &filter->IVMRMonitorConfig_iface;
542 else if (IsEqualGUID(iid, &IID_IVMRMonitorConfig9))
543 *out = &filter->IVMRMonitorConfig9_iface;
544 else if (IsEqualGUID(iid, &IID_IVMRSurfaceAllocatorNotify) && filter->mode == (VMR9Mode)VMRMode_Renderless)
545 *out = &filter->IVMRSurfaceAllocatorNotify_iface;
546 else if (IsEqualGUID(iid, &IID_IVMRSurfaceAllocatorNotify9) && filter->mode == VMR9Mode_Renderless)
547 *out = &filter->IVMRSurfaceAllocatorNotify9_iface;
548 else if (IsEqualGUID(iid, &IID_IVMRWindowlessControl) && filter->mode == (VMR9Mode)VMRMode_Windowless)
549 *out = &filter->IVMRWindowlessControl_iface;
550 else if (IsEqualGUID(iid, &IID_IVMRWindowlessControl9) && filter->mode == VMR9Mode_Windowless)
551 *out = &filter->IVMRWindowlessControl9_iface;
552 else
553 return E_NOINTERFACE;
555 IUnknown_AddRef((IUnknown *)*out);
556 return S_OK;
559 static HRESULT vmr_pin_query_interface(struct strmbase_renderer *iface, REFIID iid, void **out)
561 struct quartz_vmr *filter = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
563 if (IsEqualGUID(iid, &IID_IOverlay))
564 *out = &filter->IOverlay_iface;
565 else
566 return E_NOINTERFACE;
568 IUnknown_AddRef((IUnknown *)*out);
569 return S_OK;
572 static const struct strmbase_renderer_ops renderer_ops =
574 .pfnCheckMediaType = VMR9_CheckMediaType,
575 .pfnDoRenderSample = VMR9_DoRenderSample,
576 .renderer_start_stream = vmr_start_stream,
577 .renderer_stop_stream = vmr_stop_stream,
578 .pfnShouldDrawSampleNow = VMR9_ShouldDrawSampleNow,
579 .renderer_connect = vmr_connect,
580 .pfnBreakConnect = VMR9_BreakConnect,
581 .renderer_destroy = vmr_destroy,
582 .renderer_query_interface = vmr_query_interface,
583 .renderer_pin_query_interface = vmr_pin_query_interface,
586 static RECT WINAPI VMR9_GetDefaultRect(BaseWindow *This)
588 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
589 static RECT defRect;
591 SetRect(&defRect, 0, 0, pVMR9->VideoWidth, pVMR9->VideoHeight);
593 return defRect;
596 static BOOL WINAPI VMR9_OnSize(BaseWindow *This, LONG Width, LONG Height)
598 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
600 TRACE("WM_SIZE %d %d\n", Width, Height);
601 GetClientRect(This->hWnd, &pVMR9->target_rect);
602 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
603 pVMR9->target_rect.left,
604 pVMR9->target_rect.top,
605 pVMR9->target_rect.right - pVMR9->target_rect.left,
606 pVMR9->target_rect.bottom - pVMR9->target_rect.top);
608 return TRUE;
611 static const BaseWindowFuncTable renderer_BaseWindowFuncTable = {
612 VMR9_GetDefaultRect,
613 VMR9_OnSize,
616 static HRESULT WINAPI VMR9_GetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
618 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
619 CopyRect(pSourceRect,&pVMR9->source_rect);
620 return S_OK;
623 static HRESULT WINAPI VMR9_GetStaticImage(BaseControlVideo* This, LONG *pBufferSize, LONG *pDIBImage)
625 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
626 AM_MEDIA_TYPE *amt = &pVMR9->renderer.sink.pin.mt;
627 BITMAPINFOHEADER *bmiHeader;
628 LONG needed_size;
629 char *ptr;
631 FIXME("(%p/%p)->(%p, %p): partial stub\n", pVMR9, This, pBufferSize, pDIBImage);
633 EnterCriticalSection(&pVMR9->renderer.filter.csFilter);
635 if (!pVMR9->renderer.pMediaSample)
637 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
638 return (pVMR9->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
641 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
643 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
645 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
647 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
649 else
651 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
652 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
653 return VFW_E_RUNTIME_ERROR;
656 needed_size = bmiHeader->biSize;
657 needed_size += IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample);
659 if (!pDIBImage)
661 *pBufferSize = needed_size;
662 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
663 return S_OK;
666 if (needed_size < *pBufferSize)
668 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
669 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
670 return E_FAIL;
672 *pBufferSize = needed_size;
674 memcpy(pDIBImage, bmiHeader, bmiHeader->biSize);
675 IMediaSample_GetPointer(pVMR9->renderer.pMediaSample, (BYTE **)&ptr);
676 memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample));
678 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
679 return S_OK;
682 static HRESULT WINAPI VMR9_GetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
684 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
685 CopyRect(pTargetRect,&pVMR9->target_rect);
686 return S_OK;
689 static VIDEOINFOHEADER* WINAPI VMR9_GetVideoFormat(BaseControlVideo* This)
691 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
692 AM_MEDIA_TYPE *pmt;
694 TRACE("(%p/%p)\n", pVMR9, This);
696 pmt = &pVMR9->renderer.sink.pin.mt;
697 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) {
698 return (VIDEOINFOHEADER*)pmt->pbFormat;
699 } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) {
700 static VIDEOINFOHEADER vih;
701 VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat;
702 memcpy(&vih,vih2,sizeof(VIDEOINFOHEADER));
703 memcpy(&vih.bmiHeader, &vih2->bmiHeader, sizeof(BITMAPINFOHEADER));
704 return &vih;
705 } else {
706 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype));
707 return NULL;
711 static HRESULT WINAPI VMR9_IsDefaultSourceRect(BaseControlVideo* This)
713 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
714 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
716 return S_OK;
719 static HRESULT WINAPI VMR9_IsDefaultTargetRect(BaseControlVideo* This)
721 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
722 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
724 return S_OK;
727 static HRESULT WINAPI VMR9_SetDefaultSourceRect(BaseControlVideo* This)
729 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
731 SetRect(&pVMR9->source_rect, 0, 0, pVMR9->VideoWidth, pVMR9->VideoHeight);
733 return S_OK;
736 static HRESULT WINAPI VMR9_SetDefaultTargetRect(BaseControlVideo* This)
738 RECT rect;
739 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
741 if (!GetClientRect(pVMR9->baseControlWindow.baseWindow.hWnd, &rect))
742 return E_FAIL;
744 SetRect(&pVMR9->target_rect, 0, 0, rect.right, rect.bottom);
746 return S_OK;
749 static HRESULT WINAPI VMR9_SetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
751 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
752 CopyRect(&pVMR9->source_rect,pSourceRect);
753 return S_OK;
756 static HRESULT WINAPI VMR9_SetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
758 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
759 CopyRect(&pVMR9->target_rect,pTargetRect);
760 return S_OK;
763 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = {
764 VMR9_GetSourceRect,
765 VMR9_GetStaticImage,
766 VMR9_GetTargetRect,
767 VMR9_GetVideoFormat,
768 VMR9_IsDefaultSourceRect,
769 VMR9_IsDefaultTargetRect,
770 VMR9_SetDefaultSourceRect,
771 VMR9_SetDefaultTargetRect,
772 VMR9_SetSourceRect,
773 VMR9_SetTargetRect
776 static const IVideoWindowVtbl IVideoWindow_VTable =
778 BaseControlWindowImpl_QueryInterface,
779 BaseControlWindowImpl_AddRef,
780 BaseControlWindowImpl_Release,
781 BaseControlWindowImpl_GetTypeInfoCount,
782 BaseControlWindowImpl_GetTypeInfo,
783 BaseControlWindowImpl_GetIDsOfNames,
784 BaseControlWindowImpl_Invoke,
785 BaseControlWindowImpl_put_Caption,
786 BaseControlWindowImpl_get_Caption,
787 BaseControlWindowImpl_put_WindowStyle,
788 BaseControlWindowImpl_get_WindowStyle,
789 BaseControlWindowImpl_put_WindowStyleEx,
790 BaseControlWindowImpl_get_WindowStyleEx,
791 BaseControlWindowImpl_put_AutoShow,
792 BaseControlWindowImpl_get_AutoShow,
793 BaseControlWindowImpl_put_WindowState,
794 BaseControlWindowImpl_get_WindowState,
795 BaseControlWindowImpl_put_BackgroundPalette,
796 BaseControlWindowImpl_get_BackgroundPalette,
797 BaseControlWindowImpl_put_Visible,
798 BaseControlWindowImpl_get_Visible,
799 BaseControlWindowImpl_put_Left,
800 BaseControlWindowImpl_get_Left,
801 BaseControlWindowImpl_put_Width,
802 BaseControlWindowImpl_get_Width,
803 BaseControlWindowImpl_put_Top,
804 BaseControlWindowImpl_get_Top,
805 BaseControlWindowImpl_put_Height,
806 BaseControlWindowImpl_get_Height,
807 BaseControlWindowImpl_put_Owner,
808 BaseControlWindowImpl_get_Owner,
809 BaseControlWindowImpl_put_MessageDrain,
810 BaseControlWindowImpl_get_MessageDrain,
811 BaseControlWindowImpl_get_BorderColor,
812 BaseControlWindowImpl_put_BorderColor,
813 BaseControlWindowImpl_get_FullScreenMode,
814 BaseControlWindowImpl_put_FullScreenMode,
815 BaseControlWindowImpl_SetWindowForeground,
816 BaseControlWindowImpl_NotifyOwnerMessage,
817 BaseControlWindowImpl_SetWindowPosition,
818 BaseControlWindowImpl_GetWindowPosition,
819 BaseControlWindowImpl_GetMinIdealImageSize,
820 BaseControlWindowImpl_GetMaxIdealImageSize,
821 BaseControlWindowImpl_GetRestorePosition,
822 BaseControlWindowImpl_HideCursor,
823 BaseControlWindowImpl_IsCursorHidden
826 static HRESULT WINAPI AMCertifiedOutputProtection_QueryInterface(IAMCertifiedOutputProtection *iface,
827 REFIID riid, void **ppv)
829 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
830 return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppv);
833 static ULONG WINAPI AMCertifiedOutputProtection_AddRef(IAMCertifiedOutputProtection *iface)
835 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
836 return IUnknown_AddRef(This->renderer.filter.outer_unk);
839 static ULONG WINAPI AMCertifiedOutputProtection_Release(IAMCertifiedOutputProtection *iface)
841 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
842 return IUnknown_Release(This->renderer.filter.outer_unk);
845 static HRESULT WINAPI AMCertifiedOutputProtection_KeyExchange(IAMCertifiedOutputProtection *iface,
846 GUID* pRandom, BYTE** VarLenCertGH,
847 DWORD* pdwLengthCertGH)
849 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
851 FIXME("(%p/%p)->(%p, %p, %p) stub\n", iface, This, pRandom, VarLenCertGH, pdwLengthCertGH);
852 return VFW_E_NO_COPP_HW;
855 static HRESULT WINAPI AMCertifiedOutputProtection_SessionSequenceStart(IAMCertifiedOutputProtection *iface,
856 AMCOPPSignature* pSig)
858 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
860 FIXME("(%p/%p)->(%p) stub\n", iface, This, pSig);
861 return VFW_E_NO_COPP_HW;
864 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionCommand(IAMCertifiedOutputProtection *iface,
865 const AMCOPPCommand* cmd)
867 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
869 FIXME("(%p/%p)->(%p) stub\n", iface, This, cmd);
870 return VFW_E_NO_COPP_HW;
873 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionStatus(IAMCertifiedOutputProtection *iface,
874 const AMCOPPStatusInput* pStatusInput,
875 AMCOPPStatusOutput* pStatusOutput)
877 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
879 FIXME("(%p/%p)->(%p, %p) stub\n", iface, This, pStatusInput, pStatusOutput);
880 return VFW_E_NO_COPP_HW;
883 static const IAMCertifiedOutputProtectionVtbl IAMCertifiedOutputProtection_Vtbl =
885 AMCertifiedOutputProtection_QueryInterface,
886 AMCertifiedOutputProtection_AddRef,
887 AMCertifiedOutputProtection_Release,
888 AMCertifiedOutputProtection_KeyExchange,
889 AMCertifiedOutputProtection_SessionSequenceStart,
890 AMCertifiedOutputProtection_ProtectionCommand,
891 AMCertifiedOutputProtection_ProtectionStatus
894 static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) {
895 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
896 return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppv);
899 static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) {
900 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
901 return IUnknown_AddRef(This->renderer.filter.outer_unk);
904 static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) {
905 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
906 return IUnknown_Release(This->renderer.filter.outer_unk);
909 static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) {
910 return AM_FILTER_MISC_FLAGS_IS_RENDERER;
913 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = {
914 AMFilterMiscFlags_QueryInterface,
915 AMFilterMiscFlags_AddRef,
916 AMFilterMiscFlags_Release,
917 AMFilterMiscFlags_GetMiscFlags
920 static HRESULT WINAPI VMR7FilterConfig_QueryInterface(IVMRFilterConfig *iface, REFIID riid,
921 void** ppv)
923 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
924 return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppv);
927 static ULONG WINAPI VMR7FilterConfig_AddRef(IVMRFilterConfig *iface)
929 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
930 return IUnknown_AddRef(This->renderer.filter.outer_unk);
933 static ULONG WINAPI VMR7FilterConfig_Release(IVMRFilterConfig *iface)
935 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
936 return IUnknown_Release(This->renderer.filter.outer_unk);
939 static HRESULT WINAPI VMR7FilterConfig_SetImageCompositor(IVMRFilterConfig *iface,
940 IVMRImageCompositor *compositor)
942 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
944 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
945 return E_NOTIMPL;
948 static HRESULT WINAPI VMR7FilterConfig_SetNumberOfStreams(IVMRFilterConfig *iface, DWORD max)
950 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
952 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
953 return E_NOTIMPL;
956 static HRESULT WINAPI VMR7FilterConfig_GetNumberOfStreams(IVMRFilterConfig *iface, DWORD *max)
958 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
960 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
961 return E_NOTIMPL;
964 static HRESULT WINAPI VMR7FilterConfig_SetRenderingPrefs(IVMRFilterConfig *iface, DWORD renderflags)
966 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
968 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
969 return E_NOTIMPL;
972 static HRESULT WINAPI VMR7FilterConfig_GetRenderingPrefs(IVMRFilterConfig *iface, DWORD *renderflags)
974 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
976 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
977 return E_NOTIMPL;
980 static HRESULT WINAPI VMR7FilterConfig_SetRenderingMode(IVMRFilterConfig *iface, DWORD mode)
982 struct quartz_vmr *filter = impl_from_IVMRFilterConfig(iface);
984 TRACE("iface %p, mode %#x.\n", iface, mode);
986 return IVMRFilterConfig9_SetRenderingMode(&filter->IVMRFilterConfig9_iface, mode);
989 static HRESULT WINAPI VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig *iface, DWORD *mode)
991 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
993 TRACE("(%p/%p)->(%p)\n", iface, This, mode);
994 if (!mode) return E_POINTER;
996 if (This->mode)
997 *mode = This->mode;
998 else
999 *mode = VMRMode_Windowed;
1001 return S_OK;
1004 static const IVMRFilterConfigVtbl VMR7_FilterConfig_Vtbl =
1006 VMR7FilterConfig_QueryInterface,
1007 VMR7FilterConfig_AddRef,
1008 VMR7FilterConfig_Release,
1009 VMR7FilterConfig_SetImageCompositor,
1010 VMR7FilterConfig_SetNumberOfStreams,
1011 VMR7FilterConfig_GetNumberOfStreams,
1012 VMR7FilterConfig_SetRenderingPrefs,
1013 VMR7FilterConfig_GetRenderingPrefs,
1014 VMR7FilterConfig_SetRenderingMode,
1015 VMR7FilterConfig_GetRenderingMode
1018 struct get_available_monitors_args
1020 VMRMONITORINFO *info7;
1021 VMR9MonitorInfo *info9;
1022 DWORD arraysize;
1023 DWORD numdev;
1026 static BOOL CALLBACK get_available_monitors_proc(HMONITOR hmon, HDC hdc, LPRECT lprc, LPARAM lparam)
1028 struct get_available_monitors_args *args = (struct get_available_monitors_args *)lparam;
1029 MONITORINFOEXW mi;
1031 if (args->info7 || args->info9)
1034 if (!args->arraysize)
1035 return FALSE;
1037 mi.cbSize = sizeof(mi);
1038 if (!GetMonitorInfoW(hmon, (MONITORINFO*)&mi))
1039 return TRUE;
1041 /* fill VMRMONITORINFO struct */
1042 if (args->info7)
1044 VMRMONITORINFO *info = args->info7++;
1045 memset(info, 0, sizeof(*info));
1047 if (args->numdev > 0)
1049 info->guid.pGUID = &info->guid.GUID;
1050 info->guid.GUID.Data4[7] = args->numdev;
1052 else
1053 info->guid.pGUID = NULL;
1055 info->rcMonitor = mi.rcMonitor;
1056 info->hMon = hmon;
1057 info->dwFlags = mi.dwFlags;
1059 lstrcpynW(info->szDevice, mi.szDevice, ARRAY_SIZE(info->szDevice));
1061 /* FIXME: how to get these values? */
1062 info->szDescription[0] = 0;
1065 /* fill VMR9MonitorInfo struct */
1066 if (args->info9)
1068 VMR9MonitorInfo *info = args->info9++;
1069 memset(info, 0, sizeof(*info));
1071 info->uDevID = 0; /* FIXME */
1072 info->rcMonitor = mi.rcMonitor;
1073 info->hMon = hmon;
1074 info->dwFlags = mi.dwFlags;
1076 lstrcpynW(info->szDevice, mi.szDevice, ARRAY_SIZE(info->szDevice));
1078 /* FIXME: how to get these values? */
1079 info->szDescription[0] = 0;
1080 info->dwVendorId = 0;
1081 info->dwDeviceId = 0;
1082 info->dwSubSysId = 0;
1083 info->dwRevision = 0;
1086 args->arraysize--;
1089 args->numdev++;
1090 return TRUE;
1093 static HRESULT WINAPI VMR7MonitorConfig_QueryInterface(IVMRMonitorConfig *iface, REFIID riid,
1094 LPVOID * ppv)
1096 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1097 return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppv);
1100 static ULONG WINAPI VMR7MonitorConfig_AddRef(IVMRMonitorConfig *iface)
1102 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1103 return IUnknown_AddRef(This->renderer.filter.outer_unk);
1106 static ULONG WINAPI VMR7MonitorConfig_Release(IVMRMonitorConfig *iface)
1108 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1109 return IUnknown_Release(This->renderer.filter.outer_unk);
1112 static HRESULT WINAPI VMR7MonitorConfig_SetMonitor(IVMRMonitorConfig *iface, const VMRGUID *pGUID)
1114 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1116 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1118 if (!pGUID)
1119 return E_POINTER;
1121 return S_OK;
1124 static HRESULT WINAPI VMR7MonitorConfig_GetMonitor(IVMRMonitorConfig *iface, VMRGUID *pGUID)
1126 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1128 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1130 if (!pGUID)
1131 return E_POINTER;
1133 pGUID->pGUID = NULL; /* default DirectDraw device */
1134 return S_OK;
1137 static HRESULT WINAPI VMR7MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig *iface,
1138 const VMRGUID *pGUID)
1140 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1142 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1144 if (!pGUID)
1145 return E_POINTER;
1147 return S_OK;
1150 static HRESULT WINAPI VMR7MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig *iface, VMRGUID *pGUID)
1152 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1154 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1156 if (!pGUID)
1157 return E_POINTER;
1159 pGUID->pGUID = NULL; /* default DirectDraw device */
1160 return S_OK;
1163 static HRESULT WINAPI VMR7MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig *iface,
1164 VMRMONITORINFO *info, DWORD arraysize,
1165 DWORD *numdev)
1167 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1168 struct get_available_monitors_args args;
1170 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1172 if (!numdev)
1173 return E_POINTER;
1175 if (info && arraysize == 0)
1176 return E_INVALIDARG;
1178 args.info7 = info;
1179 args.info9 = NULL;
1180 args.arraysize = arraysize;
1181 args.numdev = 0;
1182 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1184 *numdev = args.numdev;
1185 return S_OK;
1188 static const IVMRMonitorConfigVtbl VMR7_MonitorConfig_Vtbl =
1190 VMR7MonitorConfig_QueryInterface,
1191 VMR7MonitorConfig_AddRef,
1192 VMR7MonitorConfig_Release,
1193 VMR7MonitorConfig_SetMonitor,
1194 VMR7MonitorConfig_GetMonitor,
1195 VMR7MonitorConfig_SetDefaultMonitor,
1196 VMR7MonitorConfig_GetDefaultMonitor,
1197 VMR7MonitorConfig_GetAvailableMonitors
1200 static HRESULT WINAPI VMR9MonitorConfig_QueryInterface(IVMRMonitorConfig9 *iface, REFIID riid,
1201 LPVOID * ppv)
1203 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1204 return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppv);
1207 static ULONG WINAPI VMR9MonitorConfig_AddRef(IVMRMonitorConfig9 *iface)
1209 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1210 return IUnknown_AddRef(This->renderer.filter.outer_unk);
1213 static ULONG WINAPI VMR9MonitorConfig_Release(IVMRMonitorConfig9 *iface)
1215 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1216 return IUnknown_Release(This->renderer.filter.outer_unk);
1219 static HRESULT WINAPI VMR9MonitorConfig_SetMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1221 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1223 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1225 return S_OK;
1228 static HRESULT WINAPI VMR9MonitorConfig_GetMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1230 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1232 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1234 if (!uDev)
1235 return E_POINTER;
1237 *uDev = 0;
1238 return S_OK;
1241 static HRESULT WINAPI VMR9MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1243 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1245 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1247 return S_OK;
1250 static HRESULT WINAPI VMR9MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1252 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1254 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1256 if (!uDev)
1257 return E_POINTER;
1259 *uDev = 0;
1260 return S_OK;
1263 static HRESULT WINAPI VMR9MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig9 *iface,
1264 VMR9MonitorInfo *info, DWORD arraysize,
1265 DWORD *numdev)
1267 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1268 struct get_available_monitors_args args;
1270 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1272 if (!numdev)
1273 return E_POINTER;
1275 if (info && arraysize == 0)
1276 return E_INVALIDARG;
1278 args.info7 = NULL;
1279 args.info9 = info;
1280 args.arraysize = arraysize;
1281 args.numdev = 0;
1282 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1284 *numdev = args.numdev;
1285 return S_OK;
1288 static const IVMRMonitorConfig9Vtbl VMR9_MonitorConfig_Vtbl =
1290 VMR9MonitorConfig_QueryInterface,
1291 VMR9MonitorConfig_AddRef,
1292 VMR9MonitorConfig_Release,
1293 VMR9MonitorConfig_SetMonitor,
1294 VMR9MonitorConfig_GetMonitor,
1295 VMR9MonitorConfig_SetDefaultMonitor,
1296 VMR9MonitorConfig_GetDefaultMonitor,
1297 VMR9MonitorConfig_GetAvailableMonitors
1300 static HRESULT WINAPI VMR9FilterConfig_QueryInterface(IVMRFilterConfig9 *iface, REFIID riid, LPVOID * ppv)
1302 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1303 return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppv);
1306 static ULONG WINAPI VMR9FilterConfig_AddRef(IVMRFilterConfig9 *iface)
1308 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1309 return IUnknown_AddRef(This->renderer.filter.outer_unk);
1312 static ULONG WINAPI VMR9FilterConfig_Release(IVMRFilterConfig9 *iface)
1314 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1315 return IUnknown_Release(This->renderer.filter.outer_unk);
1318 static HRESULT WINAPI VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9 *iface, IVMRImageCompositor9 *compositor)
1320 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1322 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
1323 return E_NOTIMPL;
1326 static HRESULT WINAPI VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD count)
1328 FIXME("iface %p, count %u, stub!\n", iface, count);
1329 if (count == 1)
1330 return S_OK;
1331 return E_NOTIMPL;
1334 static HRESULT WINAPI VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD *max)
1336 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1338 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
1339 return E_NOTIMPL;
1342 static HRESULT WINAPI VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD renderflags)
1344 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1346 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
1347 return E_NOTIMPL;
1350 static HRESULT WINAPI VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD *renderflags)
1352 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1354 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
1355 return E_NOTIMPL;
1358 static HRESULT WINAPI VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 *iface, DWORD mode)
1360 HRESULT hr = S_OK;
1361 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1363 TRACE("(%p/%p)->(%u)\n", iface, This, mode);
1365 EnterCriticalSection(&This->renderer.filter.csFilter);
1366 if (This->mode)
1368 LeaveCriticalSection(&This->renderer.filter.csFilter);
1369 return VFW_E_WRONG_STATE;
1372 if (This->allocator)
1373 IVMRSurfaceAllocatorEx9_Release(This->allocator);
1374 if (This->presenter)
1375 IVMRImagePresenter9_Release(This->presenter);
1377 This->allocator = NULL;
1378 This->presenter = NULL;
1380 switch (mode)
1382 case VMR9Mode_Windowed:
1383 case VMR9Mode_Windowless:
1384 This->allocator_is_ex = 0;
1385 This->cookie = ~0;
1387 hr = VMR9DefaultAllocatorPresenterImpl_create(This, (LPVOID*)&This->presenter);
1388 if (SUCCEEDED(hr))
1389 hr = IVMRImagePresenter9_QueryInterface(This->presenter, &IID_IVMRSurfaceAllocatorEx9, (LPVOID*)&This->allocator);
1390 if (FAILED(hr))
1392 ERR("Unable to find Presenter interface\n");
1393 IVMRImagePresenter9_Release(This->presenter);
1394 This->allocator = NULL;
1395 This->presenter = NULL;
1397 else
1398 hr = IVMRSurfaceAllocatorEx9_AdviseNotify(This->allocator, &This->IVMRSurfaceAllocatorNotify9_iface);
1399 break;
1400 case VMR9Mode_Renderless:
1401 break;
1402 default:
1403 LeaveCriticalSection(&This->renderer.filter.csFilter);
1404 return E_INVALIDARG;
1407 This->mode = mode;
1408 LeaveCriticalSection(&This->renderer.filter.csFilter);
1409 return hr;
1412 static HRESULT WINAPI VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9 *iface, DWORD *mode)
1414 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1416 TRACE("(%p/%p)->(%p)\n", iface, This, mode);
1417 if (!mode)
1418 return E_POINTER;
1420 if (This->mode)
1421 *mode = This->mode;
1422 else
1423 *mode = VMR9Mode_Windowed;
1425 return S_OK;
1428 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl =
1430 VMR9FilterConfig_QueryInterface,
1431 VMR9FilterConfig_AddRef,
1432 VMR9FilterConfig_Release,
1433 VMR9FilterConfig_SetImageCompositor,
1434 VMR9FilterConfig_SetNumberOfStreams,
1435 VMR9FilterConfig_GetNumberOfStreams,
1436 VMR9FilterConfig_SetRenderingPrefs,
1437 VMR9FilterConfig_GetRenderingPrefs,
1438 VMR9FilterConfig_SetRenderingMode,
1439 VMR9FilterConfig_GetRenderingMode
1442 static HRESULT WINAPI VMR7WindowlessControl_QueryInterface(IVMRWindowlessControl *iface, REFIID riid,
1443 LPVOID * ppv)
1445 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1446 return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppv);
1449 static ULONG WINAPI VMR7WindowlessControl_AddRef(IVMRWindowlessControl *iface)
1451 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1452 return IUnknown_AddRef(This->renderer.filter.outer_unk);
1455 static ULONG WINAPI VMR7WindowlessControl_Release(IVMRWindowlessControl *iface)
1457 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1458 return IUnknown_Release(This->renderer.filter.outer_unk);
1461 static HRESULT WINAPI VMR7WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl *iface,
1462 LONG *width, LONG *height,
1463 LONG *arwidth, LONG *arheight)
1465 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1466 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1468 if (!width || !height || !arwidth || !arheight)
1470 ERR("Got no pointer\n");
1471 return E_POINTER;
1474 *width = This->bmiheader.biWidth;
1475 *height = This->bmiheader.biHeight;
1476 *arwidth = This->bmiheader.biWidth;
1477 *arheight = This->bmiheader.biHeight;
1479 return S_OK;
1482 static HRESULT WINAPI VMR7WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl *iface,
1483 LONG *width, LONG *height)
1485 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1487 FIXME("(%p/%p)->(...) stub\n", iface, This);
1488 return E_NOTIMPL;
1491 static HRESULT WINAPI VMR7WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl *iface,
1492 LONG *width, LONG *height)
1494 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1496 FIXME("(%p/%p)->(...) stub\n", iface, This);
1497 return E_NOTIMPL;
1500 static HRESULT WINAPI VMR7WindowlessControl_SetVideoPosition(IVMRWindowlessControl *iface,
1501 const RECT *source, const RECT *dest)
1503 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1505 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1507 EnterCriticalSection(&This->renderer.filter.csFilter);
1509 if (source)
1510 This->source_rect = *source;
1511 if (dest)
1513 This->target_rect = *dest;
1514 FIXME("Output rectangle: %s.\n", wine_dbgstr_rect(dest));
1515 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
1516 dest->left, dest->top, dest->right - dest->left, dest->bottom-dest->top,
1517 SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOOWNERZORDER | SWP_NOREDRAW);
1520 LeaveCriticalSection(&This->renderer.filter.csFilter);
1522 return S_OK;
1525 static HRESULT WINAPI VMR7WindowlessControl_GetVideoPosition(IVMRWindowlessControl *iface,
1526 RECT *source, RECT *dest)
1528 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1530 if (source)
1531 *source = This->source_rect;
1533 if (dest)
1534 *dest = This->target_rect;
1536 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
1537 return S_OK;
1540 static HRESULT WINAPI VMR7WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl *iface,
1541 DWORD *mode)
1543 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1545 FIXME("(%p/%p)->(...) stub\n", iface, This);
1546 return E_NOTIMPL;
1549 static HRESULT WINAPI VMR7WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl *iface,
1550 DWORD mode)
1552 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1554 FIXME("(%p/%p)->(...) stub\n", iface, This);
1555 return E_NOTIMPL;
1558 static HRESULT WINAPI VMR7WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl *iface, HWND window)
1560 struct quartz_vmr *filter = impl_from_IVMRWindowlessControl(iface);
1562 TRACE("iface %p, window %p.\n", iface, window);
1564 return IVMRWindowlessControl9_SetVideoClippingWindow(&filter->IVMRWindowlessControl9_iface, window);
1567 static HRESULT WINAPI VMR7WindowlessControl_RepaintVideo(IVMRWindowlessControl *iface,
1568 HWND hwnd, HDC hdc)
1570 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1572 FIXME("(%p/%p)->(...) stub\n", iface, This);
1573 return E_NOTIMPL;
1576 static HRESULT WINAPI VMR7WindowlessControl_DisplayModeChanged(IVMRWindowlessControl *iface)
1578 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1580 FIXME("(%p/%p)->(...) stub\n", iface, This);
1581 return E_NOTIMPL;
1584 static HRESULT WINAPI VMR7WindowlessControl_GetCurrentImage(IVMRWindowlessControl *iface,
1585 BYTE **dib)
1587 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1589 FIXME("(%p/%p)->(...) stub\n", iface, This);
1590 return E_NOTIMPL;
1593 static HRESULT WINAPI VMR7WindowlessControl_SetBorderColor(IVMRWindowlessControl *iface,
1594 COLORREF color)
1596 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1598 FIXME("(%p/%p)->(...) stub\n", iface, This);
1599 return E_NOTIMPL;
1602 static HRESULT WINAPI VMR7WindowlessControl_GetBorderColor(IVMRWindowlessControl *iface,
1603 COLORREF *color)
1605 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1607 FIXME("(%p/%p)->(...) stub\n", iface, This);
1608 return E_NOTIMPL;
1611 static HRESULT WINAPI VMR7WindowlessControl_SetColorKey(IVMRWindowlessControl *iface, COLORREF color)
1613 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1615 FIXME("(%p/%p)->(...) stub\n", iface, This);
1616 return E_NOTIMPL;
1619 static HRESULT WINAPI VMR7WindowlessControl_GetColorKey(IVMRWindowlessControl *iface, COLORREF *color)
1621 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1623 FIXME("(%p/%p)->(...) stub\n", iface, This);
1624 return E_NOTIMPL;
1627 static const IVMRWindowlessControlVtbl VMR7_WindowlessControl_Vtbl =
1629 VMR7WindowlessControl_QueryInterface,
1630 VMR7WindowlessControl_AddRef,
1631 VMR7WindowlessControl_Release,
1632 VMR7WindowlessControl_GetNativeVideoSize,
1633 VMR7WindowlessControl_GetMinIdealVideoSize,
1634 VMR7WindowlessControl_GetMaxIdealVideoSize,
1635 VMR7WindowlessControl_SetVideoPosition,
1636 VMR7WindowlessControl_GetVideoPosition,
1637 VMR7WindowlessControl_GetAspectRatioMode,
1638 VMR7WindowlessControl_SetAspectRatioMode,
1639 VMR7WindowlessControl_SetVideoClippingWindow,
1640 VMR7WindowlessControl_RepaintVideo,
1641 VMR7WindowlessControl_DisplayModeChanged,
1642 VMR7WindowlessControl_GetCurrentImage,
1643 VMR7WindowlessControl_SetBorderColor,
1644 VMR7WindowlessControl_GetBorderColor,
1645 VMR7WindowlessControl_SetColorKey,
1646 VMR7WindowlessControl_GetColorKey
1649 static HRESULT WINAPI VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9 *iface, REFIID riid, LPVOID * ppv)
1651 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1652 return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppv);
1655 static ULONG WINAPI VMR9WindowlessControl_AddRef(IVMRWindowlessControl9 *iface)
1657 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1658 return IUnknown_AddRef(This->renderer.filter.outer_unk);
1661 static ULONG WINAPI VMR9WindowlessControl_Release(IVMRWindowlessControl9 *iface)
1663 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1664 return IUnknown_Release(This->renderer.filter.outer_unk);
1667 static HRESULT WINAPI VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height, LONG *arwidth, LONG *arheight)
1669 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1670 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1672 if (!width || !height || !arwidth || !arheight)
1674 ERR("Got no pointer\n");
1675 return E_POINTER;
1678 *width = This->bmiheader.biWidth;
1679 *height = This->bmiheader.biHeight;
1680 *arwidth = This->bmiheader.biWidth;
1681 *arheight = This->bmiheader.biHeight;
1683 return S_OK;
1686 static HRESULT WINAPI VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1688 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1690 FIXME("(%p/%p)->(...) stub\n", iface, This);
1691 return E_NOTIMPL;
1694 static HRESULT WINAPI VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1696 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1698 FIXME("(%p/%p)->(...) stub\n", iface, This);
1699 return E_NOTIMPL;
1702 static HRESULT WINAPI VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9 *iface, const RECT *source, const RECT *dest)
1704 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1706 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1708 EnterCriticalSection(&This->renderer.filter.csFilter);
1710 if (source)
1711 This->source_rect = *source;
1712 if (dest)
1714 This->target_rect = *dest;
1715 FIXME("Output rectangle: %s.\n", wine_dbgstr_rect(dest));
1716 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
1717 dest->left, dest->top, dest->right - dest->left, dest->bottom - dest->top,
1718 SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOOWNERZORDER | SWP_NOREDRAW);
1721 LeaveCriticalSection(&This->renderer.filter.csFilter);
1723 return S_OK;
1726 static HRESULT WINAPI VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9 *iface, RECT *source, RECT *dest)
1728 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1730 if (source)
1731 *source = This->source_rect;
1733 if (dest)
1734 *dest = This->target_rect;
1736 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
1737 return S_OK;
1740 static HRESULT WINAPI VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD *mode)
1742 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1744 FIXME("(%p/%p)->(...) stub\n", iface, This);
1745 return E_NOTIMPL;
1748 static HRESULT WINAPI VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD mode)
1750 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1752 FIXME("(%p/%p)->(...) stub\n", iface, This);
1753 return E_NOTIMPL;
1756 static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9 *iface, HWND hwnd)
1758 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1760 TRACE("(%p/%p)->(%p)\n", iface, This, hwnd);
1762 EnterCriticalSection(&This->renderer.filter.csFilter);
1763 This->hWndClippingWindow = hwnd;
1764 if (This->renderer.sink.pin.peer)
1765 VMR9_maybe_init(This, FALSE);
1766 if (!hwnd)
1767 IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie);
1768 LeaveCriticalSection(&This->renderer.filter.csFilter);
1769 return S_OK;
1772 static HRESULT WINAPI VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9 *iface, HWND hwnd, HDC hdc)
1774 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1775 HRESULT hr;
1777 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
1779 EnterCriticalSection(&This->renderer.filter.csFilter);
1780 if (hwnd != This->hWndClippingWindow && hwnd != This->baseControlWindow.baseWindow.hWnd)
1782 ERR("Not handling changing windows yet!!!\n");
1783 LeaveCriticalSection(&This->renderer.filter.csFilter);
1784 return S_OK;
1787 if (!This->allocator_d3d9_dev)
1789 ERR("No d3d9 device!\n");
1790 LeaveCriticalSection(&This->renderer.filter.csFilter);
1791 return VFW_E_WRONG_STATE;
1794 /* Windowless extension */
1795 hr = IDirect3DDevice9_Present(This->allocator_d3d9_dev, NULL, NULL, This->baseControlWindow.baseWindow.hWnd, NULL);
1796 LeaveCriticalSection(&This->renderer.filter.csFilter);
1798 return hr;
1801 static HRESULT WINAPI VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9 *iface)
1803 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1805 FIXME("(%p/%p)->(...) stub\n", iface, This);
1806 return E_NOTIMPL;
1809 static HRESULT WINAPI VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9 *iface, BYTE **dib)
1811 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1813 FIXME("(%p/%p)->(...) stub\n", iface, This);
1814 return E_NOTIMPL;
1817 static HRESULT WINAPI VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9 *iface, COLORREF color)
1819 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1821 FIXME("(%p/%p)->(...) stub\n", iface, This);
1822 return E_NOTIMPL;
1825 static HRESULT WINAPI VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9 *iface, COLORREF *color)
1827 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1829 FIXME("(%p/%p)->(...) stub\n", iface, This);
1830 return E_NOTIMPL;
1833 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl =
1835 VMR9WindowlessControl_QueryInterface,
1836 VMR9WindowlessControl_AddRef,
1837 VMR9WindowlessControl_Release,
1838 VMR9WindowlessControl_GetNativeVideoSize,
1839 VMR9WindowlessControl_GetMinIdealVideoSize,
1840 VMR9WindowlessControl_GetMaxIdealVideoSize,
1841 VMR9WindowlessControl_SetVideoPosition,
1842 VMR9WindowlessControl_GetVideoPosition,
1843 VMR9WindowlessControl_GetAspectRatioMode,
1844 VMR9WindowlessControl_SetAspectRatioMode,
1845 VMR9WindowlessControl_SetVideoClippingWindow,
1846 VMR9WindowlessControl_RepaintVideo,
1847 VMR9WindowlessControl_DisplayModeChanged,
1848 VMR9WindowlessControl_GetCurrentImage,
1849 VMR9WindowlessControl_SetBorderColor,
1850 VMR9WindowlessControl_GetBorderColor
1853 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify *iface,
1854 REFIID riid, LPVOID * ppv)
1856 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
1857 return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppv);
1860 static ULONG WINAPI VMR7SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify *iface)
1862 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
1863 return IUnknown_AddRef(This->renderer.filter.outer_unk);
1866 static ULONG WINAPI VMR7SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify *iface)
1868 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
1869 return IUnknown_Release(This->renderer.filter.outer_unk);
1872 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify *iface,
1873 DWORD_PTR id,
1874 IVMRSurfaceAllocator *alloc)
1876 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
1878 FIXME("(%p/%p)->(...) stub\n", iface, This);
1879 return E_NOTIMPL;
1882 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
1883 IDirectDraw7 *device, HMONITOR monitor)
1885 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
1887 FIXME("(%p/%p)->(...) stub\n", iface, This);
1888 return E_NOTIMPL;
1891 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_ChangeDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
1892 IDirectDraw7 *device, HMONITOR monitor)
1894 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
1896 FIXME("(%p/%p)->(...) stub\n", iface, This);
1897 return E_NOTIMPL;
1900 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces(IVMRSurfaceAllocatorNotify *iface)
1902 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
1904 FIXME("(%p/%p)->(...) stub\n", iface, This);
1905 return E_NOTIMPL;
1908 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify *iface, LONG code,
1909 LONG_PTR param1, LONG_PTR param2)
1911 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
1913 FIXME("(%p/%p)->(...) stub\n", iface, This);
1914 return E_NOTIMPL;
1917 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetBorderColor(IVMRSurfaceAllocatorNotify *iface,
1918 COLORREF clrBorder)
1920 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
1922 FIXME("(%p/%p)->(...) stub\n", iface, This);
1923 return E_NOTIMPL;
1926 static const IVMRSurfaceAllocatorNotifyVtbl VMR7_SurfaceAllocatorNotify_Vtbl =
1928 VMR7SurfaceAllocatorNotify_QueryInterface,
1929 VMR7SurfaceAllocatorNotify_AddRef,
1930 VMR7SurfaceAllocatorNotify_Release,
1931 VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator,
1932 VMR7SurfaceAllocatorNotify_SetDDrawDevice,
1933 VMR7SurfaceAllocatorNotify_ChangeDDrawDevice,
1934 VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces,
1935 VMR7SurfaceAllocatorNotify_NotifyEvent,
1936 VMR7SurfaceAllocatorNotify_SetBorderColor
1939 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9 *iface, REFIID riid, LPVOID * ppv)
1941 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1942 return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppv);
1945 static ULONG WINAPI VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9 *iface)
1947 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1948 return IUnknown_AddRef(This->renderer.filter.outer_unk);
1951 static ULONG WINAPI VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9 *iface)
1953 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1954 return IUnknown_Release(This->renderer.filter.outer_unk);
1957 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9 *iface, DWORD_PTR id, IVMRSurfaceAllocator9 *alloc)
1959 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1961 /* FIXME: This code is not tested!!! */
1962 FIXME("(%p/%p)->(...) stub\n", iface, This);
1963 This->cookie = id;
1965 if (This->presenter)
1966 return VFW_E_WRONG_STATE;
1968 if (FAILED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRImagePresenter9, (void **)&This->presenter)))
1969 return E_NOINTERFACE;
1971 if (SUCCEEDED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRSurfaceAllocatorEx9, (void **)&This->allocator)))
1972 This->allocator_is_ex = 1;
1973 else
1975 This->allocator = (IVMRSurfaceAllocatorEx9 *)alloc;
1976 IVMRSurfaceAllocator9_AddRef(alloc);
1977 This->allocator_is_ex = 0;
1980 return S_OK;
1983 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
1985 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1987 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
1988 if (This->allocator_d3d9_dev)
1989 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
1990 This->allocator_d3d9_dev = device;
1991 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
1992 This->allocator_mon = monitor;
1994 return S_OK;
1997 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
1999 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2001 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2002 if (This->allocator_d3d9_dev)
2003 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
2004 This->allocator_d3d9_dev = device;
2005 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
2006 This->allocator_mon = monitor;
2008 return S_OK;
2011 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9 *iface, VMR9AllocationInfo *allocinfo, DWORD *numbuffers, IDirect3DSurface9 **surface)
2013 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2014 DWORD i;
2015 HRESULT hr = S_OK;
2017 FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface, This, allocinfo, numbuffers, (numbuffers ? *numbuffers : 0), surface);
2019 if (!allocinfo || !numbuffers || !surface)
2020 return E_POINTER;
2022 if (!*numbuffers || *numbuffers < allocinfo->MinBuffers)
2024 ERR("Invalid number of buffers?\n");
2025 return E_INVALIDARG;
2028 if (!This->allocator_d3d9_dev)
2030 ERR("No direct3d device when requested to allocate a surface!\n");
2031 return VFW_E_WRONG_STATE;
2034 if (allocinfo->dwFlags & VMR9AllocFlag_OffscreenSurface)
2036 ERR("Creating offscreen surface\n");
2037 for (i = 0; i < *numbuffers; ++i)
2039 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight,
2040 allocinfo->Format, allocinfo->Pool, &surface[i], NULL);
2041 if (FAILED(hr))
2042 break;
2045 else if (allocinfo->dwFlags & VMR9AllocFlag_TextureSurface)
2047 TRACE("Creating texture surface\n");
2048 for (i = 0; i < *numbuffers; ++i)
2050 IDirect3DTexture9 *texture;
2052 hr = IDirect3DDevice9_CreateTexture(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight, 1, 0,
2053 allocinfo->Format, allocinfo->Pool, &texture, NULL);
2054 if (FAILED(hr))
2055 break;
2056 IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface[i]);
2057 IDirect3DTexture9_Release(texture);
2060 else
2062 FIXME("Could not allocate for type %08x\n", allocinfo->dwFlags);
2063 return E_NOTIMPL;
2066 if (i >= allocinfo->MinBuffers)
2068 hr = S_OK;
2069 *numbuffers = i;
2071 else
2073 for ( ; i > 0; --i) IDirect3DSurface9_Release(surface[i - 1]);
2074 *numbuffers = 0;
2076 return hr;
2079 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9 *iface, LONG code, LONG_PTR param1, LONG_PTR param2)
2081 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2083 FIXME("(%p/%p)->(...) stub\n", iface, This);
2084 return E_NOTIMPL;
2087 static const IVMRSurfaceAllocatorNotify9Vtbl VMR9_SurfaceAllocatorNotify_Vtbl =
2089 VMR9SurfaceAllocatorNotify_QueryInterface,
2090 VMR9SurfaceAllocatorNotify_AddRef,
2091 VMR9SurfaceAllocatorNotify_Release,
2092 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator,
2093 VMR9SurfaceAllocatorNotify_SetD3DDevice,
2094 VMR9SurfaceAllocatorNotify_ChangeD3DDevice,
2095 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper,
2096 VMR9SurfaceAllocatorNotify_NotifyEvent
2099 static inline struct quartz_vmr *impl_from_IOverlay(IOverlay *iface)
2101 return CONTAINING_RECORD(iface, struct quartz_vmr, IOverlay_iface);
2104 static HRESULT WINAPI overlay_QueryInterface(IOverlay *iface, REFIID iid, void **out)
2106 struct quartz_vmr *filter = impl_from_IOverlay(iface);
2107 return IPin_QueryInterface(&filter->renderer.sink.pin.IPin_iface, iid, out);
2110 static ULONG WINAPI overlay_AddRef(IOverlay *iface)
2112 struct quartz_vmr *filter = impl_from_IOverlay(iface);
2113 return IPin_AddRef(&filter->renderer.sink.pin.IPin_iface);
2116 static ULONG WINAPI overlay_Release(IOverlay *iface)
2118 struct quartz_vmr *filter = impl_from_IOverlay(iface);
2119 return IPin_Release(&filter->renderer.sink.pin.IPin_iface);
2122 static HRESULT WINAPI overlay_GetPalette(IOverlay *iface, DWORD *count, PALETTEENTRY **palette)
2124 FIXME("iface %p, count %p, palette %p, stub!\n", iface, count, palette);
2125 return E_NOTIMPL;
2128 static HRESULT WINAPI overlay_SetPalette(IOverlay *iface, DWORD count, PALETTEENTRY *palette)
2130 FIXME("iface %p, count %u, palette %p, stub!\n", iface, count, palette);
2131 return E_NOTIMPL;
2134 static HRESULT WINAPI overlay_GetDefaultColorKey(IOverlay *iface, COLORKEY *key)
2136 FIXME("iface %p, key %p, stub!\n", iface, key);
2137 return E_NOTIMPL;
2140 static HRESULT WINAPI overlay_GetColorKey(IOverlay *iface, COLORKEY *key)
2142 FIXME("iface %p, key %p, stub!\n", iface, key);
2143 return E_NOTIMPL;
2146 static HRESULT WINAPI overlay_SetColorKey(IOverlay *iface, COLORKEY *key)
2148 FIXME("iface %p, key %p, stub!\n", iface, key);
2149 return E_NOTIMPL;
2152 static HRESULT WINAPI overlay_GetWindowHandle(IOverlay *iface, HWND *window)
2154 struct quartz_vmr *filter = impl_from_IOverlay(iface);
2156 TRACE("filter %p, window %p.\n", filter, window);
2158 *window = filter->baseControlWindow.baseWindow.hWnd;
2159 return S_OK;
2162 static HRESULT WINAPI overlay_GetClipList(IOverlay *iface, RECT *source, RECT *dest, RGNDATA **region)
2164 FIXME("iface %p, source %p, dest %p, region %p, stub!\n", iface, source, dest, region);
2165 return E_NOTIMPL;
2168 static HRESULT WINAPI overlay_GetVideoPosition(IOverlay *iface, RECT *source, RECT *dest)
2170 FIXME("iface %p, source %p, dest %p, stub!\n", iface, source, dest);
2171 return E_NOTIMPL;
2174 static HRESULT WINAPI overlay_Advise(IOverlay *iface, IOverlayNotify *sink, DWORD flags)
2176 FIXME("iface %p, sink %p, flags %#x, stub!\n", iface, sink, flags);
2177 return E_NOTIMPL;
2180 static HRESULT WINAPI overlay_Unadvise(IOverlay *iface)
2182 FIXME("iface %p, stub!\n", iface);
2183 return E_NOTIMPL;
2186 static const IOverlayVtbl overlay_vtbl =
2188 overlay_QueryInterface,
2189 overlay_AddRef,
2190 overlay_Release,
2191 overlay_GetPalette,
2192 overlay_SetPalette,
2193 overlay_GetDefaultColorKey,
2194 overlay_GetColorKey,
2195 overlay_SetColorKey,
2196 overlay_GetWindowHandle,
2197 overlay_GetClipList,
2198 overlay_GetVideoPosition,
2199 overlay_Advise,
2200 overlay_Unadvise,
2203 static HRESULT vmr_create(IUnknown *outer, void **out, const CLSID *clsid)
2205 HRESULT hr;
2206 struct quartz_vmr* pVMR;
2208 *out = NULL;
2210 pVMR = CoTaskMemAlloc(sizeof(struct quartz_vmr));
2212 pVMR->hD3d9 = LoadLibraryA("d3d9.dll");
2213 if (!pVMR->hD3d9 )
2215 WARN("Could not load d3d9.dll\n");
2216 CoTaskMemFree(pVMR);
2217 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
2220 pVMR->IAMCertifiedOutputProtection_iface.lpVtbl = &IAMCertifiedOutputProtection_Vtbl;
2221 pVMR->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl;
2223 pVMR->mode = 0;
2224 pVMR->allocator_d3d9_dev = NULL;
2225 pVMR->allocator_mon= NULL;
2226 pVMR->num_surfaces = pVMR->cur_surface = 0;
2227 pVMR->allocator = NULL;
2228 pVMR->presenter = NULL;
2229 pVMR->hWndClippingWindow = NULL;
2230 pVMR->IVMRFilterConfig_iface.lpVtbl = &VMR7_FilterConfig_Vtbl;
2231 pVMR->IVMRFilterConfig9_iface.lpVtbl = &VMR9_FilterConfig_Vtbl;
2232 pVMR->IVMRMonitorConfig_iface.lpVtbl = &VMR7_MonitorConfig_Vtbl;
2233 pVMR->IVMRMonitorConfig9_iface.lpVtbl = &VMR9_MonitorConfig_Vtbl;
2234 pVMR->IVMRSurfaceAllocatorNotify_iface.lpVtbl = &VMR7_SurfaceAllocatorNotify_Vtbl;
2235 pVMR->IVMRSurfaceAllocatorNotify9_iface.lpVtbl = &VMR9_SurfaceAllocatorNotify_Vtbl;
2236 pVMR->IVMRWindowlessControl_iface.lpVtbl = &VMR7_WindowlessControl_Vtbl;
2237 pVMR->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl;
2238 pVMR->IOverlay_iface.lpVtbl = &overlay_vtbl;
2240 hr = strmbase_renderer_init(&pVMR->renderer, outer, clsid, L"VMR Input0", &renderer_ops);
2241 if (FAILED(hr))
2242 goto fail;
2244 hr = strmbase_window_init(&pVMR->baseControlWindow, &IVideoWindow_VTable,
2245 &pVMR->renderer.filter, &pVMR->renderer.sink.pin, &renderer_BaseWindowFuncTable);
2246 if (FAILED(hr))
2247 goto fail;
2249 if (FAILED(hr = BaseWindowImpl_PrepareWindow(&pVMR->baseControlWindow.baseWindow)))
2250 goto fail;
2252 hr = strmbase_video_init(&pVMR->baseControlVideo, &pVMR->renderer.filter,
2253 &pVMR->renderer.sink.pin, &renderer_BaseControlVideoFuncTable);
2254 if (FAILED(hr))
2255 goto fail;
2257 pVMR->run_event = CreateEventW(NULL, TRUE, FALSE, NULL);
2259 *out = &pVMR->renderer.filter.IUnknown_inner;
2260 ZeroMemory(&pVMR->source_rect, sizeof(RECT));
2261 ZeroMemory(&pVMR->target_rect, sizeof(RECT));
2262 TRACE("Created at %p\n", pVMR);
2263 return hr;
2265 fail:
2266 BaseWindowImpl_DoneWithWindow(&pVMR->baseControlWindow.baseWindow);
2267 strmbase_renderer_cleanup(&pVMR->renderer);
2268 FreeLibrary(pVMR->hD3d9);
2269 CoTaskMemFree(pVMR);
2270 return hr;
2273 HRESULT VMR7Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2275 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer);
2278 HRESULT VMR9Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2280 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer9);
2284 static HRESULT WINAPI VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID riid, void **ppv)
2286 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2287 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
2289 *ppv = NULL;
2291 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IVMRImagePresenter9))
2292 *ppv = &This->IVMRImagePresenter9_iface;
2293 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorEx9))
2294 *ppv = &This->IVMRSurfaceAllocatorEx9_iface;
2296 if (*ppv)
2298 IUnknown_AddRef((IUnknown *)(*ppv));
2299 return S_OK;
2302 FIXME("No interface for %s\n", debugstr_guid(riid));
2304 return E_NOINTERFACE;
2307 static ULONG WINAPI VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 *iface)
2309 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2310 ULONG refCount = InterlockedIncrement(&This->refCount);
2312 TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
2314 return refCount;
2317 static ULONG WINAPI VMR9_ImagePresenter_Release(IVMRImagePresenter9 *iface)
2319 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2320 ULONG refCount = InterlockedDecrement(&This->refCount);
2322 TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
2324 if (!refCount)
2326 DWORD i;
2327 TRACE("Destroying\n");
2328 IDirect3D9_Release(This->d3d9_ptr);
2330 TRACE("Number of surfaces: %u\n", This->num_surfaces);
2331 for (i = 0; i < This->num_surfaces; ++i)
2333 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2334 TRACE("Releasing surface %p\n", surface);
2335 if (surface)
2336 IDirect3DSurface9_Release(surface);
2339 CoTaskMemFree(This->d3d9_surfaces);
2340 This->d3d9_surfaces = NULL;
2341 This->num_surfaces = 0;
2342 if (This->d3d9_vertex)
2344 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2345 This->d3d9_vertex = NULL;
2347 CoTaskMemFree(This);
2348 return 0;
2350 return refCount;
2353 static HRESULT WINAPI VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2355 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2357 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2358 return S_OK;
2361 static HRESULT WINAPI VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2363 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2365 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2366 return S_OK;
2369 #define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
2370 struct VERTEX { float x, y, z, rhw, u, v; };
2372 static HRESULT VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2374 IDirect3DTexture9 *texture = NULL;
2375 HRESULT hr;
2377 hr = IDirect3DDevice9_SetFVF(This->d3d9_dev, USED_FVF);
2378 if (FAILED(hr))
2380 FIXME("SetFVF: %08x\n", hr);
2381 return hr;
2384 hr = IDirect3DDevice9_SetStreamSource(This->d3d9_dev, 0, This->d3d9_vertex, 0, sizeof(struct VERTEX));
2385 if (FAILED(hr))
2387 FIXME("SetStreamSource: %08x\n", hr);
2388 return hr;
2391 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **) &texture);
2392 if (FAILED(hr))
2394 FIXME("IDirect3DSurface9_GetContainer failed\n");
2395 return hr;
2397 hr = IDirect3DDevice9_SetTexture(This->d3d9_dev, 0, (IDirect3DBaseTexture9 *)texture);
2398 IDirect3DTexture9_Release(texture);
2399 if (FAILED(hr))
2401 FIXME("SetTexture: %08x\n", hr);
2402 return hr;
2405 hr = IDirect3DDevice9_DrawPrimitive(This->d3d9_dev, D3DPT_TRIANGLESTRIP, 0, 2);
2406 if (FAILED(hr))
2408 FIXME("DrawPrimitive: %08x\n", hr);
2409 return hr;
2412 return S_OK;
2415 static HRESULT VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2417 HRESULT hr;
2418 IDirect3DSurface9 *target = NULL;
2419 RECT target_rect;
2421 hr = IDirect3DDevice9_GetBackBuffer(This->d3d9_dev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &target);
2422 if (FAILED(hr))
2424 ERR("IDirect3DDevice9_GetBackBuffer -- %08x\n", hr);
2425 return hr;
2428 /* Move rect to origin and flip it */
2429 SetRect(&target_rect, 0, This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top,
2430 This->pVMR9->target_rect.right - This->pVMR9->target_rect.left, 0);
2432 hr = IDirect3DDevice9_StretchRect(This->d3d9_dev, surface, &This->pVMR9->source_rect, target, &target_rect, D3DTEXF_LINEAR);
2433 if (FAILED(hr))
2434 ERR("IDirect3DDevice9_StretchRect -- %08x\n", hr);
2435 IDirect3DSurface9_Release(target);
2437 return hr;
2440 static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR id, VMR9PresentationInfo *info)
2442 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2443 HRESULT hr;
2444 RECT output;
2445 BOOL render = FALSE;
2447 TRACE("(%p/%p/%p)->(...) stub\n", iface, This, This->pVMR9);
2448 GetWindowRect(This->pVMR9->baseControlWindow.baseWindow.hWnd, &output);
2449 TRACE("Output rectangle: %s\n", wine_dbgstr_rect(&output));
2451 /* This might happen if we don't have active focus (eg on a different virtual desktop) */
2452 if (!This->d3d9_dev)
2453 return S_OK;
2455 /* Display image here */
2456 hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
2457 if (FAILED(hr))
2458 FIXME("hr: %08x\n", hr);
2459 hr = IDirect3DDevice9_BeginScene(This->d3d9_dev);
2460 if (SUCCEEDED(hr))
2462 if (This->d3d9_vertex)
2463 hr = VMR9_ImagePresenter_PresentTexture(This, info->lpSurf);
2464 else
2465 hr = VMR9_ImagePresenter_PresentOffscreenSurface(This, info->lpSurf);
2466 render = SUCCEEDED(hr);
2468 else
2469 FIXME("BeginScene: %08x\n", hr);
2470 hr = IDirect3DDevice9_EndScene(This->d3d9_dev);
2471 if (render && SUCCEEDED(hr))
2473 hr = IDirect3DDevice9_Present(This->d3d9_dev, NULL, NULL, This->pVMR9->baseControlWindow.baseWindow.hWnd, NULL);
2474 if (FAILED(hr))
2475 FIXME("Presenting image: %08x\n", hr);
2478 return S_OK;
2481 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter =
2483 VMR9_ImagePresenter_QueryInterface,
2484 VMR9_ImagePresenter_AddRef,
2485 VMR9_ImagePresenter_Release,
2486 VMR9_ImagePresenter_StartPresenting,
2487 VMR9_ImagePresenter_StopPresenting,
2488 VMR9_ImagePresenter_PresentImage
2491 static HRESULT WINAPI VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9 *iface, REFIID riid, LPVOID * ppv)
2493 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2495 return VMR9_ImagePresenter_QueryInterface(&This->IVMRImagePresenter9_iface, riid, ppv);
2498 static ULONG WINAPI VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9 *iface)
2500 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2502 return VMR9_ImagePresenter_AddRef(&This->IVMRImagePresenter9_iface);
2505 static ULONG WINAPI VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9 *iface)
2507 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2509 return VMR9_ImagePresenter_Release(&This->IVMRImagePresenter9_iface);
2512 static HRESULT VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *allocinfo)
2514 D3DCAPS9 caps;
2515 UINT width, height;
2516 HRESULT hr;
2518 if (!(allocinfo->dwFlags & VMR9AllocFlag_TextureSurface))
2519 /* Only needed for texture surfaces */
2520 return S_OK;
2522 hr = IDirect3DDevice9_GetDeviceCaps(This->d3d9_dev, &caps);
2523 if (FAILED(hr))
2524 return hr;
2526 if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2) || (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY))
2528 width = allocinfo->dwWidth;
2529 height = allocinfo->dwHeight;
2531 else
2533 width = height = 1;
2534 while (width < allocinfo->dwWidth)
2535 width *= 2;
2537 while (height < allocinfo->dwHeight)
2538 height *= 2;
2539 FIXME("NPOW2 support missing, not using proper surfaces!\n");
2542 if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
2544 if (height > width)
2545 width = height;
2546 else
2547 height = width;
2548 FIXME("Square texture support required..\n");
2551 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF, allocinfo->Pool, &This->d3d9_vertex, NULL);
2552 if (FAILED(hr))
2554 ERR("Couldn't create vertex buffer: %08x\n", hr);
2555 return hr;
2558 This->reset = TRUE;
2559 allocinfo->dwHeight = height;
2560 allocinfo->dwWidth = width;
2562 return hr;
2565 static UINT d3d9_adapter_from_hwnd(IDirect3D9 *d3d9, HWND hwnd, HMONITOR *mon_out)
2567 UINT d3d9_adapter;
2568 HMONITOR mon;
2570 mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
2571 if (!mon)
2572 d3d9_adapter = 0;
2573 else
2575 for (d3d9_adapter = 0; d3d9_adapter < IDirect3D9_GetAdapterCount(d3d9); ++d3d9_adapter)
2577 if (mon == IDirect3D9_GetAdapterMonitor(d3d9, d3d9_adapter))
2578 break;
2580 if (d3d9_adapter >= IDirect3D9_GetAdapterCount(d3d9))
2581 d3d9_adapter = 0;
2583 if (mon_out)
2584 *mon_out = mon;
2585 return d3d9_adapter;
2588 static BOOL CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *info, DWORD *numbuffers)
2590 D3DPRESENT_PARAMETERS d3dpp;
2591 DWORD d3d9_adapter;
2592 HRESULT hr;
2594 TRACE("(%p)->()\n", This);
2596 /* Obtain a monitor and d3d9 device */
2597 d3d9_adapter = d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon);
2599 /* Now try to create the d3d9 device */
2600 ZeroMemory(&d3dpp, sizeof(d3dpp));
2601 d3dpp.Windowed = TRUE;
2602 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2603 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2604 d3dpp.BackBufferHeight = This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top;
2605 d3dpp.BackBufferWidth = This->pVMR9->target_rect.right - This->pVMR9->target_rect.left;
2607 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev);
2608 if (FAILED(hr))
2610 ERR("Could not create device: %08x\n", hr);
2611 return FALSE;
2613 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2615 This->d3d9_surfaces = CoTaskMemAlloc(*numbuffers * sizeof(IDirect3DSurface9 *));
2616 ZeroMemory(This->d3d9_surfaces, *numbuffers * sizeof(IDirect3DSurface9 *));
2618 hr = VMR9_SurfaceAllocator_SetAllocationSettings(This, info);
2619 if (FAILED(hr))
2620 ERR("Setting allocation settings failed: %08x\n", hr);
2622 if (SUCCEEDED(hr))
2624 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, info, numbuffers, This->d3d9_surfaces);
2625 if (FAILED(hr))
2626 ERR("Allocating surfaces failed: %08x\n", hr);
2629 if (FAILED(hr))
2631 IVMRSurfaceAllocatorEx9_TerminateDevice(This->pVMR9->allocator, This->pVMR9->cookie);
2632 return FALSE;
2635 This->num_surfaces = *numbuffers;
2637 return TRUE;
2640 static HRESULT WINAPI VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, VMR9AllocationInfo *allocinfo, DWORD *numbuffers)
2642 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2644 if (This->pVMR9->mode != VMR9Mode_Windowed && !This->pVMR9->hWndClippingWindow)
2646 ERR("No window set\n");
2647 return VFW_E_WRONG_STATE;
2650 This->info = *allocinfo;
2652 if (!CreateRenderingWindow(This, allocinfo, numbuffers))
2654 ERR("Failed to create rendering window, expect no output!\n");
2655 return VFW_E_WRONG_STATE;
2658 return S_OK;
2661 static HRESULT WINAPI VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id)
2663 TRACE("iface %p, id %#lx.\n", iface, id);
2665 return S_OK;
2668 /* Recreate all surfaces (If allocated as D3DPOOL_DEFAULT) and survive! */
2669 static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl *This)
2671 struct VERTEX t_vert[4];
2672 UINT width, height;
2673 unsigned int i;
2674 void *bits = NULL;
2675 D3DPRESENT_PARAMETERS d3dpp;
2676 HRESULT hr;
2678 if (!This->d3d9_surfaces || !This->reset)
2679 return S_OK;
2681 This->reset = FALSE;
2682 TRACE("RESETTING\n");
2683 if (This->d3d9_vertex)
2685 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2686 This->d3d9_vertex = NULL;
2689 for (i = 0; i < This->num_surfaces; ++i)
2691 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2692 TRACE("Releasing surface %p\n", surface);
2693 if (surface)
2694 IDirect3DSurface9_Release(surface);
2696 ZeroMemory(This->d3d9_surfaces, sizeof(IDirect3DSurface9 *) * This->num_surfaces);
2698 /* Now try to create the d3d9 device */
2699 ZeroMemory(&d3dpp, sizeof(d3dpp));
2700 d3dpp.Windowed = TRUE;
2701 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2702 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2704 if (This->d3d9_dev)
2705 IDirect3DDevice9_Release(This->d3d9_dev);
2706 This->d3d9_dev = NULL;
2707 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon), D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev);
2708 if (FAILED(hr))
2710 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon), D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev);
2711 if (FAILED(hr))
2713 ERR("--> Creating device: %08x\n", hr);
2714 return S_OK;
2717 IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2719 IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, &This->info, &This->num_surfaces, This->d3d9_surfaces);
2721 This->reset = FALSE;
2723 if (!(This->info.dwFlags & VMR9AllocFlag_TextureSurface))
2724 return S_OK;
2726 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF,
2727 This->info.Pool, &This->d3d9_vertex, NULL);
2729 width = This->info.dwWidth;
2730 height = This->info.dwHeight;
2732 for (i = 0; i < ARRAY_SIZE(t_vert); ++i)
2734 if (i % 2)
2736 t_vert[i].x = (float)This->pVMR9->target_rect.right - (float)This->pVMR9->target_rect.left - 0.5f;
2737 t_vert[i].u = (float)This->pVMR9->source_rect.right / (float)width;
2739 else
2741 t_vert[i].x = -0.5f;
2742 t_vert[i].u = (float)This->pVMR9->source_rect.left / (float)width;
2745 if (i % 4 < 2)
2747 t_vert[i].y = -0.5f;
2748 t_vert[i].v = (float)This->pVMR9->source_rect.bottom / (float)height;
2750 else
2752 t_vert[i].y = (float)This->pVMR9->target_rect.bottom - (float)This->pVMR9->target_rect.top - 0.5f;
2753 t_vert[i].v = (float)This->pVMR9->source_rect.top / (float)height;
2755 t_vert[i].z = 0.0f;
2756 t_vert[i].rhw = 1.0f;
2759 FIXME("Vertex rectangle:\n");
2760 FIXME("X, Y: %f, %f\n", t_vert[0].x, t_vert[0].y);
2761 FIXME("X, Y: %f, %f\n", t_vert[3].x, t_vert[3].y);
2762 FIXME("TOP, LEFT: %f, %f\n", t_vert[0].u, t_vert[0].v);
2763 FIXME("DOWN, BOTTOM: %f, %f\n", t_vert[3].u, t_vert[3].v);
2765 IDirect3DVertexBuffer9_Lock(This->d3d9_vertex, 0, sizeof(t_vert), &bits, 0);
2766 memcpy(bits, t_vert, sizeof(t_vert));
2767 IDirect3DVertexBuffer9_Unlock(This->d3d9_vertex);
2769 return S_OK;
2772 static HRESULT WINAPI VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, DWORD surfaceindex, DWORD flags, IDirect3DSurface9 **surface)
2774 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2776 /* Update everything first, this is needed because the surface might be destroyed in the reset */
2777 if (!This->d3d9_dev)
2779 TRACE("Device has left me!\n");
2780 return E_FAIL;
2783 VMR9_SurfaceAllocator_UpdateDeviceReset(This);
2785 if (surfaceindex >= This->num_surfaces)
2787 ERR("surfaceindex is greater than num_surfaces\n");
2788 return E_FAIL;
2790 *surface = This->d3d9_surfaces[surfaceindex];
2791 IDirect3DSurface9_AddRef(*surface);
2793 return S_OK;
2796 static HRESULT WINAPI VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9 *iface, IVMRSurfaceAllocatorNotify9 *allocnotify)
2798 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2800 TRACE("(%p/%p)->(...)\n", iface, This);
2802 /* No AddRef taken here or the base VMR9 filter would never be destroyed */
2803 This->SurfaceAllocatorNotify = allocnotify;
2804 return S_OK;
2807 static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator =
2809 VMR9_SurfaceAllocator_QueryInterface,
2810 VMR9_SurfaceAllocator_AddRef,
2811 VMR9_SurfaceAllocator_Release,
2812 VMR9_SurfaceAllocator_InitializeDevice,
2813 VMR9_SurfaceAllocator_TerminateDevice,
2814 VMR9_SurfaceAllocator_GetSurface,
2815 VMR9_SurfaceAllocator_AdviseNotify,
2816 NULL /* This isn't the SurfaceAllocatorEx type yet, working on it */
2819 static IDirect3D9 *init_d3d9(HMODULE d3d9_handle)
2821 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion);
2823 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
2824 if (!d3d9_create) return NULL;
2826 return d3d9_create(D3D_SDK_VERSION);
2829 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv)
2831 HRESULT hr = S_OK;
2832 int i;
2833 VMR9DefaultAllocatorPresenterImpl* This;
2835 This = CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl));
2836 if (!This)
2837 return E_OUTOFMEMORY;
2839 This->d3d9_ptr = init_d3d9(parent->hD3d9);
2840 if (!This->d3d9_ptr)
2842 WARN("Could not initialize d3d9.dll\n");
2843 CoTaskMemFree(This);
2844 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
2847 i = 0;
2850 D3DDISPLAYMODE mode;
2852 hr = IDirect3D9_EnumAdapterModes(This->d3d9_ptr, i++, D3DFMT_X8R8G8B8, 0, &mode);
2853 if (hr == D3DERR_INVALIDCALL) break; /* out of adapters */
2854 } while (FAILED(hr));
2855 if (FAILED(hr))
2856 ERR("HR: %08x\n", hr);
2857 if (hr == D3DERR_NOTAVAILABLE)
2859 ERR("Format not supported\n");
2860 IDirect3D9_Release(This->d3d9_ptr);
2861 CoTaskMemFree(This);
2862 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
2865 This->IVMRImagePresenter9_iface.lpVtbl = &VMR9_ImagePresenter;
2866 This->IVMRSurfaceAllocatorEx9_iface.lpVtbl = &VMR9_SurfaceAllocator;
2868 This->refCount = 1;
2869 This->pVMR9 = parent;
2870 This->d3d9_surfaces = NULL;
2871 This->d3d9_dev = NULL;
2872 This->hMon = 0;
2873 This->d3d9_vertex = NULL;
2874 This->num_surfaces = 0;
2875 This->SurfaceAllocatorNotify = NULL;
2876 This->reset = FALSE;
2878 *ppv = &This->IVMRImagePresenter9_iface;
2879 return S_OK;