TESTING -- override pthreads to fix gstreamer v5
[wine/multimedia.git] / dlls / quartz / vmr9.c
blob3538ddb1fe8fdf73e6d2d0a2f8824736ab348c45
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 "config.h"
25 #include "quartz_private.h"
27 #include "uuids.h"
28 #include "vfwmsgs.h"
29 #include "amvideo.h"
30 #include "windef.h"
31 #include "winbase.h"
32 #include "dshow.h"
33 #include "evcode.h"
34 #include "strmif.h"
35 #include "ddraw.h"
36 #include "dvdmedia.h"
37 #include "d3d9.h"
38 #include "vmr9.h"
39 #include "pin.h"
41 #include "wine/unicode.h"
42 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
46 struct quartz_vmr
48 BaseRenderer renderer;
49 BaseControlWindow baseControlWindow;
50 BaseControlVideo baseControlVideo;
52 IUnknown IUnknown_inner;
53 IAMCertifiedOutputProtection IAMCertifiedOutputProtection_iface;
54 IAMFilterMiscFlags IAMFilterMiscFlags_iface;
55 IVMRFilterConfig IVMRFilterConfig_iface;
56 IVMRFilterConfig9 IVMRFilterConfig9_iface;
57 IVMRMonitorConfig IVMRMonitorConfig_iface;
58 IVMRMonitorConfig9 IVMRMonitorConfig9_iface;
59 IVMRSurfaceAllocatorNotify IVMRSurfaceAllocatorNotify_iface;
60 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface;
61 IVMRWindowlessControl IVMRWindowlessControl_iface;
62 IVMRWindowlessControl9 IVMRWindowlessControl9_iface;
64 IVMRSurfaceAllocatorEx9 *allocator;
65 IVMRImagePresenter9 *presenter;
66 BOOL allocator_is_ex;
69 * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed
70 * What I do is implement windowless as a special case of renderless, and then
71 * windowed also as a special case of windowless. This is probably the easiest way.
73 VMR9Mode mode;
74 BITMAPINFOHEADER bmiheader;
75 IUnknown * outer_unk;
76 BOOL bUnkOuterValid;
77 BOOL bAggregatable;
79 HMODULE hD3d9;
81 /* Presentation related members */
82 IDirect3DDevice9 *allocator_d3d9_dev;
83 HMONITOR allocator_mon;
84 DWORD num_surfaces;
85 DWORD cur_surface;
86 DWORD_PTR cookie;
88 /* for Windowless Mode */
89 HWND hWndClippingWindow;
91 RECT source_rect;
92 RECT target_rect;
93 LONG VideoWidth;
94 LONG VideoHeight;
97 static inline struct quartz_vmr *impl_from_inner_IUnknown(IUnknown *iface)
99 return CONTAINING_RECORD(iface, struct quartz_vmr, IUnknown_inner);
102 static inline struct quartz_vmr *impl_from_BaseWindow(BaseWindow *wnd)
104 return CONTAINING_RECORD(wnd, struct quartz_vmr, baseControlWindow.baseWindow);
107 static inline struct quartz_vmr *impl_from_IVideoWindow(IVideoWindow *iface)
109 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlWindow.IVideoWindow_iface);
112 static inline struct quartz_vmr *impl_from_BaseControlVideo(BaseControlVideo *cvid)
114 return CONTAINING_RECORD(cvid, struct quartz_vmr, baseControlVideo);
117 static inline struct quartz_vmr *impl_from_IBasicVideo(IBasicVideo *iface)
119 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlVideo.IBasicVideo_iface);
122 static inline struct quartz_vmr *impl_from_IAMCertifiedOutputProtection(IAMCertifiedOutputProtection *iface)
124 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMCertifiedOutputProtection_iface);
127 static inline struct quartz_vmr *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
129 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMFilterMiscFlags_iface);
132 static inline struct quartz_vmr *impl_from_IVMRFilterConfig(IVMRFilterConfig *iface)
134 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig_iface);
137 static inline struct quartz_vmr *impl_from_IVMRFilterConfig9(IVMRFilterConfig9 *iface)
139 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig9_iface);
142 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig(IVMRMonitorConfig *iface)
144 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig_iface);
147 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig9(IVMRMonitorConfig9 *iface)
149 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig9_iface);
152 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify(IVMRSurfaceAllocatorNotify *iface)
154 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify_iface);
157 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify9(IVMRSurfaceAllocatorNotify9 *iface)
159 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify9_iface);
162 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl(IVMRWindowlessControl *iface)
164 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl_iface);
167 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl9(IVMRWindowlessControl9 *iface)
169 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl9_iface);
172 typedef struct
174 IVMRImagePresenter9 IVMRImagePresenter9_iface;
175 IVMRSurfaceAllocatorEx9 IVMRSurfaceAllocatorEx9_iface;
177 LONG refCount;
179 HANDLE ack;
180 DWORD tid;
181 HANDLE hWndThread;
183 IDirect3DDevice9 *d3d9_dev;
184 IDirect3D9 *d3d9_ptr;
185 IDirect3DSurface9 **d3d9_surfaces;
186 IDirect3DVertexBuffer9 *d3d9_vertex;
187 HMONITOR hMon;
188 DWORD num_surfaces;
190 BOOL reset;
191 VMR9AllocationInfo info;
193 struct quartz_vmr* pVMR9;
194 IVMRSurfaceAllocatorNotify9 *SurfaceAllocatorNotify;
195 } VMR9DefaultAllocatorPresenterImpl;
197 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRImagePresenter9( IVMRImagePresenter9 *iface)
199 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRImagePresenter9_iface);
202 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRSurfaceAllocatorEx9( IVMRSurfaceAllocatorEx9 *iface)
204 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRSurfaceAllocatorEx9_iface);
207 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv);
209 static DWORD VMR9_SendSampleData(struct quartz_vmr *This, VMR9PresentationInfo *info, LPBYTE data,
210 DWORD size)
212 AM_MEDIA_TYPE *amt;
213 HRESULT hr = S_OK;
214 int width;
215 int height;
216 BITMAPINFOHEADER *bmiHeader;
217 D3DLOCKED_RECT lock;
219 TRACE("%p %p %d\n", This, data, size);
221 amt = &This->renderer.pInputPin->pin.mtCurrent;
223 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
225 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
227 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
229 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
231 else
233 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
234 return VFW_E_RUNTIME_ERROR;
237 TRACE("biSize = %d\n", bmiHeader->biSize);
238 TRACE("biWidth = %d\n", bmiHeader->biWidth);
239 TRACE("biHeight = %d\n", bmiHeader->biHeight);
240 TRACE("biPlanes = %d\n", bmiHeader->biPlanes);
241 TRACE("biBitCount = %d\n", bmiHeader->biBitCount);
242 TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(bmiHeader->biCompression), 4));
243 TRACE("biSizeImage = %d\n", bmiHeader->biSizeImage);
245 width = bmiHeader->biWidth;
246 height = bmiHeader->biHeight;
248 TRACE("Src Rect: %d %d %d %d\n", This->source_rect.left, This->source_rect.top, This->source_rect.right, This->source_rect.bottom);
249 TRACE("Dst Rect: %d %d %d %d\n", This->target_rect.left, This->target_rect.top, This->target_rect.right, This->target_rect.bottom);
251 hr = IDirect3DSurface9_LockRect(info->lpSurf, &lock, NULL, D3DLOCK_DISCARD);
252 if (FAILED(hr))
254 ERR("IDirect3DSurface9_LockRect failed (%x)\n",hr);
255 return hr;
258 if (lock.Pitch != width * bmiHeader->biBitCount / 8)
260 WARN("Slow path! %u/%u\n", lock.Pitch, width * bmiHeader->biBitCount/8);
262 while (height--)
264 memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8);
265 data = data + width * bmiHeader->biBitCount / 8;
266 lock.pBits = (char *)lock.pBits + lock.Pitch;
269 else memcpy(lock.pBits, data, size);
271 IDirect3DSurface9_UnlockRect(info->lpSurf);
273 hr = IVMRImagePresenter9_PresentImage(This->presenter, This->cookie, info);
274 return hr;
277 static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample)
279 struct quartz_vmr *This = (struct quartz_vmr*)iface;
280 LPBYTE pbSrcStream = NULL;
281 long cbSrcStream = 0;
282 REFERENCE_TIME tStart, tStop;
283 VMR9PresentationInfo info;
284 HRESULT hr;
286 TRACE("%p %p\n", iface, pSample);
288 /* It is possible that there is no device at this point */
290 if (!This->allocator || !This->presenter)
292 ERR("NO PRESENTER!!\n");
293 return S_FALSE;
296 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
297 if (FAILED(hr))
298 info.dwFlags = VMR9Sample_SrcDstRectsValid;
299 else
300 info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid;
302 if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
303 info.dwFlags |= VMR9Sample_Discontinuity;
305 if (IMediaSample_IsPreroll(pSample) == S_OK)
306 info.dwFlags |= VMR9Sample_Preroll;
308 if (IMediaSample_IsSyncPoint(pSample) == S_OK)
309 info.dwFlags |= VMR9Sample_SyncPoint;
311 /* If we render ourselves, and this is a preroll sample, discard it */
312 if (This->baseControlWindow.baseWindow.hWnd && (info.dwFlags & VMR9Sample_Preroll))
314 return S_OK;
317 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
318 if (FAILED(hr))
320 ERR("Cannot get pointer to sample data (%x)\n", hr);
321 return hr;
324 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
326 info.rtStart = tStart;
327 info.rtEnd = tStop;
328 info.szAspectRatio.cx = This->bmiheader.biWidth;
329 info.szAspectRatio.cy = This->bmiheader.biHeight;
331 hr = IVMRSurfaceAllocatorEx9_GetSurface(This->allocator, This->cookie, (++This->cur_surface)%This->num_surfaces, 0, &info.lpSurf);
333 if (FAILED(hr))
334 return hr;
336 VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream);
337 IDirect3DSurface9_Release(info.lpSurf);
339 return hr;
342 static HRESULT WINAPI VMR9_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt)
344 struct quartz_vmr *This = (struct quartz_vmr*)iface;
346 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat)
347 return S_FALSE;
349 /* Ignore subtype, test for bicompression instead */
350 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
352 VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
354 This->bmiheader = format->bmiHeader;
355 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
356 This->source_rect.right = This->VideoWidth = format->bmiHeader.biWidth;
357 This->source_rect.bottom = This->VideoHeight = format->bmiHeader.biHeight;
358 This->source_rect.top = This->source_rect.left = 0;
360 else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
362 VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat;
364 This->bmiheader = format->bmiHeader;
366 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
367 This->source_rect.right = This->VideoWidth = format->bmiHeader.biWidth;
368 This->source_rect.bottom = This->VideoHeight = format->bmiHeader.biHeight;
369 This->source_rect.top = This->source_rect.left = 0;
371 else
373 ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
374 return S_FALSE;
376 if (This->bmiheader.biCompression)
377 return S_FALSE;
378 return S_OK;
381 static HRESULT VMR9_maybe_init(struct quartz_vmr *This, BOOL force)
383 VMR9AllocationInfo info;
384 DWORD buffers;
385 HRESULT hr;
387 TRACE("my mode: %u, my window: %p, my last window: %p\n", This->mode, This->baseControlWindow.baseWindow.hWnd, This->hWndClippingWindow);
388 if (This->baseControlWindow.baseWindow.hWnd || !This->renderer.pInputPin->pin.pConnectedTo)
389 return S_OK;
391 if (This->mode == VMR9Mode_Windowless && !This->hWndClippingWindow)
392 return (force ? VFW_E_RUNTIME_ERROR : S_OK);
394 TRACE("Initializing\n");
395 info.dwFlags = VMR9AllocFlag_TextureSurface;
396 info.dwHeight = This->source_rect.bottom;
397 info.dwWidth = This->source_rect.right;
398 info.Pool = D3DPOOL_DEFAULT;
399 info.MinBuffers = 2;
400 FIXME("Reduce ratio to least common denominator\n");
401 info.szAspectRatio.cx = info.dwWidth;
402 info.szAspectRatio.cy = info.dwHeight;
403 info.szNativeSize.cx = This->bmiheader.biWidth;
404 info.szNativeSize.cy = This->bmiheader.biHeight;
405 buffers = 2;
407 switch (This->bmiheader.biBitCount)
409 case 8: info.Format = D3DFMT_R3G3B2; break;
410 case 15: info.Format = D3DFMT_X1R5G5B5; break;
411 case 16: info.Format = D3DFMT_R5G6B5; break;
412 case 24: info.Format = D3DFMT_R8G8B8; break;
413 case 32: info.Format = D3DFMT_X8R8G8B8; break;
414 default:
415 FIXME("Unknown bpp %u\n", This->bmiheader.biBitCount);
416 hr = E_INVALIDARG;
419 This->cur_surface = 0;
420 if (This->num_surfaces)
422 ERR("num_surfaces or d3d9_surfaces not 0\n");
423 return E_FAIL;
426 hr = IVMRSurfaceAllocatorEx9_InitializeDevice(This->allocator, This->cookie, &info, &buffers);
427 if (SUCCEEDED(hr))
429 This->source_rect.left = This->source_rect.top = 0;
430 This->source_rect.right = This->bmiheader.biWidth;
431 This->source_rect.bottom = This->bmiheader.biHeight;
433 This->num_surfaces = buffers;
435 return hr;
438 static VOID WINAPI VMR9_OnStartStreaming(BaseRenderer* iface)
440 struct quartz_vmr *This = (struct quartz_vmr*)iface;
442 TRACE("(%p)\n", This);
444 VMR9_maybe_init(This, TRUE);
445 IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie);
446 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
447 This->source_rect.left,
448 This->source_rect.top,
449 This->source_rect.right - This->source_rect.left,
450 This->source_rect.bottom - This->source_rect.top,
451 SWP_NOZORDER|SWP_NOMOVE|SWP_DEFERERASE);
452 ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_SHOW);
453 GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->target_rect);
456 static VOID WINAPI VMR9_OnStopStreaming(BaseRenderer* iface)
458 struct quartz_vmr *This = (struct quartz_vmr*)iface;
460 TRACE("(%p)\n", This);
462 if (This->renderer.filter.state == State_Running)
463 IVMRImagePresenter9_StopPresenting(This->presenter, This->cookie);
466 static HRESULT WINAPI VMR9_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime)
468 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
469 if (IMediaSample_IsPreroll(pSample) == S_OK)
470 return E_FAIL;
471 return S_FALSE;
474 static HRESULT WINAPI VMR9_CompleteConnect(BaseRenderer *This, IPin *pReceivePin)
476 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This;
477 HRESULT hr;
479 TRACE("(%p)\n", This);
481 if (pVMR9->mode ||
482 SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&pVMR9->IVMRFilterConfig9_iface, VMR9Mode_Windowed)))
483 hr = VMR9_maybe_init(pVMR9, FALSE);
485 return hr;
488 static HRESULT WINAPI VMR9_BreakConnect(BaseRenderer *This)
490 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This;
491 HRESULT hr = S_OK;
493 if (!pVMR9->mode)
494 return S_FALSE;
495 if (This->pInputPin->pin.pConnectedTo && pVMR9->allocator && pVMR9->presenter)
497 if (pVMR9->renderer.filter.state != State_Stopped)
499 ERR("Disconnecting while not stopped! UNTESTED!!\n");
501 if (pVMR9->renderer.filter.state == State_Running)
502 hr = IVMRImagePresenter9_StopPresenting(pVMR9->presenter, pVMR9->cookie);
503 IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9->allocator, pVMR9->cookie);
504 pVMR9->num_surfaces = 0;
506 return hr;
509 static const BaseRendererFuncTable BaseFuncTable = {
510 VMR9_CheckMediaType,
511 VMR9_DoRenderSample,
512 /**/
513 NULL,
514 NULL,
515 NULL,
516 VMR9_OnStartStreaming,
517 VMR9_OnStopStreaming,
518 NULL,
519 NULL,
520 NULL,
521 VMR9_ShouldDrawSampleNow,
522 NULL,
523 /**/
524 VMR9_CompleteConnect,
525 VMR9_BreakConnect,
526 NULL,
527 NULL,
528 NULL,
531 static LPWSTR WINAPI VMR9_GetClassWindowStyles(BaseWindow *This, DWORD *pClassStyles, DWORD *pWindowStyles, DWORD *pWindowStylesEx)
533 static WCHAR classnameW[] = { 'I','V','M','R','9',' ','C','l','a','s','s', 0 };
535 *pClassStyles = 0;
536 *pWindowStyles = WS_SIZEBOX;
537 *pWindowStylesEx = 0;
539 return classnameW;
542 static RECT WINAPI VMR9_GetDefaultRect(BaseWindow *This)
544 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
545 static RECT defRect;
547 defRect.left = defRect.top = 0;
548 defRect.right = pVMR9->VideoWidth;
549 defRect.bottom = pVMR9->VideoHeight;
551 return defRect;
554 static BOOL WINAPI VMR9_OnSize(BaseWindow *This, LONG Width, LONG Height)
556 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
558 TRACE("WM_SIZE %d %d\n", Width, Height);
559 GetClientRect(This->hWnd, &pVMR9->target_rect);
560 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
561 pVMR9->target_rect.left,
562 pVMR9->target_rect.top,
563 pVMR9->target_rect.right - pVMR9->target_rect.left,
564 pVMR9->target_rect.bottom - pVMR9->target_rect.top);
565 return BaseWindowImpl_OnSize(This, Width, Height);
568 static const BaseWindowFuncTable renderer_BaseWindowFuncTable = {
569 VMR9_GetClassWindowStyles,
570 VMR9_GetDefaultRect,
571 NULL,
572 BaseControlWindowImpl_PossiblyEatMessage,
573 VMR9_OnSize,
576 static HRESULT WINAPI VMR9_GetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
578 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
579 CopyRect(pSourceRect,&pVMR9->source_rect);
580 return S_OK;
583 static HRESULT WINAPI VMR9_GetStaticImage(BaseControlVideo* This, LONG *pBufferSize, LONG *pDIBImage)
585 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
586 BITMAPINFOHEADER *bmiHeader;
587 LONG needed_size;
588 AM_MEDIA_TYPE *amt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
589 char *ptr;
591 FIXME("(%p/%p)->(%p, %p): partial stub\n", pVMR9, This, pBufferSize, pDIBImage);
593 EnterCriticalSection(&pVMR9->renderer.filter.csFilter);
595 if (!pVMR9->renderer.pMediaSample)
597 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
598 return (pVMR9->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
601 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
603 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
605 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
607 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
609 else
611 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
612 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
613 return VFW_E_RUNTIME_ERROR;
616 needed_size = bmiHeader->biSize;
617 needed_size += IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample);
619 if (!pDIBImage)
621 *pBufferSize = needed_size;
622 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
623 return S_OK;
626 if (needed_size < *pBufferSize)
628 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
629 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
630 return E_FAIL;
632 *pBufferSize = needed_size;
634 memcpy(pDIBImage, bmiHeader, bmiHeader->biSize);
635 IMediaSample_GetPointer(pVMR9->renderer.pMediaSample, (BYTE **)&ptr);
636 memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample));
638 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
639 return S_OK;
642 static HRESULT WINAPI VMR9_GetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
644 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
645 CopyRect(pTargetRect,&pVMR9->target_rect);
646 return S_OK;
649 static VIDEOINFOHEADER* WINAPI VMR9_GetVideoFormat(BaseControlVideo* This)
651 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
652 AM_MEDIA_TYPE *pmt;
654 TRACE("(%p/%p)\n", pVMR9, This);
656 pmt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
657 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) {
658 return (VIDEOINFOHEADER*)pmt->pbFormat;
659 } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) {
660 static VIDEOINFOHEADER vih;
661 VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat;
662 memcpy(&vih,vih2,sizeof(VIDEOINFOHEADER));
663 memcpy(&vih.bmiHeader, &vih2->bmiHeader, sizeof(BITMAPINFOHEADER));
664 return &vih;
665 } else {
666 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype));
667 return NULL;
671 static HRESULT WINAPI VMR9_IsDefaultSourceRect(BaseControlVideo* This)
673 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
674 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
676 return S_OK;
679 static HRESULT WINAPI VMR9_IsDefaultTargetRect(BaseControlVideo* This)
681 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
682 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
684 return S_OK;
687 static HRESULT WINAPI VMR9_SetDefaultSourceRect(BaseControlVideo* This)
689 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
691 pVMR9->source_rect.left = 0;
692 pVMR9->source_rect.top = 0;
693 pVMR9->source_rect.right = pVMR9->VideoWidth;
694 pVMR9->source_rect.bottom = pVMR9->VideoHeight;
696 return S_OK;
699 static HRESULT WINAPI VMR9_SetDefaultTargetRect(BaseControlVideo* This)
701 RECT rect;
702 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
704 if (!GetClientRect(pVMR9->baseControlWindow.baseWindow.hWnd, &rect))
705 return E_FAIL;
707 pVMR9->target_rect.left = 0;
708 pVMR9->target_rect.top = 0;
709 pVMR9->target_rect.right = rect.right;
710 pVMR9->target_rect.bottom = rect.bottom;
712 return S_OK;
715 static HRESULT WINAPI VMR9_SetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
717 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
718 CopyRect(&pVMR9->source_rect,pSourceRect);
719 return S_OK;
722 static HRESULT WINAPI VMR9_SetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
724 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
725 CopyRect(&pVMR9->target_rect,pTargetRect);
726 return S_OK;
729 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = {
730 VMR9_GetSourceRect,
731 VMR9_GetStaticImage,
732 VMR9_GetTargetRect,
733 VMR9_GetVideoFormat,
734 VMR9_IsDefaultSourceRect,
735 VMR9_IsDefaultTargetRect,
736 VMR9_SetDefaultSourceRect,
737 VMR9_SetDefaultTargetRect,
738 VMR9_SetSourceRect,
739 VMR9_SetTargetRect
742 static HRESULT WINAPI VMR9Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
744 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
745 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
747 if (This->bAggregatable)
748 This->bUnkOuterValid = TRUE;
750 *ppv = NULL;
752 if (IsEqualIID(riid, &IID_IUnknown))
753 *ppv = &This->IUnknown_inner;
754 else if (IsEqualIID(riid, &IID_IVideoWindow))
755 *ppv = &This->baseControlWindow.IVideoWindow_iface;
756 else if (IsEqualIID(riid, &IID_IBasicVideo))
757 *ppv = &This->baseControlVideo.IBasicVideo_iface;
758 else if (IsEqualIID(riid, &IID_IAMCertifiedOutputProtection))
759 *ppv = &This->IAMCertifiedOutputProtection_iface;
760 else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
761 *ppv = &This->IAMFilterMiscFlags_iface;
762 else if (IsEqualIID(riid, &IID_IVMRFilterConfig))
763 *ppv = &This->IVMRFilterConfig_iface;
764 else if (IsEqualIID(riid, &IID_IVMRFilterConfig9))
765 *ppv = &This->IVMRFilterConfig9_iface;
766 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig))
767 *ppv = &This->IVMRMonitorConfig_iface;
768 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig9))
769 *ppv = &This->IVMRMonitorConfig9_iface;
770 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify) && This->mode == (VMR9Mode)VMRMode_Renderless)
771 *ppv = &This->IVMRSurfaceAllocatorNotify_iface;
772 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9) && This->mode == VMR9Mode_Renderless)
773 *ppv = &This->IVMRSurfaceAllocatorNotify9_iface;
774 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl) && This->mode == (VMR9Mode)VMRMode_Windowless)
775 *ppv = &This->IVMRWindowlessControl_iface;
776 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9) && This->mode == VMR9Mode_Windowless)
777 *ppv = &This->IVMRWindowlessControl9_iface;
778 else
780 HRESULT hr;
781 hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
782 if (SUCCEEDED(hr))
783 return hr;
786 if (*ppv)
788 IUnknown_AddRef((IUnknown *)(*ppv));
789 return S_OK;
792 else if (IsEqualIID(riid, &IID_IBasicVideo2))
793 FIXME("No interface for IID_IBasicVideo2\n");
794 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9))
796 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9))
798 else if (IsEqualIID(riid, &IID_IMediaPosition))
799 FIXME("No interface for IID_IMediaPosition\n");
800 else if (IsEqualIID(riid, &IID_IQualProp))
801 FIXME("No interface for IID_IQualProp\n");
802 else if (IsEqualIID(riid, &IID_IVMRAspectRatioControl9))
803 FIXME("No interface for IID_IVMRAspectRatioControl9\n");
804 else if (IsEqualIID(riid, &IID_IVMRDeinterlaceControl9))
805 FIXME("No interface for IID_IVMRDeinterlaceControl9\n");
806 else if (IsEqualIID(riid, &IID_IVMRMixerBitmap9))
807 FIXME("No interface for IID_IVMRMixerBitmap9\n");
808 else if (IsEqualIID(riid, &IID_IVMRMixerControl9))
809 FIXME("No interface for IID_IVMRMixerControl9\n");
810 else
811 FIXME("No interface for %s\n", debugstr_guid(riid));
813 return E_NOINTERFACE;
816 static ULONG WINAPI VMR9Inner_AddRef(IUnknown * iface)
818 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
819 ULONG refCount = BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
821 TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
823 return refCount;
826 static ULONG WINAPI VMR9Inner_Release(IUnknown * iface)
828 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
829 ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface);
831 TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
833 if (!refCount)
835 TRACE("Destroying\n");
836 BaseControlWindow_Destroy(&This->baseControlWindow);
837 FreeLibrary(This->hD3d9);
839 if (This->allocator)
840 IVMRSurfaceAllocatorEx9_Release(This->allocator);
841 if (This->presenter)
842 IVMRImagePresenter9_Release(This->presenter);
844 This->num_surfaces = 0;
845 if (This->allocator_d3d9_dev)
847 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
848 This->allocator_d3d9_dev = NULL;
851 CoTaskMemFree(This);
853 return refCount;
856 static const IUnknownVtbl IInner_VTable =
858 VMR9Inner_QueryInterface,
859 VMR9Inner_AddRef,
860 VMR9Inner_Release
863 static HRESULT WINAPI VMR9_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
865 struct quartz_vmr *This = (struct quartz_vmr*)iface;
867 if (This->bAggregatable)
868 This->bUnkOuterValid = TRUE;
870 if (This->outer_unk)
872 if (This->bAggregatable)
873 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
875 if (IsEqualIID(riid, &IID_IUnknown))
877 HRESULT hr;
879 IUnknown_AddRef(&This->IUnknown_inner);
880 hr = IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
881 IUnknown_Release(&This->IUnknown_inner);
882 This->bAggregatable = TRUE;
883 return hr;
886 *ppv = NULL;
887 return E_NOINTERFACE;
890 return IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
893 static ULONG WINAPI VMR9_AddRef(IBaseFilter * iface)
895 struct quartz_vmr *This = (struct quartz_vmr*)iface;
896 LONG ret;
898 if (This->outer_unk && This->bUnkOuterValid)
899 ret = IUnknown_AddRef(This->outer_unk);
900 else
901 ret = IUnknown_AddRef(&This->IUnknown_inner);
903 TRACE("(%p)->AddRef from %d\n", iface, ret - 1);
905 return ret;
908 static ULONG WINAPI VMR9_Release(IBaseFilter * iface)
910 struct quartz_vmr *This = (struct quartz_vmr*)iface;
911 LONG ret;
913 if (This->outer_unk && This->bUnkOuterValid)
914 ret = IUnknown_Release(This->outer_unk);
915 else
916 ret = IUnknown_Release(&This->IUnknown_inner);
918 TRACE("(%p)->Release from %d\n", iface, ret + 1);
920 if (ret)
921 return ret;
922 return 0;
925 static const IBaseFilterVtbl VMR_Vtbl =
927 VMR9_QueryInterface,
928 VMR9_AddRef,
929 VMR9_Release,
930 BaseFilterImpl_GetClassID,
931 BaseRendererImpl_Stop,
932 BaseRendererImpl_Pause,
933 BaseRendererImpl_Run,
934 BaseRendererImpl_GetState,
935 BaseRendererImpl_SetSyncSource,
936 BaseFilterImpl_GetSyncSource,
937 BaseFilterImpl_EnumPins,
938 BaseRendererImpl_FindPin,
939 BaseFilterImpl_QueryFilterInfo,
940 BaseFilterImpl_JoinFilterGraph,
941 BaseFilterImpl_QueryVendorInfo
944 /*** IUnknown methods ***/
945 static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface, REFIID riid, LPVOID*ppvObj)
947 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
949 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
951 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
954 static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface)
956 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
958 TRACE("(%p/%p)->()\n", This, iface);
960 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
963 static ULONG WINAPI Videowindow_Release(IVideoWindow *iface)
965 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
967 TRACE("(%p/%p)->()\n", This, iface);
969 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
972 static const IVideoWindowVtbl IVideoWindow_VTable =
974 Videowindow_QueryInterface,
975 Videowindow_AddRef,
976 Videowindow_Release,
977 BaseControlWindowImpl_GetTypeInfoCount,
978 BaseControlWindowImpl_GetTypeInfo,
979 BaseControlWindowImpl_GetIDsOfNames,
980 BaseControlWindowImpl_Invoke,
981 BaseControlWindowImpl_put_Caption,
982 BaseControlWindowImpl_get_Caption,
983 BaseControlWindowImpl_put_WindowStyle,
984 BaseControlWindowImpl_get_WindowStyle,
985 BaseControlWindowImpl_put_WindowStyleEx,
986 BaseControlWindowImpl_get_WindowStyleEx,
987 BaseControlWindowImpl_put_AutoShow,
988 BaseControlWindowImpl_get_AutoShow,
989 BaseControlWindowImpl_put_WindowState,
990 BaseControlWindowImpl_get_WindowState,
991 BaseControlWindowImpl_put_BackgroundPalette,
992 BaseControlWindowImpl_get_BackgroundPalette,
993 BaseControlWindowImpl_put_Visible,
994 BaseControlWindowImpl_get_Visible,
995 BaseControlWindowImpl_put_Left,
996 BaseControlWindowImpl_get_Left,
997 BaseControlWindowImpl_put_Width,
998 BaseControlWindowImpl_get_Width,
999 BaseControlWindowImpl_put_Top,
1000 BaseControlWindowImpl_get_Top,
1001 BaseControlWindowImpl_put_Height,
1002 BaseControlWindowImpl_get_Height,
1003 BaseControlWindowImpl_put_Owner,
1004 BaseControlWindowImpl_get_Owner,
1005 BaseControlWindowImpl_put_MessageDrain,
1006 BaseControlWindowImpl_get_MessageDrain,
1007 BaseControlWindowImpl_get_BorderColor,
1008 BaseControlWindowImpl_put_BorderColor,
1009 BaseControlWindowImpl_get_FullScreenMode,
1010 BaseControlWindowImpl_put_FullScreenMode,
1011 BaseControlWindowImpl_SetWindowForeground,
1012 BaseControlWindowImpl_NotifyOwnerMessage,
1013 BaseControlWindowImpl_SetWindowPosition,
1014 BaseControlWindowImpl_GetWindowPosition,
1015 BaseControlWindowImpl_GetMinIdealImageSize,
1016 BaseControlWindowImpl_GetMaxIdealImageSize,
1017 BaseControlWindowImpl_GetRestorePosition,
1018 BaseControlWindowImpl_HideCursor,
1019 BaseControlWindowImpl_IsCursorHidden
1022 /*** IUnknown methods ***/
1023 static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface, REFIID riid, LPVOID * ppvObj)
1025 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1027 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1029 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
1032 static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface)
1034 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1036 TRACE("(%p/%p)->()\n", This, iface);
1038 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1041 static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface)
1043 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1045 TRACE("(%p/%p)->()\n", This, iface);
1047 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1050 static const IBasicVideoVtbl IBasicVideo_VTable =
1052 Basicvideo_QueryInterface,
1053 Basicvideo_AddRef,
1054 Basicvideo_Release,
1055 BaseControlVideoImpl_GetTypeInfoCount,
1056 BaseControlVideoImpl_GetTypeInfo,
1057 BaseControlVideoImpl_GetIDsOfNames,
1058 BaseControlVideoImpl_Invoke,
1059 BaseControlVideoImpl_get_AvgTimePerFrame,
1060 BaseControlVideoImpl_get_BitRate,
1061 BaseControlVideoImpl_get_BitErrorRate,
1062 BaseControlVideoImpl_get_VideoWidth,
1063 BaseControlVideoImpl_get_VideoHeight,
1064 BaseControlVideoImpl_put_SourceLeft,
1065 BaseControlVideoImpl_get_SourceLeft,
1066 BaseControlVideoImpl_put_SourceWidth,
1067 BaseControlVideoImpl_get_SourceWidth,
1068 BaseControlVideoImpl_put_SourceTop,
1069 BaseControlVideoImpl_get_SourceTop,
1070 BaseControlVideoImpl_put_SourceHeight,
1071 BaseControlVideoImpl_get_SourceHeight,
1072 BaseControlVideoImpl_put_DestinationLeft,
1073 BaseControlVideoImpl_get_DestinationLeft,
1074 BaseControlVideoImpl_put_DestinationWidth,
1075 BaseControlVideoImpl_get_DestinationWidth,
1076 BaseControlVideoImpl_put_DestinationTop,
1077 BaseControlVideoImpl_get_DestinationTop,
1078 BaseControlVideoImpl_put_DestinationHeight,
1079 BaseControlVideoImpl_get_DestinationHeight,
1080 BaseControlVideoImpl_SetSourcePosition,
1081 BaseControlVideoImpl_GetSourcePosition,
1082 BaseControlVideoImpl_SetDefaultSourcePosition,
1083 BaseControlVideoImpl_SetDestinationPosition,
1084 BaseControlVideoImpl_GetDestinationPosition,
1085 BaseControlVideoImpl_SetDefaultDestinationPosition,
1086 BaseControlVideoImpl_GetVideoSize,
1087 BaseControlVideoImpl_GetVideoPaletteEntries,
1088 BaseControlVideoImpl_GetCurrentImage,
1089 BaseControlVideoImpl_IsUsingDefaultSource,
1090 BaseControlVideoImpl_IsUsingDefaultDestination
1093 static HRESULT WINAPI AMCertifiedOutputProtection_QueryInterface(IAMCertifiedOutputProtection *iface,
1094 REFIID riid, void **ppv)
1096 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1097 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1100 static ULONG WINAPI AMCertifiedOutputProtection_AddRef(IAMCertifiedOutputProtection *iface)
1102 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1103 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1106 static ULONG WINAPI AMCertifiedOutputProtection_Release(IAMCertifiedOutputProtection *iface)
1108 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1109 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1112 static HRESULT WINAPI AMCertifiedOutputProtection_KeyExchange(IAMCertifiedOutputProtection *iface,
1113 GUID* pRandom, BYTE** VarLenCertGH,
1114 DWORD* pdwLengthCertGH)
1116 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1118 FIXME("(%p/%p)->(%p, %p, %p) stub\n", iface, This, pRandom, VarLenCertGH, pdwLengthCertGH);
1119 return VFW_E_NO_COPP_HW;
1122 static HRESULT WINAPI AMCertifiedOutputProtection_SessionSequenceStart(IAMCertifiedOutputProtection *iface,
1123 AMCOPPSignature* pSig)
1125 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1127 FIXME("(%p/%p)->(%p) stub\n", iface, This, pSig);
1128 return VFW_E_NO_COPP_HW;
1131 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionCommand(IAMCertifiedOutputProtection *iface,
1132 const AMCOPPCommand* cmd)
1134 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1136 FIXME("(%p/%p)->(%p) stub\n", iface, This, cmd);
1137 return VFW_E_NO_COPP_HW;
1140 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionStatus(IAMCertifiedOutputProtection *iface,
1141 const AMCOPPStatusInput* pStatusInput,
1142 AMCOPPStatusOutput* pStatusOutput)
1144 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1146 FIXME("(%p/%p)->(%p, %p) stub\n", iface, This, pStatusInput, pStatusOutput);
1147 return VFW_E_NO_COPP_HW;
1150 static const IAMCertifiedOutputProtectionVtbl IAMCertifiedOutputProtection_Vtbl =
1152 AMCertifiedOutputProtection_QueryInterface,
1153 AMCertifiedOutputProtection_AddRef,
1154 AMCertifiedOutputProtection_Release,
1155 AMCertifiedOutputProtection_KeyExchange,
1156 AMCertifiedOutputProtection_SessionSequenceStart,
1157 AMCertifiedOutputProtection_ProtectionCommand,
1158 AMCertifiedOutputProtection_ProtectionStatus
1161 static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) {
1162 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1163 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1166 static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) {
1167 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1168 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1171 static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) {
1172 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1173 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1176 static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) {
1177 return AM_FILTER_MISC_FLAGS_IS_RENDERER;
1180 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = {
1181 AMFilterMiscFlags_QueryInterface,
1182 AMFilterMiscFlags_AddRef,
1183 AMFilterMiscFlags_Release,
1184 AMFilterMiscFlags_GetMiscFlags
1187 static HRESULT WINAPI VMR7FilterConfig_QueryInterface(IVMRFilterConfig *iface, REFIID riid,
1188 void** ppv)
1190 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1191 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1194 static ULONG WINAPI VMR7FilterConfig_AddRef(IVMRFilterConfig *iface)
1196 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1197 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1200 static ULONG WINAPI VMR7FilterConfig_Release(IVMRFilterConfig *iface)
1202 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1203 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1206 static HRESULT WINAPI VMR7FilterConfig_SetImageCompositor(IVMRFilterConfig *iface,
1207 IVMRImageCompositor *compositor)
1209 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1211 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
1212 return E_NOTIMPL;
1215 static HRESULT WINAPI VMR7FilterConfig_SetNumberOfStreams(IVMRFilterConfig *iface, DWORD max)
1217 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1219 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
1220 return E_NOTIMPL;
1223 static HRESULT WINAPI VMR7FilterConfig_GetNumberOfStreams(IVMRFilterConfig *iface, DWORD *max)
1225 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1227 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
1228 return E_NOTIMPL;
1231 static HRESULT WINAPI VMR7FilterConfig_SetRenderingPrefs(IVMRFilterConfig *iface, DWORD renderflags)
1233 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1235 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
1236 return E_NOTIMPL;
1239 static HRESULT WINAPI VMR7FilterConfig_GetRenderingPrefs(IVMRFilterConfig *iface, DWORD *renderflags)
1241 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1243 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
1244 return E_NOTIMPL;
1247 static HRESULT WINAPI VMR7FilterConfig_SetRenderingMode(IVMRFilterConfig *iface, DWORD mode)
1249 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1251 FIXME("(%p/%p)->(%u) stub\n", iface, This, mode);
1252 return E_NOTIMPL;
1255 static HRESULT WINAPI VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig *iface, DWORD *mode)
1257 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1259 TRACE("(%p/%p)->(%p) stub\n", iface, This, mode);
1260 if (!mode) return E_POINTER;
1262 if (This->mode)
1263 *mode = This->mode;
1264 else
1265 *mode = VMRMode_Windowed;
1267 return S_OK;
1270 static const IVMRFilterConfigVtbl VMR7_FilterConfig_Vtbl =
1272 VMR7FilterConfig_QueryInterface,
1273 VMR7FilterConfig_AddRef,
1274 VMR7FilterConfig_Release,
1275 VMR7FilterConfig_SetImageCompositor,
1276 VMR7FilterConfig_SetNumberOfStreams,
1277 VMR7FilterConfig_GetNumberOfStreams,
1278 VMR7FilterConfig_SetRenderingPrefs,
1279 VMR7FilterConfig_GetRenderingPrefs,
1280 VMR7FilterConfig_SetRenderingMode,
1281 VMR7FilterConfig_GetRenderingMode
1284 struct get_available_monitors_args
1286 VMRMONITORINFO *info7;
1287 VMR9MonitorInfo *info9;
1288 DWORD arraysize;
1289 DWORD numdev;
1292 static BOOL CALLBACK get_available_monitors_proc(HMONITOR hmon, HDC hdc, LPRECT lprc, LPARAM lparam)
1294 struct get_available_monitors_args *args = (struct get_available_monitors_args *)lparam;
1295 MONITORINFOEXW mi;
1297 if (args->info7 || args->info9)
1300 if (!args->arraysize)
1301 return FALSE;
1303 mi.cbSize = sizeof(mi);
1304 if (!GetMonitorInfoW(hmon, (MONITORINFO*)&mi))
1305 return TRUE;
1307 /* fill VMRMONITORINFO struct */
1308 if (args->info7)
1310 VMRMONITORINFO *info = args->info7++;
1311 memset(info, 0, sizeof(*info));
1313 if (args->numdev > 0)
1315 info->guid.pGUID = &info->guid.GUID;
1316 info->guid.GUID.Data4[7] = args->numdev;
1318 else
1319 info->guid.pGUID = NULL;
1321 CopyRect(&info->rcMonitor, &mi.rcMonitor);
1322 info->hMon = hmon;
1323 info->dwFlags = mi.dwFlags;
1325 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR));
1327 /* FIXME: how to get these values? */
1328 info->szDescription[0] = 0;
1331 /* fill VMR9MonitorInfo struct */
1332 if (args->info9)
1334 VMR9MonitorInfo *info = args->info9++;
1335 memset(info, 0, sizeof(*info));
1337 info->uDevID = 0; /* FIXME */
1338 CopyRect(&info->rcMonitor, &mi.rcMonitor);
1339 info->hMon = hmon;
1340 info->dwFlags = mi.dwFlags;
1342 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR));
1344 /* FIXME: how to get these values? */
1345 info->szDescription[0] = 0;
1346 info->dwVendorId = 0;
1347 info->dwDeviceId = 0;
1348 info->dwSubSysId = 0;
1349 info->dwRevision = 0;
1352 args->arraysize--;
1355 args->numdev++;
1356 return TRUE;
1359 static HRESULT WINAPI VMR7MonitorConfig_QueryInterface(IVMRMonitorConfig *iface, REFIID riid,
1360 LPVOID * ppv)
1362 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1363 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1366 static ULONG WINAPI VMR7MonitorConfig_AddRef(IVMRMonitorConfig *iface)
1368 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1369 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1372 static ULONG WINAPI VMR7MonitorConfig_Release(IVMRMonitorConfig *iface)
1374 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1375 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1378 static HRESULT WINAPI VMR7MonitorConfig_SetMonitor(IVMRMonitorConfig *iface, const VMRGUID *pGUID)
1380 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1382 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1384 if (!pGUID)
1385 return E_POINTER;
1387 return S_OK;
1390 static HRESULT WINAPI VMR7MonitorConfig_GetMonitor(IVMRMonitorConfig *iface, VMRGUID *pGUID)
1392 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1394 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1396 if (!pGUID)
1397 return E_POINTER;
1399 pGUID->pGUID = NULL; /* default DirectDraw device */
1400 return S_OK;
1403 static HRESULT WINAPI VMR7MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig *iface,
1404 const VMRGUID *pGUID)
1406 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1408 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1410 if (!pGUID)
1411 return E_POINTER;
1413 return S_OK;
1416 static HRESULT WINAPI VMR7MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig *iface, VMRGUID *pGUID)
1418 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1420 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1422 if (!pGUID)
1423 return E_POINTER;
1425 pGUID->pGUID = NULL; /* default DirectDraw device */
1426 return S_OK;
1429 static HRESULT WINAPI VMR7MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig *iface,
1430 VMRMONITORINFO *info, DWORD arraysize,
1431 DWORD *numdev)
1433 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1434 struct get_available_monitors_args args;
1436 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1438 if (!numdev)
1439 return E_POINTER;
1441 if (info && arraysize == 0)
1442 return E_INVALIDARG;
1444 args.info7 = info;
1445 args.info9 = NULL;
1446 args.arraysize = arraysize;
1447 args.numdev = 0;
1448 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1450 *numdev = args.numdev;
1451 return S_OK;
1454 static const IVMRMonitorConfigVtbl VMR7_MonitorConfig_Vtbl =
1456 VMR7MonitorConfig_QueryInterface,
1457 VMR7MonitorConfig_AddRef,
1458 VMR7MonitorConfig_Release,
1459 VMR7MonitorConfig_SetMonitor,
1460 VMR7MonitorConfig_GetMonitor,
1461 VMR7MonitorConfig_SetDefaultMonitor,
1462 VMR7MonitorConfig_GetDefaultMonitor,
1463 VMR7MonitorConfig_GetAvailableMonitors
1466 static HRESULT WINAPI VMR9MonitorConfig_QueryInterface(IVMRMonitorConfig9 *iface, REFIID riid,
1467 LPVOID * ppv)
1469 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1470 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1473 static ULONG WINAPI VMR9MonitorConfig_AddRef(IVMRMonitorConfig9 *iface)
1475 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1476 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1479 static ULONG WINAPI VMR9MonitorConfig_Release(IVMRMonitorConfig9 *iface)
1481 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1482 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1485 static HRESULT WINAPI VMR9MonitorConfig_SetMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1487 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1489 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1491 return S_OK;
1494 static HRESULT WINAPI VMR9MonitorConfig_GetMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1496 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1498 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1500 if (!uDev)
1501 return E_POINTER;
1503 *uDev = 0;
1504 return S_OK;
1507 static HRESULT WINAPI VMR9MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1509 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1511 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1513 return S_OK;
1516 static HRESULT WINAPI VMR9MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1518 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1520 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1522 if (!uDev)
1523 return E_POINTER;
1525 *uDev = 0;
1526 return S_OK;
1529 static HRESULT WINAPI VMR9MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig9 *iface,
1530 VMR9MonitorInfo *info, DWORD arraysize,
1531 DWORD *numdev)
1533 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1534 struct get_available_monitors_args args;
1536 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1538 if (!numdev)
1539 return E_POINTER;
1541 if (info && arraysize == 0)
1542 return E_INVALIDARG;
1544 args.info7 = NULL;
1545 args.info9 = info;
1546 args.arraysize = arraysize;
1547 args.numdev = 0;
1548 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1550 *numdev = args.numdev;
1551 return S_OK;
1554 static const IVMRMonitorConfig9Vtbl VMR9_MonitorConfig_Vtbl =
1556 VMR9MonitorConfig_QueryInterface,
1557 VMR9MonitorConfig_AddRef,
1558 VMR9MonitorConfig_Release,
1559 VMR9MonitorConfig_SetMonitor,
1560 VMR9MonitorConfig_GetMonitor,
1561 VMR9MonitorConfig_SetDefaultMonitor,
1562 VMR9MonitorConfig_GetDefaultMonitor,
1563 VMR9MonitorConfig_GetAvailableMonitors
1566 static HRESULT WINAPI VMR9FilterConfig_QueryInterface(IVMRFilterConfig9 *iface, REFIID riid, LPVOID * ppv)
1568 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1569 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1572 static ULONG WINAPI VMR9FilterConfig_AddRef(IVMRFilterConfig9 *iface)
1574 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1575 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1578 static ULONG WINAPI VMR9FilterConfig_Release(IVMRFilterConfig9 *iface)
1580 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1581 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1584 static HRESULT WINAPI VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9 *iface, IVMRImageCompositor9 *compositor)
1586 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1588 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
1589 return E_NOTIMPL;
1592 static HRESULT WINAPI VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD max)
1594 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1596 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
1597 return E_NOTIMPL;
1600 static HRESULT WINAPI VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD *max)
1602 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1604 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
1605 return E_NOTIMPL;
1608 static HRESULT WINAPI VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD renderflags)
1610 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1612 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
1613 return E_NOTIMPL;
1616 static HRESULT WINAPI VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD *renderflags)
1618 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1620 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
1621 return E_NOTIMPL;
1624 static HRESULT WINAPI VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 *iface, DWORD mode)
1626 HRESULT hr = S_OK;
1627 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1629 TRACE("(%p/%p)->(%u)\n", iface, This, mode);
1631 EnterCriticalSection(&This->renderer.filter.csFilter);
1632 if (This->mode)
1634 LeaveCriticalSection(&This->renderer.filter.csFilter);
1635 return VFW_E_WRONG_STATE;
1638 if (This->allocator)
1639 IVMRSurfaceAllocatorEx9_Release(This->allocator);
1640 if (This->presenter)
1641 IVMRImagePresenter9_Release(This->presenter);
1643 This->allocator = NULL;
1644 This->presenter = NULL;
1646 switch (mode)
1648 case VMR9Mode_Windowed:
1649 case VMR9Mode_Windowless:
1650 This->allocator_is_ex = 0;
1651 This->cookie = ~0;
1653 hr = VMR9DefaultAllocatorPresenterImpl_create(This, (LPVOID*)&This->presenter);
1654 if (SUCCEEDED(hr))
1655 hr = IVMRImagePresenter9_QueryInterface(This->presenter, &IID_IVMRSurfaceAllocatorEx9, (LPVOID*)&This->allocator);
1656 if (FAILED(hr))
1658 ERR("Unable to find Presenter interface\n");
1659 IVMRImagePresenter9_Release(This->presenter);
1660 This->allocator = NULL;
1661 This->presenter = NULL;
1663 else
1664 hr = IVMRSurfaceAllocatorEx9_AdviseNotify(This->allocator, &This->IVMRSurfaceAllocatorNotify9_iface);
1665 break;
1666 case VMR9Mode_Renderless:
1667 break;
1668 default:
1669 LeaveCriticalSection(&This->renderer.filter.csFilter);
1670 return E_INVALIDARG;
1673 This->mode = mode;
1674 LeaveCriticalSection(&This->renderer.filter.csFilter);
1675 return hr;
1678 static HRESULT WINAPI VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9 *iface, DWORD *mode)
1680 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1682 TRACE("(%p/%p)->(%p) stub\n", iface, This, mode);
1683 if (!mode)
1684 return E_POINTER;
1686 if (This->mode)
1687 *mode = This->mode;
1688 else
1689 *mode = VMR9Mode_Windowed;
1691 return S_OK;
1694 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl =
1696 VMR9FilterConfig_QueryInterface,
1697 VMR9FilterConfig_AddRef,
1698 VMR9FilterConfig_Release,
1699 VMR9FilterConfig_SetImageCompositor,
1700 VMR9FilterConfig_SetNumberOfStreams,
1701 VMR9FilterConfig_GetNumberOfStreams,
1702 VMR9FilterConfig_SetRenderingPrefs,
1703 VMR9FilterConfig_GetRenderingPrefs,
1704 VMR9FilterConfig_SetRenderingMode,
1705 VMR9FilterConfig_GetRenderingMode
1708 static HRESULT WINAPI VMR7WindowlessControl_QueryInterface(IVMRWindowlessControl *iface, REFIID riid,
1709 LPVOID * ppv)
1711 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1712 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1715 static ULONG WINAPI VMR7WindowlessControl_AddRef(IVMRWindowlessControl *iface)
1717 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1718 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1721 static ULONG WINAPI VMR7WindowlessControl_Release(IVMRWindowlessControl *iface)
1723 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1724 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1727 static HRESULT WINAPI VMR7WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl *iface,
1728 LONG *width, LONG *height,
1729 LONG *arwidth, LONG *arheight)
1731 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1732 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1734 if (!width || !height || !arwidth || !arheight)
1736 ERR("Got no pointer\n");
1737 return E_POINTER;
1740 *width = This->bmiheader.biWidth;
1741 *height = This->bmiheader.biHeight;
1742 *arwidth = This->bmiheader.biWidth;
1743 *arheight = This->bmiheader.biHeight;
1745 return S_OK;
1748 static HRESULT WINAPI VMR7WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl *iface,
1749 LONG *width, LONG *height)
1751 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1753 FIXME("(%p/%p)->(...) stub\n", iface, This);
1754 return E_NOTIMPL;
1757 static HRESULT WINAPI VMR7WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl *iface,
1758 LONG *width, LONG *height)
1760 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1762 FIXME("(%p/%p)->(...) stub\n", iface, This);
1763 return E_NOTIMPL;
1766 static HRESULT WINAPI VMR7WindowlessControl_SetVideoPosition(IVMRWindowlessControl *iface,
1767 const RECT *source, const RECT *dest)
1769 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1771 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1773 EnterCriticalSection(&This->renderer.filter.csFilter);
1775 if (source)
1776 This->source_rect = *source;
1777 if (dest)
1779 This->target_rect = *dest;
1780 if (This->baseControlWindow.baseWindow.hWnd)
1782 FIXME("Output rectangle: starting at %dx%d, up to point %dx%d\n",
1783 dest->left, dest->top, dest->right, dest->bottom);
1784 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
1785 dest->left, dest->top, dest->right - dest->left, dest->bottom-dest->top,
1786 SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW);
1790 LeaveCriticalSection(&This->renderer.filter.csFilter);
1792 return S_OK;
1795 static HRESULT WINAPI VMR7WindowlessControl_GetVideoPosition(IVMRWindowlessControl *iface,
1796 RECT *source, RECT *dest)
1798 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1800 if (source)
1801 *source = This->source_rect;
1803 if (dest)
1804 *dest = This->target_rect;
1806 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
1807 return S_OK;
1810 static HRESULT WINAPI VMR7WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl *iface,
1811 DWORD *mode)
1813 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1815 FIXME("(%p/%p)->(...) stub\n", iface, This);
1816 return E_NOTIMPL;
1819 static HRESULT WINAPI VMR7WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl *iface,
1820 DWORD mode)
1822 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1824 FIXME("(%p/%p)->(...) stub\n", iface, This);
1825 return E_NOTIMPL;
1828 static HRESULT WINAPI VMR7WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl *iface,
1829 HWND hwnd)
1831 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1833 FIXME("(%p/%p)->(...) stub\n", iface, This);
1834 return E_NOTIMPL;
1837 static HRESULT WINAPI VMR7WindowlessControl_RepaintVideo(IVMRWindowlessControl *iface,
1838 HWND hwnd, HDC hdc)
1840 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1842 FIXME("(%p/%p)->(...) stub\n", iface, This);
1843 return E_NOTIMPL;
1846 static HRESULT WINAPI VMR7WindowlessControl_DisplayModeChanged(IVMRWindowlessControl *iface)
1848 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1850 FIXME("(%p/%p)->(...) stub\n", iface, This);
1851 return E_NOTIMPL;
1854 static HRESULT WINAPI VMR7WindowlessControl_GetCurrentImage(IVMRWindowlessControl *iface,
1855 BYTE **dib)
1857 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1859 FIXME("(%p/%p)->(...) stub\n", iface, This);
1860 return E_NOTIMPL;
1863 static HRESULT WINAPI VMR7WindowlessControl_SetBorderColor(IVMRWindowlessControl *iface,
1864 COLORREF color)
1866 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1868 FIXME("(%p/%p)->(...) stub\n", iface, This);
1869 return E_NOTIMPL;
1872 static HRESULT WINAPI VMR7WindowlessControl_GetBorderColor(IVMRWindowlessControl *iface,
1873 COLORREF *color)
1875 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1877 FIXME("(%p/%p)->(...) stub\n", iface, This);
1878 return E_NOTIMPL;
1881 static HRESULT WINAPI VMR7WindowlessControl_SetColorKey(IVMRWindowlessControl *iface, COLORREF color)
1883 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1885 FIXME("(%p/%p)->(...) stub\n", iface, This);
1886 return E_NOTIMPL;
1889 static HRESULT WINAPI VMR7WindowlessControl_GetColorKey(IVMRWindowlessControl *iface, COLORREF *color)
1891 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1893 FIXME("(%p/%p)->(...) stub\n", iface, This);
1894 return E_NOTIMPL;
1897 static const IVMRWindowlessControlVtbl VMR7_WindowlessControl_Vtbl =
1899 VMR7WindowlessControl_QueryInterface,
1900 VMR7WindowlessControl_AddRef,
1901 VMR7WindowlessControl_Release,
1902 VMR7WindowlessControl_GetNativeVideoSize,
1903 VMR7WindowlessControl_GetMinIdealVideoSize,
1904 VMR7WindowlessControl_GetMaxIdealVideoSize,
1905 VMR7WindowlessControl_SetVideoPosition,
1906 VMR7WindowlessControl_GetVideoPosition,
1907 VMR7WindowlessControl_GetAspectRatioMode,
1908 VMR7WindowlessControl_SetAspectRatioMode,
1909 VMR7WindowlessControl_SetVideoClippingWindow,
1910 VMR7WindowlessControl_RepaintVideo,
1911 VMR7WindowlessControl_DisplayModeChanged,
1912 VMR7WindowlessControl_GetCurrentImage,
1913 VMR7WindowlessControl_SetBorderColor,
1914 VMR7WindowlessControl_GetBorderColor,
1915 VMR7WindowlessControl_SetColorKey,
1916 VMR7WindowlessControl_GetColorKey
1919 static HRESULT WINAPI VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9 *iface, REFIID riid, LPVOID * ppv)
1921 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1922 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1925 static ULONG WINAPI VMR9WindowlessControl_AddRef(IVMRWindowlessControl9 *iface)
1927 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1928 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1931 static ULONG WINAPI VMR9WindowlessControl_Release(IVMRWindowlessControl9 *iface)
1933 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1934 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1937 static HRESULT WINAPI VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height, LONG *arwidth, LONG *arheight)
1939 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1940 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1942 if (!width || !height || !arwidth || !arheight)
1944 ERR("Got no pointer\n");
1945 return E_POINTER;
1948 *width = This->bmiheader.biWidth;
1949 *height = This->bmiheader.biHeight;
1950 *arwidth = This->bmiheader.biWidth;
1951 *arheight = This->bmiheader.biHeight;
1953 return S_OK;
1956 static HRESULT WINAPI VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1958 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1960 FIXME("(%p/%p)->(...) stub\n", iface, This);
1961 return E_NOTIMPL;
1964 static HRESULT WINAPI VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1966 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1968 FIXME("(%p/%p)->(...) stub\n", iface, This);
1969 return E_NOTIMPL;
1972 static HRESULT WINAPI VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9 *iface, const RECT *source, const RECT *dest)
1974 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1976 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1978 EnterCriticalSection(&This->renderer.filter.csFilter);
1980 if (source)
1981 This->source_rect = *source;
1982 if (dest)
1984 This->target_rect = *dest;
1985 if (This->baseControlWindow.baseWindow.hWnd)
1987 FIXME("Output rectangle: starting at %dx%d, up to point %dx%d\n", dest->left, dest->top, dest->right, dest->bottom);
1988 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, dest->left, dest->top, dest->right - dest->left,
1989 dest->bottom-dest->top, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW);
1993 LeaveCriticalSection(&This->renderer.filter.csFilter);
1995 return S_OK;
1998 static HRESULT WINAPI VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9 *iface, RECT *source, RECT *dest)
2000 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2002 if (source)
2003 *source = This->source_rect;
2005 if (dest)
2006 *dest = This->target_rect;
2008 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
2009 return S_OK;
2012 static HRESULT WINAPI VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD *mode)
2014 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2016 FIXME("(%p/%p)->(...) stub\n", iface, This);
2017 return E_NOTIMPL;
2020 static HRESULT WINAPI VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD mode)
2022 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2024 FIXME("(%p/%p)->(...) stub\n", iface, This);
2025 return E_NOTIMPL;
2028 static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9 *iface, HWND hwnd)
2030 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2032 TRACE("(%p/%p)->(%p)\n", iface, This, hwnd);
2034 EnterCriticalSection(&This->renderer.filter.csFilter);
2035 This->hWndClippingWindow = hwnd;
2036 VMR9_maybe_init(This, FALSE);
2037 if (!hwnd)
2038 IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie);
2039 LeaveCriticalSection(&This->renderer.filter.csFilter);
2040 return S_OK;
2043 static HRESULT WINAPI VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9 *iface, HWND hwnd, HDC hdc)
2045 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2046 HRESULT hr;
2048 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2050 EnterCriticalSection(&This->renderer.filter.csFilter);
2051 if (hwnd != This->hWndClippingWindow && hwnd != This->baseControlWindow.baseWindow.hWnd)
2053 ERR("Not handling changing windows yet!!!\n");
2054 LeaveCriticalSection(&This->renderer.filter.csFilter);
2055 return S_OK;
2058 if (!This->allocator_d3d9_dev)
2060 ERR("No d3d9 device!\n");
2061 LeaveCriticalSection(&This->renderer.filter.csFilter);
2062 return VFW_E_WRONG_STATE;
2065 /* Windowless extension */
2066 hr = IDirect3DDevice9_Present(This->allocator_d3d9_dev, NULL, NULL, This->baseControlWindow.baseWindow.hWnd, NULL);
2067 LeaveCriticalSection(&This->renderer.filter.csFilter);
2069 return hr;
2072 static HRESULT WINAPI VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9 *iface)
2074 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2076 FIXME("(%p/%p)->(...) stub\n", iface, This);
2077 return E_NOTIMPL;
2080 static HRESULT WINAPI VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9 *iface, BYTE **dib)
2082 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2084 FIXME("(%p/%p)->(...) stub\n", iface, This);
2085 return E_NOTIMPL;
2088 static HRESULT WINAPI VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9 *iface, COLORREF color)
2090 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2092 FIXME("(%p/%p)->(...) stub\n", iface, This);
2093 return E_NOTIMPL;
2096 static HRESULT WINAPI VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9 *iface, COLORREF *color)
2098 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2100 FIXME("(%p/%p)->(...) stub\n", iface, This);
2101 return E_NOTIMPL;
2104 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl =
2106 VMR9WindowlessControl_QueryInterface,
2107 VMR9WindowlessControl_AddRef,
2108 VMR9WindowlessControl_Release,
2109 VMR9WindowlessControl_GetNativeVideoSize,
2110 VMR9WindowlessControl_GetMinIdealVideoSize,
2111 VMR9WindowlessControl_GetMaxIdealVideoSize,
2112 VMR9WindowlessControl_SetVideoPosition,
2113 VMR9WindowlessControl_GetVideoPosition,
2114 VMR9WindowlessControl_GetAspectRatioMode,
2115 VMR9WindowlessControl_SetAspectRatioMode,
2116 VMR9WindowlessControl_SetVideoClippingWindow,
2117 VMR9WindowlessControl_RepaintVideo,
2118 VMR9WindowlessControl_DisplayModeChanged,
2119 VMR9WindowlessControl_GetCurrentImage,
2120 VMR9WindowlessControl_SetBorderColor,
2121 VMR9WindowlessControl_GetBorderColor
2124 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify *iface,
2125 REFIID riid, LPVOID * ppv)
2127 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2128 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
2131 static ULONG WINAPI VMR7SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify *iface)
2133 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2134 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
2137 static ULONG WINAPI VMR7SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify *iface)
2139 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2140 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
2143 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify *iface,
2144 DWORD_PTR id,
2145 IVMRSurfaceAllocator *alloc)
2147 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2149 FIXME("(%p/%p)->(...) stub\n", iface, This);
2150 return E_NOTIMPL;
2153 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
2154 IDirectDraw7 *device, HMONITOR monitor)
2156 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2158 FIXME("(%p/%p)->(...) stub\n", iface, This);
2159 return E_NOTIMPL;
2162 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_ChangeDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
2163 IDirectDraw7 *device, HMONITOR monitor)
2165 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2167 FIXME("(%p/%p)->(...) stub\n", iface, This);
2168 return E_NOTIMPL;
2171 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces(IVMRSurfaceAllocatorNotify *iface)
2173 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2175 FIXME("(%p/%p)->(...) stub\n", iface, This);
2176 return E_NOTIMPL;
2179 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify *iface, LONG code,
2180 LONG_PTR param1, LONG_PTR param2)
2182 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2184 FIXME("(%p/%p)->(...) stub\n", iface, This);
2185 return E_NOTIMPL;
2188 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetBorderColor(IVMRSurfaceAllocatorNotify *iface,
2189 COLORREF clrBorder)
2191 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2193 FIXME("(%p/%p)->(...) stub\n", iface, This);
2194 return E_NOTIMPL;
2197 static const IVMRSurfaceAllocatorNotifyVtbl VMR7_SurfaceAllocatorNotify_Vtbl =
2199 VMR7SurfaceAllocatorNotify_QueryInterface,
2200 VMR7SurfaceAllocatorNotify_AddRef,
2201 VMR7SurfaceAllocatorNotify_Release,
2202 VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator,
2203 VMR7SurfaceAllocatorNotify_SetDDrawDevice,
2204 VMR7SurfaceAllocatorNotify_ChangeDDrawDevice,
2205 VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces,
2206 VMR7SurfaceAllocatorNotify_NotifyEvent,
2207 VMR7SurfaceAllocatorNotify_SetBorderColor
2210 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9 *iface, REFIID riid, LPVOID * ppv)
2212 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2213 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
2216 static ULONG WINAPI VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9 *iface)
2218 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2219 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
2222 static ULONG WINAPI VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9 *iface)
2224 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2225 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
2228 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9 *iface, DWORD_PTR id, IVMRSurfaceAllocator9 *alloc)
2230 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2232 /* FIXME: This code is not tested!!! */
2233 FIXME("(%p/%p)->(...) stub\n", iface, This);
2234 This->cookie = id;
2236 if (This->presenter)
2237 return VFW_E_WRONG_STATE;
2239 if (FAILED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRImagePresenter9, (void **)&This->presenter)))
2240 return E_NOINTERFACE;
2242 if (SUCCEEDED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRSurfaceAllocatorEx9, (void **)&This->allocator)))
2243 This->allocator_is_ex = 1;
2244 else
2246 This->allocator = (IVMRSurfaceAllocatorEx9 *)alloc;
2247 IVMRSurfaceAllocator9_AddRef(alloc);
2248 This->allocator_is_ex = 0;
2251 return S_OK;
2254 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
2256 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2258 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2259 if (This->allocator_d3d9_dev)
2260 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
2261 This->allocator_d3d9_dev = device;
2262 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
2263 This->allocator_mon = monitor;
2265 return S_OK;
2268 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
2270 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2272 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2273 if (This->allocator_d3d9_dev)
2274 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
2275 This->allocator_d3d9_dev = device;
2276 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
2277 This->allocator_mon = monitor;
2279 return S_OK;
2282 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9 *iface, VMR9AllocationInfo *allocinfo, DWORD *numbuffers, IDirect3DSurface9 **surface)
2284 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2285 DWORD i;
2286 HRESULT hr = S_OK;
2288 FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface, This, allocinfo, numbuffers, (numbuffers ? *numbuffers : 0), surface);
2290 if (!allocinfo || !numbuffers || !surface)
2291 return E_POINTER;
2293 if (!*numbuffers || *numbuffers < allocinfo->MinBuffers)
2295 ERR("Invalid number of buffers?\n");
2296 return E_INVALIDARG;
2299 if (!This->allocator_d3d9_dev)
2301 ERR("No direct3d device when requested to allocate a surface!\n");
2302 return VFW_E_WRONG_STATE;
2305 if (allocinfo->dwFlags & VMR9AllocFlag_OffscreenSurface)
2307 ERR("Creating offscreen surface\n");
2308 for (i = 0; i < *numbuffers; ++i)
2310 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight,
2311 allocinfo->Format, allocinfo->Pool, &surface[i], NULL);
2312 if (FAILED(hr))
2313 break;
2316 else if (allocinfo->dwFlags & VMR9AllocFlag_TextureSurface)
2318 TRACE("Creating texture surface\n");
2319 for (i = 0; i < *numbuffers; ++i)
2321 IDirect3DTexture9 *texture;
2323 hr = IDirect3DDevice9_CreateTexture(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight, 1, 0,
2324 allocinfo->Format, allocinfo->Pool, &texture, NULL);
2325 if (FAILED(hr))
2326 break;
2327 IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface[i]);
2328 IDirect3DTexture9_Release(texture);
2331 else
2333 FIXME("Could not allocate for type %08x\n", allocinfo->dwFlags);
2334 return E_NOTIMPL;
2337 if (i >= allocinfo->MinBuffers)
2339 hr = S_OK;
2340 *numbuffers = i;
2342 else
2344 for ( ; i > 0; --i) IDirect3DSurface9_Release(surface[i - 1]);
2345 *numbuffers = 0;
2347 return hr;
2350 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9 *iface, LONG code, LONG_PTR param1, LONG_PTR param2)
2352 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2354 FIXME("(%p/%p)->(...) stub\n", iface, This);
2355 return E_NOTIMPL;
2358 static const IVMRSurfaceAllocatorNotify9Vtbl VMR9_SurfaceAllocatorNotify_Vtbl =
2360 VMR9SurfaceAllocatorNotify_QueryInterface,
2361 VMR9SurfaceAllocatorNotify_AddRef,
2362 VMR9SurfaceAllocatorNotify_Release,
2363 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator,
2364 VMR9SurfaceAllocatorNotify_SetD3DDevice,
2365 VMR9SurfaceAllocatorNotify_ChangeD3DDevice,
2366 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper,
2367 VMR9SurfaceAllocatorNotify_NotifyEvent
2370 static HRESULT vmr_create(IUnknown *outer_unk, LPVOID *ppv, const CLSID *clsid)
2372 HRESULT hr;
2373 struct quartz_vmr* pVMR;
2375 TRACE("(%p, %p)\n", outer_unk, ppv);
2377 *ppv = NULL;
2379 pVMR = CoTaskMemAlloc(sizeof(struct quartz_vmr));
2381 pVMR->hD3d9 = LoadLibraryA("d3d9.dll");
2382 if (!pVMR->hD3d9 )
2384 WARN("Could not load d3d9.dll\n");
2385 CoTaskMemFree(pVMR);
2386 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
2389 pVMR->outer_unk = outer_unk;
2390 pVMR->bUnkOuterValid = FALSE;
2391 pVMR->bAggregatable = FALSE;
2392 pVMR->IUnknown_inner.lpVtbl = &IInner_VTable;
2393 pVMR->IAMCertifiedOutputProtection_iface.lpVtbl = &IAMCertifiedOutputProtection_Vtbl;
2394 pVMR->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl;
2396 pVMR->mode = 0;
2397 pVMR->allocator_d3d9_dev = NULL;
2398 pVMR->allocator_mon= NULL;
2399 pVMR->num_surfaces = pVMR->cur_surface = 0;
2400 pVMR->allocator = NULL;
2401 pVMR->presenter = NULL;
2402 pVMR->hWndClippingWindow = NULL;
2403 pVMR->IVMRFilterConfig_iface.lpVtbl = &VMR7_FilterConfig_Vtbl;
2404 pVMR->IVMRFilterConfig9_iface.lpVtbl = &VMR9_FilterConfig_Vtbl;
2405 pVMR->IVMRMonitorConfig_iface.lpVtbl = &VMR7_MonitorConfig_Vtbl;
2406 pVMR->IVMRMonitorConfig9_iface.lpVtbl = &VMR9_MonitorConfig_Vtbl;
2407 pVMR->IVMRSurfaceAllocatorNotify_iface.lpVtbl = &VMR7_SurfaceAllocatorNotify_Vtbl;
2408 pVMR->IVMRSurfaceAllocatorNotify9_iface.lpVtbl = &VMR9_SurfaceAllocatorNotify_Vtbl;
2409 pVMR->IVMRWindowlessControl_iface.lpVtbl = &VMR7_WindowlessControl_Vtbl;
2410 pVMR->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl;
2412 if (IsEqualGUID(clsid, &CLSID_VideoMixingRenderer))
2413 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer,
2414 (DWORD_PTR)(__FILE__ ": VMR7Impl.csFilter"), &BaseFuncTable);
2415 else
2416 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer9,
2417 (DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable);
2419 if (FAILED(hr))
2420 goto fail;
2422 hr = BaseControlWindow_Init(&pVMR->baseControlWindow, &IVideoWindow_VTable, &pVMR->renderer.filter,
2423 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin,
2424 &renderer_BaseWindowFuncTable);
2425 if (FAILED(hr))
2426 goto fail;
2428 hr = BaseControlVideo_Init(&pVMR->baseControlVideo, &IBasicVideo_VTable, &pVMR->renderer.filter,
2429 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin,
2430 &renderer_BaseControlVideoFuncTable);
2431 if (FAILED(hr))
2432 goto fail;
2434 *ppv = (LPVOID)pVMR;
2435 ZeroMemory(&pVMR->source_rect, sizeof(RECT));
2436 ZeroMemory(&pVMR->target_rect, sizeof(RECT));
2437 TRACE("Created at %p\n", pVMR);
2438 return hr;
2440 fail:
2441 BaseRendererImpl_Release(&pVMR->renderer.filter.IBaseFilter_iface);
2442 FreeLibrary(pVMR->hD3d9);
2443 CoTaskMemFree(pVMR);
2444 return hr;
2447 HRESULT VMR7Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2449 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer);
2452 HRESULT VMR9Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2454 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer9);
2458 static HRESULT WINAPI VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID riid, LPVOID * ppv)
2460 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2461 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
2463 *ppv = NULL;
2465 if (IsEqualIID(riid, &IID_IUnknown))
2466 *ppv = (LPVOID)&(This->IVMRImagePresenter9_iface);
2467 else if (IsEqualIID(riid, &IID_IVMRImagePresenter9))
2468 *ppv = &This->IVMRImagePresenter9_iface;
2469 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorEx9))
2470 *ppv = &This->IVMRSurfaceAllocatorEx9_iface;
2472 if (*ppv)
2474 IUnknown_AddRef((IUnknown *)(*ppv));
2475 return S_OK;
2478 FIXME("No interface for %s\n", debugstr_guid(riid));
2480 return E_NOINTERFACE;
2483 static ULONG WINAPI VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 *iface)
2485 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2486 ULONG refCount = InterlockedIncrement(&This->refCount);
2488 TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
2490 return refCount;
2493 static ULONG WINAPI VMR9_ImagePresenter_Release(IVMRImagePresenter9 *iface)
2495 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2496 ULONG refCount = InterlockedDecrement(&This->refCount);
2498 TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
2500 if (!refCount)
2502 DWORD i;
2503 TRACE("Destroying\n");
2504 CloseHandle(This->ack);
2505 IDirect3D9_Release(This->d3d9_ptr);
2507 TRACE("Number of surfaces: %u\n", This->num_surfaces);
2508 for (i = 0; i < This->num_surfaces; ++i)
2510 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2511 TRACE("Releasing surface %p\n", surface);
2512 if (surface)
2513 IDirect3DSurface9_Release(surface);
2516 CoTaskMemFree(This->d3d9_surfaces);
2517 This->d3d9_surfaces = NULL;
2518 This->num_surfaces = 0;
2519 if (This->d3d9_vertex)
2521 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2522 This->d3d9_vertex = NULL;
2524 CoTaskMemFree(This);
2525 return 0;
2527 return refCount;
2530 static HRESULT WINAPI VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2532 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2534 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2535 return S_OK;
2538 static HRESULT WINAPI VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2540 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2542 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2543 return S_OK;
2546 #define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
2547 struct VERTEX { float x, y, z, rhw, u, v; };
2549 static HRESULT VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2551 IDirect3DTexture9 *texture = NULL;
2552 HRESULT hr;
2554 hr = IDirect3DDevice9_SetFVF(This->d3d9_dev, USED_FVF);
2555 if (FAILED(hr))
2557 FIXME("SetFVF: %08x\n", hr);
2558 return hr;
2561 hr = IDirect3DDevice9_SetStreamSource(This->d3d9_dev, 0, This->d3d9_vertex, 0, sizeof(struct VERTEX));
2562 if (FAILED(hr))
2564 FIXME("SetStreamSource: %08x\n", hr);
2565 return hr;
2568 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **) &texture);
2569 if (FAILED(hr))
2571 FIXME("IDirect3DSurface9_GetContainer failed\n");
2572 return hr;
2574 hr = IDirect3DDevice9_SetTexture(This->d3d9_dev, 0, (IDirect3DBaseTexture9 *)texture);
2575 IDirect3DTexture9_Release(texture);
2576 if (FAILED(hr))
2578 FIXME("SetTexture: %08x\n", hr);
2579 return hr;
2582 hr = IDirect3DDevice9_DrawPrimitive(This->d3d9_dev, D3DPT_TRIANGLESTRIP, 0, 2);
2583 if (FAILED(hr))
2585 FIXME("DrawPrimitive: %08x\n", hr);
2586 return hr;
2589 return S_OK;
2592 static HRESULT VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2594 HRESULT hr;
2595 IDirect3DSurface9 *target = NULL;
2596 RECT target_rect;
2598 hr = IDirect3DDevice9_GetBackBuffer(This->d3d9_dev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &target);
2599 if (FAILED(hr))
2601 ERR("IDirect3DDevice9_GetBackBuffer -- %08x\n", hr);
2602 return hr;
2605 target_rect = This->pVMR9->target_rect;
2606 target_rect.right -= target_rect.left;
2607 target_rect.bottom -= target_rect.top;
2608 target_rect.left = target_rect.top = 0;
2610 /* Flip */
2611 target_rect.top = target_rect.bottom;
2612 target_rect.bottom = 0;
2614 hr = IDirect3DDevice9_StretchRect(This->d3d9_dev, surface, &This->pVMR9->source_rect, target, &target_rect, D3DTEXF_LINEAR);
2615 if (FAILED(hr))
2616 ERR("IDirect3DDevice9_StretchRect -- %08x\n", hr);
2617 IDirect3DSurface9_Release(target);
2619 return hr;
2622 static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR id, VMR9PresentationInfo *info)
2624 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2625 HRESULT hr;
2626 RECT output;
2627 BOOL render = FALSE;
2629 TRACE("(%p/%p/%p)->(...) stub\n", iface, This, This->pVMR9);
2630 GetWindowRect(This->pVMR9->baseControlWindow.baseWindow.hWnd, &output);
2631 TRACE("Output rectangle: starting at %dx%d, up to point %dx%d\n", output.left, output.top, output.right, output.bottom);
2633 /* This might happen if we don't have active focus (eg on a different virtual desktop) */
2634 if (!This->d3d9_dev)
2635 return S_OK;
2637 /* Display image here */
2638 hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
2639 if (FAILED(hr))
2640 FIXME("hr: %08x\n", hr);
2641 hr = IDirect3DDevice9_BeginScene(This->d3d9_dev);
2642 if (SUCCEEDED(hr))
2644 if (This->d3d9_vertex)
2645 hr = VMR9_ImagePresenter_PresentTexture(This, info->lpSurf);
2646 else
2647 hr = VMR9_ImagePresenter_PresentOffscreenSurface(This, info->lpSurf);
2648 render = SUCCEEDED(hr);
2650 else
2651 FIXME("BeginScene: %08x\n", hr);
2652 hr = IDirect3DDevice9_EndScene(This->d3d9_dev);
2653 if (render && SUCCEEDED(hr))
2655 hr = IDirect3DDevice9_Present(This->d3d9_dev, NULL, NULL, This->pVMR9->baseControlWindow.baseWindow.hWnd, NULL);
2656 if (FAILED(hr))
2657 FIXME("Presenting image: %08x\n", hr);
2660 return S_OK;
2663 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter =
2665 VMR9_ImagePresenter_QueryInterface,
2666 VMR9_ImagePresenter_AddRef,
2667 VMR9_ImagePresenter_Release,
2668 VMR9_ImagePresenter_StartPresenting,
2669 VMR9_ImagePresenter_StopPresenting,
2670 VMR9_ImagePresenter_PresentImage
2673 static HRESULT WINAPI VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9 *iface, REFIID riid, LPVOID * ppv)
2675 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2677 return VMR9_ImagePresenter_QueryInterface(&This->IVMRImagePresenter9_iface, riid, ppv);
2680 static ULONG WINAPI VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9 *iface)
2682 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2684 return VMR9_ImagePresenter_AddRef(&This->IVMRImagePresenter9_iface);
2687 static ULONG WINAPI VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9 *iface)
2689 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2691 return VMR9_ImagePresenter_Release(&This->IVMRImagePresenter9_iface);
2694 static HRESULT VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *allocinfo)
2696 D3DCAPS9 caps;
2697 UINT width, height;
2698 HRESULT hr;
2700 if (!(allocinfo->dwFlags & VMR9AllocFlag_TextureSurface))
2701 /* Only needed for texture surfaces */
2702 return S_OK;
2704 hr = IDirect3DDevice9_GetDeviceCaps(This->d3d9_dev, &caps);
2705 if (FAILED(hr))
2706 return hr;
2708 if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2) || (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY))
2710 width = allocinfo->dwWidth;
2711 height = allocinfo->dwHeight;
2713 else
2715 width = height = 1;
2716 while (width < allocinfo->dwWidth)
2717 width *= 2;
2719 while (height < allocinfo->dwHeight)
2720 height *= 2;
2721 FIXME("NPOW2 support missing, not using proper surfaces!\n");
2724 if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
2726 if (height > width)
2727 width = height;
2728 else
2729 height = width;
2730 FIXME("Square texture support required..\n");
2733 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF, allocinfo->Pool, &This->d3d9_vertex, NULL);
2734 if (FAILED(hr))
2736 ERR("Couldn't create vertex buffer: %08x\n", hr);
2737 return hr;
2740 This->reset = TRUE;
2741 allocinfo->dwHeight = height;
2742 allocinfo->dwWidth = width;
2744 return hr;
2747 static DWORD WINAPI MessageLoop(LPVOID lpParameter)
2749 MSG msg;
2750 BOOL fGotMessage;
2751 VMR9DefaultAllocatorPresenterImpl *This = lpParameter;
2753 TRACE("Starting message loop\n");
2755 if (FAILED(BaseWindowImpl_PrepareWindow(&This->pVMR9->baseControlWindow.baseWindow)))
2757 FIXME("Failed to prepare window\n");
2758 return FALSE;
2761 SetEvent(This->ack);
2762 while ((fGotMessage = GetMessageW(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1)
2764 TranslateMessage(&msg);
2765 DispatchMessageW(&msg);
2768 TRACE("End of message loop\n");
2770 return 0;
2773 static UINT d3d9_adapter_from_hwnd(IDirect3D9 *d3d9, HWND hwnd, HMONITOR *mon_out)
2775 UINT d3d9_adapter;
2776 HMONITOR mon;
2778 mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
2779 if (!mon)
2780 d3d9_adapter = 0;
2781 else
2783 for (d3d9_adapter = 0; d3d9_adapter < IDirect3D9_GetAdapterCount(d3d9); ++d3d9_adapter)
2785 if (mon == IDirect3D9_GetAdapterMonitor(d3d9, d3d9_adapter))
2786 break;
2788 if (d3d9_adapter >= IDirect3D9_GetAdapterCount(d3d9))
2789 d3d9_adapter = 0;
2791 if (mon_out)
2792 *mon_out = mon;
2793 return d3d9_adapter;
2796 static BOOL CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *info, DWORD *numbuffers)
2798 D3DPRESENT_PARAMETERS d3dpp;
2799 DWORD d3d9_adapter;
2800 HRESULT hr;
2802 TRACE("(%p)->()\n", This);
2804 This->hWndThread = CreateThread(NULL, 0, MessageLoop, This, 0, &This->tid);
2805 if (!This->hWndThread)
2806 return FALSE;
2808 WaitForSingleObject(This->ack, INFINITE);
2810 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) return FALSE;
2812 /* Obtain a monitor and d3d9 device */
2813 d3d9_adapter = d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon);
2815 /* Now try to create the d3d9 device */
2816 ZeroMemory(&d3dpp, sizeof(d3dpp));
2817 d3dpp.Windowed = TRUE;
2818 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2819 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2820 d3dpp.BackBufferHeight = This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top;
2821 d3dpp.BackBufferWidth = This->pVMR9->target_rect.right - This->pVMR9->target_rect.left;
2823 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev);
2824 if (FAILED(hr))
2826 ERR("Could not create device: %08x\n", hr);
2827 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2828 return FALSE;
2830 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2832 This->d3d9_surfaces = CoTaskMemAlloc(*numbuffers * sizeof(IDirect3DSurface9 *));
2833 ZeroMemory(This->d3d9_surfaces, *numbuffers * sizeof(IDirect3DSurface9 *));
2835 hr = VMR9_SurfaceAllocator_SetAllocationSettings(This, info);
2836 if (FAILED(hr))
2837 ERR("Setting allocation settings failed: %08x\n", hr);
2839 if (SUCCEEDED(hr))
2841 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, info, numbuffers, This->d3d9_surfaces);
2842 if (FAILED(hr))
2843 ERR("Allocating surfaces failed: %08x\n", hr);
2846 if (FAILED(hr))
2848 IVMRSurfaceAllocatorEx9_TerminateDevice(This->pVMR9->allocator, This->pVMR9->cookie);
2849 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2850 return FALSE;
2853 This->num_surfaces = *numbuffers;
2855 return TRUE;
2858 static HRESULT WINAPI VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, VMR9AllocationInfo *allocinfo, DWORD *numbuffers)
2860 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2862 if (This->pVMR9->mode != VMR9Mode_Windowed && !This->pVMR9->hWndClippingWindow)
2864 ERR("No window set\n");
2865 return VFW_E_WRONG_STATE;
2868 This->info = *allocinfo;
2870 if (!CreateRenderingWindow(This, allocinfo, numbuffers))
2872 ERR("Failed to create rendering window, expect no output!\n");
2873 return VFW_E_WRONG_STATE;
2876 return S_OK;
2879 static HRESULT WINAPI VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id)
2881 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2883 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
2885 return S_OK;
2888 SendMessageW(This->pVMR9->baseControlWindow.baseWindow.hWnd, WM_CLOSE, 0, 0);
2889 PostThreadMessageW(This->tid, WM_QUIT, 0, 0);
2890 WaitForSingleObject(This->hWndThread, INFINITE);
2891 This->hWndThread = NULL;
2892 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2894 return S_OK;
2897 /* Recreate all surfaces (If allocated as D3DPOOL_DEFAULT) and survive! */
2898 static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl *This)
2900 struct VERTEX t_vert[4];
2901 UINT width, height;
2902 unsigned int i;
2903 void *bits = NULL;
2904 D3DPRESENT_PARAMETERS d3dpp;
2905 HRESULT hr;
2907 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
2909 ERR("No window\n");
2910 return E_FAIL;
2913 if (!This->d3d9_surfaces || !This->reset)
2914 return S_OK;
2916 This->reset = FALSE;
2917 TRACE("RESETTING\n");
2918 if (This->d3d9_vertex)
2920 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2921 This->d3d9_vertex = NULL;
2924 for (i = 0; i < This->num_surfaces; ++i)
2926 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2927 TRACE("Releasing surface %p\n", surface);
2928 if (surface)
2929 IDirect3DSurface9_Release(surface);
2931 ZeroMemory(This->d3d9_surfaces, sizeof(IDirect3DSurface9 *) * This->num_surfaces);
2933 /* Now try to create the d3d9 device */
2934 ZeroMemory(&d3dpp, sizeof(d3dpp));
2935 d3dpp.Windowed = TRUE;
2936 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2937 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2939 if (This->d3d9_dev)
2940 IDirect3DDevice9_Release(This->d3d9_dev);
2941 This->d3d9_dev = NULL;
2942 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);
2943 if (FAILED(hr))
2945 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);
2946 if (FAILED(hr))
2948 ERR("--> Creating device: %08x\n", hr);
2949 return S_OK;
2952 IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2954 IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, &This->info, &This->num_surfaces, This->d3d9_surfaces);
2956 This->reset = FALSE;
2958 if (!(This->info.dwFlags & VMR9AllocFlag_TextureSurface))
2959 return S_OK;
2961 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF,
2962 This->info.Pool, &This->d3d9_vertex, NULL);
2964 width = This->info.dwWidth;
2965 height = This->info.dwHeight;
2967 for (i = 0; i < sizeof(t_vert) / sizeof(t_vert[0]); ++i)
2969 if (i % 2)
2971 t_vert[i].x = (float)This->pVMR9->target_rect.right - (float)This->pVMR9->target_rect.left - 0.5f;
2972 t_vert[i].u = (float)This->pVMR9->source_rect.right / (float)width;
2974 else
2976 t_vert[i].x = -0.5f;
2977 t_vert[i].u = (float)This->pVMR9->source_rect.left / (float)width;
2980 if (i % 4 < 2)
2982 t_vert[i].y = -0.5f;
2983 t_vert[i].v = (float)This->pVMR9->source_rect.bottom / (float)height;
2985 else
2987 t_vert[i].y = (float)This->pVMR9->target_rect.bottom - (float)This->pVMR9->target_rect.top - 0.5f;
2988 t_vert[i].v = (float)This->pVMR9->source_rect.top / (float)height;
2990 t_vert[i].z = 0.0f;
2991 t_vert[i].rhw = 1.0f;
2994 FIXME("Vertex rectangle:\n");
2995 FIXME("X, Y: %f, %f\n", t_vert[0].x, t_vert[0].y);
2996 FIXME("X, Y: %f, %f\n", t_vert[3].x, t_vert[3].y);
2997 FIXME("TOP, LEFT: %f, %f\n", t_vert[0].u, t_vert[0].v);
2998 FIXME("DOWN, BOTTOM: %f, %f\n", t_vert[3].u, t_vert[3].v);
3000 IDirect3DVertexBuffer9_Lock(This->d3d9_vertex, 0, sizeof(t_vert), &bits, 0);
3001 memcpy(bits, t_vert, sizeof(t_vert));
3002 IDirect3DVertexBuffer9_Unlock(This->d3d9_vertex);
3004 return S_OK;
3007 static HRESULT WINAPI VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, DWORD surfaceindex, DWORD flags, IDirect3DSurface9 **surface)
3009 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
3011 /* Update everything first, this is needed because the surface might be destroyed in the reset */
3012 if (!This->d3d9_dev)
3014 TRACE("Device has left me!\n");
3015 return E_FAIL;
3018 VMR9_SurfaceAllocator_UpdateDeviceReset(This);
3020 if (surfaceindex >= This->num_surfaces)
3022 ERR("surfaceindex is greater than num_surfaces\n");
3023 return E_FAIL;
3025 *surface = This->d3d9_surfaces[surfaceindex];
3026 IDirect3DSurface9_AddRef(*surface);
3028 return S_OK;
3031 static HRESULT WINAPI VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9 *iface, IVMRSurfaceAllocatorNotify9 *allocnotify)
3033 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
3035 TRACE("(%p/%p)->(...)\n", iface, This);
3037 /* No AddRef taken here or the base VMR9 filter would never be destroied */
3038 This->SurfaceAllocatorNotify = allocnotify;
3039 return S_OK;
3042 static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator =
3044 VMR9_SurfaceAllocator_QueryInterface,
3045 VMR9_SurfaceAllocator_AddRef,
3046 VMR9_SurfaceAllocator_Release,
3047 VMR9_SurfaceAllocator_InitializeDevice,
3048 VMR9_SurfaceAllocator_TerminateDevice,
3049 VMR9_SurfaceAllocator_GetSurface,
3050 VMR9_SurfaceAllocator_AdviseNotify,
3051 NULL /* This isn't the SurfaceAllocatorEx type yet, working on it */
3054 static IDirect3D9 *init_d3d9(HMODULE d3d9_handle)
3056 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion);
3058 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
3059 if (!d3d9_create) return NULL;
3061 return d3d9_create(D3D_SDK_VERSION);
3064 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv)
3066 HRESULT hr = S_OK;
3067 int i;
3068 VMR9DefaultAllocatorPresenterImpl* This;
3070 This = CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl));
3071 if (!This)
3072 return E_OUTOFMEMORY;
3074 This->d3d9_ptr = init_d3d9(parent->hD3d9);
3075 if (!This->d3d9_ptr)
3077 WARN("Could not initialize d3d9.dll\n");
3078 CoTaskMemFree(This);
3079 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
3082 i = 0;
3085 D3DDISPLAYMODE mode;
3087 hr = IDirect3D9_EnumAdapterModes(This->d3d9_ptr, i++, D3DFMT_X8R8G8B8, 0, &mode);
3088 if (hr == D3DERR_INVALIDCALL) break; /* out of adapters */
3089 } while (FAILED(hr));
3090 if (FAILED(hr))
3091 ERR("HR: %08x\n", hr);
3092 if (hr == D3DERR_NOTAVAILABLE)
3094 ERR("Format not supported\n");
3095 IDirect3D9_Release(This->d3d9_ptr);
3096 CoTaskMemFree(This);
3097 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
3100 This->IVMRImagePresenter9_iface.lpVtbl = &VMR9_ImagePresenter;
3101 This->IVMRSurfaceAllocatorEx9_iface.lpVtbl = &VMR9_SurfaceAllocator;
3103 This->refCount = 1;
3104 This->pVMR9 = parent;
3105 This->d3d9_surfaces = NULL;
3106 This->d3d9_dev = NULL;
3107 This->hMon = 0;
3108 This->d3d9_vertex = NULL;
3109 This->num_surfaces = 0;
3110 This->hWndThread = NULL;
3111 This->ack = CreateEventW(NULL, 0, 0, NULL);
3112 This->SurfaceAllocatorNotify = NULL;
3113 This->reset = FALSE;
3115 *ppv = &This->IVMRImagePresenter9_iface;
3116 return S_OK;