inetcomm: Implement MimeOleGetPropertySchema.
[wine.git] / dlls / quartz / vmr9.c
blobf2c3d93138c95eeb14dfc7fb62967689d79c1a69
1 /*
2 * Video Mixing Renderer for dx9
4 * Copyright 2004 Christian Costa
5 * Copyright 2008 Maarten Lankhorst
6 * Copyright 2012 Aric Stewart
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "config.h"
25 #include "quartz_private.h"
27 #include "uuids.h"
28 #include "vfwmsgs.h"
29 #include "amvideo.h"
30 #include "windef.h"
31 #include "winbase.h"
32 #include "dshow.h"
33 #include "evcode.h"
34 #include "strmif.h"
35 #include "ddraw.h"
36 #include "dvdmedia.h"
37 #include "d3d9.h"
38 #include "vmr9.h"
39 #include "pin.h"
41 #include "wine/unicode.h"
42 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
46 struct quartz_vmr
48 BaseRenderer renderer;
49 BaseControlWindow baseControlWindow;
50 BaseControlVideo baseControlVideo;
52 IUnknown IUnknown_inner;
53 IAMCertifiedOutputProtection IAMCertifiedOutputProtection_iface;
54 IAMFilterMiscFlags IAMFilterMiscFlags_iface;
55 IVMRFilterConfig IVMRFilterConfig_iface;
56 IVMRFilterConfig9 IVMRFilterConfig9_iface;
57 IVMRMonitorConfig IVMRMonitorConfig_iface;
58 IVMRMonitorConfig9 IVMRMonitorConfig9_iface;
59 IVMRSurfaceAllocatorNotify IVMRSurfaceAllocatorNotify_iface;
60 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface;
61 IVMRWindowlessControl IVMRWindowlessControl_iface;
62 IVMRWindowlessControl9 IVMRWindowlessControl9_iface;
64 IVMRSurfaceAllocatorEx9 *allocator;
65 IVMRImagePresenter9 *presenter;
66 BOOL allocator_is_ex;
69 * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed
70 * What I do is implement windowless as a special case of renderless, and then
71 * windowed also as a special case of windowless. This is probably the easiest way.
73 VMR9Mode mode;
74 BITMAPINFOHEADER bmiheader;
75 IUnknown * outer_unk;
76 BOOL bUnkOuterValid;
77 BOOL bAggregatable;
79 HMODULE hD3d9;
81 /* Presentation related members */
82 IDirect3DDevice9 *allocator_d3d9_dev;
83 HMONITOR allocator_mon;
84 DWORD num_surfaces;
85 DWORD cur_surface;
86 DWORD_PTR cookie;
88 /* for Windowless Mode */
89 HWND hWndClippingWindow;
91 RECT source_rect;
92 RECT target_rect;
93 LONG VideoWidth;
94 LONG VideoHeight;
97 static inline struct quartz_vmr *impl_from_inner_IUnknown(IUnknown *iface)
99 return CONTAINING_RECORD(iface, struct quartz_vmr, IUnknown_inner);
102 static inline struct quartz_vmr *impl_from_BaseWindow(BaseWindow *wnd)
104 return CONTAINING_RECORD(wnd, struct quartz_vmr, baseControlWindow.baseWindow);
107 static inline struct quartz_vmr *impl_from_IVideoWindow(IVideoWindow *iface)
109 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlWindow.IVideoWindow_iface);
112 static inline struct quartz_vmr *impl_from_BaseControlVideo(BaseControlVideo *cvid)
114 return CONTAINING_RECORD(cvid, struct quartz_vmr, baseControlVideo);
117 static inline struct quartz_vmr *impl_from_IBasicVideo(IBasicVideo *iface)
119 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlVideo.IBasicVideo_iface);
122 static inline struct quartz_vmr *impl_from_IAMCertifiedOutputProtection(IAMCertifiedOutputProtection *iface)
124 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMCertifiedOutputProtection_iface);
127 static inline struct quartz_vmr *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
129 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMFilterMiscFlags_iface);
132 static inline struct quartz_vmr *impl_from_IVMRFilterConfig(IVMRFilterConfig *iface)
134 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig_iface);
137 static inline struct quartz_vmr *impl_from_IVMRFilterConfig9(IVMRFilterConfig9 *iface)
139 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig9_iface);
142 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig(IVMRMonitorConfig *iface)
144 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig_iface);
147 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig9(IVMRMonitorConfig9 *iface)
149 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig9_iface);
152 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify(IVMRSurfaceAllocatorNotify *iface)
154 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify_iface);
157 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify9(IVMRSurfaceAllocatorNotify9 *iface)
159 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify9_iface);
162 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl(IVMRWindowlessControl *iface)
164 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl_iface);
167 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl9(IVMRWindowlessControl9 *iface)
169 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl9_iface);
172 typedef struct
174 IVMRImagePresenter9 IVMRImagePresenter9_iface;
175 IVMRSurfaceAllocatorEx9 IVMRSurfaceAllocatorEx9_iface;
177 LONG refCount;
179 HANDLE ack;
180 DWORD tid;
181 HANDLE hWndThread;
183 IDirect3DDevice9 *d3d9_dev;
184 IDirect3D9 *d3d9_ptr;
185 IDirect3DSurface9 **d3d9_surfaces;
186 IDirect3DVertexBuffer9 *d3d9_vertex;
187 HMONITOR hMon;
188 DWORD num_surfaces;
190 BOOL reset;
191 VMR9AllocationInfo info;
193 struct quartz_vmr* pVMR9;
194 IVMRSurfaceAllocatorNotify9 *SurfaceAllocatorNotify;
195 } VMR9DefaultAllocatorPresenterImpl;
197 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRImagePresenter9( IVMRImagePresenter9 *iface)
199 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRImagePresenter9_iface);
202 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRSurfaceAllocatorEx9( IVMRSurfaceAllocatorEx9 *iface)
204 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRSurfaceAllocatorEx9_iface);
207 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv);
209 static DWORD VMR9_SendSampleData(struct quartz_vmr *This, VMR9PresentationInfo *info, LPBYTE data,
210 DWORD size)
212 AM_MEDIA_TYPE *amt;
213 HRESULT hr = S_OK;
214 int width;
215 int height;
216 BITMAPINFOHEADER *bmiHeader;
217 D3DLOCKED_RECT lock;
219 TRACE("%p %p %d\n", This, data, size);
221 amt = &This->renderer.pInputPin->pin.mtCurrent;
223 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
225 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
227 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
229 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
231 else
233 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
234 return VFW_E_RUNTIME_ERROR;
237 TRACE("biSize = %d\n", bmiHeader->biSize);
238 TRACE("biWidth = %d\n", bmiHeader->biWidth);
239 TRACE("biHeight = %d\n", bmiHeader->biHeight);
240 TRACE("biPlanes = %d\n", bmiHeader->biPlanes);
241 TRACE("biBitCount = %d\n", bmiHeader->biBitCount);
242 TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(bmiHeader->biCompression), 4));
243 TRACE("biSizeImage = %d\n", bmiHeader->biSizeImage);
245 width = bmiHeader->biWidth;
246 height = bmiHeader->biHeight;
248 TRACE("Src Rect: %s\n", wine_dbgstr_rect(&This->source_rect));
249 TRACE("Dst Rect: %s\n", wine_dbgstr_rect(&This->target_rect));
251 hr = IDirect3DSurface9_LockRect(info->lpSurf, &lock, NULL, D3DLOCK_DISCARD);
252 if (FAILED(hr))
254 ERR("IDirect3DSurface9_LockRect failed (%x)\n",hr);
255 return hr;
258 if (lock.Pitch != width * bmiHeader->biBitCount / 8)
260 WARN("Slow path! %u/%u\n", lock.Pitch, width * bmiHeader->biBitCount/8);
262 while (height--)
264 memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8);
265 data = data + width * bmiHeader->biBitCount / 8;
266 lock.pBits = (char *)lock.pBits + lock.Pitch;
269 else memcpy(lock.pBits, data, size);
271 IDirect3DSurface9_UnlockRect(info->lpSurf);
273 hr = IVMRImagePresenter9_PresentImage(This->presenter, This->cookie, info);
274 return hr;
277 static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample)
279 struct quartz_vmr *This = (struct quartz_vmr*)iface;
280 LPBYTE pbSrcStream = NULL;
281 long cbSrcStream = 0;
282 REFERENCE_TIME tStart, tStop;
283 VMR9PresentationInfo info;
284 HRESULT hr;
286 TRACE("%p %p\n", iface, pSample);
288 /* It is possible that there is no device at this point */
290 if (!This->allocator || !This->presenter)
292 ERR("NO PRESENTER!!\n");
293 return S_FALSE;
296 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
297 if (FAILED(hr))
298 info.dwFlags = VMR9Sample_SrcDstRectsValid;
299 else
300 info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid;
302 if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
303 info.dwFlags |= VMR9Sample_Discontinuity;
305 if (IMediaSample_IsPreroll(pSample) == S_OK)
306 info.dwFlags |= VMR9Sample_Preroll;
308 if (IMediaSample_IsSyncPoint(pSample) == S_OK)
309 info.dwFlags |= VMR9Sample_SyncPoint;
311 /* If we render ourselves, and this is a preroll sample, discard it */
312 if (This->baseControlWindow.baseWindow.hWnd && (info.dwFlags & VMR9Sample_Preroll))
314 return S_OK;
317 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
318 if (FAILED(hr))
320 ERR("Cannot get pointer to sample data (%x)\n", hr);
321 return hr;
324 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
326 info.rtStart = tStart;
327 info.rtEnd = tStop;
328 info.szAspectRatio.cx = This->bmiheader.biWidth;
329 info.szAspectRatio.cy = This->bmiheader.biHeight;
331 hr = IVMRSurfaceAllocatorEx9_GetSurface(This->allocator, This->cookie, (++This->cur_surface)%This->num_surfaces, 0, &info.lpSurf);
333 if (FAILED(hr))
334 return hr;
336 VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream);
337 IDirect3DSurface9_Release(info.lpSurf);
339 return hr;
342 static HRESULT WINAPI VMR9_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt)
344 struct quartz_vmr *This = (struct quartz_vmr*)iface;
346 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat)
347 return S_FALSE;
349 /* Ignore subtype, test for bicompression instead */
350 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
352 VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
354 This->bmiheader = format->bmiHeader;
355 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
356 This->VideoWidth = format->bmiHeader.biWidth;
357 This->VideoHeight = format->bmiHeader.biHeight;
358 SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight);
360 else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
362 VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat;
364 This->bmiheader = format->bmiHeader;
366 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
367 This->VideoWidth = format->bmiHeader.biWidth;
368 This->VideoHeight = format->bmiHeader.biHeight;
369 SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight);
371 else
373 ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
374 return S_FALSE;
376 if (This->bmiheader.biCompression)
377 return S_FALSE;
378 return S_OK;
381 static HRESULT VMR9_maybe_init(struct quartz_vmr *This, BOOL force)
383 VMR9AllocationInfo info;
384 DWORD buffers;
385 HRESULT hr;
387 TRACE("my mode: %u, my window: %p, my last window: %p\n", This->mode, This->baseControlWindow.baseWindow.hWnd, This->hWndClippingWindow);
388 if (This->baseControlWindow.baseWindow.hWnd || !This->renderer.pInputPin->pin.pConnectedTo)
389 return S_OK;
391 if (This->mode == VMR9Mode_Windowless && !This->hWndClippingWindow)
392 return (force ? VFW_E_RUNTIME_ERROR : S_OK);
394 TRACE("Initializing\n");
395 info.dwFlags = VMR9AllocFlag_TextureSurface;
396 info.dwHeight = This->source_rect.bottom;
397 info.dwWidth = This->source_rect.right;
398 info.Pool = D3DPOOL_DEFAULT;
399 info.MinBuffers = 2;
400 FIXME("Reduce ratio to least common denominator\n");
401 info.szAspectRatio.cx = info.dwWidth;
402 info.szAspectRatio.cy = info.dwHeight;
403 info.szNativeSize.cx = This->bmiheader.biWidth;
404 info.szNativeSize.cy = This->bmiheader.biHeight;
405 buffers = 2;
407 switch (This->bmiheader.biBitCount)
409 case 8: info.Format = D3DFMT_R3G3B2; break;
410 case 15: info.Format = D3DFMT_X1R5G5B5; break;
411 case 16: info.Format = D3DFMT_R5G6B5; break;
412 case 24: info.Format = D3DFMT_R8G8B8; break;
413 case 32: info.Format = D3DFMT_X8R8G8B8; break;
414 default:
415 FIXME("Unknown bpp %u\n", This->bmiheader.biBitCount);
416 hr = E_INVALIDARG;
419 This->cur_surface = 0;
420 if (This->num_surfaces)
422 ERR("num_surfaces or d3d9_surfaces not 0\n");
423 return E_FAIL;
426 hr = IVMRSurfaceAllocatorEx9_InitializeDevice(This->allocator, This->cookie, &info, &buffers);
427 if (SUCCEEDED(hr))
429 SetRect(&This->source_rect, 0, 0, This->bmiheader.biWidth, This->bmiheader.biHeight);
431 This->num_surfaces = buffers;
433 return hr;
436 static VOID WINAPI VMR9_OnStartStreaming(BaseRenderer* iface)
438 struct quartz_vmr *This = (struct quartz_vmr*)iface;
440 TRACE("(%p)\n", This);
442 VMR9_maybe_init(This, TRUE);
443 IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie);
444 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
445 This->source_rect.left,
446 This->source_rect.top,
447 This->source_rect.right - This->source_rect.left,
448 This->source_rect.bottom - This->source_rect.top,
449 SWP_NOZORDER|SWP_NOMOVE|SWP_DEFERERASE);
450 ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_SHOW);
451 GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->target_rect);
454 static VOID WINAPI VMR9_OnStopStreaming(BaseRenderer* iface)
456 struct quartz_vmr *This = (struct quartz_vmr*)iface;
458 TRACE("(%p)\n", This);
460 if (This->renderer.filter.state == State_Running)
461 IVMRImagePresenter9_StopPresenting(This->presenter, This->cookie);
464 static HRESULT WINAPI VMR9_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime)
466 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
467 if (IMediaSample_IsPreroll(pSample) == S_OK)
468 return E_FAIL;
469 return S_FALSE;
472 static HRESULT WINAPI VMR9_CompleteConnect(BaseRenderer *This, IPin *pReceivePin)
474 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This;
475 HRESULT hr;
477 TRACE("(%p)\n", This);
479 if (pVMR9->mode ||
480 SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&pVMR9->IVMRFilterConfig9_iface, VMR9Mode_Windowed)))
481 hr = VMR9_maybe_init(pVMR9, FALSE);
483 return hr;
486 static HRESULT WINAPI VMR9_BreakConnect(BaseRenderer *This)
488 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This;
489 HRESULT hr = S_OK;
491 if (!pVMR9->mode)
492 return S_FALSE;
493 if (This->pInputPin->pin.pConnectedTo && pVMR9->allocator && pVMR9->presenter)
495 if (pVMR9->renderer.filter.state != State_Stopped)
497 ERR("Disconnecting while not stopped! UNTESTED!!\n");
499 if (pVMR9->renderer.filter.state == State_Running)
500 hr = IVMRImagePresenter9_StopPresenting(pVMR9->presenter, pVMR9->cookie);
501 IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9->allocator, pVMR9->cookie);
502 pVMR9->num_surfaces = 0;
504 return hr;
507 static const BaseRendererFuncTable BaseFuncTable = {
508 VMR9_CheckMediaType,
509 VMR9_DoRenderSample,
510 /**/
511 NULL,
512 NULL,
513 NULL,
514 VMR9_OnStartStreaming,
515 VMR9_OnStopStreaming,
516 NULL,
517 NULL,
518 NULL,
519 VMR9_ShouldDrawSampleNow,
520 NULL,
521 /**/
522 VMR9_CompleteConnect,
523 VMR9_BreakConnect,
524 NULL,
525 NULL,
526 NULL,
529 static LPWSTR WINAPI VMR9_GetClassWindowStyles(BaseWindow *This, DWORD *pClassStyles, DWORD *pWindowStyles, DWORD *pWindowStylesEx)
531 static WCHAR classnameW[] = { 'I','V','M','R','9',' ','C','l','a','s','s', 0 };
533 *pClassStyles = 0;
534 *pWindowStyles = WS_SIZEBOX;
535 *pWindowStylesEx = 0;
537 return classnameW;
540 static RECT WINAPI VMR9_GetDefaultRect(BaseWindow *This)
542 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
543 static RECT defRect;
545 SetRect(&defRect, 0, 0, pVMR9->VideoWidth, pVMR9->VideoHeight);
547 return defRect;
550 static BOOL WINAPI VMR9_OnSize(BaseWindow *This, LONG Width, LONG Height)
552 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
554 TRACE("WM_SIZE %d %d\n", Width, Height);
555 GetClientRect(This->hWnd, &pVMR9->target_rect);
556 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
557 pVMR9->target_rect.left,
558 pVMR9->target_rect.top,
559 pVMR9->target_rect.right - pVMR9->target_rect.left,
560 pVMR9->target_rect.bottom - pVMR9->target_rect.top);
561 return BaseWindowImpl_OnSize(This, Width, Height);
564 static const BaseWindowFuncTable renderer_BaseWindowFuncTable = {
565 VMR9_GetClassWindowStyles,
566 VMR9_GetDefaultRect,
567 NULL,
568 BaseControlWindowImpl_PossiblyEatMessage,
569 VMR9_OnSize,
572 static HRESULT WINAPI VMR9_GetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
574 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
575 CopyRect(pSourceRect,&pVMR9->source_rect);
576 return S_OK;
579 static HRESULT WINAPI VMR9_GetStaticImage(BaseControlVideo* This, LONG *pBufferSize, LONG *pDIBImage)
581 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
582 BITMAPINFOHEADER *bmiHeader;
583 LONG needed_size;
584 AM_MEDIA_TYPE *amt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
585 char *ptr;
587 FIXME("(%p/%p)->(%p, %p): partial stub\n", pVMR9, This, pBufferSize, pDIBImage);
589 EnterCriticalSection(&pVMR9->renderer.filter.csFilter);
591 if (!pVMR9->renderer.pMediaSample)
593 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
594 return (pVMR9->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
597 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
599 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
601 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
603 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
605 else
607 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
608 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
609 return VFW_E_RUNTIME_ERROR;
612 needed_size = bmiHeader->biSize;
613 needed_size += IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample);
615 if (!pDIBImage)
617 *pBufferSize = needed_size;
618 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
619 return S_OK;
622 if (needed_size < *pBufferSize)
624 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
625 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
626 return E_FAIL;
628 *pBufferSize = needed_size;
630 memcpy(pDIBImage, bmiHeader, bmiHeader->biSize);
631 IMediaSample_GetPointer(pVMR9->renderer.pMediaSample, (BYTE **)&ptr);
632 memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample));
634 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
635 return S_OK;
638 static HRESULT WINAPI VMR9_GetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
640 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
641 CopyRect(pTargetRect,&pVMR9->target_rect);
642 return S_OK;
645 static VIDEOINFOHEADER* WINAPI VMR9_GetVideoFormat(BaseControlVideo* This)
647 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
648 AM_MEDIA_TYPE *pmt;
650 TRACE("(%p/%p)\n", pVMR9, This);
652 pmt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
653 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) {
654 return (VIDEOINFOHEADER*)pmt->pbFormat;
655 } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) {
656 static VIDEOINFOHEADER vih;
657 VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat;
658 memcpy(&vih,vih2,sizeof(VIDEOINFOHEADER));
659 memcpy(&vih.bmiHeader, &vih2->bmiHeader, sizeof(BITMAPINFOHEADER));
660 return &vih;
661 } else {
662 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype));
663 return NULL;
667 static HRESULT WINAPI VMR9_IsDefaultSourceRect(BaseControlVideo* This)
669 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
670 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
672 return S_OK;
675 static HRESULT WINAPI VMR9_IsDefaultTargetRect(BaseControlVideo* This)
677 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
678 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
680 return S_OK;
683 static HRESULT WINAPI VMR9_SetDefaultSourceRect(BaseControlVideo* This)
685 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
687 SetRect(&pVMR9->source_rect, 0, 0, pVMR9->VideoWidth, pVMR9->VideoHeight);
689 return S_OK;
692 static HRESULT WINAPI VMR9_SetDefaultTargetRect(BaseControlVideo* This)
694 RECT rect;
695 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
697 if (!GetClientRect(pVMR9->baseControlWindow.baseWindow.hWnd, &rect))
698 return E_FAIL;
700 SetRect(&pVMR9->target_rect, 0, 0, rect.right, rect.bottom);
702 return S_OK;
705 static HRESULT WINAPI VMR9_SetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
707 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
708 CopyRect(&pVMR9->source_rect,pSourceRect);
709 return S_OK;
712 static HRESULT WINAPI VMR9_SetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
714 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
715 CopyRect(&pVMR9->target_rect,pTargetRect);
716 return S_OK;
719 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = {
720 VMR9_GetSourceRect,
721 VMR9_GetStaticImage,
722 VMR9_GetTargetRect,
723 VMR9_GetVideoFormat,
724 VMR9_IsDefaultSourceRect,
725 VMR9_IsDefaultTargetRect,
726 VMR9_SetDefaultSourceRect,
727 VMR9_SetDefaultTargetRect,
728 VMR9_SetSourceRect,
729 VMR9_SetTargetRect
732 static HRESULT WINAPI VMR9Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
734 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
735 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
737 if (This->bAggregatable)
738 This->bUnkOuterValid = TRUE;
740 *ppv = NULL;
742 if (IsEqualIID(riid, &IID_IUnknown))
743 *ppv = &This->IUnknown_inner;
744 else if (IsEqualIID(riid, &IID_IVideoWindow))
745 *ppv = &This->baseControlWindow.IVideoWindow_iface;
746 else if (IsEqualIID(riid, &IID_IBasicVideo))
747 *ppv = &This->baseControlVideo.IBasicVideo_iface;
748 else if (IsEqualIID(riid, &IID_IAMCertifiedOutputProtection))
749 *ppv = &This->IAMCertifiedOutputProtection_iface;
750 else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
751 *ppv = &This->IAMFilterMiscFlags_iface;
752 else if (IsEqualIID(riid, &IID_IVMRFilterConfig))
753 *ppv = &This->IVMRFilterConfig_iface;
754 else if (IsEqualIID(riid, &IID_IVMRFilterConfig9))
755 *ppv = &This->IVMRFilterConfig9_iface;
756 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig))
757 *ppv = &This->IVMRMonitorConfig_iface;
758 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig9))
759 *ppv = &This->IVMRMonitorConfig9_iface;
760 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify) && This->mode == (VMR9Mode)VMRMode_Renderless)
761 *ppv = &This->IVMRSurfaceAllocatorNotify_iface;
762 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9) && This->mode == VMR9Mode_Renderless)
763 *ppv = &This->IVMRSurfaceAllocatorNotify9_iface;
764 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl) && This->mode == (VMR9Mode)VMRMode_Windowless)
765 *ppv = &This->IVMRWindowlessControl_iface;
766 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9) && This->mode == VMR9Mode_Windowless)
767 *ppv = &This->IVMRWindowlessControl9_iface;
768 else
770 HRESULT hr;
771 hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
772 if (SUCCEEDED(hr))
773 return hr;
776 if (*ppv)
778 IUnknown_AddRef((IUnknown *)(*ppv));
779 return S_OK;
782 else if (IsEqualIID(riid, &IID_IBasicVideo2))
783 FIXME("No interface for IID_IBasicVideo2\n");
784 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9))
786 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9))
788 else if (IsEqualIID(riid, &IID_IMediaPosition))
789 FIXME("No interface for IID_IMediaPosition\n");
790 else if (IsEqualIID(riid, &IID_IQualProp))
791 FIXME("No interface for IID_IQualProp\n");
792 else if (IsEqualIID(riid, &IID_IVMRAspectRatioControl9))
793 FIXME("No interface for IID_IVMRAspectRatioControl9\n");
794 else if (IsEqualIID(riid, &IID_IVMRDeinterlaceControl9))
795 FIXME("No interface for IID_IVMRDeinterlaceControl9\n");
796 else if (IsEqualIID(riid, &IID_IVMRMixerBitmap9))
797 FIXME("No interface for IID_IVMRMixerBitmap9\n");
798 else if (IsEqualIID(riid, &IID_IVMRMixerControl9))
799 FIXME("No interface for IID_IVMRMixerControl9\n");
800 else
801 FIXME("No interface for %s\n", debugstr_guid(riid));
803 return E_NOINTERFACE;
806 static ULONG WINAPI VMR9Inner_AddRef(IUnknown * iface)
808 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
809 ULONG refCount = BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
811 TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
813 return refCount;
816 static ULONG WINAPI VMR9Inner_Release(IUnknown * iface)
818 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
819 ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface);
821 TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
823 if (!refCount)
825 TRACE("Destroying\n");
826 BaseControlWindow_Destroy(&This->baseControlWindow);
827 FreeLibrary(This->hD3d9);
829 if (This->allocator)
830 IVMRSurfaceAllocatorEx9_Release(This->allocator);
831 if (This->presenter)
832 IVMRImagePresenter9_Release(This->presenter);
834 This->num_surfaces = 0;
835 if (This->allocator_d3d9_dev)
837 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
838 This->allocator_d3d9_dev = NULL;
841 CoTaskMemFree(This);
843 return refCount;
846 static const IUnknownVtbl IInner_VTable =
848 VMR9Inner_QueryInterface,
849 VMR9Inner_AddRef,
850 VMR9Inner_Release
853 static HRESULT WINAPI VMR9_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
855 struct quartz_vmr *This = (struct quartz_vmr*)iface;
857 if (This->bAggregatable)
858 This->bUnkOuterValid = TRUE;
860 if (This->outer_unk)
862 if (This->bAggregatable)
863 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
865 if (IsEqualIID(riid, &IID_IUnknown))
867 HRESULT hr;
869 IUnknown_AddRef(&This->IUnknown_inner);
870 hr = IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
871 IUnknown_Release(&This->IUnknown_inner);
872 This->bAggregatable = TRUE;
873 return hr;
876 *ppv = NULL;
877 return E_NOINTERFACE;
880 return IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
883 static ULONG WINAPI VMR9_AddRef(IBaseFilter * iface)
885 struct quartz_vmr *This = (struct quartz_vmr*)iface;
886 LONG ret;
888 if (This->outer_unk && This->bUnkOuterValid)
889 ret = IUnknown_AddRef(This->outer_unk);
890 else
891 ret = IUnknown_AddRef(&This->IUnknown_inner);
893 TRACE("(%p)->AddRef from %d\n", iface, ret - 1);
895 return ret;
898 static ULONG WINAPI VMR9_Release(IBaseFilter * iface)
900 struct quartz_vmr *This = (struct quartz_vmr*)iface;
901 LONG ret;
903 if (This->outer_unk && This->bUnkOuterValid)
904 ret = IUnknown_Release(This->outer_unk);
905 else
906 ret = IUnknown_Release(&This->IUnknown_inner);
908 TRACE("(%p)->Release from %d\n", iface, ret + 1);
910 if (ret)
911 return ret;
912 return 0;
915 static const IBaseFilterVtbl VMR_Vtbl =
917 VMR9_QueryInterface,
918 VMR9_AddRef,
919 VMR9_Release,
920 BaseFilterImpl_GetClassID,
921 BaseRendererImpl_Stop,
922 BaseRendererImpl_Pause,
923 BaseRendererImpl_Run,
924 BaseRendererImpl_GetState,
925 BaseRendererImpl_SetSyncSource,
926 BaseFilterImpl_GetSyncSource,
927 BaseFilterImpl_EnumPins,
928 BaseRendererImpl_FindPin,
929 BaseFilterImpl_QueryFilterInfo,
930 BaseFilterImpl_JoinFilterGraph,
931 BaseFilterImpl_QueryVendorInfo
934 /*** IUnknown methods ***/
935 static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface, REFIID riid, LPVOID*ppvObj)
937 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
939 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
941 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
944 static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface)
946 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
948 TRACE("(%p/%p)->()\n", This, iface);
950 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
953 static ULONG WINAPI Videowindow_Release(IVideoWindow *iface)
955 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
957 TRACE("(%p/%p)->()\n", This, iface);
959 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
962 static const IVideoWindowVtbl IVideoWindow_VTable =
964 Videowindow_QueryInterface,
965 Videowindow_AddRef,
966 Videowindow_Release,
967 BaseControlWindowImpl_GetTypeInfoCount,
968 BaseControlWindowImpl_GetTypeInfo,
969 BaseControlWindowImpl_GetIDsOfNames,
970 BaseControlWindowImpl_Invoke,
971 BaseControlWindowImpl_put_Caption,
972 BaseControlWindowImpl_get_Caption,
973 BaseControlWindowImpl_put_WindowStyle,
974 BaseControlWindowImpl_get_WindowStyle,
975 BaseControlWindowImpl_put_WindowStyleEx,
976 BaseControlWindowImpl_get_WindowStyleEx,
977 BaseControlWindowImpl_put_AutoShow,
978 BaseControlWindowImpl_get_AutoShow,
979 BaseControlWindowImpl_put_WindowState,
980 BaseControlWindowImpl_get_WindowState,
981 BaseControlWindowImpl_put_BackgroundPalette,
982 BaseControlWindowImpl_get_BackgroundPalette,
983 BaseControlWindowImpl_put_Visible,
984 BaseControlWindowImpl_get_Visible,
985 BaseControlWindowImpl_put_Left,
986 BaseControlWindowImpl_get_Left,
987 BaseControlWindowImpl_put_Width,
988 BaseControlWindowImpl_get_Width,
989 BaseControlWindowImpl_put_Top,
990 BaseControlWindowImpl_get_Top,
991 BaseControlWindowImpl_put_Height,
992 BaseControlWindowImpl_get_Height,
993 BaseControlWindowImpl_put_Owner,
994 BaseControlWindowImpl_get_Owner,
995 BaseControlWindowImpl_put_MessageDrain,
996 BaseControlWindowImpl_get_MessageDrain,
997 BaseControlWindowImpl_get_BorderColor,
998 BaseControlWindowImpl_put_BorderColor,
999 BaseControlWindowImpl_get_FullScreenMode,
1000 BaseControlWindowImpl_put_FullScreenMode,
1001 BaseControlWindowImpl_SetWindowForeground,
1002 BaseControlWindowImpl_NotifyOwnerMessage,
1003 BaseControlWindowImpl_SetWindowPosition,
1004 BaseControlWindowImpl_GetWindowPosition,
1005 BaseControlWindowImpl_GetMinIdealImageSize,
1006 BaseControlWindowImpl_GetMaxIdealImageSize,
1007 BaseControlWindowImpl_GetRestorePosition,
1008 BaseControlWindowImpl_HideCursor,
1009 BaseControlWindowImpl_IsCursorHidden
1012 /*** IUnknown methods ***/
1013 static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface, REFIID riid, LPVOID * ppvObj)
1015 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1017 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1019 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
1022 static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface)
1024 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1026 TRACE("(%p/%p)->()\n", This, iface);
1028 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1031 static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface)
1033 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1035 TRACE("(%p/%p)->()\n", This, iface);
1037 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1040 static const IBasicVideoVtbl IBasicVideo_VTable =
1042 Basicvideo_QueryInterface,
1043 Basicvideo_AddRef,
1044 Basicvideo_Release,
1045 BaseControlVideoImpl_GetTypeInfoCount,
1046 BaseControlVideoImpl_GetTypeInfo,
1047 BaseControlVideoImpl_GetIDsOfNames,
1048 BaseControlVideoImpl_Invoke,
1049 BaseControlVideoImpl_get_AvgTimePerFrame,
1050 BaseControlVideoImpl_get_BitRate,
1051 BaseControlVideoImpl_get_BitErrorRate,
1052 BaseControlVideoImpl_get_VideoWidth,
1053 BaseControlVideoImpl_get_VideoHeight,
1054 BaseControlVideoImpl_put_SourceLeft,
1055 BaseControlVideoImpl_get_SourceLeft,
1056 BaseControlVideoImpl_put_SourceWidth,
1057 BaseControlVideoImpl_get_SourceWidth,
1058 BaseControlVideoImpl_put_SourceTop,
1059 BaseControlVideoImpl_get_SourceTop,
1060 BaseControlVideoImpl_put_SourceHeight,
1061 BaseControlVideoImpl_get_SourceHeight,
1062 BaseControlVideoImpl_put_DestinationLeft,
1063 BaseControlVideoImpl_get_DestinationLeft,
1064 BaseControlVideoImpl_put_DestinationWidth,
1065 BaseControlVideoImpl_get_DestinationWidth,
1066 BaseControlVideoImpl_put_DestinationTop,
1067 BaseControlVideoImpl_get_DestinationTop,
1068 BaseControlVideoImpl_put_DestinationHeight,
1069 BaseControlVideoImpl_get_DestinationHeight,
1070 BaseControlVideoImpl_SetSourcePosition,
1071 BaseControlVideoImpl_GetSourcePosition,
1072 BaseControlVideoImpl_SetDefaultSourcePosition,
1073 BaseControlVideoImpl_SetDestinationPosition,
1074 BaseControlVideoImpl_GetDestinationPosition,
1075 BaseControlVideoImpl_SetDefaultDestinationPosition,
1076 BaseControlVideoImpl_GetVideoSize,
1077 BaseControlVideoImpl_GetVideoPaletteEntries,
1078 BaseControlVideoImpl_GetCurrentImage,
1079 BaseControlVideoImpl_IsUsingDefaultSource,
1080 BaseControlVideoImpl_IsUsingDefaultDestination
1083 static HRESULT WINAPI AMCertifiedOutputProtection_QueryInterface(IAMCertifiedOutputProtection *iface,
1084 REFIID riid, void **ppv)
1086 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1087 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1090 static ULONG WINAPI AMCertifiedOutputProtection_AddRef(IAMCertifiedOutputProtection *iface)
1092 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1093 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1096 static ULONG WINAPI AMCertifiedOutputProtection_Release(IAMCertifiedOutputProtection *iface)
1098 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1099 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1102 static HRESULT WINAPI AMCertifiedOutputProtection_KeyExchange(IAMCertifiedOutputProtection *iface,
1103 GUID* pRandom, BYTE** VarLenCertGH,
1104 DWORD* pdwLengthCertGH)
1106 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1108 FIXME("(%p/%p)->(%p, %p, %p) stub\n", iface, This, pRandom, VarLenCertGH, pdwLengthCertGH);
1109 return VFW_E_NO_COPP_HW;
1112 static HRESULT WINAPI AMCertifiedOutputProtection_SessionSequenceStart(IAMCertifiedOutputProtection *iface,
1113 AMCOPPSignature* pSig)
1115 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1117 FIXME("(%p/%p)->(%p) stub\n", iface, This, pSig);
1118 return VFW_E_NO_COPP_HW;
1121 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionCommand(IAMCertifiedOutputProtection *iface,
1122 const AMCOPPCommand* cmd)
1124 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1126 FIXME("(%p/%p)->(%p) stub\n", iface, This, cmd);
1127 return VFW_E_NO_COPP_HW;
1130 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionStatus(IAMCertifiedOutputProtection *iface,
1131 const AMCOPPStatusInput* pStatusInput,
1132 AMCOPPStatusOutput* pStatusOutput)
1134 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1136 FIXME("(%p/%p)->(%p, %p) stub\n", iface, This, pStatusInput, pStatusOutput);
1137 return VFW_E_NO_COPP_HW;
1140 static const IAMCertifiedOutputProtectionVtbl IAMCertifiedOutputProtection_Vtbl =
1142 AMCertifiedOutputProtection_QueryInterface,
1143 AMCertifiedOutputProtection_AddRef,
1144 AMCertifiedOutputProtection_Release,
1145 AMCertifiedOutputProtection_KeyExchange,
1146 AMCertifiedOutputProtection_SessionSequenceStart,
1147 AMCertifiedOutputProtection_ProtectionCommand,
1148 AMCertifiedOutputProtection_ProtectionStatus
1151 static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) {
1152 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1153 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1156 static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) {
1157 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1158 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1161 static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) {
1162 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1163 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1166 static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) {
1167 return AM_FILTER_MISC_FLAGS_IS_RENDERER;
1170 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = {
1171 AMFilterMiscFlags_QueryInterface,
1172 AMFilterMiscFlags_AddRef,
1173 AMFilterMiscFlags_Release,
1174 AMFilterMiscFlags_GetMiscFlags
1177 static HRESULT WINAPI VMR7FilterConfig_QueryInterface(IVMRFilterConfig *iface, REFIID riid,
1178 void** ppv)
1180 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1181 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1184 static ULONG WINAPI VMR7FilterConfig_AddRef(IVMRFilterConfig *iface)
1186 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1187 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1190 static ULONG WINAPI VMR7FilterConfig_Release(IVMRFilterConfig *iface)
1192 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1193 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1196 static HRESULT WINAPI VMR7FilterConfig_SetImageCompositor(IVMRFilterConfig *iface,
1197 IVMRImageCompositor *compositor)
1199 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1201 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
1202 return E_NOTIMPL;
1205 static HRESULT WINAPI VMR7FilterConfig_SetNumberOfStreams(IVMRFilterConfig *iface, DWORD max)
1207 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1209 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
1210 return E_NOTIMPL;
1213 static HRESULT WINAPI VMR7FilterConfig_GetNumberOfStreams(IVMRFilterConfig *iface, DWORD *max)
1215 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1217 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
1218 return E_NOTIMPL;
1221 static HRESULT WINAPI VMR7FilterConfig_SetRenderingPrefs(IVMRFilterConfig *iface, DWORD renderflags)
1223 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1225 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
1226 return E_NOTIMPL;
1229 static HRESULT WINAPI VMR7FilterConfig_GetRenderingPrefs(IVMRFilterConfig *iface, DWORD *renderflags)
1231 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1233 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
1234 return E_NOTIMPL;
1237 static HRESULT WINAPI VMR7FilterConfig_SetRenderingMode(IVMRFilterConfig *iface, DWORD mode)
1239 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1241 FIXME("(%p/%p)->(%u) stub\n", iface, This, mode);
1242 return E_NOTIMPL;
1245 static HRESULT WINAPI VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig *iface, DWORD *mode)
1247 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1249 TRACE("(%p/%p)->(%p) stub\n", iface, This, mode);
1250 if (!mode) return E_POINTER;
1252 if (This->mode)
1253 *mode = This->mode;
1254 else
1255 *mode = VMRMode_Windowed;
1257 return S_OK;
1260 static const IVMRFilterConfigVtbl VMR7_FilterConfig_Vtbl =
1262 VMR7FilterConfig_QueryInterface,
1263 VMR7FilterConfig_AddRef,
1264 VMR7FilterConfig_Release,
1265 VMR7FilterConfig_SetImageCompositor,
1266 VMR7FilterConfig_SetNumberOfStreams,
1267 VMR7FilterConfig_GetNumberOfStreams,
1268 VMR7FilterConfig_SetRenderingPrefs,
1269 VMR7FilterConfig_GetRenderingPrefs,
1270 VMR7FilterConfig_SetRenderingMode,
1271 VMR7FilterConfig_GetRenderingMode
1274 struct get_available_monitors_args
1276 VMRMONITORINFO *info7;
1277 VMR9MonitorInfo *info9;
1278 DWORD arraysize;
1279 DWORD numdev;
1282 static BOOL CALLBACK get_available_monitors_proc(HMONITOR hmon, HDC hdc, LPRECT lprc, LPARAM lparam)
1284 struct get_available_monitors_args *args = (struct get_available_monitors_args *)lparam;
1285 MONITORINFOEXW mi;
1287 if (args->info7 || args->info9)
1290 if (!args->arraysize)
1291 return FALSE;
1293 mi.cbSize = sizeof(mi);
1294 if (!GetMonitorInfoW(hmon, (MONITORINFO*)&mi))
1295 return TRUE;
1297 /* fill VMRMONITORINFO struct */
1298 if (args->info7)
1300 VMRMONITORINFO *info = args->info7++;
1301 memset(info, 0, sizeof(*info));
1303 if (args->numdev > 0)
1305 info->guid.pGUID = &info->guid.GUID;
1306 info->guid.GUID.Data4[7] = args->numdev;
1308 else
1309 info->guid.pGUID = NULL;
1311 CopyRect(&info->rcMonitor, &mi.rcMonitor);
1312 info->hMon = hmon;
1313 info->dwFlags = mi.dwFlags;
1315 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR));
1317 /* FIXME: how to get these values? */
1318 info->szDescription[0] = 0;
1321 /* fill VMR9MonitorInfo struct */
1322 if (args->info9)
1324 VMR9MonitorInfo *info = args->info9++;
1325 memset(info, 0, sizeof(*info));
1327 info->uDevID = 0; /* FIXME */
1328 CopyRect(&info->rcMonitor, &mi.rcMonitor);
1329 info->hMon = hmon;
1330 info->dwFlags = mi.dwFlags;
1332 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR));
1334 /* FIXME: how to get these values? */
1335 info->szDescription[0] = 0;
1336 info->dwVendorId = 0;
1337 info->dwDeviceId = 0;
1338 info->dwSubSysId = 0;
1339 info->dwRevision = 0;
1342 args->arraysize--;
1345 args->numdev++;
1346 return TRUE;
1349 static HRESULT WINAPI VMR7MonitorConfig_QueryInterface(IVMRMonitorConfig *iface, REFIID riid,
1350 LPVOID * ppv)
1352 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1353 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1356 static ULONG WINAPI VMR7MonitorConfig_AddRef(IVMRMonitorConfig *iface)
1358 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1359 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1362 static ULONG WINAPI VMR7MonitorConfig_Release(IVMRMonitorConfig *iface)
1364 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1365 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1368 static HRESULT WINAPI VMR7MonitorConfig_SetMonitor(IVMRMonitorConfig *iface, const VMRGUID *pGUID)
1370 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1372 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1374 if (!pGUID)
1375 return E_POINTER;
1377 return S_OK;
1380 static HRESULT WINAPI VMR7MonitorConfig_GetMonitor(IVMRMonitorConfig *iface, 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 pGUID->pGUID = NULL; /* default DirectDraw device */
1390 return S_OK;
1393 static HRESULT WINAPI VMR7MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig *iface,
1394 const VMRGUID *pGUID)
1396 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1398 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1400 if (!pGUID)
1401 return E_POINTER;
1403 return S_OK;
1406 static HRESULT WINAPI VMR7MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig *iface, 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 pGUID->pGUID = NULL; /* default DirectDraw device */
1416 return S_OK;
1419 static HRESULT WINAPI VMR7MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig *iface,
1420 VMRMONITORINFO *info, DWORD arraysize,
1421 DWORD *numdev)
1423 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1424 struct get_available_monitors_args args;
1426 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1428 if (!numdev)
1429 return E_POINTER;
1431 if (info && arraysize == 0)
1432 return E_INVALIDARG;
1434 args.info7 = info;
1435 args.info9 = NULL;
1436 args.arraysize = arraysize;
1437 args.numdev = 0;
1438 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1440 *numdev = args.numdev;
1441 return S_OK;
1444 static const IVMRMonitorConfigVtbl VMR7_MonitorConfig_Vtbl =
1446 VMR7MonitorConfig_QueryInterface,
1447 VMR7MonitorConfig_AddRef,
1448 VMR7MonitorConfig_Release,
1449 VMR7MonitorConfig_SetMonitor,
1450 VMR7MonitorConfig_GetMonitor,
1451 VMR7MonitorConfig_SetDefaultMonitor,
1452 VMR7MonitorConfig_GetDefaultMonitor,
1453 VMR7MonitorConfig_GetAvailableMonitors
1456 static HRESULT WINAPI VMR9MonitorConfig_QueryInterface(IVMRMonitorConfig9 *iface, REFIID riid,
1457 LPVOID * ppv)
1459 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1460 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1463 static ULONG WINAPI VMR9MonitorConfig_AddRef(IVMRMonitorConfig9 *iface)
1465 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1466 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1469 static ULONG WINAPI VMR9MonitorConfig_Release(IVMRMonitorConfig9 *iface)
1471 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1472 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1475 static HRESULT WINAPI VMR9MonitorConfig_SetMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1477 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1479 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1481 return S_OK;
1484 static HRESULT WINAPI VMR9MonitorConfig_GetMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1486 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1488 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1490 if (!uDev)
1491 return E_POINTER;
1493 *uDev = 0;
1494 return S_OK;
1497 static HRESULT WINAPI VMR9MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1499 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1501 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1503 return S_OK;
1506 static HRESULT WINAPI VMR9MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1508 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1510 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1512 if (!uDev)
1513 return E_POINTER;
1515 *uDev = 0;
1516 return S_OK;
1519 static HRESULT WINAPI VMR9MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig9 *iface,
1520 VMR9MonitorInfo *info, DWORD arraysize,
1521 DWORD *numdev)
1523 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1524 struct get_available_monitors_args args;
1526 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1528 if (!numdev)
1529 return E_POINTER;
1531 if (info && arraysize == 0)
1532 return E_INVALIDARG;
1534 args.info7 = NULL;
1535 args.info9 = info;
1536 args.arraysize = arraysize;
1537 args.numdev = 0;
1538 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1540 *numdev = args.numdev;
1541 return S_OK;
1544 static const IVMRMonitorConfig9Vtbl VMR9_MonitorConfig_Vtbl =
1546 VMR9MonitorConfig_QueryInterface,
1547 VMR9MonitorConfig_AddRef,
1548 VMR9MonitorConfig_Release,
1549 VMR9MonitorConfig_SetMonitor,
1550 VMR9MonitorConfig_GetMonitor,
1551 VMR9MonitorConfig_SetDefaultMonitor,
1552 VMR9MonitorConfig_GetDefaultMonitor,
1553 VMR9MonitorConfig_GetAvailableMonitors
1556 static HRESULT WINAPI VMR9FilterConfig_QueryInterface(IVMRFilterConfig9 *iface, REFIID riid, LPVOID * ppv)
1558 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1559 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1562 static ULONG WINAPI VMR9FilterConfig_AddRef(IVMRFilterConfig9 *iface)
1564 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1565 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1568 static ULONG WINAPI VMR9FilterConfig_Release(IVMRFilterConfig9 *iface)
1570 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1571 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1574 static HRESULT WINAPI VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9 *iface, IVMRImageCompositor9 *compositor)
1576 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1578 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
1579 return E_NOTIMPL;
1582 static HRESULT WINAPI VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD max)
1584 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1586 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
1587 return E_NOTIMPL;
1590 static HRESULT WINAPI VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD *max)
1592 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1594 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
1595 return E_NOTIMPL;
1598 static HRESULT WINAPI VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD renderflags)
1600 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1602 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
1603 return E_NOTIMPL;
1606 static HRESULT WINAPI VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD *renderflags)
1608 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1610 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
1611 return E_NOTIMPL;
1614 static HRESULT WINAPI VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 *iface, DWORD mode)
1616 HRESULT hr = S_OK;
1617 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1619 TRACE("(%p/%p)->(%u)\n", iface, This, mode);
1621 EnterCriticalSection(&This->renderer.filter.csFilter);
1622 if (This->mode)
1624 LeaveCriticalSection(&This->renderer.filter.csFilter);
1625 return VFW_E_WRONG_STATE;
1628 if (This->allocator)
1629 IVMRSurfaceAllocatorEx9_Release(This->allocator);
1630 if (This->presenter)
1631 IVMRImagePresenter9_Release(This->presenter);
1633 This->allocator = NULL;
1634 This->presenter = NULL;
1636 switch (mode)
1638 case VMR9Mode_Windowed:
1639 case VMR9Mode_Windowless:
1640 This->allocator_is_ex = 0;
1641 This->cookie = ~0;
1643 hr = VMR9DefaultAllocatorPresenterImpl_create(This, (LPVOID*)&This->presenter);
1644 if (SUCCEEDED(hr))
1645 hr = IVMRImagePresenter9_QueryInterface(This->presenter, &IID_IVMRSurfaceAllocatorEx9, (LPVOID*)&This->allocator);
1646 if (FAILED(hr))
1648 ERR("Unable to find Presenter interface\n");
1649 IVMRImagePresenter9_Release(This->presenter);
1650 This->allocator = NULL;
1651 This->presenter = NULL;
1653 else
1654 hr = IVMRSurfaceAllocatorEx9_AdviseNotify(This->allocator, &This->IVMRSurfaceAllocatorNotify9_iface);
1655 break;
1656 case VMR9Mode_Renderless:
1657 break;
1658 default:
1659 LeaveCriticalSection(&This->renderer.filter.csFilter);
1660 return E_INVALIDARG;
1663 This->mode = mode;
1664 LeaveCriticalSection(&This->renderer.filter.csFilter);
1665 return hr;
1668 static HRESULT WINAPI VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9 *iface, DWORD *mode)
1670 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1672 TRACE("(%p/%p)->(%p) stub\n", iface, This, mode);
1673 if (!mode)
1674 return E_POINTER;
1676 if (This->mode)
1677 *mode = This->mode;
1678 else
1679 *mode = VMR9Mode_Windowed;
1681 return S_OK;
1684 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl =
1686 VMR9FilterConfig_QueryInterface,
1687 VMR9FilterConfig_AddRef,
1688 VMR9FilterConfig_Release,
1689 VMR9FilterConfig_SetImageCompositor,
1690 VMR9FilterConfig_SetNumberOfStreams,
1691 VMR9FilterConfig_GetNumberOfStreams,
1692 VMR9FilterConfig_SetRenderingPrefs,
1693 VMR9FilterConfig_GetRenderingPrefs,
1694 VMR9FilterConfig_SetRenderingMode,
1695 VMR9FilterConfig_GetRenderingMode
1698 static HRESULT WINAPI VMR7WindowlessControl_QueryInterface(IVMRWindowlessControl *iface, REFIID riid,
1699 LPVOID * ppv)
1701 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1702 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1705 static ULONG WINAPI VMR7WindowlessControl_AddRef(IVMRWindowlessControl *iface)
1707 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1708 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1711 static ULONG WINAPI VMR7WindowlessControl_Release(IVMRWindowlessControl *iface)
1713 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1714 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1717 static HRESULT WINAPI VMR7WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl *iface,
1718 LONG *width, LONG *height,
1719 LONG *arwidth, LONG *arheight)
1721 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1722 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1724 if (!width || !height || !arwidth || !arheight)
1726 ERR("Got no pointer\n");
1727 return E_POINTER;
1730 *width = This->bmiheader.biWidth;
1731 *height = This->bmiheader.biHeight;
1732 *arwidth = This->bmiheader.biWidth;
1733 *arheight = This->bmiheader.biHeight;
1735 return S_OK;
1738 static HRESULT WINAPI VMR7WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl *iface,
1739 LONG *width, LONG *height)
1741 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1743 FIXME("(%p/%p)->(...) stub\n", iface, This);
1744 return E_NOTIMPL;
1747 static HRESULT WINAPI VMR7WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl *iface,
1748 LONG *width, LONG *height)
1750 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1752 FIXME("(%p/%p)->(...) stub\n", iface, This);
1753 return E_NOTIMPL;
1756 static HRESULT WINAPI VMR7WindowlessControl_SetVideoPosition(IVMRWindowlessControl *iface,
1757 const RECT *source, const RECT *dest)
1759 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1761 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1763 EnterCriticalSection(&This->renderer.filter.csFilter);
1765 if (source)
1766 This->source_rect = *source;
1767 if (dest)
1769 This->target_rect = *dest;
1770 if (This->baseControlWindow.baseWindow.hWnd)
1772 FIXME("Output rectangle: %s\n", wine_dbgstr_rect(dest));
1773 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
1774 dest->left, dest->top, dest->right - dest->left, dest->bottom-dest->top,
1775 SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW);
1779 LeaveCriticalSection(&This->renderer.filter.csFilter);
1781 return S_OK;
1784 static HRESULT WINAPI VMR7WindowlessControl_GetVideoPosition(IVMRWindowlessControl *iface,
1785 RECT *source, RECT *dest)
1787 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1789 if (source)
1790 *source = This->source_rect;
1792 if (dest)
1793 *dest = This->target_rect;
1795 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
1796 return S_OK;
1799 static HRESULT WINAPI VMR7WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl *iface,
1800 DWORD *mode)
1802 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1804 FIXME("(%p/%p)->(...) stub\n", iface, This);
1805 return E_NOTIMPL;
1808 static HRESULT WINAPI VMR7WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl *iface,
1809 DWORD mode)
1811 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1813 FIXME("(%p/%p)->(...) stub\n", iface, This);
1814 return E_NOTIMPL;
1817 static HRESULT WINAPI VMR7WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl *iface,
1818 HWND hwnd)
1820 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1822 FIXME("(%p/%p)->(...) stub\n", iface, This);
1823 return E_NOTIMPL;
1826 static HRESULT WINAPI VMR7WindowlessControl_RepaintVideo(IVMRWindowlessControl *iface,
1827 HWND hwnd, HDC hdc)
1829 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1831 FIXME("(%p/%p)->(...) stub\n", iface, This);
1832 return E_NOTIMPL;
1835 static HRESULT WINAPI VMR7WindowlessControl_DisplayModeChanged(IVMRWindowlessControl *iface)
1837 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1839 FIXME("(%p/%p)->(...) stub\n", iface, This);
1840 return E_NOTIMPL;
1843 static HRESULT WINAPI VMR7WindowlessControl_GetCurrentImage(IVMRWindowlessControl *iface,
1844 BYTE **dib)
1846 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1848 FIXME("(%p/%p)->(...) stub\n", iface, This);
1849 return E_NOTIMPL;
1852 static HRESULT WINAPI VMR7WindowlessControl_SetBorderColor(IVMRWindowlessControl *iface,
1853 COLORREF color)
1855 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1857 FIXME("(%p/%p)->(...) stub\n", iface, This);
1858 return E_NOTIMPL;
1861 static HRESULT WINAPI VMR7WindowlessControl_GetBorderColor(IVMRWindowlessControl *iface,
1862 COLORREF *color)
1864 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1866 FIXME("(%p/%p)->(...) stub\n", iface, This);
1867 return E_NOTIMPL;
1870 static HRESULT WINAPI VMR7WindowlessControl_SetColorKey(IVMRWindowlessControl *iface, COLORREF color)
1872 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1874 FIXME("(%p/%p)->(...) stub\n", iface, This);
1875 return E_NOTIMPL;
1878 static HRESULT WINAPI VMR7WindowlessControl_GetColorKey(IVMRWindowlessControl *iface, COLORREF *color)
1880 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1882 FIXME("(%p/%p)->(...) stub\n", iface, This);
1883 return E_NOTIMPL;
1886 static const IVMRWindowlessControlVtbl VMR7_WindowlessControl_Vtbl =
1888 VMR7WindowlessControl_QueryInterface,
1889 VMR7WindowlessControl_AddRef,
1890 VMR7WindowlessControl_Release,
1891 VMR7WindowlessControl_GetNativeVideoSize,
1892 VMR7WindowlessControl_GetMinIdealVideoSize,
1893 VMR7WindowlessControl_GetMaxIdealVideoSize,
1894 VMR7WindowlessControl_SetVideoPosition,
1895 VMR7WindowlessControl_GetVideoPosition,
1896 VMR7WindowlessControl_GetAspectRatioMode,
1897 VMR7WindowlessControl_SetAspectRatioMode,
1898 VMR7WindowlessControl_SetVideoClippingWindow,
1899 VMR7WindowlessControl_RepaintVideo,
1900 VMR7WindowlessControl_DisplayModeChanged,
1901 VMR7WindowlessControl_GetCurrentImage,
1902 VMR7WindowlessControl_SetBorderColor,
1903 VMR7WindowlessControl_GetBorderColor,
1904 VMR7WindowlessControl_SetColorKey,
1905 VMR7WindowlessControl_GetColorKey
1908 static HRESULT WINAPI VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9 *iface, REFIID riid, LPVOID * ppv)
1910 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1911 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1914 static ULONG WINAPI VMR9WindowlessControl_AddRef(IVMRWindowlessControl9 *iface)
1916 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1917 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1920 static ULONG WINAPI VMR9WindowlessControl_Release(IVMRWindowlessControl9 *iface)
1922 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1923 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1926 static HRESULT WINAPI VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height, LONG *arwidth, LONG *arheight)
1928 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1929 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1931 if (!width || !height || !arwidth || !arheight)
1933 ERR("Got no pointer\n");
1934 return E_POINTER;
1937 *width = This->bmiheader.biWidth;
1938 *height = This->bmiheader.biHeight;
1939 *arwidth = This->bmiheader.biWidth;
1940 *arheight = This->bmiheader.biHeight;
1942 return S_OK;
1945 static HRESULT WINAPI VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1947 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1949 FIXME("(%p/%p)->(...) stub\n", iface, This);
1950 return E_NOTIMPL;
1953 static HRESULT WINAPI VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1955 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1957 FIXME("(%p/%p)->(...) stub\n", iface, This);
1958 return E_NOTIMPL;
1961 static HRESULT WINAPI VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9 *iface, const RECT *source, const RECT *dest)
1963 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1965 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1967 EnterCriticalSection(&This->renderer.filter.csFilter);
1969 if (source)
1970 This->source_rect = *source;
1971 if (dest)
1973 This->target_rect = *dest;
1974 if (This->baseControlWindow.baseWindow.hWnd)
1976 FIXME("Output rectangle: %s\n", wine_dbgstr_rect(dest));
1977 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, dest->left, dest->top, dest->right - dest->left,
1978 dest->bottom-dest->top, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW);
1982 LeaveCriticalSection(&This->renderer.filter.csFilter);
1984 return S_OK;
1987 static HRESULT WINAPI VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9 *iface, RECT *source, RECT *dest)
1989 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1991 if (source)
1992 *source = This->source_rect;
1994 if (dest)
1995 *dest = This->target_rect;
1997 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
1998 return S_OK;
2001 static HRESULT WINAPI VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD *mode)
2003 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2005 FIXME("(%p/%p)->(...) stub\n", iface, This);
2006 return E_NOTIMPL;
2009 static HRESULT WINAPI VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD mode)
2011 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2013 FIXME("(%p/%p)->(...) stub\n", iface, This);
2014 return E_NOTIMPL;
2017 static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9 *iface, HWND hwnd)
2019 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2021 TRACE("(%p/%p)->(%p)\n", iface, This, hwnd);
2023 EnterCriticalSection(&This->renderer.filter.csFilter);
2024 This->hWndClippingWindow = hwnd;
2025 VMR9_maybe_init(This, FALSE);
2026 if (!hwnd)
2027 IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie);
2028 LeaveCriticalSection(&This->renderer.filter.csFilter);
2029 return S_OK;
2032 static HRESULT WINAPI VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9 *iface, HWND hwnd, HDC hdc)
2034 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2035 HRESULT hr;
2037 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2039 EnterCriticalSection(&This->renderer.filter.csFilter);
2040 if (hwnd != This->hWndClippingWindow && hwnd != This->baseControlWindow.baseWindow.hWnd)
2042 ERR("Not handling changing windows yet!!!\n");
2043 LeaveCriticalSection(&This->renderer.filter.csFilter);
2044 return S_OK;
2047 if (!This->allocator_d3d9_dev)
2049 ERR("No d3d9 device!\n");
2050 LeaveCriticalSection(&This->renderer.filter.csFilter);
2051 return VFW_E_WRONG_STATE;
2054 /* Windowless extension */
2055 hr = IDirect3DDevice9_Present(This->allocator_d3d9_dev, NULL, NULL, This->baseControlWindow.baseWindow.hWnd, NULL);
2056 LeaveCriticalSection(&This->renderer.filter.csFilter);
2058 return hr;
2061 static HRESULT WINAPI VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9 *iface)
2063 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2065 FIXME("(%p/%p)->(...) stub\n", iface, This);
2066 return E_NOTIMPL;
2069 static HRESULT WINAPI VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9 *iface, BYTE **dib)
2071 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2073 FIXME("(%p/%p)->(...) stub\n", iface, This);
2074 return E_NOTIMPL;
2077 static HRESULT WINAPI VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9 *iface, COLORREF color)
2079 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2081 FIXME("(%p/%p)->(...) stub\n", iface, This);
2082 return E_NOTIMPL;
2085 static HRESULT WINAPI VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9 *iface, COLORREF *color)
2087 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2089 FIXME("(%p/%p)->(...) stub\n", iface, This);
2090 return E_NOTIMPL;
2093 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl =
2095 VMR9WindowlessControl_QueryInterface,
2096 VMR9WindowlessControl_AddRef,
2097 VMR9WindowlessControl_Release,
2098 VMR9WindowlessControl_GetNativeVideoSize,
2099 VMR9WindowlessControl_GetMinIdealVideoSize,
2100 VMR9WindowlessControl_GetMaxIdealVideoSize,
2101 VMR9WindowlessControl_SetVideoPosition,
2102 VMR9WindowlessControl_GetVideoPosition,
2103 VMR9WindowlessControl_GetAspectRatioMode,
2104 VMR9WindowlessControl_SetAspectRatioMode,
2105 VMR9WindowlessControl_SetVideoClippingWindow,
2106 VMR9WindowlessControl_RepaintVideo,
2107 VMR9WindowlessControl_DisplayModeChanged,
2108 VMR9WindowlessControl_GetCurrentImage,
2109 VMR9WindowlessControl_SetBorderColor,
2110 VMR9WindowlessControl_GetBorderColor
2113 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify *iface,
2114 REFIID riid, LPVOID * ppv)
2116 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2117 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
2120 static ULONG WINAPI VMR7SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify *iface)
2122 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2123 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
2126 static ULONG WINAPI VMR7SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify *iface)
2128 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2129 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
2132 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify *iface,
2133 DWORD_PTR id,
2134 IVMRSurfaceAllocator *alloc)
2136 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2138 FIXME("(%p/%p)->(...) stub\n", iface, This);
2139 return E_NOTIMPL;
2142 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
2143 IDirectDraw7 *device, HMONITOR monitor)
2145 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2147 FIXME("(%p/%p)->(...) stub\n", iface, This);
2148 return E_NOTIMPL;
2151 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_ChangeDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
2152 IDirectDraw7 *device, HMONITOR monitor)
2154 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2156 FIXME("(%p/%p)->(...) stub\n", iface, This);
2157 return E_NOTIMPL;
2160 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces(IVMRSurfaceAllocatorNotify *iface)
2162 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2164 FIXME("(%p/%p)->(...) stub\n", iface, This);
2165 return E_NOTIMPL;
2168 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify *iface, LONG code,
2169 LONG_PTR param1, LONG_PTR param2)
2171 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2173 FIXME("(%p/%p)->(...) stub\n", iface, This);
2174 return E_NOTIMPL;
2177 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetBorderColor(IVMRSurfaceAllocatorNotify *iface,
2178 COLORREF clrBorder)
2180 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2182 FIXME("(%p/%p)->(...) stub\n", iface, This);
2183 return E_NOTIMPL;
2186 static const IVMRSurfaceAllocatorNotifyVtbl VMR7_SurfaceAllocatorNotify_Vtbl =
2188 VMR7SurfaceAllocatorNotify_QueryInterface,
2189 VMR7SurfaceAllocatorNotify_AddRef,
2190 VMR7SurfaceAllocatorNotify_Release,
2191 VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator,
2192 VMR7SurfaceAllocatorNotify_SetDDrawDevice,
2193 VMR7SurfaceAllocatorNotify_ChangeDDrawDevice,
2194 VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces,
2195 VMR7SurfaceAllocatorNotify_NotifyEvent,
2196 VMR7SurfaceAllocatorNotify_SetBorderColor
2199 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9 *iface, REFIID riid, LPVOID * ppv)
2201 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2202 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
2205 static ULONG WINAPI VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9 *iface)
2207 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2208 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
2211 static ULONG WINAPI VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9 *iface)
2213 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2214 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
2217 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9 *iface, DWORD_PTR id, IVMRSurfaceAllocator9 *alloc)
2219 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2221 /* FIXME: This code is not tested!!! */
2222 FIXME("(%p/%p)->(...) stub\n", iface, This);
2223 This->cookie = id;
2225 if (This->presenter)
2226 return VFW_E_WRONG_STATE;
2228 if (FAILED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRImagePresenter9, (void **)&This->presenter)))
2229 return E_NOINTERFACE;
2231 if (SUCCEEDED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRSurfaceAllocatorEx9, (void **)&This->allocator)))
2232 This->allocator_is_ex = 1;
2233 else
2235 This->allocator = (IVMRSurfaceAllocatorEx9 *)alloc;
2236 IVMRSurfaceAllocator9_AddRef(alloc);
2237 This->allocator_is_ex = 0;
2240 return S_OK;
2243 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
2245 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2247 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2248 if (This->allocator_d3d9_dev)
2249 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
2250 This->allocator_d3d9_dev = device;
2251 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
2252 This->allocator_mon = monitor;
2254 return S_OK;
2257 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
2259 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2261 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2262 if (This->allocator_d3d9_dev)
2263 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
2264 This->allocator_d3d9_dev = device;
2265 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
2266 This->allocator_mon = monitor;
2268 return S_OK;
2271 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9 *iface, VMR9AllocationInfo *allocinfo, DWORD *numbuffers, IDirect3DSurface9 **surface)
2273 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2274 DWORD i;
2275 HRESULT hr = S_OK;
2277 FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface, This, allocinfo, numbuffers, (numbuffers ? *numbuffers : 0), surface);
2279 if (!allocinfo || !numbuffers || !surface)
2280 return E_POINTER;
2282 if (!*numbuffers || *numbuffers < allocinfo->MinBuffers)
2284 ERR("Invalid number of buffers?\n");
2285 return E_INVALIDARG;
2288 if (!This->allocator_d3d9_dev)
2290 ERR("No direct3d device when requested to allocate a surface!\n");
2291 return VFW_E_WRONG_STATE;
2294 if (allocinfo->dwFlags & VMR9AllocFlag_OffscreenSurface)
2296 ERR("Creating offscreen surface\n");
2297 for (i = 0; i < *numbuffers; ++i)
2299 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight,
2300 allocinfo->Format, allocinfo->Pool, &surface[i], NULL);
2301 if (FAILED(hr))
2302 break;
2305 else if (allocinfo->dwFlags & VMR9AllocFlag_TextureSurface)
2307 TRACE("Creating texture surface\n");
2308 for (i = 0; i < *numbuffers; ++i)
2310 IDirect3DTexture9 *texture;
2312 hr = IDirect3DDevice9_CreateTexture(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight, 1, 0,
2313 allocinfo->Format, allocinfo->Pool, &texture, NULL);
2314 if (FAILED(hr))
2315 break;
2316 IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface[i]);
2317 IDirect3DTexture9_Release(texture);
2320 else
2322 FIXME("Could not allocate for type %08x\n", allocinfo->dwFlags);
2323 return E_NOTIMPL;
2326 if (i >= allocinfo->MinBuffers)
2328 hr = S_OK;
2329 *numbuffers = i;
2331 else
2333 for ( ; i > 0; --i) IDirect3DSurface9_Release(surface[i - 1]);
2334 *numbuffers = 0;
2336 return hr;
2339 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9 *iface, LONG code, LONG_PTR param1, LONG_PTR param2)
2341 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2343 FIXME("(%p/%p)->(...) stub\n", iface, This);
2344 return E_NOTIMPL;
2347 static const IVMRSurfaceAllocatorNotify9Vtbl VMR9_SurfaceAllocatorNotify_Vtbl =
2349 VMR9SurfaceAllocatorNotify_QueryInterface,
2350 VMR9SurfaceAllocatorNotify_AddRef,
2351 VMR9SurfaceAllocatorNotify_Release,
2352 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator,
2353 VMR9SurfaceAllocatorNotify_SetD3DDevice,
2354 VMR9SurfaceAllocatorNotify_ChangeD3DDevice,
2355 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper,
2356 VMR9SurfaceAllocatorNotify_NotifyEvent
2359 static HRESULT vmr_create(IUnknown *outer_unk, LPVOID *ppv, const CLSID *clsid)
2361 HRESULT hr;
2362 struct quartz_vmr* pVMR;
2364 TRACE("(%p, %p)\n", outer_unk, ppv);
2366 *ppv = NULL;
2368 pVMR = CoTaskMemAlloc(sizeof(struct quartz_vmr));
2370 pVMR->hD3d9 = LoadLibraryA("d3d9.dll");
2371 if (!pVMR->hD3d9 )
2373 WARN("Could not load d3d9.dll\n");
2374 CoTaskMemFree(pVMR);
2375 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
2378 pVMR->outer_unk = outer_unk;
2379 pVMR->bUnkOuterValid = FALSE;
2380 pVMR->bAggregatable = FALSE;
2381 pVMR->IUnknown_inner.lpVtbl = &IInner_VTable;
2382 pVMR->IAMCertifiedOutputProtection_iface.lpVtbl = &IAMCertifiedOutputProtection_Vtbl;
2383 pVMR->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl;
2385 pVMR->mode = 0;
2386 pVMR->allocator_d3d9_dev = NULL;
2387 pVMR->allocator_mon= NULL;
2388 pVMR->num_surfaces = pVMR->cur_surface = 0;
2389 pVMR->allocator = NULL;
2390 pVMR->presenter = NULL;
2391 pVMR->hWndClippingWindow = NULL;
2392 pVMR->IVMRFilterConfig_iface.lpVtbl = &VMR7_FilterConfig_Vtbl;
2393 pVMR->IVMRFilterConfig9_iface.lpVtbl = &VMR9_FilterConfig_Vtbl;
2394 pVMR->IVMRMonitorConfig_iface.lpVtbl = &VMR7_MonitorConfig_Vtbl;
2395 pVMR->IVMRMonitorConfig9_iface.lpVtbl = &VMR9_MonitorConfig_Vtbl;
2396 pVMR->IVMRSurfaceAllocatorNotify_iface.lpVtbl = &VMR7_SurfaceAllocatorNotify_Vtbl;
2397 pVMR->IVMRSurfaceAllocatorNotify9_iface.lpVtbl = &VMR9_SurfaceAllocatorNotify_Vtbl;
2398 pVMR->IVMRWindowlessControl_iface.lpVtbl = &VMR7_WindowlessControl_Vtbl;
2399 pVMR->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl;
2401 if (IsEqualGUID(clsid, &CLSID_VideoMixingRenderer))
2402 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer,
2403 (DWORD_PTR)(__FILE__ ": VMR7Impl.csFilter"), &BaseFuncTable);
2404 else
2405 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer9,
2406 (DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable);
2408 if (FAILED(hr))
2409 goto fail;
2411 hr = BaseControlWindow_Init(&pVMR->baseControlWindow, &IVideoWindow_VTable, &pVMR->renderer.filter,
2412 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin,
2413 &renderer_BaseWindowFuncTable);
2414 if (FAILED(hr))
2415 goto fail;
2417 hr = BaseControlVideo_Init(&pVMR->baseControlVideo, &IBasicVideo_VTable, &pVMR->renderer.filter,
2418 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin,
2419 &renderer_BaseControlVideoFuncTable);
2420 if (FAILED(hr))
2421 goto fail;
2423 *ppv = (LPVOID)pVMR;
2424 ZeroMemory(&pVMR->source_rect, sizeof(RECT));
2425 ZeroMemory(&pVMR->target_rect, sizeof(RECT));
2426 TRACE("Created at %p\n", pVMR);
2427 return hr;
2429 fail:
2430 BaseRendererImpl_Release(&pVMR->renderer.filter.IBaseFilter_iface);
2431 FreeLibrary(pVMR->hD3d9);
2432 CoTaskMemFree(pVMR);
2433 return hr;
2436 HRESULT VMR7Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2438 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer);
2441 HRESULT VMR9Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2443 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer9);
2447 static HRESULT WINAPI VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID riid, LPVOID * ppv)
2449 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2450 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
2452 *ppv = NULL;
2454 if (IsEqualIID(riid, &IID_IUnknown))
2455 *ppv = (LPVOID)&(This->IVMRImagePresenter9_iface);
2456 else if (IsEqualIID(riid, &IID_IVMRImagePresenter9))
2457 *ppv = &This->IVMRImagePresenter9_iface;
2458 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorEx9))
2459 *ppv = &This->IVMRSurfaceAllocatorEx9_iface;
2461 if (*ppv)
2463 IUnknown_AddRef((IUnknown *)(*ppv));
2464 return S_OK;
2467 FIXME("No interface for %s\n", debugstr_guid(riid));
2469 return E_NOINTERFACE;
2472 static ULONG WINAPI VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 *iface)
2474 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2475 ULONG refCount = InterlockedIncrement(&This->refCount);
2477 TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
2479 return refCount;
2482 static ULONG WINAPI VMR9_ImagePresenter_Release(IVMRImagePresenter9 *iface)
2484 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2485 ULONG refCount = InterlockedDecrement(&This->refCount);
2487 TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
2489 if (!refCount)
2491 DWORD i;
2492 TRACE("Destroying\n");
2493 CloseHandle(This->ack);
2494 IDirect3D9_Release(This->d3d9_ptr);
2496 TRACE("Number of surfaces: %u\n", This->num_surfaces);
2497 for (i = 0; i < This->num_surfaces; ++i)
2499 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2500 TRACE("Releasing surface %p\n", surface);
2501 if (surface)
2502 IDirect3DSurface9_Release(surface);
2505 CoTaskMemFree(This->d3d9_surfaces);
2506 This->d3d9_surfaces = NULL;
2507 This->num_surfaces = 0;
2508 if (This->d3d9_vertex)
2510 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2511 This->d3d9_vertex = NULL;
2513 CoTaskMemFree(This);
2514 return 0;
2516 return refCount;
2519 static HRESULT WINAPI VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2521 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2523 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2524 return S_OK;
2527 static HRESULT WINAPI VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2529 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2531 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2532 return S_OK;
2535 #define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
2536 struct VERTEX { float x, y, z, rhw, u, v; };
2538 static HRESULT VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2540 IDirect3DTexture9 *texture = NULL;
2541 HRESULT hr;
2543 hr = IDirect3DDevice9_SetFVF(This->d3d9_dev, USED_FVF);
2544 if (FAILED(hr))
2546 FIXME("SetFVF: %08x\n", hr);
2547 return hr;
2550 hr = IDirect3DDevice9_SetStreamSource(This->d3d9_dev, 0, This->d3d9_vertex, 0, sizeof(struct VERTEX));
2551 if (FAILED(hr))
2553 FIXME("SetStreamSource: %08x\n", hr);
2554 return hr;
2557 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **) &texture);
2558 if (FAILED(hr))
2560 FIXME("IDirect3DSurface9_GetContainer failed\n");
2561 return hr;
2563 hr = IDirect3DDevice9_SetTexture(This->d3d9_dev, 0, (IDirect3DBaseTexture9 *)texture);
2564 IDirect3DTexture9_Release(texture);
2565 if (FAILED(hr))
2567 FIXME("SetTexture: %08x\n", hr);
2568 return hr;
2571 hr = IDirect3DDevice9_DrawPrimitive(This->d3d9_dev, D3DPT_TRIANGLESTRIP, 0, 2);
2572 if (FAILED(hr))
2574 FIXME("DrawPrimitive: %08x\n", hr);
2575 return hr;
2578 return S_OK;
2581 static HRESULT VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2583 HRESULT hr;
2584 IDirect3DSurface9 *target = NULL;
2585 RECT target_rect;
2587 hr = IDirect3DDevice9_GetBackBuffer(This->d3d9_dev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &target);
2588 if (FAILED(hr))
2590 ERR("IDirect3DDevice9_GetBackBuffer -- %08x\n", hr);
2591 return hr;
2594 /* Move rect to origin and flip it */
2595 SetRect(&target_rect, 0, This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top,
2596 This->pVMR9->target_rect.right - This->pVMR9->target_rect.left, 0);
2598 hr = IDirect3DDevice9_StretchRect(This->d3d9_dev, surface, &This->pVMR9->source_rect, target, &target_rect, D3DTEXF_LINEAR);
2599 if (FAILED(hr))
2600 ERR("IDirect3DDevice9_StretchRect -- %08x\n", hr);
2601 IDirect3DSurface9_Release(target);
2603 return hr;
2606 static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR id, VMR9PresentationInfo *info)
2608 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2609 HRESULT hr;
2610 RECT output;
2611 BOOL render = FALSE;
2613 TRACE("(%p/%p/%p)->(...) stub\n", iface, This, This->pVMR9);
2614 GetWindowRect(This->pVMR9->baseControlWindow.baseWindow.hWnd, &output);
2615 TRACE("Output rectangle: %s\n", wine_dbgstr_rect(&output));
2617 /* This might happen if we don't have active focus (eg on a different virtual desktop) */
2618 if (!This->d3d9_dev)
2619 return S_OK;
2621 /* Display image here */
2622 hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
2623 if (FAILED(hr))
2624 FIXME("hr: %08x\n", hr);
2625 hr = IDirect3DDevice9_BeginScene(This->d3d9_dev);
2626 if (SUCCEEDED(hr))
2628 if (This->d3d9_vertex)
2629 hr = VMR9_ImagePresenter_PresentTexture(This, info->lpSurf);
2630 else
2631 hr = VMR9_ImagePresenter_PresentOffscreenSurface(This, info->lpSurf);
2632 render = SUCCEEDED(hr);
2634 else
2635 FIXME("BeginScene: %08x\n", hr);
2636 hr = IDirect3DDevice9_EndScene(This->d3d9_dev);
2637 if (render && SUCCEEDED(hr))
2639 hr = IDirect3DDevice9_Present(This->d3d9_dev, NULL, NULL, This->pVMR9->baseControlWindow.baseWindow.hWnd, NULL);
2640 if (FAILED(hr))
2641 FIXME("Presenting image: %08x\n", hr);
2644 return S_OK;
2647 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter =
2649 VMR9_ImagePresenter_QueryInterface,
2650 VMR9_ImagePresenter_AddRef,
2651 VMR9_ImagePresenter_Release,
2652 VMR9_ImagePresenter_StartPresenting,
2653 VMR9_ImagePresenter_StopPresenting,
2654 VMR9_ImagePresenter_PresentImage
2657 static HRESULT WINAPI VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9 *iface, REFIID riid, LPVOID * ppv)
2659 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2661 return VMR9_ImagePresenter_QueryInterface(&This->IVMRImagePresenter9_iface, riid, ppv);
2664 static ULONG WINAPI VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9 *iface)
2666 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2668 return VMR9_ImagePresenter_AddRef(&This->IVMRImagePresenter9_iface);
2671 static ULONG WINAPI VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9 *iface)
2673 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2675 return VMR9_ImagePresenter_Release(&This->IVMRImagePresenter9_iface);
2678 static HRESULT VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *allocinfo)
2680 D3DCAPS9 caps;
2681 UINT width, height;
2682 HRESULT hr;
2684 if (!(allocinfo->dwFlags & VMR9AllocFlag_TextureSurface))
2685 /* Only needed for texture surfaces */
2686 return S_OK;
2688 hr = IDirect3DDevice9_GetDeviceCaps(This->d3d9_dev, &caps);
2689 if (FAILED(hr))
2690 return hr;
2692 if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2) || (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY))
2694 width = allocinfo->dwWidth;
2695 height = allocinfo->dwHeight;
2697 else
2699 width = height = 1;
2700 while (width < allocinfo->dwWidth)
2701 width *= 2;
2703 while (height < allocinfo->dwHeight)
2704 height *= 2;
2705 FIXME("NPOW2 support missing, not using proper surfaces!\n");
2708 if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
2710 if (height > width)
2711 width = height;
2712 else
2713 height = width;
2714 FIXME("Square texture support required..\n");
2717 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF, allocinfo->Pool, &This->d3d9_vertex, NULL);
2718 if (FAILED(hr))
2720 ERR("Couldn't create vertex buffer: %08x\n", hr);
2721 return hr;
2724 This->reset = TRUE;
2725 allocinfo->dwHeight = height;
2726 allocinfo->dwWidth = width;
2728 return hr;
2731 static DWORD WINAPI MessageLoop(LPVOID lpParameter)
2733 MSG msg;
2734 BOOL fGotMessage;
2735 VMR9DefaultAllocatorPresenterImpl *This = lpParameter;
2737 TRACE("Starting message loop\n");
2739 if (FAILED(BaseWindowImpl_PrepareWindow(&This->pVMR9->baseControlWindow.baseWindow)))
2741 FIXME("Failed to prepare window\n");
2742 return FALSE;
2745 SetEvent(This->ack);
2746 while ((fGotMessage = GetMessageW(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1)
2748 TranslateMessage(&msg);
2749 DispatchMessageW(&msg);
2752 TRACE("End of message loop\n");
2754 return 0;
2757 static UINT d3d9_adapter_from_hwnd(IDirect3D9 *d3d9, HWND hwnd, HMONITOR *mon_out)
2759 UINT d3d9_adapter;
2760 HMONITOR mon;
2762 mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
2763 if (!mon)
2764 d3d9_adapter = 0;
2765 else
2767 for (d3d9_adapter = 0; d3d9_adapter < IDirect3D9_GetAdapterCount(d3d9); ++d3d9_adapter)
2769 if (mon == IDirect3D9_GetAdapterMonitor(d3d9, d3d9_adapter))
2770 break;
2772 if (d3d9_adapter >= IDirect3D9_GetAdapterCount(d3d9))
2773 d3d9_adapter = 0;
2775 if (mon_out)
2776 *mon_out = mon;
2777 return d3d9_adapter;
2780 static BOOL CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *info, DWORD *numbuffers)
2782 D3DPRESENT_PARAMETERS d3dpp;
2783 DWORD d3d9_adapter;
2784 HRESULT hr;
2786 TRACE("(%p)->()\n", This);
2788 This->hWndThread = CreateThread(NULL, 0, MessageLoop, This, 0, &This->tid);
2789 if (!This->hWndThread)
2790 return FALSE;
2792 WaitForSingleObject(This->ack, INFINITE);
2794 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) return FALSE;
2796 /* Obtain a monitor and d3d9 device */
2797 d3d9_adapter = d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon);
2799 /* Now try to create the d3d9 device */
2800 ZeroMemory(&d3dpp, sizeof(d3dpp));
2801 d3dpp.Windowed = TRUE;
2802 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2803 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2804 d3dpp.BackBufferHeight = This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top;
2805 d3dpp.BackBufferWidth = This->pVMR9->target_rect.right - This->pVMR9->target_rect.left;
2807 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev);
2808 if (FAILED(hr))
2810 ERR("Could not create device: %08x\n", hr);
2811 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2812 return FALSE;
2814 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2816 This->d3d9_surfaces = CoTaskMemAlloc(*numbuffers * sizeof(IDirect3DSurface9 *));
2817 ZeroMemory(This->d3d9_surfaces, *numbuffers * sizeof(IDirect3DSurface9 *));
2819 hr = VMR9_SurfaceAllocator_SetAllocationSettings(This, info);
2820 if (FAILED(hr))
2821 ERR("Setting allocation settings failed: %08x\n", hr);
2823 if (SUCCEEDED(hr))
2825 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, info, numbuffers, This->d3d9_surfaces);
2826 if (FAILED(hr))
2827 ERR("Allocating surfaces failed: %08x\n", hr);
2830 if (FAILED(hr))
2832 IVMRSurfaceAllocatorEx9_TerminateDevice(This->pVMR9->allocator, This->pVMR9->cookie);
2833 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2834 return FALSE;
2837 This->num_surfaces = *numbuffers;
2839 return TRUE;
2842 static HRESULT WINAPI VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, VMR9AllocationInfo *allocinfo, DWORD *numbuffers)
2844 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2846 if (This->pVMR9->mode != VMR9Mode_Windowed && !This->pVMR9->hWndClippingWindow)
2848 ERR("No window set\n");
2849 return VFW_E_WRONG_STATE;
2852 This->info = *allocinfo;
2854 if (!CreateRenderingWindow(This, allocinfo, numbuffers))
2856 ERR("Failed to create rendering window, expect no output!\n");
2857 return VFW_E_WRONG_STATE;
2860 return S_OK;
2863 static HRESULT WINAPI VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id)
2865 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2867 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
2869 return S_OK;
2872 SendMessageW(This->pVMR9->baseControlWindow.baseWindow.hWnd, WM_CLOSE, 0, 0);
2873 PostThreadMessageW(This->tid, WM_QUIT, 0, 0);
2874 WaitForSingleObject(This->hWndThread, INFINITE);
2875 This->hWndThread = NULL;
2876 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2878 return S_OK;
2881 /* Recreate all surfaces (If allocated as D3DPOOL_DEFAULT) and survive! */
2882 static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl *This)
2884 struct VERTEX t_vert[4];
2885 UINT width, height;
2886 unsigned int i;
2887 void *bits = NULL;
2888 D3DPRESENT_PARAMETERS d3dpp;
2889 HRESULT hr;
2891 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
2893 ERR("No window\n");
2894 return E_FAIL;
2897 if (!This->d3d9_surfaces || !This->reset)
2898 return S_OK;
2900 This->reset = FALSE;
2901 TRACE("RESETTING\n");
2902 if (This->d3d9_vertex)
2904 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2905 This->d3d9_vertex = NULL;
2908 for (i = 0; i < This->num_surfaces; ++i)
2910 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2911 TRACE("Releasing surface %p\n", surface);
2912 if (surface)
2913 IDirect3DSurface9_Release(surface);
2915 ZeroMemory(This->d3d9_surfaces, sizeof(IDirect3DSurface9 *) * This->num_surfaces);
2917 /* Now try to create the d3d9 device */
2918 ZeroMemory(&d3dpp, sizeof(d3dpp));
2919 d3dpp.Windowed = TRUE;
2920 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2921 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2923 if (This->d3d9_dev)
2924 IDirect3DDevice9_Release(This->d3d9_dev);
2925 This->d3d9_dev = NULL;
2926 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);
2927 if (FAILED(hr))
2929 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);
2930 if (FAILED(hr))
2932 ERR("--> Creating device: %08x\n", hr);
2933 return S_OK;
2936 IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2938 IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, &This->info, &This->num_surfaces, This->d3d9_surfaces);
2940 This->reset = FALSE;
2942 if (!(This->info.dwFlags & VMR9AllocFlag_TextureSurface))
2943 return S_OK;
2945 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF,
2946 This->info.Pool, &This->d3d9_vertex, NULL);
2948 width = This->info.dwWidth;
2949 height = This->info.dwHeight;
2951 for (i = 0; i < sizeof(t_vert) / sizeof(t_vert[0]); ++i)
2953 if (i % 2)
2955 t_vert[i].x = (float)This->pVMR9->target_rect.right - (float)This->pVMR9->target_rect.left - 0.5f;
2956 t_vert[i].u = (float)This->pVMR9->source_rect.right / (float)width;
2958 else
2960 t_vert[i].x = -0.5f;
2961 t_vert[i].u = (float)This->pVMR9->source_rect.left / (float)width;
2964 if (i % 4 < 2)
2966 t_vert[i].y = -0.5f;
2967 t_vert[i].v = (float)This->pVMR9->source_rect.bottom / (float)height;
2969 else
2971 t_vert[i].y = (float)This->pVMR9->target_rect.bottom - (float)This->pVMR9->target_rect.top - 0.5f;
2972 t_vert[i].v = (float)This->pVMR9->source_rect.top / (float)height;
2974 t_vert[i].z = 0.0f;
2975 t_vert[i].rhw = 1.0f;
2978 FIXME("Vertex rectangle:\n");
2979 FIXME("X, Y: %f, %f\n", t_vert[0].x, t_vert[0].y);
2980 FIXME("X, Y: %f, %f\n", t_vert[3].x, t_vert[3].y);
2981 FIXME("TOP, LEFT: %f, %f\n", t_vert[0].u, t_vert[0].v);
2982 FIXME("DOWN, BOTTOM: %f, %f\n", t_vert[3].u, t_vert[3].v);
2984 IDirect3DVertexBuffer9_Lock(This->d3d9_vertex, 0, sizeof(t_vert), &bits, 0);
2985 memcpy(bits, t_vert, sizeof(t_vert));
2986 IDirect3DVertexBuffer9_Unlock(This->d3d9_vertex);
2988 return S_OK;
2991 static HRESULT WINAPI VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, DWORD surfaceindex, DWORD flags, IDirect3DSurface9 **surface)
2993 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2995 /* Update everything first, this is needed because the surface might be destroyed in the reset */
2996 if (!This->d3d9_dev)
2998 TRACE("Device has left me!\n");
2999 return E_FAIL;
3002 VMR9_SurfaceAllocator_UpdateDeviceReset(This);
3004 if (surfaceindex >= This->num_surfaces)
3006 ERR("surfaceindex is greater than num_surfaces\n");
3007 return E_FAIL;
3009 *surface = This->d3d9_surfaces[surfaceindex];
3010 IDirect3DSurface9_AddRef(*surface);
3012 return S_OK;
3015 static HRESULT WINAPI VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9 *iface, IVMRSurfaceAllocatorNotify9 *allocnotify)
3017 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
3019 TRACE("(%p/%p)->(...)\n", iface, This);
3021 /* No AddRef taken here or the base VMR9 filter would never be destroied */
3022 This->SurfaceAllocatorNotify = allocnotify;
3023 return S_OK;
3026 static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator =
3028 VMR9_SurfaceAllocator_QueryInterface,
3029 VMR9_SurfaceAllocator_AddRef,
3030 VMR9_SurfaceAllocator_Release,
3031 VMR9_SurfaceAllocator_InitializeDevice,
3032 VMR9_SurfaceAllocator_TerminateDevice,
3033 VMR9_SurfaceAllocator_GetSurface,
3034 VMR9_SurfaceAllocator_AdviseNotify,
3035 NULL /* This isn't the SurfaceAllocatorEx type yet, working on it */
3038 static IDirect3D9 *init_d3d9(HMODULE d3d9_handle)
3040 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion);
3042 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
3043 if (!d3d9_create) return NULL;
3045 return d3d9_create(D3D_SDK_VERSION);
3048 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv)
3050 HRESULT hr = S_OK;
3051 int i;
3052 VMR9DefaultAllocatorPresenterImpl* This;
3054 This = CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl));
3055 if (!This)
3056 return E_OUTOFMEMORY;
3058 This->d3d9_ptr = init_d3d9(parent->hD3d9);
3059 if (!This->d3d9_ptr)
3061 WARN("Could not initialize d3d9.dll\n");
3062 CoTaskMemFree(This);
3063 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
3066 i = 0;
3069 D3DDISPLAYMODE mode;
3071 hr = IDirect3D9_EnumAdapterModes(This->d3d9_ptr, i++, D3DFMT_X8R8G8B8, 0, &mode);
3072 if (hr == D3DERR_INVALIDCALL) break; /* out of adapters */
3073 } while (FAILED(hr));
3074 if (FAILED(hr))
3075 ERR("HR: %08x\n", hr);
3076 if (hr == D3DERR_NOTAVAILABLE)
3078 ERR("Format not supported\n");
3079 IDirect3D9_Release(This->d3d9_ptr);
3080 CoTaskMemFree(This);
3081 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
3084 This->IVMRImagePresenter9_iface.lpVtbl = &VMR9_ImagePresenter;
3085 This->IVMRSurfaceAllocatorEx9_iface.lpVtbl = &VMR9_SurfaceAllocator;
3087 This->refCount = 1;
3088 This->pVMR9 = parent;
3089 This->d3d9_surfaces = NULL;
3090 This->d3d9_dev = NULL;
3091 This->hMon = 0;
3092 This->d3d9_vertex = NULL;
3093 This->num_surfaces = 0;
3094 This->hWndThread = NULL;
3095 This->ack = CreateEventW(NULL, 0, 0, NULL);
3096 This->SurfaceAllocatorNotify = NULL;
3097 This->reset = FALSE;
3099 *ppv = &This->IVMRImagePresenter9_iface;
3100 return S_OK;