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
25 #define NONAMELESSSTRUCT
26 #define NONAMELESSUNION
27 #include "quartz_private.h"
43 #include "wine/unicode.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
50 BaseRenderer renderer;
51 BaseControlWindow baseControlWindow;
52 BaseControlVideo baseControlVideo;
54 IUnknown IUnknown_inner;
55 IAMFilterMiscFlags IAMFilterMiscFlags_iface;
56 IVMRFilterConfig9 IVMRFilterConfig9_iface;
57 IVMRWindowlessControl9 IVMRWindowlessControl9_iface;
58 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface;
60 IVMRSurfaceAllocatorEx9 *allocator;
61 IVMRImagePresenter9 *presenter;
65 BITMAPINFOHEADER bmiheader;
72 /* for Windowless Mode */
73 HWND hWndClippingWindow;
81 static inline VMR9Impl *impl_from_inner_IUnknown(IUnknown *iface)
83 return CONTAINING_RECORD(iface, VMR9Impl, IUnknown_inner);
86 static inline VMR9Impl *impl_from_BaseWindow( BaseWindow *wnd )
88 return CONTAINING_RECORD(wnd, VMR9Impl, baseControlWindow.baseWindow);
91 static inline VMR9Impl *impl_from_IVideoWindow( IVideoWindow *iface)
93 return CONTAINING_RECORD(iface, VMR9Impl, baseControlWindow.IVideoWindow_iface);
96 static inline VMR9Impl *impl_from_BaseControlVideo( BaseControlVideo *cvid )
98 return CONTAINING_RECORD(cvid, VMR9Impl, baseControlVideo);
101 static inline VMR9Impl *impl_from_IBasicVideo( IBasicVideo *iface)
103 return CONTAINING_RECORD(iface, VMR9Impl, baseControlVideo.IBasicVideo_iface);
106 static inline VMR9Impl *impl_from_IAMFilterMiscFlags( IAMFilterMiscFlags *iface)
108 return CONTAINING_RECORD(iface, VMR9Impl, IAMFilterMiscFlags_iface);
111 static inline VMR9Impl *impl_from_IVMRFilterConfig9( IVMRFilterConfig9 *iface)
113 return CONTAINING_RECORD(iface, VMR9Impl, IVMRFilterConfig9_iface);
116 static inline VMR9Impl *impl_from_IVMRWindowlessControl9( IVMRWindowlessControl9 *iface)
118 return CONTAINING_RECORD(iface, VMR9Impl, IVMRWindowlessControl9_iface);
121 static inline VMR9Impl *impl_from_IVMRSurfaceAllocatorNotify9( IVMRSurfaceAllocatorNotify9 *iface)
123 return CONTAINING_RECORD(iface, VMR9Impl, IVMRSurfaceAllocatorNotify9_iface);
128 IVMRImagePresenter9 IVMRImagePresenter9_iface;
129 IVMRSurfaceAllocatorEx9 IVMRSurfaceAllocatorEx9_iface;
137 IDirect3DDevice9 *d3d9_dev;
138 IDirect3D9 *d3d9_ptr;
139 IDirect3DSurface9 **d3d9_surfaces;
140 IDirect3DVertexBuffer9 *d3d9_vertex;
145 VMR9AllocationInfo info;
148 IVMRSurfaceAllocatorNotify9 *SurfaceAllocatorNotify;
149 } VMR9DefaultAllocatorPresenterImpl;
151 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRImagePresenter9( IVMRImagePresenter9 *iface)
153 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRImagePresenter9_iface);
156 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRSurfaceAllocatorEx9( IVMRSurfaceAllocatorEx9 *iface)
158 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRSurfaceAllocatorEx9_iface);
161 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(VMR9Impl *parent, LPVOID * ppv);
163 static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample)
165 VMR9Impl *This = (VMR9Impl *)iface;
166 LPBYTE pbSrcStream = NULL;
167 REFERENCE_TIME tStart, tStop;
168 VMR9PresentationInfo info;
171 TRACE("%p %p\n", iface, pSample);
173 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
175 info.dwFlags = VMR9Sample_SrcDstRectsValid;
177 info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid;
179 if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
180 info.dwFlags |= VMR9Sample_Discontinuity;
182 if (IMediaSample_IsPreroll(pSample) == S_OK)
183 info.dwFlags |= VMR9Sample_Preroll;
185 if (IMediaSample_IsSyncPoint(pSample) == S_OK)
186 info.dwFlags |= VMR9Sample_SyncPoint;
188 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
191 ERR("Cannot get pointer to sample data (%x)\n", hr);
195 info.rtStart = tStart;
197 info.szAspectRatio.cx = This->bmiheader.biWidth;
198 info.szAspectRatio.cy = This->bmiheader.biHeight;
203 static HRESULT WINAPI VMR9_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt)
205 VMR9Impl *This = (VMR9Impl*)iface;
207 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat)
210 /* Ignore subtype, test for bicompression instead */
211 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
213 VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
215 This->bmiheader = format->bmiHeader;
216 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
217 This->source_rect.right = This->VideoWidth = format->bmiHeader.biWidth;
218 This->source_rect.bottom = This->VideoHeight = format->bmiHeader.biHeight;
219 This->source_rect.top = This->source_rect.left = 0;
221 else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
223 VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat;
225 This->bmiheader = format->bmiHeader;
227 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
228 This->source_rect.right = This->VideoWidth = format->bmiHeader.biWidth;
229 This->source_rect.bottom = This->VideoHeight = format->bmiHeader.biHeight;
230 This->source_rect.top = This->source_rect.left = 0;
234 ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
237 if (This->bmiheader.biCompression)
242 static HRESULT WINAPI VMR9_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime)
244 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
245 if (IMediaSample_IsPreroll(pSample) == S_OK)
250 static const BaseRendererFuncTable BaseFuncTable = {
262 VMR9_ShouldDrawSampleNow,
272 static LPWSTR WINAPI VMR9_GetClassWindowStyles(BaseWindow *This, DWORD *pClassStyles, DWORD *pWindowStyles, DWORD *pWindowStylesEx)
274 static WCHAR classnameW[] = { 'I','V','M','R','9',' ','C','l','a','s','s', 0 };
277 *pWindowStyles = WS_SIZEBOX;
278 *pWindowStylesEx = 0;
283 static RECT WINAPI VMR9_GetDefaultRect(BaseWindow *This)
285 VMR9Impl* pVMR9 = impl_from_BaseWindow(This);
288 defRect.left = defRect.top = 0;
289 defRect.right = pVMR9->VideoWidth;
290 defRect.bottom = pVMR9->VideoHeight;
295 static BOOL WINAPI VMR9_OnSize(BaseWindow *This, LONG Width, LONG Height)
297 VMR9Impl* pVMR9 = impl_from_BaseWindow(This);
299 TRACE("WM_SIZE %d %d\n", Width, Height);
300 GetClientRect(This->hWnd, &pVMR9->target_rect);
301 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
302 pVMR9->target_rect.left,
303 pVMR9->target_rect.top,
304 pVMR9->target_rect.right - pVMR9->target_rect.left,
305 pVMR9->target_rect.bottom - pVMR9->target_rect.top);
306 return BaseWindowImpl_OnSize(This, Width, Height);
309 static const BaseWindowFuncTable renderer_BaseWindowFuncTable = {
310 VMR9_GetClassWindowStyles,
313 BaseControlWindowImpl_PossiblyEatMessage,
317 static HRESULT WINAPI VMR9_GetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
319 VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This);
320 CopyRect(pSourceRect,&pVMR9->source_rect);
324 static HRESULT WINAPI VMR9_GetStaticImage(BaseControlVideo* This, LONG *pBufferSize, LONG *pDIBImage)
326 VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This);
327 BITMAPINFOHEADER *bmiHeader;
329 AM_MEDIA_TYPE *amt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
332 FIXME("(%p/%p)->(%p, %p): partial stub\n", pVMR9, This, pBufferSize, pDIBImage);
334 EnterCriticalSection(&pVMR9->renderer.filter.csFilter);
336 if (!pVMR9->renderer.pMediaSample)
338 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
339 return (pVMR9->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
342 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
344 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
346 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
348 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
352 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
353 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
354 return VFW_E_RUNTIME_ERROR;
357 needed_size = bmiHeader->biSize;
358 needed_size += IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample);
362 *pBufferSize = needed_size;
363 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
367 if (needed_size < *pBufferSize)
369 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
370 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
373 *pBufferSize = needed_size;
375 memcpy(pDIBImage, bmiHeader, bmiHeader->biSize);
376 IMediaSample_GetPointer(pVMR9->renderer.pMediaSample, (BYTE **)&ptr);
377 memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample));
379 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
383 static HRESULT WINAPI VMR9_GetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
385 VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This);
386 CopyRect(pTargetRect,&pVMR9->target_rect);
390 static VIDEOINFOHEADER* WINAPI VMR9_GetVideoFormat(BaseControlVideo* This)
392 VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This);
395 TRACE("(%p/%p)\n", pVMR9, This);
397 pmt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
398 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) {
399 return (VIDEOINFOHEADER*)pmt->pbFormat;
400 } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) {
401 static VIDEOINFOHEADER vih;
402 VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat;
403 memcpy(&vih,vih2,sizeof(VIDEOINFOHEADER));
404 memcpy(&vih.bmiHeader, &vih2->bmiHeader, sizeof(BITMAPINFOHEADER));
407 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype));
412 static HRESULT WINAPI VMR9_IsDefaultSourceRect(BaseControlVideo* This)
414 VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This);
415 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
420 static HRESULT WINAPI VMR9_IsDefaultTargetRect(BaseControlVideo* This)
422 VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This);
423 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
428 static HRESULT WINAPI VMR9_SetDefaultSourceRect(BaseControlVideo* This)
430 VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This);
432 pVMR9->source_rect.left = 0;
433 pVMR9->source_rect.top = 0;
434 pVMR9->source_rect.right = pVMR9->VideoWidth;
435 pVMR9->source_rect.bottom = pVMR9->VideoHeight;
440 static HRESULT WINAPI VMR9_SetDefaultTargetRect(BaseControlVideo* This)
443 VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This);
445 if (!GetClientRect(pVMR9->baseControlWindow.baseWindow.hWnd, &rect))
448 pVMR9->target_rect.left = 0;
449 pVMR9->target_rect.top = 0;
450 pVMR9->target_rect.right = rect.right;
451 pVMR9->target_rect.bottom = rect.bottom;
456 static HRESULT WINAPI VMR9_SetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
458 VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This);
459 CopyRect(&pVMR9->source_rect,pSourceRect);
463 static HRESULT WINAPI VMR9_SetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
465 VMR9Impl* pVMR9 = impl_from_BaseControlVideo(This);
466 CopyRect(&pVMR9->target_rect,pTargetRect);
470 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = {
475 VMR9_IsDefaultSourceRect,
476 VMR9_IsDefaultTargetRect,
477 VMR9_SetDefaultSourceRect,
478 VMR9_SetDefaultTargetRect,
483 static HRESULT WINAPI VMR9Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
485 VMR9Impl *This = impl_from_inner_IUnknown(iface);
486 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
488 if (This->bAggregatable)
489 This->bUnkOuterValid = TRUE;
493 if (IsEqualIID(riid, &IID_IUnknown))
494 *ppv = &This->IUnknown_inner;
495 else if (IsEqualIID(riid, &IID_IVideoWindow))
496 *ppv = &This->baseControlWindow.IVideoWindow_iface;
497 else if (IsEqualIID(riid, &IID_IBasicVideo))
498 *ppv = &This->baseControlVideo.IBasicVideo_iface;
499 else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
500 *ppv = &This->IAMFilterMiscFlags_iface;
501 else if (IsEqualIID(riid, &IID_IVMRFilterConfig9))
502 *ppv = &This->IVMRFilterConfig9_iface;
503 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9) && This->mode == VMR9Mode_Windowless)
504 *ppv = &This->IVMRWindowlessControl9_iface;
505 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9) && This->mode == VMR9Mode_Renderless)
506 *ppv = &This->IVMRSurfaceAllocatorNotify9_iface;
510 hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
517 IUnknown_AddRef((IUnknown *)(*ppv));
521 else if (IsEqualIID(riid, &IID_IBasicVideo2))
522 FIXME("No interface for IID_IBasicVideo2\n");
523 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9))
525 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9))
527 else if (IsEqualIID(riid, &IID_IMediaPosition))
528 FIXME("No interface for IID_IMediaPosition\n");
529 else if (IsEqualIID(riid, &IID_IQualProp))
530 FIXME("No interface for IID_IQualProp\n");
531 else if (IsEqualIID(riid, &IID_IVMRAspectRatioControl9))
532 FIXME("No interface for IID_IVMRAspectRatioControl9\n");
533 else if (IsEqualIID(riid, &IID_IVMRDeinterlaceControl9))
534 FIXME("No interface for IID_IVMRDeinterlaceControl9\n");
535 else if (IsEqualIID(riid, &IID_IVMRMixerBitmap9))
536 FIXME("No interface for IID_IVMRMixerBitmap9\n");
537 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig9))
538 FIXME("No interface for IID_IVMRMonitorConfig9\n");
539 else if (IsEqualIID(riid, &IID_IVMRMixerControl9))
540 FIXME("No interface for IID_IVMRMixerControl9\n");
542 FIXME("No interface for %s\n", debugstr_guid(riid));
544 return E_NOINTERFACE;
547 static ULONG WINAPI VMR9Inner_AddRef(IUnknown * iface)
549 VMR9Impl *This = impl_from_inner_IUnknown(iface);
550 ULONG refCount = BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
552 TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
557 static ULONG WINAPI VMR9Inner_Release(IUnknown * iface)
559 VMR9Impl *This = impl_from_inner_IUnknown(iface);
560 ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface);
562 TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
566 TRACE("Destroying\n");
567 BaseControlWindow_Destroy(&This->baseControlWindow);
570 IVMRSurfaceAllocator9_Release(This->allocator);
572 IVMRImagePresenter9_Release(This->presenter);
579 static const IUnknownVtbl IInner_VTable =
581 VMR9Inner_QueryInterface,
586 static HRESULT WINAPI VMR9_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
588 VMR9Impl *This = (VMR9Impl *)iface;
590 if (This->bAggregatable)
591 This->bUnkOuterValid = TRUE;
595 if (This->bAggregatable)
596 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
598 if (IsEqualIID(riid, &IID_IUnknown))
602 IUnknown_AddRef(&This->IUnknown_inner);
603 hr = IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
604 IUnknown_Release(&This->IUnknown_inner);
605 This->bAggregatable = TRUE;
610 return E_NOINTERFACE;
613 return IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
616 static ULONG WINAPI VMR9_AddRef(IBaseFilter * iface)
618 VMR9Impl *This = (VMR9Impl *)iface;
621 if (This->outer_unk && This->bUnkOuterValid)
622 ret = IUnknown_AddRef(This->outer_unk);
624 ret = IUnknown_AddRef(&This->IUnknown_inner);
626 TRACE("(%p)->AddRef from %d\n", iface, ret - 1);
631 static ULONG WINAPI VMR9_Release(IBaseFilter * iface)
633 VMR9Impl *This = (VMR9Impl *)iface;
636 if (This->outer_unk && This->bUnkOuterValid)
637 ret = IUnknown_Release(This->outer_unk);
639 ret = IUnknown_Release(&This->IUnknown_inner);
641 TRACE("(%p)->Release from %d\n", iface, ret + 1);
648 static const IBaseFilterVtbl VMR9_Vtbl =
653 BaseFilterImpl_GetClassID,
654 BaseRendererImpl_Stop,
655 BaseRendererImpl_Pause,
656 BaseRendererImpl_Run,
657 BaseRendererImpl_GetState,
658 BaseRendererImpl_SetSyncSource,
659 BaseFilterImpl_GetSyncSource,
660 BaseFilterImpl_EnumPins,
661 BaseRendererImpl_FindPin,
662 BaseFilterImpl_QueryFilterInfo,
663 BaseFilterImpl_JoinFilterGraph,
664 BaseFilterImpl_QueryVendorInfo
667 /*** IUnknown methods ***/
668 static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface, REFIID riid, LPVOID*ppvObj)
670 VMR9Impl *This = impl_from_IVideoWindow(iface);
672 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
674 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
677 static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface)
679 VMR9Impl *This = impl_from_IVideoWindow(iface);
681 TRACE("(%p/%p)->()\n", This, iface);
683 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
686 static ULONG WINAPI Videowindow_Release(IVideoWindow *iface)
688 VMR9Impl *This = impl_from_IVideoWindow(iface);
690 TRACE("(%p/%p)->()\n", This, iface);
692 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
695 static const IVideoWindowVtbl IVideoWindow_VTable =
697 Videowindow_QueryInterface,
700 BaseControlWindowImpl_GetTypeInfoCount,
701 BaseControlWindowImpl_GetTypeInfo,
702 BaseControlWindowImpl_GetIDsOfNames,
703 BaseControlWindowImpl_Invoke,
704 BaseControlWindowImpl_put_Caption,
705 BaseControlWindowImpl_get_Caption,
706 BaseControlWindowImpl_put_WindowStyle,
707 BaseControlWindowImpl_get_WindowStyle,
708 BaseControlWindowImpl_put_WindowStyleEx,
709 BaseControlWindowImpl_get_WindowStyleEx,
710 BaseControlWindowImpl_put_AutoShow,
711 BaseControlWindowImpl_get_AutoShow,
712 BaseControlWindowImpl_put_WindowState,
713 BaseControlWindowImpl_get_WindowState,
714 BaseControlWindowImpl_put_BackgroundPalette,
715 BaseControlWindowImpl_get_BackgroundPalette,
716 BaseControlWindowImpl_put_Visible,
717 BaseControlWindowImpl_get_Visible,
718 BaseControlWindowImpl_put_Left,
719 BaseControlWindowImpl_get_Left,
720 BaseControlWindowImpl_put_Width,
721 BaseControlWindowImpl_get_Width,
722 BaseControlWindowImpl_put_Top,
723 BaseControlWindowImpl_get_Top,
724 BaseControlWindowImpl_put_Height,
725 BaseControlWindowImpl_get_Height,
726 BaseControlWindowImpl_put_Owner,
727 BaseControlWindowImpl_get_Owner,
728 BaseControlWindowImpl_put_MessageDrain,
729 BaseControlWindowImpl_get_MessageDrain,
730 BaseControlWindowImpl_get_BorderColor,
731 BaseControlWindowImpl_put_BorderColor,
732 BaseControlWindowImpl_get_FullScreenMode,
733 BaseControlWindowImpl_put_FullScreenMode,
734 BaseControlWindowImpl_SetWindowForeground,
735 BaseControlWindowImpl_NotifyOwnerMessage,
736 BaseControlWindowImpl_SetWindowPosition,
737 BaseControlWindowImpl_GetWindowPosition,
738 BaseControlWindowImpl_GetMinIdealImageSize,
739 BaseControlWindowImpl_GetMaxIdealImageSize,
740 BaseControlWindowImpl_GetRestorePosition,
741 BaseControlWindowImpl_HideCursor,
742 BaseControlWindowImpl_IsCursorHidden
745 /*** IUnknown methods ***/
746 static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface, REFIID riid, LPVOID * ppvObj)
748 VMR9Impl *This = impl_from_IBasicVideo(iface);
750 TRACE("(%p/%p)->(%s (%p), %p)\n", This, iface, debugstr_guid(riid), riid, ppvObj);
752 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
755 static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface)
757 VMR9Impl *This = impl_from_IBasicVideo(iface);
759 TRACE("(%p/%p)->()\n", This, iface);
761 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
764 static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface)
766 VMR9Impl *This = impl_from_IBasicVideo(iface);
768 TRACE("(%p/%p)->()\n", This, iface);
770 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
773 static const IBasicVideoVtbl IBasicVideo_VTable =
775 Basicvideo_QueryInterface,
778 BaseControlVideoImpl_GetTypeInfoCount,
779 BaseControlVideoImpl_GetTypeInfo,
780 BaseControlVideoImpl_GetIDsOfNames,
781 BaseControlVideoImpl_Invoke,
782 BaseControlVideoImpl_get_AvgTimePerFrame,
783 BaseControlVideoImpl_get_BitRate,
784 BaseControlVideoImpl_get_BitErrorRate,
785 BaseControlVideoImpl_get_VideoWidth,
786 BaseControlVideoImpl_get_VideoHeight,
787 BaseControlVideoImpl_put_SourceLeft,
788 BaseControlVideoImpl_get_SourceLeft,
789 BaseControlVideoImpl_put_SourceWidth,
790 BaseControlVideoImpl_get_SourceWidth,
791 BaseControlVideoImpl_put_SourceTop,
792 BaseControlVideoImpl_get_SourceTop,
793 BaseControlVideoImpl_put_SourceHeight,
794 BaseControlVideoImpl_get_SourceHeight,
795 BaseControlVideoImpl_put_DestinationLeft,
796 BaseControlVideoImpl_get_DestinationLeft,
797 BaseControlVideoImpl_put_DestinationWidth,
798 BaseControlVideoImpl_get_DestinationWidth,
799 BaseControlVideoImpl_put_DestinationTop,
800 BaseControlVideoImpl_get_DestinationTop,
801 BaseControlVideoImpl_put_DestinationHeight,
802 BaseControlVideoImpl_get_DestinationHeight,
803 BaseControlVideoImpl_SetSourcePosition,
804 BaseControlVideoImpl_GetSourcePosition,
805 BaseControlVideoImpl_SetDefaultSourcePosition,
806 BaseControlVideoImpl_SetDestinationPosition,
807 BaseControlVideoImpl_GetDestinationPosition,
808 BaseControlVideoImpl_SetDefaultDestinationPosition,
809 BaseControlVideoImpl_GetVideoSize,
810 BaseControlVideoImpl_GetVideoPaletteEntries,
811 BaseControlVideoImpl_GetCurrentImage,
812 BaseControlVideoImpl_IsUsingDefaultSource,
813 BaseControlVideoImpl_IsUsingDefaultDestination
816 static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) {
817 VMR9Impl *This = impl_from_IAMFilterMiscFlags(iface);
818 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
821 static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) {
822 VMR9Impl *This = impl_from_IAMFilterMiscFlags(iface);
823 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
826 static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) {
827 VMR9Impl *This = impl_from_IAMFilterMiscFlags(iface);
828 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
831 static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) {
832 return AM_FILTER_MISC_FLAGS_IS_RENDERER;
835 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = {
836 AMFilterMiscFlags_QueryInterface,
837 AMFilterMiscFlags_AddRef,
838 AMFilterMiscFlags_Release,
839 AMFilterMiscFlags_GetMiscFlags
842 static HRESULT WINAPI VMR9FilterConfig_QueryInterface(IVMRFilterConfig9 *iface, REFIID riid, LPVOID * ppv)
844 VMR9Impl *This = impl_from_IVMRFilterConfig9(iface);
845 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
848 static ULONG WINAPI VMR9FilterConfig_AddRef(IVMRFilterConfig9 *iface)
850 VMR9Impl *This = impl_from_IVMRFilterConfig9(iface);
851 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
854 static ULONG WINAPI VMR9FilterConfig_Release(IVMRFilterConfig9 *iface)
856 VMR9Impl *This = impl_from_IVMRFilterConfig9(iface);
857 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
860 static HRESULT WINAPI VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9 *iface, IVMRImageCompositor9 *compositor)
862 VMR9Impl *This = impl_from_IVMRFilterConfig9(iface);
864 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
868 static HRESULT WINAPI VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD max)
870 VMR9Impl *This = impl_from_IVMRFilterConfig9(iface);
872 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
876 static HRESULT WINAPI VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD *max)
878 VMR9Impl *This = impl_from_IVMRFilterConfig9(iface);
880 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
884 static HRESULT WINAPI VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD renderflags)
886 VMR9Impl *This = impl_from_IVMRFilterConfig9(iface);
888 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
892 static HRESULT WINAPI VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD *renderflags)
894 VMR9Impl *This = impl_from_IVMRFilterConfig9(iface);
896 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
900 static HRESULT WINAPI VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 *iface, DWORD mode)
903 VMR9Impl *This = impl_from_IVMRFilterConfig9(iface);
905 TRACE("(%p/%p)->(%u)\n", iface, This, mode);
907 EnterCriticalSection(&This->renderer.filter.csFilter);
910 LeaveCriticalSection(&This->renderer.filter.csFilter);
911 return VFW_E_WRONG_STATE;
915 IVMRSurfaceAllocator9_Release(This->allocator);
917 IVMRImagePresenter9_Release(This->presenter);
919 This->allocator = NULL;
920 This->presenter = NULL;
924 case VMR9Mode_Windowed:
925 case VMR9Mode_Windowless:
926 This->allocator_is_ex = 0;
929 hr = VMR9DefaultAllocatorPresenterImpl_create(This, (LPVOID*)&This->presenter);
931 hr = IVMRImagePresenter9_QueryInterface(This->presenter, &IID_IVMRSurfaceAllocatorEx9, (LPVOID*)&This->allocator);
934 ERR("Unable to find Presenter interface\n");
935 IVMRSurfaceAllocatorEx9_Release(This->presenter);
936 This->allocator = NULL;
937 This->presenter = NULL;
940 hr = IVMRSurfaceAllocator9_AdviseNotify(This->allocator, &This->IVMRSurfaceAllocatorNotify9_iface);
942 case VMR9Mode_Renderless:
945 LeaveCriticalSection(&This->renderer.filter.csFilter);
950 LeaveCriticalSection(&This->renderer.filter.csFilter);
954 static HRESULT WINAPI VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9 *iface, DWORD *mode)
956 VMR9Impl *This = impl_from_IVMRFilterConfig9(iface);
958 TRACE("(%p/%p)->(%p) stub\n", iface, This, mode);
965 *mode = VMR9Mode_Windowed;
970 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl =
972 VMR9FilterConfig_QueryInterface,
973 VMR9FilterConfig_AddRef,
974 VMR9FilterConfig_Release,
975 VMR9FilterConfig_SetImageCompositor,
976 VMR9FilterConfig_SetNumberOfStreams,
977 VMR9FilterConfig_GetNumberOfStreams,
978 VMR9FilterConfig_SetRenderingPrefs,
979 VMR9FilterConfig_GetRenderingPrefs,
980 VMR9FilterConfig_SetRenderingMode,
981 VMR9FilterConfig_GetRenderingMode
984 static HRESULT WINAPI VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9 *iface, REFIID riid, LPVOID * ppv)
986 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
987 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
990 static ULONG WINAPI VMR9WindowlessControl_AddRef(IVMRWindowlessControl9 *iface)
992 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
993 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
996 static ULONG WINAPI VMR9WindowlessControl_Release(IVMRWindowlessControl9 *iface)
998 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
999 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1002 static HRESULT WINAPI VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height, LONG *arwidth, LONG *arheight)
1004 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1005 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1007 if (!width || !height || !arwidth || !arheight)
1009 ERR("Got no pointer\n");
1013 *width = This->bmiheader.biWidth;
1014 *height = This->bmiheader.biHeight;
1015 *arwidth = This->bmiheader.biWidth;
1016 *arheight = This->bmiheader.biHeight;
1021 static HRESULT WINAPI VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1023 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1025 FIXME("(%p/%p)->(...) stub\n", iface, This);
1029 static HRESULT WINAPI VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1031 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1033 FIXME("(%p/%p)->(...) stub\n", iface, This);
1037 static HRESULT WINAPI VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9 *iface, const RECT *source, const RECT *dest)
1039 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1041 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1043 EnterCriticalSection(&This->renderer.filter.csFilter);
1046 This->source_rect = *source;
1049 This->target_rect = *dest;
1050 if (This->baseControlWindow.baseWindow.hWnd)
1052 FIXME("Output rectangle: starting at %dx%d, up to point %dx%d\n", dest->left, dest->top, dest->right, dest->bottom);
1053 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, dest->left, dest->top, dest->right - dest->left,
1054 dest->bottom-dest->top, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW);
1058 LeaveCriticalSection(&This->renderer.filter.csFilter);
1063 static HRESULT WINAPI VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9 *iface, RECT *source, RECT *dest)
1065 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1068 *source = This->source_rect;
1071 *dest = This->target_rect;
1073 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
1077 static HRESULT WINAPI VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD *mode)
1079 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1081 FIXME("(%p/%p)->(...) stub\n", iface, This);
1085 static HRESULT WINAPI VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD mode)
1087 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1089 FIXME("(%p/%p)->(...) stub\n", iface, This);
1093 static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9 *iface, HWND hwnd)
1095 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1097 TRACE("(%p/%p)->(%p)\n", iface, This, hwnd);
1099 EnterCriticalSection(&This->renderer.filter.csFilter);
1100 This->hWndClippingWindow = hwnd;
1102 IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie);
1103 LeaveCriticalSection(&This->renderer.filter.csFilter);
1107 static HRESULT WINAPI VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9 *iface, HWND hwnd, HDC hdc)
1109 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1111 FIXME("(%p/%p)->(...) stub\n", iface, This);
1115 static HRESULT WINAPI VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9 *iface)
1117 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1119 FIXME("(%p/%p)->(...) stub\n", iface, This);
1123 static HRESULT WINAPI VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9 *iface, BYTE **dib)
1125 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1127 FIXME("(%p/%p)->(...) stub\n", iface, This);
1131 static HRESULT WINAPI VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9 *iface, COLORREF color)
1133 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1135 FIXME("(%p/%p)->(...) stub\n", iface, This);
1139 static HRESULT WINAPI VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9 *iface, COLORREF *color)
1141 VMR9Impl *This = impl_from_IVMRWindowlessControl9(iface);
1143 FIXME("(%p/%p)->(...) stub\n", iface, This);
1147 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl =
1149 VMR9WindowlessControl_QueryInterface,
1150 VMR9WindowlessControl_AddRef,
1151 VMR9WindowlessControl_Release,
1152 VMR9WindowlessControl_GetNativeVideoSize,
1153 VMR9WindowlessControl_GetMinIdealVideoSize,
1154 VMR9WindowlessControl_GetMaxIdealVideoSize,
1155 VMR9WindowlessControl_SetVideoPosition,
1156 VMR9WindowlessControl_GetVideoPosition,
1157 VMR9WindowlessControl_GetAspectRatioMode,
1158 VMR9WindowlessControl_SetAspectRatioMode,
1159 VMR9WindowlessControl_SetVideoClippingWindow,
1160 VMR9WindowlessControl_RepaintVideo,
1161 VMR9WindowlessControl_DisplayModeChanged,
1162 VMR9WindowlessControl_GetCurrentImage,
1163 VMR9WindowlessControl_SetBorderColor,
1164 VMR9WindowlessControl_GetBorderColor
1167 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9 *iface, REFIID riid, LPVOID * ppv)
1169 VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1170 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1173 static ULONG WINAPI VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9 *iface)
1175 VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1176 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1179 static ULONG WINAPI VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9 *iface)
1181 VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1182 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1185 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9 *iface, DWORD_PTR id, IVMRSurfaceAllocator9 *alloc)
1187 VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1189 /* FIXME: This code is not tested!!! */
1190 FIXME("(%p/%p)->(...) stub\n", iface, This);
1193 if (This->presenter)
1194 return VFW_E_WRONG_STATE;
1196 if (FAILED(IUnknown_QueryInterface(alloc, &IID_IVMRImagePresenter9, (void **)&This->presenter)))
1197 return E_NOINTERFACE;
1199 if (SUCCEEDED(IUnknown_QueryInterface(alloc, &IID_IVMRSurfaceAllocatorEx9, (void **)&This->allocator)))
1200 This->allocator_is_ex = 1;
1203 This->allocator = (IVMRSurfaceAllocatorEx9 *)alloc;
1204 IUnknown_AddRef(alloc);
1205 This->allocator_is_ex = 0;
1211 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
1213 VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1215 FIXME("(%p/%p)->(...) stub\n", iface, This);
1219 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
1221 VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1223 FIXME("(%p/%p)->(...) stub\n", iface, This);
1227 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9 *iface, VMR9AllocationInfo *allocinfo, DWORD *numbuffers, IDirect3DSurface9 **surface)
1229 VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1231 FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface, This, allocinfo, numbuffers, (numbuffers ? *numbuffers : 0), surface);
1233 if (!allocinfo || !numbuffers || !surface)
1236 if (!*numbuffers || *numbuffers < allocinfo->MinBuffers)
1238 ERR("Invalid number of buffers?\n");
1239 return E_INVALIDARG;
1245 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9 *iface, LONG code, LONG_PTR param1, LONG_PTR param2)
1247 VMR9Impl *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
1249 FIXME("(%p/%p)->(...) stub\n", iface, This);
1253 static const IVMRSurfaceAllocatorNotify9Vtbl IVMRSurfaceAllocatorNotify9_Vtbl =
1255 VMR9SurfaceAllocatorNotify_QueryInterface,
1256 VMR9SurfaceAllocatorNotify_AddRef,
1257 VMR9SurfaceAllocatorNotify_Release,
1258 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator,
1259 VMR9SurfaceAllocatorNotify_SetD3DDevice,
1260 VMR9SurfaceAllocatorNotify_ChangeD3DDevice,
1261 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper,
1262 VMR9SurfaceAllocatorNotify_NotifyEvent
1265 HRESULT VMR9Impl_create(IUnknown * outer_unk, LPVOID * ppv)
1270 TRACE("(%p, %p)\n", outer_unk, ppv);
1274 pVMR9 = CoTaskMemAlloc(sizeof(VMR9Impl));
1276 pVMR9->outer_unk = outer_unk;
1277 pVMR9->bUnkOuterValid = FALSE;
1278 pVMR9->bAggregatable = FALSE;
1279 pVMR9->IUnknown_inner.lpVtbl = &IInner_VTable;
1280 pVMR9->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl;
1283 pVMR9->allocator = NULL;
1284 pVMR9->presenter = NULL;
1285 pVMR9->hWndClippingWindow = NULL;
1286 pVMR9->IVMRFilterConfig9_iface.lpVtbl = &VMR9_FilterConfig_Vtbl;
1287 pVMR9->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl;
1288 pVMR9->IVMRSurfaceAllocatorNotify9_iface.lpVtbl = &IVMRSurfaceAllocatorNotify9_Vtbl;
1290 hr = BaseRenderer_Init(&pVMR9->renderer, &VMR9_Vtbl, outer_unk, &CLSID_VideoMixingRenderer9, (DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable);
1294 hr = BaseControlWindow_Init(&pVMR9->baseControlWindow, &IVideoWindow_VTable, &pVMR9->renderer.filter, &pVMR9->renderer.filter.csFilter, &pVMR9->renderer.pInputPin->pin, &renderer_BaseWindowFuncTable);
1298 hr = BaseControlVideo_Init(&pVMR9->baseControlVideo, &IBasicVideo_VTable, &pVMR9->renderer.filter, &pVMR9->renderer.filter.csFilter, &pVMR9->renderer.pInputPin->pin, &renderer_BaseControlVideoFuncTable);
1302 *ppv = (LPVOID)pVMR9;
1303 ZeroMemory(&pVMR9->source_rect, sizeof(RECT));
1304 ZeroMemory(&pVMR9->target_rect, sizeof(RECT));
1305 TRACE("Created at %p\n", pVMR9);
1309 BaseRendererImpl_Release(&pVMR9->renderer.filter.IBaseFilter_iface);
1310 CoTaskMemFree(pVMR9);
1316 static HRESULT WINAPI VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID riid, LPVOID * ppv)
1318 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
1319 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
1323 if (IsEqualIID(riid, &IID_IUnknown))
1324 *ppv = (LPVOID)&(This->IVMRImagePresenter9_iface);
1325 else if (IsEqualIID(riid, &IID_IVMRImagePresenter9))
1326 *ppv = &This->IVMRImagePresenter9_iface;
1327 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorEx9))
1328 *ppv = &This->IVMRSurfaceAllocatorEx9_iface;
1332 IUnknown_AddRef((IUnknown *)(*ppv));
1336 FIXME("No interface for %s\n", debugstr_guid(riid));
1338 return E_NOINTERFACE;
1341 static ULONG WINAPI VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 *iface)
1343 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
1344 ULONG refCount = InterlockedIncrement(&This->refCount);
1346 TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
1351 static ULONG WINAPI VMR9_ImagePresenter_Release(IVMRImagePresenter9 *iface)
1353 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
1354 ULONG refCount = InterlockedDecrement(&This->refCount);
1356 TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
1361 TRACE("Destroying\n");
1362 CloseHandle(This->ack);
1363 IUnknown_Release(This->d3d9_ptr);
1365 TRACE("Number of surfaces: %u\n", This->num_surfaces);
1366 for (i = 0; i < This->num_surfaces; ++i)
1368 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
1369 TRACE("Releasing surface %p\n", surface);
1371 IUnknown_Release(surface);
1374 CoTaskMemFree(This->d3d9_surfaces);
1375 This->d3d9_surfaces = NULL;
1376 This->num_surfaces = 0;
1377 if (This->d3d9_vertex)
1379 IUnknown_Release(This->d3d9_vertex);
1380 This->d3d9_vertex = NULL;
1382 CoTaskMemFree(This);
1388 static HRESULT WINAPI VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
1390 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
1392 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
1396 static HRESULT WINAPI VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
1398 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
1400 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
1404 #define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
1405 struct VERTEX { float x, y, z, rhw, u, v; };
1407 static HRESULT VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
1409 IDirect3DTexture9 *texture = NULL;
1412 hr = IDirect3DDevice9_SetFVF(This->d3d9_dev, USED_FVF);
1415 FIXME("SetFVF: %08x\n", hr);
1419 hr = IDirect3DDevice9_SetStreamSource(This->d3d9_dev, 0, This->d3d9_vertex, 0, sizeof(struct VERTEX));
1422 FIXME("SetStreamSource: %08x\n", hr);
1426 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **) &texture);
1429 FIXME("IDirect3DSurface9_GetContainer failed\n");
1432 hr = IDirect3DDevice9_SetTexture(This->d3d9_dev, 0, (IDirect3DBaseTexture9 *)texture);
1433 IDirect3DTexture9_Release(texture);
1436 FIXME("SetTexture: %08x\n", hr);
1440 hr = IDirect3DDevice9_DrawPrimitive(This->d3d9_dev, D3DPT_TRIANGLESTRIP, 0, 2);
1443 FIXME("DrawPrimitive: %08x\n", hr);
1450 static HRESULT VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
1453 IDirect3DSurface9 *target = NULL;
1456 hr = IDirect3DDevice9_GetBackBuffer(This->d3d9_dev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &target);
1459 ERR("IDirect3DDevice9_GetBackBuffer -- %08x\n", hr);
1463 target_rect = This->pVMR9->target_rect;
1464 target_rect.right -= target_rect.left;
1465 target_rect.bottom -= target_rect.top;
1466 target_rect.left = target_rect.top = 0;
1469 target_rect.top = target_rect.bottom;
1470 target_rect.bottom = 0;
1472 hr = IDirect3DDevice9_StretchRect(This->d3d9_dev, surface, &This->pVMR9->source_rect, target, &target_rect, D3DTEXF_LINEAR);
1474 ERR("IDirect3DDevice9_StretchRect -- %08x\n", hr);
1475 IDirect3DSurface9_Release(target);
1480 static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR id, VMR9PresentationInfo *info)
1482 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
1485 BOOL render = FALSE;
1487 TRACE("(%p/%p/%p)->(...) stub\n", iface, This, This->pVMR9);
1488 GetWindowRect(This->pVMR9->baseControlWindow.baseWindow.hWnd, &output);
1489 TRACE("Output rectangle: starting at %dx%d, up to point %dx%d\n", output.left, output.top, output.right, output.bottom);
1491 /* This might happen if we don't have active focus (eg on a different virtual desktop) */
1492 if (!This->d3d9_dev)
1495 /* Display image here */
1496 hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
1498 FIXME("hr: %08x\n", hr);
1499 hr = IDirect3DDevice9_BeginScene(This->d3d9_dev);
1502 if (This->d3d9_vertex)
1503 hr = VMR9_ImagePresenter_PresentTexture(This, info->lpSurf);
1505 hr = VMR9_ImagePresenter_PresentOffscreenSurface(This, info->lpSurf);
1506 render = SUCCEEDED(hr);
1509 FIXME("BeginScene: %08x\n", hr);
1510 hr = IDirect3DDevice9_EndScene(This->d3d9_dev);
1511 if (render && SUCCEEDED(hr))
1513 hr = IDirect3DDevice9_Present(This->d3d9_dev, NULL, NULL, This->pVMR9->baseControlWindow.baseWindow.hWnd, NULL);
1515 FIXME("Presenting image: %08x\n", hr);
1521 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter =
1523 VMR9_ImagePresenter_QueryInterface,
1524 VMR9_ImagePresenter_AddRef,
1525 VMR9_ImagePresenter_Release,
1526 VMR9_ImagePresenter_StartPresenting,
1527 VMR9_ImagePresenter_StopPresenting,
1528 VMR9_ImagePresenter_PresentImage
1531 static HRESULT WINAPI VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9 *iface, REFIID riid, LPVOID * ppv)
1533 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
1535 return VMR9_ImagePresenter_QueryInterface(&This->IVMRImagePresenter9_iface, riid, ppv);
1538 static ULONG WINAPI VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9 *iface)
1540 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
1542 return VMR9_ImagePresenter_AddRef(&This->IVMRImagePresenter9_iface);
1545 static ULONG WINAPI VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9 *iface)
1547 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
1549 return VMR9_ImagePresenter_Release(&This->IVMRImagePresenter9_iface);
1552 static HRESULT VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *allocinfo)
1558 if (!(allocinfo->dwFlags & VMR9AllocFlag_TextureSurface))
1559 /* Only needed for texture surfaces */
1562 hr = IDirect3DDevice9_GetDeviceCaps(This->d3d9_dev, &caps);
1566 if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2) || (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY))
1568 width = allocinfo->dwWidth;
1569 height = allocinfo->dwHeight;
1574 while (width < allocinfo->dwWidth)
1577 while (height < allocinfo->dwHeight)
1579 FIXME("NPOW2 support missing, not using proper surfaces!\n");
1582 if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
1588 FIXME("Square texture support required..\n");
1591 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF, allocinfo->Pool, &This->d3d9_vertex, NULL);
1594 ERR("Couldn't create vertex buffer: %08x\n", hr);
1599 allocinfo->dwHeight = height;
1600 allocinfo->dwWidth = width;
1605 static DWORD WINAPI MessageLoop(LPVOID lpParameter)
1609 VMR9DefaultAllocatorPresenterImpl *This = lpParameter;
1611 TRACE("Starting message loop\n");
1613 if (FAILED(BaseWindowImpl_PrepareWindow(&This->pVMR9->baseControlWindow.baseWindow)))
1615 FIXME("Failed to prepare window\n");
1619 SetEvent(This->ack);
1620 while ((fGotMessage = GetMessageW(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1)
1622 TranslateMessage(&msg);
1623 DispatchMessageW(&msg);
1626 TRACE("End of message loop\n");
1631 static UINT d3d9_adapter_from_hwnd(IDirect3D9 *d3d9, HWND hwnd, HMONITOR *mon_out)
1636 mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
1641 for (d3d9_adapter = 0; d3d9_adapter < IDirect3D9_GetAdapterCount(d3d9); ++d3d9_adapter)
1643 if (mon == IDirect3D9_GetAdapterMonitor(d3d9, d3d9_adapter))
1646 if (d3d9_adapter >= IDirect3D9_GetAdapterCount(d3d9))
1651 return d3d9_adapter;
1654 static BOOL CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *info, DWORD *numbuffers)
1656 D3DPRESENT_PARAMETERS d3dpp;
1660 TRACE("(%p)->()\n", This);
1662 This->hWndThread = CreateThread(NULL, 0, MessageLoop, This, 0, &This->tid);
1663 if (!This->hWndThread)
1666 WaitForSingleObject(This->ack, INFINITE);
1668 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) return FALSE;
1670 /* Obtain a monitor and d3d9 device */
1671 d3d9_adapter = d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon);
1673 /* Now try to create the d3d9 device */
1674 ZeroMemory(&d3dpp, sizeof(d3dpp));
1675 d3dpp.Windowed = TRUE;
1676 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
1677 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1678 d3dpp.BackBufferHeight = This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top;
1679 d3dpp.BackBufferWidth = This->pVMR9->target_rect.right - This->pVMR9->target_rect.left;
1681 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev);
1684 ERR("Could not create device: %08x\n", hr);
1685 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
1688 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
1690 This->d3d9_surfaces = CoTaskMemAlloc(*numbuffers * sizeof(IDirect3DSurface9 *));
1691 ZeroMemory(This->d3d9_surfaces, *numbuffers * sizeof(IDirect3DSurface9 *));
1693 hr = VMR9_SurfaceAllocator_SetAllocationSettings(This, info);
1695 ERR("Setting allocation settings failed: %08x\n", hr);
1699 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, info, numbuffers, This->d3d9_surfaces);
1701 ERR("Allocating surfaces failed: %08x\n", hr);
1706 IVMRSurfaceAllocatorEx9_TerminateDevice(This->pVMR9->allocator, This->pVMR9->cookie);
1707 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
1711 This->num_surfaces = *numbuffers;
1716 static HRESULT WINAPI VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, VMR9AllocationInfo *allocinfo, DWORD *numbuffers)
1718 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
1720 if (This->pVMR9->mode != VMR9Mode_Windowed && !This->pVMR9->hWndClippingWindow)
1722 ERR("No window set\n");
1723 return VFW_E_WRONG_STATE;
1726 This->info = *allocinfo;
1728 if (!CreateRenderingWindow(This, allocinfo, numbuffers))
1730 ERR("Failed to create rendering window, expect no output!\n");
1731 return VFW_E_WRONG_STATE;
1737 static HRESULT WINAPI VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id)
1739 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
1741 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
1746 SendMessageW(This->pVMR9->baseControlWindow.baseWindow.hWnd, WM_CLOSE, 0, 0);
1747 PostThreadMessageW(This->tid, WM_QUIT, 0, 0);
1748 WaitForSingleObject(This->hWndThread, INFINITE);
1749 This->hWndThread = NULL;
1750 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
1755 /* Recreate all surfaces (If allocated as D3DPOOL_DEFAULT) and survive! */
1756 static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl *This)
1758 struct VERTEX t_vert[4];
1762 D3DPRESENT_PARAMETERS d3dpp;
1765 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
1771 if (!This->d3d9_surfaces || !This->reset)
1774 This->reset = FALSE;
1775 TRACE("RESETTING\n");
1776 if (This->d3d9_vertex)
1778 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
1779 This->d3d9_vertex = NULL;
1782 for (i = 0; i < This->num_surfaces; ++i)
1784 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
1785 TRACE("Releasing surface %p\n", surface);
1787 IUnknown_Release(surface);
1789 ZeroMemory(This->d3d9_surfaces, sizeof(IDirect3DSurface9 *) * This->num_surfaces);
1791 /* Now try to create the d3d9 device */
1792 ZeroMemory(&d3dpp, sizeof(d3dpp));
1793 d3dpp.Windowed = TRUE;
1794 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
1795 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
1798 IDirect3DDevice9_Release(This->d3d9_dev);
1799 This->d3d9_dev = NULL;
1800 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);
1803 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);
1806 ERR("--> Creating device: %08x\n", hr);
1810 IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
1812 IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, &This->info, &This->num_surfaces, This->d3d9_surfaces);
1814 This->reset = FALSE;
1816 if (!(This->info.dwFlags & VMR9AllocFlag_TextureSurface))
1819 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF,
1820 This->info.Pool, &This->d3d9_vertex, NULL);
1822 width = This->info.dwWidth;
1823 height = This->info.dwHeight;
1825 for (i = 0; i < sizeof(t_vert) / sizeof(t_vert[0]); ++i)
1829 t_vert[i].x = (float)This->pVMR9->target_rect.right - (float)This->pVMR9->target_rect.left - 0.5f;
1830 t_vert[i].u = (float)This->pVMR9->source_rect.right / (float)width;
1834 t_vert[i].x = -0.5f;
1835 t_vert[i].u = (float)This->pVMR9->source_rect.left / (float)width;
1840 t_vert[i].y = -0.5f;
1841 t_vert[i].v = (float)This->pVMR9->source_rect.bottom / (float)height;
1845 t_vert[i].y = (float)This->pVMR9->target_rect.bottom - (float)This->pVMR9->target_rect.top - 0.5f;
1846 t_vert[i].v = (float)This->pVMR9->source_rect.top / (float)height;
1849 t_vert[i].rhw = 1.0f;
1852 FIXME("Vertex rectangle:\n");
1853 FIXME("X, Y: %f, %f\n", t_vert[0].x, t_vert[0].y);
1854 FIXME("X, Y: %f, %f\n", t_vert[3].x, t_vert[3].y);
1855 FIXME("TOP, LEFT: %f, %f\n", t_vert[0].u, t_vert[0].v);
1856 FIXME("DOWN, BOTTOM: %f, %f\n", t_vert[3].u, t_vert[3].v);
1858 IDirect3DVertexBuffer9_Lock(This->d3d9_vertex, 0, sizeof(t_vert), &bits, 0);
1859 memcpy(bits, t_vert, sizeof(t_vert));
1860 IDirect3DVertexBuffer9_Unlock(This->d3d9_vertex);
1865 static HRESULT WINAPI VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, DWORD surfaceindex, DWORD flags, IDirect3DSurface9 **surface)
1867 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
1869 /* Update everything first, this is needed because the surface might be destroyed in the reset */
1870 if (!This->d3d9_dev)
1872 TRACE("Device has left me!\n");
1876 VMR9_SurfaceAllocator_UpdateDeviceReset(This);
1878 if (surfaceindex >= This->num_surfaces)
1880 ERR("surfaceindex is greater than num_surfaces\n");
1883 *surface = This->d3d9_surfaces[surfaceindex];
1884 IUnknown_AddRef(*surface);
1889 static HRESULT WINAPI VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9 *iface, IVMRSurfaceAllocatorNotify9 *allocnotify)
1891 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
1893 TRACE("(%p/%p)->(...)\n", iface, This);
1895 /* No AddRef taken here or the base VMR9 filter would never be destroied */
1896 This->SurfaceAllocatorNotify = allocnotify;
1900 static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator =
1902 VMR9_SurfaceAllocator_QueryInterface,
1903 VMR9_SurfaceAllocator_AddRef,
1904 VMR9_SurfaceAllocator_Release,
1905 VMR9_SurfaceAllocator_InitializeDevice,
1906 VMR9_SurfaceAllocator_TerminateDevice,
1907 VMR9_SurfaceAllocator_GetSurface,
1908 VMR9_SurfaceAllocator_AdviseNotify,
1909 NULL /* This isn't the SurfaceAllocatorEx type yet, working on it */
1912 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(VMR9Impl *parent, LPVOID * ppv)
1916 VMR9DefaultAllocatorPresenterImpl* This;
1918 This = CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl));
1920 return E_OUTOFMEMORY;
1922 This->d3d9_ptr = NULL;
1923 if (!This->d3d9_ptr)
1925 WARN("Could not initialize d3d9.dll\n");
1926 CoTaskMemFree(This);
1927 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
1933 D3DDISPLAYMODE mode;
1935 hr = IDirect3D9_EnumAdapterModes(This->d3d9_ptr, i++, D3DFMT_X8R8G8B8, 0, &mode);
1936 } while (FAILED(hr));
1938 ERR("HR: %08x\n", hr);
1939 if (hr == D3DERR_NOTAVAILABLE)
1941 ERR("Format not supported\n");
1942 IUnknown_Release(This->d3d9_ptr);
1943 CoTaskMemFree(This);
1944 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
1947 This->IVMRImagePresenter9_iface.lpVtbl = &VMR9_ImagePresenter;
1948 This->IVMRSurfaceAllocatorEx9_iface.lpVtbl = &VMR9_SurfaceAllocator;
1951 This->pVMR9 = parent;
1952 This->d3d9_surfaces = NULL;
1953 This->d3d9_dev = NULL;
1955 This->d3d9_vertex = NULL;
1956 This->num_surfaces = 0;
1957 This->hWndThread = NULL;
1958 This->ack = CreateEventW(NULL, 0, 0, NULL);
1959 This->SurfaceAllocatorNotify = NULL;
1960 This->reset = FALSE;