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 "quartz_private.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
44 struct strmbase_renderer renderer
;
45 BaseControlWindow baseControlWindow
;
46 BaseControlVideo baseControlVideo
;
48 IAMCertifiedOutputProtection IAMCertifiedOutputProtection_iface
;
49 IAMFilterMiscFlags IAMFilterMiscFlags_iface
;
50 IVMRFilterConfig IVMRFilterConfig_iface
;
51 IVMRFilterConfig9 IVMRFilterConfig9_iface
;
52 IVMRMonitorConfig IVMRMonitorConfig_iface
;
53 IVMRMonitorConfig9 IVMRMonitorConfig9_iface
;
54 IVMRSurfaceAllocatorNotify IVMRSurfaceAllocatorNotify_iface
;
55 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface
;
56 IVMRWindowlessControl IVMRWindowlessControl_iface
;
57 IVMRWindowlessControl9 IVMRWindowlessControl9_iface
;
59 IOverlay IOverlay_iface
;
61 IVMRSurfaceAllocatorEx9
*allocator
;
62 IVMRImagePresenter9
*presenter
;
66 * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed
67 * What I do is implement windowless as a special case of renderless, and then
68 * windowed also as a special case of windowless. This is probably the easiest way.
71 BITMAPINFOHEADER bmiheader
;
75 /* Presentation related members */
76 IDirect3DDevice9
*allocator_d3d9_dev
;
77 HMONITOR allocator_mon
;
82 /* for Windowless Mode */
83 HWND hWndClippingWindow
;
93 static inline struct quartz_vmr
*impl_from_BaseWindow(BaseWindow
*wnd
)
95 return CONTAINING_RECORD(wnd
, struct quartz_vmr
, baseControlWindow
.baseWindow
);
98 static inline struct quartz_vmr
*impl_from_BaseControlVideo(BaseControlVideo
*cvid
)
100 return CONTAINING_RECORD(cvid
, struct quartz_vmr
, baseControlVideo
);
103 static inline struct quartz_vmr
*impl_from_IAMCertifiedOutputProtection(IAMCertifiedOutputProtection
*iface
)
105 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IAMCertifiedOutputProtection_iface
);
108 static inline struct quartz_vmr
*impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags
*iface
)
110 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IAMFilterMiscFlags_iface
);
113 static inline struct quartz_vmr
*impl_from_IVMRFilterConfig(IVMRFilterConfig
*iface
)
115 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRFilterConfig_iface
);
118 static inline struct quartz_vmr
*impl_from_IVMRFilterConfig9(IVMRFilterConfig9
*iface
)
120 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRFilterConfig9_iface
);
123 static inline struct quartz_vmr
*impl_from_IVMRMonitorConfig(IVMRMonitorConfig
*iface
)
125 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRMonitorConfig_iface
);
128 static inline struct quartz_vmr
*impl_from_IVMRMonitorConfig9(IVMRMonitorConfig9
*iface
)
130 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRMonitorConfig9_iface
);
133 static inline struct quartz_vmr
*impl_from_IVMRSurfaceAllocatorNotify(IVMRSurfaceAllocatorNotify
*iface
)
135 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRSurfaceAllocatorNotify_iface
);
138 static inline struct quartz_vmr
*impl_from_IVMRSurfaceAllocatorNotify9(IVMRSurfaceAllocatorNotify9
*iface
)
140 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRSurfaceAllocatorNotify9_iface
);
143 static inline struct quartz_vmr
*impl_from_IVMRWindowlessControl(IVMRWindowlessControl
*iface
)
145 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRWindowlessControl_iface
);
148 static inline struct quartz_vmr
*impl_from_IVMRWindowlessControl9(IVMRWindowlessControl9
*iface
)
150 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRWindowlessControl9_iface
);
155 IVMRImagePresenter9 IVMRImagePresenter9_iface
;
156 IVMRSurfaceAllocatorEx9 IVMRSurfaceAllocatorEx9_iface
;
160 IDirect3DDevice9
*d3d9_dev
;
161 IDirect3D9
*d3d9_ptr
;
162 IDirect3DSurface9
**d3d9_surfaces
;
163 IDirect3DVertexBuffer9
*d3d9_vertex
;
168 VMR9AllocationInfo info
;
170 struct quartz_vmr
* pVMR9
;
171 IVMRSurfaceAllocatorNotify9
*SurfaceAllocatorNotify
;
172 } VMR9DefaultAllocatorPresenterImpl
;
174 static inline VMR9DefaultAllocatorPresenterImpl
*impl_from_IVMRImagePresenter9( IVMRImagePresenter9
*iface
)
176 return CONTAINING_RECORD(iface
, VMR9DefaultAllocatorPresenterImpl
, IVMRImagePresenter9_iface
);
179 static inline VMR9DefaultAllocatorPresenterImpl
*impl_from_IVMRSurfaceAllocatorEx9( IVMRSurfaceAllocatorEx9
*iface
)
181 return CONTAINING_RECORD(iface
, VMR9DefaultAllocatorPresenterImpl
, IVMRSurfaceAllocatorEx9_iface
);
184 static HRESULT
VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr
*parent
, LPVOID
* ppv
);
186 static inline struct quartz_vmr
*impl_from_IBaseFilter(IBaseFilter
*iface
)
188 return CONTAINING_RECORD(iface
, struct quartz_vmr
, renderer
.filter
.IBaseFilter_iface
);
191 static DWORD
VMR9_SendSampleData(struct quartz_vmr
*This
, VMR9PresentationInfo
*info
, LPBYTE data
,
198 BITMAPINFOHEADER
*bmiHeader
;
201 TRACE("%p %p %d\n", This
, data
, size
);
203 amt
= &This
->renderer
.sink
.pin
.mt
;
205 if (IsEqualIID(&amt
->formattype
, &FORMAT_VideoInfo
))
207 bmiHeader
= &((VIDEOINFOHEADER
*)amt
->pbFormat
)->bmiHeader
;
209 else if (IsEqualIID(&amt
->formattype
, &FORMAT_VideoInfo2
))
211 bmiHeader
= &((VIDEOINFOHEADER2
*)amt
->pbFormat
)->bmiHeader
;
215 FIXME("Unknown type %s\n", debugstr_guid(&amt
->subtype
));
216 return VFW_E_RUNTIME_ERROR
;
219 width
= bmiHeader
->biWidth
;
220 height
= bmiHeader
->biHeight
;
222 TRACE("Src Rect: %s\n", wine_dbgstr_rect(&This
->source_rect
));
223 TRACE("Dst Rect: %s\n", wine_dbgstr_rect(&This
->target_rect
));
225 hr
= IDirect3DSurface9_LockRect(info
->lpSurf
, &lock
, NULL
, D3DLOCK_DISCARD
);
228 ERR("IDirect3DSurface9_LockRect failed (%x)\n",hr
);
233 /* Bottom up image needs inverting */
234 lock
.pBits
= (char *)lock
.pBits
+ (height
* lock
.Pitch
);
237 lock
.pBits
= (char *)lock
.pBits
- lock
.Pitch
;
238 memcpy(lock
.pBits
, data
, width
* bmiHeader
->biBitCount
/ 8);
239 data
= data
+ width
* bmiHeader
->biBitCount
/ 8;
242 else if (lock
.Pitch
!= width
* bmiHeader
->biBitCount
/ 8)
244 WARN("Slow path! %u/%u\n", lock
.Pitch
, width
* bmiHeader
->biBitCount
/8);
248 memcpy(lock
.pBits
, data
, width
* bmiHeader
->biBitCount
/ 8);
249 data
= data
+ width
* bmiHeader
->biBitCount
/ 8;
250 lock
.pBits
= (char *)lock
.pBits
+ lock
.Pitch
;
253 else memcpy(lock
.pBits
, data
, size
);
255 IDirect3DSurface9_UnlockRect(info
->lpSurf
);
257 hr
= IVMRImagePresenter9_PresentImage(This
->presenter
, This
->cookie
, info
);
261 static HRESULT WINAPI
VMR9_DoRenderSample(struct strmbase_renderer
*iface
, IMediaSample
*pSample
)
263 struct quartz_vmr
*This
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
264 const HANDLE events
[2] = {This
->run_event
, This
->renderer
.flush_event
};
265 LPBYTE pbSrcStream
= NULL
;
266 long cbSrcStream
= 0;
267 REFERENCE_TIME tStart
, tStop
;
268 VMR9PresentationInfo info
;
271 TRACE("%p %p\n", iface
, pSample
);
273 /* It is possible that there is no device at this point */
275 if (!This
->allocator
|| !This
->presenter
)
277 ERR("NO PRESENTER!!\n");
281 hr
= IMediaSample_GetTime(pSample
, &tStart
, &tStop
);
283 info
.dwFlags
= VMR9Sample_SrcDstRectsValid
;
285 info
.dwFlags
= VMR9Sample_SrcDstRectsValid
| VMR9Sample_TimeValid
;
287 if (IMediaSample_IsDiscontinuity(pSample
) == S_OK
)
288 info
.dwFlags
|= VMR9Sample_Discontinuity
;
290 if (IMediaSample_IsPreroll(pSample
) == S_OK
)
291 info
.dwFlags
|= VMR9Sample_Preroll
;
293 if (IMediaSample_IsSyncPoint(pSample
) == S_OK
)
294 info
.dwFlags
|= VMR9Sample_SyncPoint
;
296 /* If we render ourselves, and this is a preroll sample, discard it */
297 if (info
.dwFlags
& VMR9Sample_Preroll
)
302 hr
= IMediaSample_GetPointer(pSample
, &pbSrcStream
);
305 ERR("Cannot get pointer to sample data (%x)\n", hr
);
309 cbSrcStream
= IMediaSample_GetActualDataLength(pSample
);
311 info
.rtStart
= tStart
;
313 info
.szAspectRatio
.cx
= This
->bmiheader
.biWidth
;
314 info
.szAspectRatio
.cy
= This
->bmiheader
.biHeight
;
316 hr
= IVMRSurfaceAllocatorEx9_GetSurface(This
->allocator
, This
->cookie
, (++This
->cur_surface
)%This
->num_surfaces
, 0, &info
.lpSurf
);
321 VMR9_SendSampleData(This
, &info
, pbSrcStream
, cbSrcStream
);
322 IDirect3DSurface9_Release(info
.lpSurf
);
324 if (This
->renderer
.filter
.state
== State_Paused
)
326 LeaveCriticalSection(&This
->renderer
.csRenderLock
);
327 WaitForMultipleObjects(2, events
, FALSE
, INFINITE
);
328 EnterCriticalSection(&This
->renderer
.csRenderLock
);
334 static HRESULT WINAPI
VMR9_CheckMediaType(struct strmbase_renderer
*iface
, const AM_MEDIA_TYPE
*mt
)
336 const VIDEOINFOHEADER
*vih
;
338 if (!IsEqualIID(&mt
->majortype
, &MEDIATYPE_Video
) || !mt
->pbFormat
)
341 if (!IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
)
342 && !IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo2
))
345 vih
= (VIDEOINFOHEADER
*)mt
->pbFormat
;
347 if (vih
->bmiHeader
.biCompression
!= BI_RGB
)
352 static HRESULT
VMR9_maybe_init(struct quartz_vmr
*This
, BOOL force
)
354 VMR9AllocationInfo info
;
358 TRACE("my mode: %u, my window: %p, my last window: %p\n", This
->mode
, This
->baseControlWindow
.baseWindow
.hWnd
, This
->hWndClippingWindow
);
359 if (This
->num_surfaces
)
362 if (This
->mode
== VMR9Mode_Windowless
&& !This
->hWndClippingWindow
)
363 return (force
? VFW_E_RUNTIME_ERROR
: S_OK
);
365 TRACE("Initializing\n");
366 info
.dwFlags
= VMR9AllocFlag_TextureSurface
;
367 info
.dwHeight
= This
->source_rect
.bottom
;
368 info
.dwWidth
= This
->source_rect
.right
;
369 info
.Pool
= D3DPOOL_DEFAULT
;
371 FIXME("Reduce ratio to least common denominator\n");
372 info
.szAspectRatio
.cx
= info
.dwWidth
;
373 info
.szAspectRatio
.cy
= info
.dwHeight
;
374 info
.szNativeSize
.cx
= This
->bmiheader
.biWidth
;
375 info
.szNativeSize
.cy
= This
->bmiheader
.biHeight
;
378 switch (This
->bmiheader
.biBitCount
)
380 case 8: info
.Format
= D3DFMT_R3G3B2
; break;
381 case 15: info
.Format
= D3DFMT_X1R5G5B5
; break;
382 case 16: info
.Format
= D3DFMT_R5G6B5
; break;
383 case 24: info
.Format
= D3DFMT_R8G8B8
; break;
384 case 32: info
.Format
= D3DFMT_X8R8G8B8
; break;
386 FIXME("Unknown bpp %u\n", This
->bmiheader
.biBitCount
);
390 This
->cur_surface
= 0;
391 if (This
->num_surfaces
)
393 ERR("num_surfaces or d3d9_surfaces not 0\n");
397 hr
= IVMRSurfaceAllocatorEx9_InitializeDevice(This
->allocator
, This
->cookie
, &info
, &buffers
);
400 SetRect(&This
->source_rect
, 0, 0, This
->bmiheader
.biWidth
, This
->bmiheader
.biHeight
);
402 This
->num_surfaces
= buffers
;
407 static void vmr_start_stream(struct strmbase_renderer
*iface
)
409 struct quartz_vmr
*This
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
411 TRACE("(%p)\n", This
);
413 if (This
->renderer
.sink
.pin
.peer
)
414 VMR9_maybe_init(This
, TRUE
);
415 IVMRImagePresenter9_StartPresenting(This
->presenter
, This
->cookie
);
416 SetWindowPos(This
->baseControlWindow
.baseWindow
.hWnd
, NULL
,
417 This
->source_rect
.left
,
418 This
->source_rect
.top
,
419 This
->source_rect
.right
- This
->source_rect
.left
,
420 This
->source_rect
.bottom
- This
->source_rect
.top
,
421 SWP_NOZORDER
|SWP_NOMOVE
|SWP_DEFERERASE
);
422 ShowWindow(This
->baseControlWindow
.baseWindow
.hWnd
, SW_SHOW
);
423 GetClientRect(This
->baseControlWindow
.baseWindow
.hWnd
, &This
->target_rect
);
424 SetEvent(This
->run_event
);
427 static void vmr_stop_stream(struct strmbase_renderer
*iface
)
429 struct quartz_vmr
*This
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
431 TRACE("(%p)\n", This
);
433 if (This
->renderer
.filter
.state
== State_Running
)
434 IVMRImagePresenter9_StopPresenting(This
->presenter
, This
->cookie
);
435 ResetEvent(This
->run_event
);
438 static HRESULT WINAPI
VMR9_ShouldDrawSampleNow(struct strmbase_renderer
*iface
,
439 IMediaSample
*pSample
, REFERENCE_TIME
*start
, REFERENCE_TIME
*end
)
441 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
442 if (IMediaSample_IsPreroll(pSample
) == S_OK
)
447 static HRESULT
vmr_connect(struct strmbase_renderer
*iface
, const AM_MEDIA_TYPE
*mt
)
449 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
452 if (IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
))
454 VIDEOINFOHEADER
*format
= (VIDEOINFOHEADER
*)mt
->pbFormat
;
456 filter
->bmiheader
= format
->bmiHeader
;
457 filter
->VideoWidth
= format
->bmiHeader
.biWidth
;
458 filter
->VideoHeight
= format
->bmiHeader
.biHeight
;
459 SetRect(&filter
->source_rect
, 0, 0, filter
->VideoWidth
, filter
->VideoHeight
);
461 else if (IsEqualIID(&mt
->formattype
, &FORMAT_VideoInfo2
))
463 VIDEOINFOHEADER2
*format
= (VIDEOINFOHEADER2
*)mt
->pbFormat
;
465 filter
->bmiheader
= format
->bmiHeader
;
466 filter
->VideoWidth
= format
->bmiHeader
.biWidth
;
467 filter
->VideoHeight
= format
->bmiHeader
.biHeight
;
468 SetRect(&filter
->source_rect
, 0, 0, filter
->VideoWidth
, filter
->VideoHeight
);
472 || SUCCEEDED(hr
= IVMRFilterConfig9_SetRenderingMode(&filter
->IVMRFilterConfig9_iface
, VMR9Mode_Windowed
)))
473 hr
= VMR9_maybe_init(filter
, FALSE
);
478 static HRESULT WINAPI
VMR9_BreakConnect(struct strmbase_renderer
*This
)
480 struct quartz_vmr
*pVMR9
= impl_from_IBaseFilter(&This
->filter
.IBaseFilter_iface
);
485 if (This
->sink
.pin
.peer
&& pVMR9
->allocator
&& pVMR9
->presenter
)
487 if (pVMR9
->renderer
.filter
.state
!= State_Stopped
)
489 ERR("Disconnecting while not stopped! UNTESTED!!\n");
491 if (pVMR9
->renderer
.filter
.state
== State_Running
)
492 hr
= IVMRImagePresenter9_StopPresenting(pVMR9
->presenter
, pVMR9
->cookie
);
493 IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9
->allocator
, pVMR9
->cookie
);
494 pVMR9
->num_surfaces
= 0;
499 static void vmr_destroy(struct strmbase_renderer
*iface
)
501 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
503 BaseControlWindow_Destroy(&filter
->baseControlWindow
);
505 if (filter
->allocator
)
506 IVMRSurfaceAllocatorEx9_Release(filter
->allocator
);
507 if (filter
->presenter
)
508 IVMRImagePresenter9_Release(filter
->presenter
);
510 filter
->num_surfaces
= 0;
511 if (filter
->allocator_d3d9_dev
)
513 IDirect3DDevice9_Release(filter
->allocator_d3d9_dev
);
514 filter
->allocator_d3d9_dev
= NULL
;
517 CloseHandle(filter
->run_event
);
518 FreeLibrary(filter
->hD3d9
);
519 BaseControlWindow_Destroy(&filter
->baseControlWindow
);
520 strmbase_renderer_cleanup(&filter
->renderer
);
521 CoTaskMemFree(filter
);
524 static HRESULT
vmr_query_interface(struct strmbase_renderer
*iface
, REFIID iid
, void **out
)
526 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
528 if (IsEqualGUID(iid
, &IID_IVideoWindow
))
529 *out
= &filter
->baseControlWindow
.IVideoWindow_iface
;
530 else if (IsEqualGUID(iid
, &IID_IBasicVideo
))
531 *out
= &filter
->baseControlVideo
.IBasicVideo_iface
;
532 else if (IsEqualGUID(iid
, &IID_IAMCertifiedOutputProtection
))
533 *out
= &filter
->IAMCertifiedOutputProtection_iface
;
534 else if (IsEqualGUID(iid
, &IID_IAMFilterMiscFlags
))
535 *out
= &filter
->IAMFilterMiscFlags_iface
;
536 else if (IsEqualGUID(iid
, &IID_IVMRFilterConfig
))
537 *out
= &filter
->IVMRFilterConfig_iface
;
538 else if (IsEqualGUID(iid
, &IID_IVMRFilterConfig9
))
539 *out
= &filter
->IVMRFilterConfig9_iface
;
540 else if (IsEqualGUID(iid
, &IID_IVMRMonitorConfig
))
541 *out
= &filter
->IVMRMonitorConfig_iface
;
542 else if (IsEqualGUID(iid
, &IID_IVMRMonitorConfig9
))
543 *out
= &filter
->IVMRMonitorConfig9_iface
;
544 else if (IsEqualGUID(iid
, &IID_IVMRSurfaceAllocatorNotify
) && filter
->mode
== (VMR9Mode
)VMRMode_Renderless
)
545 *out
= &filter
->IVMRSurfaceAllocatorNotify_iface
;
546 else if (IsEqualGUID(iid
, &IID_IVMRSurfaceAllocatorNotify9
) && filter
->mode
== VMR9Mode_Renderless
)
547 *out
= &filter
->IVMRSurfaceAllocatorNotify9_iface
;
548 else if (IsEqualGUID(iid
, &IID_IVMRWindowlessControl
) && filter
->mode
== (VMR9Mode
)VMRMode_Windowless
)
549 *out
= &filter
->IVMRWindowlessControl_iface
;
550 else if (IsEqualGUID(iid
, &IID_IVMRWindowlessControl9
) && filter
->mode
== VMR9Mode_Windowless
)
551 *out
= &filter
->IVMRWindowlessControl9_iface
;
553 return E_NOINTERFACE
;
555 IUnknown_AddRef((IUnknown
*)*out
);
559 static HRESULT
vmr_pin_query_interface(struct strmbase_renderer
*iface
, REFIID iid
, void **out
)
561 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
563 if (IsEqualGUID(iid
, &IID_IOverlay
))
564 *out
= &filter
->IOverlay_iface
;
566 return E_NOINTERFACE
;
568 IUnknown_AddRef((IUnknown
*)*out
);
572 static const struct strmbase_renderer_ops renderer_ops
=
574 .pfnCheckMediaType
= VMR9_CheckMediaType
,
575 .pfnDoRenderSample
= VMR9_DoRenderSample
,
576 .renderer_start_stream
= vmr_start_stream
,
577 .renderer_stop_stream
= vmr_stop_stream
,
578 .pfnShouldDrawSampleNow
= VMR9_ShouldDrawSampleNow
,
579 .renderer_connect
= vmr_connect
,
580 .pfnBreakConnect
= VMR9_BreakConnect
,
581 .renderer_destroy
= vmr_destroy
,
582 .renderer_query_interface
= vmr_query_interface
,
583 .renderer_pin_query_interface
= vmr_pin_query_interface
,
586 static RECT WINAPI
VMR9_GetDefaultRect(BaseWindow
*This
)
588 struct quartz_vmr
* pVMR9
= impl_from_BaseWindow(This
);
591 SetRect(&defRect
, 0, 0, pVMR9
->VideoWidth
, pVMR9
->VideoHeight
);
596 static BOOL WINAPI
VMR9_OnSize(BaseWindow
*This
, LONG Width
, LONG Height
)
598 struct quartz_vmr
* pVMR9
= impl_from_BaseWindow(This
);
600 TRACE("WM_SIZE %d %d\n", Width
, Height
);
601 GetClientRect(This
->hWnd
, &pVMR9
->target_rect
);
602 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
603 pVMR9
->target_rect
.left
,
604 pVMR9
->target_rect
.top
,
605 pVMR9
->target_rect
.right
- pVMR9
->target_rect
.left
,
606 pVMR9
->target_rect
.bottom
- pVMR9
->target_rect
.top
);
611 static const BaseWindowFuncTable renderer_BaseWindowFuncTable
= {
616 static HRESULT WINAPI
VMR9_GetSourceRect(BaseControlVideo
* This
, RECT
*pSourceRect
)
618 struct quartz_vmr
* pVMR9
= impl_from_BaseControlVideo(This
);
619 CopyRect(pSourceRect
,&pVMR9
->source_rect
);
623 static HRESULT WINAPI
VMR9_GetStaticImage(BaseControlVideo
*iface
, LONG
*size
, LONG
*image
)
625 struct quartz_vmr
*filter
= impl_from_BaseControlVideo(iface
);
626 const AM_MEDIA_TYPE
*mt
= &filter
->renderer
.sink
.pin
.mt
;
627 IDirect3DSurface9
*rt
= NULL
, *surface
= NULL
;
628 D3DLOCKED_RECT locked_rect
;
629 IDirect3DDevice9
*device
;
630 unsigned int row_size
;
631 BITMAPINFOHEADER bih
;
636 TRACE("filter %p, size %d, image %p.\n", filter
, *size
, image
);
638 EnterCriticalSection(&filter
->renderer
.csRenderLock
);
639 device
= filter
->allocator_d3d9_dev
;
641 if (IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
))
642 bih
= ((VIDEOINFOHEADER
*)mt
->pbFormat
)->bmiHeader
;
643 else if (IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo2
))
644 bih
= ((VIDEOINFOHEADER2
*)mt
->pbFormat
)->bmiHeader
;
645 bih
.biSizeImage
= bih
.biWidth
* bih
.biHeight
* bih
.biBitCount
/ 8;
649 *size
= sizeof(BITMAPINFOHEADER
) + bih
.biSizeImage
;
650 LeaveCriticalSection(&filter
->renderer
.csRenderLock
);
654 if (FAILED(hr
= IDirect3DDevice9_GetRenderTarget(device
, 0, &rt
)))
657 if (FAILED(hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, bih
.biWidth
,
658 bih
.biHeight
, D3DFMT_X8R8G8B8
, D3DPOOL_SYSTEMMEM
, &surface
, NULL
)))
661 if (FAILED(hr
= IDirect3DDevice9_GetRenderTargetData(device
, rt
, surface
)))
664 if (FAILED(hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, NULL
, D3DLOCK_READONLY
)))
668 memcpy(image
, &bih
, min(size_left
, sizeof(BITMAPINFOHEADER
)));
669 size_left
-= sizeof(BITMAPINFOHEADER
);
671 dst
= (char *)image
+ sizeof(BITMAPINFOHEADER
);
672 row_size
= bih
.biWidth
* bih
.biBitCount
/ 8;
674 for (i
= 0; i
< bih
.biHeight
&& size_left
> 0; ++i
)
676 memcpy(dst
, (char *)locked_rect
.pBits
+ (i
* locked_rect
.Pitch
), min(row_size
, size_left
));
678 size_left
-= row_size
;
681 IDirect3DSurface9_UnlockRect(surface
);
684 if (surface
) IDirect3DSurface9_Release(surface
);
685 if (rt
) IDirect3DSurface9_Release(rt
);
686 LeaveCriticalSection(&filter
->renderer
.csRenderLock
);
690 static HRESULT WINAPI
VMR9_GetTargetRect(BaseControlVideo
* This
, RECT
*pTargetRect
)
692 struct quartz_vmr
* pVMR9
= impl_from_BaseControlVideo(This
);
693 CopyRect(pTargetRect
,&pVMR9
->target_rect
);
697 static VIDEOINFOHEADER
* WINAPI
VMR9_GetVideoFormat(BaseControlVideo
* This
)
699 struct quartz_vmr
* pVMR9
= impl_from_BaseControlVideo(This
);
702 TRACE("(%p/%p)\n", pVMR9
, This
);
704 pmt
= &pVMR9
->renderer
.sink
.pin
.mt
;
705 if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo
)) {
706 return (VIDEOINFOHEADER
*)pmt
->pbFormat
;
707 } else if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo2
)) {
708 static VIDEOINFOHEADER vih
;
709 VIDEOINFOHEADER2
*vih2
= (VIDEOINFOHEADER2
*)pmt
->pbFormat
;
710 memcpy(&vih
,vih2
,sizeof(VIDEOINFOHEADER
));
711 memcpy(&vih
.bmiHeader
, &vih2
->bmiHeader
, sizeof(BITMAPINFOHEADER
));
714 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt
->formattype
));
719 static HRESULT WINAPI
VMR9_IsDefaultSourceRect(BaseControlVideo
* This
)
721 struct quartz_vmr
* pVMR9
= impl_from_BaseControlVideo(This
);
722 FIXME("(%p/%p)->(): stub !!!\n", pVMR9
, This
);
727 static HRESULT WINAPI
VMR9_IsDefaultTargetRect(BaseControlVideo
* This
)
729 struct quartz_vmr
* pVMR9
= impl_from_BaseControlVideo(This
);
730 FIXME("(%p/%p)->(): stub !!!\n", pVMR9
, This
);
735 static HRESULT WINAPI
VMR9_SetDefaultSourceRect(BaseControlVideo
* This
)
737 struct quartz_vmr
* pVMR9
= impl_from_BaseControlVideo(This
);
739 SetRect(&pVMR9
->source_rect
, 0, 0, pVMR9
->VideoWidth
, pVMR9
->VideoHeight
);
744 static HRESULT WINAPI
VMR9_SetDefaultTargetRect(BaseControlVideo
* This
)
747 struct quartz_vmr
* pVMR9
= impl_from_BaseControlVideo(This
);
749 if (!GetClientRect(pVMR9
->baseControlWindow
.baseWindow
.hWnd
, &rect
))
752 SetRect(&pVMR9
->target_rect
, 0, 0, rect
.right
, rect
.bottom
);
757 static HRESULT WINAPI
VMR9_SetSourceRect(BaseControlVideo
* This
, RECT
*pSourceRect
)
759 struct quartz_vmr
* pVMR9
= impl_from_BaseControlVideo(This
);
760 CopyRect(&pVMR9
->source_rect
,pSourceRect
);
764 static HRESULT WINAPI
VMR9_SetTargetRect(BaseControlVideo
* This
, RECT
*pTargetRect
)
766 struct quartz_vmr
* pVMR9
= impl_from_BaseControlVideo(This
);
767 CopyRect(&pVMR9
->target_rect
,pTargetRect
);
771 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable
= {
776 VMR9_IsDefaultSourceRect
,
777 VMR9_IsDefaultTargetRect
,
778 VMR9_SetDefaultSourceRect
,
779 VMR9_SetDefaultTargetRect
,
784 static const IVideoWindowVtbl IVideoWindow_VTable
=
786 BaseControlWindowImpl_QueryInterface
,
787 BaseControlWindowImpl_AddRef
,
788 BaseControlWindowImpl_Release
,
789 BaseControlWindowImpl_GetTypeInfoCount
,
790 BaseControlWindowImpl_GetTypeInfo
,
791 BaseControlWindowImpl_GetIDsOfNames
,
792 BaseControlWindowImpl_Invoke
,
793 BaseControlWindowImpl_put_Caption
,
794 BaseControlWindowImpl_get_Caption
,
795 BaseControlWindowImpl_put_WindowStyle
,
796 BaseControlWindowImpl_get_WindowStyle
,
797 BaseControlWindowImpl_put_WindowStyleEx
,
798 BaseControlWindowImpl_get_WindowStyleEx
,
799 BaseControlWindowImpl_put_AutoShow
,
800 BaseControlWindowImpl_get_AutoShow
,
801 BaseControlWindowImpl_put_WindowState
,
802 BaseControlWindowImpl_get_WindowState
,
803 BaseControlWindowImpl_put_BackgroundPalette
,
804 BaseControlWindowImpl_get_BackgroundPalette
,
805 BaseControlWindowImpl_put_Visible
,
806 BaseControlWindowImpl_get_Visible
,
807 BaseControlWindowImpl_put_Left
,
808 BaseControlWindowImpl_get_Left
,
809 BaseControlWindowImpl_put_Width
,
810 BaseControlWindowImpl_get_Width
,
811 BaseControlWindowImpl_put_Top
,
812 BaseControlWindowImpl_get_Top
,
813 BaseControlWindowImpl_put_Height
,
814 BaseControlWindowImpl_get_Height
,
815 BaseControlWindowImpl_put_Owner
,
816 BaseControlWindowImpl_get_Owner
,
817 BaseControlWindowImpl_put_MessageDrain
,
818 BaseControlWindowImpl_get_MessageDrain
,
819 BaseControlWindowImpl_get_BorderColor
,
820 BaseControlWindowImpl_put_BorderColor
,
821 BaseControlWindowImpl_get_FullScreenMode
,
822 BaseControlWindowImpl_put_FullScreenMode
,
823 BaseControlWindowImpl_SetWindowForeground
,
824 BaseControlWindowImpl_NotifyOwnerMessage
,
825 BaseControlWindowImpl_SetWindowPosition
,
826 BaseControlWindowImpl_GetWindowPosition
,
827 BaseControlWindowImpl_GetMinIdealImageSize
,
828 BaseControlWindowImpl_GetMaxIdealImageSize
,
829 BaseControlWindowImpl_GetRestorePosition
,
830 BaseControlWindowImpl_HideCursor
,
831 BaseControlWindowImpl_IsCursorHidden
834 static HRESULT WINAPI
AMCertifiedOutputProtection_QueryInterface(IAMCertifiedOutputProtection
*iface
,
835 REFIID riid
, void **ppv
)
837 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
838 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
841 static ULONG WINAPI
AMCertifiedOutputProtection_AddRef(IAMCertifiedOutputProtection
*iface
)
843 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
844 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
847 static ULONG WINAPI
AMCertifiedOutputProtection_Release(IAMCertifiedOutputProtection
*iface
)
849 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
850 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
853 static HRESULT WINAPI
AMCertifiedOutputProtection_KeyExchange(IAMCertifiedOutputProtection
*iface
,
854 GUID
* pRandom
, BYTE
** VarLenCertGH
,
855 DWORD
* pdwLengthCertGH
)
857 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
859 FIXME("(%p/%p)->(%p, %p, %p) stub\n", iface
, This
, pRandom
, VarLenCertGH
, pdwLengthCertGH
);
860 return VFW_E_NO_COPP_HW
;
863 static HRESULT WINAPI
AMCertifiedOutputProtection_SessionSequenceStart(IAMCertifiedOutputProtection
*iface
,
864 AMCOPPSignature
* pSig
)
866 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
868 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pSig
);
869 return VFW_E_NO_COPP_HW
;
872 static HRESULT WINAPI
AMCertifiedOutputProtection_ProtectionCommand(IAMCertifiedOutputProtection
*iface
,
873 const AMCOPPCommand
* cmd
)
875 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
877 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, cmd
);
878 return VFW_E_NO_COPP_HW
;
881 static HRESULT WINAPI
AMCertifiedOutputProtection_ProtectionStatus(IAMCertifiedOutputProtection
*iface
,
882 const AMCOPPStatusInput
* pStatusInput
,
883 AMCOPPStatusOutput
* pStatusOutput
)
885 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
887 FIXME("(%p/%p)->(%p, %p) stub\n", iface
, This
, pStatusInput
, pStatusOutput
);
888 return VFW_E_NO_COPP_HW
;
891 static const IAMCertifiedOutputProtectionVtbl IAMCertifiedOutputProtection_Vtbl
=
893 AMCertifiedOutputProtection_QueryInterface
,
894 AMCertifiedOutputProtection_AddRef
,
895 AMCertifiedOutputProtection_Release
,
896 AMCertifiedOutputProtection_KeyExchange
,
897 AMCertifiedOutputProtection_SessionSequenceStart
,
898 AMCertifiedOutputProtection_ProtectionCommand
,
899 AMCertifiedOutputProtection_ProtectionStatus
902 static HRESULT WINAPI
AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags
*iface
, REFIID riid
, void **ppv
) {
903 struct quartz_vmr
*This
= impl_from_IAMFilterMiscFlags(iface
);
904 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
907 static ULONG WINAPI
AMFilterMiscFlags_AddRef(IAMFilterMiscFlags
*iface
) {
908 struct quartz_vmr
*This
= impl_from_IAMFilterMiscFlags(iface
);
909 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
912 static ULONG WINAPI
AMFilterMiscFlags_Release(IAMFilterMiscFlags
*iface
) {
913 struct quartz_vmr
*This
= impl_from_IAMFilterMiscFlags(iface
);
914 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
917 static ULONG WINAPI
AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags
*iface
) {
918 return AM_FILTER_MISC_FLAGS_IS_RENDERER
;
921 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl
= {
922 AMFilterMiscFlags_QueryInterface
,
923 AMFilterMiscFlags_AddRef
,
924 AMFilterMiscFlags_Release
,
925 AMFilterMiscFlags_GetMiscFlags
928 static HRESULT WINAPI
VMR7FilterConfig_QueryInterface(IVMRFilterConfig
*iface
, REFIID riid
,
931 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
932 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
935 static ULONG WINAPI
VMR7FilterConfig_AddRef(IVMRFilterConfig
*iface
)
937 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
938 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
941 static ULONG WINAPI
VMR7FilterConfig_Release(IVMRFilterConfig
*iface
)
943 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
944 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
947 static HRESULT WINAPI
VMR7FilterConfig_SetImageCompositor(IVMRFilterConfig
*iface
,
948 IVMRImageCompositor
*compositor
)
950 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
952 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, compositor
);
956 static HRESULT WINAPI
VMR7FilterConfig_SetNumberOfStreams(IVMRFilterConfig
*iface
, DWORD max
)
958 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
960 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, max
);
964 static HRESULT WINAPI
VMR7FilterConfig_GetNumberOfStreams(IVMRFilterConfig
*iface
, DWORD
*max
)
966 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
968 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, max
);
972 static HRESULT WINAPI
VMR7FilterConfig_SetRenderingPrefs(IVMRFilterConfig
*iface
, DWORD renderflags
)
974 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
976 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, renderflags
);
980 static HRESULT WINAPI
VMR7FilterConfig_GetRenderingPrefs(IVMRFilterConfig
*iface
, DWORD
*renderflags
)
982 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
984 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, renderflags
);
988 static HRESULT WINAPI
VMR7FilterConfig_SetRenderingMode(IVMRFilterConfig
*iface
, DWORD mode
)
990 struct quartz_vmr
*filter
= impl_from_IVMRFilterConfig(iface
);
992 TRACE("iface %p, mode %#x.\n", iface
, mode
);
994 return IVMRFilterConfig9_SetRenderingMode(&filter
->IVMRFilterConfig9_iface
, mode
);
997 static HRESULT WINAPI
VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig
*iface
, DWORD
*mode
)
999 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
1001 TRACE("(%p/%p)->(%p)\n", iface
, This
, mode
);
1002 if (!mode
) return E_POINTER
;
1007 *mode
= VMRMode_Windowed
;
1012 static const IVMRFilterConfigVtbl VMR7_FilterConfig_Vtbl
=
1014 VMR7FilterConfig_QueryInterface
,
1015 VMR7FilterConfig_AddRef
,
1016 VMR7FilterConfig_Release
,
1017 VMR7FilterConfig_SetImageCompositor
,
1018 VMR7FilterConfig_SetNumberOfStreams
,
1019 VMR7FilterConfig_GetNumberOfStreams
,
1020 VMR7FilterConfig_SetRenderingPrefs
,
1021 VMR7FilterConfig_GetRenderingPrefs
,
1022 VMR7FilterConfig_SetRenderingMode
,
1023 VMR7FilterConfig_GetRenderingMode
1026 struct get_available_monitors_args
1028 VMRMONITORINFO
*info7
;
1029 VMR9MonitorInfo
*info9
;
1034 static BOOL CALLBACK
get_available_monitors_proc(HMONITOR hmon
, HDC hdc
, LPRECT lprc
, LPARAM lparam
)
1036 struct get_available_monitors_args
*args
= (struct get_available_monitors_args
*)lparam
;
1039 if (args
->info7
|| args
->info9
)
1042 if (!args
->arraysize
)
1045 mi
.cbSize
= sizeof(mi
);
1046 if (!GetMonitorInfoW(hmon
, (MONITORINFO
*)&mi
))
1049 /* fill VMRMONITORINFO struct */
1052 VMRMONITORINFO
*info
= args
->info7
++;
1053 memset(info
, 0, sizeof(*info
));
1055 if (args
->numdev
> 0)
1057 info
->guid
.pGUID
= &info
->guid
.GUID
;
1058 info
->guid
.GUID
.Data4
[7] = args
->numdev
;
1061 info
->guid
.pGUID
= NULL
;
1063 info
->rcMonitor
= mi
.rcMonitor
;
1065 info
->dwFlags
= mi
.dwFlags
;
1067 lstrcpynW(info
->szDevice
, mi
.szDevice
, ARRAY_SIZE(info
->szDevice
));
1069 /* FIXME: how to get these values? */
1070 info
->szDescription
[0] = 0;
1073 /* fill VMR9MonitorInfo struct */
1076 VMR9MonitorInfo
*info
= args
->info9
++;
1077 memset(info
, 0, sizeof(*info
));
1079 info
->uDevID
= 0; /* FIXME */
1080 info
->rcMonitor
= mi
.rcMonitor
;
1082 info
->dwFlags
= mi
.dwFlags
;
1084 lstrcpynW(info
->szDevice
, mi
.szDevice
, ARRAY_SIZE(info
->szDevice
));
1086 /* FIXME: how to get these values? */
1087 info
->szDescription
[0] = 0;
1088 info
->dwVendorId
= 0;
1089 info
->dwDeviceId
= 0;
1090 info
->dwSubSysId
= 0;
1091 info
->dwRevision
= 0;
1101 static HRESULT WINAPI
VMR7MonitorConfig_QueryInterface(IVMRMonitorConfig
*iface
, REFIID riid
,
1104 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1105 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1108 static ULONG WINAPI
VMR7MonitorConfig_AddRef(IVMRMonitorConfig
*iface
)
1110 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1111 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1114 static ULONG WINAPI
VMR7MonitorConfig_Release(IVMRMonitorConfig
*iface
)
1116 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1117 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1120 static HRESULT WINAPI
VMR7MonitorConfig_SetMonitor(IVMRMonitorConfig
*iface
, const VMRGUID
*pGUID
)
1122 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1124 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1132 static HRESULT WINAPI
VMR7MonitorConfig_GetMonitor(IVMRMonitorConfig
*iface
, VMRGUID
*pGUID
)
1134 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1136 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1141 pGUID
->pGUID
= NULL
; /* default DirectDraw device */
1145 static HRESULT WINAPI
VMR7MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig
*iface
,
1146 const VMRGUID
*pGUID
)
1148 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1150 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1158 static HRESULT WINAPI
VMR7MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig
*iface
, VMRGUID
*pGUID
)
1160 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1162 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1167 pGUID
->pGUID
= NULL
; /* default DirectDraw device */
1171 static HRESULT WINAPI
VMR7MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig
*iface
,
1172 VMRMONITORINFO
*info
, DWORD arraysize
,
1175 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1176 struct get_available_monitors_args args
;
1178 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface
, This
, info
, arraysize
, numdev
);
1183 if (info
&& arraysize
== 0)
1184 return E_INVALIDARG
;
1188 args
.arraysize
= arraysize
;
1190 EnumDisplayMonitors(NULL
, NULL
, get_available_monitors_proc
, (LPARAM
)&args
);
1192 *numdev
= args
.numdev
;
1196 static const IVMRMonitorConfigVtbl VMR7_MonitorConfig_Vtbl
=
1198 VMR7MonitorConfig_QueryInterface
,
1199 VMR7MonitorConfig_AddRef
,
1200 VMR7MonitorConfig_Release
,
1201 VMR7MonitorConfig_SetMonitor
,
1202 VMR7MonitorConfig_GetMonitor
,
1203 VMR7MonitorConfig_SetDefaultMonitor
,
1204 VMR7MonitorConfig_GetDefaultMonitor
,
1205 VMR7MonitorConfig_GetAvailableMonitors
1208 static HRESULT WINAPI
VMR9MonitorConfig_QueryInterface(IVMRMonitorConfig9
*iface
, REFIID riid
,
1211 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1212 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1215 static ULONG WINAPI
VMR9MonitorConfig_AddRef(IVMRMonitorConfig9
*iface
)
1217 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1218 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1221 static ULONG WINAPI
VMR9MonitorConfig_Release(IVMRMonitorConfig9
*iface
)
1223 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1224 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1227 static HRESULT WINAPI
VMR9MonitorConfig_SetMonitor(IVMRMonitorConfig9
*iface
, UINT uDev
)
1229 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1231 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, uDev
);
1236 static HRESULT WINAPI
VMR9MonitorConfig_GetMonitor(IVMRMonitorConfig9
*iface
, UINT
*uDev
)
1238 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1240 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, uDev
);
1249 static HRESULT WINAPI
VMR9MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig9
*iface
, UINT uDev
)
1251 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1253 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, uDev
);
1258 static HRESULT WINAPI
VMR9MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig9
*iface
, UINT
*uDev
)
1260 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1262 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, uDev
);
1271 static HRESULT WINAPI
VMR9MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig9
*iface
,
1272 VMR9MonitorInfo
*info
, DWORD arraysize
,
1275 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1276 struct get_available_monitors_args args
;
1278 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface
, This
, info
, arraysize
, numdev
);
1283 if (info
&& arraysize
== 0)
1284 return E_INVALIDARG
;
1288 args
.arraysize
= arraysize
;
1290 EnumDisplayMonitors(NULL
, NULL
, get_available_monitors_proc
, (LPARAM
)&args
);
1292 *numdev
= args
.numdev
;
1296 static const IVMRMonitorConfig9Vtbl VMR9_MonitorConfig_Vtbl
=
1298 VMR9MonitorConfig_QueryInterface
,
1299 VMR9MonitorConfig_AddRef
,
1300 VMR9MonitorConfig_Release
,
1301 VMR9MonitorConfig_SetMonitor
,
1302 VMR9MonitorConfig_GetMonitor
,
1303 VMR9MonitorConfig_SetDefaultMonitor
,
1304 VMR9MonitorConfig_GetDefaultMonitor
,
1305 VMR9MonitorConfig_GetAvailableMonitors
1308 static HRESULT WINAPI
VMR9FilterConfig_QueryInterface(IVMRFilterConfig9
*iface
, REFIID riid
, LPVOID
* ppv
)
1310 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1311 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1314 static ULONG WINAPI
VMR9FilterConfig_AddRef(IVMRFilterConfig9
*iface
)
1316 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1317 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1320 static ULONG WINAPI
VMR9FilterConfig_Release(IVMRFilterConfig9
*iface
)
1322 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1323 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1326 static HRESULT WINAPI
VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9
*iface
, IVMRImageCompositor9
*compositor
)
1328 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1330 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, compositor
);
1334 static HRESULT WINAPI
VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9
*iface
, DWORD count
)
1336 FIXME("iface %p, count %u, stub!\n", iface
, count
);
1342 static HRESULT WINAPI
VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9
*iface
, DWORD
*max
)
1344 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1346 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, max
);
1350 static HRESULT WINAPI
VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9
*iface
, DWORD renderflags
)
1352 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1354 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, renderflags
);
1358 static HRESULT WINAPI
VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9
*iface
, DWORD
*renderflags
)
1360 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1362 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, renderflags
);
1366 static HRESULT WINAPI
VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9
*iface
, DWORD mode
)
1369 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1371 TRACE("(%p/%p)->(%u)\n", iface
, This
, mode
);
1373 EnterCriticalSection(&This
->renderer
.filter
.csFilter
);
1376 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1377 return VFW_E_WRONG_STATE
;
1380 if (This
->allocator
)
1381 IVMRSurfaceAllocatorEx9_Release(This
->allocator
);
1382 if (This
->presenter
)
1383 IVMRImagePresenter9_Release(This
->presenter
);
1385 This
->allocator
= NULL
;
1386 This
->presenter
= NULL
;
1390 case VMR9Mode_Windowed
:
1391 case VMR9Mode_Windowless
:
1392 This
->allocator_is_ex
= 0;
1395 hr
= VMR9DefaultAllocatorPresenterImpl_create(This
, (LPVOID
*)&This
->presenter
);
1397 hr
= IVMRImagePresenter9_QueryInterface(This
->presenter
, &IID_IVMRSurfaceAllocatorEx9
, (LPVOID
*)&This
->allocator
);
1400 ERR("Unable to find Presenter interface\n");
1401 IVMRImagePresenter9_Release(This
->presenter
);
1402 This
->allocator
= NULL
;
1403 This
->presenter
= NULL
;
1406 hr
= IVMRSurfaceAllocatorEx9_AdviseNotify(This
->allocator
, &This
->IVMRSurfaceAllocatorNotify9_iface
);
1408 case VMR9Mode_Renderless
:
1411 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1412 return E_INVALIDARG
;
1416 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1420 static HRESULT WINAPI
VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9
*iface
, DWORD
*mode
)
1422 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1424 TRACE("(%p/%p)->(%p)\n", iface
, This
, mode
);
1431 *mode
= VMR9Mode_Windowed
;
1436 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl
=
1438 VMR9FilterConfig_QueryInterface
,
1439 VMR9FilterConfig_AddRef
,
1440 VMR9FilterConfig_Release
,
1441 VMR9FilterConfig_SetImageCompositor
,
1442 VMR9FilterConfig_SetNumberOfStreams
,
1443 VMR9FilterConfig_GetNumberOfStreams
,
1444 VMR9FilterConfig_SetRenderingPrefs
,
1445 VMR9FilterConfig_GetRenderingPrefs
,
1446 VMR9FilterConfig_SetRenderingMode
,
1447 VMR9FilterConfig_GetRenderingMode
1450 static HRESULT WINAPI
VMR7WindowlessControl_QueryInterface(IVMRWindowlessControl
*iface
, REFIID riid
,
1453 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1454 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1457 static ULONG WINAPI
VMR7WindowlessControl_AddRef(IVMRWindowlessControl
*iface
)
1459 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1460 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1463 static ULONG WINAPI
VMR7WindowlessControl_Release(IVMRWindowlessControl
*iface
)
1465 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1466 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1469 static HRESULT WINAPI
VMR7WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl
*iface
,
1470 LONG
*width
, LONG
*height
,
1471 LONG
*arwidth
, LONG
*arheight
)
1473 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1474 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface
, This
, width
, height
, arwidth
, arheight
);
1476 if (!width
|| !height
|| !arwidth
|| !arheight
)
1478 ERR("Got no pointer\n");
1482 *width
= This
->bmiheader
.biWidth
;
1483 *height
= This
->bmiheader
.biHeight
;
1484 *arwidth
= This
->bmiheader
.biWidth
;
1485 *arheight
= This
->bmiheader
.biHeight
;
1490 static HRESULT WINAPI
VMR7WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl
*iface
,
1491 LONG
*width
, LONG
*height
)
1493 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1495 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1499 static HRESULT WINAPI
VMR7WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl
*iface
,
1500 LONG
*width
, LONG
*height
)
1502 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1504 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1508 static HRESULT WINAPI
VMR7WindowlessControl_SetVideoPosition(IVMRWindowlessControl
*iface
,
1509 const RECT
*source
, const RECT
*dest
)
1511 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1513 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, source
, dest
);
1515 EnterCriticalSection(&This
->renderer
.filter
.csFilter
);
1518 This
->source_rect
= *source
;
1521 This
->target_rect
= *dest
;
1522 FIXME("Output rectangle: %s.\n", wine_dbgstr_rect(dest
));
1523 SetWindowPos(This
->baseControlWindow
.baseWindow
.hWnd
, NULL
,
1524 dest
->left
, dest
->top
, dest
->right
- dest
->left
, dest
->bottom
-dest
->top
,
1525 SWP_NOACTIVATE
| SWP_NOCOPYBITS
| SWP_NOOWNERZORDER
| SWP_NOREDRAW
);
1528 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1533 static HRESULT WINAPI
VMR7WindowlessControl_GetVideoPosition(IVMRWindowlessControl
*iface
,
1534 RECT
*source
, RECT
*dest
)
1536 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1539 *source
= This
->source_rect
;
1542 *dest
= This
->target_rect
;
1544 FIXME("(%p/%p)->(%p/%p) stub\n", iface
, This
, source
, dest
);
1548 static HRESULT WINAPI
VMR7WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl
*iface
,
1551 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1553 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1557 static HRESULT WINAPI
VMR7WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl
*iface
,
1560 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1562 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1566 static HRESULT WINAPI
VMR7WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl
*iface
, HWND window
)
1568 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl(iface
);
1570 TRACE("iface %p, window %p.\n", iface
, window
);
1572 return IVMRWindowlessControl9_SetVideoClippingWindow(&filter
->IVMRWindowlessControl9_iface
, window
);
1575 static HRESULT WINAPI
VMR7WindowlessControl_RepaintVideo(IVMRWindowlessControl
*iface
,
1578 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1580 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1584 static HRESULT WINAPI
VMR7WindowlessControl_DisplayModeChanged(IVMRWindowlessControl
*iface
)
1586 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1588 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1592 static HRESULT WINAPI
VMR7WindowlessControl_GetCurrentImage(IVMRWindowlessControl
*iface
,
1595 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1597 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1601 static HRESULT WINAPI
VMR7WindowlessControl_SetBorderColor(IVMRWindowlessControl
*iface
,
1604 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1606 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1610 static HRESULT WINAPI
VMR7WindowlessControl_GetBorderColor(IVMRWindowlessControl
*iface
,
1613 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1615 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1619 static HRESULT WINAPI
VMR7WindowlessControl_SetColorKey(IVMRWindowlessControl
*iface
, COLORREF color
)
1621 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1623 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1627 static HRESULT WINAPI
VMR7WindowlessControl_GetColorKey(IVMRWindowlessControl
*iface
, COLORREF
*color
)
1629 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1631 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1635 static const IVMRWindowlessControlVtbl VMR7_WindowlessControl_Vtbl
=
1637 VMR7WindowlessControl_QueryInterface
,
1638 VMR7WindowlessControl_AddRef
,
1639 VMR7WindowlessControl_Release
,
1640 VMR7WindowlessControl_GetNativeVideoSize
,
1641 VMR7WindowlessControl_GetMinIdealVideoSize
,
1642 VMR7WindowlessControl_GetMaxIdealVideoSize
,
1643 VMR7WindowlessControl_SetVideoPosition
,
1644 VMR7WindowlessControl_GetVideoPosition
,
1645 VMR7WindowlessControl_GetAspectRatioMode
,
1646 VMR7WindowlessControl_SetAspectRatioMode
,
1647 VMR7WindowlessControl_SetVideoClippingWindow
,
1648 VMR7WindowlessControl_RepaintVideo
,
1649 VMR7WindowlessControl_DisplayModeChanged
,
1650 VMR7WindowlessControl_GetCurrentImage
,
1651 VMR7WindowlessControl_SetBorderColor
,
1652 VMR7WindowlessControl_GetBorderColor
,
1653 VMR7WindowlessControl_SetColorKey
,
1654 VMR7WindowlessControl_GetColorKey
1657 static HRESULT WINAPI
VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9
*iface
, REFIID riid
, LPVOID
* ppv
)
1659 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1660 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1663 static ULONG WINAPI
VMR9WindowlessControl_AddRef(IVMRWindowlessControl9
*iface
)
1665 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1666 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1669 static ULONG WINAPI
VMR9WindowlessControl_Release(IVMRWindowlessControl9
*iface
)
1671 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1672 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1675 static HRESULT WINAPI
VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9
*iface
, LONG
*width
, LONG
*height
, LONG
*arwidth
, LONG
*arheight
)
1677 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1678 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface
, This
, width
, height
, arwidth
, arheight
);
1680 if (!width
|| !height
|| !arwidth
|| !arheight
)
1682 ERR("Got no pointer\n");
1686 *width
= This
->bmiheader
.biWidth
;
1687 *height
= This
->bmiheader
.biHeight
;
1688 *arwidth
= This
->bmiheader
.biWidth
;
1689 *arheight
= This
->bmiheader
.biHeight
;
1694 static HRESULT WINAPI
VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9
*iface
, LONG
*width
, LONG
*height
)
1696 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1698 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1702 static HRESULT WINAPI
VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9
*iface
, LONG
*width
, LONG
*height
)
1704 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1706 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1710 static HRESULT WINAPI
VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9
*iface
, const RECT
*source
, const RECT
*dest
)
1712 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1714 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, source
, dest
);
1716 EnterCriticalSection(&This
->renderer
.filter
.csFilter
);
1719 This
->source_rect
= *source
;
1722 This
->target_rect
= *dest
;
1723 FIXME("Output rectangle: %s.\n", wine_dbgstr_rect(dest
));
1724 SetWindowPos(This
->baseControlWindow
.baseWindow
.hWnd
, NULL
,
1725 dest
->left
, dest
->top
, dest
->right
- dest
->left
, dest
->bottom
- dest
->top
,
1726 SWP_NOACTIVATE
| SWP_NOCOPYBITS
| SWP_NOOWNERZORDER
| SWP_NOREDRAW
);
1729 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1734 static HRESULT WINAPI
VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9
*iface
, RECT
*source
, RECT
*dest
)
1736 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1739 *source
= This
->source_rect
;
1742 *dest
= This
->target_rect
;
1744 FIXME("(%p/%p)->(%p/%p) stub\n", iface
, This
, source
, dest
);
1748 static HRESULT WINAPI
VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9
*iface
, DWORD
*mode
)
1750 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1752 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1756 static HRESULT WINAPI
VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9
*iface
, DWORD mode
)
1758 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1760 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1764 static HRESULT WINAPI
VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9
*iface
, HWND hwnd
)
1766 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1768 TRACE("(%p/%p)->(%p)\n", iface
, This
, hwnd
);
1770 EnterCriticalSection(&This
->renderer
.filter
.csFilter
);
1771 This
->hWndClippingWindow
= hwnd
;
1772 if (This
->renderer
.sink
.pin
.peer
)
1773 VMR9_maybe_init(This
, FALSE
);
1775 IVMRSurfaceAllocatorEx9_TerminateDevice(This
->allocator
, This
->cookie
);
1776 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1780 static HRESULT WINAPI
VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9
*iface
, HWND hwnd
, HDC hdc
)
1782 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1785 FIXME("(%p/%p)->(...) semi-stub\n", iface
, This
);
1787 EnterCriticalSection(&This
->renderer
.filter
.csFilter
);
1788 if (hwnd
!= This
->hWndClippingWindow
&& hwnd
!= This
->baseControlWindow
.baseWindow
.hWnd
)
1790 ERR("Not handling changing windows yet!!!\n");
1791 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1795 if (!This
->allocator_d3d9_dev
)
1797 ERR("No d3d9 device!\n");
1798 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1799 return VFW_E_WRONG_STATE
;
1802 /* Windowless extension */
1803 hr
= IDirect3DDevice9_Present(This
->allocator_d3d9_dev
, NULL
, NULL
, This
->baseControlWindow
.baseWindow
.hWnd
, NULL
);
1804 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1809 static HRESULT WINAPI
VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9
*iface
)
1811 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1813 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1817 static HRESULT WINAPI
VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9
*iface
, BYTE
**dib
)
1819 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1821 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1825 static HRESULT WINAPI
VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9
*iface
, COLORREF color
)
1827 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1829 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1833 static HRESULT WINAPI
VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9
*iface
, COLORREF
*color
)
1835 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1837 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1841 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl
=
1843 VMR9WindowlessControl_QueryInterface
,
1844 VMR9WindowlessControl_AddRef
,
1845 VMR9WindowlessControl_Release
,
1846 VMR9WindowlessControl_GetNativeVideoSize
,
1847 VMR9WindowlessControl_GetMinIdealVideoSize
,
1848 VMR9WindowlessControl_GetMaxIdealVideoSize
,
1849 VMR9WindowlessControl_SetVideoPosition
,
1850 VMR9WindowlessControl_GetVideoPosition
,
1851 VMR9WindowlessControl_GetAspectRatioMode
,
1852 VMR9WindowlessControl_SetAspectRatioMode
,
1853 VMR9WindowlessControl_SetVideoClippingWindow
,
1854 VMR9WindowlessControl_RepaintVideo
,
1855 VMR9WindowlessControl_DisplayModeChanged
,
1856 VMR9WindowlessControl_GetCurrentImage
,
1857 VMR9WindowlessControl_SetBorderColor
,
1858 VMR9WindowlessControl_GetBorderColor
1861 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify
*iface
,
1862 REFIID riid
, LPVOID
* ppv
)
1864 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1865 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1868 static ULONG WINAPI
VMR7SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify
*iface
)
1870 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1871 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1874 static ULONG WINAPI
VMR7SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify
*iface
)
1876 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1877 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1880 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify
*iface
,
1882 IVMRSurfaceAllocator
*alloc
)
1884 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1886 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1890 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_SetDDrawDevice(IVMRSurfaceAllocatorNotify
*iface
,
1891 IDirectDraw7
*device
, HMONITOR monitor
)
1893 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1895 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1899 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_ChangeDDrawDevice(IVMRSurfaceAllocatorNotify
*iface
,
1900 IDirectDraw7
*device
, HMONITOR monitor
)
1902 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1904 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1908 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces(IVMRSurfaceAllocatorNotify
*iface
)
1910 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1912 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1916 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify
*iface
, LONG code
,
1917 LONG_PTR param1
, LONG_PTR param2
)
1919 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1921 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1925 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_SetBorderColor(IVMRSurfaceAllocatorNotify
*iface
,
1928 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1930 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1934 static const IVMRSurfaceAllocatorNotifyVtbl VMR7_SurfaceAllocatorNotify_Vtbl
=
1936 VMR7SurfaceAllocatorNotify_QueryInterface
,
1937 VMR7SurfaceAllocatorNotify_AddRef
,
1938 VMR7SurfaceAllocatorNotify_Release
,
1939 VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator
,
1940 VMR7SurfaceAllocatorNotify_SetDDrawDevice
,
1941 VMR7SurfaceAllocatorNotify_ChangeDDrawDevice
,
1942 VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces
,
1943 VMR7SurfaceAllocatorNotify_NotifyEvent
,
1944 VMR7SurfaceAllocatorNotify_SetBorderColor
1947 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9
*iface
, REFIID riid
, LPVOID
* ppv
)
1949 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1950 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1953 static ULONG WINAPI
VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9
*iface
)
1955 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1956 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1959 static ULONG WINAPI
VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9
*iface
)
1961 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1962 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1965 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9
*iface
, DWORD_PTR id
, IVMRSurfaceAllocator9
*alloc
)
1967 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1969 /* FIXME: This code is not tested!!! */
1970 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1973 if (This
->presenter
)
1974 return VFW_E_WRONG_STATE
;
1976 if (FAILED(IVMRSurfaceAllocator9_QueryInterface(alloc
, &IID_IVMRImagePresenter9
, (void **)&This
->presenter
)))
1977 return E_NOINTERFACE
;
1979 if (SUCCEEDED(IVMRSurfaceAllocator9_QueryInterface(alloc
, &IID_IVMRSurfaceAllocatorEx9
, (void **)&This
->allocator
)))
1980 This
->allocator_is_ex
= 1;
1983 This
->allocator
= (IVMRSurfaceAllocatorEx9
*)alloc
;
1984 IVMRSurfaceAllocator9_AddRef(alloc
);
1985 This
->allocator_is_ex
= 0;
1991 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9
*iface
, IDirect3DDevice9
*device
, HMONITOR monitor
)
1993 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1995 FIXME("(%p/%p)->(...) semi-stub\n", iface
, This
);
1996 if (This
->allocator_d3d9_dev
)
1997 IDirect3DDevice9_Release(This
->allocator_d3d9_dev
);
1998 This
->allocator_d3d9_dev
= device
;
1999 IDirect3DDevice9_AddRef(This
->allocator_d3d9_dev
);
2000 This
->allocator_mon
= monitor
;
2005 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9
*iface
, IDirect3DDevice9
*device
, HMONITOR monitor
)
2007 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
2009 FIXME("(%p/%p)->(...) semi-stub\n", iface
, This
);
2010 if (This
->allocator_d3d9_dev
)
2011 IDirect3DDevice9_Release(This
->allocator_d3d9_dev
);
2012 This
->allocator_d3d9_dev
= device
;
2013 IDirect3DDevice9_AddRef(This
->allocator_d3d9_dev
);
2014 This
->allocator_mon
= monitor
;
2019 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9
*iface
, VMR9AllocationInfo
*allocinfo
, DWORD
*numbuffers
, IDirect3DSurface9
**surface
)
2021 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
2025 FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface
, This
, allocinfo
, numbuffers
, (numbuffers
? *numbuffers
: 0), surface
);
2027 if (!allocinfo
|| !numbuffers
|| !surface
)
2030 if (!*numbuffers
|| *numbuffers
< allocinfo
->MinBuffers
)
2032 ERR("Invalid number of buffers?\n");
2033 return E_INVALIDARG
;
2036 if (!This
->allocator_d3d9_dev
)
2038 ERR("No direct3d device when requested to allocate a surface!\n");
2039 return VFW_E_WRONG_STATE
;
2042 if (allocinfo
->dwFlags
& VMR9AllocFlag_OffscreenSurface
)
2044 ERR("Creating offscreen surface\n");
2045 for (i
= 0; i
< *numbuffers
; ++i
)
2047 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(This
->allocator_d3d9_dev
, allocinfo
->dwWidth
, allocinfo
->dwHeight
,
2048 allocinfo
->Format
, allocinfo
->Pool
, &surface
[i
], NULL
);
2053 else if (allocinfo
->dwFlags
& VMR9AllocFlag_TextureSurface
)
2055 TRACE("Creating texture surface\n");
2056 for (i
= 0; i
< *numbuffers
; ++i
)
2058 IDirect3DTexture9
*texture
;
2060 hr
= IDirect3DDevice9_CreateTexture(This
->allocator_d3d9_dev
, allocinfo
->dwWidth
, allocinfo
->dwHeight
, 1, 0,
2061 allocinfo
->Format
, allocinfo
->Pool
, &texture
, NULL
);
2064 IDirect3DTexture9_GetSurfaceLevel(texture
, 0, &surface
[i
]);
2065 IDirect3DTexture9_Release(texture
);
2070 FIXME("Could not allocate for type %08x\n", allocinfo
->dwFlags
);
2074 if (i
>= allocinfo
->MinBuffers
)
2081 for ( ; i
> 0; --i
) IDirect3DSurface9_Release(surface
[i
- 1]);
2087 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9
*iface
, LONG code
, LONG_PTR param1
, LONG_PTR param2
)
2089 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
2091 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
2095 static const IVMRSurfaceAllocatorNotify9Vtbl VMR9_SurfaceAllocatorNotify_Vtbl
=
2097 VMR9SurfaceAllocatorNotify_QueryInterface
,
2098 VMR9SurfaceAllocatorNotify_AddRef
,
2099 VMR9SurfaceAllocatorNotify_Release
,
2100 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator
,
2101 VMR9SurfaceAllocatorNotify_SetD3DDevice
,
2102 VMR9SurfaceAllocatorNotify_ChangeD3DDevice
,
2103 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper
,
2104 VMR9SurfaceAllocatorNotify_NotifyEvent
2107 static inline struct quartz_vmr
*impl_from_IOverlay(IOverlay
*iface
)
2109 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IOverlay_iface
);
2112 static HRESULT WINAPI
overlay_QueryInterface(IOverlay
*iface
, REFIID iid
, void **out
)
2114 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2115 return IPin_QueryInterface(&filter
->renderer
.sink
.pin
.IPin_iface
, iid
, out
);
2118 static ULONG WINAPI
overlay_AddRef(IOverlay
*iface
)
2120 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2121 return IPin_AddRef(&filter
->renderer
.sink
.pin
.IPin_iface
);
2124 static ULONG WINAPI
overlay_Release(IOverlay
*iface
)
2126 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2127 return IPin_Release(&filter
->renderer
.sink
.pin
.IPin_iface
);
2130 static HRESULT WINAPI
overlay_GetPalette(IOverlay
*iface
, DWORD
*count
, PALETTEENTRY
**palette
)
2132 FIXME("iface %p, count %p, palette %p, stub!\n", iface
, count
, palette
);
2136 static HRESULT WINAPI
overlay_SetPalette(IOverlay
*iface
, DWORD count
, PALETTEENTRY
*palette
)
2138 FIXME("iface %p, count %u, palette %p, stub!\n", iface
, count
, palette
);
2142 static HRESULT WINAPI
overlay_GetDefaultColorKey(IOverlay
*iface
, COLORKEY
*key
)
2144 FIXME("iface %p, key %p, stub!\n", iface
, key
);
2148 static HRESULT WINAPI
overlay_GetColorKey(IOverlay
*iface
, COLORKEY
*key
)
2150 FIXME("iface %p, key %p, stub!\n", iface
, key
);
2154 static HRESULT WINAPI
overlay_SetColorKey(IOverlay
*iface
, COLORKEY
*key
)
2156 FIXME("iface %p, key %p, stub!\n", iface
, key
);
2160 static HRESULT WINAPI
overlay_GetWindowHandle(IOverlay
*iface
, HWND
*window
)
2162 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2164 TRACE("filter %p, window %p.\n", filter
, window
);
2166 *window
= filter
->baseControlWindow
.baseWindow
.hWnd
;
2170 static HRESULT WINAPI
overlay_GetClipList(IOverlay
*iface
, RECT
*source
, RECT
*dest
, RGNDATA
**region
)
2172 FIXME("iface %p, source %p, dest %p, region %p, stub!\n", iface
, source
, dest
, region
);
2176 static HRESULT WINAPI
overlay_GetVideoPosition(IOverlay
*iface
, RECT
*source
, RECT
*dest
)
2178 FIXME("iface %p, source %p, dest %p, stub!\n", iface
, source
, dest
);
2182 static HRESULT WINAPI
overlay_Advise(IOverlay
*iface
, IOverlayNotify
*sink
, DWORD flags
)
2184 FIXME("iface %p, sink %p, flags %#x, stub!\n", iface
, sink
, flags
);
2188 static HRESULT WINAPI
overlay_Unadvise(IOverlay
*iface
)
2190 FIXME("iface %p, stub!\n", iface
);
2194 static const IOverlayVtbl overlay_vtbl
=
2196 overlay_QueryInterface
,
2201 overlay_GetDefaultColorKey
,
2202 overlay_GetColorKey
,
2203 overlay_SetColorKey
,
2204 overlay_GetWindowHandle
,
2205 overlay_GetClipList
,
2206 overlay_GetVideoPosition
,
2211 static HRESULT
vmr_create(IUnknown
*outer
, void **out
, const CLSID
*clsid
)
2214 struct quartz_vmr
* pVMR
;
2218 pVMR
= CoTaskMemAlloc(sizeof(struct quartz_vmr
));
2220 pVMR
->hD3d9
= LoadLibraryA("d3d9.dll");
2223 WARN("Could not load d3d9.dll\n");
2224 CoTaskMemFree(pVMR
);
2225 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
2228 pVMR
->IAMCertifiedOutputProtection_iface
.lpVtbl
= &IAMCertifiedOutputProtection_Vtbl
;
2229 pVMR
->IAMFilterMiscFlags_iface
.lpVtbl
= &IAMFilterMiscFlags_Vtbl
;
2232 pVMR
->allocator_d3d9_dev
= NULL
;
2233 pVMR
->allocator_mon
= NULL
;
2234 pVMR
->num_surfaces
= pVMR
->cur_surface
= 0;
2235 pVMR
->allocator
= NULL
;
2236 pVMR
->presenter
= NULL
;
2237 pVMR
->hWndClippingWindow
= NULL
;
2238 pVMR
->IVMRFilterConfig_iface
.lpVtbl
= &VMR7_FilterConfig_Vtbl
;
2239 pVMR
->IVMRFilterConfig9_iface
.lpVtbl
= &VMR9_FilterConfig_Vtbl
;
2240 pVMR
->IVMRMonitorConfig_iface
.lpVtbl
= &VMR7_MonitorConfig_Vtbl
;
2241 pVMR
->IVMRMonitorConfig9_iface
.lpVtbl
= &VMR9_MonitorConfig_Vtbl
;
2242 pVMR
->IVMRSurfaceAllocatorNotify_iface
.lpVtbl
= &VMR7_SurfaceAllocatorNotify_Vtbl
;
2243 pVMR
->IVMRSurfaceAllocatorNotify9_iface
.lpVtbl
= &VMR9_SurfaceAllocatorNotify_Vtbl
;
2244 pVMR
->IVMRWindowlessControl_iface
.lpVtbl
= &VMR7_WindowlessControl_Vtbl
;
2245 pVMR
->IVMRWindowlessControl9_iface
.lpVtbl
= &VMR9_WindowlessControl_Vtbl
;
2246 pVMR
->IOverlay_iface
.lpVtbl
= &overlay_vtbl
;
2248 hr
= strmbase_renderer_init(&pVMR
->renderer
, outer
, clsid
, L
"VMR Input0", &renderer_ops
);
2252 hr
= strmbase_window_init(&pVMR
->baseControlWindow
, &IVideoWindow_VTable
,
2253 &pVMR
->renderer
.filter
, &pVMR
->renderer
.sink
.pin
, &renderer_BaseWindowFuncTable
);
2257 if (FAILED(hr
= BaseWindowImpl_PrepareWindow(&pVMR
->baseControlWindow
.baseWindow
)))
2260 hr
= strmbase_video_init(&pVMR
->baseControlVideo
, &pVMR
->renderer
.filter
,
2261 &pVMR
->renderer
.sink
.pin
, &renderer_BaseControlVideoFuncTable
);
2265 pVMR
->run_event
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
2267 *out
= &pVMR
->renderer
.filter
.IUnknown_inner
;
2268 ZeroMemory(&pVMR
->source_rect
, sizeof(RECT
));
2269 ZeroMemory(&pVMR
->target_rect
, sizeof(RECT
));
2270 TRACE("Created at %p\n", pVMR
);
2274 BaseWindowImpl_DoneWithWindow(&pVMR
->baseControlWindow
.baseWindow
);
2275 strmbase_renderer_cleanup(&pVMR
->renderer
);
2276 FreeLibrary(pVMR
->hD3d9
);
2277 CoTaskMemFree(pVMR
);
2281 HRESULT
VMR7Impl_create(IUnknown
*outer_unk
, LPVOID
*ppv
)
2283 return vmr_create(outer_unk
, ppv
, &CLSID_VideoMixingRenderer
);
2286 HRESULT
VMR9Impl_create(IUnknown
*outer_unk
, LPVOID
*ppv
)
2288 return vmr_create(outer_unk
, ppv
, &CLSID_VideoMixingRenderer9
);
2292 static HRESULT WINAPI
VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9
*iface
, REFIID riid
, void **ppv
)
2294 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
2295 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, qzdebugstr_guid(riid
), ppv
);
2299 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IVMRImagePresenter9
))
2300 *ppv
= &This
->IVMRImagePresenter9_iface
;
2301 else if (IsEqualIID(riid
, &IID_IVMRSurfaceAllocatorEx9
))
2302 *ppv
= &This
->IVMRSurfaceAllocatorEx9_iface
;
2306 IUnknown_AddRef((IUnknown
*)(*ppv
));
2310 FIXME("No interface for %s\n", debugstr_guid(riid
));
2312 return E_NOINTERFACE
;
2315 static ULONG WINAPI
VMR9_ImagePresenter_AddRef(IVMRImagePresenter9
*iface
)
2317 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
2318 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
2320 TRACE("(%p)->() AddRef from %d\n", iface
, refCount
- 1);
2325 static ULONG WINAPI
VMR9_ImagePresenter_Release(IVMRImagePresenter9
*iface
)
2327 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
2328 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
2330 TRACE("(%p)->() Release from %d\n", iface
, refCount
+ 1);
2335 TRACE("Destroying\n");
2336 IDirect3D9_Release(This
->d3d9_ptr
);
2338 TRACE("Number of surfaces: %u\n", This
->num_surfaces
);
2339 for (i
= 0; i
< This
->num_surfaces
; ++i
)
2341 IDirect3DSurface9
*surface
= This
->d3d9_surfaces
[i
];
2342 TRACE("Releasing surface %p\n", surface
);
2344 IDirect3DSurface9_Release(surface
);
2347 CoTaskMemFree(This
->d3d9_surfaces
);
2348 This
->d3d9_surfaces
= NULL
;
2349 This
->num_surfaces
= 0;
2350 if (This
->d3d9_vertex
)
2352 IDirect3DVertexBuffer9_Release(This
->d3d9_vertex
);
2353 This
->d3d9_vertex
= NULL
;
2355 CoTaskMemFree(This
);
2361 static HRESULT WINAPI
VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9
*iface
, DWORD_PTR id
)
2363 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
2365 TRACE("(%p/%p/%p)->(...) stub\n", iface
, This
,This
->pVMR9
);
2369 static HRESULT WINAPI
VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9
*iface
, DWORD_PTR id
)
2371 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
2373 TRACE("(%p/%p/%p)->(...) stub\n", iface
, This
,This
->pVMR9
);
2377 #define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
2378 struct VERTEX
{ float x
, y
, z
, rhw
, u
, v
; };
2380 static HRESULT
VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl
*This
, IDirect3DSurface9
*surface
)
2382 IDirect3DTexture9
*texture
= NULL
;
2385 hr
= IDirect3DDevice9_SetFVF(This
->d3d9_dev
, USED_FVF
);
2388 FIXME("SetFVF: %08x\n", hr
);
2392 hr
= IDirect3DDevice9_SetStreamSource(This
->d3d9_dev
, 0, This
->d3d9_vertex
, 0, sizeof(struct VERTEX
));
2395 FIXME("SetStreamSource: %08x\n", hr
);
2399 hr
= IDirect3DSurface9_GetContainer(surface
, &IID_IDirect3DTexture9
, (void **) &texture
);
2402 FIXME("IDirect3DSurface9_GetContainer failed\n");
2405 hr
= IDirect3DDevice9_SetTexture(This
->d3d9_dev
, 0, (IDirect3DBaseTexture9
*)texture
);
2406 IDirect3DTexture9_Release(texture
);
2409 FIXME("SetTexture: %08x\n", hr
);
2413 hr
= IDirect3DDevice9_DrawPrimitive(This
->d3d9_dev
, D3DPT_TRIANGLESTRIP
, 0, 2);
2416 FIXME("DrawPrimitive: %08x\n", hr
);
2423 static HRESULT
VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl
*This
, IDirect3DSurface9
*surface
)
2426 IDirect3DSurface9
*target
= NULL
;
2429 hr
= IDirect3DDevice9_GetBackBuffer(This
->d3d9_dev
, 0, 0, D3DBACKBUFFER_TYPE_MONO
, &target
);
2432 ERR("IDirect3DDevice9_GetBackBuffer -- %08x\n", hr
);
2436 /* Move rect to origin and flip it */
2437 SetRect(&target_rect
, 0, This
->pVMR9
->target_rect
.bottom
- This
->pVMR9
->target_rect
.top
,
2438 This
->pVMR9
->target_rect
.right
- This
->pVMR9
->target_rect
.left
, 0);
2440 hr
= IDirect3DDevice9_StretchRect(This
->d3d9_dev
, surface
, &This
->pVMR9
->source_rect
, target
, &target_rect
, D3DTEXF_LINEAR
);
2442 ERR("IDirect3DDevice9_StretchRect -- %08x\n", hr
);
2443 IDirect3DSurface9_Release(target
);
2448 static HRESULT WINAPI
VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9
*iface
, DWORD_PTR id
, VMR9PresentationInfo
*info
)
2450 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
2453 BOOL render
= FALSE
;
2455 TRACE("(%p/%p/%p)->(...) stub\n", iface
, This
, This
->pVMR9
);
2456 GetWindowRect(This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
, &output
);
2457 TRACE("Output rectangle: %s\n", wine_dbgstr_rect(&output
));
2459 /* This might happen if we don't have active focus (eg on a different virtual desktop) */
2460 if (!This
->d3d9_dev
)
2463 /* Display image here */
2464 hr
= IDirect3DDevice9_Clear(This
->d3d9_dev
, 0, NULL
, D3DCLEAR_TARGET
, D3DCOLOR_XRGB(0, 0, 0), 1.0f
, 0);
2466 FIXME("hr: %08x\n", hr
);
2467 hr
= IDirect3DDevice9_BeginScene(This
->d3d9_dev
);
2470 if (This
->d3d9_vertex
)
2471 hr
= VMR9_ImagePresenter_PresentTexture(This
, info
->lpSurf
);
2473 hr
= VMR9_ImagePresenter_PresentOffscreenSurface(This
, info
->lpSurf
);
2474 render
= SUCCEEDED(hr
);
2477 FIXME("BeginScene: %08x\n", hr
);
2478 hr
= IDirect3DDevice9_EndScene(This
->d3d9_dev
);
2479 if (render
&& SUCCEEDED(hr
))
2481 hr
= IDirect3DDevice9_Present(This
->d3d9_dev
, NULL
, NULL
, This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
, NULL
);
2483 FIXME("Presenting image: %08x\n", hr
);
2489 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter
=
2491 VMR9_ImagePresenter_QueryInterface
,
2492 VMR9_ImagePresenter_AddRef
,
2493 VMR9_ImagePresenter_Release
,
2494 VMR9_ImagePresenter_StartPresenting
,
2495 VMR9_ImagePresenter_StopPresenting
,
2496 VMR9_ImagePresenter_PresentImage
2499 static HRESULT WINAPI
VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9
*iface
, REFIID riid
, LPVOID
* ppv
)
2501 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
2503 return VMR9_ImagePresenter_QueryInterface(&This
->IVMRImagePresenter9_iface
, riid
, ppv
);
2506 static ULONG WINAPI
VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9
*iface
)
2508 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
2510 return VMR9_ImagePresenter_AddRef(&This
->IVMRImagePresenter9_iface
);
2513 static ULONG WINAPI
VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9
*iface
)
2515 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
2517 return VMR9_ImagePresenter_Release(&This
->IVMRImagePresenter9_iface
);
2520 static HRESULT
VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl
*This
, VMR9AllocationInfo
*allocinfo
)
2526 if (!(allocinfo
->dwFlags
& VMR9AllocFlag_TextureSurface
))
2527 /* Only needed for texture surfaces */
2530 hr
= IDirect3DDevice9_GetDeviceCaps(This
->d3d9_dev
, &caps
);
2534 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
) || (caps
.TextureCaps
& D3DPTEXTURECAPS_SQUAREONLY
))
2536 width
= allocinfo
->dwWidth
;
2537 height
= allocinfo
->dwHeight
;
2542 while (width
< allocinfo
->dwWidth
)
2545 while (height
< allocinfo
->dwHeight
)
2547 FIXME("NPOW2 support missing, not using proper surfaces!\n");
2550 if (caps
.TextureCaps
& D3DPTEXTURECAPS_SQUAREONLY
)
2556 FIXME("Square texture support required..\n");
2559 hr
= IDirect3DDevice9_CreateVertexBuffer(This
->d3d9_dev
, 4 * sizeof(struct VERTEX
), D3DUSAGE_WRITEONLY
, USED_FVF
, allocinfo
->Pool
, &This
->d3d9_vertex
, NULL
);
2562 ERR("Couldn't create vertex buffer: %08x\n", hr
);
2567 allocinfo
->dwHeight
= height
;
2568 allocinfo
->dwWidth
= width
;
2573 static UINT
d3d9_adapter_from_hwnd(IDirect3D9
*d3d9
, HWND hwnd
, HMONITOR
*mon_out
)
2578 mon
= MonitorFromWindow(hwnd
, MONITOR_DEFAULTTONULL
);
2583 for (d3d9_adapter
= 0; d3d9_adapter
< IDirect3D9_GetAdapterCount(d3d9
); ++d3d9_adapter
)
2585 if (mon
== IDirect3D9_GetAdapterMonitor(d3d9
, d3d9_adapter
))
2588 if (d3d9_adapter
>= IDirect3D9_GetAdapterCount(d3d9
))
2593 return d3d9_adapter
;
2596 static BOOL
CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl
*This
, VMR9AllocationInfo
*info
, DWORD
*numbuffers
)
2598 D3DPRESENT_PARAMETERS d3dpp
;
2602 TRACE("(%p)->()\n", This
);
2604 /* Obtain a monitor and d3d9 device */
2605 d3d9_adapter
= d3d9_adapter_from_hwnd(This
->d3d9_ptr
, This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
, &This
->hMon
);
2607 /* Now try to create the d3d9 device */
2608 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
2609 d3dpp
.Windowed
= TRUE
;
2610 d3dpp
.hDeviceWindow
= This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
;
2611 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2612 d3dpp
.BackBufferHeight
= This
->pVMR9
->target_rect
.bottom
- This
->pVMR9
->target_rect
.top
;
2613 d3dpp
.BackBufferWidth
= This
->pVMR9
->target_rect
.right
- This
->pVMR9
->target_rect
.left
;
2615 hr
= IDirect3D9_CreateDevice(This
->d3d9_ptr
, d3d9_adapter
, D3DDEVTYPE_HAL
, NULL
, D3DCREATE_MIXED_VERTEXPROCESSING
, &d3dpp
, &This
->d3d9_dev
);
2618 ERR("Could not create device: %08x\n", hr
);
2621 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This
->SurfaceAllocatorNotify
, This
->d3d9_dev
, This
->hMon
);
2623 This
->d3d9_surfaces
= CoTaskMemAlloc(*numbuffers
* sizeof(IDirect3DSurface9
*));
2624 ZeroMemory(This
->d3d9_surfaces
, *numbuffers
* sizeof(IDirect3DSurface9
*));
2626 hr
= VMR9_SurfaceAllocator_SetAllocationSettings(This
, info
);
2628 ERR("Setting allocation settings failed: %08x\n", hr
);
2632 hr
= IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This
->SurfaceAllocatorNotify
, info
, numbuffers
, This
->d3d9_surfaces
);
2634 ERR("Allocating surfaces failed: %08x\n", hr
);
2639 IVMRSurfaceAllocatorEx9_TerminateDevice(This
->pVMR9
->allocator
, This
->pVMR9
->cookie
);
2643 This
->num_surfaces
= *numbuffers
;
2648 static HRESULT WINAPI
VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9
*iface
, DWORD_PTR id
, VMR9AllocationInfo
*allocinfo
, DWORD
*numbuffers
)
2650 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
2652 if (This
->pVMR9
->mode
!= VMR9Mode_Windowed
&& !This
->pVMR9
->hWndClippingWindow
)
2654 ERR("No window set\n");
2655 return VFW_E_WRONG_STATE
;
2658 This
->info
= *allocinfo
;
2660 if (!CreateRenderingWindow(This
, allocinfo
, numbuffers
))
2662 ERR("Failed to create rendering window, expect no output!\n");
2663 return VFW_E_WRONG_STATE
;
2669 static HRESULT WINAPI
VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9
*iface
, DWORD_PTR id
)
2671 TRACE("iface %p, id %#lx.\n", iface
, id
);
2676 /* Recreate all surfaces (If allocated as D3DPOOL_DEFAULT) and survive! */
2677 static HRESULT
VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl
*This
)
2679 struct VERTEX t_vert
[4];
2683 D3DPRESENT_PARAMETERS d3dpp
;
2686 if (!This
->d3d9_surfaces
|| !This
->reset
)
2689 This
->reset
= FALSE
;
2690 TRACE("RESETTING\n");
2691 if (This
->d3d9_vertex
)
2693 IDirect3DVertexBuffer9_Release(This
->d3d9_vertex
);
2694 This
->d3d9_vertex
= NULL
;
2697 for (i
= 0; i
< This
->num_surfaces
; ++i
)
2699 IDirect3DSurface9
*surface
= This
->d3d9_surfaces
[i
];
2700 TRACE("Releasing surface %p\n", surface
);
2702 IDirect3DSurface9_Release(surface
);
2704 ZeroMemory(This
->d3d9_surfaces
, sizeof(IDirect3DSurface9
*) * This
->num_surfaces
);
2706 /* Now try to create the d3d9 device */
2707 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
2708 d3dpp
.Windowed
= TRUE
;
2709 d3dpp
.hDeviceWindow
= This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
;
2710 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2713 IDirect3DDevice9_Release(This
->d3d9_dev
);
2714 This
->d3d9_dev
= NULL
;
2715 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
);
2718 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
);
2721 ERR("--> Creating device: %08x\n", hr
);
2725 IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(This
->SurfaceAllocatorNotify
, This
->d3d9_dev
, This
->hMon
);
2727 IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This
->SurfaceAllocatorNotify
, &This
->info
, &This
->num_surfaces
, This
->d3d9_surfaces
);
2729 This
->reset
= FALSE
;
2731 if (!(This
->info
.dwFlags
& VMR9AllocFlag_TextureSurface
))
2734 hr
= IDirect3DDevice9_CreateVertexBuffer(This
->d3d9_dev
, 4 * sizeof(struct VERTEX
), D3DUSAGE_WRITEONLY
, USED_FVF
,
2735 This
->info
.Pool
, &This
->d3d9_vertex
, NULL
);
2737 width
= This
->info
.dwWidth
;
2738 height
= This
->info
.dwHeight
;
2740 for (i
= 0; i
< ARRAY_SIZE(t_vert
); ++i
)
2744 t_vert
[i
].x
= (float)This
->pVMR9
->target_rect
.right
- (float)This
->pVMR9
->target_rect
.left
- 0.5f
;
2745 t_vert
[i
].u
= (float)This
->pVMR9
->source_rect
.right
/ (float)width
;
2749 t_vert
[i
].x
= -0.5f
;
2750 t_vert
[i
].u
= (float)This
->pVMR9
->source_rect
.left
/ (float)width
;
2755 t_vert
[i
].y
= -0.5f
;
2756 t_vert
[i
].v
= (float)This
->pVMR9
->source_rect
.bottom
/ (float)height
;
2760 t_vert
[i
].y
= (float)This
->pVMR9
->target_rect
.bottom
- (float)This
->pVMR9
->target_rect
.top
- 0.5f
;
2761 t_vert
[i
].v
= (float)This
->pVMR9
->source_rect
.top
/ (float)height
;
2764 t_vert
[i
].rhw
= 1.0f
;
2767 FIXME("Vertex rectangle:\n");
2768 FIXME("X, Y: %f, %f\n", t_vert
[0].x
, t_vert
[0].y
);
2769 FIXME("X, Y: %f, %f\n", t_vert
[3].x
, t_vert
[3].y
);
2770 FIXME("TOP, LEFT: %f, %f\n", t_vert
[0].u
, t_vert
[0].v
);
2771 FIXME("DOWN, BOTTOM: %f, %f\n", t_vert
[3].u
, t_vert
[3].v
);
2773 IDirect3DVertexBuffer9_Lock(This
->d3d9_vertex
, 0, sizeof(t_vert
), &bits
, 0);
2774 memcpy(bits
, t_vert
, sizeof(t_vert
));
2775 IDirect3DVertexBuffer9_Unlock(This
->d3d9_vertex
);
2780 static HRESULT WINAPI
VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9
*iface
, DWORD_PTR id
, DWORD surfaceindex
, DWORD flags
, IDirect3DSurface9
**surface
)
2782 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
2784 /* Update everything first, this is needed because the surface might be destroyed in the reset */
2785 if (!This
->d3d9_dev
)
2787 TRACE("Device has left me!\n");
2791 VMR9_SurfaceAllocator_UpdateDeviceReset(This
);
2793 if (surfaceindex
>= This
->num_surfaces
)
2795 ERR("surfaceindex is greater than num_surfaces\n");
2798 *surface
= This
->d3d9_surfaces
[surfaceindex
];
2799 IDirect3DSurface9_AddRef(*surface
);
2804 static HRESULT WINAPI
VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9
*iface
, IVMRSurfaceAllocatorNotify9
*allocnotify
)
2806 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
2808 TRACE("(%p/%p)->(...)\n", iface
, This
);
2810 /* No AddRef taken here or the base VMR9 filter would never be destroyed */
2811 This
->SurfaceAllocatorNotify
= allocnotify
;
2815 static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator
=
2817 VMR9_SurfaceAllocator_QueryInterface
,
2818 VMR9_SurfaceAllocator_AddRef
,
2819 VMR9_SurfaceAllocator_Release
,
2820 VMR9_SurfaceAllocator_InitializeDevice
,
2821 VMR9_SurfaceAllocator_TerminateDevice
,
2822 VMR9_SurfaceAllocator_GetSurface
,
2823 VMR9_SurfaceAllocator_AdviseNotify
,
2824 NULL
/* This isn't the SurfaceAllocatorEx type yet, working on it */
2827 static IDirect3D9
*init_d3d9(HMODULE d3d9_handle
)
2829 IDirect3D9
* (__stdcall
* d3d9_create
)(UINT SDKVersion
);
2831 d3d9_create
= (void *)GetProcAddress(d3d9_handle
, "Direct3DCreate9");
2832 if (!d3d9_create
) return NULL
;
2834 return d3d9_create(D3D_SDK_VERSION
);
2837 static HRESULT
VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr
*parent
, LPVOID
* ppv
)
2841 VMR9DefaultAllocatorPresenterImpl
* This
;
2843 This
= CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl
));
2845 return E_OUTOFMEMORY
;
2847 This
->d3d9_ptr
= init_d3d9(parent
->hD3d9
);
2848 if (!This
->d3d9_ptr
)
2850 WARN("Could not initialize d3d9.dll\n");
2851 CoTaskMemFree(This
);
2852 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
2858 D3DDISPLAYMODE mode
;
2860 hr
= IDirect3D9_EnumAdapterModes(This
->d3d9_ptr
, i
++, D3DFMT_X8R8G8B8
, 0, &mode
);
2861 if (hr
== D3DERR_INVALIDCALL
) break; /* out of adapters */
2862 } while (FAILED(hr
));
2864 ERR("HR: %08x\n", hr
);
2865 if (hr
== D3DERR_NOTAVAILABLE
)
2867 ERR("Format not supported\n");
2868 IDirect3D9_Release(This
->d3d9_ptr
);
2869 CoTaskMemFree(This
);
2870 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
2873 This
->IVMRImagePresenter9_iface
.lpVtbl
= &VMR9_ImagePresenter
;
2874 This
->IVMRSurfaceAllocatorEx9_iface
.lpVtbl
= &VMR9_SurfaceAllocator
;
2877 This
->pVMR9
= parent
;
2878 This
->d3d9_surfaces
= NULL
;
2879 This
->d3d9_dev
= NULL
;
2881 This
->d3d9_vertex
= NULL
;
2882 This
->num_surfaces
= 0;
2883 This
->SurfaceAllocatorNotify
= NULL
;
2884 This
->reset
= FALSE
;
2886 *ppv
= &This
->IVMRImagePresenter9_iface
;