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"
39 #include "wine/debug.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
43 static inline const char *debugstr_normalized_rect(const VMR9NormalizedRect
*rect
)
45 if (!rect
) return "(null)";
46 return wine_dbg_sprintf("(%.8e,%.8e)-(%.8e,%.8e)", rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
49 static const BITMAPINFOHEADER
*get_bitmap_header(const AM_MEDIA_TYPE
*mt
)
51 if (IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
))
52 return &((VIDEOINFOHEADER
*)mt
->pbFormat
)->bmiHeader
;
54 return &((VIDEOINFOHEADER2
*)mt
->pbFormat
)->bmiHeader
;
59 struct strmbase_renderer renderer
;
60 struct video_window window
;
62 IAMCertifiedOutputProtection IAMCertifiedOutputProtection_iface
;
63 IAMFilterMiscFlags IAMFilterMiscFlags_iface
;
64 IVMRAspectRatioControl9 IVMRAspectRatioControl9_iface
;
65 IVMRFilterConfig IVMRFilterConfig_iface
;
66 IVMRFilterConfig9 IVMRFilterConfig9_iface
;
67 IVMRMixerBitmap9 IVMRMixerBitmap9_iface
;
68 IVMRMixerControl9 IVMRMixerControl9_iface
;
69 IVMRMonitorConfig IVMRMonitorConfig_iface
;
70 IVMRMonitorConfig9 IVMRMonitorConfig9_iface
;
71 IVMRSurfaceAllocatorNotify IVMRSurfaceAllocatorNotify_iface
;
72 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface
;
73 IVMRWindowlessControl IVMRWindowlessControl_iface
;
74 IVMRWindowlessControl9 IVMRWindowlessControl9_iface
;
76 /* Devil May Cry 3 releases the last IBaseFilter reference while still
77 * holding an IVMRSurfaceAllocatorNotify9 reference, and depends on
78 * IVMRSurfaceAllocator9::TerminateDevice() being called as a result.
79 * Native uses a separate reference count for IVMRSurfaceAllocatorNotify9. */
80 LONG IVMRSurfaceAllocatorNotify9_refcount
;
82 IAMVideoAccelerator IAMVideoAccelerator_iface
;
83 IOverlay IOverlay_iface
;
85 IVMRSurfaceAllocator9
*allocator
;
86 IVMRImagePresenter9
*presenter
;
92 * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed
93 * What I do is implement windowless as a special case of renderless, and then
94 * windowed also as a special case of windowless. This is probably the easiest way.
97 BITMAPINFOHEADER bmiheader
;
101 /* Presentation related members */
102 IDirect3DDevice9
*allocator_d3d9_dev
;
103 IDirect3DSurface9
**surfaces
;
108 HWND clipping_window
;
112 VMR9AspectRatioMode aspect_mode
;
115 static inline BOOL
is_vmr9(const struct quartz_vmr
*filter
)
117 return IsEqualGUID(&filter
->renderer
.filter
.clsid
, &CLSID_VideoMixingRenderer9
);
120 static inline struct quartz_vmr
*impl_from_video_window(struct video_window
*iface
)
122 return CONTAINING_RECORD(iface
, struct quartz_vmr
, window
);
125 static inline struct quartz_vmr
*impl_from_IAMCertifiedOutputProtection(IAMCertifiedOutputProtection
*iface
)
127 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IAMCertifiedOutputProtection_iface
);
130 static inline struct quartz_vmr
*impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags
*iface
)
132 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IAMFilterMiscFlags_iface
);
135 static inline struct quartz_vmr
*impl_from_IVMRFilterConfig(IVMRFilterConfig
*iface
)
137 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRFilterConfig_iface
);
140 static inline struct quartz_vmr
*impl_from_IVMRFilterConfig9(IVMRFilterConfig9
*iface
)
142 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRFilterConfig9_iface
);
145 static inline struct quartz_vmr
*impl_from_IVMRMonitorConfig(IVMRMonitorConfig
*iface
)
147 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRMonitorConfig_iface
);
150 static inline struct quartz_vmr
*impl_from_IVMRMonitorConfig9(IVMRMonitorConfig9
*iface
)
152 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRMonitorConfig9_iface
);
155 static inline struct quartz_vmr
*impl_from_IVMRSurfaceAllocatorNotify(IVMRSurfaceAllocatorNotify
*iface
)
157 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRSurfaceAllocatorNotify_iface
);
160 static inline struct quartz_vmr
*impl_from_IVMRSurfaceAllocatorNotify9(IVMRSurfaceAllocatorNotify9
*iface
)
162 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRSurfaceAllocatorNotify9_iface
);
165 static inline struct quartz_vmr
*impl_from_IVMRWindowlessControl(IVMRWindowlessControl
*iface
)
167 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRWindowlessControl_iface
);
170 static inline struct quartz_vmr
*impl_from_IVMRWindowlessControl9(IVMRWindowlessControl9
*iface
)
172 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRWindowlessControl9_iface
);
175 struct default_presenter
177 IVMRImagePresenter9 IVMRImagePresenter9_iface
;
178 IVMRSurfaceAllocator9 IVMRSurfaceAllocator9_iface
;
182 IDirect3DDevice9
*d3d9_dev
;
183 IDirect3D9
*d3d9_ptr
;
184 IDirect3DSurface9
**d3d9_surfaces
;
188 VMR9AllocationInfo info
;
190 struct quartz_vmr
* pVMR9
;
191 IVMRSurfaceAllocatorNotify9
*SurfaceAllocatorNotify
;
194 static inline struct default_presenter
*impl_from_IVMRImagePresenter9(IVMRImagePresenter9
*iface
)
196 return CONTAINING_RECORD(iface
, struct default_presenter
, IVMRImagePresenter9_iface
);
199 static inline struct default_presenter
*impl_from_IVMRSurfaceAllocator9(IVMRSurfaceAllocator9
*iface
)
201 return CONTAINING_RECORD(iface
, struct default_presenter
, IVMRSurfaceAllocator9_iface
);
204 static HRESULT
VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr
*parent
, LPVOID
* ppv
);
206 static inline struct quartz_vmr
*impl_from_IBaseFilter(IBaseFilter
*iface
)
208 return CONTAINING_RECORD(iface
, struct quartz_vmr
, renderer
.filter
.IBaseFilter_iface
);
211 static HRESULT
vmr_render(struct strmbase_renderer
*iface
, IMediaSample
*sample
)
213 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
214 unsigned int data_size
, width
, depth
, src_pitch
;
215 const BITMAPINFOHEADER
*bitmap_header
;
216 REFERENCE_TIME start_time
, end_time
;
217 VMR9PresentationInfo info
= {};
218 D3DLOCKED_RECT locked_rect
;
223 TRACE("filter %p, sample %p.\n", filter
, sample
);
225 /* It is possible that there is no device at this point */
227 if (!filter
->allocator
|| !filter
->presenter
)
229 ERR("NO PRESENTER!!\n");
233 info
.dwFlags
= VMR9Sample_SrcDstRectsValid
;
235 if (SUCCEEDED(hr
= IMediaSample_GetTime(sample
, &start_time
, &end_time
)))
236 info
.dwFlags
|= VMR9Sample_TimeValid
;
238 if (IMediaSample_IsDiscontinuity(sample
) == S_OK
)
239 info
.dwFlags
|= VMR9Sample_Discontinuity
;
241 if (IMediaSample_IsPreroll(sample
) == S_OK
)
242 info
.dwFlags
|= VMR9Sample_Preroll
;
244 if (IMediaSample_IsSyncPoint(sample
) == S_OK
)
245 info
.dwFlags
|= VMR9Sample_SyncPoint
;
247 if (FAILED(hr
= IMediaSample_GetPointer(sample
, &data
)))
249 ERR("Failed to get pointer to sample data, hr %#lx.\n", hr
);
252 data_size
= IMediaSample_GetActualDataLength(sample
);
254 bitmap_header
= get_bitmap_header(&filter
->renderer
.sink
.pin
.mt
);
255 width
= bitmap_header
->biWidth
;
256 height
= bitmap_header
->biHeight
;
257 depth
= bitmap_header
->biBitCount
;
258 if (bitmap_header
->biCompression
== mmioFOURCC('N','V','1','2')
259 || bitmap_header
->biCompression
== mmioFOURCC('Y','V','1','2'))
261 else /* packed YUV (UYVY or YUY2) or RGB */
262 src_pitch
= ((width
* depth
/ 8) + 3) & ~3;
264 info
.rtStart
= start_time
;
265 info
.rtEnd
= end_time
;
266 info
.szAspectRatio
.cx
= width
;
267 info
.szAspectRatio
.cy
= height
;
268 info
.lpSurf
= filter
->surfaces
[(++filter
->cur_surface
) % filter
->num_surfaces
];
270 if (FAILED(hr
= IDirect3DSurface9_LockRect(info
.lpSurf
, &locked_rect
, NULL
, D3DLOCK_DISCARD
)))
272 ERR("Failed to lock surface, hr %#lx.\n", hr
);
276 if (height
> 0 && bitmap_header
->biCompression
== BI_RGB
)
278 BYTE
*dst
= (BYTE
*)locked_rect
.pBits
+ (height
* locked_rect
.Pitch
);
279 const BYTE
*src
= data
;
281 TRACE("Inverting image.\n");
285 dst
-= locked_rect
.Pitch
;
286 memcpy(dst
, src
, width
* depth
/ 8);
290 else if (locked_rect
.Pitch
!= src_pitch
)
292 BYTE
*dst
= locked_rect
.pBits
;
293 const BYTE
*src
= data
;
295 height
= abs(height
);
297 TRACE("Source pitch %u does not match dest pitch %u; copying manually.\n",
298 src_pitch
, locked_rect
.Pitch
);
302 memcpy(dst
, src
, width
* depth
/ 8);
304 dst
+= locked_rect
.Pitch
;
309 memcpy(locked_rect
.pBits
, data
, data_size
);
312 IDirect3DSurface9_UnlockRect(info
.lpSurf
);
314 return IVMRImagePresenter9_PresentImage(filter
->presenter
, filter
->cookie
, &info
);
317 static HRESULT
vmr_query_accept(struct strmbase_renderer
*iface
, const AM_MEDIA_TYPE
*mt
)
319 if (!IsEqualIID(&mt
->majortype
, &MEDIATYPE_Video
) || !mt
->pbFormat
)
322 if (!IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo
)
323 && !IsEqualGUID(&mt
->formattype
, &FORMAT_VideoInfo2
))
329 static HRESULT
initialize_device(struct quartz_vmr
*filter
, VMR9AllocationInfo
*info
, DWORD count
)
334 if (FAILED(hr
= IVMRSurfaceAllocator9_InitializeDevice(filter
->allocator
,
335 filter
->cookie
, info
, &count
)))
337 WARN("Failed to initialize device (flags %#lx), hr %#lx.\n", info
->dwFlags
, hr
);
341 for (i
= 0; i
< count
; ++i
)
343 if (FAILED(hr
= IVMRSurfaceAllocator9_GetSurface(filter
->allocator
,
344 filter
->cookie
, i
, 0, &filter
->surfaces
[i
])))
346 ERR("Failed to get surface %lu, hr %#lx.\n", i
, hr
);
348 IDirect3DSurface9_Release(filter
->surfaces
[i
]);
349 IVMRSurfaceAllocator9_TerminateDevice(filter
->allocator
, filter
->cookie
);
357 static HRESULT
allocate_surfaces(struct quartz_vmr
*filter
, const AM_MEDIA_TYPE
*mt
)
359 VMR9AllocationInfo info
= {};
372 {&MEDIASUBTYPE_ARGB1555
, D3DFMT_A1R5G5B5
, VMR9AllocFlag_TextureSurface
},
373 {&MEDIASUBTYPE_ARGB32
, D3DFMT_A8R8G8B8
, VMR9AllocFlag_TextureSurface
},
374 {&MEDIASUBTYPE_ARGB4444
, D3DFMT_A4R4G4B4
, VMR9AllocFlag_TextureSurface
},
376 {&MEDIASUBTYPE_RGB24
, D3DFMT_R8G8B8
, VMR9AllocFlag_TextureSurface
| VMR9AllocFlag_OffscreenSurface
},
377 {&MEDIASUBTYPE_RGB32
, D3DFMT_X8R8G8B8
, VMR9AllocFlag_TextureSurface
| VMR9AllocFlag_OffscreenSurface
},
378 {&MEDIASUBTYPE_RGB555
, D3DFMT_X1R5G5B5
, VMR9AllocFlag_TextureSurface
| VMR9AllocFlag_OffscreenSurface
},
379 {&MEDIASUBTYPE_RGB565
, D3DFMT_R5G6B5
, VMR9AllocFlag_TextureSurface
| VMR9AllocFlag_OffscreenSurface
},
381 {&MEDIASUBTYPE_NV12
, MAKEFOURCC('N','V','1','2'), VMR9AllocFlag_OffscreenSurface
},
382 {&MEDIASUBTYPE_UYVY
, D3DFMT_UYVY
, VMR9AllocFlag_OffscreenSurface
},
383 {&MEDIASUBTYPE_YUY2
, D3DFMT_YUY2
, VMR9AllocFlag_OffscreenSurface
},
384 {&MEDIASUBTYPE_YV12
, MAKEFOURCC('Y','V','1','2'), VMR9AllocFlag_OffscreenSurface
},
387 TRACE("Initializing in mode %u, our window %p, clipping window %p.\n",
388 filter
->mode
, filter
->window
.hwnd
, filter
->clipping_window
);
390 if (filter
->mode
== VMR9Mode_Windowless
&& !filter
->clipping_window
)
393 info
.Pool
= D3DPOOL_DEFAULT
;
394 info
.MinBuffers
= count
;
395 info
.dwWidth
= info
.szAspectRatio
.cx
= info
.szNativeSize
.cx
= filter
->bmiheader
.biWidth
;
396 info
.dwHeight
= info
.szAspectRatio
.cy
= info
.szNativeSize
.cy
= filter
->bmiheader
.biHeight
;
398 if (!(filter
->surfaces
= calloc(count
, sizeof(IDirect3DSurface9
*))))
399 return E_OUTOFMEMORY
;
400 filter
->num_surfaces
= count
;
401 filter
->cur_surface
= 0;
403 if (!is_vmr9(filter
))
405 switch (filter
->bmiheader
.biCompression
)
408 switch (filter
->bmiheader
.biBitCount
)
410 case 24: info
.Format
= D3DFMT_R8G8B8
; break;
411 case 32: info
.Format
= D3DFMT_X8R8G8B8
; break;
413 FIXME("Unhandled bit depth %u.\n", filter
->bmiheader
.biBitCount
);
414 free(filter
->surfaces
);
415 return VFW_E_TYPE_NOT_ACCEPTED
;
418 info
.dwFlags
= VMR9AllocFlag_TextureSurface
;
421 case mmioFOURCC('N','V','1','2'):
422 case mmioFOURCC('U','Y','V','Y'):
423 case mmioFOURCC('Y','U','Y','2'):
424 case mmioFOURCC('Y','V','1','2'):
425 info
.Format
= filter
->bmiheader
.biCompression
;
426 info
.dwFlags
= VMR9AllocFlag_OffscreenSurface
;
430 WARN("Unhandled video compression %#lx.\n", filter
->bmiheader
.biCompression
);
431 free(filter
->surfaces
);
432 return VFW_E_TYPE_NOT_ACCEPTED
;
434 if (FAILED(hr
= initialize_device(filter
, &info
, count
)))
435 free(filter
->surfaces
);
439 for (i
= 0; i
< ARRAY_SIZE(formats
); ++i
)
441 if (IsEqualGUID(&mt
->subtype
, formats
[i
].subtype
))
443 info
.Format
= formats
[i
].format
;
445 if (formats
[i
].flags
& VMR9AllocFlag_TextureSurface
)
447 info
.dwFlags
= VMR9AllocFlag_TextureSurface
;
448 if (SUCCEEDED(hr
= initialize_device(filter
, &info
, count
)))
452 if (formats
[i
].flags
& VMR9AllocFlag_OffscreenSurface
)
454 info
.dwFlags
= VMR9AllocFlag_OffscreenSurface
;
455 if (SUCCEEDED(hr
= initialize_device(filter
, &info
, count
)))
461 free(filter
->surfaces
);
462 return VFW_E_TYPE_NOT_ACCEPTED
;
465 static void vmr_init_stream(struct strmbase_renderer
*iface
)
467 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
469 if (filter
->window
.hwnd
&& filter
->window
.AutoShow
)
470 ShowWindow(filter
->window
.hwnd
, SW_SHOW
);
473 static void vmr_start_stream(struct strmbase_renderer
*iface
)
475 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
477 IVMRImagePresenter9_StartPresenting(filter
->presenter
, filter
->cookie
);
480 static void vmr_stop_stream(struct strmbase_renderer
*iface
)
482 struct quartz_vmr
*This
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
484 TRACE("(%p)\n", This
);
486 if (This
->renderer
.filter
.state
== State_Running
)
487 IVMRImagePresenter9_StopPresenting(This
->presenter
, This
->cookie
);
490 static HRESULT
vmr_connect(struct strmbase_renderer
*iface
, const AM_MEDIA_TYPE
*mt
)
492 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
493 const BITMAPINFOHEADER
*bitmap_header
= get_bitmap_header(mt
);
494 HWND window
= filter
->window
.hwnd
;
498 filter
->bmiheader
= *bitmap_header
;
499 filter
->VideoWidth
= bitmap_header
->biWidth
;
500 filter
->VideoHeight
= bitmap_header
->biHeight
;
501 SetRect(&rect
, 0, 0, filter
->VideoWidth
, filter
->VideoHeight
);
502 filter
->window
.src
= rect
;
504 AdjustWindowRectEx(&rect
, GetWindowLongW(window
, GWL_STYLE
), FALSE
,
505 GetWindowLongW(window
, GWL_EXSTYLE
));
506 SetWindowPos(window
, NULL
, 0, 0, rect
.right
- rect
.left
, rect
.bottom
- rect
.top
,
507 SWP_NOMOVE
| SWP_NOZORDER
| SWP_NOACTIVATE
);
508 GetClientRect(window
, &filter
->window
.dst
);
511 || SUCCEEDED(hr
= IVMRFilterConfig9_SetRenderingMode(&filter
->IVMRFilterConfig9_iface
, VMR9Mode_Windowed
)))
512 hr
= allocate_surfaces(filter
, mt
);
517 static void vmr_disconnect(struct strmbase_renderer
*This
)
519 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&This
->filter
.IBaseFilter_iface
);
522 if (filter
->mode
&& filter
->allocator
&& filter
->presenter
)
524 for (i
= 0; i
< filter
->num_surfaces
; ++i
)
525 IDirect3DSurface9_Release(filter
->surfaces
[i
]);
526 free(filter
->surfaces
);
528 IVMRSurfaceAllocator9_TerminateDevice(filter
->allocator
, filter
->cookie
);
529 filter
->num_surfaces
= 0;
533 static void vmr_destroy(struct strmbase_renderer
*iface
)
535 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
537 video_window_cleanup(&filter
->window
);
539 /* Devil May Cry 3 releases the IVMRSurfaceAllocatorNotify9 interface from
540 * TerminateDevice(). Artificially increase the reference count so that we
541 * don't free the filter yet. */
542 InterlockedIncrement(&filter
->renderer
.filter
.refcount
);
544 if (filter
->allocator
)
546 IVMRSurfaceAllocator9_TerminateDevice(filter
->allocator
, filter
->cookie
);
547 IVMRSurfaceAllocator9_Release(filter
->allocator
);
549 if (filter
->presenter
)
550 IVMRImagePresenter9_Release(filter
->presenter
);
552 filter
->num_surfaces
= 0;
553 if (filter
->allocator_d3d9_dev
)
555 IDirect3DDevice9_Release(filter
->allocator_d3d9_dev
);
556 filter
->allocator_d3d9_dev
= NULL
;
559 FreeLibrary(filter
->hD3d9
);
560 strmbase_renderer_cleanup(&filter
->renderer
);
561 if (!filter
->IVMRSurfaceAllocatorNotify9_refcount
)
565 static HRESULT
vmr_query_interface(struct strmbase_renderer
*iface
, REFIID iid
, void **out
)
567 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
569 if (IsEqualGUID(iid
, &IID_IVideoWindow
))
570 *out
= &filter
->window
.IVideoWindow_iface
;
571 else if (IsEqualGUID(iid
, &IID_IBasicVideo
))
572 *out
= &filter
->window
.IBasicVideo_iface
;
573 else if (IsEqualGUID(iid
, &IID_IAMCertifiedOutputProtection
))
574 *out
= &filter
->IAMCertifiedOutputProtection_iface
;
575 else if (IsEqualGUID(iid
, &IID_IAMFilterMiscFlags
))
576 *out
= &filter
->IAMFilterMiscFlags_iface
;
577 else if (IsEqualGUID(iid
, &IID_IVMRAspectRatioControl9
) && is_vmr9(filter
))
578 *out
= &filter
->IVMRAspectRatioControl9_iface
;
579 else if (IsEqualGUID(iid
, &IID_IVMRFilterConfig
) && !is_vmr9(filter
))
580 *out
= &filter
->IVMRFilterConfig_iface
;
581 else if (IsEqualGUID(iid
, &IID_IVMRFilterConfig9
) && is_vmr9(filter
))
582 *out
= &filter
->IVMRFilterConfig9_iface
;
583 else if (IsEqualGUID(iid
, &IID_IVMRMixerBitmap9
) && is_vmr9(filter
))
584 *out
= &filter
->IVMRMixerBitmap9_iface
;
585 else if (IsEqualGUID(iid
, &IID_IVMRMixerControl9
) && is_vmr9(filter
) && filter
->stream_count
)
586 *out
= &filter
->IVMRMixerControl9_iface
;
587 else if (IsEqualGUID(iid
, &IID_IVMRMonitorConfig
) && !is_vmr9(filter
))
588 *out
= &filter
->IVMRMonitorConfig_iface
;
589 else if (IsEqualGUID(iid
, &IID_IVMRMonitorConfig9
)
590 && filter
->mode
!= VMR9Mode_Renderless
&& is_vmr9(filter
))
591 *out
= &filter
->IVMRMonitorConfig9_iface
;
592 else if (IsEqualGUID(iid
, &IID_IVMRSurfaceAllocatorNotify
)
593 && filter
->mode
== (VMR9Mode
)VMRMode_Renderless
&& !is_vmr9(filter
))
594 *out
= &filter
->IVMRSurfaceAllocatorNotify_iface
;
595 else if (IsEqualGUID(iid
, &IID_IVMRSurfaceAllocatorNotify9
)
596 && filter
->mode
== VMR9Mode_Renderless
&& is_vmr9(filter
))
597 *out
= &filter
->IVMRSurfaceAllocatorNotify9_iface
;
598 else if (IsEqualGUID(iid
, &IID_IVMRWindowlessControl
)
599 && filter
->mode
== (VMR9Mode
)VMRMode_Windowless
&& !is_vmr9(filter
))
600 *out
= &filter
->IVMRWindowlessControl_iface
;
601 else if (IsEqualGUID(iid
, &IID_IVMRWindowlessControl9
)
602 && filter
->mode
== VMR9Mode_Windowless
&& is_vmr9(filter
))
603 *out
= &filter
->IVMRWindowlessControl9_iface
;
605 return E_NOINTERFACE
;
607 IUnknown_AddRef((IUnknown
*)*out
);
611 static HRESULT
vmr_pin_query_interface(struct strmbase_renderer
*iface
, REFIID iid
, void **out
)
613 struct quartz_vmr
*filter
= impl_from_IBaseFilter(&iface
->filter
.IBaseFilter_iface
);
615 if (IsEqualGUID(iid
, &IID_IAMVideoAccelerator
))
616 *out
= &filter
->IAMVideoAccelerator_iface
;
617 else if (IsEqualGUID(iid
, &IID_IOverlay
))
618 *out
= &filter
->IOverlay_iface
;
620 return E_NOINTERFACE
;
622 IUnknown_AddRef((IUnknown
*)*out
);
626 static const struct strmbase_renderer_ops renderer_ops
=
628 .renderer_query_accept
= vmr_query_accept
,
629 .renderer_render
= vmr_render
,
630 .renderer_init_stream
= vmr_init_stream
,
631 .renderer_start_stream
= vmr_start_stream
,
632 .renderer_stop_stream
= vmr_stop_stream
,
633 .renderer_connect
= vmr_connect
,
634 .renderer_disconnect
= vmr_disconnect
,
635 .renderer_destroy
= vmr_destroy
,
636 .renderer_query_interface
= vmr_query_interface
,
637 .renderer_pin_query_interface
= vmr_pin_query_interface
,
640 static RECT
vmr_get_default_rect(struct video_window
*This
)
642 struct quartz_vmr
*pVMR9
= impl_from_video_window(This
);
645 SetRect(&defRect
, 0, 0, pVMR9
->VideoWidth
, pVMR9
->VideoHeight
);
650 static HRESULT
vmr_get_current_image(struct video_window
*iface
, LONG
*size
, LONG
*image
)
652 struct quartz_vmr
*filter
= impl_from_video_window(iface
);
653 IDirect3DSurface9
*rt
= NULL
, *surface
= NULL
;
654 D3DLOCKED_RECT locked_rect
;
655 IDirect3DDevice9
*device
;
656 unsigned int row_size
;
657 BITMAPINFOHEADER bih
;
662 EnterCriticalSection(&filter
->renderer
.filter
.stream_cs
);
663 device
= filter
->allocator_d3d9_dev
;
665 bih
= *get_bitmap_header(&filter
->renderer
.sink
.pin
.mt
);
666 bih
.biSizeImage
= bih
.biWidth
* bih
.biHeight
* bih
.biBitCount
/ 8;
670 *size
= sizeof(BITMAPINFOHEADER
) + bih
.biSizeImage
;
671 LeaveCriticalSection(&filter
->renderer
.filter
.stream_cs
);
675 if (FAILED(hr
= IDirect3DDevice9_GetRenderTarget(device
, 0, &rt
)))
678 if (FAILED(hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(device
, bih
.biWidth
,
679 bih
.biHeight
, D3DFMT_X8R8G8B8
, D3DPOOL_SYSTEMMEM
, &surface
, NULL
)))
682 if (FAILED(hr
= IDirect3DDevice9_GetRenderTargetData(device
, rt
, surface
)))
685 if (FAILED(hr
= IDirect3DSurface9_LockRect(surface
, &locked_rect
, NULL
, D3DLOCK_READONLY
)))
689 memcpy(image
, &bih
, min(size_left
, sizeof(BITMAPINFOHEADER
)));
690 size_left
-= sizeof(BITMAPINFOHEADER
);
692 dst
= (char *)image
+ sizeof(BITMAPINFOHEADER
);
693 row_size
= bih
.biWidth
* bih
.biBitCount
/ 8;
695 for (i
= 0; i
< bih
.biHeight
&& size_left
> 0; ++i
)
697 memcpy(dst
, (char *)locked_rect
.pBits
+ (i
* locked_rect
.Pitch
), min(row_size
, size_left
));
699 size_left
-= row_size
;
702 IDirect3DSurface9_UnlockRect(surface
);
705 if (surface
) IDirect3DSurface9_Release(surface
);
706 if (rt
) IDirect3DSurface9_Release(rt
);
707 LeaveCriticalSection(&filter
->renderer
.filter
.stream_cs
);
711 static const struct video_window_ops window_ops
=
713 .get_default_rect
= vmr_get_default_rect
,
714 .get_current_image
= vmr_get_current_image
,
717 static const IVideoWindowVtbl IVideoWindow_VTable
=
719 BaseControlWindowImpl_QueryInterface
,
720 BaseControlWindowImpl_AddRef
,
721 BaseControlWindowImpl_Release
,
722 BaseControlWindowImpl_GetTypeInfoCount
,
723 BaseControlWindowImpl_GetTypeInfo
,
724 BaseControlWindowImpl_GetIDsOfNames
,
725 BaseControlWindowImpl_Invoke
,
726 BaseControlWindowImpl_put_Caption
,
727 BaseControlWindowImpl_get_Caption
,
728 BaseControlWindowImpl_put_WindowStyle
,
729 BaseControlWindowImpl_get_WindowStyle
,
730 BaseControlWindowImpl_put_WindowStyleEx
,
731 BaseControlWindowImpl_get_WindowStyleEx
,
732 BaseControlWindowImpl_put_AutoShow
,
733 BaseControlWindowImpl_get_AutoShow
,
734 BaseControlWindowImpl_put_WindowState
,
735 BaseControlWindowImpl_get_WindowState
,
736 BaseControlWindowImpl_put_BackgroundPalette
,
737 BaseControlWindowImpl_get_BackgroundPalette
,
738 BaseControlWindowImpl_put_Visible
,
739 BaseControlWindowImpl_get_Visible
,
740 BaseControlWindowImpl_put_Left
,
741 BaseControlWindowImpl_get_Left
,
742 BaseControlWindowImpl_put_Width
,
743 BaseControlWindowImpl_get_Width
,
744 BaseControlWindowImpl_put_Top
,
745 BaseControlWindowImpl_get_Top
,
746 BaseControlWindowImpl_put_Height
,
747 BaseControlWindowImpl_get_Height
,
748 BaseControlWindowImpl_put_Owner
,
749 BaseControlWindowImpl_get_Owner
,
750 BaseControlWindowImpl_put_MessageDrain
,
751 BaseControlWindowImpl_get_MessageDrain
,
752 BaseControlWindowImpl_get_BorderColor
,
753 BaseControlWindowImpl_put_BorderColor
,
754 BaseControlWindowImpl_get_FullScreenMode
,
755 BaseControlWindowImpl_put_FullScreenMode
,
756 BaseControlWindowImpl_SetWindowForeground
,
757 BaseControlWindowImpl_NotifyOwnerMessage
,
758 BaseControlWindowImpl_SetWindowPosition
,
759 BaseControlWindowImpl_GetWindowPosition
,
760 BaseControlWindowImpl_GetMinIdealImageSize
,
761 BaseControlWindowImpl_GetMaxIdealImageSize
,
762 BaseControlWindowImpl_GetRestorePosition
,
763 BaseControlWindowImpl_HideCursor
,
764 BaseControlWindowImpl_IsCursorHidden
767 static HRESULT WINAPI
AMCertifiedOutputProtection_QueryInterface(IAMCertifiedOutputProtection
*iface
,
768 REFIID riid
, void **ppv
)
770 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
771 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
774 static ULONG WINAPI
AMCertifiedOutputProtection_AddRef(IAMCertifiedOutputProtection
*iface
)
776 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
777 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
780 static ULONG WINAPI
AMCertifiedOutputProtection_Release(IAMCertifiedOutputProtection
*iface
)
782 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
783 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
786 static HRESULT WINAPI
AMCertifiedOutputProtection_KeyExchange(IAMCertifiedOutputProtection
*iface
,
787 GUID
* pRandom
, BYTE
** VarLenCertGH
,
788 DWORD
* pdwLengthCertGH
)
790 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
792 FIXME("(%p/%p)->(%p, %p, %p) stub\n", iface
, This
, pRandom
, VarLenCertGH
, pdwLengthCertGH
);
793 return VFW_E_NO_COPP_HW
;
796 static HRESULT WINAPI
AMCertifiedOutputProtection_SessionSequenceStart(IAMCertifiedOutputProtection
*iface
,
797 AMCOPPSignature
* pSig
)
799 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
801 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pSig
);
802 return VFW_E_NO_COPP_HW
;
805 static HRESULT WINAPI
AMCertifiedOutputProtection_ProtectionCommand(IAMCertifiedOutputProtection
*iface
,
806 const AMCOPPCommand
* cmd
)
808 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
810 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, cmd
);
811 return VFW_E_NO_COPP_HW
;
814 static HRESULT WINAPI
AMCertifiedOutputProtection_ProtectionStatus(IAMCertifiedOutputProtection
*iface
,
815 const AMCOPPStatusInput
* pStatusInput
,
816 AMCOPPStatusOutput
* pStatusOutput
)
818 struct quartz_vmr
*This
= impl_from_IAMCertifiedOutputProtection(iface
);
820 FIXME("(%p/%p)->(%p, %p) stub\n", iface
, This
, pStatusInput
, pStatusOutput
);
821 return VFW_E_NO_COPP_HW
;
824 static const IAMCertifiedOutputProtectionVtbl IAMCertifiedOutputProtection_Vtbl
=
826 AMCertifiedOutputProtection_QueryInterface
,
827 AMCertifiedOutputProtection_AddRef
,
828 AMCertifiedOutputProtection_Release
,
829 AMCertifiedOutputProtection_KeyExchange
,
830 AMCertifiedOutputProtection_SessionSequenceStart
,
831 AMCertifiedOutputProtection_ProtectionCommand
,
832 AMCertifiedOutputProtection_ProtectionStatus
835 static HRESULT WINAPI
AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags
*iface
, REFIID riid
, void **ppv
) {
836 struct quartz_vmr
*This
= impl_from_IAMFilterMiscFlags(iface
);
837 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
840 static ULONG WINAPI
AMFilterMiscFlags_AddRef(IAMFilterMiscFlags
*iface
) {
841 struct quartz_vmr
*This
= impl_from_IAMFilterMiscFlags(iface
);
842 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
845 static ULONG WINAPI
AMFilterMiscFlags_Release(IAMFilterMiscFlags
*iface
) {
846 struct quartz_vmr
*This
= impl_from_IAMFilterMiscFlags(iface
);
847 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
850 static ULONG WINAPI
AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags
*iface
) {
851 return AM_FILTER_MISC_FLAGS_IS_RENDERER
;
854 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl
= {
855 AMFilterMiscFlags_QueryInterface
,
856 AMFilterMiscFlags_AddRef
,
857 AMFilterMiscFlags_Release
,
858 AMFilterMiscFlags_GetMiscFlags
861 static HRESULT WINAPI
VMR7FilterConfig_QueryInterface(IVMRFilterConfig
*iface
, REFIID riid
,
864 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
865 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
868 static ULONG WINAPI
VMR7FilterConfig_AddRef(IVMRFilterConfig
*iface
)
870 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
871 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
874 static ULONG WINAPI
VMR7FilterConfig_Release(IVMRFilterConfig
*iface
)
876 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
877 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
880 static HRESULT WINAPI
VMR7FilterConfig_SetImageCompositor(IVMRFilterConfig
*iface
,
881 IVMRImageCompositor
*compositor
)
883 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
885 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, compositor
);
889 static HRESULT WINAPI
VMR7FilterConfig_SetNumberOfStreams(IVMRFilterConfig
*iface
, DWORD count
)
891 struct quartz_vmr
*filter
= impl_from_IVMRFilterConfig(iface
);
893 FIXME("filter %p, count %lu, stub!\n", filter
, count
);
898 static HRESULT WINAPI
VMR7FilterConfig_GetNumberOfStreams(IVMRFilterConfig
*iface
, DWORD
*max
)
900 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
902 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, max
);
906 static HRESULT WINAPI
VMR7FilterConfig_SetRenderingPrefs(IVMRFilterConfig
*iface
, DWORD flags
)
908 struct quartz_vmr
*filter
= impl_from_IVMRFilterConfig(iface
);
910 FIXME("filter %p, flags %#lx, stub!\n", filter
, flags
);
915 static HRESULT WINAPI
VMR7FilterConfig_GetRenderingPrefs(IVMRFilterConfig
*iface
, DWORD
*renderflags
)
917 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
919 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, renderflags
);
923 static HRESULT WINAPI
VMR7FilterConfig_SetRenderingMode(IVMRFilterConfig
*iface
, DWORD mode
)
925 struct quartz_vmr
*filter
= impl_from_IVMRFilterConfig(iface
);
927 TRACE("iface %p, mode %#lx.\n", iface
, mode
);
929 return IVMRFilterConfig9_SetRenderingMode(&filter
->IVMRFilterConfig9_iface
, mode
);
932 static HRESULT WINAPI
VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig
*iface
, DWORD
*mode
)
934 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig(iface
);
936 TRACE("(%p/%p)->(%p)\n", iface
, This
, mode
);
937 if (!mode
) return E_POINTER
;
942 *mode
= VMRMode_Windowed
;
947 static const IVMRFilterConfigVtbl VMR7_FilterConfig_Vtbl
=
949 VMR7FilterConfig_QueryInterface
,
950 VMR7FilterConfig_AddRef
,
951 VMR7FilterConfig_Release
,
952 VMR7FilterConfig_SetImageCompositor
,
953 VMR7FilterConfig_SetNumberOfStreams
,
954 VMR7FilterConfig_GetNumberOfStreams
,
955 VMR7FilterConfig_SetRenderingPrefs
,
956 VMR7FilterConfig_GetRenderingPrefs
,
957 VMR7FilterConfig_SetRenderingMode
,
958 VMR7FilterConfig_GetRenderingMode
961 struct get_available_monitors_args
963 VMRMONITORINFO
*info7
;
964 VMR9MonitorInfo
*info9
;
969 static BOOL CALLBACK
get_available_monitors_proc(HMONITOR hmon
, HDC hdc
, LPRECT lprc
, LPARAM lparam
)
971 struct get_available_monitors_args
*args
= (struct get_available_monitors_args
*)lparam
;
974 if (args
->info7
|| args
->info9
)
977 if (!args
->arraysize
)
980 mi
.cbSize
= sizeof(mi
);
981 if (!GetMonitorInfoW(hmon
, (MONITORINFO
*)&mi
))
984 /* fill VMRMONITORINFO struct */
987 VMRMONITORINFO
*info
= args
->info7
++;
988 memset(info
, 0, sizeof(*info
));
990 if (args
->numdev
> 0)
992 info
->guid
.pGUID
= &info
->guid
.GUID
;
993 info
->guid
.GUID
.Data4
[7] = args
->numdev
;
996 info
->guid
.pGUID
= NULL
;
998 info
->rcMonitor
= mi
.rcMonitor
;
1000 info
->dwFlags
= mi
.dwFlags
;
1002 lstrcpynW(info
->szDevice
, mi
.szDevice
, ARRAY_SIZE(info
->szDevice
));
1004 /* FIXME: how to get these values? */
1005 info
->szDescription
[0] = 0;
1008 /* fill VMR9MonitorInfo struct */
1011 VMR9MonitorInfo
*info
= args
->info9
++;
1012 memset(info
, 0, sizeof(*info
));
1014 info
->uDevID
= 0; /* FIXME */
1015 info
->rcMonitor
= mi
.rcMonitor
;
1017 info
->dwFlags
= mi
.dwFlags
;
1019 lstrcpynW(info
->szDevice
, mi
.szDevice
, ARRAY_SIZE(info
->szDevice
));
1021 /* FIXME: how to get these values? */
1022 info
->szDescription
[0] = 0;
1023 info
->dwVendorId
= 0;
1024 info
->dwDeviceId
= 0;
1025 info
->dwSubSysId
= 0;
1026 info
->dwRevision
= 0;
1036 static HRESULT WINAPI
VMR7MonitorConfig_QueryInterface(IVMRMonitorConfig
*iface
, REFIID riid
,
1039 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1040 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1043 static ULONG WINAPI
VMR7MonitorConfig_AddRef(IVMRMonitorConfig
*iface
)
1045 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1046 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1049 static ULONG WINAPI
VMR7MonitorConfig_Release(IVMRMonitorConfig
*iface
)
1051 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1052 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1055 static HRESULT WINAPI
VMR7MonitorConfig_SetMonitor(IVMRMonitorConfig
*iface
, const VMRGUID
*pGUID
)
1057 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1059 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1067 static HRESULT WINAPI
VMR7MonitorConfig_GetMonitor(IVMRMonitorConfig
*iface
, VMRGUID
*pGUID
)
1069 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1071 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1076 pGUID
->pGUID
= NULL
; /* default DirectDraw device */
1080 static HRESULT WINAPI
VMR7MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig
*iface
,
1081 const VMRGUID
*pGUID
)
1083 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1085 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1093 static HRESULT WINAPI
VMR7MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig
*iface
, VMRGUID
*pGUID
)
1095 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1097 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, pGUID
);
1102 pGUID
->pGUID
= NULL
; /* default DirectDraw device */
1106 static HRESULT WINAPI
VMR7MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig
*iface
,
1107 VMRMONITORINFO
*info
, DWORD arraysize
,
1110 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig(iface
);
1111 struct get_available_monitors_args args
;
1113 TRACE("filter %p, info %p, arraysize %lu, numdev %p.\n", This
, info
, arraysize
, numdev
);
1118 if (info
&& arraysize
== 0)
1119 return E_INVALIDARG
;
1123 args
.arraysize
= arraysize
;
1125 EnumDisplayMonitors(NULL
, NULL
, get_available_monitors_proc
, (LPARAM
)&args
);
1127 *numdev
= args
.numdev
;
1131 static const IVMRMonitorConfigVtbl VMR7_MonitorConfig_Vtbl
=
1133 VMR7MonitorConfig_QueryInterface
,
1134 VMR7MonitorConfig_AddRef
,
1135 VMR7MonitorConfig_Release
,
1136 VMR7MonitorConfig_SetMonitor
,
1137 VMR7MonitorConfig_GetMonitor
,
1138 VMR7MonitorConfig_SetDefaultMonitor
,
1139 VMR7MonitorConfig_GetDefaultMonitor
,
1140 VMR7MonitorConfig_GetAvailableMonitors
1143 static HRESULT WINAPI
VMR9MonitorConfig_QueryInterface(IVMRMonitorConfig9
*iface
, REFIID riid
,
1146 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1147 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1150 static ULONG WINAPI
VMR9MonitorConfig_AddRef(IVMRMonitorConfig9
*iface
)
1152 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1153 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1156 static ULONG WINAPI
VMR9MonitorConfig_Release(IVMRMonitorConfig9
*iface
)
1158 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1159 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1162 static HRESULT WINAPI
VMR9MonitorConfig_SetMonitor(IVMRMonitorConfig9
*iface
, UINT uDev
)
1164 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1166 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, uDev
);
1171 static HRESULT WINAPI
VMR9MonitorConfig_GetMonitor(IVMRMonitorConfig9
*iface
, UINT
*uDev
)
1173 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1175 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, uDev
);
1184 static HRESULT WINAPI
VMR9MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig9
*iface
, UINT uDev
)
1186 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1188 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, uDev
);
1193 static HRESULT WINAPI
VMR9MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig9
*iface
, UINT
*uDev
)
1195 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1197 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, uDev
);
1206 static HRESULT WINAPI
VMR9MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig9
*iface
,
1207 VMR9MonitorInfo
*info
, DWORD arraysize
,
1210 struct quartz_vmr
*This
= impl_from_IVMRMonitorConfig9(iface
);
1211 struct get_available_monitors_args args
;
1213 TRACE("filter %p, info %p, arraysize %lu, numdev %p.\n", This
, info
, arraysize
, numdev
);
1218 if (info
&& arraysize
== 0)
1219 return E_INVALIDARG
;
1223 args
.arraysize
= arraysize
;
1225 EnumDisplayMonitors(NULL
, NULL
, get_available_monitors_proc
, (LPARAM
)&args
);
1227 *numdev
= args
.numdev
;
1231 static const IVMRMonitorConfig9Vtbl VMR9_MonitorConfig_Vtbl
=
1233 VMR9MonitorConfig_QueryInterface
,
1234 VMR9MonitorConfig_AddRef
,
1235 VMR9MonitorConfig_Release
,
1236 VMR9MonitorConfig_SetMonitor
,
1237 VMR9MonitorConfig_GetMonitor
,
1238 VMR9MonitorConfig_SetDefaultMonitor
,
1239 VMR9MonitorConfig_GetDefaultMonitor
,
1240 VMR9MonitorConfig_GetAvailableMonitors
1243 static HRESULT WINAPI
VMR9FilterConfig_QueryInterface(IVMRFilterConfig9
*iface
, REFIID riid
, LPVOID
* ppv
)
1245 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1246 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1249 static ULONG WINAPI
VMR9FilterConfig_AddRef(IVMRFilterConfig9
*iface
)
1251 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1252 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1255 static ULONG WINAPI
VMR9FilterConfig_Release(IVMRFilterConfig9
*iface
)
1257 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1258 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1261 static HRESULT WINAPI
VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9
*iface
, IVMRImageCompositor9
*compositor
)
1263 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1265 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, compositor
);
1269 static HRESULT WINAPI
VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9
*iface
, DWORD count
)
1271 struct quartz_vmr
*filter
= impl_from_IVMRFilterConfig9(iface
);
1273 FIXME("iface %p, count %lu, stub!\n", iface
, count
);
1277 WARN("Application requested zero streams; returning E_INVALIDARG.\n");
1278 return E_INVALIDARG
;
1281 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1283 if (filter
->stream_count
)
1285 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1286 WARN("Stream count is already set; returning VFW_E_WRONG_STATE.\n");
1287 return VFW_E_WRONG_STATE
;
1290 filter
->stream_count
= count
;
1292 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1296 static HRESULT WINAPI
VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9
*iface
, DWORD
*count
)
1298 struct quartz_vmr
*filter
= impl_from_IVMRFilterConfig9(iface
);
1300 TRACE("filter %p, count %p.\n", filter
, count
);
1302 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1304 if (!filter
->stream_count
)
1306 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1307 return VFW_E_VMR_NOT_IN_MIXER_MODE
;
1310 *count
= filter
->stream_count
;
1312 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1316 static HRESULT WINAPI
VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9
*iface
, DWORD flags
)
1318 struct quartz_vmr
*filter
= impl_from_IVMRFilterConfig9(iface
);
1320 TRACE("filter %p, flags %#lx.\n", filter
, flags
);
1325 static HRESULT WINAPI
VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9
*iface
, DWORD
*renderflags
)
1327 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1329 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, renderflags
);
1333 static HRESULT WINAPI
VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9
*iface
, DWORD mode
)
1336 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1338 TRACE("filter %p, mode %lu.\n", This
, mode
);
1340 EnterCriticalSection(&This
->renderer
.filter
.filter_cs
);
1343 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1344 return VFW_E_WRONG_STATE
;
1347 if (This
->allocator
)
1348 IVMRSurfaceAllocator9_Release(This
->allocator
);
1349 if (This
->presenter
)
1350 IVMRImagePresenter9_Release(This
->presenter
);
1352 This
->allocator
= NULL
;
1353 This
->presenter
= NULL
;
1357 case VMR9Mode_Windowed
:
1358 case VMR9Mode_Windowless
:
1361 if (FAILED(hr
= VMR9DefaultAllocatorPresenterImpl_create(This
, (void **)&This
->presenter
)))
1363 ERR("Failed to create default presenter, hr %#lx.\n", hr
);
1367 if (FAILED(hr
= IVMRImagePresenter9_QueryInterface(This
->presenter
,
1368 &IID_IVMRSurfaceAllocator9
, (void **)&This
->allocator
)))
1370 ERR("Failed to query for IVMRSurfaceAllocator9, hr %#lx.\n", hr
);
1371 IVMRImagePresenter9_Release(This
->presenter
);
1372 This
->allocator
= NULL
;
1373 This
->presenter
= NULL
;
1377 hr
= IVMRSurfaceAllocator9_AdviseNotify(This
->allocator
, &This
->IVMRSurfaceAllocatorNotify9_iface
);
1379 case VMR9Mode_Renderless
:
1382 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1383 return E_INVALIDARG
;
1386 if (mode
!= VMR9Mode_Windowed
)
1387 video_window_cleanup(&This
->window
);
1390 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1394 static HRESULT WINAPI
VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9
*iface
, DWORD
*mode
)
1396 struct quartz_vmr
*This
= impl_from_IVMRFilterConfig9(iface
);
1398 TRACE("(%p/%p)->(%p)\n", iface
, This
, mode
);
1405 *mode
= VMR9Mode_Windowed
;
1410 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl
=
1412 VMR9FilterConfig_QueryInterface
,
1413 VMR9FilterConfig_AddRef
,
1414 VMR9FilterConfig_Release
,
1415 VMR9FilterConfig_SetImageCompositor
,
1416 VMR9FilterConfig_SetNumberOfStreams
,
1417 VMR9FilterConfig_GetNumberOfStreams
,
1418 VMR9FilterConfig_SetRenderingPrefs
,
1419 VMR9FilterConfig_GetRenderingPrefs
,
1420 VMR9FilterConfig_SetRenderingMode
,
1421 VMR9FilterConfig_GetRenderingMode
1424 static HRESULT WINAPI
VMR7WindowlessControl_QueryInterface(IVMRWindowlessControl
*iface
, REFIID riid
,
1427 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1428 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1431 static ULONG WINAPI
VMR7WindowlessControl_AddRef(IVMRWindowlessControl
*iface
)
1433 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1434 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1437 static ULONG WINAPI
VMR7WindowlessControl_Release(IVMRWindowlessControl
*iface
)
1439 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1440 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1443 static HRESULT WINAPI
VMR7WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl
*iface
,
1444 LONG
*width
, LONG
*height
, LONG
*aspect_width
, LONG
*aspect_height
)
1446 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl(iface
);
1448 TRACE("filter %p, width %p, height %p, aspect_width %p, aspect_height %p.\n",
1449 filter
, width
, height
, aspect_width
, aspect_height
);
1451 if (!width
|| !height
)
1454 *width
= filter
->bmiheader
.biWidth
;
1455 *height
= filter
->bmiheader
.biHeight
;
1457 *aspect_width
= filter
->bmiheader
.biWidth
;
1459 *aspect_height
= filter
->bmiheader
.biHeight
;
1464 static HRESULT WINAPI
VMR7WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl
*iface
,
1465 LONG
*width
, LONG
*height
)
1467 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1469 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1473 static HRESULT WINAPI
VMR7WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl
*iface
,
1474 LONG
*width
, LONG
*height
)
1476 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1478 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1482 static HRESULT WINAPI
VMR7WindowlessControl_SetVideoPosition(IVMRWindowlessControl
*iface
,
1483 const RECT
*source
, const RECT
*dest
)
1485 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1487 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, source
, dest
);
1489 EnterCriticalSection(&This
->renderer
.filter
.filter_cs
);
1492 This
->window
.src
= *source
;
1494 This
->window
.dst
= *dest
;
1496 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1501 static HRESULT WINAPI
VMR7WindowlessControl_GetVideoPosition(IVMRWindowlessControl
*iface
,
1502 RECT
*source
, RECT
*dest
)
1504 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1507 *source
= This
->window
.src
;
1510 *dest
= This
->window
.dst
;
1512 FIXME("(%p/%p)->(%p/%p) stub\n", iface
, This
, source
, dest
);
1516 static HRESULT WINAPI
VMR7WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl
*iface
,
1519 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1521 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1525 static HRESULT WINAPI
VMR7WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl
*iface
,
1528 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1530 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1534 static HRESULT WINAPI
VMR7WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl
*iface
, HWND window
)
1536 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl(iface
);
1538 TRACE("iface %p, window %p.\n", iface
, window
);
1540 return IVMRWindowlessControl9_SetVideoClippingWindow(&filter
->IVMRWindowlessControl9_iface
, window
);
1543 static HRESULT WINAPI
VMR7WindowlessControl_RepaintVideo(IVMRWindowlessControl
*iface
,
1546 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1548 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1552 static HRESULT WINAPI
VMR7WindowlessControl_DisplayModeChanged(IVMRWindowlessControl
*iface
)
1554 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1556 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1560 static HRESULT WINAPI
VMR7WindowlessControl_GetCurrentImage(IVMRWindowlessControl
*iface
,
1563 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1565 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1569 static HRESULT WINAPI
VMR7WindowlessControl_SetBorderColor(IVMRWindowlessControl
*iface
,
1572 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1574 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1578 static HRESULT WINAPI
VMR7WindowlessControl_GetBorderColor(IVMRWindowlessControl
*iface
,
1581 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1583 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1587 static HRESULT WINAPI
VMR7WindowlessControl_SetColorKey(IVMRWindowlessControl
*iface
, COLORREF color
)
1589 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1591 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1595 static HRESULT WINAPI
VMR7WindowlessControl_GetColorKey(IVMRWindowlessControl
*iface
, COLORREF
*color
)
1597 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl(iface
);
1599 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1603 static const IVMRWindowlessControlVtbl VMR7_WindowlessControl_Vtbl
=
1605 VMR7WindowlessControl_QueryInterface
,
1606 VMR7WindowlessControl_AddRef
,
1607 VMR7WindowlessControl_Release
,
1608 VMR7WindowlessControl_GetNativeVideoSize
,
1609 VMR7WindowlessControl_GetMinIdealVideoSize
,
1610 VMR7WindowlessControl_GetMaxIdealVideoSize
,
1611 VMR7WindowlessControl_SetVideoPosition
,
1612 VMR7WindowlessControl_GetVideoPosition
,
1613 VMR7WindowlessControl_GetAspectRatioMode
,
1614 VMR7WindowlessControl_SetAspectRatioMode
,
1615 VMR7WindowlessControl_SetVideoClippingWindow
,
1616 VMR7WindowlessControl_RepaintVideo
,
1617 VMR7WindowlessControl_DisplayModeChanged
,
1618 VMR7WindowlessControl_GetCurrentImage
,
1619 VMR7WindowlessControl_SetBorderColor
,
1620 VMR7WindowlessControl_GetBorderColor
,
1621 VMR7WindowlessControl_SetColorKey
,
1622 VMR7WindowlessControl_GetColorKey
1625 static HRESULT WINAPI
VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9
*iface
, REFIID riid
, LPVOID
* ppv
)
1627 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1628 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1631 static ULONG WINAPI
VMR9WindowlessControl_AddRef(IVMRWindowlessControl9
*iface
)
1633 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1634 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1637 static ULONG WINAPI
VMR9WindowlessControl_Release(IVMRWindowlessControl9
*iface
)
1639 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1640 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1643 static HRESULT WINAPI
VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9
*iface
,
1644 LONG
*width
, LONG
*height
, LONG
*aspect_width
, LONG
*aspect_height
)
1646 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1648 TRACE("filter %p, width %p, height %p, aspect_width %p, aspect_height %p.\n",
1649 filter
, width
, height
, aspect_width
, aspect_height
);
1651 if (!width
|| !height
)
1654 *width
= filter
->bmiheader
.biWidth
;
1655 *height
= filter
->bmiheader
.biHeight
;
1657 *aspect_width
= filter
->bmiheader
.biWidth
;
1659 *aspect_height
= filter
->bmiheader
.biHeight
;
1664 static HRESULT WINAPI
VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9
*iface
, LONG
*width
, LONG
*height
)
1666 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1668 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1672 static HRESULT WINAPI
VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9
*iface
, LONG
*width
, LONG
*height
)
1674 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1676 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1680 static HRESULT WINAPI
VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9
*iface
,
1681 const RECT
*src
, const RECT
*dst
)
1683 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1685 TRACE("filter %p, src %s, dst %s.\n", filter
, wine_dbgstr_rect(src
), wine_dbgstr_rect(dst
));
1687 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1690 filter
->window
.src
= *src
;
1692 filter
->window
.dst
= *dst
;
1694 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1699 static HRESULT WINAPI
VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9
*iface
, RECT
*src
, RECT
*dst
)
1701 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1703 TRACE("filter %p, src %p, dst %p.\n", filter
, src
, dst
);
1706 *src
= filter
->window
.src
;
1709 *dst
= filter
->window
.dst
;
1714 static HRESULT WINAPI
VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9
*iface
, DWORD
*mode
)
1716 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1718 TRACE("filter %p, mode %p.\n", filter
, mode
);
1720 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1721 *mode
= filter
->aspect_mode
;
1722 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1726 static HRESULT WINAPI
VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9
*iface
, DWORD mode
)
1728 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1730 TRACE("filter %p, mode %lu.\n", filter
, mode
);
1732 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1733 filter
->aspect_mode
= mode
;
1734 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1738 static HRESULT WINAPI
VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9
*iface
, HWND window
)
1740 struct quartz_vmr
*filter
= impl_from_IVMRWindowlessControl9(iface
);
1743 TRACE("filter %p, window %p.\n", filter
, window
);
1745 if (!IsWindow(window
))
1747 WARN("Invalid window %p, returning E_INVALIDARG.\n", window
);
1748 return E_INVALIDARG
;
1751 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1753 if (filter
->renderer
.sink
.pin
.peer
)
1755 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1756 WARN("Attempt to set the clipping window while connected; returning VFW_E_WRONG_STATE.\n");
1757 return VFW_E_WRONG_STATE
;
1760 filter
->clipping_window
= window
;
1762 hr
= IVMRFilterConfig9_SetNumberOfStreams(&filter
->IVMRFilterConfig9_iface
, 4);
1764 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1768 static HRESULT WINAPI
VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9
*iface
, HWND hwnd
, HDC hdc
)
1770 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1773 FIXME("(%p/%p)->(...) semi-stub\n", iface
, This
);
1775 EnterCriticalSection(&This
->renderer
.filter
.filter_cs
);
1776 if (hwnd
!= This
->clipping_window
)
1778 ERR("Not handling changing windows yet!!!\n");
1779 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1783 if (!This
->allocator_d3d9_dev
)
1785 ERR("No d3d9 device!\n");
1786 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1787 return VFW_E_WRONG_STATE
;
1790 /* Windowless extension */
1791 hr
= IDirect3DDevice9_Present(This
->allocator_d3d9_dev
, NULL
, NULL
, NULL
, NULL
);
1792 LeaveCriticalSection(&This
->renderer
.filter
.filter_cs
);
1797 static HRESULT WINAPI
VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9
*iface
)
1799 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1801 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1805 static HRESULT WINAPI
VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9
*iface
, BYTE
**dib
)
1807 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1809 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1813 static HRESULT WINAPI
VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9
*iface
, COLORREF color
)
1815 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1817 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1821 static HRESULT WINAPI
VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9
*iface
, COLORREF
*color
)
1823 struct quartz_vmr
*This
= impl_from_IVMRWindowlessControl9(iface
);
1825 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1829 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl
=
1831 VMR9WindowlessControl_QueryInterface
,
1832 VMR9WindowlessControl_AddRef
,
1833 VMR9WindowlessControl_Release
,
1834 VMR9WindowlessControl_GetNativeVideoSize
,
1835 VMR9WindowlessControl_GetMinIdealVideoSize
,
1836 VMR9WindowlessControl_GetMaxIdealVideoSize
,
1837 VMR9WindowlessControl_SetVideoPosition
,
1838 VMR9WindowlessControl_GetVideoPosition
,
1839 VMR9WindowlessControl_GetAspectRatioMode
,
1840 VMR9WindowlessControl_SetAspectRatioMode
,
1841 VMR9WindowlessControl_SetVideoClippingWindow
,
1842 VMR9WindowlessControl_RepaintVideo
,
1843 VMR9WindowlessControl_DisplayModeChanged
,
1844 VMR9WindowlessControl_GetCurrentImage
,
1845 VMR9WindowlessControl_SetBorderColor
,
1846 VMR9WindowlessControl_GetBorderColor
1849 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify
*iface
,
1850 REFIID riid
, LPVOID
* ppv
)
1852 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1853 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1856 static ULONG WINAPI
VMR7SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify
*iface
)
1858 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1859 return IUnknown_AddRef(This
->renderer
.filter
.outer_unk
);
1862 static ULONG WINAPI
VMR7SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify
*iface
)
1864 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1865 return IUnknown_Release(This
->renderer
.filter
.outer_unk
);
1868 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify
*iface
,
1870 IVMRSurfaceAllocator
*alloc
)
1872 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1874 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1878 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_SetDDrawDevice(IVMRSurfaceAllocatorNotify
*iface
,
1879 IDirectDraw7
*device
, HMONITOR monitor
)
1881 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1883 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1887 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_ChangeDDrawDevice(IVMRSurfaceAllocatorNotify
*iface
,
1888 IDirectDraw7
*device
, HMONITOR monitor
)
1890 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1892 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1896 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces(IVMRSurfaceAllocatorNotify
*iface
)
1898 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1900 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1904 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify
*iface
, LONG code
,
1905 LONG_PTR param1
, LONG_PTR param2
)
1907 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1909 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1913 static HRESULT WINAPI
VMR7SurfaceAllocatorNotify_SetBorderColor(IVMRSurfaceAllocatorNotify
*iface
,
1916 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify(iface
);
1918 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1922 static const IVMRSurfaceAllocatorNotifyVtbl VMR7_SurfaceAllocatorNotify_Vtbl
=
1924 VMR7SurfaceAllocatorNotify_QueryInterface
,
1925 VMR7SurfaceAllocatorNotify_AddRef
,
1926 VMR7SurfaceAllocatorNotify_Release
,
1927 VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator
,
1928 VMR7SurfaceAllocatorNotify_SetDDrawDevice
,
1929 VMR7SurfaceAllocatorNotify_ChangeDDrawDevice
,
1930 VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces
,
1931 VMR7SurfaceAllocatorNotify_NotifyEvent
,
1932 VMR7SurfaceAllocatorNotify_SetBorderColor
1935 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9
*iface
, REFIID riid
, LPVOID
* ppv
)
1937 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1938 return IUnknown_QueryInterface(This
->renderer
.filter
.outer_unk
, riid
, ppv
);
1941 static ULONG WINAPI
VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9
*iface
)
1943 struct quartz_vmr
*filter
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1944 ULONG refcount
= InterlockedIncrement(&filter
->IVMRSurfaceAllocatorNotify9_refcount
);
1946 TRACE("%p increasing refcount to %lu.\n", iface
, refcount
);
1951 static ULONG WINAPI
VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9
*iface
)
1953 struct quartz_vmr
*filter
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1954 ULONG refcount
= InterlockedDecrement(&filter
->IVMRSurfaceAllocatorNotify9_refcount
);
1956 TRACE("%p decreasing refcount to %lu.\n", iface
, refcount
);
1958 if (!refcount
&& !filter
->renderer
.filter
.refcount
)
1964 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(
1965 IVMRSurfaceAllocatorNotify9
*iface
, DWORD_PTR cookie
, IVMRSurfaceAllocator9
*allocator
)
1967 struct quartz_vmr
*filter
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1968 IVMRImagePresenter9
*presenter
;
1970 TRACE("filter %p, cookie %#Ix, allocator %p.\n", filter
, cookie
, allocator
);
1972 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1974 filter
->cookie
= cookie
;
1976 if (filter
->renderer
.sink
.pin
.peer
)
1978 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1979 WARN("Attempt to set allocator while connected; returning VFW_E_WRONG_STATE.\n");
1980 return VFW_E_WRONG_STATE
;
1983 if (FAILED(IVMRSurfaceAllocator9_QueryInterface(allocator
, &IID_IVMRImagePresenter9
, (void **)&presenter
)))
1985 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
1986 return E_NOINTERFACE
;
1989 if (filter
->allocator
)
1991 IVMRImagePresenter9_Release(filter
->presenter
);
1992 IVMRSurfaceAllocator9_Release(filter
->allocator
);
1994 filter
->allocator
= allocator
;
1995 filter
->presenter
= presenter
;
1996 IVMRSurfaceAllocator9_AddRef(allocator
);
1998 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2002 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9
*iface
,
2003 IDirect3DDevice9
*device
, HMONITOR monitor
)
2005 struct quartz_vmr
*filter
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
2007 TRACE("filter %p, device %p, monitor %p.\n", filter
, device
, monitor
);
2009 if (filter
->allocator_d3d9_dev
)
2010 IDirect3DDevice9_Release(filter
->allocator_d3d9_dev
);
2011 filter
->allocator_d3d9_dev
= device
;
2012 IDirect3DDevice9_AddRef(device
);
2017 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9
*iface
, IDirect3DDevice9
*device
, HMONITOR monitor
)
2019 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
2021 FIXME("(%p/%p)->(...) semi-stub\n", iface
, This
);
2022 if (This
->allocator_d3d9_dev
)
2023 IDirect3DDevice9_Release(This
->allocator_d3d9_dev
);
2024 This
->allocator_d3d9_dev
= device
;
2025 IDirect3DDevice9_AddRef(This
->allocator_d3d9_dev
);
2030 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9
*iface
, VMR9AllocationInfo
*allocinfo
, DWORD
*numbuffers
, IDirect3DSurface9
**surface
)
2032 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
2036 TRACE("filter %p, allocinfo %p, numbuffers %p, surface %p.\n", This
, numbuffers
, allocinfo
, surface
);
2038 if (!allocinfo
|| !numbuffers
|| !surface
)
2041 TRACE("Flags %#lx, size %lux%lu, format %u (%#x), pool %u, minimum buffers %lu.\n",
2042 allocinfo
->dwFlags
, allocinfo
->dwWidth
, allocinfo
->dwHeight
,
2043 allocinfo
->Format
, allocinfo
->Format
, allocinfo
->Pool
, allocinfo
->MinBuffers
);
2045 if ((allocinfo
->dwFlags
& VMR9AllocFlag_TextureSurface
)
2046 && (allocinfo
->dwFlags
& VMR9AllocFlag_OffscreenSurface
))
2048 WARN("Invalid flags specified; returning E_INVALIDARG.\n");
2049 return E_INVALIDARG
;
2052 if (!allocinfo
->Format
)
2054 IDirect3DSurface9
*backbuffer
;
2055 D3DSURFACE_DESC desc
;
2057 IDirect3DDevice9_GetBackBuffer(This
->allocator_d3d9_dev
, 0, 0,
2058 D3DBACKBUFFER_TYPE_MONO
, &backbuffer
);
2059 IDirect3DSurface9_GetDesc(backbuffer
, &desc
);
2060 IDirect3DSurface9_Release(backbuffer
);
2061 allocinfo
->Format
= desc
.Format
;
2064 if (!*numbuffers
|| *numbuffers
< allocinfo
->MinBuffers
)
2066 WARN("%lu surfaces requested (minimum %lu); returning E_INVALIDARG.\n",
2067 *numbuffers
, allocinfo
->MinBuffers
);
2068 return E_INVALIDARG
;
2071 if (!This
->allocator_d3d9_dev
)
2073 WARN("No Direct3D device; returning VFW_E_WRONG_STATE.\n");
2074 return VFW_E_WRONG_STATE
;
2077 if (allocinfo
->dwFlags
== VMR9AllocFlag_OffscreenSurface
)
2079 for (i
= 0; i
< *numbuffers
; ++i
)
2081 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(This
->allocator_d3d9_dev
, allocinfo
->dwWidth
, allocinfo
->dwHeight
,
2082 allocinfo
->Format
, allocinfo
->Pool
, &surface
[i
], NULL
);
2087 else if (allocinfo
->dwFlags
== VMR9AllocFlag_TextureSurface
)
2089 for (i
= 0; i
< *numbuffers
; ++i
)
2091 IDirect3DTexture9
*texture
;
2093 hr
= IDirect3DDevice9_CreateTexture(This
->allocator_d3d9_dev
, allocinfo
->dwWidth
, allocinfo
->dwHeight
, 1, D3DUSAGE_DYNAMIC
,
2094 allocinfo
->Format
, allocinfo
->Pool
, &texture
, NULL
);
2097 IDirect3DTexture9_GetSurfaceLevel(texture
, 0, &surface
[i
]);
2098 IDirect3DTexture9_Release(texture
);
2101 else if (allocinfo
->dwFlags
== VMR9AllocFlag_3DRenderTarget
)
2103 for (i
= 0; i
< *numbuffers
; ++i
)
2105 if (FAILED(hr
= IDirect3DDevice9_CreateRenderTarget(This
->allocator_d3d9_dev
,
2106 allocinfo
->dwWidth
, allocinfo
->dwHeight
, allocinfo
->Format
,
2107 D3DMULTISAMPLE_NONE
, 0, FALSE
, &surface
[i
], NULL
)))
2113 FIXME("Unhandled flags %#lx.\n", allocinfo
->dwFlags
);
2118 WARN("%lu/%lu surfaces allocated, hr %#lx.\n", i
, *numbuffers
, hr
);
2120 if (i
>= allocinfo
->MinBuffers
)
2127 for ( ; i
> 0; --i
) IDirect3DSurface9_Release(surface
[i
- 1]);
2133 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9
*iface
, LONG code
, LONG_PTR param1
, LONG_PTR param2
)
2135 struct quartz_vmr
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
2137 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
2141 static const IVMRSurfaceAllocatorNotify9Vtbl VMR9_SurfaceAllocatorNotify_Vtbl
=
2143 VMR9SurfaceAllocatorNotify_QueryInterface
,
2144 VMR9SurfaceAllocatorNotify_AddRef
,
2145 VMR9SurfaceAllocatorNotify_Release
,
2146 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator
,
2147 VMR9SurfaceAllocatorNotify_SetD3DDevice
,
2148 VMR9SurfaceAllocatorNotify_ChangeD3DDevice
,
2149 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper
,
2150 VMR9SurfaceAllocatorNotify_NotifyEvent
2153 static inline struct quartz_vmr
*impl_from_IVMRMixerControl9(IVMRMixerControl9
*iface
)
2155 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRMixerControl9_iface
);
2158 static HRESULT WINAPI
mixer_control9_QueryInterface(IVMRMixerControl9
*iface
, REFIID iid
, void **out
)
2160 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2161 return IUnknown_QueryInterface(filter
->renderer
.filter
.outer_unk
, iid
, out
);
2164 static ULONG WINAPI
mixer_control9_AddRef(IVMRMixerControl9
*iface
)
2166 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2167 return IUnknown_AddRef(filter
->renderer
.filter
.outer_unk
);
2170 static ULONG WINAPI
mixer_control9_Release(IVMRMixerControl9
*iface
)
2172 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2173 return IUnknown_Release(filter
->renderer
.filter
.outer_unk
);
2176 static HRESULT WINAPI
mixer_control9_SetAlpha(IVMRMixerControl9
*iface
, DWORD stream
, float alpha
)
2178 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2180 FIXME("filter %p, stream %lu, alpha %.8e, stub!\n", filter
, stream
, alpha
);
2185 static HRESULT WINAPI
mixer_control9_GetAlpha(IVMRMixerControl9
*iface
, DWORD stream
, float *alpha
)
2187 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2189 FIXME("filter %p, stream %lu, alpha %p, stub!\n", filter
, stream
, alpha
);
2194 static HRESULT WINAPI
mixer_control9_SetZOrder(IVMRMixerControl9
*iface
, DWORD stream
, DWORD z
)
2196 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2198 FIXME("filter %p, stream %lu, z %lu, stub!\n", filter
, stream
, z
);
2203 static HRESULT WINAPI
mixer_control9_GetZOrder(IVMRMixerControl9
*iface
, DWORD stream
, DWORD
*z
)
2205 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2207 FIXME("filter %p, stream %lu, z %p, stub!\n", filter
, stream
, z
);
2212 static HRESULT WINAPI
mixer_control9_SetOutputRect(IVMRMixerControl9
*iface
,
2213 DWORD stream
, const VMR9NormalizedRect
*rect
)
2215 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2217 FIXME("filter %p, stream %lu, rect %s, stub!\n", filter
, stream
, debugstr_normalized_rect(rect
));
2222 static HRESULT WINAPI
mixer_control9_GetOutputRect(IVMRMixerControl9
*iface
,
2223 DWORD stream
, VMR9NormalizedRect
*rect
)
2225 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2227 FIXME("filter %p, stream %lu, rect %p, stub!\n", filter
, stream
, rect
);
2232 static HRESULT WINAPI
mixer_control9_SetBackgroundClr(IVMRMixerControl9
*iface
, COLORREF color
)
2234 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2236 FIXME("filter %p, color #%06lx, stub!\n", filter
, color
);
2241 static HRESULT WINAPI
mixer_control9_GetBackgroundClr(IVMRMixerControl9
*iface
, COLORREF
*color
)
2243 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2245 FIXME("filter %p, color %p, stub!\n", filter
, color
);
2250 static HRESULT WINAPI
mixer_control9_SetMixingPrefs(IVMRMixerControl9
*iface
, DWORD flags
)
2252 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2254 FIXME("filter %p, flags %#lx, stub!\n", filter
, flags
);
2256 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2257 filter
->mixing_prefs
= flags
;
2258 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2262 static HRESULT WINAPI
mixer_control9_GetMixingPrefs(IVMRMixerControl9
*iface
, DWORD
*flags
)
2264 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2266 FIXME("filter %p, flags %p, stub!\n", filter
, flags
);
2268 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2269 *flags
= filter
->mixing_prefs
;
2270 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2274 static HRESULT WINAPI
mixer_control9_SetProcAmpControl(IVMRMixerControl9
*iface
,
2275 DWORD stream
, VMR9ProcAmpControl
*settings
)
2277 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2279 FIXME("filter %p, settings %p, stub!\n", filter
, settings
);
2284 static HRESULT WINAPI
mixer_control9_GetProcAmpControl(IVMRMixerControl9
*iface
,
2285 DWORD stream
, VMR9ProcAmpControl
*settings
)
2287 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2289 FIXME("filter %p, settings %p, stub!\n", filter
, settings
);
2294 static HRESULT WINAPI
mixer_control9_GetProcAmpControlRange(IVMRMixerControl9
*iface
,
2295 DWORD stream
, VMR9ProcAmpControlRange
*settings
)
2297 struct quartz_vmr
*filter
= impl_from_IVMRMixerControl9(iface
);
2299 FIXME("filter %p, settings %p, stub!\n", filter
, settings
);
2304 static const IVMRMixerControl9Vtbl mixer_control9_vtbl
=
2306 mixer_control9_QueryInterface
,
2307 mixer_control9_AddRef
,
2308 mixer_control9_Release
,
2309 mixer_control9_SetAlpha
,
2310 mixer_control9_GetAlpha
,
2311 mixer_control9_SetZOrder
,
2312 mixer_control9_GetZOrder
,
2313 mixer_control9_SetOutputRect
,
2314 mixer_control9_GetOutputRect
,
2315 mixer_control9_SetBackgroundClr
,
2316 mixer_control9_GetBackgroundClr
,
2317 mixer_control9_SetMixingPrefs
,
2318 mixer_control9_GetMixingPrefs
,
2319 mixer_control9_SetProcAmpControl
,
2320 mixer_control9_GetProcAmpControl
,
2321 mixer_control9_GetProcAmpControlRange
,
2324 static inline struct quartz_vmr
*impl_from_IVMRMixerBitmap9(IVMRMixerBitmap9
*iface
)
2326 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRMixerBitmap9_iface
);
2329 static HRESULT WINAPI
mixer_bitmap9_QueryInterface(IVMRMixerBitmap9
*iface
, REFIID iid
, void **out
)
2331 struct quartz_vmr
*filter
= impl_from_IVMRMixerBitmap9(iface
);
2332 return IUnknown_QueryInterface(filter
->renderer
.filter
.outer_unk
, iid
, out
);
2335 static ULONG WINAPI
mixer_bitmap9_AddRef(IVMRMixerBitmap9
*iface
)
2337 struct quartz_vmr
*filter
= impl_from_IVMRMixerBitmap9(iface
);
2338 return IUnknown_AddRef(filter
->renderer
.filter
.outer_unk
);
2341 static ULONG WINAPI
mixer_bitmap9_Release(IVMRMixerBitmap9
*iface
)
2343 struct quartz_vmr
*filter
= impl_from_IVMRMixerBitmap9(iface
);
2344 return IUnknown_Release(filter
->renderer
.filter
.outer_unk
);
2347 static HRESULT WINAPI
mixer_bitmap9_SetAlphaBitmap(IVMRMixerBitmap9
*iface
,
2348 const VMR9AlphaBitmap
*bitmap
)
2350 FIXME("iface %p, bitmap %p, stub!\n", iface
, bitmap
);
2351 TRACE("dwFlags %#lx, hdc %p, pDDS %p, rSrc %s, rDest %s, fAlpha %.8e, clrSrcKey #%06lx, dwFilterMode %#lx.\n",
2352 bitmap
->dwFlags
, bitmap
->hdc
, bitmap
->pDDS
, wine_dbgstr_rect(&bitmap
->rSrc
),
2353 debugstr_normalized_rect(&bitmap
->rDest
), bitmap
->fAlpha
, bitmap
->clrSrcKey
, bitmap
->dwFilterMode
);
2357 static HRESULT WINAPI
mixer_bitmap9_UpdateAlphaBitmapParameters(IVMRMixerBitmap9
*iface
,
2358 const VMR9AlphaBitmap
*bitmap
)
2360 FIXME("iface %p, bitmap %p, stub!\n", iface
, bitmap
);
2364 static HRESULT WINAPI
mixer_bitmap9_GetAlphaBitmapParameters(IVMRMixerBitmap9
*iface
,
2365 VMR9AlphaBitmap
*bitmap
)
2367 FIXME("iface %p, bitmap %p, stub!\n", iface
, bitmap
);
2371 static const IVMRMixerBitmap9Vtbl mixer_bitmap9_vtbl
=
2373 mixer_bitmap9_QueryInterface
,
2374 mixer_bitmap9_AddRef
,
2375 mixer_bitmap9_Release
,
2376 mixer_bitmap9_SetAlphaBitmap
,
2377 mixer_bitmap9_UpdateAlphaBitmapParameters
,
2378 mixer_bitmap9_GetAlphaBitmapParameters
,
2381 static inline struct quartz_vmr
*impl_from_IVMRAspectRatioControl9(IVMRAspectRatioControl9
*iface
)
2383 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IVMRAspectRatioControl9_iface
);
2386 static HRESULT WINAPI
aspect_ratio_control9_QueryInterface(IVMRAspectRatioControl9
*iface
, REFIID iid
, void **out
)
2388 struct quartz_vmr
*filter
= impl_from_IVMRAspectRatioControl9(iface
);
2389 return IUnknown_QueryInterface(filter
->renderer
.filter
.outer_unk
, iid
, out
);
2392 static ULONG WINAPI
aspect_ratio_control9_AddRef(IVMRAspectRatioControl9
*iface
)
2394 struct quartz_vmr
*filter
= impl_from_IVMRAspectRatioControl9(iface
);
2395 return IUnknown_AddRef(filter
->renderer
.filter
.outer_unk
);
2398 static ULONG WINAPI
aspect_ratio_control9_Release(IVMRAspectRatioControl9
*iface
)
2400 struct quartz_vmr
*filter
= impl_from_IVMRAspectRatioControl9(iface
);
2401 return IUnknown_Release(filter
->renderer
.filter
.outer_unk
);
2404 static HRESULT WINAPI
aspect_ratio_control9_GetAspectRatioMode(IVMRAspectRatioControl9
*iface
, DWORD
*mode
)
2406 struct quartz_vmr
*filter
= impl_from_IVMRAspectRatioControl9(iface
);
2408 TRACE("filter %p, mode %p.\n", filter
, mode
);
2410 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2411 *mode
= filter
->aspect_mode
;
2412 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2416 static HRESULT WINAPI
aspect_ratio_control9_SetAspectRatioMode(IVMRAspectRatioControl9
*iface
, DWORD mode
)
2418 struct quartz_vmr
*filter
= impl_from_IVMRAspectRatioControl9(iface
);
2420 TRACE("filter %p, mode %lu.\n", filter
, mode
);
2422 EnterCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2423 filter
->aspect_mode
= mode
;
2424 LeaveCriticalSection(&filter
->renderer
.filter
.filter_cs
);
2428 static const IVMRAspectRatioControl9Vtbl aspect_ratio_control9_vtbl
=
2430 aspect_ratio_control9_QueryInterface
,
2431 aspect_ratio_control9_AddRef
,
2432 aspect_ratio_control9_Release
,
2433 aspect_ratio_control9_GetAspectRatioMode
,
2434 aspect_ratio_control9_SetAspectRatioMode
,
2437 static struct quartz_vmr
*impl_from_IAMVideoAccelerator(IAMVideoAccelerator
*iface
)
2439 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IAMVideoAccelerator_iface
);
2442 static HRESULT WINAPI
video_accelerator_QueryInterface(IAMVideoAccelerator
*iface
, REFIID iid
, void **out
)
2444 struct quartz_vmr
*filter
= impl_from_IAMVideoAccelerator(iface
);
2445 return IPin_QueryInterface(&filter
->renderer
.sink
.pin
.IPin_iface
, iid
, out
);
2448 static ULONG WINAPI
video_accelerator_AddRef(IAMVideoAccelerator
*iface
)
2450 struct quartz_vmr
*filter
= impl_from_IAMVideoAccelerator(iface
);
2451 return IPin_AddRef(&filter
->renderer
.sink
.pin
.IPin_iface
);
2454 static ULONG WINAPI
video_accelerator_Release(IAMVideoAccelerator
*iface
)
2456 struct quartz_vmr
*filter
= impl_from_IAMVideoAccelerator(iface
);
2457 return IPin_Release(&filter
->renderer
.sink
.pin
.IPin_iface
);
2460 static HRESULT WINAPI
video_accelerator_GetVideoAcceleratorGUIDs(
2461 IAMVideoAccelerator
*iface
, DWORD
*count
, GUID
*accelerators
)
2463 FIXME("iface %p, count %p, accelerators %p, stub!\n", iface
, count
, accelerators
);
2467 static HRESULT WINAPI
video_accelerator_GetUncompFormatsSupported(IAMVideoAccelerator
*iface
,
2468 const GUID
*accelerator
, DWORD
*count
, DDPIXELFORMAT
*formats
)
2470 FIXME("iface %p, accelerator %s, count %p, formats %p, stub!\n",
2471 iface
, debugstr_guid(accelerator
), count
, formats
);
2475 static HRESULT WINAPI
video_accelerator_GetInternalMemInfo(IAMVideoAccelerator
*iface
,
2476 const GUID
*accelerator
, const AMVAUncompDataInfo
*format_info
, AMVAInternalMemInfo
*mem_info
)
2478 FIXME("iface %p, accelerator %s, format_info %p, mem_info %p, stub!\n",
2479 iface
, debugstr_guid(accelerator
), format_info
, mem_info
);
2483 static HRESULT WINAPI
video_accelerator_GetCompBufferInfo(IAMVideoAccelerator
*iface
,
2484 const GUID
*accelerator
, const AMVAUncompDataInfo
*uncompressed_info
,
2485 DWORD
*compressed_info_count
, AMVACompBufferInfo
*compressed_infos
)
2487 FIXME("iface %p, accelerator %s, uncompressed_info %p, compressed_info_count %p, compressed_infos %p, stub!\n",
2488 iface
, debugstr_guid(accelerator
), uncompressed_info
, compressed_info_count
, compressed_infos
);
2492 static HRESULT WINAPI
video_accelerator_GetInternalCompBufferInfo(
2493 IAMVideoAccelerator
*iface
, DWORD
*count
, AMVACompBufferInfo
*infos
)
2495 FIXME("iface %p, count %p, infos %p, stub!\n", iface
, count
, infos
);
2499 static HRESULT WINAPI
video_accelerator_BeginFrame(IAMVideoAccelerator
*iface
, const AMVABeginFrameInfo
*info
)
2501 FIXME("iface %p, info %p, stub!\n", iface
, info
);
2505 static HRESULT WINAPI
video_accelerator_EndFrame(IAMVideoAccelerator
*iface
, const AMVAEndFrameInfo
*info
)
2507 FIXME("iface %p, info %p, stub!\n", iface
, info
);
2511 static HRESULT WINAPI
video_accelerator_GetBuffer(IAMVideoAccelerator
*iface
,
2512 DWORD type_index
, DWORD buffer_index
, BOOL read_only
, void **buffer
, LONG
*stride
)
2514 FIXME("iface %p, type_index %lu, buffer_index %lu, read_only %d, buffer %p, stride %p, stub!\n",
2515 iface
, type_index
, buffer_index
, read_only
, buffer
, stride
);
2519 static HRESULT WINAPI
video_accelerator_ReleaseBuffer(
2520 IAMVideoAccelerator
*iface
, DWORD type_index
, DWORD buffer_index
)
2522 FIXME("iface %p, type_index %lu, buffer_index %lu, stub!\n", iface
, type_index
, buffer_index
);
2526 static HRESULT WINAPI
video_accelerator_Execute(IAMVideoAccelerator
*iface
,
2527 DWORD function
, void *in_data
, DWORD in_size
, void *out_data
,
2528 DWORD out_size
, DWORD buffer_count
, const AMVABUFFERINFO
*buffers
)
2530 FIXME("iface %p, function %#lx, in_data %p, in_size %lu,"
2531 " out_data %p, out_size %lu, buffer_count %lu, buffers %p, stub!\n",
2532 iface
, function
, in_data
, in_size
, out_data
, out_size
, buffer_count
, buffers
);
2536 static HRESULT WINAPI
video_accelerator_QueryRenderStatus(IAMVideoAccelerator
*iface
,
2537 DWORD type_index
, DWORD buffer_index
, DWORD flags
)
2539 FIXME("iface %p, type_index %lu, buffer_index %lu, flags %#lx, stub!\n",
2540 iface
, type_index
, buffer_index
, flags
);
2544 static HRESULT WINAPI
video_accelerator_DisplayFrame(
2545 IAMVideoAccelerator
*iface
, DWORD index
, IMediaSample
*sample
)
2547 FIXME("iface %p, index %lu, sample %p, stub!\n", iface
, index
, sample
);
2551 static const IAMVideoAcceleratorVtbl video_accelerator_vtbl
=
2553 video_accelerator_QueryInterface
,
2554 video_accelerator_AddRef
,
2555 video_accelerator_Release
,
2556 video_accelerator_GetVideoAcceleratorGUIDs
,
2557 video_accelerator_GetUncompFormatsSupported
,
2558 video_accelerator_GetInternalMemInfo
,
2559 video_accelerator_GetCompBufferInfo
,
2560 video_accelerator_GetInternalCompBufferInfo
,
2561 video_accelerator_BeginFrame
,
2562 video_accelerator_EndFrame
,
2563 video_accelerator_GetBuffer
,
2564 video_accelerator_ReleaseBuffer
,
2565 video_accelerator_Execute
,
2566 video_accelerator_QueryRenderStatus
,
2567 video_accelerator_DisplayFrame
,
2570 static inline struct quartz_vmr
*impl_from_IOverlay(IOverlay
*iface
)
2572 return CONTAINING_RECORD(iface
, struct quartz_vmr
, IOverlay_iface
);
2575 static HRESULT WINAPI
overlay_QueryInterface(IOverlay
*iface
, REFIID iid
, void **out
)
2577 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2578 return IPin_QueryInterface(&filter
->renderer
.sink
.pin
.IPin_iface
, iid
, out
);
2581 static ULONG WINAPI
overlay_AddRef(IOverlay
*iface
)
2583 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2584 return IPin_AddRef(&filter
->renderer
.sink
.pin
.IPin_iface
);
2587 static ULONG WINAPI
overlay_Release(IOverlay
*iface
)
2589 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2590 return IPin_Release(&filter
->renderer
.sink
.pin
.IPin_iface
);
2593 static HRESULT WINAPI
overlay_GetPalette(IOverlay
*iface
, DWORD
*count
, PALETTEENTRY
**palette
)
2595 FIXME("iface %p, count %p, palette %p, stub!\n", iface
, count
, palette
);
2599 static HRESULT WINAPI
overlay_SetPalette(IOverlay
*iface
, DWORD count
, PALETTEENTRY
*palette
)
2601 FIXME("iface %p, count %lu, palette %p, stub!\n", iface
, count
, palette
);
2605 static HRESULT WINAPI
overlay_GetDefaultColorKey(IOverlay
*iface
, COLORKEY
*key
)
2607 FIXME("iface %p, key %p, stub!\n", iface
, key
);
2611 static HRESULT WINAPI
overlay_GetColorKey(IOverlay
*iface
, COLORKEY
*key
)
2613 FIXME("iface %p, key %p, stub!\n", iface
, key
);
2617 static HRESULT WINAPI
overlay_SetColorKey(IOverlay
*iface
, COLORKEY
*key
)
2619 FIXME("iface %p, key %p, stub!\n", iface
, key
);
2623 static HRESULT WINAPI
overlay_GetWindowHandle(IOverlay
*iface
, HWND
*window
)
2625 struct quartz_vmr
*filter
= impl_from_IOverlay(iface
);
2627 TRACE("filter %p, window %p.\n", filter
, window
);
2629 if (!filter
->window
.hwnd
)
2630 return VFW_E_WRONG_STATE
;
2632 *window
= filter
->window
.hwnd
;
2636 static HRESULT WINAPI
overlay_GetClipList(IOverlay
*iface
, RECT
*source
, RECT
*dest
, RGNDATA
**region
)
2638 FIXME("iface %p, source %p, dest %p, region %p, stub!\n", iface
, source
, dest
, region
);
2642 static HRESULT WINAPI
overlay_GetVideoPosition(IOverlay
*iface
, RECT
*source
, RECT
*dest
)
2644 FIXME("iface %p, source %p, dest %p, stub!\n", iface
, source
, dest
);
2648 static HRESULT WINAPI
overlay_Advise(IOverlay
*iface
, IOverlayNotify
*sink
, DWORD flags
)
2650 FIXME("iface %p, sink %p, flags %#lx, stub!\n", iface
, sink
, flags
);
2654 static HRESULT WINAPI
overlay_Unadvise(IOverlay
*iface
)
2656 FIXME("iface %p, stub!\n", iface
);
2660 static const IOverlayVtbl overlay_vtbl
=
2662 overlay_QueryInterface
,
2667 overlay_GetDefaultColorKey
,
2668 overlay_GetColorKey
,
2669 overlay_SetColorKey
,
2670 overlay_GetWindowHandle
,
2671 overlay_GetClipList
,
2672 overlay_GetVideoPosition
,
2677 static HRESULT
vmr_create(IUnknown
*outer
, IUnknown
**out
, const CLSID
*clsid
)
2679 struct quartz_vmr
*object
;
2682 if (!(object
= calloc(1, sizeof(*object
))))
2683 return E_OUTOFMEMORY
;
2685 object
->hD3d9
= LoadLibraryA("d3d9.dll");
2688 WARN("Could not load d3d9.dll\n");
2690 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
2693 strmbase_renderer_init(&object
->renderer
, outer
, clsid
, L
"VMR Input0", &renderer_ops
);
2694 object
->IAMCertifiedOutputProtection_iface
.lpVtbl
= &IAMCertifiedOutputProtection_Vtbl
;
2695 object
->IAMFilterMiscFlags_iface
.lpVtbl
= &IAMFilterMiscFlags_Vtbl
;
2696 object
->IVMRAspectRatioControl9_iface
.lpVtbl
= &aspect_ratio_control9_vtbl
;
2697 object
->IVMRFilterConfig_iface
.lpVtbl
= &VMR7_FilterConfig_Vtbl
;
2698 object
->IVMRFilterConfig9_iface
.lpVtbl
= &VMR9_FilterConfig_Vtbl
;
2699 object
->IVMRMixerBitmap9_iface
.lpVtbl
= &mixer_bitmap9_vtbl
;
2700 object
->IVMRMixerControl9_iface
.lpVtbl
= &mixer_control9_vtbl
;
2701 object
->IVMRMonitorConfig_iface
.lpVtbl
= &VMR7_MonitorConfig_Vtbl
;
2702 object
->IVMRMonitorConfig9_iface
.lpVtbl
= &VMR9_MonitorConfig_Vtbl
;
2703 object
->IVMRSurfaceAllocatorNotify_iface
.lpVtbl
= &VMR7_SurfaceAllocatorNotify_Vtbl
;
2704 object
->IVMRSurfaceAllocatorNotify9_iface
.lpVtbl
= &VMR9_SurfaceAllocatorNotify_Vtbl
;
2705 object
->IVMRWindowlessControl_iface
.lpVtbl
= &VMR7_WindowlessControl_Vtbl
;
2706 object
->IVMRWindowlessControl9_iface
.lpVtbl
= &VMR9_WindowlessControl_Vtbl
;
2708 object
->IAMVideoAccelerator_iface
.lpVtbl
= &video_accelerator_vtbl
;
2709 object
->IOverlay_iface
.lpVtbl
= &overlay_vtbl
;
2711 video_window_init(&object
->window
, &IVideoWindow_VTable
,
2712 &object
->renderer
.filter
, &object
->renderer
.sink
.pin
, &window_ops
);
2714 if (FAILED(hr
= video_window_create_window(&object
->window
)))
2716 video_window_cleanup(&object
->window
);
2717 strmbase_renderer_cleanup(&object
->renderer
);
2718 FreeLibrary(object
->hD3d9
);
2723 object
->mixing_prefs
= MixerPref9_NoDecimation
| MixerPref9_ARAdjustXorY
2724 | MixerPref9_BiLinearFiltering
| MixerPref9_RenderTargetRGB
;
2726 TRACE("Created VMR %p.\n", object
);
2727 *out
= &object
->renderer
.filter
.IUnknown_inner
;
2731 HRESULT
vmr7_create(IUnknown
*outer
, IUnknown
**out
)
2733 return vmr_create(outer
, out
, &CLSID_VideoMixingRenderer
);
2736 HRESULT
vmr9_create(IUnknown
*outer
, IUnknown
**out
)
2738 return vmr_create(outer
, out
, &CLSID_VideoMixingRenderer9
);
2742 static HRESULT WINAPI
VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9
*iface
, REFIID riid
, void **ppv
)
2744 struct default_presenter
*This
= impl_from_IVMRImagePresenter9(iface
);
2746 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, qzdebugstr_guid(riid
), ppv
);
2750 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IVMRImagePresenter9
))
2751 *ppv
= &This
->IVMRImagePresenter9_iface
;
2752 else if (IsEqualIID(riid
, &IID_IVMRSurfaceAllocator9
))
2753 *ppv
= &This
->IVMRSurfaceAllocator9_iface
;
2757 IUnknown_AddRef((IUnknown
*)(*ppv
));
2761 FIXME("No interface for %s\n", debugstr_guid(riid
));
2763 return E_NOINTERFACE
;
2766 static ULONG WINAPI
VMR9_ImagePresenter_AddRef(IVMRImagePresenter9
*iface
)
2768 struct default_presenter
*presenter
= impl_from_IVMRImagePresenter9(iface
);
2769 ULONG refcount
= InterlockedIncrement(&presenter
->refCount
);
2771 TRACE("%p increasing refcount to %lu.\n", presenter
, refcount
);
2776 static ULONG WINAPI
VMR9_ImagePresenter_Release(IVMRImagePresenter9
*iface
)
2778 struct default_presenter
*This
= impl_from_IVMRImagePresenter9(iface
);
2779 ULONG refcount
= InterlockedDecrement(&This
->refCount
);
2781 TRACE("%p decreasing refcount to %lu.\n", This
, refcount
);
2787 IDirect3D9_Release(This
->d3d9_ptr
);
2789 for (i
= 0; i
< This
->num_surfaces
; ++i
)
2791 IDirect3DSurface9
*surface
= This
->d3d9_surfaces
[i
];
2793 IDirect3DSurface9_Release(surface
);
2797 IDirect3DDevice9_Release(This
->d3d9_dev
);
2798 free(This
->d3d9_surfaces
);
2799 This
->d3d9_surfaces
= NULL
;
2800 This
->num_surfaces
= 0;
2807 static HRESULT WINAPI
VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9
*iface
, DWORD_PTR cookie
)
2809 struct default_presenter
*presenter
= impl_from_IVMRImagePresenter9(iface
);
2811 TRACE("presenter %p, cookie %#Ix.\n", presenter
, cookie
);
2816 static HRESULT WINAPI
VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9
*iface
, DWORD_PTR cookie
)
2818 struct default_presenter
*presenter
= impl_from_IVMRImagePresenter9(iface
);
2820 TRACE("presenter %p, cookie %#Ix.\n", presenter
, cookie
);
2825 static HRESULT WINAPI
VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9
*iface
,
2826 DWORD_PTR cookie
, VMR9PresentationInfo
*info
)
2828 struct default_presenter
*presenter
= impl_from_IVMRImagePresenter9(iface
);
2829 const struct quartz_vmr
*filter
= presenter
->pVMR9
;
2830 IDirect3DDevice9
*device
= presenter
->d3d9_dev
;
2831 const RECT src
= filter
->window
.src
;
2832 IDirect3DSurface9
*backbuffer
;
2833 RECT dst
= filter
->window
.dst
;
2836 TRACE("presenter %p, cookie %#Ix, info %p.\n", presenter
, cookie
, info
);
2838 /* This might happen if we don't have active focus (eg on a different virtual desktop) */
2842 if (FAILED(hr
= IDirect3DDevice9_Clear(device
, 0, NULL
, D3DCLEAR_TARGET
,
2843 D3DCOLOR_XRGB(0, 0, 0), 1.0f
, 0)))
2844 ERR("Failed to clear, hr %#lx.\n", hr
);
2846 if (FAILED(hr
= IDirect3DDevice9_BeginScene(device
)))
2847 ERR("Failed to begin scene, hr %#lx.\n", hr
);
2849 if (FAILED(hr
= IDirect3DDevice9_GetBackBuffer(device
, 0, 0, D3DBACKBUFFER_TYPE_MONO
, &backbuffer
)))
2851 ERR("Failed to get backbuffer, hr %#lx.\n", hr
);
2855 if (FAILED(hr
= IDirect3DDevice9_StretchRect(device
, info
->lpSurf
, NULL
, backbuffer
, NULL
, D3DTEXF_POINT
)))
2856 ERR("Failed to blit image, hr %#lx.\n", hr
);
2857 IDirect3DSurface9_Release(backbuffer
);
2859 if (FAILED(hr
= IDirect3DDevice9_EndScene(device
)))
2860 ERR("Failed to end scene, hr %#lx.\n", hr
);
2862 if (filter
->aspect_mode
== VMR9ARMode_LetterBox
)
2864 unsigned int src_width
= src
.right
- src
.left
, src_height
= src
.bottom
- src
.top
;
2865 unsigned int dst_width
= dst
.right
- dst
.left
, dst_height
= dst
.bottom
- dst
.top
;
2867 if (src_width
* dst_height
> dst_width
* src_height
)
2869 /* src is "wider" than dst. */
2870 unsigned int dst_center
= (dst
.top
+ dst
.bottom
) / 2;
2871 unsigned int scaled_height
= src_height
* dst_width
/ src_width
;
2873 dst
.top
= dst_center
- scaled_height
/ 2;
2874 dst
.bottom
= dst
.top
+ scaled_height
;
2876 else if (src_width
* dst_height
< dst_width
* src_height
)
2878 /* src is "taller" than dst. */
2879 unsigned int dst_center
= (dst
.left
+ dst
.right
) / 2;
2880 unsigned int scaled_width
= src_width
* dst_height
/ src_height
;
2882 dst
.left
= dst_center
- scaled_width
/ 2;
2883 dst
.right
= dst
.left
+ scaled_width
;
2887 if (FAILED(hr
= IDirect3DDevice9_Present(device
, &src
, &dst
, NULL
, NULL
)))
2888 ERR("Failed to present, hr %#lx.\n", hr
);
2893 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter
=
2895 VMR9_ImagePresenter_QueryInterface
,
2896 VMR9_ImagePresenter_AddRef
,
2897 VMR9_ImagePresenter_Release
,
2898 VMR9_ImagePresenter_StartPresenting
,
2899 VMR9_ImagePresenter_StopPresenting
,
2900 VMR9_ImagePresenter_PresentImage
2903 static HRESULT WINAPI
VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocator9
*iface
, REFIID iid
, void **out
)
2905 struct default_presenter
*presenter
= impl_from_IVMRSurfaceAllocator9(iface
);
2906 return IVMRImagePresenter9_QueryInterface(&presenter
->IVMRImagePresenter9_iface
, iid
, out
);
2909 static ULONG WINAPI
VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocator9
*iface
)
2911 struct default_presenter
*presenter
= impl_from_IVMRSurfaceAllocator9(iface
);
2912 return IVMRImagePresenter9_AddRef(&presenter
->IVMRImagePresenter9_iface
);
2915 static ULONG WINAPI
VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocator9
*iface
)
2917 struct default_presenter
*presenter
= impl_from_IVMRSurfaceAllocator9(iface
);
2918 return IVMRImagePresenter9_Release(&presenter
->IVMRImagePresenter9_iface
);
2921 static void adjust_surface_size(const D3DCAPS9
*caps
, VMR9AllocationInfo
*allocinfo
)
2925 /* There are no restrictions on the size of offscreen surfaces. */
2926 if (!(allocinfo
->dwFlags
& VMR9AllocFlag_TextureSurface
))
2929 if (!(caps
->TextureCaps
& D3DPTEXTURECAPS_POW2
) || (caps
->TextureCaps
& D3DPTEXTURECAPS_SQUAREONLY
))
2931 width
= allocinfo
->dwWidth
;
2932 height
= allocinfo
->dwHeight
;
2937 while (width
< allocinfo
->dwWidth
)
2940 while (height
< allocinfo
->dwHeight
)
2942 FIXME("NPOW2 support missing, not using proper surfaces!\n");
2945 if (caps
->TextureCaps
& D3DPTEXTURECAPS_SQUAREONLY
)
2951 FIXME("Square texture support required..\n");
2954 allocinfo
->dwHeight
= height
;
2955 allocinfo
->dwWidth
= width
;
2958 static UINT
d3d9_adapter_from_hwnd(IDirect3D9
*d3d9
, HWND hwnd
, HMONITOR
*mon_out
)
2963 mon
= MonitorFromWindow(hwnd
, MONITOR_DEFAULTTONULL
);
2968 for (d3d9_adapter
= 0; d3d9_adapter
< IDirect3D9_GetAdapterCount(d3d9
); ++d3d9_adapter
)
2970 if (mon
== IDirect3D9_GetAdapterMonitor(d3d9
, d3d9_adapter
))
2973 if (d3d9_adapter
>= IDirect3D9_GetAdapterCount(d3d9
))
2978 return d3d9_adapter
;
2981 static HRESULT WINAPI
VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocator9
*iface
,
2982 DWORD_PTR cookie
, VMR9AllocationInfo
*info
, DWORD
*numbuffers
)
2984 struct default_presenter
*This
= impl_from_IVMRSurfaceAllocator9(iface
);
2985 D3DPRESENT_PARAMETERS d3dpp
;
2986 IDirect3DDevice9
*device
;
2992 TRACE("presenter %p, cookie %#Ix, info %p, numbuffers %p.\n", This
, cookie
, info
, numbuffers
);
2996 if (This
->pVMR9
->mode
== VMR9Mode_Windowed
)
2997 window
= This
->pVMR9
->window
.hwnd
;
2999 window
= This
->pVMR9
->clipping_window
;
3001 /* Obtain a monitor and d3d9 device */
3002 d3d9_adapter
= d3d9_adapter_from_hwnd(This
->d3d9_ptr
, window
, &This
->hMon
);
3004 /* Now try to create the d3d9 device */
3005 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
3006 d3dpp
.Windowed
= TRUE
;
3007 d3dpp
.hDeviceWindow
= window
;
3008 d3dpp
.SwapEffect
= D3DSWAPEFFECT_COPY
;
3009 d3dpp
.BackBufferWidth
= info
->dwWidth
;
3010 d3dpp
.BackBufferHeight
= info
->dwHeight
;
3012 hr
= IDirect3D9_CreateDevice(This
->d3d9_ptr
, d3d9_adapter
, D3DDEVTYPE_HAL
,
3013 NULL
, D3DCREATE_MIXED_VERTEXPROCESSING
, &d3dpp
, &device
);
3016 ERR("Failed to create device, hr %#lx.\n", hr
);
3020 IDirect3DDevice9_GetDeviceCaps(device
, &caps
);
3021 if (!(caps
.DevCaps2
& D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES
))
3023 WARN("Device does not support blitting from textures.\n");
3024 IDirect3DDevice9_Release(device
);
3025 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
3028 This
->d3d9_dev
= device
;
3029 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This
->SurfaceAllocatorNotify
, This
->d3d9_dev
, This
->hMon
);
3031 if (!(This
->d3d9_surfaces
= calloc(*numbuffers
, sizeof(IDirect3DSurface9
*))))
3032 return E_OUTOFMEMORY
;
3034 adjust_surface_size(&caps
, info
);
3036 hr
= IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This
->SurfaceAllocatorNotify
,
3037 info
, numbuffers
, This
->d3d9_surfaces
);
3040 ERR("Failed to allocate surfaces, hr %#lx.\n", hr
);
3041 IVMRSurfaceAllocator9_TerminateDevice(This
->pVMR9
->allocator
, This
->pVMR9
->cookie
);
3045 This
->num_surfaces
= *numbuffers
;
3050 static HRESULT WINAPI
VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocator9
*iface
, DWORD_PTR cookie
)
3052 TRACE("iface %p, cookie %#Ix.\n", iface
, cookie
);
3057 static HRESULT WINAPI
VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocator9
*iface
,
3058 DWORD_PTR cookie
, DWORD surfaceindex
, DWORD flags
, IDirect3DSurface9
**surface
)
3060 struct default_presenter
*This
= impl_from_IVMRSurfaceAllocator9(iface
);
3062 /* Update everything first, this is needed because the surface might be destroyed in the reset */
3063 if (!This
->d3d9_dev
)
3065 TRACE("Device has left me!\n");
3069 if (surfaceindex
>= This
->num_surfaces
)
3071 ERR("surfaceindex is greater than num_surfaces\n");
3074 *surface
= This
->d3d9_surfaces
[surfaceindex
];
3075 IDirect3DSurface9_AddRef(*surface
);
3080 static HRESULT WINAPI
VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocator9
*iface
,
3081 IVMRSurfaceAllocatorNotify9
*notify
)
3083 struct default_presenter
*presenter
= impl_from_IVMRSurfaceAllocator9(iface
);
3085 TRACE("presenter %p, notify %p.\n", presenter
, notify
);
3087 /* No AddRef taken here or the base VMR9 filter would never be destroyed */
3088 presenter
->SurfaceAllocatorNotify
= notify
;
3092 static const IVMRSurfaceAllocator9Vtbl VMR9_SurfaceAllocator
=
3094 VMR9_SurfaceAllocator_QueryInterface
,
3095 VMR9_SurfaceAllocator_AddRef
,
3096 VMR9_SurfaceAllocator_Release
,
3097 VMR9_SurfaceAllocator_InitializeDevice
,
3098 VMR9_SurfaceAllocator_TerminateDevice
,
3099 VMR9_SurfaceAllocator_GetSurface
,
3100 VMR9_SurfaceAllocator_AdviseNotify
,
3103 static IDirect3D9
*init_d3d9(HMODULE d3d9_handle
)
3105 IDirect3D9
* (__stdcall
* d3d9_create
)(UINT SDKVersion
);
3107 d3d9_create
= (void *)GetProcAddress(d3d9_handle
, "Direct3DCreate9");
3108 if (!d3d9_create
) return NULL
;
3110 return d3d9_create(D3D_SDK_VERSION
);
3113 static HRESULT
VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr
*parent
, LPVOID
* ppv
)
3115 struct default_presenter
*object
;
3117 if (!(object
= calloc(1, sizeof(*object
))))
3118 return E_OUTOFMEMORY
;
3120 object
->d3d9_ptr
= init_d3d9(parent
->hD3d9
);
3121 if (!object
->d3d9_ptr
)
3123 WARN("Could not initialize d3d9.dll\n");
3125 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
3128 object
->IVMRImagePresenter9_iface
.lpVtbl
= &VMR9_ImagePresenter
;
3129 object
->IVMRSurfaceAllocator9_iface
.lpVtbl
= &VMR9_SurfaceAllocator
;
3131 object
->refCount
= 1;
3132 object
->pVMR9
= parent
;
3134 TRACE("Created default presenter %p.\n", object
);
3135 *ppv
= &object
->IVMRImagePresenter9_iface
;