quartz: Destroy BaseRenderer in NullRendererInner_Release.
[wine.git] / dlls / quartz / vmr9.c
blob53e4942cc83e9a1f2818ec3990defa08e5910c7c
1 /*
2 * Video Mixing Renderer for dx9
4 * Copyright 2004 Christian Costa
5 * Copyright 2008 Maarten Lankhorst
6 * Copyright 2012 Aric Stewart
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "config.h"
25 #define NONAMELESSSTRUCT
26 #define NONAMELESSUNION
27 #include "quartz_private.h"
29 #include "uuids.h"
30 #include "vfwmsgs.h"
31 #include "amvideo.h"
32 #include "windef.h"
33 #include "winbase.h"
34 #include "dshow.h"
35 #include "evcode.h"
36 #include "strmif.h"
37 #include "ddraw.h"
38 #include "dvdmedia.h"
39 #include "d3d9.h"
40 #include "vmr9.h"
41 #include "pin.h"
43 #include "wine/unicode.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
48 struct quartz_vmr
50 BaseRenderer renderer;
51 BaseControlWindow baseControlWindow;
52 BaseControlVideo baseControlVideo;
54 IUnknown IUnknown_inner;
55 IAMCertifiedOutputProtection IAMCertifiedOutputProtection_iface;
56 IAMFilterMiscFlags IAMFilterMiscFlags_iface;
57 IVMRFilterConfig IVMRFilterConfig_iface;
58 IVMRFilterConfig9 IVMRFilterConfig9_iface;
59 IVMRMonitorConfig IVMRMonitorConfig_iface;
60 IVMRMonitorConfig9 IVMRMonitorConfig9_iface;
61 IVMRSurfaceAllocatorNotify IVMRSurfaceAllocatorNotify_iface;
62 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface;
63 IVMRWindowlessControl IVMRWindowlessControl_iface;
64 IVMRWindowlessControl9 IVMRWindowlessControl9_iface;
66 IVMRSurfaceAllocatorEx9 *allocator;
67 IVMRImagePresenter9 *presenter;
68 BOOL allocator_is_ex;
71 * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed
72 * What I do is implement windowless as a special case of renderless, and then
73 * windowed also as a special case of windowless. This is probably the easiest way.
75 VMR9Mode mode;
76 BITMAPINFOHEADER bmiheader;
77 IUnknown * outer_unk;
78 BOOL bUnkOuterValid;
79 BOOL bAggregatable;
81 HMODULE hD3d9;
83 /* Presentation related members */
84 IDirect3DDevice9 *allocator_d3d9_dev;
85 HMONITOR allocator_mon;
86 DWORD num_surfaces;
87 DWORD cur_surface;
88 DWORD_PTR cookie;
90 /* for Windowless Mode */
91 HWND hWndClippingWindow;
93 RECT source_rect;
94 RECT target_rect;
95 LONG VideoWidth;
96 LONG VideoHeight;
99 static inline struct quartz_vmr *impl_from_inner_IUnknown(IUnknown *iface)
101 return CONTAINING_RECORD(iface, struct quartz_vmr, IUnknown_inner);
104 static inline struct quartz_vmr *impl_from_BaseWindow(BaseWindow *wnd)
106 return CONTAINING_RECORD(wnd, struct quartz_vmr, baseControlWindow.baseWindow);
109 static inline struct quartz_vmr *impl_from_IVideoWindow(IVideoWindow *iface)
111 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlWindow.IVideoWindow_iface);
114 static inline struct quartz_vmr *impl_from_BaseControlVideo(BaseControlVideo *cvid)
116 return CONTAINING_RECORD(cvid, struct quartz_vmr, baseControlVideo);
119 static inline struct quartz_vmr *impl_from_IBasicVideo(IBasicVideo *iface)
121 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlVideo.IBasicVideo_iface);
124 static inline struct quartz_vmr *impl_from_IAMCertifiedOutputProtection(IAMCertifiedOutputProtection *iface)
126 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMCertifiedOutputProtection_iface);
129 static inline struct quartz_vmr *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
131 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMFilterMiscFlags_iface);
134 static inline struct quartz_vmr *impl_from_IVMRFilterConfig(IVMRFilterConfig *iface)
136 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig_iface);
139 static inline struct quartz_vmr *impl_from_IVMRFilterConfig9(IVMRFilterConfig9 *iface)
141 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig9_iface);
144 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig(IVMRMonitorConfig *iface)
146 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig_iface);
149 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig9(IVMRMonitorConfig9 *iface)
151 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig9_iface);
154 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify(IVMRSurfaceAllocatorNotify *iface)
156 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify_iface);
159 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify9(IVMRSurfaceAllocatorNotify9 *iface)
161 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify9_iface);
164 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl(IVMRWindowlessControl *iface)
166 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl_iface);
169 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl9(IVMRWindowlessControl9 *iface)
171 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl9_iface);
174 typedef struct
176 IVMRImagePresenter9 IVMRImagePresenter9_iface;
177 IVMRSurfaceAllocatorEx9 IVMRSurfaceAllocatorEx9_iface;
179 LONG refCount;
181 HANDLE ack;
182 DWORD tid;
183 HANDLE hWndThread;
185 IDirect3DDevice9 *d3d9_dev;
186 IDirect3D9 *d3d9_ptr;
187 IDirect3DSurface9 **d3d9_surfaces;
188 IDirect3DVertexBuffer9 *d3d9_vertex;
189 HMONITOR hMon;
190 DWORD num_surfaces;
192 BOOL reset;
193 VMR9AllocationInfo info;
195 struct quartz_vmr* pVMR9;
196 IVMRSurfaceAllocatorNotify9 *SurfaceAllocatorNotify;
197 } VMR9DefaultAllocatorPresenterImpl;
199 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRImagePresenter9( IVMRImagePresenter9 *iface)
201 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRImagePresenter9_iface);
204 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRSurfaceAllocatorEx9( IVMRSurfaceAllocatorEx9 *iface)
206 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRSurfaceAllocatorEx9_iface);
209 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv);
211 static DWORD VMR9_SendSampleData(struct quartz_vmr *This, VMR9PresentationInfo *info, LPBYTE data,
212 DWORD size)
214 AM_MEDIA_TYPE *amt;
215 HRESULT hr = S_OK;
216 int width;
217 int height;
218 BITMAPINFOHEADER *bmiHeader;
219 D3DLOCKED_RECT lock;
221 TRACE("%p %p %d\n", This, data, size);
223 amt = &This->renderer.pInputPin->pin.mtCurrent;
225 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
227 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
229 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
231 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
233 else
235 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
236 return VFW_E_RUNTIME_ERROR;
239 TRACE("biSize = %d\n", bmiHeader->biSize);
240 TRACE("biWidth = %d\n", bmiHeader->biWidth);
241 TRACE("biHeight = %d\n", bmiHeader->biHeight);
242 TRACE("biPlanes = %d\n", bmiHeader->biPlanes);
243 TRACE("biBitCount = %d\n", bmiHeader->biBitCount);
244 TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(bmiHeader->biCompression), 4));
245 TRACE("biSizeImage = %d\n", bmiHeader->biSizeImage);
247 width = bmiHeader->biWidth;
248 height = bmiHeader->biHeight;
250 TRACE("Src Rect: %d %d %d %d\n", This->source_rect.left, This->source_rect.top, This->source_rect.right, This->source_rect.bottom);
251 TRACE("Dst Rect: %d %d %d %d\n", This->target_rect.left, This->target_rect.top, This->target_rect.right, This->target_rect.bottom);
253 hr = IDirect3DSurface9_LockRect(info->lpSurf, &lock, NULL, D3DLOCK_DISCARD);
254 if (FAILED(hr))
256 ERR("IDirect3DSurface9_LockRect failed (%x)\n",hr);
257 return hr;
260 if (lock.Pitch != width * bmiHeader->biBitCount / 8)
262 WARN("Slow path! %u/%u\n", lock.Pitch, width * bmiHeader->biBitCount/8);
264 while (height--)
266 memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8);
267 data = data + width * bmiHeader->biBitCount / 8;
268 lock.pBits = (char *)lock.pBits + lock.Pitch;
271 else memcpy(lock.pBits, data, size);
273 IDirect3DSurface9_UnlockRect(info->lpSurf);
275 hr = IVMRImagePresenter9_PresentImage(This->presenter, This->cookie, info);
276 return hr;
279 static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample)
281 struct quartz_vmr *This = (struct quartz_vmr*)iface;
282 LPBYTE pbSrcStream = NULL;
283 long cbSrcStream = 0;
284 REFERENCE_TIME tStart, tStop;
285 VMR9PresentationInfo info;
286 HRESULT hr;
288 TRACE("%p %p\n", iface, pSample);
290 /* It is possible that there is no device at this point */
292 if (!This->allocator || !This->presenter)
294 ERR("NO PRESENTER!!\n");
295 return S_FALSE;
298 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
299 if (FAILED(hr))
300 info.dwFlags = VMR9Sample_SrcDstRectsValid;
301 else
302 info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid;
304 if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
305 info.dwFlags |= VMR9Sample_Discontinuity;
307 if (IMediaSample_IsPreroll(pSample) == S_OK)
308 info.dwFlags |= VMR9Sample_Preroll;
310 if (IMediaSample_IsSyncPoint(pSample) == S_OK)
311 info.dwFlags |= VMR9Sample_SyncPoint;
313 /* If we render ourselves, and this is a preroll sample, discard it */
314 if (This->baseControlWindow.baseWindow.hWnd && (info.dwFlags & VMR9Sample_Preroll))
316 return S_OK;
319 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
320 if (FAILED(hr))
322 ERR("Cannot get pointer to sample data (%x)\n", hr);
323 return hr;
326 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
328 info.rtStart = tStart;
329 info.rtEnd = tStop;
330 info.szAspectRatio.cx = This->bmiheader.biWidth;
331 info.szAspectRatio.cy = This->bmiheader.biHeight;
333 hr = IVMRSurfaceAllocatorEx9_GetSurface(This->allocator, This->cookie, (++This->cur_surface)%This->num_surfaces, 0, &info.lpSurf);
335 if (FAILED(hr))
336 return hr;
338 VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream);
339 IDirect3DSurface9_Release(info.lpSurf);
341 return hr;
344 static HRESULT WINAPI VMR9_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt)
346 struct quartz_vmr *This = (struct quartz_vmr*)iface;
348 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat)
349 return S_FALSE;
351 /* Ignore subtype, test for bicompression instead */
352 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
354 VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
356 This->bmiheader = format->bmiHeader;
357 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
358 This->source_rect.right = This->VideoWidth = format->bmiHeader.biWidth;
359 This->source_rect.bottom = This->VideoHeight = format->bmiHeader.biHeight;
360 This->source_rect.top = This->source_rect.left = 0;
362 else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
364 VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat;
366 This->bmiheader = format->bmiHeader;
368 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
369 This->source_rect.right = This->VideoWidth = format->bmiHeader.biWidth;
370 This->source_rect.bottom = This->VideoHeight = format->bmiHeader.biHeight;
371 This->source_rect.top = This->source_rect.left = 0;
373 else
375 ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
376 return S_FALSE;
378 if (This->bmiheader.biCompression)
379 return S_FALSE;
380 return S_OK;
383 static HRESULT VMR9_maybe_init(struct quartz_vmr *This, BOOL force)
385 VMR9AllocationInfo info;
386 DWORD buffers;
387 HRESULT hr;
389 TRACE("my mode: %u, my window: %p, my last window: %p\n", This->mode, This->baseControlWindow.baseWindow.hWnd, This->hWndClippingWindow);
390 if (This->baseControlWindow.baseWindow.hWnd || !This->renderer.pInputPin->pin.pConnectedTo)
391 return S_OK;
393 if (This->mode == VMR9Mode_Windowless && !This->hWndClippingWindow)
394 return (force ? VFW_E_RUNTIME_ERROR : S_OK);
396 TRACE("Initializing\n");
397 info.dwFlags = VMR9AllocFlag_TextureSurface;
398 info.dwHeight = This->source_rect.bottom;
399 info.dwWidth = This->source_rect.right;
400 info.Pool = D3DPOOL_DEFAULT;
401 info.MinBuffers = 2;
402 FIXME("Reduce ratio to least common denominator\n");
403 info.szAspectRatio.cx = info.dwWidth;
404 info.szAspectRatio.cy = info.dwHeight;
405 info.szNativeSize.cx = This->bmiheader.biWidth;
406 info.szNativeSize.cy = This->bmiheader.biHeight;
407 buffers = 2;
409 switch (This->bmiheader.biBitCount)
411 case 8: info.Format = D3DFMT_R3G3B2; break;
412 case 15: info.Format = D3DFMT_X1R5G5B5; break;
413 case 16: info.Format = D3DFMT_R5G6B5; break;
414 case 24: info.Format = D3DFMT_R8G8B8; break;
415 case 32: info.Format = D3DFMT_X8R8G8B8; break;
416 default:
417 FIXME("Unknown bpp %u\n", This->bmiheader.biBitCount);
418 hr = E_INVALIDARG;
421 This->cur_surface = 0;
422 if (This->num_surfaces)
424 ERR("num_surfaces or d3d9_surfaces not 0\n");
425 return E_FAIL;
428 hr = IVMRSurfaceAllocatorEx9_InitializeDevice(This->allocator, This->cookie, &info, &buffers);
429 if (SUCCEEDED(hr))
431 This->source_rect.left = This->source_rect.top = 0;
432 This->source_rect.right = This->bmiheader.biWidth;
433 This->source_rect.bottom = This->bmiheader.biHeight;
435 This->num_surfaces = buffers;
437 return hr;
440 static VOID WINAPI VMR9_OnStartStreaming(BaseRenderer* iface)
442 struct quartz_vmr *This = (struct quartz_vmr*)iface;
444 TRACE("(%p)\n", This);
446 VMR9_maybe_init(This, TRUE);
447 IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie);
448 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
449 This->source_rect.left,
450 This->source_rect.top,
451 This->source_rect.right - This->source_rect.left,
452 This->source_rect.bottom - This->source_rect.top,
453 SWP_NOZORDER|SWP_NOMOVE|SWP_DEFERERASE);
454 ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_SHOW);
455 GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->target_rect);
458 static VOID WINAPI VMR9_OnStopStreaming(BaseRenderer* iface)
460 struct quartz_vmr *This = (struct quartz_vmr*)iface;
462 TRACE("(%p)\n", This);
464 if (This->renderer.filter.state == State_Running)
465 IVMRImagePresenter9_StopPresenting(This->presenter, This->cookie);
468 static HRESULT WINAPI VMR9_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime)
470 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
471 if (IMediaSample_IsPreroll(pSample) == S_OK)
472 return E_FAIL;
473 return S_FALSE;
476 static HRESULT WINAPI VMR9_CompleteConnect(BaseRenderer *This, IPin *pReceivePin)
478 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This;
479 HRESULT hr = S_OK;
481 TRACE("(%p)\n", This);
483 if (!pVMR9->mode && SUCCEEDED(hr))
484 hr = IVMRFilterConfig9_SetRenderingMode(&pVMR9->IVMRFilterConfig9_iface, VMR9Mode_Windowed);
486 if (SUCCEEDED(hr))
487 hr = VMR9_maybe_init(pVMR9, FALSE);
489 return hr;
492 static HRESULT WINAPI VMR9_BreakConnect(BaseRenderer *This)
494 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This;
495 HRESULT hr = S_OK;
497 if (!pVMR9->mode)
498 return S_FALSE;
499 if (This->pInputPin->pin.pConnectedTo && pVMR9->allocator && pVMR9->presenter)
501 if (pVMR9->renderer.filter.state != State_Stopped)
503 ERR("Disconnecting while not stopped! UNTESTED!!\n");
505 if (pVMR9->renderer.filter.state == State_Running)
506 hr = IVMRImagePresenter9_StopPresenting(pVMR9->presenter, pVMR9->cookie);
507 IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9->allocator, pVMR9->cookie);
508 pVMR9->num_surfaces = 0;
510 return hr;
513 static const BaseRendererFuncTable BaseFuncTable = {
514 VMR9_CheckMediaType,
515 VMR9_DoRenderSample,
516 /**/
517 NULL,
518 NULL,
519 NULL,
520 VMR9_OnStartStreaming,
521 VMR9_OnStopStreaming,
522 NULL,
523 NULL,
524 NULL,
525 VMR9_ShouldDrawSampleNow,
526 NULL,
527 /**/
528 VMR9_CompleteConnect,
529 VMR9_BreakConnect,
530 NULL,
531 NULL,
532 NULL,
535 static LPWSTR WINAPI VMR9_GetClassWindowStyles(BaseWindow *This, DWORD *pClassStyles, DWORD *pWindowStyles, DWORD *pWindowStylesEx)
537 static WCHAR classnameW[] = { 'I','V','M','R','9',' ','C','l','a','s','s', 0 };
539 *pClassStyles = 0;
540 *pWindowStyles = WS_SIZEBOX;
541 *pWindowStylesEx = 0;
543 return classnameW;
546 static RECT WINAPI VMR9_GetDefaultRect(BaseWindow *This)
548 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
549 static RECT defRect;
551 defRect.left = defRect.top = 0;
552 defRect.right = pVMR9->VideoWidth;
553 defRect.bottom = pVMR9->VideoHeight;
555 return defRect;
558 static BOOL WINAPI VMR9_OnSize(BaseWindow *This, LONG Width, LONG Height)
560 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
562 TRACE("WM_SIZE %d %d\n", Width, Height);
563 GetClientRect(This->hWnd, &pVMR9->target_rect);
564 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
565 pVMR9->target_rect.left,
566 pVMR9->target_rect.top,
567 pVMR9->target_rect.right - pVMR9->target_rect.left,
568 pVMR9->target_rect.bottom - pVMR9->target_rect.top);
569 return BaseWindowImpl_OnSize(This, Width, Height);
572 static const BaseWindowFuncTable renderer_BaseWindowFuncTable = {
573 VMR9_GetClassWindowStyles,
574 VMR9_GetDefaultRect,
575 NULL,
576 BaseControlWindowImpl_PossiblyEatMessage,
577 VMR9_OnSize,
580 static HRESULT WINAPI VMR9_GetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
582 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
583 CopyRect(pSourceRect,&pVMR9->source_rect);
584 return S_OK;
587 static HRESULT WINAPI VMR9_GetStaticImage(BaseControlVideo* This, LONG *pBufferSize, LONG *pDIBImage)
589 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
590 BITMAPINFOHEADER *bmiHeader;
591 LONG needed_size;
592 AM_MEDIA_TYPE *amt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
593 char *ptr;
595 FIXME("(%p/%p)->(%p, %p): partial stub\n", pVMR9, This, pBufferSize, pDIBImage);
597 EnterCriticalSection(&pVMR9->renderer.filter.csFilter);
599 if (!pVMR9->renderer.pMediaSample)
601 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
602 return (pVMR9->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
605 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
607 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
609 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
611 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
613 else
615 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
616 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
617 return VFW_E_RUNTIME_ERROR;
620 needed_size = bmiHeader->biSize;
621 needed_size += IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample);
623 if (!pDIBImage)
625 *pBufferSize = needed_size;
626 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
627 return S_OK;
630 if (needed_size < *pBufferSize)
632 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
633 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
634 return E_FAIL;
636 *pBufferSize = needed_size;
638 memcpy(pDIBImage, bmiHeader, bmiHeader->biSize);
639 IMediaSample_GetPointer(pVMR9->renderer.pMediaSample, (BYTE **)&ptr);
640 memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample));
642 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
643 return S_OK;
646 static HRESULT WINAPI VMR9_GetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
648 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
649 CopyRect(pTargetRect,&pVMR9->target_rect);
650 return S_OK;
653 static VIDEOINFOHEADER* WINAPI VMR9_GetVideoFormat(BaseControlVideo* This)
655 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
656 AM_MEDIA_TYPE *pmt;
658 TRACE("(%p/%p)\n", pVMR9, This);
660 pmt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
661 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) {
662 return (VIDEOINFOHEADER*)pmt->pbFormat;
663 } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) {
664 static VIDEOINFOHEADER vih;
665 VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat;
666 memcpy(&vih,vih2,sizeof(VIDEOINFOHEADER));
667 memcpy(&vih.bmiHeader, &vih2->bmiHeader, sizeof(BITMAPINFOHEADER));
668 return &vih;
669 } else {
670 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype));
671 return NULL;
675 static HRESULT WINAPI VMR9_IsDefaultSourceRect(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_IsDefaultTargetRect(BaseControlVideo* This)
685 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
686 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
688 return S_OK;
691 static HRESULT WINAPI VMR9_SetDefaultSourceRect(BaseControlVideo* This)
693 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
695 pVMR9->source_rect.left = 0;
696 pVMR9->source_rect.top = 0;
697 pVMR9->source_rect.right = pVMR9->VideoWidth;
698 pVMR9->source_rect.bottom = pVMR9->VideoHeight;
700 return S_OK;
703 static HRESULT WINAPI VMR9_SetDefaultTargetRect(BaseControlVideo* This)
705 RECT rect;
706 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
708 if (!GetClientRect(pVMR9->baseControlWindow.baseWindow.hWnd, &rect))
709 return E_FAIL;
711 pVMR9->target_rect.left = 0;
712 pVMR9->target_rect.top = 0;
713 pVMR9->target_rect.right = rect.right;
714 pVMR9->target_rect.bottom = rect.bottom;
716 return S_OK;
719 static HRESULT WINAPI VMR9_SetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
721 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
722 CopyRect(&pVMR9->source_rect,pSourceRect);
723 return S_OK;
726 static HRESULT WINAPI VMR9_SetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
728 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
729 CopyRect(&pVMR9->target_rect,pTargetRect);
730 return S_OK;
733 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = {
734 VMR9_GetSourceRect,
735 VMR9_GetStaticImage,
736 VMR9_GetTargetRect,
737 VMR9_GetVideoFormat,
738 VMR9_IsDefaultSourceRect,
739 VMR9_IsDefaultTargetRect,
740 VMR9_SetDefaultSourceRect,
741 VMR9_SetDefaultTargetRect,
742 VMR9_SetSourceRect,
743 VMR9_SetTargetRect
746 static HRESULT WINAPI VMR9Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
748 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
749 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
751 if (This->bAggregatable)
752 This->bUnkOuterValid = TRUE;
754 *ppv = NULL;
756 if (IsEqualIID(riid, &IID_IUnknown))
757 *ppv = &This->IUnknown_inner;
758 else if (IsEqualIID(riid, &IID_IVideoWindow))
759 *ppv = &This->baseControlWindow.IVideoWindow_iface;
760 else if (IsEqualIID(riid, &IID_IBasicVideo))
761 *ppv = &This->baseControlVideo.IBasicVideo_iface;
762 else if (IsEqualIID(riid, &IID_IAMCertifiedOutputProtection))
763 *ppv = &This->IAMCertifiedOutputProtection_iface;
764 else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
765 *ppv = &This->IAMFilterMiscFlags_iface;
766 else if (IsEqualIID(riid, &IID_IVMRFilterConfig))
767 *ppv = &This->IVMRFilterConfig_iface;
768 else if (IsEqualIID(riid, &IID_IVMRFilterConfig9))
769 *ppv = &This->IVMRFilterConfig9_iface;
770 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig))
771 *ppv = &This->IVMRMonitorConfig_iface;
772 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig9))
773 *ppv = &This->IVMRMonitorConfig9_iface;
774 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify) && This->mode == (VMR9Mode)VMRMode_Renderless)
775 *ppv = &This->IVMRSurfaceAllocatorNotify_iface;
776 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9) && This->mode == VMR9Mode_Renderless)
777 *ppv = &This->IVMRSurfaceAllocatorNotify9_iface;
778 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl) && This->mode == (VMR9Mode)VMRMode_Windowless)
779 *ppv = &This->IVMRWindowlessControl_iface;
780 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9) && This->mode == VMR9Mode_Windowless)
781 *ppv = &This->IVMRWindowlessControl9_iface;
782 else
784 HRESULT hr;
785 hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
786 if (SUCCEEDED(hr))
787 return hr;
790 if (*ppv)
792 IUnknown_AddRef((IUnknown *)(*ppv));
793 return S_OK;
796 else if (IsEqualIID(riid, &IID_IBasicVideo2))
797 FIXME("No interface for IID_IBasicVideo2\n");
798 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9))
800 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9))
802 else if (IsEqualIID(riid, &IID_IMediaPosition))
803 FIXME("No interface for IID_IMediaPosition\n");
804 else if (IsEqualIID(riid, &IID_IQualProp))
805 FIXME("No interface for IID_IQualProp\n");
806 else if (IsEqualIID(riid, &IID_IVMRAspectRatioControl9))
807 FIXME("No interface for IID_IVMRAspectRatioControl9\n");
808 else if (IsEqualIID(riid, &IID_IVMRDeinterlaceControl9))
809 FIXME("No interface for IID_IVMRDeinterlaceControl9\n");
810 else if (IsEqualIID(riid, &IID_IVMRMixerBitmap9))
811 FIXME("No interface for IID_IVMRMixerBitmap9\n");
812 else if (IsEqualIID(riid, &IID_IVMRMixerControl9))
813 FIXME("No interface for IID_IVMRMixerControl9\n");
814 else
815 FIXME("No interface for %s\n", debugstr_guid(riid));
817 return E_NOINTERFACE;
820 static ULONG WINAPI VMR9Inner_AddRef(IUnknown * iface)
822 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
823 ULONG refCount = BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
825 TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
827 return refCount;
830 static ULONG WINAPI VMR9Inner_Release(IUnknown * iface)
832 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
833 ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface);
835 TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
837 if (!refCount)
839 TRACE("Destroying\n");
840 BaseControlWindow_Destroy(&This->baseControlWindow);
841 FreeLibrary(This->hD3d9);
843 if (This->allocator)
844 IVMRSurfaceAllocatorEx9_Release(This->allocator);
845 if (This->presenter)
846 IVMRImagePresenter9_Release(This->presenter);
848 This->num_surfaces = 0;
849 if (This->allocator_d3d9_dev)
851 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
852 This->allocator_d3d9_dev = NULL;
855 CoTaskMemFree(This);
857 return refCount;
860 static const IUnknownVtbl IInner_VTable =
862 VMR9Inner_QueryInterface,
863 VMR9Inner_AddRef,
864 VMR9Inner_Release
867 static HRESULT WINAPI VMR9_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
869 struct quartz_vmr *This = (struct quartz_vmr*)iface;
871 if (This->bAggregatable)
872 This->bUnkOuterValid = TRUE;
874 if (This->outer_unk)
876 if (This->bAggregatable)
877 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
879 if (IsEqualIID(riid, &IID_IUnknown))
881 HRESULT hr;
883 IUnknown_AddRef(&This->IUnknown_inner);
884 hr = IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
885 IUnknown_Release(&This->IUnknown_inner);
886 This->bAggregatable = TRUE;
887 return hr;
890 *ppv = NULL;
891 return E_NOINTERFACE;
894 return IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
897 static ULONG WINAPI VMR9_AddRef(IBaseFilter * iface)
899 struct quartz_vmr *This = (struct quartz_vmr*)iface;
900 LONG ret;
902 if (This->outer_unk && This->bUnkOuterValid)
903 ret = IUnknown_AddRef(This->outer_unk);
904 else
905 ret = IUnknown_AddRef(&This->IUnknown_inner);
907 TRACE("(%p)->AddRef from %d\n", iface, ret - 1);
909 return ret;
912 static ULONG WINAPI VMR9_Release(IBaseFilter * iface)
914 struct quartz_vmr *This = (struct quartz_vmr*)iface;
915 LONG ret;
917 if (This->outer_unk && This->bUnkOuterValid)
918 ret = IUnknown_Release(This->outer_unk);
919 else
920 ret = IUnknown_Release(&This->IUnknown_inner);
922 TRACE("(%p)->Release from %d\n", iface, ret + 1);
924 if (ret)
925 return ret;
926 return 0;
929 static const IBaseFilterVtbl VMR_Vtbl =
931 VMR9_QueryInterface,
932 VMR9_AddRef,
933 VMR9_Release,
934 BaseFilterImpl_GetClassID,
935 BaseRendererImpl_Stop,
936 BaseRendererImpl_Pause,
937 BaseRendererImpl_Run,
938 BaseRendererImpl_GetState,
939 BaseRendererImpl_SetSyncSource,
940 BaseFilterImpl_GetSyncSource,
941 BaseFilterImpl_EnumPins,
942 BaseRendererImpl_FindPin,
943 BaseFilterImpl_QueryFilterInfo,
944 BaseFilterImpl_JoinFilterGraph,
945 BaseFilterImpl_QueryVendorInfo
948 /*** IUnknown methods ***/
949 static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface, REFIID riid, LPVOID*ppvObj)
951 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
953 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
955 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
958 static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface)
960 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
962 TRACE("(%p/%p)->()\n", This, iface);
964 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
967 static ULONG WINAPI Videowindow_Release(IVideoWindow *iface)
969 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
971 TRACE("(%p/%p)->()\n", This, iface);
973 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
976 static const IVideoWindowVtbl IVideoWindow_VTable =
978 Videowindow_QueryInterface,
979 Videowindow_AddRef,
980 Videowindow_Release,
981 BaseControlWindowImpl_GetTypeInfoCount,
982 BaseControlWindowImpl_GetTypeInfo,
983 BaseControlWindowImpl_GetIDsOfNames,
984 BaseControlWindowImpl_Invoke,
985 BaseControlWindowImpl_put_Caption,
986 BaseControlWindowImpl_get_Caption,
987 BaseControlWindowImpl_put_WindowStyle,
988 BaseControlWindowImpl_get_WindowStyle,
989 BaseControlWindowImpl_put_WindowStyleEx,
990 BaseControlWindowImpl_get_WindowStyleEx,
991 BaseControlWindowImpl_put_AutoShow,
992 BaseControlWindowImpl_get_AutoShow,
993 BaseControlWindowImpl_put_WindowState,
994 BaseControlWindowImpl_get_WindowState,
995 BaseControlWindowImpl_put_BackgroundPalette,
996 BaseControlWindowImpl_get_BackgroundPalette,
997 BaseControlWindowImpl_put_Visible,
998 BaseControlWindowImpl_get_Visible,
999 BaseControlWindowImpl_put_Left,
1000 BaseControlWindowImpl_get_Left,
1001 BaseControlWindowImpl_put_Width,
1002 BaseControlWindowImpl_get_Width,
1003 BaseControlWindowImpl_put_Top,
1004 BaseControlWindowImpl_get_Top,
1005 BaseControlWindowImpl_put_Height,
1006 BaseControlWindowImpl_get_Height,
1007 BaseControlWindowImpl_put_Owner,
1008 BaseControlWindowImpl_get_Owner,
1009 BaseControlWindowImpl_put_MessageDrain,
1010 BaseControlWindowImpl_get_MessageDrain,
1011 BaseControlWindowImpl_get_BorderColor,
1012 BaseControlWindowImpl_put_BorderColor,
1013 BaseControlWindowImpl_get_FullScreenMode,
1014 BaseControlWindowImpl_put_FullScreenMode,
1015 BaseControlWindowImpl_SetWindowForeground,
1016 BaseControlWindowImpl_NotifyOwnerMessage,
1017 BaseControlWindowImpl_SetWindowPosition,
1018 BaseControlWindowImpl_GetWindowPosition,
1019 BaseControlWindowImpl_GetMinIdealImageSize,
1020 BaseControlWindowImpl_GetMaxIdealImageSize,
1021 BaseControlWindowImpl_GetRestorePosition,
1022 BaseControlWindowImpl_HideCursor,
1023 BaseControlWindowImpl_IsCursorHidden
1026 /*** IUnknown methods ***/
1027 static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface, REFIID riid, LPVOID * ppvObj)
1029 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1031 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
1033 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
1036 static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface)
1038 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1040 TRACE("(%p/%p)->()\n", This, iface);
1042 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1045 static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface)
1047 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1049 TRACE("(%p/%p)->()\n", This, iface);
1051 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1054 static const IBasicVideoVtbl IBasicVideo_VTable =
1056 Basicvideo_QueryInterface,
1057 Basicvideo_AddRef,
1058 Basicvideo_Release,
1059 BaseControlVideoImpl_GetTypeInfoCount,
1060 BaseControlVideoImpl_GetTypeInfo,
1061 BaseControlVideoImpl_GetIDsOfNames,
1062 BaseControlVideoImpl_Invoke,
1063 BaseControlVideoImpl_get_AvgTimePerFrame,
1064 BaseControlVideoImpl_get_BitRate,
1065 BaseControlVideoImpl_get_BitErrorRate,
1066 BaseControlVideoImpl_get_VideoWidth,
1067 BaseControlVideoImpl_get_VideoHeight,
1068 BaseControlVideoImpl_put_SourceLeft,
1069 BaseControlVideoImpl_get_SourceLeft,
1070 BaseControlVideoImpl_put_SourceWidth,
1071 BaseControlVideoImpl_get_SourceWidth,
1072 BaseControlVideoImpl_put_SourceTop,
1073 BaseControlVideoImpl_get_SourceTop,
1074 BaseControlVideoImpl_put_SourceHeight,
1075 BaseControlVideoImpl_get_SourceHeight,
1076 BaseControlVideoImpl_put_DestinationLeft,
1077 BaseControlVideoImpl_get_DestinationLeft,
1078 BaseControlVideoImpl_put_DestinationWidth,
1079 BaseControlVideoImpl_get_DestinationWidth,
1080 BaseControlVideoImpl_put_DestinationTop,
1081 BaseControlVideoImpl_get_DestinationTop,
1082 BaseControlVideoImpl_put_DestinationHeight,
1083 BaseControlVideoImpl_get_DestinationHeight,
1084 BaseControlVideoImpl_SetSourcePosition,
1085 BaseControlVideoImpl_GetSourcePosition,
1086 BaseControlVideoImpl_SetDefaultSourcePosition,
1087 BaseControlVideoImpl_SetDestinationPosition,
1088 BaseControlVideoImpl_GetDestinationPosition,
1089 BaseControlVideoImpl_SetDefaultDestinationPosition,
1090 BaseControlVideoImpl_GetVideoSize,
1091 BaseControlVideoImpl_GetVideoPaletteEntries,
1092 BaseControlVideoImpl_GetCurrentImage,
1093 BaseControlVideoImpl_IsUsingDefaultSource,
1094 BaseControlVideoImpl_IsUsingDefaultDestination
1097 static HRESULT WINAPI AMCertifiedOutputProtection_QueryInterface(IAMCertifiedOutputProtection *iface,
1098 REFIID riid, void **ppv)
1100 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1101 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1104 static ULONG WINAPI AMCertifiedOutputProtection_AddRef(IAMCertifiedOutputProtection *iface)
1106 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1107 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1110 static ULONG WINAPI AMCertifiedOutputProtection_Release(IAMCertifiedOutputProtection *iface)
1112 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1113 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1116 static HRESULT WINAPI AMCertifiedOutputProtection_KeyExchange(IAMCertifiedOutputProtection *iface,
1117 GUID* pRandom, BYTE** VarLenCertGH,
1118 DWORD* pdwLengthCertGH)
1120 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1122 FIXME("(%p/%p)->(%p, %p, %p) stub\n", iface, This, pRandom, VarLenCertGH, pdwLengthCertGH);
1123 return VFW_E_NO_COPP_HW;
1126 static HRESULT WINAPI AMCertifiedOutputProtection_SessionSequenceStart(IAMCertifiedOutputProtection *iface,
1127 AMCOPPSignature* pSig)
1129 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1131 FIXME("(%p/%p)->(%p) stub\n", iface, This, pSig);
1132 return VFW_E_NO_COPP_HW;
1135 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionCommand(IAMCertifiedOutputProtection *iface,
1136 const AMCOPPCommand* cmd)
1138 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1140 FIXME("(%p/%p)->(%p) stub\n", iface, This, cmd);
1141 return VFW_E_NO_COPP_HW;
1144 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionStatus(IAMCertifiedOutputProtection *iface,
1145 const AMCOPPStatusInput* pStatusInput,
1146 AMCOPPStatusOutput* pStatusOutput)
1148 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1150 FIXME("(%p/%p)->(%p, %p) stub\n", iface, This, pStatusInput, pStatusOutput);
1151 return VFW_E_NO_COPP_HW;
1154 static const IAMCertifiedOutputProtectionVtbl IAMCertifiedOutputProtection_Vtbl =
1156 AMCertifiedOutputProtection_QueryInterface,
1157 AMCertifiedOutputProtection_AddRef,
1158 AMCertifiedOutputProtection_Release,
1159 AMCertifiedOutputProtection_KeyExchange,
1160 AMCertifiedOutputProtection_SessionSequenceStart,
1161 AMCertifiedOutputProtection_ProtectionCommand,
1162 AMCertifiedOutputProtection_ProtectionStatus
1165 static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) {
1166 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1167 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1170 static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) {
1171 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1172 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1175 static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) {
1176 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1177 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1180 static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) {
1181 return AM_FILTER_MISC_FLAGS_IS_RENDERER;
1184 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = {
1185 AMFilterMiscFlags_QueryInterface,
1186 AMFilterMiscFlags_AddRef,
1187 AMFilterMiscFlags_Release,
1188 AMFilterMiscFlags_GetMiscFlags
1191 static HRESULT WINAPI VMR7FilterConfig_QueryInterface(IVMRFilterConfig *iface, REFIID riid,
1192 void** ppv)
1194 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1195 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1198 static ULONG WINAPI VMR7FilterConfig_AddRef(IVMRFilterConfig *iface)
1200 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1201 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1204 static ULONG WINAPI VMR7FilterConfig_Release(IVMRFilterConfig *iface)
1206 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1207 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1210 static HRESULT WINAPI VMR7FilterConfig_SetImageCompositor(IVMRFilterConfig *iface,
1211 IVMRImageCompositor *compositor)
1213 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1215 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
1216 return E_NOTIMPL;
1219 static HRESULT WINAPI VMR7FilterConfig_SetNumberOfStreams(IVMRFilterConfig *iface, DWORD max)
1221 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1223 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
1224 return E_NOTIMPL;
1227 static HRESULT WINAPI VMR7FilterConfig_GetNumberOfStreams(IVMRFilterConfig *iface, DWORD *max)
1229 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1231 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
1232 return E_NOTIMPL;
1235 static HRESULT WINAPI VMR7FilterConfig_SetRenderingPrefs(IVMRFilterConfig *iface, DWORD renderflags)
1237 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1239 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
1240 return E_NOTIMPL;
1243 static HRESULT WINAPI VMR7FilterConfig_GetRenderingPrefs(IVMRFilterConfig *iface, DWORD *renderflags)
1245 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1247 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
1248 return E_NOTIMPL;
1251 static HRESULT WINAPI VMR7FilterConfig_SetRenderingMode(IVMRFilterConfig *iface, DWORD mode)
1253 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1255 FIXME("(%p/%p)->(%u) stub\n", iface, This, mode);
1256 return E_NOTIMPL;
1259 static HRESULT WINAPI VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig *iface, DWORD *mode)
1261 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1263 TRACE("(%p/%p)->(%p) stub\n", iface, This, mode);
1264 if (!mode) return E_POINTER;
1266 if (This->mode)
1267 *mode = This->mode;
1268 else
1269 *mode = VMRMode_Windowed;
1271 return S_OK;
1274 static const IVMRFilterConfigVtbl VMR7_FilterConfig_Vtbl =
1276 VMR7FilterConfig_QueryInterface,
1277 VMR7FilterConfig_AddRef,
1278 VMR7FilterConfig_Release,
1279 VMR7FilterConfig_SetImageCompositor,
1280 VMR7FilterConfig_SetNumberOfStreams,
1281 VMR7FilterConfig_GetNumberOfStreams,
1282 VMR7FilterConfig_SetRenderingPrefs,
1283 VMR7FilterConfig_GetRenderingPrefs,
1284 VMR7FilterConfig_SetRenderingMode,
1285 VMR7FilterConfig_GetRenderingMode
1288 struct get_available_monitors_args
1290 VMRMONITORINFO *info7;
1291 VMR9MonitorInfo *info9;
1292 DWORD arraysize;
1293 DWORD numdev;
1296 static BOOL CALLBACK get_available_monitors_proc(HMONITOR hmon, HDC hdc, LPRECT lprc, LPARAM lparam)
1298 struct get_available_monitors_args *args = (struct get_available_monitors_args *)lparam;
1299 MONITORINFOEXW mi;
1301 if (args->info7 || args->info9)
1304 if (!args->arraysize)
1305 return FALSE;
1307 mi.cbSize = sizeof(mi);
1308 if (!GetMonitorInfoW(hmon, (MONITORINFO*)&mi))
1309 return TRUE;
1311 /* fill VMRMONITORINFO struct */
1312 if (args->info7)
1314 VMRMONITORINFO *info = args->info7++;
1315 memset(info, 0, sizeof(*info));
1317 if (args->numdev > 0)
1319 info->guid.pGUID = &info->guid.GUID;
1320 info->guid.GUID.Data4[7] = args->numdev;
1322 else
1323 info->guid.pGUID = NULL;
1325 CopyRect(&info->rcMonitor, &mi.rcMonitor);
1326 info->hMon = hmon;
1327 info->dwFlags = mi.dwFlags;
1329 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR));
1331 /* FIXME: how to get these values? */
1332 info->szDescription[0] = 0;
1335 /* fill VMR9MonitorInfo struct */
1336 if (args->info9)
1338 VMR9MonitorInfo *info = args->info9++;
1339 memset(info, 0, sizeof(*info));
1341 info->uDevID = 0; /* FIXME */
1342 CopyRect(&info->rcMonitor, &mi.rcMonitor);
1343 info->hMon = hmon;
1344 info->dwFlags = mi.dwFlags;
1346 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR));
1348 /* FIXME: how to get these values? */
1349 info->szDescription[0] = 0;
1350 info->dwVendorId = 0;
1351 info->dwDeviceId = 0;
1352 info->dwSubSysId = 0;
1353 info->dwRevision = 0;
1356 args->arraysize--;
1359 args->numdev++;
1360 return TRUE;
1363 static HRESULT WINAPI VMR7MonitorConfig_QueryInterface(IVMRMonitorConfig *iface, REFIID riid,
1364 LPVOID * ppv)
1366 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1367 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1370 static ULONG WINAPI VMR7MonitorConfig_AddRef(IVMRMonitorConfig *iface)
1372 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1373 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1376 static ULONG WINAPI VMR7MonitorConfig_Release(IVMRMonitorConfig *iface)
1378 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1379 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1382 static HRESULT WINAPI VMR7MonitorConfig_SetMonitor(IVMRMonitorConfig *iface, const VMRGUID *pGUID)
1384 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1386 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1388 if (!pGUID)
1389 return E_POINTER;
1391 return S_OK;
1394 static HRESULT WINAPI VMR7MonitorConfig_GetMonitor(IVMRMonitorConfig *iface, 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 pGUID->pGUID = NULL; /* default DirectDraw device */
1404 return S_OK;
1407 static HRESULT WINAPI VMR7MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig *iface,
1408 const VMRGUID *pGUID)
1410 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1412 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1414 if (!pGUID)
1415 return E_POINTER;
1417 return S_OK;
1420 static HRESULT WINAPI VMR7MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig *iface, VMRGUID *pGUID)
1422 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1424 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1426 if (!pGUID)
1427 return E_POINTER;
1429 pGUID->pGUID = NULL; /* default DirectDraw device */
1430 return S_OK;
1433 static HRESULT WINAPI VMR7MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig *iface,
1434 VMRMONITORINFO *info, DWORD arraysize,
1435 DWORD *numdev)
1437 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1438 struct get_available_monitors_args args;
1440 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1442 if (!numdev)
1443 return E_POINTER;
1445 if (info && arraysize == 0)
1446 return E_INVALIDARG;
1448 args.info7 = info;
1449 args.info9 = NULL;
1450 args.arraysize = arraysize;
1451 args.numdev = 0;
1452 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1454 *numdev = args.numdev;
1455 return S_OK;
1458 static const IVMRMonitorConfigVtbl VMR7_MonitorConfig_Vtbl =
1460 VMR7MonitorConfig_QueryInterface,
1461 VMR7MonitorConfig_AddRef,
1462 VMR7MonitorConfig_Release,
1463 VMR7MonitorConfig_SetMonitor,
1464 VMR7MonitorConfig_GetMonitor,
1465 VMR7MonitorConfig_SetDefaultMonitor,
1466 VMR7MonitorConfig_GetDefaultMonitor,
1467 VMR7MonitorConfig_GetAvailableMonitors
1470 static HRESULT WINAPI VMR9MonitorConfig_QueryInterface(IVMRMonitorConfig9 *iface, REFIID riid,
1471 LPVOID * ppv)
1473 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1474 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1477 static ULONG WINAPI VMR9MonitorConfig_AddRef(IVMRMonitorConfig9 *iface)
1479 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1480 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1483 static ULONG WINAPI VMR9MonitorConfig_Release(IVMRMonitorConfig9 *iface)
1485 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1486 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1489 static HRESULT WINAPI VMR9MonitorConfig_SetMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1491 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1493 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1495 return S_OK;
1498 static HRESULT WINAPI VMR9MonitorConfig_GetMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1500 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1502 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1504 if (!uDev)
1505 return E_POINTER;
1507 *uDev = 0;
1508 return S_OK;
1511 static HRESULT WINAPI VMR9MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1513 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1515 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1517 return S_OK;
1520 static HRESULT WINAPI VMR9MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1522 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1524 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1526 if (!uDev)
1527 return E_POINTER;
1529 *uDev = 0;
1530 return S_OK;
1533 static HRESULT WINAPI VMR9MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig9 *iface,
1534 VMR9MonitorInfo *info, DWORD arraysize,
1535 DWORD *numdev)
1537 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1538 struct get_available_monitors_args args;
1540 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1542 if (!numdev)
1543 return E_POINTER;
1545 if (info && arraysize == 0)
1546 return E_INVALIDARG;
1548 args.info7 = NULL;
1549 args.info9 = info;
1550 args.arraysize = arraysize;
1551 args.numdev = 0;
1552 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1554 *numdev = args.numdev;
1555 return S_OK;
1558 static const IVMRMonitorConfig9Vtbl VMR9_MonitorConfig_Vtbl =
1560 VMR9MonitorConfig_QueryInterface,
1561 VMR9MonitorConfig_AddRef,
1562 VMR9MonitorConfig_Release,
1563 VMR9MonitorConfig_SetMonitor,
1564 VMR9MonitorConfig_GetMonitor,
1565 VMR9MonitorConfig_SetDefaultMonitor,
1566 VMR9MonitorConfig_GetDefaultMonitor,
1567 VMR9MonitorConfig_GetAvailableMonitors
1570 static HRESULT WINAPI VMR9FilterConfig_QueryInterface(IVMRFilterConfig9 *iface, REFIID riid, LPVOID * ppv)
1572 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1573 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1576 static ULONG WINAPI VMR9FilterConfig_AddRef(IVMRFilterConfig9 *iface)
1578 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1579 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1582 static ULONG WINAPI VMR9FilterConfig_Release(IVMRFilterConfig9 *iface)
1584 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1585 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1588 static HRESULT WINAPI VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9 *iface, IVMRImageCompositor9 *compositor)
1590 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1592 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
1593 return E_NOTIMPL;
1596 static HRESULT WINAPI VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD max)
1598 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1600 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
1601 return E_NOTIMPL;
1604 static HRESULT WINAPI VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD *max)
1606 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1608 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
1609 return E_NOTIMPL;
1612 static HRESULT WINAPI VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD renderflags)
1614 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1616 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
1617 return E_NOTIMPL;
1620 static HRESULT WINAPI VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD *renderflags)
1622 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1624 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
1625 return E_NOTIMPL;
1628 static HRESULT WINAPI VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 *iface, DWORD mode)
1630 HRESULT hr = S_OK;
1631 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1633 TRACE("(%p/%p)->(%u)\n", iface, This, mode);
1635 EnterCriticalSection(&This->renderer.filter.csFilter);
1636 if (This->mode)
1638 LeaveCriticalSection(&This->renderer.filter.csFilter);
1639 return VFW_E_WRONG_STATE;
1642 if (This->allocator)
1643 IVMRSurfaceAllocatorEx9_Release(This->allocator);
1644 if (This->presenter)
1645 IVMRImagePresenter9_Release(This->presenter);
1647 This->allocator = NULL;
1648 This->presenter = NULL;
1650 switch (mode)
1652 case VMR9Mode_Windowed:
1653 case VMR9Mode_Windowless:
1654 This->allocator_is_ex = 0;
1655 This->cookie = ~0;
1657 hr = VMR9DefaultAllocatorPresenterImpl_create(This, (LPVOID*)&This->presenter);
1658 if (SUCCEEDED(hr))
1659 hr = IVMRImagePresenter9_QueryInterface(This->presenter, &IID_IVMRSurfaceAllocatorEx9, (LPVOID*)&This->allocator);
1660 if (FAILED(hr))
1662 ERR("Unable to find Presenter interface\n");
1663 IVMRImagePresenter9_Release(This->presenter);
1664 This->allocator = NULL;
1665 This->presenter = NULL;
1667 else
1668 hr = IVMRSurfaceAllocatorEx9_AdviseNotify(This->allocator, &This->IVMRSurfaceAllocatorNotify9_iface);
1669 break;
1670 case VMR9Mode_Renderless:
1671 break;
1672 default:
1673 LeaveCriticalSection(&This->renderer.filter.csFilter);
1674 return E_INVALIDARG;
1677 This->mode = mode;
1678 LeaveCriticalSection(&This->renderer.filter.csFilter);
1679 return hr;
1682 static HRESULT WINAPI VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9 *iface, DWORD *mode)
1684 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1686 TRACE("(%p/%p)->(%p) stub\n", iface, This, mode);
1687 if (!mode)
1688 return E_POINTER;
1690 if (This->mode)
1691 *mode = This->mode;
1692 else
1693 *mode = VMR9Mode_Windowed;
1695 return S_OK;
1698 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl =
1700 VMR9FilterConfig_QueryInterface,
1701 VMR9FilterConfig_AddRef,
1702 VMR9FilterConfig_Release,
1703 VMR9FilterConfig_SetImageCompositor,
1704 VMR9FilterConfig_SetNumberOfStreams,
1705 VMR9FilterConfig_GetNumberOfStreams,
1706 VMR9FilterConfig_SetRenderingPrefs,
1707 VMR9FilterConfig_GetRenderingPrefs,
1708 VMR9FilterConfig_SetRenderingMode,
1709 VMR9FilterConfig_GetRenderingMode
1712 static HRESULT WINAPI VMR7WindowlessControl_QueryInterface(IVMRWindowlessControl *iface, REFIID riid,
1713 LPVOID * ppv)
1715 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1716 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1719 static ULONG WINAPI VMR7WindowlessControl_AddRef(IVMRWindowlessControl *iface)
1721 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1722 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1725 static ULONG WINAPI VMR7WindowlessControl_Release(IVMRWindowlessControl *iface)
1727 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1728 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1731 static HRESULT WINAPI VMR7WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl *iface,
1732 LONG *width, LONG *height,
1733 LONG *arwidth, LONG *arheight)
1735 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1736 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1738 if (!width || !height || !arwidth || !arheight)
1740 ERR("Got no pointer\n");
1741 return E_POINTER;
1744 *width = This->bmiheader.biWidth;
1745 *height = This->bmiheader.biHeight;
1746 *arwidth = This->bmiheader.biWidth;
1747 *arheight = This->bmiheader.biHeight;
1749 return S_OK;
1752 static HRESULT WINAPI VMR7WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl *iface,
1753 LONG *width, LONG *height)
1755 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1757 FIXME("(%p/%p)->(...) stub\n", iface, This);
1758 return E_NOTIMPL;
1761 static HRESULT WINAPI VMR7WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl *iface,
1762 LONG *width, LONG *height)
1764 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1766 FIXME("(%p/%p)->(...) stub\n", iface, This);
1767 return E_NOTIMPL;
1770 static HRESULT WINAPI VMR7WindowlessControl_SetVideoPosition(IVMRWindowlessControl *iface,
1771 const RECT *source, const RECT *dest)
1773 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1775 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1777 EnterCriticalSection(&This->renderer.filter.csFilter);
1779 if (source)
1780 This->source_rect = *source;
1781 if (dest)
1783 This->target_rect = *dest;
1784 if (This->baseControlWindow.baseWindow.hWnd)
1786 FIXME("Output rectangle: starting at %dx%d, up to point %dx%d\n",
1787 dest->left, dest->top, dest->right, dest->bottom);
1788 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
1789 dest->left, dest->top, dest->right - dest->left, dest->bottom-dest->top,
1790 SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW);
1794 LeaveCriticalSection(&This->renderer.filter.csFilter);
1796 return S_OK;
1799 static HRESULT WINAPI VMR7WindowlessControl_GetVideoPosition(IVMRWindowlessControl *iface,
1800 RECT *source, RECT *dest)
1802 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1804 if (source)
1805 *source = This->source_rect;
1807 if (dest)
1808 *dest = This->target_rect;
1810 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
1811 return S_OK;
1814 static HRESULT WINAPI VMR7WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl *iface,
1815 DWORD *mode)
1817 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1819 FIXME("(%p/%p)->(...) stub\n", iface, This);
1820 return E_NOTIMPL;
1823 static HRESULT WINAPI VMR7WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl *iface,
1824 DWORD mode)
1826 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1828 FIXME("(%p/%p)->(...) stub\n", iface, This);
1829 return E_NOTIMPL;
1832 static HRESULT WINAPI VMR7WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl *iface,
1833 HWND hwnd)
1835 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1837 FIXME("(%p/%p)->(...) stub\n", iface, This);
1838 return E_NOTIMPL;
1841 static HRESULT WINAPI VMR7WindowlessControl_RepaintVideo(IVMRWindowlessControl *iface,
1842 HWND hwnd, HDC hdc)
1844 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1846 FIXME("(%p/%p)->(...) stub\n", iface, This);
1847 return E_NOTIMPL;
1850 static HRESULT WINAPI VMR7WindowlessControl_DisplayModeChanged(IVMRWindowlessControl *iface)
1852 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1854 FIXME("(%p/%p)->(...) stub\n", iface, This);
1855 return E_NOTIMPL;
1858 static HRESULT WINAPI VMR7WindowlessControl_GetCurrentImage(IVMRWindowlessControl *iface,
1859 BYTE **dib)
1861 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1863 FIXME("(%p/%p)->(...) stub\n", iface, This);
1864 return E_NOTIMPL;
1867 static HRESULT WINAPI VMR7WindowlessControl_SetBorderColor(IVMRWindowlessControl *iface,
1868 COLORREF color)
1870 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1872 FIXME("(%p/%p)->(...) stub\n", iface, This);
1873 return E_NOTIMPL;
1876 static HRESULT WINAPI VMR7WindowlessControl_GetBorderColor(IVMRWindowlessControl *iface,
1877 COLORREF *color)
1879 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1881 FIXME("(%p/%p)->(...) stub\n", iface, This);
1882 return E_NOTIMPL;
1885 static HRESULT WINAPI VMR7WindowlessControl_SetColorKey(IVMRWindowlessControl *iface, COLORREF color)
1887 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1889 FIXME("(%p/%p)->(...) stub\n", iface, This);
1890 return E_NOTIMPL;
1893 static HRESULT WINAPI VMR7WindowlessControl_GetColorKey(IVMRWindowlessControl *iface, COLORREF *color)
1895 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1897 FIXME("(%p/%p)->(...) stub\n", iface, This);
1898 return E_NOTIMPL;
1901 static const IVMRWindowlessControlVtbl VMR7_WindowlessControl_Vtbl =
1903 VMR7WindowlessControl_QueryInterface,
1904 VMR7WindowlessControl_AddRef,
1905 VMR7WindowlessControl_Release,
1906 VMR7WindowlessControl_GetNativeVideoSize,
1907 VMR7WindowlessControl_GetMinIdealVideoSize,
1908 VMR7WindowlessControl_GetMaxIdealVideoSize,
1909 VMR7WindowlessControl_SetVideoPosition,
1910 VMR7WindowlessControl_GetVideoPosition,
1911 VMR7WindowlessControl_GetAspectRatioMode,
1912 VMR7WindowlessControl_SetAspectRatioMode,
1913 VMR7WindowlessControl_SetVideoClippingWindow,
1914 VMR7WindowlessControl_RepaintVideo,
1915 VMR7WindowlessControl_DisplayModeChanged,
1916 VMR7WindowlessControl_GetCurrentImage,
1917 VMR7WindowlessControl_SetBorderColor,
1918 VMR7WindowlessControl_GetBorderColor,
1919 VMR7WindowlessControl_SetColorKey,
1920 VMR7WindowlessControl_GetColorKey
1923 static HRESULT WINAPI VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9 *iface, REFIID riid, LPVOID * ppv)
1925 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1926 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1929 static ULONG WINAPI VMR9WindowlessControl_AddRef(IVMRWindowlessControl9 *iface)
1931 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1932 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1935 static ULONG WINAPI VMR9WindowlessControl_Release(IVMRWindowlessControl9 *iface)
1937 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1938 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1941 static HRESULT WINAPI VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height, LONG *arwidth, LONG *arheight)
1943 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1944 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1946 if (!width || !height || !arwidth || !arheight)
1948 ERR("Got no pointer\n");
1949 return E_POINTER;
1952 *width = This->bmiheader.biWidth;
1953 *height = This->bmiheader.biHeight;
1954 *arwidth = This->bmiheader.biWidth;
1955 *arheight = This->bmiheader.biHeight;
1957 return S_OK;
1960 static HRESULT WINAPI VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1962 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1964 FIXME("(%p/%p)->(...) stub\n", iface, This);
1965 return E_NOTIMPL;
1968 static HRESULT WINAPI VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1970 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1972 FIXME("(%p/%p)->(...) stub\n", iface, This);
1973 return E_NOTIMPL;
1976 static HRESULT WINAPI VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9 *iface, const RECT *source, const RECT *dest)
1978 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1980 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1982 EnterCriticalSection(&This->renderer.filter.csFilter);
1984 if (source)
1985 This->source_rect = *source;
1986 if (dest)
1988 This->target_rect = *dest;
1989 if (This->baseControlWindow.baseWindow.hWnd)
1991 FIXME("Output rectangle: starting at %dx%d, up to point %dx%d\n", dest->left, dest->top, dest->right, dest->bottom);
1992 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, dest->left, dest->top, dest->right - dest->left,
1993 dest->bottom-dest->top, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW);
1997 LeaveCriticalSection(&This->renderer.filter.csFilter);
1999 return S_OK;
2002 static HRESULT WINAPI VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9 *iface, RECT *source, RECT *dest)
2004 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2006 if (source)
2007 *source = This->source_rect;
2009 if (dest)
2010 *dest = This->target_rect;
2012 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
2013 return S_OK;
2016 static HRESULT WINAPI VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD *mode)
2018 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2020 FIXME("(%p/%p)->(...) stub\n", iface, This);
2021 return E_NOTIMPL;
2024 static HRESULT WINAPI VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD mode)
2026 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2028 FIXME("(%p/%p)->(...) stub\n", iface, This);
2029 return E_NOTIMPL;
2032 static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9 *iface, HWND hwnd)
2034 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2036 TRACE("(%p/%p)->(%p)\n", iface, This, hwnd);
2038 EnterCriticalSection(&This->renderer.filter.csFilter);
2039 This->hWndClippingWindow = hwnd;
2040 VMR9_maybe_init(This, FALSE);
2041 if (!hwnd)
2042 IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie);
2043 LeaveCriticalSection(&This->renderer.filter.csFilter);
2044 return S_OK;
2047 static HRESULT WINAPI VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9 *iface, HWND hwnd, HDC hdc)
2049 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2050 HRESULT hr;
2052 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2054 EnterCriticalSection(&This->renderer.filter.csFilter);
2055 if (hwnd != This->hWndClippingWindow && hwnd != This->baseControlWindow.baseWindow.hWnd)
2057 ERR("Not handling changing windows yet!!!\n");
2058 LeaveCriticalSection(&This->renderer.filter.csFilter);
2059 return S_OK;
2062 if (!This->allocator_d3d9_dev)
2064 ERR("No d3d9 device!\n");
2065 LeaveCriticalSection(&This->renderer.filter.csFilter);
2066 return VFW_E_WRONG_STATE;
2069 /* Windowless extension */
2070 hr = IDirect3DDevice9_Present(This->allocator_d3d9_dev, NULL, NULL, This->baseControlWindow.baseWindow.hWnd, NULL);
2071 LeaveCriticalSection(&This->renderer.filter.csFilter);
2073 return hr;
2076 static HRESULT WINAPI VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9 *iface)
2078 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2080 FIXME("(%p/%p)->(...) stub\n", iface, This);
2081 return E_NOTIMPL;
2084 static HRESULT WINAPI VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9 *iface, BYTE **dib)
2086 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2088 FIXME("(%p/%p)->(...) stub\n", iface, This);
2089 return E_NOTIMPL;
2092 static HRESULT WINAPI VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9 *iface, COLORREF color)
2094 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2096 FIXME("(%p/%p)->(...) stub\n", iface, This);
2097 return E_NOTIMPL;
2100 static HRESULT WINAPI VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9 *iface, COLORREF *color)
2102 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2104 FIXME("(%p/%p)->(...) stub\n", iface, This);
2105 return E_NOTIMPL;
2108 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl =
2110 VMR9WindowlessControl_QueryInterface,
2111 VMR9WindowlessControl_AddRef,
2112 VMR9WindowlessControl_Release,
2113 VMR9WindowlessControl_GetNativeVideoSize,
2114 VMR9WindowlessControl_GetMinIdealVideoSize,
2115 VMR9WindowlessControl_GetMaxIdealVideoSize,
2116 VMR9WindowlessControl_SetVideoPosition,
2117 VMR9WindowlessControl_GetVideoPosition,
2118 VMR9WindowlessControl_GetAspectRatioMode,
2119 VMR9WindowlessControl_SetAspectRatioMode,
2120 VMR9WindowlessControl_SetVideoClippingWindow,
2121 VMR9WindowlessControl_RepaintVideo,
2122 VMR9WindowlessControl_DisplayModeChanged,
2123 VMR9WindowlessControl_GetCurrentImage,
2124 VMR9WindowlessControl_SetBorderColor,
2125 VMR9WindowlessControl_GetBorderColor
2128 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify *iface,
2129 REFIID riid, LPVOID * ppv)
2131 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2132 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
2135 static ULONG WINAPI VMR7SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify *iface)
2137 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2138 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
2141 static ULONG WINAPI VMR7SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify *iface)
2143 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2144 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
2147 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify *iface,
2148 DWORD_PTR id,
2149 IVMRSurfaceAllocator *alloc)
2151 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2153 FIXME("(%p/%p)->(...) stub\n", iface, This);
2154 return E_NOTIMPL;
2157 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
2158 IDirectDraw7 *device, HMONITOR monitor)
2160 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2162 FIXME("(%p/%p)->(...) stub\n", iface, This);
2163 return E_NOTIMPL;
2166 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_ChangeDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
2167 IDirectDraw7 *device, HMONITOR monitor)
2169 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2171 FIXME("(%p/%p)->(...) stub\n", iface, This);
2172 return E_NOTIMPL;
2175 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces(IVMRSurfaceAllocatorNotify *iface)
2177 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2179 FIXME("(%p/%p)->(...) stub\n", iface, This);
2180 return E_NOTIMPL;
2183 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify *iface, LONG code,
2184 LONG_PTR param1, LONG_PTR param2)
2186 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2188 FIXME("(%p/%p)->(...) stub\n", iface, This);
2189 return E_NOTIMPL;
2192 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetBorderColor(IVMRSurfaceAllocatorNotify *iface,
2193 COLORREF clrBorder)
2195 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2197 FIXME("(%p/%p)->(...) stub\n", iface, This);
2198 return E_NOTIMPL;
2201 static const IVMRSurfaceAllocatorNotifyVtbl VMR7_SurfaceAllocatorNotify_Vtbl =
2203 VMR7SurfaceAllocatorNotify_QueryInterface,
2204 VMR7SurfaceAllocatorNotify_AddRef,
2205 VMR7SurfaceAllocatorNotify_Release,
2206 VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator,
2207 VMR7SurfaceAllocatorNotify_SetDDrawDevice,
2208 VMR7SurfaceAllocatorNotify_ChangeDDrawDevice,
2209 VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces,
2210 VMR7SurfaceAllocatorNotify_NotifyEvent,
2211 VMR7SurfaceAllocatorNotify_SetBorderColor
2214 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9 *iface, REFIID riid, LPVOID * ppv)
2216 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2217 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
2220 static ULONG WINAPI VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9 *iface)
2222 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2223 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
2226 static ULONG WINAPI VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9 *iface)
2228 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2229 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
2232 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9 *iface, DWORD_PTR id, IVMRSurfaceAllocator9 *alloc)
2234 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2236 /* FIXME: This code is not tested!!! */
2237 FIXME("(%p/%p)->(...) stub\n", iface, This);
2238 This->cookie = id;
2240 if (This->presenter)
2241 return VFW_E_WRONG_STATE;
2243 if (FAILED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRImagePresenter9, (void **)&This->presenter)))
2244 return E_NOINTERFACE;
2246 if (SUCCEEDED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRSurfaceAllocatorEx9, (void **)&This->allocator)))
2247 This->allocator_is_ex = 1;
2248 else
2250 This->allocator = (IVMRSurfaceAllocatorEx9 *)alloc;
2251 IVMRSurfaceAllocator9_AddRef(alloc);
2252 This->allocator_is_ex = 0;
2255 return S_OK;
2258 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
2260 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2262 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2263 if (This->allocator_d3d9_dev)
2264 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
2265 This->allocator_d3d9_dev = device;
2266 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
2267 This->allocator_mon = monitor;
2269 return S_OK;
2272 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
2274 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2276 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2277 if (This->allocator_d3d9_dev)
2278 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
2279 This->allocator_d3d9_dev = device;
2280 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
2281 This->allocator_mon = monitor;
2283 return S_OK;
2286 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9 *iface, VMR9AllocationInfo *allocinfo, DWORD *numbuffers, IDirect3DSurface9 **surface)
2288 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2289 DWORD i;
2290 HRESULT hr = S_OK;
2292 FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface, This, allocinfo, numbuffers, (numbuffers ? *numbuffers : 0), surface);
2294 if (!allocinfo || !numbuffers || !surface)
2295 return E_POINTER;
2297 if (!*numbuffers || *numbuffers < allocinfo->MinBuffers)
2299 ERR("Invalid number of buffers?\n");
2300 return E_INVALIDARG;
2303 if (!This->allocator_d3d9_dev)
2305 ERR("No direct3d device when requested to allocate a surface!\n");
2306 return VFW_E_WRONG_STATE;
2309 if (allocinfo->dwFlags & VMR9AllocFlag_OffscreenSurface)
2311 ERR("Creating offscreen surface\n");
2312 for (i = 0; i < *numbuffers; ++i)
2314 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight,
2315 allocinfo->Format, allocinfo->Pool, &surface[i], NULL);
2316 if (FAILED(hr))
2317 break;
2320 else if (allocinfo->dwFlags & VMR9AllocFlag_TextureSurface)
2322 TRACE("Creating texture surface\n");
2323 for (i = 0; i < *numbuffers; ++i)
2325 IDirect3DTexture9 *texture;
2327 hr = IDirect3DDevice9_CreateTexture(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight, 1, 0,
2328 allocinfo->Format, allocinfo->Pool, &texture, NULL);
2329 if (FAILED(hr))
2330 break;
2331 IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface[i]);
2332 IDirect3DTexture9_Release(texture);
2335 else
2337 FIXME("Could not allocate for type %08x\n", allocinfo->dwFlags);
2338 return E_NOTIMPL;
2341 if (i >= allocinfo->MinBuffers)
2343 hr = S_OK;
2344 *numbuffers = i;
2346 else
2348 for ( ; i > 0; --i) IDirect3DSurface9_Release(surface[i - 1]);
2349 *numbuffers = 0;
2351 return hr;
2354 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9 *iface, LONG code, LONG_PTR param1, LONG_PTR param2)
2356 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2358 FIXME("(%p/%p)->(...) stub\n", iface, This);
2359 return E_NOTIMPL;
2362 static const IVMRSurfaceAllocatorNotify9Vtbl VMR9_SurfaceAllocatorNotify_Vtbl =
2364 VMR9SurfaceAllocatorNotify_QueryInterface,
2365 VMR9SurfaceAllocatorNotify_AddRef,
2366 VMR9SurfaceAllocatorNotify_Release,
2367 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator,
2368 VMR9SurfaceAllocatorNotify_SetD3DDevice,
2369 VMR9SurfaceAllocatorNotify_ChangeD3DDevice,
2370 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper,
2371 VMR9SurfaceAllocatorNotify_NotifyEvent
2374 static HRESULT vmr_create(IUnknown *outer_unk, LPVOID *ppv, const CLSID *clsid)
2376 HRESULT hr;
2377 struct quartz_vmr* pVMR;
2379 TRACE("(%p, %p)\n", outer_unk, ppv);
2381 *ppv = NULL;
2383 pVMR = CoTaskMemAlloc(sizeof(struct quartz_vmr));
2385 pVMR->hD3d9 = LoadLibraryA("d3d9.dll");
2386 if (!pVMR->hD3d9 )
2388 WARN("Could not load d3d9.dll\n");
2389 CoTaskMemFree(pVMR);
2390 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
2393 pVMR->outer_unk = outer_unk;
2394 pVMR->bUnkOuterValid = FALSE;
2395 pVMR->bAggregatable = FALSE;
2396 pVMR->IUnknown_inner.lpVtbl = &IInner_VTable;
2397 pVMR->IAMCertifiedOutputProtection_iface.lpVtbl = &IAMCertifiedOutputProtection_Vtbl;
2398 pVMR->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl;
2400 pVMR->mode = 0;
2401 pVMR->allocator_d3d9_dev = NULL;
2402 pVMR->allocator_mon= NULL;
2403 pVMR->num_surfaces = pVMR->cur_surface = 0;
2404 pVMR->allocator = NULL;
2405 pVMR->presenter = NULL;
2406 pVMR->hWndClippingWindow = NULL;
2407 pVMR->IVMRFilterConfig_iface.lpVtbl = &VMR7_FilterConfig_Vtbl;
2408 pVMR->IVMRFilterConfig9_iface.lpVtbl = &VMR9_FilterConfig_Vtbl;
2409 pVMR->IVMRMonitorConfig_iface.lpVtbl = &VMR7_MonitorConfig_Vtbl;
2410 pVMR->IVMRMonitorConfig9_iface.lpVtbl = &VMR9_MonitorConfig_Vtbl;
2411 pVMR->IVMRSurfaceAllocatorNotify_iface.lpVtbl = &VMR7_SurfaceAllocatorNotify_Vtbl;
2412 pVMR->IVMRSurfaceAllocatorNotify9_iface.lpVtbl = &VMR9_SurfaceAllocatorNotify_Vtbl;
2413 pVMR->IVMRWindowlessControl_iface.lpVtbl = &VMR7_WindowlessControl_Vtbl;
2414 pVMR->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl;
2416 if (IsEqualGUID(clsid, &CLSID_VideoMixingRenderer))
2417 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer,
2418 (DWORD_PTR)(__FILE__ ": VMR7Impl.csFilter"), &BaseFuncTable);
2419 else
2420 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer9,
2421 (DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable);
2423 if (FAILED(hr))
2424 goto fail;
2426 hr = BaseControlWindow_Init(&pVMR->baseControlWindow, &IVideoWindow_VTable, &pVMR->renderer.filter,
2427 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin,
2428 &renderer_BaseWindowFuncTable);
2429 if (FAILED(hr))
2430 goto fail;
2432 hr = BaseControlVideo_Init(&pVMR->baseControlVideo, &IBasicVideo_VTable, &pVMR->renderer.filter,
2433 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin,
2434 &renderer_BaseControlVideoFuncTable);
2435 if (FAILED(hr))
2436 goto fail;
2438 *ppv = (LPVOID)pVMR;
2439 ZeroMemory(&pVMR->source_rect, sizeof(RECT));
2440 ZeroMemory(&pVMR->target_rect, sizeof(RECT));
2441 TRACE("Created at %p\n", pVMR);
2442 return hr;
2444 fail:
2445 BaseRendererImpl_Release(&pVMR->renderer.filter.IBaseFilter_iface);
2446 FreeLibrary(pVMR->hD3d9);
2447 CoTaskMemFree(pVMR);
2448 return hr;
2451 HRESULT VMR7Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2453 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer);
2456 HRESULT VMR9Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2458 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer9);
2462 static HRESULT WINAPI VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID riid, LPVOID * ppv)
2464 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2465 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
2467 *ppv = NULL;
2469 if (IsEqualIID(riid, &IID_IUnknown))
2470 *ppv = (LPVOID)&(This->IVMRImagePresenter9_iface);
2471 else if (IsEqualIID(riid, &IID_IVMRImagePresenter9))
2472 *ppv = &This->IVMRImagePresenter9_iface;
2473 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorEx9))
2474 *ppv = &This->IVMRSurfaceAllocatorEx9_iface;
2476 if (*ppv)
2478 IUnknown_AddRef((IUnknown *)(*ppv));
2479 return S_OK;
2482 FIXME("No interface for %s\n", debugstr_guid(riid));
2484 return E_NOINTERFACE;
2487 static ULONG WINAPI VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 *iface)
2489 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2490 ULONG refCount = InterlockedIncrement(&This->refCount);
2492 TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
2494 return refCount;
2497 static ULONG WINAPI VMR9_ImagePresenter_Release(IVMRImagePresenter9 *iface)
2499 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2500 ULONG refCount = InterlockedDecrement(&This->refCount);
2502 TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
2504 if (!refCount)
2506 DWORD i;
2507 TRACE("Destroying\n");
2508 CloseHandle(This->ack);
2509 IDirect3D9_Release(This->d3d9_ptr);
2511 TRACE("Number of surfaces: %u\n", This->num_surfaces);
2512 for (i = 0; i < This->num_surfaces; ++i)
2514 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2515 TRACE("Releasing surface %p\n", surface);
2516 if (surface)
2517 IDirect3DSurface9_Release(surface);
2520 CoTaskMemFree(This->d3d9_surfaces);
2521 This->d3d9_surfaces = NULL;
2522 This->num_surfaces = 0;
2523 if (This->d3d9_vertex)
2525 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2526 This->d3d9_vertex = NULL;
2528 CoTaskMemFree(This);
2529 return 0;
2531 return refCount;
2534 static HRESULT WINAPI VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2536 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2538 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2539 return S_OK;
2542 static HRESULT WINAPI VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2544 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2546 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2547 return S_OK;
2550 #define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
2551 struct VERTEX { float x, y, z, rhw, u, v; };
2553 static HRESULT VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2555 IDirect3DTexture9 *texture = NULL;
2556 HRESULT hr;
2558 hr = IDirect3DDevice9_SetFVF(This->d3d9_dev, USED_FVF);
2559 if (FAILED(hr))
2561 FIXME("SetFVF: %08x\n", hr);
2562 return hr;
2565 hr = IDirect3DDevice9_SetStreamSource(This->d3d9_dev, 0, This->d3d9_vertex, 0, sizeof(struct VERTEX));
2566 if (FAILED(hr))
2568 FIXME("SetStreamSource: %08x\n", hr);
2569 return hr;
2572 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **) &texture);
2573 if (FAILED(hr))
2575 FIXME("IDirect3DSurface9_GetContainer failed\n");
2576 return hr;
2578 hr = IDirect3DDevice9_SetTexture(This->d3d9_dev, 0, (IDirect3DBaseTexture9 *)texture);
2579 IDirect3DTexture9_Release(texture);
2580 if (FAILED(hr))
2582 FIXME("SetTexture: %08x\n", hr);
2583 return hr;
2586 hr = IDirect3DDevice9_DrawPrimitive(This->d3d9_dev, D3DPT_TRIANGLESTRIP, 0, 2);
2587 if (FAILED(hr))
2589 FIXME("DrawPrimitive: %08x\n", hr);
2590 return hr;
2593 return S_OK;
2596 static HRESULT VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2598 HRESULT hr;
2599 IDirect3DSurface9 *target = NULL;
2600 RECT target_rect;
2602 hr = IDirect3DDevice9_GetBackBuffer(This->d3d9_dev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &target);
2603 if (FAILED(hr))
2605 ERR("IDirect3DDevice9_GetBackBuffer -- %08x\n", hr);
2606 return hr;
2609 target_rect = This->pVMR9->target_rect;
2610 target_rect.right -= target_rect.left;
2611 target_rect.bottom -= target_rect.top;
2612 target_rect.left = target_rect.top = 0;
2614 /* Flip */
2615 target_rect.top = target_rect.bottom;
2616 target_rect.bottom = 0;
2618 hr = IDirect3DDevice9_StretchRect(This->d3d9_dev, surface, &This->pVMR9->source_rect, target, &target_rect, D3DTEXF_LINEAR);
2619 if (FAILED(hr))
2620 ERR("IDirect3DDevice9_StretchRect -- %08x\n", hr);
2621 IDirect3DSurface9_Release(target);
2623 return hr;
2626 static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR id, VMR9PresentationInfo *info)
2628 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2629 HRESULT hr;
2630 RECT output;
2631 BOOL render = FALSE;
2633 TRACE("(%p/%p/%p)->(...) stub\n", iface, This, This->pVMR9);
2634 GetWindowRect(This->pVMR9->baseControlWindow.baseWindow.hWnd, &output);
2635 TRACE("Output rectangle: starting at %dx%d, up to point %dx%d\n", output.left, output.top, output.right, output.bottom);
2637 /* This might happen if we don't have active focus (eg on a different virtual desktop) */
2638 if (!This->d3d9_dev)
2639 return S_OK;
2641 /* Display image here */
2642 hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
2643 if (FAILED(hr))
2644 FIXME("hr: %08x\n", hr);
2645 hr = IDirect3DDevice9_BeginScene(This->d3d9_dev);
2646 if (SUCCEEDED(hr))
2648 if (This->d3d9_vertex)
2649 hr = VMR9_ImagePresenter_PresentTexture(This, info->lpSurf);
2650 else
2651 hr = VMR9_ImagePresenter_PresentOffscreenSurface(This, info->lpSurf);
2652 render = SUCCEEDED(hr);
2654 else
2655 FIXME("BeginScene: %08x\n", hr);
2656 hr = IDirect3DDevice9_EndScene(This->d3d9_dev);
2657 if (render && SUCCEEDED(hr))
2659 hr = IDirect3DDevice9_Present(This->d3d9_dev, NULL, NULL, This->pVMR9->baseControlWindow.baseWindow.hWnd, NULL);
2660 if (FAILED(hr))
2661 FIXME("Presenting image: %08x\n", hr);
2664 return S_OK;
2667 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter =
2669 VMR9_ImagePresenter_QueryInterface,
2670 VMR9_ImagePresenter_AddRef,
2671 VMR9_ImagePresenter_Release,
2672 VMR9_ImagePresenter_StartPresenting,
2673 VMR9_ImagePresenter_StopPresenting,
2674 VMR9_ImagePresenter_PresentImage
2677 static HRESULT WINAPI VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9 *iface, REFIID riid, LPVOID * ppv)
2679 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2681 return VMR9_ImagePresenter_QueryInterface(&This->IVMRImagePresenter9_iface, riid, ppv);
2684 static ULONG WINAPI VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9 *iface)
2686 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2688 return VMR9_ImagePresenter_AddRef(&This->IVMRImagePresenter9_iface);
2691 static ULONG WINAPI VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9 *iface)
2693 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2695 return VMR9_ImagePresenter_Release(&This->IVMRImagePresenter9_iface);
2698 static HRESULT VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *allocinfo)
2700 D3DCAPS9 caps;
2701 UINT width, height;
2702 HRESULT hr;
2704 if (!(allocinfo->dwFlags & VMR9AllocFlag_TextureSurface))
2705 /* Only needed for texture surfaces */
2706 return S_OK;
2708 hr = IDirect3DDevice9_GetDeviceCaps(This->d3d9_dev, &caps);
2709 if (FAILED(hr))
2710 return hr;
2712 if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2) || (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY))
2714 width = allocinfo->dwWidth;
2715 height = allocinfo->dwHeight;
2717 else
2719 width = height = 1;
2720 while (width < allocinfo->dwWidth)
2721 width *= 2;
2723 while (height < allocinfo->dwHeight)
2724 height *= 2;
2725 FIXME("NPOW2 support missing, not using proper surfaces!\n");
2728 if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
2730 if (height > width)
2731 width = height;
2732 else
2733 height = width;
2734 FIXME("Square texture support required..\n");
2737 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF, allocinfo->Pool, &This->d3d9_vertex, NULL);
2738 if (FAILED(hr))
2740 ERR("Couldn't create vertex buffer: %08x\n", hr);
2741 return hr;
2744 This->reset = TRUE;
2745 allocinfo->dwHeight = height;
2746 allocinfo->dwWidth = width;
2748 return hr;
2751 static DWORD WINAPI MessageLoop(LPVOID lpParameter)
2753 MSG msg;
2754 BOOL fGotMessage;
2755 VMR9DefaultAllocatorPresenterImpl *This = lpParameter;
2757 TRACE("Starting message loop\n");
2759 if (FAILED(BaseWindowImpl_PrepareWindow(&This->pVMR9->baseControlWindow.baseWindow)))
2761 FIXME("Failed to prepare window\n");
2762 return FALSE;
2765 SetEvent(This->ack);
2766 while ((fGotMessage = GetMessageW(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1)
2768 TranslateMessage(&msg);
2769 DispatchMessageW(&msg);
2772 TRACE("End of message loop\n");
2774 return 0;
2777 static UINT d3d9_adapter_from_hwnd(IDirect3D9 *d3d9, HWND hwnd, HMONITOR *mon_out)
2779 UINT d3d9_adapter;
2780 HMONITOR mon;
2782 mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
2783 if (!mon)
2784 d3d9_adapter = 0;
2785 else
2787 for (d3d9_adapter = 0; d3d9_adapter < IDirect3D9_GetAdapterCount(d3d9); ++d3d9_adapter)
2789 if (mon == IDirect3D9_GetAdapterMonitor(d3d9, d3d9_adapter))
2790 break;
2792 if (d3d9_adapter >= IDirect3D9_GetAdapterCount(d3d9))
2793 d3d9_adapter = 0;
2795 if (mon_out)
2796 *mon_out = mon;
2797 return d3d9_adapter;
2800 static BOOL CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *info, DWORD *numbuffers)
2802 D3DPRESENT_PARAMETERS d3dpp;
2803 DWORD d3d9_adapter;
2804 HRESULT hr;
2806 TRACE("(%p)->()\n", This);
2808 This->hWndThread = CreateThread(NULL, 0, MessageLoop, This, 0, &This->tid);
2809 if (!This->hWndThread)
2810 return FALSE;
2812 WaitForSingleObject(This->ack, INFINITE);
2814 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) return FALSE;
2816 /* Obtain a monitor and d3d9 device */
2817 d3d9_adapter = d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon);
2819 /* Now try to create the d3d9 device */
2820 ZeroMemory(&d3dpp, sizeof(d3dpp));
2821 d3dpp.Windowed = TRUE;
2822 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2823 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2824 d3dpp.BackBufferHeight = This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top;
2825 d3dpp.BackBufferWidth = This->pVMR9->target_rect.right - This->pVMR9->target_rect.left;
2827 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev);
2828 if (FAILED(hr))
2830 ERR("Could not create device: %08x\n", hr);
2831 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2832 return FALSE;
2834 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2836 This->d3d9_surfaces = CoTaskMemAlloc(*numbuffers * sizeof(IDirect3DSurface9 *));
2837 ZeroMemory(This->d3d9_surfaces, *numbuffers * sizeof(IDirect3DSurface9 *));
2839 hr = VMR9_SurfaceAllocator_SetAllocationSettings(This, info);
2840 if (FAILED(hr))
2841 ERR("Setting allocation settings failed: %08x\n", hr);
2843 if (SUCCEEDED(hr))
2845 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, info, numbuffers, This->d3d9_surfaces);
2846 if (FAILED(hr))
2847 ERR("Allocating surfaces failed: %08x\n", hr);
2850 if (FAILED(hr))
2852 IVMRSurfaceAllocatorEx9_TerminateDevice(This->pVMR9->allocator, This->pVMR9->cookie);
2853 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2854 return FALSE;
2857 This->num_surfaces = *numbuffers;
2859 return TRUE;
2862 static HRESULT WINAPI VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, VMR9AllocationInfo *allocinfo, DWORD *numbuffers)
2864 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2866 if (This->pVMR9->mode != VMR9Mode_Windowed && !This->pVMR9->hWndClippingWindow)
2868 ERR("No window set\n");
2869 return VFW_E_WRONG_STATE;
2872 This->info = *allocinfo;
2874 if (!CreateRenderingWindow(This, allocinfo, numbuffers))
2876 ERR("Failed to create rendering window, expect no output!\n");
2877 return VFW_E_WRONG_STATE;
2880 return S_OK;
2883 static HRESULT WINAPI VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id)
2885 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2887 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
2889 return S_OK;
2892 SendMessageW(This->pVMR9->baseControlWindow.baseWindow.hWnd, WM_CLOSE, 0, 0);
2893 PostThreadMessageW(This->tid, WM_QUIT, 0, 0);
2894 WaitForSingleObject(This->hWndThread, INFINITE);
2895 This->hWndThread = NULL;
2896 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2898 return S_OK;
2901 /* Recreate all surfaces (If allocated as D3DPOOL_DEFAULT) and survive! */
2902 static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl *This)
2904 struct VERTEX t_vert[4];
2905 UINT width, height;
2906 unsigned int i;
2907 void *bits = NULL;
2908 D3DPRESENT_PARAMETERS d3dpp;
2909 HRESULT hr;
2911 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
2913 ERR("No window\n");
2914 return E_FAIL;
2917 if (!This->d3d9_surfaces || !This->reset)
2918 return S_OK;
2920 This->reset = FALSE;
2921 TRACE("RESETTING\n");
2922 if (This->d3d9_vertex)
2924 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2925 This->d3d9_vertex = NULL;
2928 for (i = 0; i < This->num_surfaces; ++i)
2930 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2931 TRACE("Releasing surface %p\n", surface);
2932 if (surface)
2933 IDirect3DSurface9_Release(surface);
2935 ZeroMemory(This->d3d9_surfaces, sizeof(IDirect3DSurface9 *) * This->num_surfaces);
2937 /* Now try to create the d3d9 device */
2938 ZeroMemory(&d3dpp, sizeof(d3dpp));
2939 d3dpp.Windowed = TRUE;
2940 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2941 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2943 if (This->d3d9_dev)
2944 IDirect3DDevice9_Release(This->d3d9_dev);
2945 This->d3d9_dev = NULL;
2946 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);
2947 if (FAILED(hr))
2949 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);
2950 if (FAILED(hr))
2952 ERR("--> Creating device: %08x\n", hr);
2953 return S_OK;
2956 IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2958 IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, &This->info, &This->num_surfaces, This->d3d9_surfaces);
2960 This->reset = FALSE;
2962 if (!(This->info.dwFlags & VMR9AllocFlag_TextureSurface))
2963 return S_OK;
2965 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF,
2966 This->info.Pool, &This->d3d9_vertex, NULL);
2968 width = This->info.dwWidth;
2969 height = This->info.dwHeight;
2971 for (i = 0; i < sizeof(t_vert) / sizeof(t_vert[0]); ++i)
2973 if (i % 2)
2975 t_vert[i].x = (float)This->pVMR9->target_rect.right - (float)This->pVMR9->target_rect.left - 0.5f;
2976 t_vert[i].u = (float)This->pVMR9->source_rect.right / (float)width;
2978 else
2980 t_vert[i].x = -0.5f;
2981 t_vert[i].u = (float)This->pVMR9->source_rect.left / (float)width;
2984 if (i % 4 < 2)
2986 t_vert[i].y = -0.5f;
2987 t_vert[i].v = (float)This->pVMR9->source_rect.bottom / (float)height;
2989 else
2991 t_vert[i].y = (float)This->pVMR9->target_rect.bottom - (float)This->pVMR9->target_rect.top - 0.5f;
2992 t_vert[i].v = (float)This->pVMR9->source_rect.top / (float)height;
2994 t_vert[i].z = 0.0f;
2995 t_vert[i].rhw = 1.0f;
2998 FIXME("Vertex rectangle:\n");
2999 FIXME("X, Y: %f, %f\n", t_vert[0].x, t_vert[0].y);
3000 FIXME("X, Y: %f, %f\n", t_vert[3].x, t_vert[3].y);
3001 FIXME("TOP, LEFT: %f, %f\n", t_vert[0].u, t_vert[0].v);
3002 FIXME("DOWN, BOTTOM: %f, %f\n", t_vert[3].u, t_vert[3].v);
3004 IDirect3DVertexBuffer9_Lock(This->d3d9_vertex, 0, sizeof(t_vert), &bits, 0);
3005 memcpy(bits, t_vert, sizeof(t_vert));
3006 IDirect3DVertexBuffer9_Unlock(This->d3d9_vertex);
3008 return S_OK;
3011 static HRESULT WINAPI VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, DWORD surfaceindex, DWORD flags, IDirect3DSurface9 **surface)
3013 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
3015 /* Update everything first, this is needed because the surface might be destroyed in the reset */
3016 if (!This->d3d9_dev)
3018 TRACE("Device has left me!\n");
3019 return E_FAIL;
3022 VMR9_SurfaceAllocator_UpdateDeviceReset(This);
3024 if (surfaceindex >= This->num_surfaces)
3026 ERR("surfaceindex is greater than num_surfaces\n");
3027 return E_FAIL;
3029 *surface = This->d3d9_surfaces[surfaceindex];
3030 IDirect3DSurface9_AddRef(*surface);
3032 return S_OK;
3035 static HRESULT WINAPI VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9 *iface, IVMRSurfaceAllocatorNotify9 *allocnotify)
3037 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
3039 TRACE("(%p/%p)->(...)\n", iface, This);
3041 /* No AddRef taken here or the base VMR9 filter would never be destroied */
3042 This->SurfaceAllocatorNotify = allocnotify;
3043 return S_OK;
3046 static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator =
3048 VMR9_SurfaceAllocator_QueryInterface,
3049 VMR9_SurfaceAllocator_AddRef,
3050 VMR9_SurfaceAllocator_Release,
3051 VMR9_SurfaceAllocator_InitializeDevice,
3052 VMR9_SurfaceAllocator_TerminateDevice,
3053 VMR9_SurfaceAllocator_GetSurface,
3054 VMR9_SurfaceAllocator_AdviseNotify,
3055 NULL /* This isn't the SurfaceAllocatorEx type yet, working on it */
3058 static IDirect3D9 *init_d3d9(HMODULE d3d9_handle)
3060 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion);
3062 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
3063 if (!d3d9_create) return NULL;
3065 return d3d9_create(D3D_SDK_VERSION);
3068 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv)
3070 HRESULT hr = S_OK;
3071 int i;
3072 VMR9DefaultAllocatorPresenterImpl* This;
3074 This = CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl));
3075 if (!This)
3076 return E_OUTOFMEMORY;
3078 This->d3d9_ptr = init_d3d9(parent->hD3d9);
3079 if (!This->d3d9_ptr)
3081 WARN("Could not initialize d3d9.dll\n");
3082 CoTaskMemFree(This);
3083 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
3086 i = 0;
3089 D3DDISPLAYMODE mode;
3091 hr = IDirect3D9_EnumAdapterModes(This->d3d9_ptr, i++, D3DFMT_X8R8G8B8, 0, &mode);
3092 } while (FAILED(hr));
3093 if (FAILED(hr))
3094 ERR("HR: %08x\n", hr);
3095 if (hr == D3DERR_NOTAVAILABLE)
3097 ERR("Format not supported\n");
3098 IDirect3D9_Release(This->d3d9_ptr);
3099 CoTaskMemFree(This);
3100 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
3103 This->IVMRImagePresenter9_iface.lpVtbl = &VMR9_ImagePresenter;
3104 This->IVMRSurfaceAllocatorEx9_iface.lpVtbl = &VMR9_SurfaceAllocator;
3106 This->refCount = 1;
3107 This->pVMR9 = parent;
3108 This->d3d9_surfaces = NULL;
3109 This->d3d9_dev = NULL;
3110 This->hMon = 0;
3111 This->d3d9_vertex = NULL;
3112 This->num_surfaces = 0;
3113 This->hWndThread = NULL;
3114 This->ack = CreateEventW(NULL, 0, 0, NULL);
3115 This->SurfaceAllocatorNotify = NULL;
3116 This->reset = FALSE;
3118 *ppv = This;
3119 return S_OK;