netapi32: Add support for info level 20 in NetUserEnum.
[wine.git] / dlls / quartz / vmr9.c
blobe950a484842eb5a0e4d963c17866bb1fc9752767
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 #define NONAMELESSSTRUCT
26 #define NONAMELESSUNION
27 #include "quartz_private.h"
29 #include "uuids.h"
30 #include "vfwmsgs.h"
31 #include "amvideo.h"
32 #include "windef.h"
33 #include "winbase.h"
34 #include "dshow.h"
35 #include "evcode.h"
36 #include "strmif.h"
37 #include "ddraw.h"
38 #include "dvdmedia.h"
39 #include "d3d9.h"
40 #include "vmr9.h"
41 #include "pin.h"
43 #include "wine/unicode.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
48 struct quartz_vmr
50 BaseRenderer renderer;
51 BaseControlWindow baseControlWindow;
52 BaseControlVideo baseControlVideo;
54 IUnknown IUnknown_inner;
55 IAMCertifiedOutputProtection IAMCertifiedOutputProtection_iface;
56 IAMFilterMiscFlags IAMFilterMiscFlags_iface;
57 IVMRFilterConfig IVMRFilterConfig_iface;
58 IVMRFilterConfig9 IVMRFilterConfig9_iface;
59 IVMRMonitorConfig IVMRMonitorConfig_iface;
60 IVMRMonitorConfig9 IVMRMonitorConfig9_iface;
61 IVMRSurfaceAllocatorNotify IVMRSurfaceAllocatorNotify_iface;
62 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface;
63 IVMRWindowlessControl IVMRWindowlessControl_iface;
64 IVMRWindowlessControl9 IVMRWindowlessControl9_iface;
66 IVMRSurfaceAllocatorEx9 *allocator;
67 IVMRImagePresenter9 *presenter;
68 BOOL allocator_is_ex;
71 * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed
72 * What I do is implement windowless as a special case of renderless, and then
73 * windowed also as a special case of windowless. This is probably the easiest way.
75 VMR9Mode mode;
76 BITMAPINFOHEADER bmiheader;
77 IUnknown * outer_unk;
78 BOOL bUnkOuterValid;
79 BOOL bAggregatable;
81 HMODULE hD3d9;
83 /* Presentation related members */
84 IDirect3DDevice9 *allocator_d3d9_dev;
85 HMONITOR allocator_mon;
86 DWORD num_surfaces;
87 DWORD cur_surface;
88 DWORD_PTR cookie;
90 /* for Windowless Mode */
91 HWND hWndClippingWindow;
93 RECT source_rect;
94 RECT target_rect;
95 LONG VideoWidth;
96 LONG VideoHeight;
99 static inline struct quartz_vmr *impl_from_inner_IUnknown(IUnknown *iface)
101 return CONTAINING_RECORD(iface, struct quartz_vmr, IUnknown_inner);
104 static inline struct quartz_vmr *impl_from_BaseWindow(BaseWindow *wnd)
106 return CONTAINING_RECORD(wnd, struct quartz_vmr, baseControlWindow.baseWindow);
109 static inline struct quartz_vmr *impl_from_IVideoWindow(IVideoWindow *iface)
111 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlWindow.IVideoWindow_iface);
114 static inline struct quartz_vmr *impl_from_BaseControlVideo(BaseControlVideo *cvid)
116 return CONTAINING_RECORD(cvid, struct quartz_vmr, baseControlVideo);
119 static inline struct quartz_vmr *impl_from_IBasicVideo(IBasicVideo *iface)
121 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlVideo.IBasicVideo_iface);
124 static inline struct quartz_vmr *impl_from_IAMCertifiedOutputProtection(IAMCertifiedOutputProtection *iface)
126 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMCertifiedOutputProtection_iface);
129 static inline struct quartz_vmr *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
131 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMFilterMiscFlags_iface);
134 static inline struct quartz_vmr *impl_from_IVMRFilterConfig(IVMRFilterConfig *iface)
136 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig_iface);
139 static inline struct quartz_vmr *impl_from_IVMRFilterConfig9(IVMRFilterConfig9 *iface)
141 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig9_iface);
144 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig(IVMRMonitorConfig *iface)
146 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig_iface);
149 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig9(IVMRMonitorConfig9 *iface)
151 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig9_iface);
154 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify(IVMRSurfaceAllocatorNotify *iface)
156 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify_iface);
159 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify9(IVMRSurfaceAllocatorNotify9 *iface)
161 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify9_iface);
164 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl(IVMRWindowlessControl *iface)
166 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl_iface);
169 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl9(IVMRWindowlessControl9 *iface)
171 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl9_iface);
174 typedef struct
176 IVMRImagePresenter9 IVMRImagePresenter9_iface;
177 IVMRSurfaceAllocatorEx9 IVMRSurfaceAllocatorEx9_iface;
179 LONG refCount;
181 HANDLE ack;
182 DWORD tid;
183 HANDLE hWndThread;
185 IDirect3DDevice9 *d3d9_dev;
186 IDirect3D9 *d3d9_ptr;
187 IDirect3DSurface9 **d3d9_surfaces;
188 IDirect3DVertexBuffer9 *d3d9_vertex;
189 HMONITOR hMon;
190 DWORD num_surfaces;
192 BOOL reset;
193 VMR9AllocationInfo info;
195 struct quartz_vmr* pVMR9;
196 IVMRSurfaceAllocatorNotify9 *SurfaceAllocatorNotify;
197 } VMR9DefaultAllocatorPresenterImpl;
199 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRImagePresenter9( IVMRImagePresenter9 *iface)
201 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRImagePresenter9_iface);
204 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRSurfaceAllocatorEx9( IVMRSurfaceAllocatorEx9 *iface)
206 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRSurfaceAllocatorEx9_iface);
209 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv);
211 static DWORD VMR9_SendSampleData(struct quartz_vmr *This, VMR9PresentationInfo *info, LPBYTE data,
212 DWORD size)
214 AM_MEDIA_TYPE *amt;
215 HRESULT hr = S_OK;
216 int width;
217 int height;
218 BITMAPINFOHEADER *bmiHeader;
219 D3DLOCKED_RECT lock;
221 TRACE("%p %p %d\n", This, data, size);
223 amt = &This->renderer.pInputPin->pin.mtCurrent;
225 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
227 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
229 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
231 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
233 else
235 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
236 return VFW_E_RUNTIME_ERROR;
239 TRACE("biSize = %d\n", bmiHeader->biSize);
240 TRACE("biWidth = %d\n", bmiHeader->biWidth);
241 TRACE("biHeight = %d\n", bmiHeader->biHeight);
242 TRACE("biPlanes = %d\n", bmiHeader->biPlanes);
243 TRACE("biBitCount = %d\n", bmiHeader->biBitCount);
244 TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(bmiHeader->biCompression), 4));
245 TRACE("biSizeImage = %d\n", bmiHeader->biSizeImage);
247 width = bmiHeader->biWidth;
248 height = bmiHeader->biHeight;
250 TRACE("Src Rect: %d %d %d %d\n", This->source_rect.left, This->source_rect.top, This->source_rect.right, This->source_rect.bottom);
251 TRACE("Dst Rect: %d %d %d %d\n", This->target_rect.left, This->target_rect.top, This->target_rect.right, This->target_rect.bottom);
253 hr = IDirect3DSurface9_LockRect(info->lpSurf, &lock, NULL, D3DLOCK_DISCARD);
254 if (FAILED(hr))
256 ERR("IDirect3DSurface9_LockRect failed (%x)\n",hr);
257 return hr;
260 if (lock.Pitch != width * bmiHeader->biBitCount / 8)
262 WARN("Slow path! %u/%u\n", lock.Pitch, width * bmiHeader->biBitCount/8);
264 while (height--)
266 memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8);
267 data = data + width * bmiHeader->biBitCount / 8;
268 lock.pBits = (char *)lock.pBits + lock.Pitch;
271 else memcpy(lock.pBits, data, size);
273 IDirect3DSurface9_UnlockRect(info->lpSurf);
275 hr = IVMRImagePresenter9_PresentImage(This->presenter, This->cookie, info);
276 return hr;
279 static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample)
281 struct quartz_vmr *This = (struct quartz_vmr*)iface;
282 LPBYTE pbSrcStream = NULL;
283 long cbSrcStream = 0;
284 REFERENCE_TIME tStart, tStop;
285 VMR9PresentationInfo info;
286 HRESULT hr;
288 TRACE("%p %p\n", iface, pSample);
290 /* It is possible that there is no device at this point */
292 if (!This->allocator || !This->presenter)
294 ERR("NO PRESENTER!!\n");
295 return S_FALSE;
298 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
299 if (FAILED(hr))
300 info.dwFlags = VMR9Sample_SrcDstRectsValid;
301 else
302 info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid;
304 if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
305 info.dwFlags |= VMR9Sample_Discontinuity;
307 if (IMediaSample_IsPreroll(pSample) == S_OK)
308 info.dwFlags |= VMR9Sample_Preroll;
310 if (IMediaSample_IsSyncPoint(pSample) == S_OK)
311 info.dwFlags |= VMR9Sample_SyncPoint;
313 /* If we render ourselves, and this is a preroll sample, discard it */
314 if (This->baseControlWindow.baseWindow.hWnd && (info.dwFlags & VMR9Sample_Preroll))
316 return S_OK;
319 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
320 if (FAILED(hr))
322 ERR("Cannot get pointer to sample data (%x)\n", hr);
323 return hr;
326 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
328 info.rtStart = tStart;
329 info.rtEnd = tStop;
330 info.szAspectRatio.cx = This->bmiheader.biWidth;
331 info.szAspectRatio.cy = This->bmiheader.biHeight;
333 hr = IVMRSurfaceAllocatorEx9_GetSurface(This->allocator, This->cookie, (++This->cur_surface)%This->num_surfaces, 0, &info.lpSurf);
335 if (FAILED(hr))
336 return hr;
338 VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream);
339 IDirect3DSurface9_Release(info.lpSurf);
341 return hr;
344 static HRESULT WINAPI VMR9_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt)
346 struct quartz_vmr *This = (struct quartz_vmr*)iface;
348 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat)
349 return S_FALSE;
351 /* Ignore subtype, test for bicompression instead */
352 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
354 VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
356 This->bmiheader = format->bmiHeader;
357 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
358 This->source_rect.right = This->VideoWidth = format->bmiHeader.biWidth;
359 This->source_rect.bottom = This->VideoHeight = format->bmiHeader.biHeight;
360 This->source_rect.top = This->source_rect.left = 0;
362 else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
364 VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat;
366 This->bmiheader = format->bmiHeader;
368 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
369 This->source_rect.right = This->VideoWidth = format->bmiHeader.biWidth;
370 This->source_rect.bottom = This->VideoHeight = format->bmiHeader.biHeight;
371 This->source_rect.top = This->source_rect.left = 0;
373 else
375 ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
376 return S_FALSE;
378 if (This->bmiheader.biCompression)
379 return S_FALSE;
380 return S_OK;
383 static HRESULT VMR9_maybe_init(struct quartz_vmr *This, BOOL force)
385 VMR9AllocationInfo info;
386 DWORD buffers;
387 HRESULT hr;
389 TRACE("my mode: %u, my window: %p, my last window: %p\n", This->mode, This->baseControlWindow.baseWindow.hWnd, This->hWndClippingWindow);
390 if (This->baseControlWindow.baseWindow.hWnd || !This->renderer.pInputPin->pin.pConnectedTo)
391 return S_OK;
393 if (This->mode == VMR9Mode_Windowless && !This->hWndClippingWindow)
394 return (force ? VFW_E_RUNTIME_ERROR : S_OK);
396 TRACE("Initializing\n");
397 info.dwFlags = VMR9AllocFlag_TextureSurface;
398 info.dwHeight = This->source_rect.bottom;
399 info.dwWidth = This->source_rect.right;
400 info.Pool = D3DPOOL_DEFAULT;
401 info.MinBuffers = 2;
402 FIXME("Reduce ratio to least common denominator\n");
403 info.szAspectRatio.cx = info.dwWidth;
404 info.szAspectRatio.cy = info.dwHeight;
405 info.szNativeSize.cx = This->bmiheader.biWidth;
406 info.szNativeSize.cy = This->bmiheader.biHeight;
407 buffers = 2;
409 switch (This->bmiheader.biBitCount)
411 case 8: info.Format = D3DFMT_R3G3B2; break;
412 case 15: info.Format = D3DFMT_X1R5G5B5; break;
413 case 16: info.Format = D3DFMT_R5G6B5; break;
414 case 24: info.Format = D3DFMT_R8G8B8; break;
415 case 32: info.Format = D3DFMT_X8R8G8B8; break;
416 default:
417 FIXME("Unknown bpp %u\n", This->bmiheader.biBitCount);
418 hr = E_INVALIDARG;
421 This->cur_surface = 0;
422 if (This->num_surfaces)
424 ERR("num_surfaces or d3d9_surfaces not 0\n");
425 return E_FAIL;
428 hr = IVMRSurfaceAllocatorEx9_InitializeDevice(This->allocator, This->cookie, &info, &buffers);
429 if (SUCCEEDED(hr))
431 This->source_rect.left = This->source_rect.top = 0;
432 This->source_rect.right = This->bmiheader.biWidth;
433 This->source_rect.bottom = This->bmiheader.biHeight;
435 This->num_surfaces = buffers;
437 return hr;
440 static VOID WINAPI VMR9_OnStartStreaming(BaseRenderer* iface)
442 struct quartz_vmr *This = (struct quartz_vmr*)iface;
444 TRACE("(%p)\n", This);
446 VMR9_maybe_init(This, TRUE);
447 IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie);
448 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
449 This->source_rect.left,
450 This->source_rect.top,
451 This->source_rect.right - This->source_rect.left,
452 This->source_rect.bottom - This->source_rect.top,
453 SWP_NOZORDER|SWP_NOMOVE|SWP_DEFERERASE);
454 ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_SHOW);
455 GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->target_rect);
458 static VOID WINAPI VMR9_OnStopStreaming(BaseRenderer* iface)
460 struct quartz_vmr *This = (struct quartz_vmr*)iface;
462 TRACE("(%p)\n", This);
464 if (This->renderer.filter.state == State_Running)
465 IVMRImagePresenter9_StopPresenting(This->presenter, This->cookie);
468 static HRESULT WINAPI VMR9_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime)
470 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
471 if (IMediaSample_IsPreroll(pSample) == S_OK)
472 return E_FAIL;
473 return S_FALSE;
476 static HRESULT WINAPI VMR9_CompleteConnect(BaseRenderer *This, IPin *pReceivePin)
478 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This;
479 HRESULT hr;
481 TRACE("(%p)\n", This);
483 if (pVMR9->mode ||
484 SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&pVMR9->IVMRFilterConfig9_iface, VMR9Mode_Windowed)))
485 hr = VMR9_maybe_init(pVMR9, FALSE);
487 return hr;
490 static HRESULT WINAPI VMR9_BreakConnect(BaseRenderer *This)
492 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This;
493 HRESULT hr = S_OK;
495 if (!pVMR9->mode)
496 return S_FALSE;
497 if (This->pInputPin->pin.pConnectedTo && pVMR9->allocator && pVMR9->presenter)
499 if (pVMR9->renderer.filter.state != State_Stopped)
501 ERR("Disconnecting while not stopped! UNTESTED!!\n");
503 if (pVMR9->renderer.filter.state == State_Running)
504 hr = IVMRImagePresenter9_StopPresenting(pVMR9->presenter, pVMR9->cookie);
505 IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9->allocator, pVMR9->cookie);
506 pVMR9->num_surfaces = 0;
508 return hr;
511 static const BaseRendererFuncTable BaseFuncTable = {
512 VMR9_CheckMediaType,
513 VMR9_DoRenderSample,
514 /**/
515 NULL,
516 NULL,
517 NULL,
518 VMR9_OnStartStreaming,
519 VMR9_OnStopStreaming,
520 NULL,
521 NULL,
522 NULL,
523 VMR9_ShouldDrawSampleNow,
524 NULL,
525 /**/
526 VMR9_CompleteConnect,
527 VMR9_BreakConnect,
528 NULL,
529 NULL,
530 NULL,
533 static LPWSTR WINAPI VMR9_GetClassWindowStyles(BaseWindow *This, DWORD *pClassStyles, DWORD *pWindowStyles, DWORD *pWindowStylesEx)
535 static WCHAR classnameW[] = { 'I','V','M','R','9',' ','C','l','a','s','s', 0 };
537 *pClassStyles = 0;
538 *pWindowStyles = WS_SIZEBOX;
539 *pWindowStylesEx = 0;
541 return classnameW;
544 static RECT WINAPI VMR9_GetDefaultRect(BaseWindow *This)
546 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
547 static RECT defRect;
549 defRect.left = defRect.top = 0;
550 defRect.right = pVMR9->VideoWidth;
551 defRect.bottom = pVMR9->VideoHeight;
553 return defRect;
556 static BOOL WINAPI VMR9_OnSize(BaseWindow *This, LONG Width, LONG Height)
558 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
560 TRACE("WM_SIZE %d %d\n", Width, Height);
561 GetClientRect(This->hWnd, &pVMR9->target_rect);
562 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
563 pVMR9->target_rect.left,
564 pVMR9->target_rect.top,
565 pVMR9->target_rect.right - pVMR9->target_rect.left,
566 pVMR9->target_rect.bottom - pVMR9->target_rect.top);
567 return BaseWindowImpl_OnSize(This, Width, Height);
570 static const BaseWindowFuncTable renderer_BaseWindowFuncTable = {
571 VMR9_GetClassWindowStyles,
572 VMR9_GetDefaultRect,
573 NULL,
574 BaseControlWindowImpl_PossiblyEatMessage,
575 VMR9_OnSize,
578 static HRESULT WINAPI VMR9_GetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
580 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
581 CopyRect(pSourceRect,&pVMR9->source_rect);
582 return S_OK;
585 static HRESULT WINAPI VMR9_GetStaticImage(BaseControlVideo* This, LONG *pBufferSize, LONG *pDIBImage)
587 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
588 BITMAPINFOHEADER *bmiHeader;
589 LONG needed_size;
590 AM_MEDIA_TYPE *amt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
591 char *ptr;
593 FIXME("(%p/%p)->(%p, %p): partial stub\n", pVMR9, This, pBufferSize, pDIBImage);
595 EnterCriticalSection(&pVMR9->renderer.filter.csFilter);
597 if (!pVMR9->renderer.pMediaSample)
599 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
600 return (pVMR9->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
603 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
605 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
607 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
609 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
611 else
613 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
614 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
615 return VFW_E_RUNTIME_ERROR;
618 needed_size = bmiHeader->biSize;
619 needed_size += IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample);
621 if (!pDIBImage)
623 *pBufferSize = needed_size;
624 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
625 return S_OK;
628 if (needed_size < *pBufferSize)
630 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
631 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
632 return E_FAIL;
634 *pBufferSize = needed_size;
636 memcpy(pDIBImage, bmiHeader, bmiHeader->biSize);
637 IMediaSample_GetPointer(pVMR9->renderer.pMediaSample, (BYTE **)&ptr);
638 memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample));
640 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
641 return S_OK;
644 static HRESULT WINAPI VMR9_GetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
646 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
647 CopyRect(pTargetRect,&pVMR9->target_rect);
648 return S_OK;
651 static VIDEOINFOHEADER* WINAPI VMR9_GetVideoFormat(BaseControlVideo* This)
653 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
654 AM_MEDIA_TYPE *pmt;
656 TRACE("(%p/%p)\n", pVMR9, This);
658 pmt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
659 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) {
660 return (VIDEOINFOHEADER*)pmt->pbFormat;
661 } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) {
662 static VIDEOINFOHEADER vih;
663 VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat;
664 memcpy(&vih,vih2,sizeof(VIDEOINFOHEADER));
665 memcpy(&vih.bmiHeader, &vih2->bmiHeader, sizeof(BITMAPINFOHEADER));
666 return &vih;
667 } else {
668 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype));
669 return NULL;
673 static HRESULT WINAPI VMR9_IsDefaultSourceRect(BaseControlVideo* This)
675 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
676 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
678 return S_OK;
681 static HRESULT WINAPI VMR9_IsDefaultTargetRect(BaseControlVideo* This)
683 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
684 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
686 return S_OK;
689 static HRESULT WINAPI VMR9_SetDefaultSourceRect(BaseControlVideo* This)
691 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
693 pVMR9->source_rect.left = 0;
694 pVMR9->source_rect.top = 0;
695 pVMR9->source_rect.right = pVMR9->VideoWidth;
696 pVMR9->source_rect.bottom = pVMR9->VideoHeight;
698 return S_OK;
701 static HRESULT WINAPI VMR9_SetDefaultTargetRect(BaseControlVideo* This)
703 RECT rect;
704 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
706 if (!GetClientRect(pVMR9->baseControlWindow.baseWindow.hWnd, &rect))
707 return E_FAIL;
709 pVMR9->target_rect.left = 0;
710 pVMR9->target_rect.top = 0;
711 pVMR9->target_rect.right = rect.right;
712 pVMR9->target_rect.bottom = rect.bottom;
714 return S_OK;
717 static HRESULT WINAPI VMR9_SetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
719 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
720 CopyRect(&pVMR9->source_rect,pSourceRect);
721 return S_OK;
724 static HRESULT WINAPI VMR9_SetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
726 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
727 CopyRect(&pVMR9->target_rect,pTargetRect);
728 return S_OK;
731 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = {
732 VMR9_GetSourceRect,
733 VMR9_GetStaticImage,
734 VMR9_GetTargetRect,
735 VMR9_GetVideoFormat,
736 VMR9_IsDefaultSourceRect,
737 VMR9_IsDefaultTargetRect,
738 VMR9_SetDefaultSourceRect,
739 VMR9_SetDefaultTargetRect,
740 VMR9_SetSourceRect,
741 VMR9_SetTargetRect
744 static HRESULT WINAPI VMR9Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
746 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
747 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
749 if (This->bAggregatable)
750 This->bUnkOuterValid = TRUE;
752 *ppv = NULL;
754 if (IsEqualIID(riid, &IID_IUnknown))
755 *ppv = &This->IUnknown_inner;
756 else if (IsEqualIID(riid, &IID_IVideoWindow))
757 *ppv = &This->baseControlWindow.IVideoWindow_iface;
758 else if (IsEqualIID(riid, &IID_IBasicVideo))
759 *ppv = &This->baseControlVideo.IBasicVideo_iface;
760 else if (IsEqualIID(riid, &IID_IAMCertifiedOutputProtection))
761 *ppv = &This->IAMCertifiedOutputProtection_iface;
762 else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
763 *ppv = &This->IAMFilterMiscFlags_iface;
764 else if (IsEqualIID(riid, &IID_IVMRFilterConfig))
765 *ppv = &This->IVMRFilterConfig_iface;
766 else if (IsEqualIID(riid, &IID_IVMRFilterConfig9))
767 *ppv = &This->IVMRFilterConfig9_iface;
768 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig))
769 *ppv = &This->IVMRMonitorConfig_iface;
770 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig9))
771 *ppv = &This->IVMRMonitorConfig9_iface;
772 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify) && This->mode == (VMR9Mode)VMRMode_Renderless)
773 *ppv = &This->IVMRSurfaceAllocatorNotify_iface;
774 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9) && This->mode == VMR9Mode_Renderless)
775 *ppv = &This->IVMRSurfaceAllocatorNotify9_iface;
776 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl) && This->mode == (VMR9Mode)VMRMode_Windowless)
777 *ppv = &This->IVMRWindowlessControl_iface;
778 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9) && This->mode == VMR9Mode_Windowless)
779 *ppv = &This->IVMRWindowlessControl9_iface;
780 else
782 HRESULT hr;
783 hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
784 if (SUCCEEDED(hr))
785 return hr;
788 if (*ppv)
790 IUnknown_AddRef((IUnknown *)(*ppv));
791 return S_OK;
794 else if (IsEqualIID(riid, &IID_IBasicVideo2))
795 FIXME("No interface for IID_IBasicVideo2\n");
796 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9))
798 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9))
800 else if (IsEqualIID(riid, &IID_IMediaPosition))
801 FIXME("No interface for IID_IMediaPosition\n");
802 else if (IsEqualIID(riid, &IID_IQualProp))
803 FIXME("No interface for IID_IQualProp\n");
804 else if (IsEqualIID(riid, &IID_IVMRAspectRatioControl9))
805 FIXME("No interface for IID_IVMRAspectRatioControl9\n");
806 else if (IsEqualIID(riid, &IID_IVMRDeinterlaceControl9))
807 FIXME("No interface for IID_IVMRDeinterlaceControl9\n");
808 else if (IsEqualIID(riid, &IID_IVMRMixerBitmap9))
809 FIXME("No interface for IID_IVMRMixerBitmap9\n");
810 else if (IsEqualIID(riid, &IID_IVMRMixerControl9))
811 FIXME("No interface for IID_IVMRMixerControl9\n");
812 else
813 FIXME("No interface for %s\n", debugstr_guid(riid));
815 return E_NOINTERFACE;
818 static ULONG WINAPI VMR9Inner_AddRef(IUnknown * iface)
820 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
821 ULONG refCount = BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
823 TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
825 return refCount;
828 static ULONG WINAPI VMR9Inner_Release(IUnknown * iface)
830 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
831 ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface);
833 TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
835 if (!refCount)
837 TRACE("Destroying\n");
838 BaseControlWindow_Destroy(&This->baseControlWindow);
839 FreeLibrary(This->hD3d9);
841 if (This->allocator)
842 IVMRSurfaceAllocatorEx9_Release(This->allocator);
843 if (This->presenter)
844 IVMRImagePresenter9_Release(This->presenter);
846 This->num_surfaces = 0;
847 if (This->allocator_d3d9_dev)
849 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
850 This->allocator_d3d9_dev = NULL;
853 CoTaskMemFree(This);
855 return refCount;
858 static const IUnknownVtbl IInner_VTable =
860 VMR9Inner_QueryInterface,
861 VMR9Inner_AddRef,
862 VMR9Inner_Release
865 static HRESULT WINAPI VMR9_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
867 struct quartz_vmr *This = (struct quartz_vmr*)iface;
869 if (This->bAggregatable)
870 This->bUnkOuterValid = TRUE;
872 if (This->outer_unk)
874 if (This->bAggregatable)
875 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
877 if (IsEqualIID(riid, &IID_IUnknown))
879 HRESULT hr;
881 IUnknown_AddRef(&This->IUnknown_inner);
882 hr = IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
883 IUnknown_Release(&This->IUnknown_inner);
884 This->bAggregatable = TRUE;
885 return hr;
888 *ppv = NULL;
889 return E_NOINTERFACE;
892 return IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
895 static ULONG WINAPI VMR9_AddRef(IBaseFilter * iface)
897 struct quartz_vmr *This = (struct quartz_vmr*)iface;
898 LONG ret;
900 if (This->outer_unk && This->bUnkOuterValid)
901 ret = IUnknown_AddRef(This->outer_unk);
902 else
903 ret = IUnknown_AddRef(&This->IUnknown_inner);
905 TRACE("(%p)->AddRef from %d\n", iface, ret - 1);
907 return ret;
910 static ULONG WINAPI VMR9_Release(IBaseFilter * iface)
912 struct quartz_vmr *This = (struct quartz_vmr*)iface;
913 LONG ret;
915 if (This->outer_unk && This->bUnkOuterValid)
916 ret = IUnknown_Release(This->outer_unk);
917 else
918 ret = IUnknown_Release(&This->IUnknown_inner);
920 TRACE("(%p)->Release from %d\n", iface, ret + 1);
922 if (ret)
923 return ret;
924 return 0;
927 static const IBaseFilterVtbl VMR_Vtbl =
929 VMR9_QueryInterface,
930 VMR9_AddRef,
931 VMR9_Release,
932 BaseFilterImpl_GetClassID,
933 BaseRendererImpl_Stop,
934 BaseRendererImpl_Pause,
935 BaseRendererImpl_Run,
936 BaseRendererImpl_GetState,
937 BaseRendererImpl_SetSyncSource,
938 BaseFilterImpl_GetSyncSource,
939 BaseFilterImpl_EnumPins,
940 BaseRendererImpl_FindPin,
941 BaseFilterImpl_QueryFilterInfo,
942 BaseFilterImpl_JoinFilterGraph,
943 BaseFilterImpl_QueryVendorInfo
946 /*** IUnknown methods ***/
947 static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface, REFIID riid, LPVOID*ppvObj)
949 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
951 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
953 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
956 static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface)
958 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
960 TRACE("(%p/%p)->()\n", This, iface);
962 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
965 static ULONG WINAPI Videowindow_Release(IVideoWindow *iface)
967 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
969 TRACE("(%p/%p)->()\n", This, iface);
971 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
974 static const IVideoWindowVtbl IVideoWindow_VTable =
976 Videowindow_QueryInterface,
977 Videowindow_AddRef,
978 Videowindow_Release,
979 BaseControlWindowImpl_GetTypeInfoCount,
980 BaseControlWindowImpl_GetTypeInfo,
981 BaseControlWindowImpl_GetIDsOfNames,
982 BaseControlWindowImpl_Invoke,
983 BaseControlWindowImpl_put_Caption,
984 BaseControlWindowImpl_get_Caption,
985 BaseControlWindowImpl_put_WindowStyle,
986 BaseControlWindowImpl_get_WindowStyle,
987 BaseControlWindowImpl_put_WindowStyleEx,
988 BaseControlWindowImpl_get_WindowStyleEx,
989 BaseControlWindowImpl_put_AutoShow,
990 BaseControlWindowImpl_get_AutoShow,
991 BaseControlWindowImpl_put_WindowState,
992 BaseControlWindowImpl_get_WindowState,
993 BaseControlWindowImpl_put_BackgroundPalette,
994 BaseControlWindowImpl_get_BackgroundPalette,
995 BaseControlWindowImpl_put_Visible,
996 BaseControlWindowImpl_get_Visible,
997 BaseControlWindowImpl_put_Left,
998 BaseControlWindowImpl_get_Left,
999 BaseControlWindowImpl_put_Width,
1000 BaseControlWindowImpl_get_Width,
1001 BaseControlWindowImpl_put_Top,
1002 BaseControlWindowImpl_get_Top,
1003 BaseControlWindowImpl_put_Height,
1004 BaseControlWindowImpl_get_Height,
1005 BaseControlWindowImpl_put_Owner,
1006 BaseControlWindowImpl_get_Owner,
1007 BaseControlWindowImpl_put_MessageDrain,
1008 BaseControlWindowImpl_get_MessageDrain,
1009 BaseControlWindowImpl_get_BorderColor,
1010 BaseControlWindowImpl_put_BorderColor,
1011 BaseControlWindowImpl_get_FullScreenMode,
1012 BaseControlWindowImpl_put_FullScreenMode,
1013 BaseControlWindowImpl_SetWindowForeground,
1014 BaseControlWindowImpl_NotifyOwnerMessage,
1015 BaseControlWindowImpl_SetWindowPosition,
1016 BaseControlWindowImpl_GetWindowPosition,
1017 BaseControlWindowImpl_GetMinIdealImageSize,
1018 BaseControlWindowImpl_GetMaxIdealImageSize,
1019 BaseControlWindowImpl_GetRestorePosition,
1020 BaseControlWindowImpl_HideCursor,
1021 BaseControlWindowImpl_IsCursorHidden
1024 /*** IUnknown methods ***/
1025 static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface, REFIID riid, LPVOID * ppvObj)
1027 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1029 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1031 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
1034 static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface)
1036 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1038 TRACE("(%p/%p)->()\n", This, iface);
1040 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1043 static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface)
1045 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1047 TRACE("(%p/%p)->()\n", This, iface);
1049 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1052 static const IBasicVideoVtbl IBasicVideo_VTable =
1054 Basicvideo_QueryInterface,
1055 Basicvideo_AddRef,
1056 Basicvideo_Release,
1057 BaseControlVideoImpl_GetTypeInfoCount,
1058 BaseControlVideoImpl_GetTypeInfo,
1059 BaseControlVideoImpl_GetIDsOfNames,
1060 BaseControlVideoImpl_Invoke,
1061 BaseControlVideoImpl_get_AvgTimePerFrame,
1062 BaseControlVideoImpl_get_BitRate,
1063 BaseControlVideoImpl_get_BitErrorRate,
1064 BaseControlVideoImpl_get_VideoWidth,
1065 BaseControlVideoImpl_get_VideoHeight,
1066 BaseControlVideoImpl_put_SourceLeft,
1067 BaseControlVideoImpl_get_SourceLeft,
1068 BaseControlVideoImpl_put_SourceWidth,
1069 BaseControlVideoImpl_get_SourceWidth,
1070 BaseControlVideoImpl_put_SourceTop,
1071 BaseControlVideoImpl_get_SourceTop,
1072 BaseControlVideoImpl_put_SourceHeight,
1073 BaseControlVideoImpl_get_SourceHeight,
1074 BaseControlVideoImpl_put_DestinationLeft,
1075 BaseControlVideoImpl_get_DestinationLeft,
1076 BaseControlVideoImpl_put_DestinationWidth,
1077 BaseControlVideoImpl_get_DestinationWidth,
1078 BaseControlVideoImpl_put_DestinationTop,
1079 BaseControlVideoImpl_get_DestinationTop,
1080 BaseControlVideoImpl_put_DestinationHeight,
1081 BaseControlVideoImpl_get_DestinationHeight,
1082 BaseControlVideoImpl_SetSourcePosition,
1083 BaseControlVideoImpl_GetSourcePosition,
1084 BaseControlVideoImpl_SetDefaultSourcePosition,
1085 BaseControlVideoImpl_SetDestinationPosition,
1086 BaseControlVideoImpl_GetDestinationPosition,
1087 BaseControlVideoImpl_SetDefaultDestinationPosition,
1088 BaseControlVideoImpl_GetVideoSize,
1089 BaseControlVideoImpl_GetVideoPaletteEntries,
1090 BaseControlVideoImpl_GetCurrentImage,
1091 BaseControlVideoImpl_IsUsingDefaultSource,
1092 BaseControlVideoImpl_IsUsingDefaultDestination
1095 static HRESULT WINAPI AMCertifiedOutputProtection_QueryInterface(IAMCertifiedOutputProtection *iface,
1096 REFIID riid, void **ppv)
1098 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1099 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1102 static ULONG WINAPI AMCertifiedOutputProtection_AddRef(IAMCertifiedOutputProtection *iface)
1104 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1105 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1108 static ULONG WINAPI AMCertifiedOutputProtection_Release(IAMCertifiedOutputProtection *iface)
1110 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1111 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1114 static HRESULT WINAPI AMCertifiedOutputProtection_KeyExchange(IAMCertifiedOutputProtection *iface,
1115 GUID* pRandom, BYTE** VarLenCertGH,
1116 DWORD* pdwLengthCertGH)
1118 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1120 FIXME("(%p/%p)->(%p, %p, %p) stub\n", iface, This, pRandom, VarLenCertGH, pdwLengthCertGH);
1121 return VFW_E_NO_COPP_HW;
1124 static HRESULT WINAPI AMCertifiedOutputProtection_SessionSequenceStart(IAMCertifiedOutputProtection *iface,
1125 AMCOPPSignature* pSig)
1127 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1129 FIXME("(%p/%p)->(%p) stub\n", iface, This, pSig);
1130 return VFW_E_NO_COPP_HW;
1133 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionCommand(IAMCertifiedOutputProtection *iface,
1134 const AMCOPPCommand* cmd)
1136 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1138 FIXME("(%p/%p)->(%p) stub\n", iface, This, cmd);
1139 return VFW_E_NO_COPP_HW;
1142 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionStatus(IAMCertifiedOutputProtection *iface,
1143 const AMCOPPStatusInput* pStatusInput,
1144 AMCOPPStatusOutput* pStatusOutput)
1146 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1148 FIXME("(%p/%p)->(%p, %p) stub\n", iface, This, pStatusInput, pStatusOutput);
1149 return VFW_E_NO_COPP_HW;
1152 static const IAMCertifiedOutputProtectionVtbl IAMCertifiedOutputProtection_Vtbl =
1154 AMCertifiedOutputProtection_QueryInterface,
1155 AMCertifiedOutputProtection_AddRef,
1156 AMCertifiedOutputProtection_Release,
1157 AMCertifiedOutputProtection_KeyExchange,
1158 AMCertifiedOutputProtection_SessionSequenceStart,
1159 AMCertifiedOutputProtection_ProtectionCommand,
1160 AMCertifiedOutputProtection_ProtectionStatus
1163 static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) {
1164 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1165 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1168 static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) {
1169 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1170 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1173 static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) {
1174 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1175 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1178 static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) {
1179 return AM_FILTER_MISC_FLAGS_IS_RENDERER;
1182 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = {
1183 AMFilterMiscFlags_QueryInterface,
1184 AMFilterMiscFlags_AddRef,
1185 AMFilterMiscFlags_Release,
1186 AMFilterMiscFlags_GetMiscFlags
1189 static HRESULT WINAPI VMR7FilterConfig_QueryInterface(IVMRFilterConfig *iface, REFIID riid,
1190 void** ppv)
1192 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1193 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1196 static ULONG WINAPI VMR7FilterConfig_AddRef(IVMRFilterConfig *iface)
1198 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1199 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1202 static ULONG WINAPI VMR7FilterConfig_Release(IVMRFilterConfig *iface)
1204 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1205 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1208 static HRESULT WINAPI VMR7FilterConfig_SetImageCompositor(IVMRFilterConfig *iface,
1209 IVMRImageCompositor *compositor)
1211 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1213 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
1214 return E_NOTIMPL;
1217 static HRESULT WINAPI VMR7FilterConfig_SetNumberOfStreams(IVMRFilterConfig *iface, DWORD max)
1219 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1221 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
1222 return E_NOTIMPL;
1225 static HRESULT WINAPI VMR7FilterConfig_GetNumberOfStreams(IVMRFilterConfig *iface, DWORD *max)
1227 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1229 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
1230 return E_NOTIMPL;
1233 static HRESULT WINAPI VMR7FilterConfig_SetRenderingPrefs(IVMRFilterConfig *iface, DWORD renderflags)
1235 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1237 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
1238 return E_NOTIMPL;
1241 static HRESULT WINAPI VMR7FilterConfig_GetRenderingPrefs(IVMRFilterConfig *iface, DWORD *renderflags)
1243 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1245 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
1246 return E_NOTIMPL;
1249 static HRESULT WINAPI VMR7FilterConfig_SetRenderingMode(IVMRFilterConfig *iface, DWORD mode)
1251 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1253 FIXME("(%p/%p)->(%u) stub\n", iface, This, mode);
1254 return E_NOTIMPL;
1257 static HRESULT WINAPI VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig *iface, DWORD *mode)
1259 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1261 TRACE("(%p/%p)->(%p) stub\n", iface, This, mode);
1262 if (!mode) return E_POINTER;
1264 if (This->mode)
1265 *mode = This->mode;
1266 else
1267 *mode = VMRMode_Windowed;
1269 return S_OK;
1272 static const IVMRFilterConfigVtbl VMR7_FilterConfig_Vtbl =
1274 VMR7FilterConfig_QueryInterface,
1275 VMR7FilterConfig_AddRef,
1276 VMR7FilterConfig_Release,
1277 VMR7FilterConfig_SetImageCompositor,
1278 VMR7FilterConfig_SetNumberOfStreams,
1279 VMR7FilterConfig_GetNumberOfStreams,
1280 VMR7FilterConfig_SetRenderingPrefs,
1281 VMR7FilterConfig_GetRenderingPrefs,
1282 VMR7FilterConfig_SetRenderingMode,
1283 VMR7FilterConfig_GetRenderingMode
1286 struct get_available_monitors_args
1288 VMRMONITORINFO *info7;
1289 VMR9MonitorInfo *info9;
1290 DWORD arraysize;
1291 DWORD numdev;
1294 static BOOL CALLBACK get_available_monitors_proc(HMONITOR hmon, HDC hdc, LPRECT lprc, LPARAM lparam)
1296 struct get_available_monitors_args *args = (struct get_available_monitors_args *)lparam;
1297 MONITORINFOEXW mi;
1299 if (args->info7 || args->info9)
1302 if (!args->arraysize)
1303 return FALSE;
1305 mi.cbSize = sizeof(mi);
1306 if (!GetMonitorInfoW(hmon, (MONITORINFO*)&mi))
1307 return TRUE;
1309 /* fill VMRMONITORINFO struct */
1310 if (args->info7)
1312 VMRMONITORINFO *info = args->info7++;
1313 memset(info, 0, sizeof(*info));
1315 if (args->numdev > 0)
1317 info->guid.pGUID = &info->guid.GUID;
1318 info->guid.GUID.Data4[7] = args->numdev;
1320 else
1321 info->guid.pGUID = NULL;
1323 CopyRect(&info->rcMonitor, &mi.rcMonitor);
1324 info->hMon = hmon;
1325 info->dwFlags = mi.dwFlags;
1327 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR));
1329 /* FIXME: how to get these values? */
1330 info->szDescription[0] = 0;
1333 /* fill VMR9MonitorInfo struct */
1334 if (args->info9)
1336 VMR9MonitorInfo *info = args->info9++;
1337 memset(info, 0, sizeof(*info));
1339 info->uDevID = 0; /* FIXME */
1340 CopyRect(&info->rcMonitor, &mi.rcMonitor);
1341 info->hMon = hmon;
1342 info->dwFlags = mi.dwFlags;
1344 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR));
1346 /* FIXME: how to get these values? */
1347 info->szDescription[0] = 0;
1348 info->dwVendorId = 0;
1349 info->dwDeviceId = 0;
1350 info->dwSubSysId = 0;
1351 info->dwRevision = 0;
1354 args->arraysize--;
1357 args->numdev++;
1358 return TRUE;
1361 static HRESULT WINAPI VMR7MonitorConfig_QueryInterface(IVMRMonitorConfig *iface, REFIID riid,
1362 LPVOID * ppv)
1364 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1365 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1368 static ULONG WINAPI VMR7MonitorConfig_AddRef(IVMRMonitorConfig *iface)
1370 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1371 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1374 static ULONG WINAPI VMR7MonitorConfig_Release(IVMRMonitorConfig *iface)
1376 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1377 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1380 static HRESULT WINAPI VMR7MonitorConfig_SetMonitor(IVMRMonitorConfig *iface, const VMRGUID *pGUID)
1382 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1384 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1386 if (!pGUID)
1387 return E_POINTER;
1389 return S_OK;
1392 static HRESULT WINAPI VMR7MonitorConfig_GetMonitor(IVMRMonitorConfig *iface, VMRGUID *pGUID)
1394 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1396 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1398 if (!pGUID)
1399 return E_POINTER;
1401 pGUID->pGUID = NULL; /* default DirectDraw device */
1402 return S_OK;
1405 static HRESULT WINAPI VMR7MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig *iface,
1406 const VMRGUID *pGUID)
1408 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1410 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1412 if (!pGUID)
1413 return E_POINTER;
1415 return S_OK;
1418 static HRESULT WINAPI VMR7MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig *iface, VMRGUID *pGUID)
1420 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1422 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1424 if (!pGUID)
1425 return E_POINTER;
1427 pGUID->pGUID = NULL; /* default DirectDraw device */
1428 return S_OK;
1431 static HRESULT WINAPI VMR7MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig *iface,
1432 VMRMONITORINFO *info, DWORD arraysize,
1433 DWORD *numdev)
1435 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1436 struct get_available_monitors_args args;
1438 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1440 if (!numdev)
1441 return E_POINTER;
1443 if (info && arraysize == 0)
1444 return E_INVALIDARG;
1446 args.info7 = info;
1447 args.info9 = NULL;
1448 args.arraysize = arraysize;
1449 args.numdev = 0;
1450 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1452 *numdev = args.numdev;
1453 return S_OK;
1456 static const IVMRMonitorConfigVtbl VMR7_MonitorConfig_Vtbl =
1458 VMR7MonitorConfig_QueryInterface,
1459 VMR7MonitorConfig_AddRef,
1460 VMR7MonitorConfig_Release,
1461 VMR7MonitorConfig_SetMonitor,
1462 VMR7MonitorConfig_GetMonitor,
1463 VMR7MonitorConfig_SetDefaultMonitor,
1464 VMR7MonitorConfig_GetDefaultMonitor,
1465 VMR7MonitorConfig_GetAvailableMonitors
1468 static HRESULT WINAPI VMR9MonitorConfig_QueryInterface(IVMRMonitorConfig9 *iface, REFIID riid,
1469 LPVOID * ppv)
1471 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1472 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1475 static ULONG WINAPI VMR9MonitorConfig_AddRef(IVMRMonitorConfig9 *iface)
1477 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1478 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1481 static ULONG WINAPI VMR9MonitorConfig_Release(IVMRMonitorConfig9 *iface)
1483 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1484 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1487 static HRESULT WINAPI VMR9MonitorConfig_SetMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1489 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1491 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1493 return S_OK;
1496 static HRESULT WINAPI VMR9MonitorConfig_GetMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1498 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1500 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1502 if (!uDev)
1503 return E_POINTER;
1505 *uDev = 0;
1506 return S_OK;
1509 static HRESULT WINAPI VMR9MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1511 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1513 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1515 return S_OK;
1518 static HRESULT WINAPI VMR9MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1520 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1522 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1524 if (!uDev)
1525 return E_POINTER;
1527 *uDev = 0;
1528 return S_OK;
1531 static HRESULT WINAPI VMR9MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig9 *iface,
1532 VMR9MonitorInfo *info, DWORD arraysize,
1533 DWORD *numdev)
1535 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1536 struct get_available_monitors_args args;
1538 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1540 if (!numdev)
1541 return E_POINTER;
1543 if (info && arraysize == 0)
1544 return E_INVALIDARG;
1546 args.info7 = NULL;
1547 args.info9 = info;
1548 args.arraysize = arraysize;
1549 args.numdev = 0;
1550 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1552 *numdev = args.numdev;
1553 return S_OK;
1556 static const IVMRMonitorConfig9Vtbl VMR9_MonitorConfig_Vtbl =
1558 VMR9MonitorConfig_QueryInterface,
1559 VMR9MonitorConfig_AddRef,
1560 VMR9MonitorConfig_Release,
1561 VMR9MonitorConfig_SetMonitor,
1562 VMR9MonitorConfig_GetMonitor,
1563 VMR9MonitorConfig_SetDefaultMonitor,
1564 VMR9MonitorConfig_GetDefaultMonitor,
1565 VMR9MonitorConfig_GetAvailableMonitors
1568 static HRESULT WINAPI VMR9FilterConfig_QueryInterface(IVMRFilterConfig9 *iface, REFIID riid, LPVOID * ppv)
1570 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1571 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1574 static ULONG WINAPI VMR9FilterConfig_AddRef(IVMRFilterConfig9 *iface)
1576 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1577 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1580 static ULONG WINAPI VMR9FilterConfig_Release(IVMRFilterConfig9 *iface)
1582 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1583 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1586 static HRESULT WINAPI VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9 *iface, IVMRImageCompositor9 *compositor)
1588 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1590 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
1591 return E_NOTIMPL;
1594 static HRESULT WINAPI VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD max)
1596 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1598 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
1599 return E_NOTIMPL;
1602 static HRESULT WINAPI VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD *max)
1604 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1606 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
1607 return E_NOTIMPL;
1610 static HRESULT WINAPI VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD renderflags)
1612 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1614 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
1615 return E_NOTIMPL;
1618 static HRESULT WINAPI VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD *renderflags)
1620 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1622 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
1623 return E_NOTIMPL;
1626 static HRESULT WINAPI VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 *iface, DWORD mode)
1628 HRESULT hr = S_OK;
1629 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1631 TRACE("(%p/%p)->(%u)\n", iface, This, mode);
1633 EnterCriticalSection(&This->renderer.filter.csFilter);
1634 if (This->mode)
1636 LeaveCriticalSection(&This->renderer.filter.csFilter);
1637 return VFW_E_WRONG_STATE;
1640 if (This->allocator)
1641 IVMRSurfaceAllocatorEx9_Release(This->allocator);
1642 if (This->presenter)
1643 IVMRImagePresenter9_Release(This->presenter);
1645 This->allocator = NULL;
1646 This->presenter = NULL;
1648 switch (mode)
1650 case VMR9Mode_Windowed:
1651 case VMR9Mode_Windowless:
1652 This->allocator_is_ex = 0;
1653 This->cookie = ~0;
1655 hr = VMR9DefaultAllocatorPresenterImpl_create(This, (LPVOID*)&This->presenter);
1656 if (SUCCEEDED(hr))
1657 hr = IVMRImagePresenter9_QueryInterface(This->presenter, &IID_IVMRSurfaceAllocatorEx9, (LPVOID*)&This->allocator);
1658 if (FAILED(hr))
1660 ERR("Unable to find Presenter interface\n");
1661 IVMRImagePresenter9_Release(This->presenter);
1662 This->allocator = NULL;
1663 This->presenter = NULL;
1665 else
1666 hr = IVMRSurfaceAllocatorEx9_AdviseNotify(This->allocator, &This->IVMRSurfaceAllocatorNotify9_iface);
1667 break;
1668 case VMR9Mode_Renderless:
1669 break;
1670 default:
1671 LeaveCriticalSection(&This->renderer.filter.csFilter);
1672 return E_INVALIDARG;
1675 This->mode = mode;
1676 LeaveCriticalSection(&This->renderer.filter.csFilter);
1677 return hr;
1680 static HRESULT WINAPI VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9 *iface, DWORD *mode)
1682 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1684 TRACE("(%p/%p)->(%p) stub\n", iface, This, mode);
1685 if (!mode)
1686 return E_POINTER;
1688 if (This->mode)
1689 *mode = This->mode;
1690 else
1691 *mode = VMR9Mode_Windowed;
1693 return S_OK;
1696 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl =
1698 VMR9FilterConfig_QueryInterface,
1699 VMR9FilterConfig_AddRef,
1700 VMR9FilterConfig_Release,
1701 VMR9FilterConfig_SetImageCompositor,
1702 VMR9FilterConfig_SetNumberOfStreams,
1703 VMR9FilterConfig_GetNumberOfStreams,
1704 VMR9FilterConfig_SetRenderingPrefs,
1705 VMR9FilterConfig_GetRenderingPrefs,
1706 VMR9FilterConfig_SetRenderingMode,
1707 VMR9FilterConfig_GetRenderingMode
1710 static HRESULT WINAPI VMR7WindowlessControl_QueryInterface(IVMRWindowlessControl *iface, REFIID riid,
1711 LPVOID * ppv)
1713 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1714 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1717 static ULONG WINAPI VMR7WindowlessControl_AddRef(IVMRWindowlessControl *iface)
1719 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1720 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1723 static ULONG WINAPI VMR7WindowlessControl_Release(IVMRWindowlessControl *iface)
1725 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1726 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1729 static HRESULT WINAPI VMR7WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl *iface,
1730 LONG *width, LONG *height,
1731 LONG *arwidth, LONG *arheight)
1733 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1734 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1736 if (!width || !height || !arwidth || !arheight)
1738 ERR("Got no pointer\n");
1739 return E_POINTER;
1742 *width = This->bmiheader.biWidth;
1743 *height = This->bmiheader.biHeight;
1744 *arwidth = This->bmiheader.biWidth;
1745 *arheight = This->bmiheader.biHeight;
1747 return S_OK;
1750 static HRESULT WINAPI VMR7WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl *iface,
1751 LONG *width, LONG *height)
1753 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1755 FIXME("(%p/%p)->(...) stub\n", iface, This);
1756 return E_NOTIMPL;
1759 static HRESULT WINAPI VMR7WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl *iface,
1760 LONG *width, LONG *height)
1762 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1764 FIXME("(%p/%p)->(...) stub\n", iface, This);
1765 return E_NOTIMPL;
1768 static HRESULT WINAPI VMR7WindowlessControl_SetVideoPosition(IVMRWindowlessControl *iface,
1769 const RECT *source, const RECT *dest)
1771 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1773 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1775 EnterCriticalSection(&This->renderer.filter.csFilter);
1777 if (source)
1778 This->source_rect = *source;
1779 if (dest)
1781 This->target_rect = *dest;
1782 if (This->baseControlWindow.baseWindow.hWnd)
1784 FIXME("Output rectangle: starting at %dx%d, up to point %dx%d\n",
1785 dest->left, dest->top, dest->right, dest->bottom);
1786 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
1787 dest->left, dest->top, dest->right - dest->left, dest->bottom-dest->top,
1788 SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW);
1792 LeaveCriticalSection(&This->renderer.filter.csFilter);
1794 return S_OK;
1797 static HRESULT WINAPI VMR7WindowlessControl_GetVideoPosition(IVMRWindowlessControl *iface,
1798 RECT *source, RECT *dest)
1800 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1802 if (source)
1803 *source = This->source_rect;
1805 if (dest)
1806 *dest = This->target_rect;
1808 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
1809 return S_OK;
1812 static HRESULT WINAPI VMR7WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl *iface,
1813 DWORD *mode)
1815 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1817 FIXME("(%p/%p)->(...) stub\n", iface, This);
1818 return E_NOTIMPL;
1821 static HRESULT WINAPI VMR7WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl *iface,
1822 DWORD mode)
1824 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1826 FIXME("(%p/%p)->(...) stub\n", iface, This);
1827 return E_NOTIMPL;
1830 static HRESULT WINAPI VMR7WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl *iface,
1831 HWND hwnd)
1833 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1835 FIXME("(%p/%p)->(...) stub\n", iface, This);
1836 return E_NOTIMPL;
1839 static HRESULT WINAPI VMR7WindowlessControl_RepaintVideo(IVMRWindowlessControl *iface,
1840 HWND hwnd, HDC hdc)
1842 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1844 FIXME("(%p/%p)->(...) stub\n", iface, This);
1845 return E_NOTIMPL;
1848 static HRESULT WINAPI VMR7WindowlessControl_DisplayModeChanged(IVMRWindowlessControl *iface)
1850 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1852 FIXME("(%p/%p)->(...) stub\n", iface, This);
1853 return E_NOTIMPL;
1856 static HRESULT WINAPI VMR7WindowlessControl_GetCurrentImage(IVMRWindowlessControl *iface,
1857 BYTE **dib)
1859 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1861 FIXME("(%p/%p)->(...) stub\n", iface, This);
1862 return E_NOTIMPL;
1865 static HRESULT WINAPI VMR7WindowlessControl_SetBorderColor(IVMRWindowlessControl *iface,
1866 COLORREF color)
1868 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1870 FIXME("(%p/%p)->(...) stub\n", iface, This);
1871 return E_NOTIMPL;
1874 static HRESULT WINAPI VMR7WindowlessControl_GetBorderColor(IVMRWindowlessControl *iface,
1875 COLORREF *color)
1877 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1879 FIXME("(%p/%p)->(...) stub\n", iface, This);
1880 return E_NOTIMPL;
1883 static HRESULT WINAPI VMR7WindowlessControl_SetColorKey(IVMRWindowlessControl *iface, COLORREF color)
1885 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1887 FIXME("(%p/%p)->(...) stub\n", iface, This);
1888 return E_NOTIMPL;
1891 static HRESULT WINAPI VMR7WindowlessControl_GetColorKey(IVMRWindowlessControl *iface, COLORREF *color)
1893 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1895 FIXME("(%p/%p)->(...) stub\n", iface, This);
1896 return E_NOTIMPL;
1899 static const IVMRWindowlessControlVtbl VMR7_WindowlessControl_Vtbl =
1901 VMR7WindowlessControl_QueryInterface,
1902 VMR7WindowlessControl_AddRef,
1903 VMR7WindowlessControl_Release,
1904 VMR7WindowlessControl_GetNativeVideoSize,
1905 VMR7WindowlessControl_GetMinIdealVideoSize,
1906 VMR7WindowlessControl_GetMaxIdealVideoSize,
1907 VMR7WindowlessControl_SetVideoPosition,
1908 VMR7WindowlessControl_GetVideoPosition,
1909 VMR7WindowlessControl_GetAspectRatioMode,
1910 VMR7WindowlessControl_SetAspectRatioMode,
1911 VMR7WindowlessControl_SetVideoClippingWindow,
1912 VMR7WindowlessControl_RepaintVideo,
1913 VMR7WindowlessControl_DisplayModeChanged,
1914 VMR7WindowlessControl_GetCurrentImage,
1915 VMR7WindowlessControl_SetBorderColor,
1916 VMR7WindowlessControl_GetBorderColor,
1917 VMR7WindowlessControl_SetColorKey,
1918 VMR7WindowlessControl_GetColorKey
1921 static HRESULT WINAPI VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9 *iface, REFIID riid, LPVOID * ppv)
1923 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1924 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1927 static ULONG WINAPI VMR9WindowlessControl_AddRef(IVMRWindowlessControl9 *iface)
1929 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1930 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1933 static ULONG WINAPI VMR9WindowlessControl_Release(IVMRWindowlessControl9 *iface)
1935 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1936 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1939 static HRESULT WINAPI VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height, LONG *arwidth, LONG *arheight)
1941 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1942 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1944 if (!width || !height || !arwidth || !arheight)
1946 ERR("Got no pointer\n");
1947 return E_POINTER;
1950 *width = This->bmiheader.biWidth;
1951 *height = This->bmiheader.biHeight;
1952 *arwidth = This->bmiheader.biWidth;
1953 *arheight = This->bmiheader.biHeight;
1955 return S_OK;
1958 static HRESULT WINAPI VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1960 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1962 FIXME("(%p/%p)->(...) stub\n", iface, This);
1963 return E_NOTIMPL;
1966 static HRESULT WINAPI VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1968 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1970 FIXME("(%p/%p)->(...) stub\n", iface, This);
1971 return E_NOTIMPL;
1974 static HRESULT WINAPI VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9 *iface, const RECT *source, const RECT *dest)
1976 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1978 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1980 EnterCriticalSection(&This->renderer.filter.csFilter);
1982 if (source)
1983 This->source_rect = *source;
1984 if (dest)
1986 This->target_rect = *dest;
1987 if (This->baseControlWindow.baseWindow.hWnd)
1989 FIXME("Output rectangle: starting at %dx%d, up to point %dx%d\n", dest->left, dest->top, dest->right, dest->bottom);
1990 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, dest->left, dest->top, dest->right - dest->left,
1991 dest->bottom-dest->top, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW);
1995 LeaveCriticalSection(&This->renderer.filter.csFilter);
1997 return S_OK;
2000 static HRESULT WINAPI VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9 *iface, RECT *source, RECT *dest)
2002 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2004 if (source)
2005 *source = This->source_rect;
2007 if (dest)
2008 *dest = This->target_rect;
2010 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
2011 return S_OK;
2014 static HRESULT WINAPI VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD *mode)
2016 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2018 FIXME("(%p/%p)->(...) stub\n", iface, This);
2019 return E_NOTIMPL;
2022 static HRESULT WINAPI VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD mode)
2024 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2026 FIXME("(%p/%p)->(...) stub\n", iface, This);
2027 return E_NOTIMPL;
2030 static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9 *iface, HWND hwnd)
2032 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2034 TRACE("(%p/%p)->(%p)\n", iface, This, hwnd);
2036 EnterCriticalSection(&This->renderer.filter.csFilter);
2037 This->hWndClippingWindow = hwnd;
2038 VMR9_maybe_init(This, FALSE);
2039 if (!hwnd)
2040 IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie);
2041 LeaveCriticalSection(&This->renderer.filter.csFilter);
2042 return S_OK;
2045 static HRESULT WINAPI VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9 *iface, HWND hwnd, HDC hdc)
2047 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2048 HRESULT hr;
2050 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2052 EnterCriticalSection(&This->renderer.filter.csFilter);
2053 if (hwnd != This->hWndClippingWindow && hwnd != This->baseControlWindow.baseWindow.hWnd)
2055 ERR("Not handling changing windows yet!!!\n");
2056 LeaveCriticalSection(&This->renderer.filter.csFilter);
2057 return S_OK;
2060 if (!This->allocator_d3d9_dev)
2062 ERR("No d3d9 device!\n");
2063 LeaveCriticalSection(&This->renderer.filter.csFilter);
2064 return VFW_E_WRONG_STATE;
2067 /* Windowless extension */
2068 hr = IDirect3DDevice9_Present(This->allocator_d3d9_dev, NULL, NULL, This->baseControlWindow.baseWindow.hWnd, NULL);
2069 LeaveCriticalSection(&This->renderer.filter.csFilter);
2071 return hr;
2074 static HRESULT WINAPI VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9 *iface)
2076 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2078 FIXME("(%p/%p)->(...) stub\n", iface, This);
2079 return E_NOTIMPL;
2082 static HRESULT WINAPI VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9 *iface, BYTE **dib)
2084 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2086 FIXME("(%p/%p)->(...) stub\n", iface, This);
2087 return E_NOTIMPL;
2090 static HRESULT WINAPI VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9 *iface, COLORREF color)
2092 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2094 FIXME("(%p/%p)->(...) stub\n", iface, This);
2095 return E_NOTIMPL;
2098 static HRESULT WINAPI VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9 *iface, COLORREF *color)
2100 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2102 FIXME("(%p/%p)->(...) stub\n", iface, This);
2103 return E_NOTIMPL;
2106 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl =
2108 VMR9WindowlessControl_QueryInterface,
2109 VMR9WindowlessControl_AddRef,
2110 VMR9WindowlessControl_Release,
2111 VMR9WindowlessControl_GetNativeVideoSize,
2112 VMR9WindowlessControl_GetMinIdealVideoSize,
2113 VMR9WindowlessControl_GetMaxIdealVideoSize,
2114 VMR9WindowlessControl_SetVideoPosition,
2115 VMR9WindowlessControl_GetVideoPosition,
2116 VMR9WindowlessControl_GetAspectRatioMode,
2117 VMR9WindowlessControl_SetAspectRatioMode,
2118 VMR9WindowlessControl_SetVideoClippingWindow,
2119 VMR9WindowlessControl_RepaintVideo,
2120 VMR9WindowlessControl_DisplayModeChanged,
2121 VMR9WindowlessControl_GetCurrentImage,
2122 VMR9WindowlessControl_SetBorderColor,
2123 VMR9WindowlessControl_GetBorderColor
2126 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify *iface,
2127 REFIID riid, LPVOID * ppv)
2129 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2130 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
2133 static ULONG WINAPI VMR7SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify *iface)
2135 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2136 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
2139 static ULONG WINAPI VMR7SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify *iface)
2141 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2142 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
2145 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify *iface,
2146 DWORD_PTR id,
2147 IVMRSurfaceAllocator *alloc)
2149 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2151 FIXME("(%p/%p)->(...) stub\n", iface, This);
2152 return E_NOTIMPL;
2155 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
2156 IDirectDraw7 *device, HMONITOR monitor)
2158 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2160 FIXME("(%p/%p)->(...) stub\n", iface, This);
2161 return E_NOTIMPL;
2164 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_ChangeDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
2165 IDirectDraw7 *device, HMONITOR monitor)
2167 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2169 FIXME("(%p/%p)->(...) stub\n", iface, This);
2170 return E_NOTIMPL;
2173 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces(IVMRSurfaceAllocatorNotify *iface)
2175 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2177 FIXME("(%p/%p)->(...) stub\n", iface, This);
2178 return E_NOTIMPL;
2181 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify *iface, LONG code,
2182 LONG_PTR param1, LONG_PTR param2)
2184 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2186 FIXME("(%p/%p)->(...) stub\n", iface, This);
2187 return E_NOTIMPL;
2190 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetBorderColor(IVMRSurfaceAllocatorNotify *iface,
2191 COLORREF clrBorder)
2193 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2195 FIXME("(%p/%p)->(...) stub\n", iface, This);
2196 return E_NOTIMPL;
2199 static const IVMRSurfaceAllocatorNotifyVtbl VMR7_SurfaceAllocatorNotify_Vtbl =
2201 VMR7SurfaceAllocatorNotify_QueryInterface,
2202 VMR7SurfaceAllocatorNotify_AddRef,
2203 VMR7SurfaceAllocatorNotify_Release,
2204 VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator,
2205 VMR7SurfaceAllocatorNotify_SetDDrawDevice,
2206 VMR7SurfaceAllocatorNotify_ChangeDDrawDevice,
2207 VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces,
2208 VMR7SurfaceAllocatorNotify_NotifyEvent,
2209 VMR7SurfaceAllocatorNotify_SetBorderColor
2212 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9 *iface, REFIID riid, LPVOID * ppv)
2214 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2215 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
2218 static ULONG WINAPI VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9 *iface)
2220 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2221 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
2224 static ULONG WINAPI VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9 *iface)
2226 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2227 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
2230 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9 *iface, DWORD_PTR id, IVMRSurfaceAllocator9 *alloc)
2232 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2234 /* FIXME: This code is not tested!!! */
2235 FIXME("(%p/%p)->(...) stub\n", iface, This);
2236 This->cookie = id;
2238 if (This->presenter)
2239 return VFW_E_WRONG_STATE;
2241 if (FAILED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRImagePresenter9, (void **)&This->presenter)))
2242 return E_NOINTERFACE;
2244 if (SUCCEEDED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRSurfaceAllocatorEx9, (void **)&This->allocator)))
2245 This->allocator_is_ex = 1;
2246 else
2248 This->allocator = (IVMRSurfaceAllocatorEx9 *)alloc;
2249 IVMRSurfaceAllocator9_AddRef(alloc);
2250 This->allocator_is_ex = 0;
2253 return S_OK;
2256 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
2258 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2260 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2261 if (This->allocator_d3d9_dev)
2262 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
2263 This->allocator_d3d9_dev = device;
2264 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
2265 This->allocator_mon = monitor;
2267 return S_OK;
2270 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
2272 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2274 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2275 if (This->allocator_d3d9_dev)
2276 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
2277 This->allocator_d3d9_dev = device;
2278 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
2279 This->allocator_mon = monitor;
2281 return S_OK;
2284 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9 *iface, VMR9AllocationInfo *allocinfo, DWORD *numbuffers, IDirect3DSurface9 **surface)
2286 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2287 DWORD i;
2288 HRESULT hr = S_OK;
2290 FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface, This, allocinfo, numbuffers, (numbuffers ? *numbuffers : 0), surface);
2292 if (!allocinfo || !numbuffers || !surface)
2293 return E_POINTER;
2295 if (!*numbuffers || *numbuffers < allocinfo->MinBuffers)
2297 ERR("Invalid number of buffers?\n");
2298 return E_INVALIDARG;
2301 if (!This->allocator_d3d9_dev)
2303 ERR("No direct3d device when requested to allocate a surface!\n");
2304 return VFW_E_WRONG_STATE;
2307 if (allocinfo->dwFlags & VMR9AllocFlag_OffscreenSurface)
2309 ERR("Creating offscreen surface\n");
2310 for (i = 0; i < *numbuffers; ++i)
2312 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight,
2313 allocinfo->Format, allocinfo->Pool, &surface[i], NULL);
2314 if (FAILED(hr))
2315 break;
2318 else if (allocinfo->dwFlags & VMR9AllocFlag_TextureSurface)
2320 TRACE("Creating texture surface\n");
2321 for (i = 0; i < *numbuffers; ++i)
2323 IDirect3DTexture9 *texture;
2325 hr = IDirect3DDevice9_CreateTexture(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight, 1, 0,
2326 allocinfo->Format, allocinfo->Pool, &texture, NULL);
2327 if (FAILED(hr))
2328 break;
2329 IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface[i]);
2330 IDirect3DTexture9_Release(texture);
2333 else
2335 FIXME("Could not allocate for type %08x\n", allocinfo->dwFlags);
2336 return E_NOTIMPL;
2339 if (i >= allocinfo->MinBuffers)
2341 hr = S_OK;
2342 *numbuffers = i;
2344 else
2346 for ( ; i > 0; --i) IDirect3DSurface9_Release(surface[i - 1]);
2347 *numbuffers = 0;
2349 return hr;
2352 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9 *iface, LONG code, LONG_PTR param1, LONG_PTR param2)
2354 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2356 FIXME("(%p/%p)->(...) stub\n", iface, This);
2357 return E_NOTIMPL;
2360 static const IVMRSurfaceAllocatorNotify9Vtbl VMR9_SurfaceAllocatorNotify_Vtbl =
2362 VMR9SurfaceAllocatorNotify_QueryInterface,
2363 VMR9SurfaceAllocatorNotify_AddRef,
2364 VMR9SurfaceAllocatorNotify_Release,
2365 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator,
2366 VMR9SurfaceAllocatorNotify_SetD3DDevice,
2367 VMR9SurfaceAllocatorNotify_ChangeD3DDevice,
2368 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper,
2369 VMR9SurfaceAllocatorNotify_NotifyEvent
2372 static HRESULT vmr_create(IUnknown *outer_unk, LPVOID *ppv, const CLSID *clsid)
2374 HRESULT hr;
2375 struct quartz_vmr* pVMR;
2377 TRACE("(%p, %p)\n", outer_unk, ppv);
2379 *ppv = NULL;
2381 pVMR = CoTaskMemAlloc(sizeof(struct quartz_vmr));
2383 pVMR->hD3d9 = LoadLibraryA("d3d9.dll");
2384 if (!pVMR->hD3d9 )
2386 WARN("Could not load d3d9.dll\n");
2387 CoTaskMemFree(pVMR);
2388 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
2391 pVMR->outer_unk = outer_unk;
2392 pVMR->bUnkOuterValid = FALSE;
2393 pVMR->bAggregatable = FALSE;
2394 pVMR->IUnknown_inner.lpVtbl = &IInner_VTable;
2395 pVMR->IAMCertifiedOutputProtection_iface.lpVtbl = &IAMCertifiedOutputProtection_Vtbl;
2396 pVMR->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl;
2398 pVMR->mode = 0;
2399 pVMR->allocator_d3d9_dev = NULL;
2400 pVMR->allocator_mon= NULL;
2401 pVMR->num_surfaces = pVMR->cur_surface = 0;
2402 pVMR->allocator = NULL;
2403 pVMR->presenter = NULL;
2404 pVMR->hWndClippingWindow = NULL;
2405 pVMR->IVMRFilterConfig_iface.lpVtbl = &VMR7_FilterConfig_Vtbl;
2406 pVMR->IVMRFilterConfig9_iface.lpVtbl = &VMR9_FilterConfig_Vtbl;
2407 pVMR->IVMRMonitorConfig_iface.lpVtbl = &VMR7_MonitorConfig_Vtbl;
2408 pVMR->IVMRMonitorConfig9_iface.lpVtbl = &VMR9_MonitorConfig_Vtbl;
2409 pVMR->IVMRSurfaceAllocatorNotify_iface.lpVtbl = &VMR7_SurfaceAllocatorNotify_Vtbl;
2410 pVMR->IVMRSurfaceAllocatorNotify9_iface.lpVtbl = &VMR9_SurfaceAllocatorNotify_Vtbl;
2411 pVMR->IVMRWindowlessControl_iface.lpVtbl = &VMR7_WindowlessControl_Vtbl;
2412 pVMR->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl;
2414 if (IsEqualGUID(clsid, &CLSID_VideoMixingRenderer))
2415 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer,
2416 (DWORD_PTR)(__FILE__ ": VMR7Impl.csFilter"), &BaseFuncTable);
2417 else
2418 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer9,
2419 (DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable);
2421 if (FAILED(hr))
2422 goto fail;
2424 hr = BaseControlWindow_Init(&pVMR->baseControlWindow, &IVideoWindow_VTable, &pVMR->renderer.filter,
2425 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin,
2426 &renderer_BaseWindowFuncTable);
2427 if (FAILED(hr))
2428 goto fail;
2430 hr = BaseControlVideo_Init(&pVMR->baseControlVideo, &IBasicVideo_VTable, &pVMR->renderer.filter,
2431 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin,
2432 &renderer_BaseControlVideoFuncTable);
2433 if (FAILED(hr))
2434 goto fail;
2436 *ppv = (LPVOID)pVMR;
2437 ZeroMemory(&pVMR->source_rect, sizeof(RECT));
2438 ZeroMemory(&pVMR->target_rect, sizeof(RECT));
2439 TRACE("Created at %p\n", pVMR);
2440 return hr;
2442 fail:
2443 BaseRendererImpl_Release(&pVMR->renderer.filter.IBaseFilter_iface);
2444 FreeLibrary(pVMR->hD3d9);
2445 CoTaskMemFree(pVMR);
2446 return hr;
2449 HRESULT VMR7Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2451 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer);
2454 HRESULT VMR9Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2456 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer9);
2460 static HRESULT WINAPI VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID riid, LPVOID * ppv)
2462 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2463 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
2465 *ppv = NULL;
2467 if (IsEqualIID(riid, &IID_IUnknown))
2468 *ppv = (LPVOID)&(This->IVMRImagePresenter9_iface);
2469 else if (IsEqualIID(riid, &IID_IVMRImagePresenter9))
2470 *ppv = &This->IVMRImagePresenter9_iface;
2471 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorEx9))
2472 *ppv = &This->IVMRSurfaceAllocatorEx9_iface;
2474 if (*ppv)
2476 IUnknown_AddRef((IUnknown *)(*ppv));
2477 return S_OK;
2480 FIXME("No interface for %s\n", debugstr_guid(riid));
2482 return E_NOINTERFACE;
2485 static ULONG WINAPI VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 *iface)
2487 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2488 ULONG refCount = InterlockedIncrement(&This->refCount);
2490 TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
2492 return refCount;
2495 static ULONG WINAPI VMR9_ImagePresenter_Release(IVMRImagePresenter9 *iface)
2497 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2498 ULONG refCount = InterlockedDecrement(&This->refCount);
2500 TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
2502 if (!refCount)
2504 DWORD i;
2505 TRACE("Destroying\n");
2506 CloseHandle(This->ack);
2507 IDirect3D9_Release(This->d3d9_ptr);
2509 TRACE("Number of surfaces: %u\n", This->num_surfaces);
2510 for (i = 0; i < This->num_surfaces; ++i)
2512 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2513 TRACE("Releasing surface %p\n", surface);
2514 if (surface)
2515 IDirect3DSurface9_Release(surface);
2518 CoTaskMemFree(This->d3d9_surfaces);
2519 This->d3d9_surfaces = NULL;
2520 This->num_surfaces = 0;
2521 if (This->d3d9_vertex)
2523 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2524 This->d3d9_vertex = NULL;
2526 CoTaskMemFree(This);
2527 return 0;
2529 return refCount;
2532 static HRESULT WINAPI VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2534 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2536 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2537 return S_OK;
2540 static HRESULT WINAPI VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2542 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2544 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2545 return S_OK;
2548 #define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
2549 struct VERTEX { float x, y, z, rhw, u, v; };
2551 static HRESULT VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2553 IDirect3DTexture9 *texture = NULL;
2554 HRESULT hr;
2556 hr = IDirect3DDevice9_SetFVF(This->d3d9_dev, USED_FVF);
2557 if (FAILED(hr))
2559 FIXME("SetFVF: %08x\n", hr);
2560 return hr;
2563 hr = IDirect3DDevice9_SetStreamSource(This->d3d9_dev, 0, This->d3d9_vertex, 0, sizeof(struct VERTEX));
2564 if (FAILED(hr))
2566 FIXME("SetStreamSource: %08x\n", hr);
2567 return hr;
2570 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **) &texture);
2571 if (FAILED(hr))
2573 FIXME("IDirect3DSurface9_GetContainer failed\n");
2574 return hr;
2576 hr = IDirect3DDevice9_SetTexture(This->d3d9_dev, 0, (IDirect3DBaseTexture9 *)texture);
2577 IDirect3DTexture9_Release(texture);
2578 if (FAILED(hr))
2580 FIXME("SetTexture: %08x\n", hr);
2581 return hr;
2584 hr = IDirect3DDevice9_DrawPrimitive(This->d3d9_dev, D3DPT_TRIANGLESTRIP, 0, 2);
2585 if (FAILED(hr))
2587 FIXME("DrawPrimitive: %08x\n", hr);
2588 return hr;
2591 return S_OK;
2594 static HRESULT VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2596 HRESULT hr;
2597 IDirect3DSurface9 *target = NULL;
2598 RECT target_rect;
2600 hr = IDirect3DDevice9_GetBackBuffer(This->d3d9_dev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &target);
2601 if (FAILED(hr))
2603 ERR("IDirect3DDevice9_GetBackBuffer -- %08x\n", hr);
2604 return hr;
2607 target_rect = This->pVMR9->target_rect;
2608 target_rect.right -= target_rect.left;
2609 target_rect.bottom -= target_rect.top;
2610 target_rect.left = target_rect.top = 0;
2612 /* Flip */
2613 target_rect.top = target_rect.bottom;
2614 target_rect.bottom = 0;
2616 hr = IDirect3DDevice9_StretchRect(This->d3d9_dev, surface, &This->pVMR9->source_rect, target, &target_rect, D3DTEXF_LINEAR);
2617 if (FAILED(hr))
2618 ERR("IDirect3DDevice9_StretchRect -- %08x\n", hr);
2619 IDirect3DSurface9_Release(target);
2621 return hr;
2624 static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR id, VMR9PresentationInfo *info)
2626 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2627 HRESULT hr;
2628 RECT output;
2629 BOOL render = FALSE;
2631 TRACE("(%p/%p/%p)->(...) stub\n", iface, This, This->pVMR9);
2632 GetWindowRect(This->pVMR9->baseControlWindow.baseWindow.hWnd, &output);
2633 TRACE("Output rectangle: starting at %dx%d, up to point %dx%d\n", output.left, output.top, output.right, output.bottom);
2635 /* This might happen if we don't have active focus (eg on a different virtual desktop) */
2636 if (!This->d3d9_dev)
2637 return S_OK;
2639 /* Display image here */
2640 hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
2641 if (FAILED(hr))
2642 FIXME("hr: %08x\n", hr);
2643 hr = IDirect3DDevice9_BeginScene(This->d3d9_dev);
2644 if (SUCCEEDED(hr))
2646 if (This->d3d9_vertex)
2647 hr = VMR9_ImagePresenter_PresentTexture(This, info->lpSurf);
2648 else
2649 hr = VMR9_ImagePresenter_PresentOffscreenSurface(This, info->lpSurf);
2650 render = SUCCEEDED(hr);
2652 else
2653 FIXME("BeginScene: %08x\n", hr);
2654 hr = IDirect3DDevice9_EndScene(This->d3d9_dev);
2655 if (render && SUCCEEDED(hr))
2657 hr = IDirect3DDevice9_Present(This->d3d9_dev, NULL, NULL, This->pVMR9->baseControlWindow.baseWindow.hWnd, NULL);
2658 if (FAILED(hr))
2659 FIXME("Presenting image: %08x\n", hr);
2662 return S_OK;
2665 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter =
2667 VMR9_ImagePresenter_QueryInterface,
2668 VMR9_ImagePresenter_AddRef,
2669 VMR9_ImagePresenter_Release,
2670 VMR9_ImagePresenter_StartPresenting,
2671 VMR9_ImagePresenter_StopPresenting,
2672 VMR9_ImagePresenter_PresentImage
2675 static HRESULT WINAPI VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9 *iface, REFIID riid, LPVOID * ppv)
2677 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2679 return VMR9_ImagePresenter_QueryInterface(&This->IVMRImagePresenter9_iface, riid, ppv);
2682 static ULONG WINAPI VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9 *iface)
2684 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2686 return VMR9_ImagePresenter_AddRef(&This->IVMRImagePresenter9_iface);
2689 static ULONG WINAPI VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9 *iface)
2691 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2693 return VMR9_ImagePresenter_Release(&This->IVMRImagePresenter9_iface);
2696 static HRESULT VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *allocinfo)
2698 D3DCAPS9 caps;
2699 UINT width, height;
2700 HRESULT hr;
2702 if (!(allocinfo->dwFlags & VMR9AllocFlag_TextureSurface))
2703 /* Only needed for texture surfaces */
2704 return S_OK;
2706 hr = IDirect3DDevice9_GetDeviceCaps(This->d3d9_dev, &caps);
2707 if (FAILED(hr))
2708 return hr;
2710 if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2) || (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY))
2712 width = allocinfo->dwWidth;
2713 height = allocinfo->dwHeight;
2715 else
2717 width = height = 1;
2718 while (width < allocinfo->dwWidth)
2719 width *= 2;
2721 while (height < allocinfo->dwHeight)
2722 height *= 2;
2723 FIXME("NPOW2 support missing, not using proper surfaces!\n");
2726 if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
2728 if (height > width)
2729 width = height;
2730 else
2731 height = width;
2732 FIXME("Square texture support required..\n");
2735 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF, allocinfo->Pool, &This->d3d9_vertex, NULL);
2736 if (FAILED(hr))
2738 ERR("Couldn't create vertex buffer: %08x\n", hr);
2739 return hr;
2742 This->reset = TRUE;
2743 allocinfo->dwHeight = height;
2744 allocinfo->dwWidth = width;
2746 return hr;
2749 static DWORD WINAPI MessageLoop(LPVOID lpParameter)
2751 MSG msg;
2752 BOOL fGotMessage;
2753 VMR9DefaultAllocatorPresenterImpl *This = lpParameter;
2755 TRACE("Starting message loop\n");
2757 if (FAILED(BaseWindowImpl_PrepareWindow(&This->pVMR9->baseControlWindow.baseWindow)))
2759 FIXME("Failed to prepare window\n");
2760 return FALSE;
2763 SetEvent(This->ack);
2764 while ((fGotMessage = GetMessageW(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1)
2766 TranslateMessage(&msg);
2767 DispatchMessageW(&msg);
2770 TRACE("End of message loop\n");
2772 return 0;
2775 static UINT d3d9_adapter_from_hwnd(IDirect3D9 *d3d9, HWND hwnd, HMONITOR *mon_out)
2777 UINT d3d9_adapter;
2778 HMONITOR mon;
2780 mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
2781 if (!mon)
2782 d3d9_adapter = 0;
2783 else
2785 for (d3d9_adapter = 0; d3d9_adapter < IDirect3D9_GetAdapterCount(d3d9); ++d3d9_adapter)
2787 if (mon == IDirect3D9_GetAdapterMonitor(d3d9, d3d9_adapter))
2788 break;
2790 if (d3d9_adapter >= IDirect3D9_GetAdapterCount(d3d9))
2791 d3d9_adapter = 0;
2793 if (mon_out)
2794 *mon_out = mon;
2795 return d3d9_adapter;
2798 static BOOL CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *info, DWORD *numbuffers)
2800 D3DPRESENT_PARAMETERS d3dpp;
2801 DWORD d3d9_adapter;
2802 HRESULT hr;
2804 TRACE("(%p)->()\n", This);
2806 This->hWndThread = CreateThread(NULL, 0, MessageLoop, This, 0, &This->tid);
2807 if (!This->hWndThread)
2808 return FALSE;
2810 WaitForSingleObject(This->ack, INFINITE);
2812 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) return FALSE;
2814 /* Obtain a monitor and d3d9 device */
2815 d3d9_adapter = d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon);
2817 /* Now try to create the d3d9 device */
2818 ZeroMemory(&d3dpp, sizeof(d3dpp));
2819 d3dpp.Windowed = TRUE;
2820 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2821 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2822 d3dpp.BackBufferHeight = This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top;
2823 d3dpp.BackBufferWidth = This->pVMR9->target_rect.right - This->pVMR9->target_rect.left;
2825 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev);
2826 if (FAILED(hr))
2828 ERR("Could not create device: %08x\n", hr);
2829 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2830 return FALSE;
2832 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2834 This->d3d9_surfaces = CoTaskMemAlloc(*numbuffers * sizeof(IDirect3DSurface9 *));
2835 ZeroMemory(This->d3d9_surfaces, *numbuffers * sizeof(IDirect3DSurface9 *));
2837 hr = VMR9_SurfaceAllocator_SetAllocationSettings(This, info);
2838 if (FAILED(hr))
2839 ERR("Setting allocation settings failed: %08x\n", hr);
2841 if (SUCCEEDED(hr))
2843 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, info, numbuffers, This->d3d9_surfaces);
2844 if (FAILED(hr))
2845 ERR("Allocating surfaces failed: %08x\n", hr);
2848 if (FAILED(hr))
2850 IVMRSurfaceAllocatorEx9_TerminateDevice(This->pVMR9->allocator, This->pVMR9->cookie);
2851 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2852 return FALSE;
2855 This->num_surfaces = *numbuffers;
2857 return TRUE;
2860 static HRESULT WINAPI VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, VMR9AllocationInfo *allocinfo, DWORD *numbuffers)
2862 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2864 if (This->pVMR9->mode != VMR9Mode_Windowed && !This->pVMR9->hWndClippingWindow)
2866 ERR("No window set\n");
2867 return VFW_E_WRONG_STATE;
2870 This->info = *allocinfo;
2872 if (!CreateRenderingWindow(This, allocinfo, numbuffers))
2874 ERR("Failed to create rendering window, expect no output!\n");
2875 return VFW_E_WRONG_STATE;
2878 return S_OK;
2881 static HRESULT WINAPI VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id)
2883 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2885 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
2887 return S_OK;
2890 SendMessageW(This->pVMR9->baseControlWindow.baseWindow.hWnd, WM_CLOSE, 0, 0);
2891 PostThreadMessageW(This->tid, WM_QUIT, 0, 0);
2892 WaitForSingleObject(This->hWndThread, INFINITE);
2893 This->hWndThread = NULL;
2894 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2896 return S_OK;
2899 /* Recreate all surfaces (If allocated as D3DPOOL_DEFAULT) and survive! */
2900 static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl *This)
2902 struct VERTEX t_vert[4];
2903 UINT width, height;
2904 unsigned int i;
2905 void *bits = NULL;
2906 D3DPRESENT_PARAMETERS d3dpp;
2907 HRESULT hr;
2909 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
2911 ERR("No window\n");
2912 return E_FAIL;
2915 if (!This->d3d9_surfaces || !This->reset)
2916 return S_OK;
2918 This->reset = FALSE;
2919 TRACE("RESETTING\n");
2920 if (This->d3d9_vertex)
2922 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2923 This->d3d9_vertex = NULL;
2926 for (i = 0; i < This->num_surfaces; ++i)
2928 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2929 TRACE("Releasing surface %p\n", surface);
2930 if (surface)
2931 IDirect3DSurface9_Release(surface);
2933 ZeroMemory(This->d3d9_surfaces, sizeof(IDirect3DSurface9 *) * This->num_surfaces);
2935 /* Now try to create the d3d9 device */
2936 ZeroMemory(&d3dpp, sizeof(d3dpp));
2937 d3dpp.Windowed = TRUE;
2938 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2939 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2941 if (This->d3d9_dev)
2942 IDirect3DDevice9_Release(This->d3d9_dev);
2943 This->d3d9_dev = NULL;
2944 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);
2945 if (FAILED(hr))
2947 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);
2948 if (FAILED(hr))
2950 ERR("--> Creating device: %08x\n", hr);
2951 return S_OK;
2954 IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2956 IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, &This->info, &This->num_surfaces, This->d3d9_surfaces);
2958 This->reset = FALSE;
2960 if (!(This->info.dwFlags & VMR9AllocFlag_TextureSurface))
2961 return S_OK;
2963 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF,
2964 This->info.Pool, &This->d3d9_vertex, NULL);
2966 width = This->info.dwWidth;
2967 height = This->info.dwHeight;
2969 for (i = 0; i < sizeof(t_vert) / sizeof(t_vert[0]); ++i)
2971 if (i % 2)
2973 t_vert[i].x = (float)This->pVMR9->target_rect.right - (float)This->pVMR9->target_rect.left - 0.5f;
2974 t_vert[i].u = (float)This->pVMR9->source_rect.right / (float)width;
2976 else
2978 t_vert[i].x = -0.5f;
2979 t_vert[i].u = (float)This->pVMR9->source_rect.left / (float)width;
2982 if (i % 4 < 2)
2984 t_vert[i].y = -0.5f;
2985 t_vert[i].v = (float)This->pVMR9->source_rect.bottom / (float)height;
2987 else
2989 t_vert[i].y = (float)This->pVMR9->target_rect.bottom - (float)This->pVMR9->target_rect.top - 0.5f;
2990 t_vert[i].v = (float)This->pVMR9->source_rect.top / (float)height;
2992 t_vert[i].z = 0.0f;
2993 t_vert[i].rhw = 1.0f;
2996 FIXME("Vertex rectangle:\n");
2997 FIXME("X, Y: %f, %f\n", t_vert[0].x, t_vert[0].y);
2998 FIXME("X, Y: %f, %f\n", t_vert[3].x, t_vert[3].y);
2999 FIXME("TOP, LEFT: %f, %f\n", t_vert[0].u, t_vert[0].v);
3000 FIXME("DOWN, BOTTOM: %f, %f\n", t_vert[3].u, t_vert[3].v);
3002 IDirect3DVertexBuffer9_Lock(This->d3d9_vertex, 0, sizeof(t_vert), &bits, 0);
3003 memcpy(bits, t_vert, sizeof(t_vert));
3004 IDirect3DVertexBuffer9_Unlock(This->d3d9_vertex);
3006 return S_OK;
3009 static HRESULT WINAPI VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, DWORD surfaceindex, DWORD flags, IDirect3DSurface9 **surface)
3011 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
3013 /* Update everything first, this is needed because the surface might be destroyed in the reset */
3014 if (!This->d3d9_dev)
3016 TRACE("Device has left me!\n");
3017 return E_FAIL;
3020 VMR9_SurfaceAllocator_UpdateDeviceReset(This);
3022 if (surfaceindex >= This->num_surfaces)
3024 ERR("surfaceindex is greater than num_surfaces\n");
3025 return E_FAIL;
3027 *surface = This->d3d9_surfaces[surfaceindex];
3028 IDirect3DSurface9_AddRef(*surface);
3030 return S_OK;
3033 static HRESULT WINAPI VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9 *iface, IVMRSurfaceAllocatorNotify9 *allocnotify)
3035 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
3037 TRACE("(%p/%p)->(...)\n", iface, This);
3039 /* No AddRef taken here or the base VMR9 filter would never be destroied */
3040 This->SurfaceAllocatorNotify = allocnotify;
3041 return S_OK;
3044 static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator =
3046 VMR9_SurfaceAllocator_QueryInterface,
3047 VMR9_SurfaceAllocator_AddRef,
3048 VMR9_SurfaceAllocator_Release,
3049 VMR9_SurfaceAllocator_InitializeDevice,
3050 VMR9_SurfaceAllocator_TerminateDevice,
3051 VMR9_SurfaceAllocator_GetSurface,
3052 VMR9_SurfaceAllocator_AdviseNotify,
3053 NULL /* This isn't the SurfaceAllocatorEx type yet, working on it */
3056 static IDirect3D9 *init_d3d9(HMODULE d3d9_handle)
3058 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion);
3060 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
3061 if (!d3d9_create) return NULL;
3063 return d3d9_create(D3D_SDK_VERSION);
3066 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv)
3068 HRESULT hr = S_OK;
3069 int i;
3070 VMR9DefaultAllocatorPresenterImpl* This;
3072 This = CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl));
3073 if (!This)
3074 return E_OUTOFMEMORY;
3076 This->d3d9_ptr = init_d3d9(parent->hD3d9);
3077 if (!This->d3d9_ptr)
3079 WARN("Could not initialize d3d9.dll\n");
3080 CoTaskMemFree(This);
3081 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
3084 i = 0;
3087 D3DDISPLAYMODE mode;
3089 hr = IDirect3D9_EnumAdapterModes(This->d3d9_ptr, i++, D3DFMT_X8R8G8B8, 0, &mode);
3090 } while (FAILED(hr));
3091 if (FAILED(hr))
3092 ERR("HR: %08x\n", hr);
3093 if (hr == D3DERR_NOTAVAILABLE)
3095 ERR("Format not supported\n");
3096 IDirect3D9_Release(This->d3d9_ptr);
3097 CoTaskMemFree(This);
3098 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
3101 This->IVMRImagePresenter9_iface.lpVtbl = &VMR9_ImagePresenter;
3102 This->IVMRSurfaceAllocatorEx9_iface.lpVtbl = &VMR9_SurfaceAllocator;
3104 This->refCount = 1;
3105 This->pVMR9 = parent;
3106 This->d3d9_surfaces = NULL;
3107 This->d3d9_dev = NULL;
3108 This->hMon = 0;
3109 This->d3d9_vertex = NULL;
3110 This->num_surfaces = 0;
3111 This->hWndThread = NULL;
3112 This->ack = CreateEventW(NULL, 0, 0, NULL);
3113 This->SurfaceAllocatorNotify = NULL;
3114 This->reset = FALSE;
3116 *ppv = This;
3117 return S_OK;