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
);
42 static inline const char *debugstr_normalized_rect(const VMR9NormalizedRect
*rect
)
44 if (!rect
) return "(null)";
45 return wine_dbg_sprintf("(%.8e,%.8e)-(%.8e,%.8e)", rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
48 static const BITMAPINFOHEADER
*get_bitmap_header(const AM_MEDIA_TYPE
*mt
)
50 if (IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
))
51 return &((VIDEOINFOHEADER
*)mt
->pbFormat
)->bmiHeader
;
53 return &((VIDEOINFOHEADER2
*)mt
->pbFormat
)->bmiHeader
;
58 struct strmbase_renderer renderer
;
59 struct video_window window
;
61 IAMCertifiedOutputProtection IAMCertifiedOutputProtection_iface
;
62 IAMFilterMiscFlags IAMFilterMiscFlags_iface
;
63 IVMRAspectRatioControl9 IVMRAspectRatioControl9_iface
;
64 IVMRFilterConfig IVMRFilterConfig_iface
;
65 IVMRFilterConfig9 IVMRFilterConfig9_iface
;
66 IVMRMixerBitmap9 IVMRMixerBitmap9_iface
;
67 IVMRMixerControl9 IVMRMixerControl9_iface
;
68 IVMRMonitorConfig IVMRMonitorConfig_iface
;
69 IVMRMonitorConfig9 IVMRMonitorConfig9_iface
;
70 IVMRSurfaceAllocatorNotify IVMRSurfaceAllocatorNotify_iface
;
71 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface
;
72 IVMRWindowlessControl IVMRWindowlessControl_iface
;
73 IVMRWindowlessControl9 IVMRWindowlessControl9_iface
;
75 /* Devil May Cry 3 releases the last IBaseFilter reference while still
76 * holding an IVMRSurfaceAllocatorNotify9 reference, and depends on
77 * IVMRSurfaceAllocator9::TerminateDevice() being called as a result.
78 * Native uses a separate reference count for IVMRSurfaceAllocatorNotify9. */
79 LONG IVMRSurfaceAllocatorNotify9_refcount
;
81 IOverlay IOverlay_iface
;
83 IVMRSurfaceAllocator9
*allocator
;
84 IVMRImagePresenter9
*presenter
;
90 * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed
91 * What I do is implement windowless as a special case of renderless, and then
92 * windowed also as a special case of windowless. This is probably the easiest way.
95 BITMAPINFOHEADER bmiheader
;
99 /* Presentation related members */
100 IDirect3DDevice9
*allocator_d3d9_dev
;
101 IDirect3DSurface9
**surfaces
;
106 HWND clipping_window
;
110 VMR9AspectRatioMode aspect_mode
;
113 static inline BOOL
is_vmr9(const struct quartz_vmr
*filter
)
115 return IsEqualGUID(&filter
->renderer
.filter
.clsid
, &CLSID_VideoMixingRenderer9
);
118 static inline struct quartz_vmr
*impl_from_video_window(struct video_window
*iface
)
120 return CONTAINING_RECORD(iface
, struct quartz_vmr
, window
);
123 static inline struct quartz_vmr
*impl_from_IAMCertifiedOutputProtection(IAMCertifiedOutputProtection
*iface
)
125 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IAMCertifiedOutputProtection_iface
);
128 static inline struct quartz_vmr
*impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags
*iface
)
130 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IAMFilterMiscFlags_iface
);
133 static inline struct quartz_vmr
*impl_from_IVMRFilterConfig(IVMRFilterConfig
*iface
)
135 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRFilterConfig_iface
);
138 static inline struct quartz_vmr
*impl_from_IVMRFilterConfig9(IVMRFilterConfig9
*iface
)
140 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRFilterConfig9_iface
);
143 static inline struct quartz_vmr
*impl_from_IVMRMonitorConfig(IVMRMonitorConfig
*iface
)
145 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRMonitorConfig_iface
);
148 static inline struct quartz_vmr
*impl_from_IVMRMonitorConfig9(IVMRMonitorConfig9
*iface
)
150 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRMonitorConfig9_iface
);
153 static inline struct quartz_vmr
*impl_from_IVMRSurfaceAllocatorNotify(IVMRSurfaceAllocatorNotify
*iface
)
155 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRSurfaceAllocatorNotify_iface
);
158 static inline struct quartz_vmr
*impl_from_IVMRSurfaceAllocatorNotify9(IVMRSurfaceAllocatorNotify9
*iface
)
160 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRSurfaceAllocatorNotify9_iface
);
163 static inline struct quartz_vmr
*impl_from_IVMRWindowlessControl(IVMRWindowlessControl
*iface
)
165 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRWindowlessControl_iface
);
168 static inline struct quartz_vmr
*impl_from_IVMRWindowlessControl9(IVMRWindowlessControl9
*iface
)
170 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRWindowlessControl9_iface
);
173 struct default_presenter
175 IVMRImagePresenter9 IVMRImagePresenter9_iface
;
176 IVMRSurfaceAllocator9 IVMRSurfaceAllocator9_iface
;
180 IDirect3DDevice9
*d3d9_dev
;
181 IDirect3D9
*d3d9_ptr
;
182 IDirect3DSurface9
**d3d9_surfaces
;
186 VMR9AllocationInfo info
;
188 struct quartz_vmr
* pVMR9
;
189 IVMRSurfaceAllocatorNotify9
*SurfaceAllocatorNotify
;
192 static inline struct default_presenter
*impl_from_IVMRImagePresenter9(IVMRImagePresenter9
*iface
)
194 return CONTAINING_RECORD(iface
, struct default_presenter
, IVMRImagePresenter9_iface
);
197 static inline struct default_presenter
*impl_from_IVMRSurfaceAllocator9(IVMRSurfaceAllocator9
*iface
)
199 return CONTAINING_RECORD(iface
, struct default_presenter
, IVMRSurfaceAllocator9_iface
);
202 static HRESULT
VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr
*parent
, LPVOID
* ppv
);
204 static inline struct quartz_vmr
*impl_from_IBaseFilter(IBaseFilter
*iface
)
206 return CONTAINING_RECORD(iface
, struct quartz_vmr
, renderer
.filter
.IBaseFilter_iface
);
209 static HRESULT
vmr_render(struct strmbase_renderer
*iface
, IMediaSample
*sample
)
211 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
212 unsigned int data_size
, width
, depth
, src_pitch
;
213 const BITMAPINFOHEADER
*bitmap_header
;
214 REFERENCE_TIME start_time
, end_time
;
215 VMR9PresentationInfo info
= {};
216 D3DLOCKED_RECT locked_rect
;
221 TRACE("filter %p, sample %p.\n", filter
, sample
);
223 /* It is possible that there is no device at this point */
225 if (!filter
->allocator
|| !filter
->presenter
)
227 ERR("NO PRESENTER!!\n");
231 info
.dwFlags
= VMR9Sample_SrcDstRectsValid
;
233 if (SUCCEEDED(hr
= IMediaSample_GetTime(sample
, &start_time
, &end_time
)))
234 info
.dwFlags
|= VMR9Sample_TimeValid
;
236 if (IMediaSample_IsDiscontinuity(sample
) == S_OK
)
237 info
.dwFlags
|= VMR9Sample_Discontinuity
;
239 if (IMediaSample_IsPreroll(sample
) == S_OK
)
240 info
.dwFlags
|= VMR9Sample_Preroll
;
242 if (IMediaSample_IsSyncPoint(sample
) == S_OK
)
243 info
.dwFlags
|= VMR9Sample_SyncPoint
;
245 if (FAILED(hr
= IMediaSample_GetPointer(sample
, &data
)))
247 ERR("Failed to get pointer to sample data, hr %#x.\n", hr
);
250 data_size
= IMediaSample_GetActualDataLength(sample
);
252 bitmap_header
= get_bitmap_header(&filter
->renderer
.sink
.pin
.mt
);
253 width
= bitmap_header
->biWidth
;
254 height
= bitmap_header
->biHeight
;
255 depth
= bitmap_header
->biBitCount
;
256 if (bitmap_header
->biCompression
== mmioFOURCC('N','V','1','2')
257 || bitmap_header
->biCompression
== mmioFOURCC('Y','V','1','2'))
259 else /* packed YUV (UYVY or YUY2) or RGB */
260 src_pitch
= ((width
* depth
/ 8) + 3) & ~3;
262 info
.rtStart
= start_time
;
263 info
.rtEnd
= end_time
;
264 info
.szAspectRatio
.cx
= width
;
265 info
.szAspectRatio
.cy
= height
;
266 info
.lpSurf
= filter
->surfaces
[(++filter
->cur_surface
) % filter
->num_surfaces
];
268 if (FAILED(hr
= IDirect3DSurface9_LockRect(info
.lpSurf
, &locked_rect
, NULL
, D3DLOCK_DISCARD
)))
270 ERR("Failed to lock surface, hr %#x.\n", hr
);
274 if (height
> 0 && bitmap_header
->biCompression
== BI_RGB
)
276 BYTE
*dst
= (BYTE
*)locked_rect
.pBits
+ (height
* locked_rect
.Pitch
);
277 const BYTE
*src
= data
;
279 TRACE("Inverting image.\n");
283 dst
-= locked_rect
.Pitch
;
284 memcpy(dst
, src
, width
* depth
/ 8);
288 else if (locked_rect
.Pitch
!= src_pitch
)
290 BYTE
*dst
= locked_rect
.pBits
;
291 const BYTE
*src
= data
;
293 height
= abs(height
);
295 TRACE("Source pitch %u does not match dest pitch %u; copying manually.\n",
296 src_pitch
, locked_rect
.Pitch
);
300 memcpy(dst
, src
, width
* depth
/ 8);
302 dst
+= locked_rect
.Pitch
;
307 memcpy(locked_rect
.pBits
, data
, data_size
);
310 IDirect3DSurface9_UnlockRect(info
.lpSurf
);
312 return IVMRImagePresenter9_PresentImage(filter
->presenter
, filter
->cookie
, &info
);
315 static HRESULT
vmr_query_accept(struct strmbase_renderer
*iface
, const AM_MEDIA_TYPE
*mt
)
317 if (!IsEqualIID(&mt
->majortype
, &MEDIATYPE_Video
) || !mt
->pbFormat
)
320 if (!IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
)
321 && !IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo2
))
327 static HRESULT
initialize_device(struct quartz_vmr
*filter
, VMR9AllocationInfo
*info
, DWORD count
)
332 if (FAILED(hr
= IVMRSurfaceAllocator9_InitializeDevice(filter
->allocator
,
333 filter
->cookie
, info
, &count
)))
335 WARN("Failed to initialize device (flags %#x), hr %#x.\n", info
->dwFlags
, hr
);
339 for (i
= 0; i
< count
; ++i
)
341 if (FAILED(hr
= IVMRSurfaceAllocator9_GetSurface(filter
->allocator
,
342 filter
->cookie
, i
, 0, &filter
->surfaces
[i
])))
344 ERR("Failed to get surface %u, hr %#x.\n", i
, hr
);
346 IDirect3DSurface9_Release(filter
->surfaces
[i
]);
347 IVMRSurfaceAllocator9_TerminateDevice(filter
->allocator
, filter
->cookie
);
355 static HRESULT
allocate_surfaces(struct quartz_vmr
*filter
, const AM_MEDIA_TYPE
*mt
)
357 VMR9AllocationInfo info
= {};
370 {&MEDIASUBTYPE_ARGB1555
, D3DFMT_A1R5G5B5
, VMR9AllocFlag_TextureSurface
},
371 {&MEDIASUBTYPE_ARGB32
, D3DFMT_A8R8G8B8
, VMR9AllocFlag_TextureSurface
},
372 {&MEDIASUBTYPE_ARGB4444
, D3DFMT_A4R4G4B4
, VMR9AllocFlag_TextureSurface
},
374 {&MEDIASUBTYPE_RGB24
, D3DFMT_R8G8B8
, VMR9AllocFlag_TextureSurface
| VMR9AllocFlag_OffscreenSurface
},
375 {&MEDIASUBTYPE_RGB32
, D3DFMT_X8R8G8B8
, VMR9AllocFlag_TextureSurface
| VMR9AllocFlag_OffscreenSurface
},
376 {&MEDIASUBTYPE_RGB555
, D3DFMT_X1R5G5B5
, VMR9AllocFlag_TextureSurface
| VMR9AllocFlag_OffscreenSurface
},
377 {&MEDIASUBTYPE_RGB565
, D3DFMT_R5G6B5
, VMR9AllocFlag_TextureSurface
| VMR9AllocFlag_OffscreenSurface
},
379 {&MEDIASUBTYPE_NV12
, MAKEFOURCC('N','V','1','2'), VMR9AllocFlag_OffscreenSurface
},
380 {&MEDIASUBTYPE_UYVY
, D3DFMT_UYVY
, VMR9AllocFlag_OffscreenSurface
},
381 {&MEDIASUBTYPE_YUY2
, D3DFMT_YUY2
, VMR9AllocFlag_OffscreenSurface
},
382 {&MEDIASUBTYPE_YV12
, MAKEFOURCC('Y','V','1','2'), VMR9AllocFlag_OffscreenSurface
},
385 TRACE("Initializing in mode %u, our window %p, clipping window %p.\n",
386 filter
->mode
, filter
->window
.hwnd
, filter
->clipping_window
);
388 if (filter
->mode
== VMR9Mode_Windowless
&& !filter
->clipping_window
)
391 info
.Pool
= D3DPOOL_DEFAULT
;
392 info
.MinBuffers
= count
;
393 info
.dwWidth
= info
.szAspectRatio
.cx
= info
.szNativeSize
.cx
= filter
->bmiheader
.biWidth
;
394 info
.dwHeight
= info
.szAspectRatio
.cy
= info
.szNativeSize
.cy
= filter
->bmiheader
.biHeight
;
396 if (!(filter
->surfaces
= calloc(count
, sizeof(IDirect3DSurface9
*))))
397 return E_OUTOFMEMORY
;
398 filter
->num_surfaces
= count
;
399 filter
->cur_surface
= 0;
401 if (!is_vmr9(filter
))
403 switch (filter
->bmiheader
.biCompression
)
406 switch (filter
->bmiheader
.biBitCount
)
408 case 24: info
.Format
= D3DFMT_R8G8B8
; break;
409 case 32: info
.Format
= D3DFMT_X8R8G8B8
; break;
411 FIXME("Unhandled bit depth %u.\n", filter
->bmiheader
.biBitCount
);
412 free(filter
->surfaces
);
413 return VFW_E_TYPE_NOT_ACCEPTED
;
416 info
.dwFlags
= VMR9AllocFlag_TextureSurface
;
419 case mmioFOURCC('N','V','1','2'):
420 case mmioFOURCC('U','Y','V','Y'):
421 case mmioFOURCC('Y','U','Y','2'):
422 case mmioFOURCC('Y','V','1','2'):
423 info
.Format
= filter
->bmiheader
.biCompression
;
424 info
.dwFlags
= VMR9AllocFlag_OffscreenSurface
;
428 WARN("Unhandled video compression %#x.\n", filter
->bmiheader
.biCompression
);
429 free(filter
->surfaces
);
430 return VFW_E_TYPE_NOT_ACCEPTED
;
432 if (FAILED(hr
= initialize_device(filter
, &info
, count
)))
433 free(filter
->surfaces
);
437 for (i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
439 if (IsEqualGUID(&mt
->subtype
, formats
[i
].subtype
))
441 info
.Format
= formats
[i
].format
;
443 if (formats
[i
].flags
& VMR9AllocFlag_TextureSurface
)
445 info
.dwFlags
= VMR9AllocFlag_TextureSurface
;
446 if (SUCCEEDED(hr
= initialize_device(filter
, &info
, count
)))
450 if (formats
[i
].flags
& VMR9AllocFlag_OffscreenSurface
)
452 info
.dwFlags
= VMR9AllocFlag_OffscreenSurface
;
453 if (SUCCEEDED(hr
= initialize_device(filter
, &info
, count
)))
459 free(filter
->surfaces
);
460 return VFW_E_TYPE_NOT_ACCEPTED
;
463 static void vmr_init_stream(struct strmbase_renderer
*iface
)
465 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
467 if (filter
->window
.hwnd
&& filter
->window
.AutoShow
)
468 ShowWindow(filter
->window
.hwnd
, SW_SHOW
);
471 static void vmr_start_stream(struct strmbase_renderer
*iface
)
473 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
475 IVMRImagePresenter9_StartPresenting(filter
->presenter
, filter
->cookie
);
478 static void vmr_stop_stream(struct strmbase_renderer
*iface
)
480 struct quartz_vmr
*This
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
482 TRACE("(%p)\n", This
);
484 if (This
->renderer
.filter
.state
== State_Running
)
485 IVMRImagePresenter9_StopPresenting(This
->presenter
, This
->cookie
);
488 static HRESULT
vmr_connect(struct strmbase_renderer
*iface
, const AM_MEDIA_TYPE
*mt
)
490 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
491 const BITMAPINFOHEADER
*bitmap_header
= get_bitmap_header(mt
);
492 HWND window
= filter
->window
.hwnd
;
496 filter
->bmiheader
= *bitmap_header
;
497 filter
->VideoWidth
= bitmap_header
->biWidth
;
498 filter
->VideoHeight
= bitmap_header
->biHeight
;
499 SetRect(&rect
, 0, 0, filter
->VideoWidth
, filter
->VideoHeight
);
500 filter
->window
.src
= rect
;
502 AdjustWindowRectEx(&rect
, GetWindowLongW(window
, GWL_STYLE
), FALSE
,
503 GetWindowLongW(window
, GWL_EXSTYLE
));
504 SetWindowPos(window
, NULL
, 0, 0, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
505 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
506 GetClientRect(window
, &filter
->window
.dst
);
509 || SUCCEEDED(hr
= IVMRFilterConfig9_SetRenderingMode(&filter
->IVMRFilterConfig9_iface
, VMR9Mode_Windowed
)))
510 hr
= allocate_surfaces(filter
, mt
);
515 static void vmr_disconnect(struct strmbase_renderer
*This
)
517 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&This
->filter
.IBaseFilter_iface
);
520 if (filter
->mode
&& filter
->allocator
&& filter
->presenter
)
522 for (i
= 0; i
< filter
->num_surfaces
; ++i
)
523 IDirect3DSurface9_Release(filter
->surfaces
[i
]);
524 free(filter
->surfaces
);
526 IVMRSurfaceAllocator9_TerminateDevice(filter
->allocator
, filter
->cookie
);
527 filter
->num_surfaces
= 0;
531 static void vmr_destroy(struct strmbase_renderer
*iface
)
533 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
535 video_window_cleanup(&filter
->window
);
537 /* Devil May Cry 3 releases the IVMRSurfaceAllocatorNotify9 interface from
538 * TerminateDevice(). Artificially increase the reference count so that we
539 * don't free the filter yet. */
540 InterlockedIncrement(&filter
->renderer
.filter
.refcount
);
542 if (filter
->allocator
)
544 IVMRSurfaceAllocator9_TerminateDevice(filter
->allocator
, filter
->cookie
);
545 IVMRSurfaceAllocator9_Release(filter
->allocator
);
547 if (filter
->presenter
)
548 IVMRImagePresenter9_Release(filter
->presenter
);
550 filter
->num_surfaces
= 0;
551 if (filter
->allocator_d3d9_dev
)
553 IDirect3DDevice9_Release(filter
->allocator_d3d9_dev
);
554 filter
->allocator_d3d9_dev
= NULL
;
557 FreeLibrary(filter
->hD3d9
);
558 strmbase_renderer_cleanup(&filter
->renderer
);
559 if (!filter
->IVMRSurfaceAllocatorNotify9_refcount
)
563 static HRESULT
vmr_query_interface(struct strmbase_renderer
*iface
, REFIID iid
, void **out
)
565 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
567 if (IsEqualGUID(iid
, &IID_IVideoWindow
))
568 *out
= &filter
->window
.IVideoWindow_iface
;
569 else if (IsEqualGUID(iid
, &IID_IBasicVideo
))
570 *out
= &filter
->window
.IBasicVideo_iface
;
571 else if (IsEqualGUID(iid
, &IID_IAMCertifiedOutputProtection
))
572 *out
= &filter
->IAMCertifiedOutputProtection_iface
;
573 else if (IsEqualGUID(iid
, &IID_IAMFilterMiscFlags
))
574 *out
= &filter
->IAMFilterMiscFlags_iface
;
575 else if (IsEqualGUID(iid
, &IID_IVMRAspectRatioControl9
) && is_vmr9(filter
))
576 *out
= &filter
->IVMRAspectRatioControl9_iface
;
577 else if (IsEqualGUID(iid
, &IID_IVMRFilterConfig
) && !is_vmr9(filter
))
578 *out
= &filter
->IVMRFilterConfig_iface
;
579 else if (IsEqualGUID(iid
, &IID_IVMRFilterConfig9
) && is_vmr9(filter
))
580 *out
= &filter
->IVMRFilterConfig9_iface
;
581 else if (IsEqualGUID(iid
, &IID_IVMRMixerBitmap9
) && is_vmr9(filter
))
582 *out
= &filter
->IVMRMixerBitmap9_iface
;
583 else if (IsEqualGUID(iid
, &IID_IVMRMixerControl9
) && is_vmr9(filter
) && filter
->stream_count
)
584 *out
= &filter
->IVMRMixerControl9_iface
;
585 else if (IsEqualGUID(iid
, &IID_IVMRMonitorConfig
) && !is_vmr9(filter
))
586 *out
= &filter
->IVMRMonitorConfig_iface
;
587 else if (IsEqualGUID(iid
, &IID_IVMRMonitorConfig9
)
588 && filter
->mode
!= VMR9Mode_Renderless
&& is_vmr9(filter
))
589 *out
= &filter
->IVMRMonitorConfig9_iface
;
590 else if (IsEqualGUID(iid
, &IID_IVMRSurfaceAllocatorNotify
)
591 && filter
->mode
== (VMR9Mode
)VMRMode_Renderless
&& !is_vmr9(filter
))
592 *out
= &filter
->IVMRSurfaceAllocatorNotify_iface
;
593 else if (IsEqualGUID(iid
, &IID_IVMRSurfaceAllocatorNotify9
)
594 && filter
->mode
== VMR9Mode_Renderless
&& is_vmr9(filter
))
595 *out
= &filter
->IVMRSurfaceAllocatorNotify9_iface
;
596 else if (IsEqualGUID(iid
, &IID_IVMRWindowlessControl
)
597 && filter
->mode
== (VMR9Mode
)VMRMode_Windowless
&& !is_vmr9(filter
))
598 *out
= &filter
->IVMRWindowlessControl_iface
;
599 else if (IsEqualGUID(iid
, &IID_IVMRWindowlessControl9
)
600 && filter
->mode
== VMR9Mode_Windowless
&& is_vmr9(filter
))
601 *out
= &filter
->IVMRWindowlessControl9_iface
;
603 return E_NOINTERFACE
;
605 IUnknown_AddRef((IUnknown
*)*out
);
609 static HRESULT
vmr_pin_query_interface(struct strmbase_renderer
*iface
, REFIID iid
, void **out
)
611 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
613 if (IsEqualGUID(iid
, &IID_IOverlay
))
614 *out
= &filter
->IOverlay_iface
;
616 return E_NOINTERFACE
;
618 IUnknown_AddRef((IUnknown
*)*out
);
622 static const struct strmbase_renderer_ops renderer_ops
=
624 .renderer_query_accept
= vmr_query_accept
,
625 .renderer_render
= vmr_render
,
626 .renderer_init_stream
= vmr_init_stream
,
627 .renderer_start_stream
= vmr_start_stream
,
628 .renderer_stop_stream
= vmr_stop_stream
,
629 .renderer_connect
= vmr_connect
,
630 .renderer_disconnect
= vmr_disconnect
,
631 .renderer_destroy
= vmr_destroy
,
632 .renderer_query_interface
= vmr_query_interface
,
633 .renderer_pin_query_interface
= vmr_pin_query_interface
,
636 static RECT
vmr_get_default_rect(struct video_window
*This
)
638 struct quartz_vmr
*pVMR9
= impl_from_video_window(This
);
641 SetRect(&defRect
, 0, 0, pVMR9
->VideoWidth
, pVMR9
->VideoHeight
);
646 static HRESULT
vmr_get_current_image(struct video_window
*iface
, LONG
*size
, LONG
*image
)
648 struct quartz_vmr
*filter
= impl_from_video_window(iface
);
649 IDirect3DSurface9
*rt
= NULL
, *surface
= NULL
;
650 D3DLOCKED_RECT locked_rect
;
651 IDirect3DDevice9
*device
;
652 unsigned int row_size
;
653 BITMAPINFOHEADER bih
;
658 EnterCriticalSection(&filter
->renderer
.filter
.stream_cs
);
659 device
= filter
->allocator_d3d9_dev
;
661 bih
= *get_bitmap_header(&filter
->renderer
.sink
.pin
.mt
);
662 bih
.biSizeImage
= bih
.biWidth
* bih
.biHeight
* bih
.biBitCount
/ 8;
666 *size
= sizeof(BITMAPINFOHEADER
) + bih
.biSizeImage
;
667 LeaveCriticalSection(&filter
->renderer
.filter
.stream_cs
);
671 if (FAILED(hr
= IDirect3DDevice9_GetRenderTarget(device
, 0, &rt
)))
674 if (FAILED(hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, bih
.biWidth
,
675 bih
.biHeight
, D3DFMT_X8R8G8B8
, D3DPOOL_SYSTEMMEM
, &surface
, NULL
)))
678 if (FAILED(hr
= IDirect3DDevice9_GetRenderTargetData(device
, rt
, surface
)))
681 if (FAILED(hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, NULL
, D3DLOCK_READONLY
)))
685 memcpy(image
, &bih
, min(size_left
, sizeof(BITMAPINFOHEADER
)));
686 size_left
-= sizeof(BITMAPINFOHEADER
);
688 dst
= (char *)image
+ sizeof(BITMAPINFOHEADER
);
689 row_size
= bih
.biWidth
* bih
.biBitCount
/ 8;
691 for (i
= 0; i
< bih
.biHeight
&& size_left
> 0; ++i
)
693 memcpy(dst
, (char *)locked_rect
.pBits
+ (i
* locked_rect
.Pitch
), min(row_size
, size_left
));
695 size_left
-= row_size
;
698 IDirect3DSurface9_UnlockRect(surface
);
701 if (surface
) IDirect3DSurface9_Release(surface
);
702 if (rt
) IDirect3DSurface9_Release(rt
);
703 LeaveCriticalSection(&filter
->renderer
.filter
.stream_cs
);
707 static const struct video_window_ops window_ops
=
709 .get_default_rect
= vmr_get_default_rect
,
710 .get_current_image
= vmr_get_current_image
,
713 static const IVideoWindowVtbl IVideoWindow_VTable
=
715 BaseControlWindowImpl_QueryInterface
,
716 BaseControlWindowImpl_AddRef
,
717 BaseControlWindowImpl_Release
,
718 BaseControlWindowImpl_GetTypeInfoCount
,
719 BaseControlWindowImpl_GetTypeInfo
,
720 BaseControlWindowImpl_GetIDsOfNames
,
721 BaseControlWindowImpl_Invoke
,
722 BaseControlWindowImpl_put_Caption
,
723 BaseControlWindowImpl_get_Caption
,
724 BaseControlWindowImpl_put_WindowStyle
,
725 BaseControlWindowImpl_get_WindowStyle
,
726 BaseControlWindowImpl_put_WindowStyleEx
,
727 BaseControlWindowImpl_get_WindowStyleEx
,
728 BaseControlWindowImpl_put_AutoShow
,
729 BaseControlWindowImpl_get_AutoShow
,
730 BaseControlWindowImpl_put_WindowState
,
731 BaseControlWindowImpl_get_WindowState
,
732 BaseControlWindowImpl_put_BackgroundPalette
,
733 BaseControlWindowImpl_get_BackgroundPalette
,
734 BaseControlWindowImpl_put_Visible
,
735 BaseControlWindowImpl_get_Visible
,
736 BaseControlWindowImpl_put_Left
,
737 BaseControlWindowImpl_get_Left
,
738 BaseControlWindowImpl_put_Width
,
739 BaseControlWindowImpl_get_Width
,
740 BaseControlWindowImpl_put_Top
,
741 BaseControlWindowImpl_get_Top
,
742 BaseControlWindowImpl_put_Height
,
743 BaseControlWindowImpl_get_Height
,
744 BaseControlWindowImpl_put_Owner
,
745 BaseControlWindowImpl_get_Owner
,
746 BaseControlWindowImpl_put_MessageDrain
,
747 BaseControlWindowImpl_get_MessageDrain
,
748 BaseControlWindowImpl_get_BorderColor
,
749 BaseControlWindowImpl_put_BorderColor
,
750 BaseControlWindowImpl_get_FullScreenMode
,
751 BaseControlWindowImpl_put_FullScreenMode
,
752 BaseControlWindowImpl_SetWindowForeground
,
753 BaseControlWindowImpl_NotifyOwnerMessage
,
754 BaseControlWindowImpl_SetWindowPosition
,
755 BaseControlWindowImpl_GetWindowPosition
,
756 BaseControlWindowImpl_GetMinIdealImageSize
,
757 BaseControlWindowImpl_GetMaxIdealImageSize
,
758 BaseControlWindowImpl_GetRestorePosition
,
759 BaseControlWindowImpl_HideCursor
,
760 BaseControlWindowImpl_IsCursorHidden
763 static HRESULT WINAPI
AMCertifiedOutputProtection_QueryInterface(IAMCertifiedOutputProtection
*iface
,
764 REFIID riid
, void **ppv
)
766 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
767 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
770 static ULONG WINAPI
AMCertifiedOutputProtection_AddRef(IAMCertifiedOutputProtection
*iface
)
772 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
773 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
776 static ULONG WINAPI
AMCertifiedOutputProtection_Release(IAMCertifiedOutputProtection
*iface
)
778 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
779 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
782 static HRESULT WINAPI
AMCertifiedOutputProtection_KeyExchange(IAMCertifiedOutputProtection
*iface
,
783 GUID
* pRandom
, BYTE
** VarLenCertGH
,
784 DWORD
* pdwLengthCertGH
)
786 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
788 FIXME("(%p/%p)->(%p, %p, %p) stub\n", iface
, This
, pRandom
, VarLenCertGH
, pdwLengthCertGH
);
789 return VFW_E_NO_COPP_HW
;
792 static HRESULT WINAPI
AMCertifiedOutputProtection_SessionSequenceStart(IAMCertifiedOutputProtection
*iface
,
793 AMCOPPSignature
* pSig
)
795 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
797 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pSig
);
798 return VFW_E_NO_COPP_HW
;
801 static HRESULT WINAPI
AMCertifiedOutputProtection_ProtectionCommand(IAMCertifiedOutputProtection
*iface
,
802 const AMCOPPCommand
* cmd
)
804 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
806 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, cmd
);
807 return VFW_E_NO_COPP_HW
;
810 static HRESULT WINAPI
AMCertifiedOutputProtection_ProtectionStatus(IAMCertifiedOutputProtection
*iface
,
811 const AMCOPPStatusInput
* pStatusInput
,
812 AMCOPPStatusOutput
* pStatusOutput
)
814 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
816 FIXME("(%p/%p)->(%p, %p) stub\n", iface
, This
, pStatusInput
, pStatusOutput
);
817 return VFW_E_NO_COPP_HW
;
820 static const IAMCertifiedOutputProtectionVtbl IAMCertifiedOutputProtection_Vtbl
=
822 AMCertifiedOutputProtection_QueryInterface
,
823 AMCertifiedOutputProtection_AddRef
,
824 AMCertifiedOutputProtection_Release
,
825 AMCertifiedOutputProtection_KeyExchange
,
826 AMCertifiedOutputProtection_SessionSequenceStart
,
827 AMCertifiedOutputProtection_ProtectionCommand
,
828 AMCertifiedOutputProtection_ProtectionStatus
831 static HRESULT WINAPI
AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags
*iface
, REFIID riid
, void **ppv
) {
832 struct quartz_vmr
*This
= impl_from_IAMFilterMiscFlags(iface
);
833 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
836 static ULONG WINAPI
AMFilterMiscFlags_AddRef(IAMFilterMiscFlags
*iface
) {
837 struct quartz_vmr
*This
= impl_from_IAMFilterMiscFlags(iface
);
838 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
841 static ULONG WINAPI
AMFilterMiscFlags_Release(IAMFilterMiscFlags
*iface
) {
842 struct quartz_vmr
*This
= impl_from_IAMFilterMiscFlags(iface
);
843 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
846 static ULONG WINAPI
AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags
*iface
) {
847 return AM_FILTER_MISC_FLAGS_IS_RENDERER
;
850 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl
= {
851 AMFilterMiscFlags_QueryInterface
,
852 AMFilterMiscFlags_AddRef
,
853 AMFilterMiscFlags_Release
,
854 AMFilterMiscFlags_GetMiscFlags
857 static HRESULT WINAPI
VMR7FilterConfig_QueryInterface(IVMRFilterConfig
*iface
, REFIID riid
,
860 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
861 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
864 static ULONG WINAPI
VMR7FilterConfig_AddRef(IVMRFilterConfig
*iface
)
866 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
867 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
870 static ULONG WINAPI
VMR7FilterConfig_Release(IVMRFilterConfig
*iface
)
872 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
873 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
876 static HRESULT WINAPI
VMR7FilterConfig_SetImageCompositor(IVMRFilterConfig
*iface
,
877 IVMRImageCompositor
*compositor
)
879 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
881 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, compositor
);
885 static HRESULT WINAPI
VMR7FilterConfig_SetNumberOfStreams(IVMRFilterConfig
*iface
, DWORD max
)
887 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
889 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, max
);
893 static HRESULT WINAPI
VMR7FilterConfig_GetNumberOfStreams(IVMRFilterConfig
*iface
, DWORD
*max
)
895 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
897 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, max
);
901 static HRESULT WINAPI
VMR7FilterConfig_SetRenderingPrefs(IVMRFilterConfig
*iface
, DWORD renderflags
)
903 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
905 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, renderflags
);
909 static HRESULT WINAPI
VMR7FilterConfig_GetRenderingPrefs(IVMRFilterConfig
*iface
, DWORD
*renderflags
)
911 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
913 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, renderflags
);
917 static HRESULT WINAPI
VMR7FilterConfig_SetRenderingMode(IVMRFilterConfig
*iface
, DWORD mode
)
919 struct quartz_vmr
*filter
= impl_from_IVMRFilterConfig(iface
);
921 TRACE("iface %p, mode %#x.\n", iface
, mode
);
923 return IVMRFilterConfig9_SetRenderingMode(&filter
->IVMRFilterConfig9_iface
, mode
);
926 static HRESULT WINAPI
VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig
*iface
, DWORD
*mode
)
928 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
930 TRACE("(%p/%p)->(%p)\n", iface
, This
, mode
);
931 if (!mode
) return E_POINTER
;
936 *mode
= VMRMode_Windowed
;
941 static const IVMRFilterConfigVtbl VMR7_FilterConfig_Vtbl
=
943 VMR7FilterConfig_QueryInterface
,
944 VMR7FilterConfig_AddRef
,
945 VMR7FilterConfig_Release
,
946 VMR7FilterConfig_SetImageCompositor
,
947 VMR7FilterConfig_SetNumberOfStreams
,
948 VMR7FilterConfig_GetNumberOfStreams
,
949 VMR7FilterConfig_SetRenderingPrefs
,
950 VMR7FilterConfig_GetRenderingPrefs
,
951 VMR7FilterConfig_SetRenderingMode
,
952 VMR7FilterConfig_GetRenderingMode
955 struct get_available_monitors_args
957 VMRMONITORINFO
*info7
;
958 VMR9MonitorInfo
*info9
;
963 static BOOL CALLBACK
get_available_monitors_proc(HMONITOR hmon
, HDC hdc
, LPRECT lprc
, LPARAM lparam
)
965 struct get_available_monitors_args
*args
= (struct get_available_monitors_args
*)lparam
;
968 if (args
->info7
|| args
->info9
)
971 if (!args
->arraysize
)
974 mi
.cbSize
= sizeof(mi
);
975 if (!GetMonitorInfoW(hmon
, (MONITORINFO
*)&mi
))
978 /* fill VMRMONITORINFO struct */
981 VMRMONITORINFO
*info
= args
->info7
++;
982 memset(info
, 0, sizeof(*info
));
984 if (args
->numdev
> 0)
986 info
->guid
.pGUID
= &info
->guid
.GUID
;
987 info
->guid
.GUID
.Data4
[7] = args
->numdev
;
990 info
->guid
.pGUID
= NULL
;
992 info
->rcMonitor
= mi
.rcMonitor
;
994 info
->dwFlags
= mi
.dwFlags
;
996 lstrcpynW(info
->szDevice
, mi
.szDevice
, ARRAY_SIZE(info
->szDevice
));
998 /* FIXME: how to get these values? */
999 info
->szDescription
[0] = 0;
1002 /* fill VMR9MonitorInfo struct */
1005 VMR9MonitorInfo
*info
= args
->info9
++;
1006 memset(info
, 0, sizeof(*info
));
1008 info
->uDevID
= 0; /* FIXME */
1009 info
->rcMonitor
= mi
.rcMonitor
;
1011 info
->dwFlags
= mi
.dwFlags
;
1013 lstrcpynW(info
->szDevice
, mi
.szDevice
, ARRAY_SIZE(info
->szDevice
));
1015 /* FIXME: how to get these values? */
1016 info
->szDescription
[0] = 0;
1017 info
->dwVendorId
= 0;
1018 info
->dwDeviceId
= 0;
1019 info
->dwSubSysId
= 0;
1020 info
->dwRevision
= 0;
1030 static HRESULT WINAPI
VMR7MonitorConfig_QueryInterface(IVMRMonitorConfig
*iface
, REFIID riid
,
1033 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1034 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1037 static ULONG WINAPI
VMR7MonitorConfig_AddRef(IVMRMonitorConfig
*iface
)
1039 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1040 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1043 static ULONG WINAPI
VMR7MonitorConfig_Release(IVMRMonitorConfig
*iface
)
1045 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1046 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1049 static HRESULT WINAPI
VMR7MonitorConfig_SetMonitor(IVMRMonitorConfig
*iface
, const VMRGUID
*pGUID
)
1051 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1053 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1061 static HRESULT WINAPI
VMR7MonitorConfig_GetMonitor(IVMRMonitorConfig
*iface
, VMRGUID
*pGUID
)
1063 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1065 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1070 pGUID
->pGUID
= NULL
; /* default DirectDraw device */
1074 static HRESULT WINAPI
VMR7MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig
*iface
,
1075 const VMRGUID
*pGUID
)
1077 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1079 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1087 static HRESULT WINAPI
VMR7MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig
*iface
, VMRGUID
*pGUID
)
1089 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1091 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1096 pGUID
->pGUID
= NULL
; /* default DirectDraw device */
1100 static HRESULT WINAPI
VMR7MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig
*iface
,
1101 VMRMONITORINFO
*info
, DWORD arraysize
,
1104 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1105 struct get_available_monitors_args args
;
1107 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface
, This
, info
, arraysize
, numdev
);
1112 if (info
&& arraysize
== 0)
1113 return E_INVALIDARG
;
1117 args
.arraysize
= arraysize
;
1119 EnumDisplayMonitors(NULL
, NULL
, get_available_monitors_proc
, (LPARAM
)&args
);
1121 *numdev
= args
.numdev
;
1125 static const IVMRMonitorConfigVtbl VMR7_MonitorConfig_Vtbl
=
1127 VMR7MonitorConfig_QueryInterface
,
1128 VMR7MonitorConfig_AddRef
,
1129 VMR7MonitorConfig_Release
,
1130 VMR7MonitorConfig_SetMonitor
,
1131 VMR7MonitorConfig_GetMonitor
,
1132 VMR7MonitorConfig_SetDefaultMonitor
,
1133 VMR7MonitorConfig_GetDefaultMonitor
,
1134 VMR7MonitorConfig_GetAvailableMonitors
1137 static HRESULT WINAPI
VMR9MonitorConfig_QueryInterface(IVMRMonitorConfig9
*iface
, REFIID riid
,
1140 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1141 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1144 static ULONG WINAPI
VMR9MonitorConfig_AddRef(IVMRMonitorConfig9
*iface
)
1146 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1147 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1150 static ULONG WINAPI
VMR9MonitorConfig_Release(IVMRMonitorConfig9
*iface
)
1152 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1153 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1156 static HRESULT WINAPI
VMR9MonitorConfig_SetMonitor(IVMRMonitorConfig9
*iface
, UINT uDev
)
1158 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1160 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, uDev
);
1165 static HRESULT WINAPI
VMR9MonitorConfig_GetMonitor(IVMRMonitorConfig9
*iface
, UINT
*uDev
)
1167 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1169 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, uDev
);
1178 static HRESULT WINAPI
VMR9MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig9
*iface
, UINT uDev
)
1180 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1182 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, uDev
);
1187 static HRESULT WINAPI
VMR9MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig9
*iface
, UINT
*uDev
)
1189 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1191 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, uDev
);
1200 static HRESULT WINAPI
VMR9MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig9
*iface
,
1201 VMR9MonitorInfo
*info
, DWORD arraysize
,
1204 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1205 struct get_available_monitors_args args
;
1207 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface
, This
, info
, arraysize
, numdev
);
1212 if (info
&& arraysize
== 0)
1213 return E_INVALIDARG
;
1217 args
.arraysize
= arraysize
;
1219 EnumDisplayMonitors(NULL
, NULL
, get_available_monitors_proc
, (LPARAM
)&args
);
1221 *numdev
= args
.numdev
;
1225 static const IVMRMonitorConfig9Vtbl VMR9_MonitorConfig_Vtbl
=
1227 VMR9MonitorConfig_QueryInterface
,
1228 VMR9MonitorConfig_AddRef
,
1229 VMR9MonitorConfig_Release
,
1230 VMR9MonitorConfig_SetMonitor
,
1231 VMR9MonitorConfig_GetMonitor
,
1232 VMR9MonitorConfig_SetDefaultMonitor
,
1233 VMR9MonitorConfig_GetDefaultMonitor
,
1234 VMR9MonitorConfig_GetAvailableMonitors
1237 static HRESULT WINAPI
VMR9FilterConfig_QueryInterface(IVMRFilterConfig9
*iface
, REFIID riid
, LPVOID
* ppv
)
1239 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1240 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1243 static ULONG WINAPI
VMR9FilterConfig_AddRef(IVMRFilterConfig9
*iface
)
1245 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1246 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1249 static ULONG WINAPI
VMR9FilterConfig_Release(IVMRFilterConfig9
*iface
)
1251 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1252 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1255 static HRESULT WINAPI
VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9
*iface
, IVMRImageCompositor9
*compositor
)
1257 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1259 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, compositor
);
1263 static HRESULT WINAPI
VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9
*iface
, DWORD count
)
1265 struct quartz_vmr
*filter
= impl_from_IVMRFilterConfig9(iface
);
1267 FIXME("iface %p, count %u, stub!\n", iface
, count
);
1271 WARN("Application requested zero streams; returning E_INVALIDARG.\n");
1272 return E_INVALIDARG
;
1275 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1277 if (filter
->stream_count
)
1279 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1280 WARN("Stream count is already set; returning VFW_E_WRONG_STATE.\n");
1281 return VFW_E_WRONG_STATE
;
1284 filter
->stream_count
= count
;
1286 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1290 static HRESULT WINAPI
VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9
*iface
, DWORD
*count
)
1292 struct quartz_vmr
*filter
= impl_from_IVMRFilterConfig9(iface
);
1294 TRACE("filter %p, count %p.\n", filter
, count
);
1296 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1298 if (!filter
->stream_count
)
1300 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1301 return VFW_E_VMR_NOT_IN_MIXER_MODE
;
1304 *count
= filter
->stream_count
;
1306 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1310 static HRESULT WINAPI
VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9
*iface
, DWORD renderflags
)
1312 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1314 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, renderflags
);
1318 static HRESULT WINAPI
VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9
*iface
, DWORD
*renderflags
)
1320 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1322 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, renderflags
);
1326 static HRESULT WINAPI
VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9
*iface
, DWORD mode
)
1329 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1331 TRACE("(%p/%p)->(%u)\n", iface
, This
, mode
);
1333 EnterCriticalSection(&This
->renderer
.filter
.filter_cs
);
1336 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1337 return VFW_E_WRONG_STATE
;
1340 if (This
->allocator
)
1341 IVMRSurfaceAllocator9_Release(This
->allocator
);
1342 if (This
->presenter
)
1343 IVMRImagePresenter9_Release(This
->presenter
);
1345 This
->allocator
= NULL
;
1346 This
->presenter
= NULL
;
1350 case VMR9Mode_Windowed
:
1351 case VMR9Mode_Windowless
:
1354 if (FAILED(hr
= VMR9DefaultAllocatorPresenterImpl_create(This
, (void **)&This
->presenter
)))
1356 ERR("Failed to create default presenter, hr %#x.\n", hr
);
1360 if (FAILED(hr
= IVMRImagePresenter9_QueryInterface(This
->presenter
,
1361 &IID_IVMRSurfaceAllocator9
, (void **)&This
->allocator
)))
1363 ERR("Failed to query for IVMRSurfaceAllocator9, hr %#x.\n", hr
);
1364 IVMRImagePresenter9_Release(This
->presenter
);
1365 This
->allocator
= NULL
;
1366 This
->presenter
= NULL
;
1370 hr
= IVMRSurfaceAllocator9_AdviseNotify(This
->allocator
, &This
->IVMRSurfaceAllocatorNotify9_iface
);
1372 case VMR9Mode_Renderless
:
1375 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1376 return E_INVALIDARG
;
1379 if (mode
!= VMR9Mode_Windowed
)
1380 video_window_cleanup(&This
->window
);
1383 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1387 static HRESULT WINAPI
VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9
*iface
, DWORD
*mode
)
1389 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1391 TRACE("(%p/%p)->(%p)\n", iface
, This
, mode
);
1398 *mode
= VMR9Mode_Windowed
;
1403 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl
=
1405 VMR9FilterConfig_QueryInterface
,
1406 VMR9FilterConfig_AddRef
,
1407 VMR9FilterConfig_Release
,
1408 VMR9FilterConfig_SetImageCompositor
,
1409 VMR9FilterConfig_SetNumberOfStreams
,
1410 VMR9FilterConfig_GetNumberOfStreams
,
1411 VMR9FilterConfig_SetRenderingPrefs
,
1412 VMR9FilterConfig_GetRenderingPrefs
,
1413 VMR9FilterConfig_SetRenderingMode
,
1414 VMR9FilterConfig_GetRenderingMode
1417 static HRESULT WINAPI
VMR7WindowlessControl_QueryInterface(IVMRWindowlessControl
*iface
, REFIID riid
,
1420 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1421 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1424 static ULONG WINAPI
VMR7WindowlessControl_AddRef(IVMRWindowlessControl
*iface
)
1426 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1427 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1430 static ULONG WINAPI
VMR7WindowlessControl_Release(IVMRWindowlessControl
*iface
)
1432 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1433 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1436 static HRESULT WINAPI
VMR7WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl
*iface
,
1437 LONG
*width
, LONG
*height
, LONG
*aspect_width
, LONG
*aspect_height
)
1439 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl(iface
);
1441 TRACE("filter %p, width %p, height %p, aspect_width %p, aspect_height %p.\n",
1442 filter
, width
, height
, aspect_width
, aspect_height
);
1444 if (!width
|| !height
)
1447 *width
= filter
->bmiheader
.biWidth
;
1448 *height
= filter
->bmiheader
.biHeight
;
1450 *aspect_width
= filter
->bmiheader
.biWidth
;
1452 *aspect_height
= filter
->bmiheader
.biHeight
;
1457 static HRESULT WINAPI
VMR7WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl
*iface
,
1458 LONG
*width
, LONG
*height
)
1460 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1462 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1466 static HRESULT WINAPI
VMR7WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl
*iface
,
1467 LONG
*width
, LONG
*height
)
1469 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1471 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1475 static HRESULT WINAPI
VMR7WindowlessControl_SetVideoPosition(IVMRWindowlessControl
*iface
,
1476 const RECT
*source
, const RECT
*dest
)
1478 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1480 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, source
, dest
);
1482 EnterCriticalSection(&This
->renderer
.filter
.filter_cs
);
1485 This
->window
.src
= *source
;
1487 This
->window
.dst
= *dest
;
1489 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1494 static HRESULT WINAPI
VMR7WindowlessControl_GetVideoPosition(IVMRWindowlessControl
*iface
,
1495 RECT
*source
, RECT
*dest
)
1497 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1500 *source
= This
->window
.src
;
1503 *dest
= This
->window
.dst
;
1505 FIXME("(%p/%p)->(%p/%p) stub\n", iface
, This
, source
, dest
);
1509 static HRESULT WINAPI
VMR7WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl
*iface
,
1512 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1514 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1518 static HRESULT WINAPI
VMR7WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl
*iface
,
1521 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1523 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1527 static HRESULT WINAPI
VMR7WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl
*iface
, HWND window
)
1529 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl(iface
);
1531 TRACE("iface %p, window %p.\n", iface
, window
);
1533 return IVMRWindowlessControl9_SetVideoClippingWindow(&filter
->IVMRWindowlessControl9_iface
, window
);
1536 static HRESULT WINAPI
VMR7WindowlessControl_RepaintVideo(IVMRWindowlessControl
*iface
,
1539 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1541 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1545 static HRESULT WINAPI
VMR7WindowlessControl_DisplayModeChanged(IVMRWindowlessControl
*iface
)
1547 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1549 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1553 static HRESULT WINAPI
VMR7WindowlessControl_GetCurrentImage(IVMRWindowlessControl
*iface
,
1556 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1558 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1562 static HRESULT WINAPI
VMR7WindowlessControl_SetBorderColor(IVMRWindowlessControl
*iface
,
1565 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1567 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1571 static HRESULT WINAPI
VMR7WindowlessControl_GetBorderColor(IVMRWindowlessControl
*iface
,
1574 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1576 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1580 static HRESULT WINAPI
VMR7WindowlessControl_SetColorKey(IVMRWindowlessControl
*iface
, COLORREF color
)
1582 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1584 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1588 static HRESULT WINAPI
VMR7WindowlessControl_GetColorKey(IVMRWindowlessControl
*iface
, COLORREF
*color
)
1590 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1592 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1596 static const IVMRWindowlessControlVtbl VMR7_WindowlessControl_Vtbl
=
1598 VMR7WindowlessControl_QueryInterface
,
1599 VMR7WindowlessControl_AddRef
,
1600 VMR7WindowlessControl_Release
,
1601 VMR7WindowlessControl_GetNativeVideoSize
,
1602 VMR7WindowlessControl_GetMinIdealVideoSize
,
1603 VMR7WindowlessControl_GetMaxIdealVideoSize
,
1604 VMR7WindowlessControl_SetVideoPosition
,
1605 VMR7WindowlessControl_GetVideoPosition
,
1606 VMR7WindowlessControl_GetAspectRatioMode
,
1607 VMR7WindowlessControl_SetAspectRatioMode
,
1608 VMR7WindowlessControl_SetVideoClippingWindow
,
1609 VMR7WindowlessControl_RepaintVideo
,
1610 VMR7WindowlessControl_DisplayModeChanged
,
1611 VMR7WindowlessControl_GetCurrentImage
,
1612 VMR7WindowlessControl_SetBorderColor
,
1613 VMR7WindowlessControl_GetBorderColor
,
1614 VMR7WindowlessControl_SetColorKey
,
1615 VMR7WindowlessControl_GetColorKey
1618 static HRESULT WINAPI
VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9
*iface
, REFIID riid
, LPVOID
* ppv
)
1620 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1621 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1624 static ULONG WINAPI
VMR9WindowlessControl_AddRef(IVMRWindowlessControl9
*iface
)
1626 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1627 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1630 static ULONG WINAPI
VMR9WindowlessControl_Release(IVMRWindowlessControl9
*iface
)
1632 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1633 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1636 static HRESULT WINAPI
VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9
*iface
,
1637 LONG
*width
, LONG
*height
, LONG
*aspect_width
, LONG
*aspect_height
)
1639 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1641 TRACE("filter %p, width %p, height %p, aspect_width %p, aspect_height %p.\n",
1642 filter
, width
, height
, aspect_width
, aspect_height
);
1644 if (!width
|| !height
)
1647 *width
= filter
->bmiheader
.biWidth
;
1648 *height
= filter
->bmiheader
.biHeight
;
1650 *aspect_width
= filter
->bmiheader
.biWidth
;
1652 *aspect_height
= filter
->bmiheader
.biHeight
;
1657 static HRESULT WINAPI
VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9
*iface
, LONG
*width
, LONG
*height
)
1659 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1661 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1665 static HRESULT WINAPI
VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9
*iface
, LONG
*width
, LONG
*height
)
1667 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1669 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1673 static HRESULT WINAPI
VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9
*iface
,
1674 const RECT
*src
, const RECT
*dst
)
1676 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1678 TRACE("filter %p, src %s, dst %s.\n", filter
, wine_dbgstr_rect(src
), wine_dbgstr_rect(dst
));
1680 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1683 filter
->window
.src
= *src
;
1685 filter
->window
.dst
= *dst
;
1687 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1692 static HRESULT WINAPI
VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9
*iface
, RECT
*src
, RECT
*dst
)
1694 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1696 TRACE("filter %p, src %p, dst %p.\n", filter
, src
, dst
);
1699 *src
= filter
->window
.src
;
1702 *dst
= filter
->window
.dst
;
1707 static HRESULT WINAPI
VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9
*iface
, DWORD
*mode
)
1709 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1711 TRACE("filter %p, mode %p.\n", filter
, mode
);
1713 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1714 *mode
= filter
->aspect_mode
;
1715 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1719 static HRESULT WINAPI
VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9
*iface
, DWORD mode
)
1721 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1723 TRACE("filter %p, mode %u.\n", filter
, mode
);
1725 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1726 filter
->aspect_mode
= mode
;
1727 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1731 static HRESULT WINAPI
VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9
*iface
, HWND window
)
1733 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1736 TRACE("filter %p, window %p.\n", filter
, window
);
1738 if (!IsWindow(window
))
1740 WARN("Invalid window %p, returning E_INVALIDARG.\n", window
);
1741 return E_INVALIDARG
;
1744 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1746 if (filter
->renderer
.sink
.pin
.peer
)
1748 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1749 WARN("Attempt to set the clipping window while connected; returning VFW_E_WRONG_STATE.\n");
1750 return VFW_E_WRONG_STATE
;
1753 filter
->clipping_window
= window
;
1755 hr
= IVMRFilterConfig9_SetNumberOfStreams(&filter
->IVMRFilterConfig9_iface
, 4);
1757 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1761 static HRESULT WINAPI
VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9
*iface
, HWND hwnd
, HDC hdc
)
1763 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1766 FIXME("(%p/%p)->(...) semi-stub\n", iface
, This
);
1768 EnterCriticalSection(&This
->renderer
.filter
.filter_cs
);
1769 if (hwnd
!= This
->clipping_window
)
1771 ERR("Not handling changing windows yet!!!\n");
1772 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1776 if (!This
->allocator_d3d9_dev
)
1778 ERR("No d3d9 device!\n");
1779 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1780 return VFW_E_WRONG_STATE
;
1783 /* Windowless extension */
1784 hr
= IDirect3DDevice9_Present(This
->allocator_d3d9_dev
, NULL
, NULL
, NULL
, NULL
);
1785 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1790 static HRESULT WINAPI
VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9
*iface
)
1792 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1794 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1798 static HRESULT WINAPI
VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9
*iface
, BYTE
**dib
)
1800 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1802 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1806 static HRESULT WINAPI
VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9
*iface
, COLORREF color
)
1808 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1810 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1814 static HRESULT WINAPI
VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9
*iface
, COLORREF
*color
)
1816 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1818 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1822 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl
=
1824 VMR9WindowlessControl_QueryInterface
,
1825 VMR9WindowlessControl_AddRef
,
1826 VMR9WindowlessControl_Release
,
1827 VMR9WindowlessControl_GetNativeVideoSize
,
1828 VMR9WindowlessControl_GetMinIdealVideoSize
,
1829 VMR9WindowlessControl_GetMaxIdealVideoSize
,
1830 VMR9WindowlessControl_SetVideoPosition
,
1831 VMR9WindowlessControl_GetVideoPosition
,
1832 VMR9WindowlessControl_GetAspectRatioMode
,
1833 VMR9WindowlessControl_SetAspectRatioMode
,
1834 VMR9WindowlessControl_SetVideoClippingWindow
,
1835 VMR9WindowlessControl_RepaintVideo
,
1836 VMR9WindowlessControl_DisplayModeChanged
,
1837 VMR9WindowlessControl_GetCurrentImage
,
1838 VMR9WindowlessControl_SetBorderColor
,
1839 VMR9WindowlessControl_GetBorderColor
1842 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify
*iface
,
1843 REFIID riid
, LPVOID
* ppv
)
1845 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1846 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1849 static ULONG WINAPI
VMR7SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify
*iface
)
1851 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1852 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1855 static ULONG WINAPI
VMR7SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify
*iface
)
1857 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1858 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1861 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify
*iface
,
1863 IVMRSurfaceAllocator
*alloc
)
1865 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1867 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1871 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_SetDDrawDevice(IVMRSurfaceAllocatorNotify
*iface
,
1872 IDirectDraw7
*device
, HMONITOR monitor
)
1874 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1876 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1880 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_ChangeDDrawDevice(IVMRSurfaceAllocatorNotify
*iface
,
1881 IDirectDraw7
*device
, HMONITOR monitor
)
1883 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1885 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1889 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces(IVMRSurfaceAllocatorNotify
*iface
)
1891 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1893 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1897 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify
*iface
, LONG code
,
1898 LONG_PTR param1
, LONG_PTR param2
)
1900 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1902 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1906 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_SetBorderColor(IVMRSurfaceAllocatorNotify
*iface
,
1909 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1911 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1915 static const IVMRSurfaceAllocatorNotifyVtbl VMR7_SurfaceAllocatorNotify_Vtbl
=
1917 VMR7SurfaceAllocatorNotify_QueryInterface
,
1918 VMR7SurfaceAllocatorNotify_AddRef
,
1919 VMR7SurfaceAllocatorNotify_Release
,
1920 VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator
,
1921 VMR7SurfaceAllocatorNotify_SetDDrawDevice
,
1922 VMR7SurfaceAllocatorNotify_ChangeDDrawDevice
,
1923 VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces
,
1924 VMR7SurfaceAllocatorNotify_NotifyEvent
,
1925 VMR7SurfaceAllocatorNotify_SetBorderColor
1928 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9
*iface
, REFIID riid
, LPVOID
* ppv
)
1930 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1931 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1934 static ULONG WINAPI
VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9
*iface
)
1936 struct quartz_vmr
*filter
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1937 ULONG refcount
= InterlockedIncrement(&filter
->IVMRSurfaceAllocatorNotify9_refcount
);
1939 TRACE("%p increasing refcount to %u.\n", iface
, refcount
);
1944 static ULONG WINAPI
VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9
*iface
)
1946 struct quartz_vmr
*filter
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1947 ULONG refcount
= InterlockedDecrement(&filter
->IVMRSurfaceAllocatorNotify9_refcount
);
1949 TRACE("%p decreasing refcount to %u.\n", iface
, refcount
);
1951 if (!refcount
&& !filter
->renderer
.filter
.refcount
)
1957 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(
1958 IVMRSurfaceAllocatorNotify9
*iface
, DWORD_PTR cookie
, IVMRSurfaceAllocator9
*allocator
)
1960 struct quartz_vmr
*filter
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1961 IVMRImagePresenter9
*presenter
;
1963 TRACE("filter %p, cookie %#Ix, allocator %p.\n", filter
, cookie
, allocator
);
1965 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1967 filter
->cookie
= cookie
;
1969 if (filter
->renderer
.sink
.pin
.peer
)
1971 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1972 WARN("Attempt to set allocator while connected; returning VFW_E_WRONG_STATE.\n");
1973 return VFW_E_WRONG_STATE
;
1976 if (FAILED(IVMRSurfaceAllocator9_QueryInterface(allocator
, &IID_IVMRImagePresenter9
, (void **)&presenter
)))
1978 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1979 return E_NOINTERFACE
;
1982 if (filter
->allocator
)
1984 IVMRImagePresenter9_Release(filter
->presenter
);
1985 IVMRSurfaceAllocator9_Release(filter
->allocator
);
1987 filter
->allocator
= allocator
;
1988 filter
->presenter
= presenter
;
1989 IVMRSurfaceAllocator9_AddRef(allocator
);
1991 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1995 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9
*iface
,
1996 IDirect3DDevice9
*device
, HMONITOR monitor
)
1998 struct quartz_vmr
*filter
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
2000 TRACE("filter %p, device %p, monitor %p.\n", filter
, device
, monitor
);
2002 if (filter
->allocator_d3d9_dev
)
2003 IDirect3DDevice9_Release(filter
->allocator_d3d9_dev
);
2004 filter
->allocator_d3d9_dev
= device
;
2005 IDirect3DDevice9_AddRef(device
);
2010 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9
*iface
, IDirect3DDevice9
*device
, HMONITOR monitor
)
2012 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
2014 FIXME("(%p/%p)->(...) semi-stub\n", iface
, This
);
2015 if (This
->allocator_d3d9_dev
)
2016 IDirect3DDevice9_Release(This
->allocator_d3d9_dev
);
2017 This
->allocator_d3d9_dev
= device
;
2018 IDirect3DDevice9_AddRef(This
->allocator_d3d9_dev
);
2023 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9
*iface
, VMR9AllocationInfo
*allocinfo
, DWORD
*numbuffers
, IDirect3DSurface9
**surface
)
2025 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
2029 TRACE("filter %p, allocinfo %p, numbuffers %p, surface %p.\n", This
, numbuffers
, allocinfo
, surface
);
2031 if (!allocinfo
|| !numbuffers
|| !surface
)
2034 TRACE("Flags %#x, size %ux%u, format %u (%#x), pool %u, minimum buffers %u.\n",
2035 allocinfo
->dwFlags
, allocinfo
->dwWidth
, allocinfo
->dwHeight
,
2036 allocinfo
->Format
, allocinfo
->Format
, allocinfo
->Pool
, allocinfo
->MinBuffers
);
2038 if ((allocinfo
->dwFlags
& VMR9AllocFlag_TextureSurface
)
2039 && (allocinfo
->dwFlags
& VMR9AllocFlag_OffscreenSurface
))
2041 WARN("Invalid flags specified; returning E_INVALIDARG.\n");
2042 return E_INVALIDARG
;
2045 if (!allocinfo
->Format
)
2047 IDirect3DSurface9
*backbuffer
;
2048 D3DSURFACE_DESC desc
;
2050 IDirect3DDevice9_GetBackBuffer(This
->allocator_d3d9_dev
, 0, 0,
2051 D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
2052 IDirect3DSurface9_GetDesc(backbuffer
, &desc
);
2053 IDirect3DSurface9_Release(backbuffer
);
2054 allocinfo
->Format
= desc
.Format
;
2057 if (!*numbuffers
|| *numbuffers
< allocinfo
->MinBuffers
)
2059 WARN("%u surfaces requested (minimum %u); returning E_INVALIDARG.\n",
2060 *numbuffers
, allocinfo
->MinBuffers
);
2061 return E_INVALIDARG
;
2064 if (!This
->allocator_d3d9_dev
)
2066 WARN("No Direct3D device; returning VFW_E_WRONG_STATE.\n");
2067 return VFW_E_WRONG_STATE
;
2070 if (allocinfo
->dwFlags
== VMR9AllocFlag_OffscreenSurface
)
2072 for (i
= 0; i
< *numbuffers
; ++i
)
2074 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(This
->allocator_d3d9_dev
, allocinfo
->dwWidth
, allocinfo
->dwHeight
,
2075 allocinfo
->Format
, allocinfo
->Pool
, &surface
[i
], NULL
);
2080 else if (allocinfo
->dwFlags
== VMR9AllocFlag_TextureSurface
)
2082 for (i
= 0; i
< *numbuffers
; ++i
)
2084 IDirect3DTexture9
*texture
;
2086 hr
= IDirect3DDevice9_CreateTexture(This
->allocator_d3d9_dev
, allocinfo
->dwWidth
, allocinfo
->dwHeight
, 1, D3DUSAGE_DYNAMIC
,
2087 allocinfo
->Format
, allocinfo
->Pool
, &texture
, NULL
);
2090 IDirect3DTexture9_GetSurfaceLevel(texture
, 0, &surface
[i
]);
2091 IDirect3DTexture9_Release(texture
);
2094 else if (allocinfo
->dwFlags
== VMR9AllocFlag_3DRenderTarget
)
2096 for (i
= 0; i
< *numbuffers
; ++i
)
2098 if (FAILED(hr
= IDirect3DDevice9_CreateRenderTarget(This
->allocator_d3d9_dev
,
2099 allocinfo
->dwWidth
, allocinfo
->dwHeight
, allocinfo
->Format
,
2100 D3DMULTISAMPLE_NONE
, 0, FALSE
, &surface
[i
], NULL
)))
2106 FIXME("Unhandled flags %#x.\n", allocinfo
->dwFlags
);
2111 WARN("%u/%u surfaces allocated, hr %#x.\n", i
, *numbuffers
, hr
);
2113 if (i
>= allocinfo
->MinBuffers
)
2120 for ( ; i
> 0; --i
) IDirect3DSurface9_Release(surface
[i
- 1]);
2126 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9
*iface
, LONG code
, LONG_PTR param1
, LONG_PTR param2
)
2128 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
2130 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
2134 static const IVMRSurfaceAllocatorNotify9Vtbl VMR9_SurfaceAllocatorNotify_Vtbl
=
2136 VMR9SurfaceAllocatorNotify_QueryInterface
,
2137 VMR9SurfaceAllocatorNotify_AddRef
,
2138 VMR9SurfaceAllocatorNotify_Release
,
2139 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator
,
2140 VMR9SurfaceAllocatorNotify_SetD3DDevice
,
2141 VMR9SurfaceAllocatorNotify_ChangeD3DDevice
,
2142 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper
,
2143 VMR9SurfaceAllocatorNotify_NotifyEvent
2146 static inline struct quartz_vmr
*impl_from_IVMRMixerControl9(IVMRMixerControl9
*iface
)
2148 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRMixerControl9_iface
);
2151 static HRESULT WINAPI
mixer_control9_QueryInterface(IVMRMixerControl9
*iface
, REFIID iid
, void **out
)
2153 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2154 return IUnknown_QueryInterface(filter
->renderer
.filter
.outer_unk
, iid
, out
);
2157 static ULONG WINAPI
mixer_control9_AddRef(IVMRMixerControl9
*iface
)
2159 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2160 return IUnknown_AddRef(filter
->renderer
.filter
.outer_unk
);
2163 static ULONG WINAPI
mixer_control9_Release(IVMRMixerControl9
*iface
)
2165 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2166 return IUnknown_Release(filter
->renderer
.filter
.outer_unk
);
2169 static HRESULT WINAPI
mixer_control9_SetAlpha(IVMRMixerControl9
*iface
, DWORD stream
, float alpha
)
2171 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2173 FIXME("filter %p, stream %u, alpha %.8e, stub!\n", filter
, stream
, alpha
);
2178 static HRESULT WINAPI
mixer_control9_GetAlpha(IVMRMixerControl9
*iface
, DWORD stream
, float *alpha
)
2180 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2182 FIXME("filter %p, stream %u, alpha %p, stub!\n", filter
, stream
, alpha
);
2187 static HRESULT WINAPI
mixer_control9_SetZOrder(IVMRMixerControl9
*iface
, DWORD stream
, DWORD z
)
2189 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2191 FIXME("filter %p, stream %u, z %u, stub!\n", filter
, stream
, z
);
2196 static HRESULT WINAPI
mixer_control9_GetZOrder(IVMRMixerControl9
*iface
, DWORD stream
, DWORD
*z
)
2198 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2200 FIXME("filter %p, stream %u, z %p, stub!\n", filter
, stream
, z
);
2205 static HRESULT WINAPI
mixer_control9_SetOutputRect(IVMRMixerControl9
*iface
,
2206 DWORD stream
, const VMR9NormalizedRect
*rect
)
2208 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2210 FIXME("filter %p, stream %u, rect %s, stub!\n", filter
, stream
, debugstr_normalized_rect(rect
));
2215 static HRESULT WINAPI
mixer_control9_GetOutputRect(IVMRMixerControl9
*iface
,
2216 DWORD stream
, VMR9NormalizedRect
*rect
)
2218 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2220 FIXME("filter %p, stream %u, rect %p, stub!\n", filter
, stream
, rect
);
2225 static HRESULT WINAPI
mixer_control9_SetBackgroundClr(IVMRMixerControl9
*iface
, COLORREF color
)
2227 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2229 FIXME("filter %p, color #%06x, stub!\n", filter
, color
);
2234 static HRESULT WINAPI
mixer_control9_GetBackgroundClr(IVMRMixerControl9
*iface
, COLORREF
*color
)
2236 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2238 FIXME("filter %p, color %p, stub!\n", filter
, color
);
2243 static HRESULT WINAPI
mixer_control9_SetMixingPrefs(IVMRMixerControl9
*iface
, DWORD flags
)
2245 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2247 FIXME("filter %p, flags %#x, stub!\n", filter
, flags
);
2249 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2250 filter
->mixing_prefs
= flags
;
2251 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2255 static HRESULT WINAPI
mixer_control9_GetMixingPrefs(IVMRMixerControl9
*iface
, DWORD
*flags
)
2257 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2259 FIXME("filter %p, flags %p, stub!\n", filter
, flags
);
2261 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2262 *flags
= filter
->mixing_prefs
;
2263 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2267 static HRESULT WINAPI
mixer_control9_SetProcAmpControl(IVMRMixerControl9
*iface
,
2268 DWORD stream
, VMR9ProcAmpControl
*settings
)
2270 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2272 FIXME("filter %p, settings %p, stub!\n", filter
, settings
);
2277 static HRESULT WINAPI
mixer_control9_GetProcAmpControl(IVMRMixerControl9
*iface
,
2278 DWORD stream
, VMR9ProcAmpControl
*settings
)
2280 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2282 FIXME("filter %p, settings %p, stub!\n", filter
, settings
);
2287 static HRESULT WINAPI
mixer_control9_GetProcAmpControlRange(IVMRMixerControl9
*iface
,
2288 DWORD stream
, VMR9ProcAmpControlRange
*settings
)
2290 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2292 FIXME("filter %p, settings %p, stub!\n", filter
, settings
);
2297 static const IVMRMixerControl9Vtbl mixer_control9_vtbl
=
2299 mixer_control9_QueryInterface
,
2300 mixer_control9_AddRef
,
2301 mixer_control9_Release
,
2302 mixer_control9_SetAlpha
,
2303 mixer_control9_GetAlpha
,
2304 mixer_control9_SetZOrder
,
2305 mixer_control9_GetZOrder
,
2306 mixer_control9_SetOutputRect
,
2307 mixer_control9_GetOutputRect
,
2308 mixer_control9_SetBackgroundClr
,
2309 mixer_control9_GetBackgroundClr
,
2310 mixer_control9_SetMixingPrefs
,
2311 mixer_control9_GetMixingPrefs
,
2312 mixer_control9_SetProcAmpControl
,
2313 mixer_control9_GetProcAmpControl
,
2314 mixer_control9_GetProcAmpControlRange
,
2317 static inline struct quartz_vmr
*impl_from_IVMRMixerBitmap9(IVMRMixerBitmap9
*iface
)
2319 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRMixerBitmap9_iface
);
2322 static HRESULT WINAPI
mixer_bitmap9_QueryInterface(IVMRMixerBitmap9
*iface
, REFIID iid
, void **out
)
2324 struct quartz_vmr
*filter
= impl_from_IVMRMixerBitmap9(iface
);
2325 return IUnknown_QueryInterface(filter
->renderer
.filter
.outer_unk
, iid
, out
);
2328 static ULONG WINAPI
mixer_bitmap9_AddRef(IVMRMixerBitmap9
*iface
)
2330 struct quartz_vmr
*filter
= impl_from_IVMRMixerBitmap9(iface
);
2331 return IUnknown_AddRef(filter
->renderer
.filter
.outer_unk
);
2334 static ULONG WINAPI
mixer_bitmap9_Release(IVMRMixerBitmap9
*iface
)
2336 struct quartz_vmr
*filter
= impl_from_IVMRMixerBitmap9(iface
);
2337 return IUnknown_Release(filter
->renderer
.filter
.outer_unk
);
2340 static HRESULT WINAPI
mixer_bitmap9_SetAlphaBitmap(IVMRMixerBitmap9
*iface
,
2341 const VMR9AlphaBitmap
*bitmap
)
2343 FIXME("iface %p, bitmap %p, stub!\n", iface
, bitmap
);
2344 TRACE("dwFlags %#x, hdc %p, pDDS %p, rSrc %s, rDest %s, fAlpha %.8e, clrSrcKey #%06x, dwFilterMode %#x.\n",
2345 bitmap
->dwFlags
, bitmap
->hdc
, bitmap
->pDDS
, wine_dbgstr_rect(&bitmap
->rSrc
),
2346 debugstr_normalized_rect(&bitmap
->rDest
), bitmap
->fAlpha
, bitmap
->clrSrcKey
, bitmap
->dwFilterMode
);
2350 static HRESULT WINAPI
mixer_bitmap9_UpdateAlphaBitmapParameters(IVMRMixerBitmap9
*iface
,
2351 const VMR9AlphaBitmap
*bitmap
)
2353 FIXME("iface %p, bitmap %p, stub!\n", iface
, bitmap
);
2357 static HRESULT WINAPI
mixer_bitmap9_GetAlphaBitmapParameters(IVMRMixerBitmap9
*iface
,
2358 VMR9AlphaBitmap
*bitmap
)
2360 FIXME("iface %p, bitmap %p, stub!\n", iface
, bitmap
);
2364 static const IVMRMixerBitmap9Vtbl mixer_bitmap9_vtbl
=
2366 mixer_bitmap9_QueryInterface
,
2367 mixer_bitmap9_AddRef
,
2368 mixer_bitmap9_Release
,
2369 mixer_bitmap9_SetAlphaBitmap
,
2370 mixer_bitmap9_UpdateAlphaBitmapParameters
,
2371 mixer_bitmap9_GetAlphaBitmapParameters
,
2374 static inline struct quartz_vmr
*impl_from_IVMRAspectRatioControl9(IVMRAspectRatioControl9
*iface
)
2376 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRAspectRatioControl9_iface
);
2379 static HRESULT WINAPI
aspect_ratio_control9_QueryInterface(IVMRAspectRatioControl9
*iface
, REFIID iid
, void **out
)
2381 struct quartz_vmr
*filter
= impl_from_IVMRAspectRatioControl9(iface
);
2382 return IUnknown_QueryInterface(filter
->renderer
.filter
.outer_unk
, iid
, out
);
2385 static ULONG WINAPI
aspect_ratio_control9_AddRef(IVMRAspectRatioControl9
*iface
)
2387 struct quartz_vmr
*filter
= impl_from_IVMRAspectRatioControl9(iface
);
2388 return IUnknown_AddRef(filter
->renderer
.filter
.outer_unk
);
2391 static ULONG WINAPI
aspect_ratio_control9_Release(IVMRAspectRatioControl9
*iface
)
2393 struct quartz_vmr
*filter
= impl_from_IVMRAspectRatioControl9(iface
);
2394 return IUnknown_Release(filter
->renderer
.filter
.outer_unk
);
2397 static HRESULT WINAPI
aspect_ratio_control9_GetAspectRatioMode(IVMRAspectRatioControl9
*iface
, DWORD
*mode
)
2399 struct quartz_vmr
*filter
= impl_from_IVMRAspectRatioControl9(iface
);
2401 TRACE("filter %p, mode %p.\n", filter
, mode
);
2403 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2404 *mode
= filter
->aspect_mode
;
2405 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2409 static HRESULT WINAPI
aspect_ratio_control9_SetAspectRatioMode(IVMRAspectRatioControl9
*iface
, DWORD mode
)
2411 struct quartz_vmr
*filter
= impl_from_IVMRAspectRatioControl9(iface
);
2413 TRACE("filter %p, mode %u.\n", filter
, mode
);
2415 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2416 filter
->aspect_mode
= mode
;
2417 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2421 static const IVMRAspectRatioControl9Vtbl aspect_ratio_control9_vtbl
=
2423 aspect_ratio_control9_QueryInterface
,
2424 aspect_ratio_control9_AddRef
,
2425 aspect_ratio_control9_Release
,
2426 aspect_ratio_control9_GetAspectRatioMode
,
2427 aspect_ratio_control9_SetAspectRatioMode
,
2430 static inline struct quartz_vmr
*impl_from_IOverlay(IOverlay
*iface
)
2432 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IOverlay_iface
);
2435 static HRESULT WINAPI
overlay_QueryInterface(IOverlay
*iface
, REFIID iid
, void **out
)
2437 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2438 return IPin_QueryInterface(&filter
->renderer
.sink
.pin
.IPin_iface
, iid
, out
);
2441 static ULONG WINAPI
overlay_AddRef(IOverlay
*iface
)
2443 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2444 return IPin_AddRef(&filter
->renderer
.sink
.pin
.IPin_iface
);
2447 static ULONG WINAPI
overlay_Release(IOverlay
*iface
)
2449 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2450 return IPin_Release(&filter
->renderer
.sink
.pin
.IPin_iface
);
2453 static HRESULT WINAPI
overlay_GetPalette(IOverlay
*iface
, DWORD
*count
, PALETTEENTRY
**palette
)
2455 FIXME("iface %p, count %p, palette %p, stub!\n", iface
, count
, palette
);
2459 static HRESULT WINAPI
overlay_SetPalette(IOverlay
*iface
, DWORD count
, PALETTEENTRY
*palette
)
2461 FIXME("iface %p, count %u, palette %p, stub!\n", iface
, count
, palette
);
2465 static HRESULT WINAPI
overlay_GetDefaultColorKey(IOverlay
*iface
, COLORKEY
*key
)
2467 FIXME("iface %p, key %p, stub!\n", iface
, key
);
2471 static HRESULT WINAPI
overlay_GetColorKey(IOverlay
*iface
, COLORKEY
*key
)
2473 FIXME("iface %p, key %p, stub!\n", iface
, key
);
2477 static HRESULT WINAPI
overlay_SetColorKey(IOverlay
*iface
, COLORKEY
*key
)
2479 FIXME("iface %p, key %p, stub!\n", iface
, key
);
2483 static HRESULT WINAPI
overlay_GetWindowHandle(IOverlay
*iface
, HWND
*window
)
2485 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2487 TRACE("filter %p, window %p.\n", filter
, window
);
2489 if (!filter
->window
.hwnd
)
2490 return VFW_E_WRONG_STATE
;
2492 *window
= filter
->window
.hwnd
;
2496 static HRESULT WINAPI
overlay_GetClipList(IOverlay
*iface
, RECT
*source
, RECT
*dest
, RGNDATA
**region
)
2498 FIXME("iface %p, source %p, dest %p, region %p, stub!\n", iface
, source
, dest
, region
);
2502 static HRESULT WINAPI
overlay_GetVideoPosition(IOverlay
*iface
, RECT
*source
, RECT
*dest
)
2504 FIXME("iface %p, source %p, dest %p, stub!\n", iface
, source
, dest
);
2508 static HRESULT WINAPI
overlay_Advise(IOverlay
*iface
, IOverlayNotify
*sink
, DWORD flags
)
2510 FIXME("iface %p, sink %p, flags %#x, stub!\n", iface
, sink
, flags
);
2514 static HRESULT WINAPI
overlay_Unadvise(IOverlay
*iface
)
2516 FIXME("iface %p, stub!\n", iface
);
2520 static const IOverlayVtbl overlay_vtbl
=
2522 overlay_QueryInterface
,
2527 overlay_GetDefaultColorKey
,
2528 overlay_GetColorKey
,
2529 overlay_SetColorKey
,
2530 overlay_GetWindowHandle
,
2531 overlay_GetClipList
,
2532 overlay_GetVideoPosition
,
2537 static HRESULT
vmr_create(IUnknown
*outer
, IUnknown
**out
, const CLSID
*clsid
)
2539 struct quartz_vmr
*object
;
2542 if (!(object
= calloc(1, sizeof(*object
))))
2543 return E_OUTOFMEMORY
;
2545 object
->hD3d9
= LoadLibraryA("d3d9.dll");
2548 WARN("Could not load d3d9.dll\n");
2550 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
2553 strmbase_renderer_init(&object
->renderer
, outer
, clsid
, L
"VMR Input0", &renderer_ops
);
2554 object
->IAMCertifiedOutputProtection_iface
.lpVtbl
= &IAMCertifiedOutputProtection_Vtbl
;
2555 object
->IAMFilterMiscFlags_iface
.lpVtbl
= &IAMFilterMiscFlags_Vtbl
;
2556 object
->IVMRAspectRatioControl9_iface
.lpVtbl
= &aspect_ratio_control9_vtbl
;
2557 object
->IVMRFilterConfig_iface
.lpVtbl
= &VMR7_FilterConfig_Vtbl
;
2558 object
->IVMRFilterConfig9_iface
.lpVtbl
= &VMR9_FilterConfig_Vtbl
;
2559 object
->IVMRMixerBitmap9_iface
.lpVtbl
= &mixer_bitmap9_vtbl
;
2560 object
->IVMRMixerControl9_iface
.lpVtbl
= &mixer_control9_vtbl
;
2561 object
->IVMRMonitorConfig_iface
.lpVtbl
= &VMR7_MonitorConfig_Vtbl
;
2562 object
->IVMRMonitorConfig9_iface
.lpVtbl
= &VMR9_MonitorConfig_Vtbl
;
2563 object
->IVMRSurfaceAllocatorNotify_iface
.lpVtbl
= &VMR7_SurfaceAllocatorNotify_Vtbl
;
2564 object
->IVMRSurfaceAllocatorNotify9_iface
.lpVtbl
= &VMR9_SurfaceAllocatorNotify_Vtbl
;
2565 object
->IVMRWindowlessControl_iface
.lpVtbl
= &VMR7_WindowlessControl_Vtbl
;
2566 object
->IVMRWindowlessControl9_iface
.lpVtbl
= &VMR9_WindowlessControl_Vtbl
;
2567 object
->IOverlay_iface
.lpVtbl
= &overlay_vtbl
;
2569 video_window_init(&object
->window
, &IVideoWindow_VTable
,
2570 &object
->renderer
.filter
, &object
->renderer
.sink
.pin
, &window_ops
);
2572 if (FAILED(hr
= video_window_create_window(&object
->window
)))
2574 video_window_cleanup(&object
->window
);
2575 strmbase_renderer_cleanup(&object
->renderer
);
2576 FreeLibrary(object
->hD3d9
);
2581 object
->mixing_prefs
= MixerPref9_NoDecimation
| MixerPref9_ARAdjustXorY
2582 | MixerPref9_BiLinearFiltering
| MixerPref9_RenderTargetRGB
;
2584 TRACE("Created VMR %p.\n", object
);
2585 *out
= &object
->renderer
.filter
.IUnknown_inner
;
2589 HRESULT
vmr7_create(IUnknown
*outer
, IUnknown
**out
)
2591 return vmr_create(outer
, out
, &CLSID_VideoMixingRenderer
);
2594 HRESULT
vmr9_create(IUnknown
*outer
, IUnknown
**out
)
2596 return vmr_create(outer
, out
, &CLSID_VideoMixingRenderer9
);
2600 static HRESULT WINAPI
VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9
*iface
, REFIID riid
, void **ppv
)
2602 struct default_presenter
*This
= impl_from_IVMRImagePresenter9(iface
);
2604 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, qzdebugstr_guid(riid
), ppv
);
2608 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IVMRImagePresenter9
))
2609 *ppv
= &This
->IVMRImagePresenter9_iface
;
2610 else if (IsEqualIID(riid
, &IID_IVMRSurfaceAllocator9
))
2611 *ppv
= &This
->IVMRSurfaceAllocator9_iface
;
2615 IUnknown_AddRef((IUnknown
*)(*ppv
));
2619 FIXME("No interface for %s\n", debugstr_guid(riid
));
2621 return E_NOINTERFACE
;
2624 static ULONG WINAPI
VMR9_ImagePresenter_AddRef(IVMRImagePresenter9
*iface
)
2626 struct default_presenter
*This
= impl_from_IVMRImagePresenter9(iface
);
2627 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
2629 TRACE("(%p)->() AddRef from %d\n", iface
, refCount
- 1);
2634 static ULONG WINAPI
VMR9_ImagePresenter_Release(IVMRImagePresenter9
*iface
)
2636 struct default_presenter
*This
= impl_from_IVMRImagePresenter9(iface
);
2637 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
2639 TRACE("(%p)->() Release from %d\n", iface
, refCount
+ 1);
2644 TRACE("Destroying\n");
2645 IDirect3D9_Release(This
->d3d9_ptr
);
2647 TRACE("Number of surfaces: %u\n", This
->num_surfaces
);
2648 for (i
= 0; i
< This
->num_surfaces
; ++i
)
2650 IDirect3DSurface9
*surface
= This
->d3d9_surfaces
[i
];
2651 TRACE("Releasing surface %p\n", surface
);
2653 IDirect3DSurface9_Release(surface
);
2657 IDirect3DDevice9_Release(This
->d3d9_dev
);
2658 free(This
->d3d9_surfaces
);
2659 This
->d3d9_surfaces
= NULL
;
2660 This
->num_surfaces
= 0;
2667 static HRESULT WINAPI
VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9
*iface
, DWORD_PTR cookie
)
2669 struct default_presenter
*presenter
= impl_from_IVMRImagePresenter9(iface
);
2671 TRACE("presenter %p, cookie %#Ix.\n", presenter
, cookie
);
2676 static HRESULT WINAPI
VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9
*iface
, DWORD_PTR cookie
)
2678 struct default_presenter
*presenter
= impl_from_IVMRImagePresenter9(iface
);
2680 TRACE("presenter %p, cookie %#Ix.\n", presenter
, cookie
);
2685 static HRESULT WINAPI
VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9
*iface
,
2686 DWORD_PTR cookie
, VMR9PresentationInfo
*info
)
2688 struct default_presenter
*presenter
= impl_from_IVMRImagePresenter9(iface
);
2689 const struct quartz_vmr
*filter
= presenter
->pVMR9
;
2690 IDirect3DDevice9
*device
= presenter
->d3d9_dev
;
2691 const RECT src
= filter
->window
.src
;
2692 IDirect3DSurface9
*backbuffer
;
2693 RECT dst
= filter
->window
.dst
;
2696 TRACE("presenter %p, cookie %#Ix, info %p.\n", presenter
, cookie
, info
);
2698 /* This might happen if we don't have active focus (eg on a different virtual desktop) */
2702 if (FAILED(hr
= IDirect3DDevice9_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
,
2703 D3DCOLOR_XRGB(0, 0, 0), 1.0f
, 0)))
2704 ERR("Failed to clear, hr %#x.\n", hr
);
2706 if (FAILED(hr
= IDirect3DDevice9_BeginScene(device
)))
2707 ERR("Failed to begin scene, hr %#x.\n", hr
);
2709 if (FAILED(hr
= IDirect3DDevice9_GetBackBuffer(device
, 0, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
)))
2711 ERR("Failed to get backbuffer, hr %#x.\n", hr
);
2715 if (FAILED(hr
= IDirect3DDevice9_StretchRect(device
, info
->lpSurf
, NULL
, backbuffer
, NULL
, D3DTEXF_POINT
)))
2716 ERR("Failed to blit image, hr %#x.\n", hr
);
2717 IDirect3DSurface9_Release(backbuffer
);
2719 if (FAILED(hr
= IDirect3DDevice9_EndScene(device
)))
2720 ERR("Failed to end scene, hr %#x.\n", hr
);
2722 if (filter
->aspect_mode
== VMR9ARMode_LetterBox
)
2724 unsigned int src_width
= src
.right
- src
.left
, src_height
= src
.bottom
- src
.top
;
2725 unsigned int dst_width
= dst
.right
- dst
.left
, dst_height
= dst
.bottom
- dst
.top
;
2727 if (src_width
* dst_height
> dst_width
* src_height
)
2729 /* src is "wider" than dst. */
2730 unsigned int dst_center
= (dst
.top
+ dst
.bottom
) / 2;
2731 unsigned int scaled_height
= src_height
* dst_width
/ src_width
;
2733 dst
.top
= dst_center
- scaled_height
/ 2;
2734 dst
.bottom
= dst
.top
+ scaled_height
;
2736 else if (src_width
* dst_height
< dst_width
* src_height
)
2738 /* src is "taller" than dst. */
2739 unsigned int dst_center
= (dst
.left
+ dst
.right
) / 2;
2740 unsigned int scaled_width
= src_width
* dst_height
/ src_height
;
2742 dst
.left
= dst_center
- scaled_width
/ 2;
2743 dst
.right
= dst
.left
+ scaled_width
;
2747 if (FAILED(hr
= IDirect3DDevice9_Present(device
, &src
, &dst
, NULL
, NULL
)))
2748 ERR("Failed to present, hr %#x.\n", hr
);
2753 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter
=
2755 VMR9_ImagePresenter_QueryInterface
,
2756 VMR9_ImagePresenter_AddRef
,
2757 VMR9_ImagePresenter_Release
,
2758 VMR9_ImagePresenter_StartPresenting
,
2759 VMR9_ImagePresenter_StopPresenting
,
2760 VMR9_ImagePresenter_PresentImage
2763 static HRESULT WINAPI
VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocator9
*iface
, REFIID iid
, void **out
)
2765 struct default_presenter
*presenter
= impl_from_IVMRSurfaceAllocator9(iface
);
2766 return IVMRImagePresenter9_QueryInterface(&presenter
->IVMRImagePresenter9_iface
, iid
, out
);
2769 static ULONG WINAPI
VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocator9
*iface
)
2771 struct default_presenter
*presenter
= impl_from_IVMRSurfaceAllocator9(iface
);
2772 return IVMRImagePresenter9_AddRef(&presenter
->IVMRImagePresenter9_iface
);
2775 static ULONG WINAPI
VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocator9
*iface
)
2777 struct default_presenter
*presenter
= impl_from_IVMRSurfaceAllocator9(iface
);
2778 return IVMRImagePresenter9_Release(&presenter
->IVMRImagePresenter9_iface
);
2781 static HRESULT
VMR9_SurfaceAllocator_SetAllocationSettings(struct default_presenter
*This
, VMR9AllocationInfo
*allocinfo
)
2787 if (!(allocinfo
->dwFlags
& VMR9AllocFlag_TextureSurface
))
2788 /* Only needed for texture surfaces */
2791 hr
= IDirect3DDevice9_GetDeviceCaps(This
->d3d9_dev
, &caps
);
2795 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
) || (caps
.TextureCaps
& D3DPTEXTURECAPS_SQUAREONLY
))
2797 width
= allocinfo
->dwWidth
;
2798 height
= allocinfo
->dwHeight
;
2803 while (width
< allocinfo
->dwWidth
)
2806 while (height
< allocinfo
->dwHeight
)
2808 FIXME("NPOW2 support missing, not using proper surfaces!\n");
2811 if (caps
.TextureCaps
& D3DPTEXTURECAPS_SQUAREONLY
)
2817 FIXME("Square texture support required..\n");
2820 allocinfo
->dwHeight
= height
;
2821 allocinfo
->dwWidth
= width
;
2826 static UINT
d3d9_adapter_from_hwnd(IDirect3D9
*d3d9
, HWND hwnd
, HMONITOR
*mon_out
)
2831 mon
= MonitorFromWindow(hwnd
, MONITOR_DEFAULTTONULL
);
2836 for (d3d9_adapter
= 0; d3d9_adapter
< IDirect3D9_GetAdapterCount(d3d9
); ++d3d9_adapter
)
2838 if (mon
== IDirect3D9_GetAdapterMonitor(d3d9
, d3d9_adapter
))
2841 if (d3d9_adapter
>= IDirect3D9_GetAdapterCount(d3d9
))
2846 return d3d9_adapter
;
2849 static HRESULT WINAPI
VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocator9
*iface
,
2850 DWORD_PTR cookie
, VMR9AllocationInfo
*info
, DWORD
*numbuffers
)
2852 struct default_presenter
*This
= impl_from_IVMRSurfaceAllocator9(iface
);
2853 D3DPRESENT_PARAMETERS d3dpp
;
2854 IDirect3DDevice9
*device
;
2860 TRACE("presenter %p, cookie %#Ix, info %p, numbuffers %p.\n", This
, cookie
, info
, numbuffers
);
2864 if (This
->pVMR9
->mode
== VMR9Mode_Windowed
)
2865 window
= This
->pVMR9
->window
.hwnd
;
2867 window
= This
->pVMR9
->clipping_window
;
2869 /* Obtain a monitor and d3d9 device */
2870 d3d9_adapter
= d3d9_adapter_from_hwnd(This
->d3d9_ptr
, window
, &This
->hMon
);
2872 /* Now try to create the d3d9 device */
2873 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
2874 d3dpp
.Windowed
= TRUE
;
2875 d3dpp
.hDeviceWindow
= window
;
2876 d3dpp
.SwapEffect
= D3DSWAPEFFECT_COPY
;
2877 d3dpp
.BackBufferWidth
= info
->dwWidth
;
2878 d3dpp
.BackBufferHeight
= info
->dwHeight
;
2880 hr
= IDirect3D9_CreateDevice(This
->d3d9_ptr
, d3d9_adapter
, D3DDEVTYPE_HAL
,
2881 NULL
, D3DCREATE_MIXED_VERTEXPROCESSING
, &d3dpp
, &device
);
2884 ERR("Could not create device: %08x\n", hr
);
2888 IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
2889 if (!(caps
.DevCaps2
& D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES
))
2891 WARN("Device does not support blitting from textures.\n");
2892 IDirect3DDevice9_Release(device
);
2893 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
2896 This
->d3d9_dev
= device
;
2897 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This
->SurfaceAllocatorNotify
, This
->d3d9_dev
, This
->hMon
);
2899 if (!(This
->d3d9_surfaces
= calloc(*numbuffers
, sizeof(IDirect3DSurface9
*))))
2900 return E_OUTOFMEMORY
;
2902 hr
= VMR9_SurfaceAllocator_SetAllocationSettings(This
, info
);
2904 ERR("Setting allocation settings failed: %08x\n", hr
);
2908 hr
= IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This
->SurfaceAllocatorNotify
, info
, numbuffers
, This
->d3d9_surfaces
);
2910 ERR("Allocating surfaces failed: %08x\n", hr
);
2915 IVMRSurfaceAllocator9_TerminateDevice(This
->pVMR9
->allocator
, This
->pVMR9
->cookie
);
2919 This
->num_surfaces
= *numbuffers
;
2924 static HRESULT WINAPI
VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocator9
*iface
, DWORD_PTR cookie
)
2926 TRACE("iface %p, cookie %#lx.\n", iface
, cookie
);
2931 static HRESULT WINAPI
VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocator9
*iface
,
2932 DWORD_PTR cookie
, DWORD surfaceindex
, DWORD flags
, IDirect3DSurface9
**surface
)
2934 struct default_presenter
*This
= impl_from_IVMRSurfaceAllocator9(iface
);
2936 /* Update everything first, this is needed because the surface might be destroyed in the reset */
2937 if (!This
->d3d9_dev
)
2939 TRACE("Device has left me!\n");
2943 if (surfaceindex
>= This
->num_surfaces
)
2945 ERR("surfaceindex is greater than num_surfaces\n");
2948 *surface
= This
->d3d9_surfaces
[surfaceindex
];
2949 IDirect3DSurface9_AddRef(*surface
);
2954 static HRESULT WINAPI
VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocator9
*iface
,
2955 IVMRSurfaceAllocatorNotify9
*notify
)
2957 struct default_presenter
*presenter
= impl_from_IVMRSurfaceAllocator9(iface
);
2959 TRACE("presenter %p, notify %p.\n", presenter
, notify
);
2961 /* No AddRef taken here or the base VMR9 filter would never be destroyed */
2962 presenter
->SurfaceAllocatorNotify
= notify
;
2966 static const IVMRSurfaceAllocator9Vtbl VMR9_SurfaceAllocator
=
2968 VMR9_SurfaceAllocator_QueryInterface
,
2969 VMR9_SurfaceAllocator_AddRef
,
2970 VMR9_SurfaceAllocator_Release
,
2971 VMR9_SurfaceAllocator_InitializeDevice
,
2972 VMR9_SurfaceAllocator_TerminateDevice
,
2973 VMR9_SurfaceAllocator_GetSurface
,
2974 VMR9_SurfaceAllocator_AdviseNotify
,
2977 static IDirect3D9
*init_d3d9(HMODULE d3d9_handle
)
2979 IDirect3D9
* (__stdcall
* d3d9_create
)(UINT SDKVersion
);
2981 d3d9_create
= (void *)GetProcAddress(d3d9_handle
, "Direct3DCreate9");
2982 if (!d3d9_create
) return NULL
;
2984 return d3d9_create(D3D_SDK_VERSION
);
2987 static HRESULT
VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr
*parent
, LPVOID
* ppv
)
2989 struct default_presenter
*object
;
2993 if (!(object
= calloc(1, sizeof(*object
))))
2994 return E_OUTOFMEMORY
;
2996 object
->d3d9_ptr
= init_d3d9(parent
->hD3d9
);
2997 if (!object
->d3d9_ptr
)
2999 WARN("Could not initialize d3d9.dll\n");
3001 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
3007 D3DDISPLAYMODE mode
;
3009 hr
= IDirect3D9_EnumAdapterModes(object
->d3d9_ptr
, i
++, D3DFMT_X8R8G8B8
, 0, &mode
);
3010 if (hr
== D3DERR_INVALIDCALL
) break; /* out of adapters */
3011 } while (FAILED(hr
));
3013 ERR("HR: %08x\n", hr
);
3014 if (hr
== D3DERR_NOTAVAILABLE
)
3016 ERR("Format not supported\n");
3017 IDirect3D9_Release(object
->d3d9_ptr
);
3019 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
3022 object
->IVMRImagePresenter9_iface
.lpVtbl
= &VMR9_ImagePresenter
;
3023 object
->IVMRSurfaceAllocator9_iface
.lpVtbl
= &VMR9_SurfaceAllocator
;
3025 object
->refCount
= 1;
3026 object
->pVMR9
= parent
;
3028 TRACE("Created default presenter %p.\n", object
);
3029 *ppv
= &object
->IVMRImagePresenter9_iface
;