1 /*
2 * Video Mixing Renderer for dx9
3 *
4 * Copyright 2004 Christian Costa
5 * Copyright 2008 Maarten Lankhorst
6 * Copyright 2012 Aric Stewart
7 *
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.
12 *
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.
17 *
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
21 */
22
23 #include "config.h"
24
25 #include "quartz_private.h"
26
27 #include "uuids.h"
28 #include "vfwmsgs.h"
29 #include "amvideo.h"
30 #include "windef.h"
31 #include "winbase.h"
32 #include "dshow.h"
33 #include "evcode.h"
34 #include "strmif.h"
35 #include "ddraw.h"
36 #include "dvdmedia.h"
37 #include "d3d9.h"
38 #include "vmr9.h"
39 #include "pin.h"
40
41 #include "wine/unicode.h"
42 #include "wine/debug.h"
43
44 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
45
46 struct quartz_vmr
47 {
48 BaseRenderer renderer;
49 BaseControlWindow baseControlWindow;
50 BaseControlVideo baseControlVideo;
51
52 IUnknown IUnknown_inner;
53 IAMCertifiedOutputProtection IAMCertifiedOutputProtection_iface;
54 IAMFilterMiscFlags IAMFilterMiscFlags_iface;
55 IVMRFilterConfig IVMRFilterConfig_iface;
56 IVMRFilterConfig9 IVMRFilterConfig9_iface;
57 IVMRMonitorConfig IVMRMonitorConfig_iface;
58 IVMRMonitorConfig9 IVMRMonitorConfig9_iface;
59 IVMRSurfaceAllocatorNotify IVMRSurfaceAllocatorNotify_iface;
60 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface;
61 IVMRWindowlessControl IVMRWindowlessControl_iface;
62 IVMRWindowlessControl9 IVMRWindowlessControl9_iface;
63
64 IVMRSurfaceAllocatorEx9 *allocator;
65 IVMRImagePresenter9 *presenter;
66 BOOL allocator_is_ex;
67
68 /*
69 * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed
70 * What I do is implement windowless as a special case of renderless, and then
71 * windowed also as a special case of windowless. This is probably the easiest way.
72 */
73 VMR9Mode mode;
74 BITMAPINFOHEADER bmiheader;
75 IUnknown * outer_unk;
76 BOOL bUnkOuterValid;
77 BOOL bAggregatable;
78
79 HMODULE hD3d9;
80
81 /* Presentation related members */
82 IDirect3DDevice9 *allocator_d3d9_dev;
83 HMONITOR allocator_mon;
84 DWORD num_surfaces;
85 DWORD cur_surface;
86 DWORD_PTR cookie;
87
88 /* for Windowless Mode */
89 HWND hWndClippingWindow;
90
91 RECT source_rect;
92 RECT target_rect;
93 LONG VideoWidth;
94 LONG VideoHeight;
95 };
96
impl_from_inner_IUnknown(IUnknown * iface)97 static inline struct quartz_vmr *impl_from_inner_IUnknown(IUnknown *iface)
98 {
99 return CONTAINING_RECORD(iface, struct quartz_vmr, IUnknown_inner);
100 }
101
impl_from_BaseWindow(BaseWindow * wnd)102 static inline struct quartz_vmr *impl_from_BaseWindow(BaseWindow *wnd)
103 {
104 return CONTAINING_RECORD(wnd, struct quartz_vmr, baseControlWindow.baseWindow);
105 }
106
impl_from_IVideoWindow(IVideoWindow * iface)107 static inline struct quartz_vmr *impl_from_IVideoWindow(IVideoWindow *iface)
108 {
109 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlWindow.IVideoWindow_iface);
110 }
111
impl_from_BaseControlVideo(BaseControlVideo * cvid)112 static inline struct quartz_vmr *impl_from_BaseControlVideo(BaseControlVideo *cvid)
113 {
114 return CONTAINING_RECORD(cvid, struct quartz_vmr, baseControlVideo);
115 }
116
impl_from_IBasicVideo(IBasicVideo * iface)117 static inline struct quartz_vmr *impl_from_IBasicVideo(IBasicVideo *iface)
118 {
119 return CONTAINING_RECORD(iface, struct quartz_vmr, baseControlVideo.IBasicVideo_iface);
120 }
121
impl_from_IAMCertifiedOutputProtection(IAMCertifiedOutputProtection * iface)122 static inline struct quartz_vmr *impl_from_IAMCertifiedOutputProtection(IAMCertifiedOutputProtection *iface)
123 {
124 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMCertifiedOutputProtection_iface);
125 }
126
impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags * iface)127 static inline struct quartz_vmr *impl_from_IAMFilterMiscFlags(IAMFilterMiscFlags *iface)
128 {
129 return CONTAINING_RECORD(iface, struct quartz_vmr, IAMFilterMiscFlags_iface);
130 }
131
impl_from_IVMRFilterConfig(IVMRFilterConfig * iface)132 static inline struct quartz_vmr *impl_from_IVMRFilterConfig(IVMRFilterConfig *iface)
133 {
134 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig_iface);
135 }
136
impl_from_IVMRFilterConfig9(IVMRFilterConfig9 * iface)137 static inline struct quartz_vmr *impl_from_IVMRFilterConfig9(IVMRFilterConfig9 *iface)
138 {
139 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRFilterConfig9_iface);
140 }
141
impl_from_IVMRMonitorConfig(IVMRMonitorConfig * iface)142 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig(IVMRMonitorConfig *iface)
143 {
144 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig_iface);
145 }
146
impl_from_IVMRMonitorConfig9(IVMRMonitorConfig9 * iface)147 static inline struct quartz_vmr *impl_from_IVMRMonitorConfig9(IVMRMonitorConfig9 *iface)
148 {
149 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRMonitorConfig9_iface);
150 }
151
impl_from_IVMRSurfaceAllocatorNotify(IVMRSurfaceAllocatorNotify * iface)152 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify(IVMRSurfaceAllocatorNotify *iface)
153 {
154 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify_iface);
155 }
156
impl_from_IVMRSurfaceAllocatorNotify9(IVMRSurfaceAllocatorNotify9 * iface)157 static inline struct quartz_vmr *impl_from_IVMRSurfaceAllocatorNotify9(IVMRSurfaceAllocatorNotify9 *iface)
158 {
159 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRSurfaceAllocatorNotify9_iface);
160 }
161
impl_from_IVMRWindowlessControl(IVMRWindowlessControl * iface)162 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl(IVMRWindowlessControl *iface)
163 {
164 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl_iface);
165 }
166
impl_from_IVMRWindowlessControl9(IVMRWindowlessControl9 * iface)167 static inline struct quartz_vmr *impl_from_IVMRWindowlessControl9(IVMRWindowlessControl9 *iface)
168 {
169 return CONTAINING_RECORD(iface, struct quartz_vmr, IVMRWindowlessControl9_iface);
170 }
171
172 typedef struct
173 {
174 IVMRImagePresenter9 IVMRImagePresenter9_iface;
175 IVMRSurfaceAllocatorEx9 IVMRSurfaceAllocatorEx9_iface;
176
177 LONG refCount;
178
179 HANDLE ack;
180 DWORD tid;
181 HANDLE hWndThread;
182
183 IDirect3DDevice9 *d3d9_dev;
184 IDirect3D9 *d3d9_ptr;
185 IDirect3DSurface9 **d3d9_surfaces;
186 IDirect3DVertexBuffer9 *d3d9_vertex;
187 HMONITOR hMon;
188 DWORD num_surfaces;
189
190 BOOL reset;
191 VMR9AllocationInfo info;
192
193 struct quartz_vmr* pVMR9;
194 IVMRSurfaceAllocatorNotify9 *SurfaceAllocatorNotify;
195 } VMR9DefaultAllocatorPresenterImpl;
196
impl_from_IVMRImagePresenter9(IVMRImagePresenter9 * iface)197 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRImagePresenter9( IVMRImagePresenter9 *iface)
198 {
199 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRImagePresenter9_iface);
200 }
201
impl_from_IVMRSurfaceAllocatorEx9(IVMRSurfaceAllocatorEx9 * iface)202 static inline VMR9DefaultAllocatorPresenterImpl *impl_from_IVMRSurfaceAllocatorEx9( IVMRSurfaceAllocatorEx9 *iface)
203 {
204 return CONTAINING_RECORD(iface, VMR9DefaultAllocatorPresenterImpl, IVMRSurfaceAllocatorEx9_iface);
205 }
206
207 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv);
208
VMR9_SendSampleData(struct quartz_vmr * This,VMR9PresentationInfo * info,LPBYTE data,DWORD size)209 static DWORD VMR9_SendSampleData(struct quartz_vmr *This, VMR9PresentationInfo *info, LPBYTE data,
210 DWORD size)
211 {
212 AM_MEDIA_TYPE *amt;
213 HRESULT hr = S_OK;
214 int width;
215 int height;
216 BITMAPINFOHEADER *bmiHeader;
217 D3DLOCKED_RECT lock;
218
219 TRACE("%p %p %d\n", This, data, size);
220
221 amt = &This->renderer.pInputPin->pin.mtCurrent;
222
223 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
224 {
225 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
226 }
227 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
228 {
229 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
230 }
231 else
232 {
233 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
234 return VFW_E_RUNTIME_ERROR;
235 }
236
237 TRACE("biSize = %d\n", bmiHeader->biSize);
238 TRACE("biWidth = %d\n", bmiHeader->biWidth);
239 TRACE("biHeight = %d\n", bmiHeader->biHeight);
240 TRACE("biPlanes = %d\n", bmiHeader->biPlanes);
241 TRACE("biBitCount = %d\n", bmiHeader->biBitCount);
242 TRACE("biCompression = %s\n", debugstr_an((LPSTR)&(bmiHeader->biCompression), 4));
243 TRACE("biSizeImage = %d\n", bmiHeader->biSizeImage);
244
245 width = bmiHeader->biWidth;
246 height = bmiHeader->biHeight;
247
248 TRACE("Src Rect: %s\n", wine_dbgstr_rect(&This->source_rect));
249 TRACE("Dst Rect: %s\n", wine_dbgstr_rect(&This->target_rect));
250
251 hr = IDirect3DSurface9_LockRect(info->lpSurf, &lock, NULL, D3DLOCK_DISCARD);
252 if (FAILED(hr))
253 {
254 ERR("IDirect3DSurface9_LockRect failed (%x)\n",hr);
255 return hr;
256 }
257
258 if (height > 0) {
259 /* Bottom up image needs inverting */
260 lock.pBits = (char *)lock.pBits + (height * lock.Pitch);
261 while (height--)
262 {
263 lock.pBits = (char *)lock.pBits - lock.Pitch;
264 memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8);
265 data = data + width * bmiHeader->biBitCount / 8;
266 }
267 }
268 else if (lock.Pitch != width * bmiHeader->biBitCount / 8)
269 {
270 WARN("Slow path! %u/%u\n", lock.Pitch, width * bmiHeader->biBitCount/8);
271
272 while (height--)
273 {
274 memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8);
275 data = data + width * bmiHeader->biBitCount / 8;
276 lock.pBits = (char *)lock.pBits + lock.Pitch;
277 }
278 }
279 else memcpy(lock.pBits, data, size);
280
281 IDirect3DSurface9_UnlockRect(info->lpSurf);
282
283 hr = IVMRImagePresenter9_PresentImage(This->presenter, This->cookie, info);
284 return hr;
285 }
286
VMR9_DoRenderSample(BaseRenderer * iface,IMediaSample * pSample)287 static HRESULT WINAPI VMR9_DoRenderSample(BaseRenderer *iface, IMediaSample * pSample)
288 {
289 struct quartz_vmr *This = (struct quartz_vmr*)iface;
290 LPBYTE pbSrcStream = NULL;
291 long cbSrcStream = 0;
292 REFERENCE_TIME tStart, tStop;
293 VMR9PresentationInfo info;
294 HRESULT hr;
295
296 TRACE("%p %p\n", iface, pSample);
297
298 /* It is possible that there is no device at this point */
299
300 if (!This->allocator || !This->presenter)
301 {
302 ERR("NO PRESENTER!!\n");
303 return S_FALSE;
304 }
305
306 hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
307 if (FAILED(hr))
308 info.dwFlags = VMR9Sample_SrcDstRectsValid;
309 else
310 info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid;
311
312 if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
313 info.dwFlags |= VMR9Sample_Discontinuity;
314
315 if (IMediaSample_IsPreroll(pSample) == S_OK)
316 info.dwFlags |= VMR9Sample_Preroll;
317
318 if (IMediaSample_IsSyncPoint(pSample) == S_OK)
319 info.dwFlags |= VMR9Sample_SyncPoint;
320
321 /* If we render ourselves, and this is a preroll sample, discard it */
322 if (This->baseControlWindow.baseWindow.hWnd && (info.dwFlags & VMR9Sample_Preroll))
323 {
324 return S_OK;
325 }
326
327 hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
328 if (FAILED(hr))
329 {
330 ERR("Cannot get pointer to sample data (%x)\n", hr);
331 return hr;
332 }
333
334 cbSrcStream = IMediaSample_GetActualDataLength(pSample);
335
336 info.rtStart = tStart;
337 info.rtEnd = tStop;
338 info.szAspectRatio.cx = This->bmiheader.biWidth;
339 info.szAspectRatio.cy = This->bmiheader.biHeight;
340
341 hr = IVMRSurfaceAllocatorEx9_GetSurface(This->allocator, This->cookie, (++This->cur_surface)%This->num_surfaces, 0, &info.lpSurf);
342
343 if (FAILED(hr))
344 return hr;
345
346 VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream);
347 IDirect3DSurface9_Release(info.lpSurf);
348
349 return hr;
350 }
351
VMR9_CheckMediaType(BaseRenderer * iface,const AM_MEDIA_TYPE * pmt)352 static HRESULT WINAPI VMR9_CheckMediaType(BaseRenderer *iface, const AM_MEDIA_TYPE * pmt)
353 {
354 struct quartz_vmr *This = (struct quartz_vmr*)iface;
355
356 if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat)
357 return S_FALSE;
358
359 /* Ignore subtype, test for bicompression instead */
360 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
361 {
362 VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
363
364 This->bmiheader = format->bmiHeader;
365 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
366 This->VideoWidth = format->bmiHeader.biWidth;
367 This->VideoHeight = format->bmiHeader.biHeight;
368 SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight);
369 }
370 else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
371 {
372 VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat;
373
374 This->bmiheader = format->bmiHeader;
375
376 TRACE("Resolution: %dx%d\n", format->bmiHeader.biWidth, format->bmiHeader.biHeight);
377 This->VideoWidth = format->bmiHeader.biWidth;
378 This->VideoHeight = format->bmiHeader.biHeight;
379 SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight);
380 }
381 else
382 {
383 ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
384 return S_FALSE;
385 }
386 if (This->bmiheader.biCompression != BI_RGB)
387 return S_FALSE;
388 return S_OK;
389 }
390
VMR9_maybe_init(struct quartz_vmr * This,BOOL force)391 static HRESULT VMR9_maybe_init(struct quartz_vmr *This, BOOL force)
392 {
393 VMR9AllocationInfo info;
394 DWORD buffers;
395 HRESULT hr;
396
397 TRACE("my mode: %u, my window: %p, my last window: %p\n", This->mode, This->baseControlWindow.baseWindow.hWnd, This->hWndClippingWindow);
398 if (This->baseControlWindow.baseWindow.hWnd || !This->renderer.pInputPin->pin.pConnectedTo)
399 return S_OK;
400
401 if (This->mode == VMR9Mode_Windowless && !This->hWndClippingWindow)
402 return (force ? VFW_E_RUNTIME_ERROR : S_OK);
403
404 TRACE("Initializing\n");
405 info.dwFlags = VMR9AllocFlag_TextureSurface;
406 info.dwHeight = This->source_rect.bottom;
407 info.dwWidth = This->source_rect.right;
408 info.Pool = D3DPOOL_DEFAULT;
409 info.MinBuffers = 2;
410 FIXME("Reduce ratio to least common denominator\n");
411 info.szAspectRatio.cx = info.dwWidth;
412 info.szAspectRatio.cy = info.dwHeight;
413 info.szNativeSize.cx = This->bmiheader.biWidth;
414 info.szNativeSize.cy = This->bmiheader.biHeight;
415 buffers = 2;
416
417 switch (This->bmiheader.biBitCount)
418 {
419 case 8: info.Format = D3DFMT_R3G3B2; break;
420 case 15: info.Format = D3DFMT_X1R5G5B5; break;
421 case 16: info.Format = D3DFMT_R5G6B5; break;
422 case 24: info.Format = D3DFMT_R8G8B8; break;
423 case 32: info.Format = D3DFMT_X8R8G8B8; break;
424 default:
425 FIXME("Unknown bpp %u\n", This->bmiheader.biBitCount);
426 hr = E_INVALIDARG;
427 }
428
429 This->cur_surface = 0;
430 if (This->num_surfaces)
431 {
432 ERR("num_surfaces or d3d9_surfaces not 0\n");
433 return E_FAIL;
434 }
435
436 hr = IVMRSurfaceAllocatorEx9_InitializeDevice(This->allocator, This->cookie, &info, &buffers);
437 if (SUCCEEDED(hr))
438 {
439 SetRect(&This->source_rect, 0, 0, This->bmiheader.biWidth, This->bmiheader.biHeight);
440
441 This->num_surfaces = buffers;
442 }
443 return hr;
444 }
445
VMR9_OnStartStreaming(BaseRenderer * iface)446 static VOID WINAPI VMR9_OnStartStreaming(BaseRenderer* iface)
447 {
448 struct quartz_vmr *This = (struct quartz_vmr*)iface;
449
450 TRACE("(%p)\n", This);
451
452 VMR9_maybe_init(This, TRUE);
453 IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie);
454 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
455 This->source_rect.left,
456 This->source_rect.top,
457 This->source_rect.right - This->source_rect.left,
458 This->source_rect.bottom - This->source_rect.top,
459 SWP_NOZORDER|SWP_NOMOVE|SWP_DEFERERASE);
460 ShowWindow(This->baseControlWindow.baseWindow.hWnd, SW_SHOW);
461 GetClientRect(This->baseControlWindow.baseWindow.hWnd, &This->target_rect);
462 }
463
VMR9_OnStopStreaming(BaseRenderer * iface)464 static VOID WINAPI VMR9_OnStopStreaming(BaseRenderer* iface)
465 {
466 struct quartz_vmr *This = (struct quartz_vmr*)iface;
467
468 TRACE("(%p)\n", This);
469
470 if (This->renderer.filter.state == State_Running)
471 IVMRImagePresenter9_StopPresenting(This->presenter, This->cookie);
472 }
473
VMR9_ShouldDrawSampleNow(BaseRenderer * This,IMediaSample * pSample,REFERENCE_TIME * pStartTime,REFERENCE_TIME * pEndTime)474 static HRESULT WINAPI VMR9_ShouldDrawSampleNow(BaseRenderer *This, IMediaSample *pSample, REFERENCE_TIME *pStartTime, REFERENCE_TIME *pEndTime)
475 {
476 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
477 if (IMediaSample_IsPreroll(pSample) == S_OK)
478 return E_FAIL;
479 return S_FALSE;
480 }
481
VMR9_CompleteConnect(BaseRenderer * This,IPin * pReceivePin)482 static HRESULT WINAPI VMR9_CompleteConnect(BaseRenderer *This, IPin *pReceivePin)
483 {
484 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This;
485 HRESULT hr;
486
487 TRACE("(%p)\n", This);
488
489 if (pVMR9->mode ||
490 SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&pVMR9->IVMRFilterConfig9_iface, VMR9Mode_Windowed)))
491 hr = VMR9_maybe_init(pVMR9, FALSE);
492
493 return hr;
494 }
495
VMR9_BreakConnect(BaseRenderer * This)496 static HRESULT WINAPI VMR9_BreakConnect(BaseRenderer *This)
497 {
498 struct quartz_vmr *pVMR9 = (struct quartz_vmr*)This;
499 HRESULT hr = S_OK;
500
501 if (!pVMR9->mode)
502 return S_FALSE;
503 if (This->pInputPin->pin.pConnectedTo && pVMR9->allocator && pVMR9->presenter)
504 {
505 if (pVMR9->renderer.filter.state != State_Stopped)
506 {
507 ERR("Disconnecting while not stopped! UNTESTED!!\n");
508 }
509 if (pVMR9->renderer.filter.state == State_Running)
510 hr = IVMRImagePresenter9_StopPresenting(pVMR9->presenter, pVMR9->cookie);
511 IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9->allocator, pVMR9->cookie);
512 pVMR9->num_surfaces = 0;
513 }
514 return hr;
515 }
516
517 static const BaseRendererFuncTable BaseFuncTable = {
518 VMR9_CheckMediaType,
519 VMR9_DoRenderSample,
520 /**/
521 NULL,
522 NULL,
523 NULL,
524 VMR9_OnStartStreaming,
525 VMR9_OnStopStreaming,
526 NULL,
527 NULL,
528 NULL,
529 VMR9_ShouldDrawSampleNow,
530 NULL,
531 /**/
532 VMR9_CompleteConnect,
533 VMR9_BreakConnect,
534 NULL,
535 NULL,
536 NULL,
537 };
538
VMR9_GetClassWindowStyles(BaseWindow * This,DWORD * pClassStyles,DWORD * pWindowStyles,DWORD * pWindowStylesEx)539 static LPWSTR WINAPI VMR9_GetClassWindowStyles(BaseWindow *This, DWORD *pClassStyles, DWORD *pWindowStyles, DWORD *pWindowStylesEx)
540 {
541 static WCHAR classnameW[] = { 'I','V','M','R','9',' ','C','l','a','s','s', 0 };
542
543 *pClassStyles = 0;
544 *pWindowStyles = WS_SIZEBOX;
545 *pWindowStylesEx = 0;
546
547 return classnameW;
548 }
549
VMR9_GetDefaultRect(BaseWindow * This)550 static RECT WINAPI VMR9_GetDefaultRect(BaseWindow *This)
551 {
552 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
553 static RECT defRect;
554
555 SetRect(&defRect, 0, 0, pVMR9->VideoWidth, pVMR9->VideoHeight);
556
557 return defRect;
558 }
559
VMR9_OnSize(BaseWindow * This,LONG Width,LONG Height)560 static BOOL WINAPI VMR9_OnSize(BaseWindow *This, LONG Width, LONG Height)
561 {
562 struct quartz_vmr* pVMR9 = impl_from_BaseWindow(This);
563
564 TRACE("WM_SIZE %d %d\n", Width, Height);
565 GetClientRect(This->hWnd, &pVMR9->target_rect);
566 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
567 pVMR9->target_rect.left,
568 pVMR9->target_rect.top,
569 pVMR9->target_rect.right - pVMR9->target_rect.left,
570 pVMR9->target_rect.bottom - pVMR9->target_rect.top);
571 return BaseWindowImpl_OnSize(This, Width, Height);
572 }
573
574 static const BaseWindowFuncTable renderer_BaseWindowFuncTable = {
575 VMR9_GetClassWindowStyles,
576 VMR9_GetDefaultRect,
577 NULL,
578 BaseControlWindowImpl_PossiblyEatMessage,
579 VMR9_OnSize,
580 };
581
VMR9_GetSourceRect(BaseControlVideo * This,RECT * pSourceRect)582 static HRESULT WINAPI VMR9_GetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
583 {
584 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
585 CopyRect(pSourceRect,&pVMR9->source_rect);
586 return S_OK;
587 }
588
VMR9_GetStaticImage(BaseControlVideo * This,LONG * pBufferSize,LONG * pDIBImage)589 static HRESULT WINAPI VMR9_GetStaticImage(BaseControlVideo* This, LONG *pBufferSize, LONG *pDIBImage)
590 {
591 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
592 BITMAPINFOHEADER *bmiHeader;
593 LONG needed_size;
594 AM_MEDIA_TYPE *amt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
595 char *ptr;
596
597 FIXME("(%p/%p)->(%p, %p): partial stub\n", pVMR9, This, pBufferSize, pDIBImage);
598
599 EnterCriticalSection(&pVMR9->renderer.filter.csFilter);
600
601 if (!pVMR9->renderer.pMediaSample)
602 {
603 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
604 return (pVMR9->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
605 }
606
607 if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
608 {
609 bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
610 }
611 else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
612 {
613 bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
614 }
615 else
616 {
617 FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
618 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
619 return VFW_E_RUNTIME_ERROR;
620 }
621
622 needed_size = bmiHeader->biSize;
623 needed_size += IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample);
624
625 if (!pDIBImage)
626 {
627 *pBufferSize = needed_size;
628 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
629 return S_OK;
630 }
631
632 if (needed_size < *pBufferSize)
633 {
634 ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
635 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
636 return E_FAIL;
637 }
638 *pBufferSize = needed_size;
639
640 memcpy(pDIBImage, bmiHeader, bmiHeader->biSize);
641 IMediaSample_GetPointer(pVMR9->renderer.pMediaSample, (BYTE **)&ptr);
642 memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample));
643
644 LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
645 return S_OK;
646 }
647
VMR9_GetTargetRect(BaseControlVideo * This,RECT * pTargetRect)648 static HRESULT WINAPI VMR9_GetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
649 {
650 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
651 CopyRect(pTargetRect,&pVMR9->target_rect);
652 return S_OK;
653 }
654
VMR9_GetVideoFormat(BaseControlVideo * This)655 static VIDEOINFOHEADER* WINAPI VMR9_GetVideoFormat(BaseControlVideo* This)
656 {
657 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
658 AM_MEDIA_TYPE *pmt;
659
660 TRACE("(%p/%p)\n", pVMR9, This);
661
662 pmt = &pVMR9->renderer.pInputPin->pin.mtCurrent;
663 if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)) {
664 return (VIDEOINFOHEADER*)pmt->pbFormat;
665 } else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2)) {
666 static VIDEOINFOHEADER vih;
667 VIDEOINFOHEADER2 *vih2 = (VIDEOINFOHEADER2*)pmt->pbFormat;
668 memcpy(&vih,vih2,sizeof(VIDEOINFOHEADER));
669 memcpy(&vih.bmiHeader, &vih2->bmiHeader, sizeof(BITMAPINFOHEADER));
670 return &vih;
671 } else {
672 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt->formattype));
673 return NULL;
674 }
675 }
676
VMR9_IsDefaultSourceRect(BaseControlVideo * This)677 static HRESULT WINAPI VMR9_IsDefaultSourceRect(BaseControlVideo* This)
678 {
679 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
680 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
681
682 return S_OK;
683 }
684
VMR9_IsDefaultTargetRect(BaseControlVideo * This)685 static HRESULT WINAPI VMR9_IsDefaultTargetRect(BaseControlVideo* This)
686 {
687 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
688 FIXME("(%p/%p)->(): stub !!!\n", pVMR9, This);
689
690 return S_OK;
691 }
692
VMR9_SetDefaultSourceRect(BaseControlVideo * This)693 static HRESULT WINAPI VMR9_SetDefaultSourceRect(BaseControlVideo* This)
694 {
695 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
696
697 SetRect(&pVMR9->source_rect, 0, 0, pVMR9->VideoWidth, pVMR9->VideoHeight);
698
699 return S_OK;
700 }
701
VMR9_SetDefaultTargetRect(BaseControlVideo * This)702 static HRESULT WINAPI VMR9_SetDefaultTargetRect(BaseControlVideo* This)
703 {
704 RECT rect;
705 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
706
707 if (!GetClientRect(pVMR9->baseControlWindow.baseWindow.hWnd, &rect))
708 return E_FAIL;
709
710 SetRect(&pVMR9->target_rect, 0, 0, rect.right, rect.bottom);
711
712 return S_OK;
713 }
714
VMR9_SetSourceRect(BaseControlVideo * This,RECT * pSourceRect)715 static HRESULT WINAPI VMR9_SetSourceRect(BaseControlVideo* This, RECT *pSourceRect)
716 {
717 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
718 CopyRect(&pVMR9->source_rect,pSourceRect);
719 return S_OK;
720 }
721
VMR9_SetTargetRect(BaseControlVideo * This,RECT * pTargetRect)722 static HRESULT WINAPI VMR9_SetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
723 {
724 struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
725 CopyRect(&pVMR9->target_rect,pTargetRect);
726 return S_OK;
727 }
728
729 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable = {
730 VMR9_GetSourceRect,
731 VMR9_GetStaticImage,
732 VMR9_GetTargetRect,
733 VMR9_GetVideoFormat,
734 VMR9_IsDefaultSourceRect,
735 VMR9_IsDefaultTargetRect,
736 VMR9_SetDefaultSourceRect,
737 VMR9_SetDefaultTargetRect,
738 VMR9_SetSourceRect,
739 VMR9_SetTargetRect
740 };
741
VMR9Inner_QueryInterface(IUnknown * iface,REFIID riid,LPVOID * ppv)742 static HRESULT WINAPI VMR9Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv)
743 {
744 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
745 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
746
747 if (This->bAggregatable)
748 This->bUnkOuterValid = TRUE;
749
750 *ppv = NULL;
751
752 if (IsEqualIID(riid, &IID_IUnknown))
753 *ppv = &This->IUnknown_inner;
754 else if (IsEqualIID(riid, &IID_IVideoWindow))
755 *ppv = &This->baseControlWindow.IVideoWindow_iface;
756 else if (IsEqualIID(riid, &IID_IBasicVideo))
757 *ppv = &This->baseControlVideo.IBasicVideo_iface;
758 else if (IsEqualIID(riid, &IID_IAMCertifiedOutputProtection))
759 *ppv = &This->IAMCertifiedOutputProtection_iface;
760 else if (IsEqualIID(riid, &IID_IAMFilterMiscFlags))
761 *ppv = &This->IAMFilterMiscFlags_iface;
762 else if (IsEqualIID(riid, &IID_IVMRFilterConfig))
763 *ppv = &This->IVMRFilterConfig_iface;
764 else if (IsEqualIID(riid, &IID_IVMRFilterConfig9))
765 *ppv = &This->IVMRFilterConfig9_iface;
766 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig))
767 *ppv = &This->IVMRMonitorConfig_iface;
768 else if (IsEqualIID(riid, &IID_IVMRMonitorConfig9))
769 *ppv = &This->IVMRMonitorConfig9_iface;
770 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify) && This->mode == (VMR9Mode)VMRMode_Renderless)
771 *ppv = &This->IVMRSurfaceAllocatorNotify_iface;
772 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9) && This->mode == VMR9Mode_Renderless)
773 *ppv = &This->IVMRSurfaceAllocatorNotify9_iface;
774 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl) && This->mode == (VMR9Mode)VMRMode_Windowless)
775 *ppv = &This->IVMRWindowlessControl_iface;
776 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9) && This->mode == VMR9Mode_Windowless)
777 *ppv = &This->IVMRWindowlessControl9_iface;
778 else
779 {
780 HRESULT hr;
781 hr = BaseRendererImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
782 if (SUCCEEDED(hr))
783 return hr;
784 }
785
786 if (*ppv)
787 {
788 IUnknown_AddRef((IUnknown *)(*ppv));
789 return S_OK;
790 }
791
792 else if (IsEqualIID(riid, &IID_IBasicVideo2))
793 FIXME("No interface for IID_IBasicVideo2\n");
794 else if (IsEqualIID(riid, &IID_IVMRWindowlessControl9))
795 ;
796 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorNotify9))
797 ;
798 else if (IsEqualIID(riid, &IID_IMediaPosition))
799 FIXME("No interface for IID_IMediaPosition\n");
800 else if (IsEqualIID(riid, &IID_IQualProp))
801 FIXME("No interface for IID_IQualProp\n");
802 else if (IsEqualIID(riid, &IID_IVMRAspectRatioControl9))
803 FIXME("No interface for IID_IVMRAspectRatioControl9\n");
804 else if (IsEqualIID(riid, &IID_IVMRDeinterlaceControl9))
805 FIXME("No interface for IID_IVMRDeinterlaceControl9\n");
806 else if (IsEqualIID(riid, &IID_IVMRMixerBitmap9))
807 FIXME("No interface for IID_IVMRMixerBitmap9\n");
808 else if (IsEqualIID(riid, &IID_IVMRMixerControl9))
809 FIXME("No interface for IID_IVMRMixerControl9\n");
810 else
811 FIXME("No interface for %s\n", debugstr_guid(riid));
812
813 return E_NOINTERFACE;
814 }
815
VMR9Inner_AddRef(IUnknown * iface)816 static ULONG WINAPI VMR9Inner_AddRef(IUnknown * iface)
817 {
818 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
819 ULONG refCount = BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
820
821 TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1);
822
823 return refCount;
824 }
825
VMR9Inner_Release(IUnknown * iface)826 static ULONG WINAPI VMR9Inner_Release(IUnknown * iface)
827 {
828 struct quartz_vmr *This = impl_from_inner_IUnknown(iface);
829 ULONG refCount = BaseRendererImpl_Release(&This->renderer.filter.IBaseFilter_iface);
830
831 TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1);
832
833 if (!refCount)
834 {
835 TRACE("Destroying\n");
836 BaseControlWindow_Destroy(&This->baseControlWindow);
837 FreeLibrary(This->hD3d9);
838
839 if (This->allocator)
840 IVMRSurfaceAllocatorEx9_Release(This->allocator);
841 if (This->presenter)
842 IVMRImagePresenter9_Release(This->presenter);
843
844 This->num_surfaces = 0;
845 if (This->allocator_d3d9_dev)
846 {
847 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
848 This->allocator_d3d9_dev = NULL;
849 }
850
851 CoTaskMemFree(This);
852 }
853 return refCount;
854 }
855
856 static const IUnknownVtbl IInner_VTable =
857 {
858 VMR9Inner_QueryInterface,
859 VMR9Inner_AddRef,
860 VMR9Inner_Release
861 };
862
VMR9_QueryInterface(IBaseFilter * iface,REFIID riid,LPVOID * ppv)863 static HRESULT WINAPI VMR9_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
864 {
865 struct quartz_vmr *This = (struct quartz_vmr*)iface;
866
867 if (This->bAggregatable)
868 This->bUnkOuterValid = TRUE;
869
870 if (This->outer_unk)
871 {
872 if (This->bAggregatable)
873 return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
874
875 if (IsEqualIID(riid, &IID_IUnknown))
876 {
877 HRESULT hr;
878
879 IUnknown_AddRef(&This->IUnknown_inner);
880 hr = IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
881 IUnknown_Release(&This->IUnknown_inner);
882 This->bAggregatable = TRUE;
883 return hr;
884 }
885
886 *ppv = NULL;
887 return E_NOINTERFACE;
888 }
889
890 return IUnknown_QueryInterface(&This->IUnknown_inner, riid, ppv);
891 }
892
VMR9_AddRef(IBaseFilter * iface)893 static ULONG WINAPI VMR9_AddRef(IBaseFilter * iface)
894 {
895 struct quartz_vmr *This = (struct quartz_vmr*)iface;
896 LONG ret;
897
898 if (This->outer_unk && This->bUnkOuterValid)
899 ret = IUnknown_AddRef(This->outer_unk);
900 else
901 ret = IUnknown_AddRef(&This->IUnknown_inner);
902
903 TRACE("(%p)->AddRef from %d\n", iface, ret - 1);
904
905 return ret;
906 }
907
VMR9_Release(IBaseFilter * iface)908 static ULONG WINAPI VMR9_Release(IBaseFilter * iface)
909 {
910 struct quartz_vmr *This = (struct quartz_vmr*)iface;
911 LONG ret;
912
913 if (This->outer_unk && This->bUnkOuterValid)
914 ret = IUnknown_Release(This->outer_unk);
915 else
916 ret = IUnknown_Release(&This->IUnknown_inner);
917
918 TRACE("(%p)->Release from %d\n", iface, ret + 1);
919
920 if (ret)
921 return ret;
922 return 0;
923 }
924
925 static const IBaseFilterVtbl VMR_Vtbl =
926 {
927 VMR9_QueryInterface,
928 VMR9_AddRef,
929 VMR9_Release,
930 BaseFilterImpl_GetClassID,
931 BaseRendererImpl_Stop,
932 BaseRendererImpl_Pause,
933 BaseRendererImpl_Run,
934 BaseRendererImpl_GetState,
935 BaseRendererImpl_SetSyncSource,
936 BaseFilterImpl_GetSyncSource,
937 BaseFilterImpl_EnumPins,
938 BaseRendererImpl_FindPin,
939 BaseFilterImpl_QueryFilterInfo,
940 BaseFilterImpl_JoinFilterGraph,
941 BaseFilterImpl_QueryVendorInfo
942 };
943
944 /*** IUnknown methods ***/
Videowindow_QueryInterface(IVideoWindow * iface,REFIID riid,LPVOID * ppvObj)945 static HRESULT WINAPI Videowindow_QueryInterface(IVideoWindow *iface, REFIID riid, LPVOID*ppvObj)
946 {
947 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
948
949 TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppvObj);
950
951 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
952 }
953
Videowindow_AddRef(IVideoWindow * iface)954 static ULONG WINAPI Videowindow_AddRef(IVideoWindow *iface)
955 {
956 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
957
958 TRACE("(%p/%p)->()\n", This, iface);
959
960 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
961 }
962
Videowindow_Release(IVideoWindow * iface)963 static ULONG WINAPI Videowindow_Release(IVideoWindow *iface)
964 {
965 struct quartz_vmr *This = impl_from_IVideoWindow(iface);
966
967 TRACE("(%p/%p)->()\n", This, iface);
968
969 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
970 }
971
972 static const IVideoWindowVtbl IVideoWindow_VTable =
973 {
974 Videowindow_QueryInterface,
975 Videowindow_AddRef,
976 Videowindow_Release,
977 BaseControlWindowImpl_GetTypeInfoCount,
978 BaseControlWindowImpl_GetTypeInfo,
979 BaseControlWindowImpl_GetIDsOfNames,
980 BaseControlWindowImpl_Invoke,
981 BaseControlWindowImpl_put_Caption,
982 BaseControlWindowImpl_get_Caption,
983 BaseControlWindowImpl_put_WindowStyle,
984 BaseControlWindowImpl_get_WindowStyle,
985 BaseControlWindowImpl_put_WindowStyleEx,
986 BaseControlWindowImpl_get_WindowStyleEx,
987 BaseControlWindowImpl_put_AutoShow,
988 BaseControlWindowImpl_get_AutoShow,
989 BaseControlWindowImpl_put_WindowState,
990 BaseControlWindowImpl_get_WindowState,
991 BaseControlWindowImpl_put_BackgroundPalette,
992 BaseControlWindowImpl_get_BackgroundPalette,
993 BaseControlWindowImpl_put_Visible,
994 BaseControlWindowImpl_get_Visible,
995 BaseControlWindowImpl_put_Left,
996 BaseControlWindowImpl_get_Left,
997 BaseControlWindowImpl_put_Width,
998 BaseControlWindowImpl_get_Width,
999 BaseControlWindowImpl_put_Top,
1000 BaseControlWindowImpl_get_Top,
1001 BaseControlWindowImpl_put_Height,
1002 BaseControlWindowImpl_get_Height,
1003 BaseControlWindowImpl_put_Owner,
1004 BaseControlWindowImpl_get_Owner,
1005 BaseControlWindowImpl_put_MessageDrain,
1006 BaseControlWindowImpl_get_MessageDrain,
1007 BaseControlWindowImpl_get_BorderColor,
1008 BaseControlWindowImpl_put_BorderColor,
1009 BaseControlWindowImpl_get_FullScreenMode,
1010 BaseControlWindowImpl_put_FullScreenMode,
1011 BaseControlWindowImpl_SetWindowForeground,
1012 BaseControlWindowImpl_NotifyOwnerMessage,
1013 BaseControlWindowImpl_SetWindowPosition,
1014 BaseControlWindowImpl_GetWindowPosition,
1015 BaseControlWindowImpl_GetMinIdealImageSize,
1016 BaseControlWindowImpl_GetMaxIdealImageSize,
1017 BaseControlWindowImpl_GetRestorePosition,
1018 BaseControlWindowImpl_HideCursor,
1019 BaseControlWindowImpl_IsCursorHidden
1020 };
1021
1022 /*** IUnknown methods ***/
Basicvideo_QueryInterface(IBasicVideo * iface,REFIID riid,LPVOID * ppvObj)1023 static HRESULT WINAPI Basicvideo_QueryInterface(IBasicVideo *iface, REFIID riid, LPVOID * ppvObj)
1024 {
1025 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1026
1027 TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppvObj);
1028
1029 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
1030 }
1031
Basicvideo_AddRef(IBasicVideo * iface)1032 static ULONG WINAPI Basicvideo_AddRef(IBasicVideo *iface)
1033 {
1034 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1035
1036 TRACE("(%p/%p)->()\n", This, iface);
1037
1038 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1039 }
1040
Basicvideo_Release(IBasicVideo * iface)1041 static ULONG WINAPI Basicvideo_Release(IBasicVideo *iface)
1042 {
1043 struct quartz_vmr *This = impl_from_IBasicVideo(iface);
1044
1045 TRACE("(%p/%p)->()\n", This, iface);
1046
1047 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1048 }
1049
1050 static const IBasicVideoVtbl IBasicVideo_VTable =
1051 {
1052 Basicvideo_QueryInterface,
1053 Basicvideo_AddRef,
1054 Basicvideo_Release,
1055 BaseControlVideoImpl_GetTypeInfoCount,
1056 BaseControlVideoImpl_GetTypeInfo,
1057 BaseControlVideoImpl_GetIDsOfNames,
1058 BaseControlVideoImpl_Invoke,
1059 BaseControlVideoImpl_get_AvgTimePerFrame,
1060 BaseControlVideoImpl_get_BitRate,
1061 BaseControlVideoImpl_get_BitErrorRate,
1062 BaseControlVideoImpl_get_VideoWidth,
1063 BaseControlVideoImpl_get_VideoHeight,
1064 BaseControlVideoImpl_put_SourceLeft,
1065 BaseControlVideoImpl_get_SourceLeft,
1066 BaseControlVideoImpl_put_SourceWidth,
1067 BaseControlVideoImpl_get_SourceWidth,
1068 BaseControlVideoImpl_put_SourceTop,
1069 BaseControlVideoImpl_get_SourceTop,
1070 BaseControlVideoImpl_put_SourceHeight,
1071 BaseControlVideoImpl_get_SourceHeight,
1072 BaseControlVideoImpl_put_DestinationLeft,
1073 BaseControlVideoImpl_get_DestinationLeft,
1074 BaseControlVideoImpl_put_DestinationWidth,
1075 BaseControlVideoImpl_get_DestinationWidth,
1076 BaseControlVideoImpl_put_DestinationTop,
1077 BaseControlVideoImpl_get_DestinationTop,
1078 BaseControlVideoImpl_put_DestinationHeight,
1079 BaseControlVideoImpl_get_DestinationHeight,
1080 BaseControlVideoImpl_SetSourcePosition,
1081 BaseControlVideoImpl_GetSourcePosition,
1082 BaseControlVideoImpl_SetDefaultSourcePosition,
1083 BaseControlVideoImpl_SetDestinationPosition,
1084 BaseControlVideoImpl_GetDestinationPosition,
1085 BaseControlVideoImpl_SetDefaultDestinationPosition,
1086 BaseControlVideoImpl_GetVideoSize,
1087 BaseControlVideoImpl_GetVideoPaletteEntries,
1088 BaseControlVideoImpl_GetCurrentImage,
1089 BaseControlVideoImpl_IsUsingDefaultSource,
1090 BaseControlVideoImpl_IsUsingDefaultDestination
1091 };
1092
AMCertifiedOutputProtection_QueryInterface(IAMCertifiedOutputProtection * iface,REFIID riid,void ** ppv)1093 static HRESULT WINAPI AMCertifiedOutputProtection_QueryInterface(IAMCertifiedOutputProtection *iface,
1094 REFIID riid, void **ppv)
1095 {
1096 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1097 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1098 }
1099
AMCertifiedOutputProtection_AddRef(IAMCertifiedOutputProtection * iface)1100 static ULONG WINAPI AMCertifiedOutputProtection_AddRef(IAMCertifiedOutputProtection *iface)
1101 {
1102 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1103 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1104 }
1105
AMCertifiedOutputProtection_Release(IAMCertifiedOutputProtection * iface)1106 static ULONG WINAPI AMCertifiedOutputProtection_Release(IAMCertifiedOutputProtection *iface)
1107 {
1108 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1109 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1110 }
1111
AMCertifiedOutputProtection_KeyExchange(IAMCertifiedOutputProtection * iface,GUID * pRandom,BYTE ** VarLenCertGH,DWORD * pdwLengthCertGH)1112 static HRESULT WINAPI AMCertifiedOutputProtection_KeyExchange(IAMCertifiedOutputProtection *iface,
1113 GUID* pRandom, BYTE** VarLenCertGH,
1114 DWORD* pdwLengthCertGH)
1115 {
1116 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1117
1118 FIXME("(%p/%p)->(%p, %p, %p) stub\n", iface, This, pRandom, VarLenCertGH, pdwLengthCertGH);
1119 return VFW_E_NO_COPP_HW;
1120 }
1121
AMCertifiedOutputProtection_SessionSequenceStart(IAMCertifiedOutputProtection * iface,AMCOPPSignature * pSig)1122 static HRESULT WINAPI AMCertifiedOutputProtection_SessionSequenceStart(IAMCertifiedOutputProtection *iface,
1123 AMCOPPSignature* pSig)
1124 {
1125 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1126
1127 FIXME("(%p/%p)->(%p) stub\n", iface, This, pSig);
1128 return VFW_E_NO_COPP_HW;
1129 }
1130
AMCertifiedOutputProtection_ProtectionCommand(IAMCertifiedOutputProtection * iface,const AMCOPPCommand * cmd)1131 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionCommand(IAMCertifiedOutputProtection *iface,
1132 const AMCOPPCommand* cmd)
1133 {
1134 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1135
1136 FIXME("(%p/%p)->(%p) stub\n", iface, This, cmd);
1137 return VFW_E_NO_COPP_HW;
1138 }
1139
AMCertifiedOutputProtection_ProtectionStatus(IAMCertifiedOutputProtection * iface,const AMCOPPStatusInput * pStatusInput,AMCOPPStatusOutput * pStatusOutput)1140 static HRESULT WINAPI AMCertifiedOutputProtection_ProtectionStatus(IAMCertifiedOutputProtection *iface,
1141 const AMCOPPStatusInput* pStatusInput,
1142 AMCOPPStatusOutput* pStatusOutput)
1143 {
1144 struct quartz_vmr *This = impl_from_IAMCertifiedOutputProtection(iface);
1145
1146 FIXME("(%p/%p)->(%p, %p) stub\n", iface, This, pStatusInput, pStatusOutput);
1147 return VFW_E_NO_COPP_HW;
1148 }
1149
1150 static const IAMCertifiedOutputProtectionVtbl IAMCertifiedOutputProtection_Vtbl =
1151 {
1152 AMCertifiedOutputProtection_QueryInterface,
1153 AMCertifiedOutputProtection_AddRef,
1154 AMCertifiedOutputProtection_Release,
1155 AMCertifiedOutputProtection_KeyExchange,
1156 AMCertifiedOutputProtection_SessionSequenceStart,
1157 AMCertifiedOutputProtection_ProtectionCommand,
1158 AMCertifiedOutputProtection_ProtectionStatus
1159 };
1160
AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags * iface,REFIID riid,void ** ppv)1161 static HRESULT WINAPI AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags *iface, REFIID riid, void **ppv) {
1162 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1163 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1164 }
1165
AMFilterMiscFlags_AddRef(IAMFilterMiscFlags * iface)1166 static ULONG WINAPI AMFilterMiscFlags_AddRef(IAMFilterMiscFlags *iface) {
1167 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1168 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1169 }
1170
AMFilterMiscFlags_Release(IAMFilterMiscFlags * iface)1171 static ULONG WINAPI AMFilterMiscFlags_Release(IAMFilterMiscFlags *iface) {
1172 struct quartz_vmr *This = impl_from_IAMFilterMiscFlags(iface);
1173 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1174 }
1175
AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags * iface)1176 static ULONG WINAPI AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags *iface) {
1177 return AM_FILTER_MISC_FLAGS_IS_RENDERER;
1178 }
1179
1180 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl = {
1181 AMFilterMiscFlags_QueryInterface,
1182 AMFilterMiscFlags_AddRef,
1183 AMFilterMiscFlags_Release,
1184 AMFilterMiscFlags_GetMiscFlags
1185 };
1186
VMR7FilterConfig_QueryInterface(IVMRFilterConfig * iface,REFIID riid,void ** ppv)1187 static HRESULT WINAPI VMR7FilterConfig_QueryInterface(IVMRFilterConfig *iface, REFIID riid,
1188 void** ppv)
1189 {
1190 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1191 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1192 }
1193
VMR7FilterConfig_AddRef(IVMRFilterConfig * iface)1194 static ULONG WINAPI VMR7FilterConfig_AddRef(IVMRFilterConfig *iface)
1195 {
1196 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1197 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1198 }
1199
VMR7FilterConfig_Release(IVMRFilterConfig * iface)1200 static ULONG WINAPI VMR7FilterConfig_Release(IVMRFilterConfig *iface)
1201 {
1202 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1203 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1204 }
1205
VMR7FilterConfig_SetImageCompositor(IVMRFilterConfig * iface,IVMRImageCompositor * compositor)1206 static HRESULT WINAPI VMR7FilterConfig_SetImageCompositor(IVMRFilterConfig *iface,
1207 IVMRImageCompositor *compositor)
1208 {
1209 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1210
1211 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
1212 return E_NOTIMPL;
1213 }
1214
VMR7FilterConfig_SetNumberOfStreams(IVMRFilterConfig * iface,DWORD max)1215 static HRESULT WINAPI VMR7FilterConfig_SetNumberOfStreams(IVMRFilterConfig *iface, DWORD max)
1216 {
1217 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1218
1219 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
1220 return E_NOTIMPL;
1221 }
1222
VMR7FilterConfig_GetNumberOfStreams(IVMRFilterConfig * iface,DWORD * max)1223 static HRESULT WINAPI VMR7FilterConfig_GetNumberOfStreams(IVMRFilterConfig *iface, DWORD *max)
1224 {
1225 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1226
1227 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
1228 return E_NOTIMPL;
1229 }
1230
VMR7FilterConfig_SetRenderingPrefs(IVMRFilterConfig * iface,DWORD renderflags)1231 static HRESULT WINAPI VMR7FilterConfig_SetRenderingPrefs(IVMRFilterConfig *iface, DWORD renderflags)
1232 {
1233 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1234
1235 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
1236 return E_NOTIMPL;
1237 }
1238
VMR7FilterConfig_GetRenderingPrefs(IVMRFilterConfig * iface,DWORD * renderflags)1239 static HRESULT WINAPI VMR7FilterConfig_GetRenderingPrefs(IVMRFilterConfig *iface, DWORD *renderflags)
1240 {
1241 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1242
1243 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
1244 return E_NOTIMPL;
1245 }
1246
VMR7FilterConfig_SetRenderingMode(IVMRFilterConfig * iface,DWORD mode)1247 static HRESULT WINAPI VMR7FilterConfig_SetRenderingMode(IVMRFilterConfig *iface, DWORD mode)
1248 {
1249 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1250
1251 FIXME("(%p/%p)->(%u) stub\n", iface, This, mode);
1252 return E_NOTIMPL;
1253 }
1254
VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig * iface,DWORD * mode)1255 static HRESULT WINAPI VMR7FilterConfig_GetRenderingMode(IVMRFilterConfig *iface, DWORD *mode)
1256 {
1257 struct quartz_vmr *This = impl_from_IVMRFilterConfig(iface);
1258
1259 TRACE("(%p/%p)->(%p)\n", iface, This, mode);
1260 if (!mode) return E_POINTER;
1261
1262 if (This->mode)
1263 *mode = This->mode;
1264 else
1265 *mode = VMRMode_Windowed;
1266
1267 return S_OK;
1268 }
1269
1270 static const IVMRFilterConfigVtbl VMR7_FilterConfig_Vtbl =
1271 {
1272 VMR7FilterConfig_QueryInterface,
1273 VMR7FilterConfig_AddRef,
1274 VMR7FilterConfig_Release,
1275 VMR7FilterConfig_SetImageCompositor,
1276 VMR7FilterConfig_SetNumberOfStreams,
1277 VMR7FilterConfig_GetNumberOfStreams,
1278 VMR7FilterConfig_SetRenderingPrefs,
1279 VMR7FilterConfig_GetRenderingPrefs,
1280 VMR7FilterConfig_SetRenderingMode,
1281 VMR7FilterConfig_GetRenderingMode
1282 };
1283
1284 struct get_available_monitors_args
1285 {
1286 VMRMONITORINFO *info7;
1287 VMR9MonitorInfo *info9;
1288 DWORD arraysize;
1289 DWORD numdev;
1290 };
1291
get_available_monitors_proc(HMONITOR hmon,HDC hdc,LPRECT lprc,LPARAM lparam)1292 static BOOL CALLBACK get_available_monitors_proc(HMONITOR hmon, HDC hdc, LPRECT lprc, LPARAM lparam)
1293 {
1294 struct get_available_monitors_args *args = (struct get_available_monitors_args *)lparam;
1295 MONITORINFOEXW mi;
1296
1297 if (args->info7 || args->info9)
1298 {
1299
1300 if (!args->arraysize)
1301 return FALSE;
1302
1303 mi.cbSize = sizeof(mi);
1304 if (!GetMonitorInfoW(hmon, (MONITORINFO*)&mi))
1305 return TRUE;
1306
1307 /* fill VMRMONITORINFO struct */
1308 if (args->info7)
1309 {
1310 VMRMONITORINFO *info = args->info7++;
1311 memset(info, 0, sizeof(*info));
1312
1313 if (args->numdev > 0)
1314 {
1315 info->guid.pGUID = &info->guid.GUID;
1316 info->guid.GUID.Data4[7] = args->numdev;
1317 }
1318 else
1319 info->guid.pGUID = NULL;
1320
1321 info->rcMonitor = mi.rcMonitor;
1322 info->hMon = hmon;
1323 info->dwFlags = mi.dwFlags;
1324
1325 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR));
1326
1327 /* FIXME: how to get these values? */
1328 info->szDescription[0] = 0;
1329 }
1330
1331 /* fill VMR9MonitorInfo struct */
1332 if (args->info9)
1333 {
1334 VMR9MonitorInfo *info = args->info9++;
1335 memset(info, 0, sizeof(*info));
1336
1337 info->uDevID = 0; /* FIXME */
1338 info->rcMonitor = mi.rcMonitor;
1339 info->hMon = hmon;
1340 info->dwFlags = mi.dwFlags;
1341
1342 lstrcpynW(info->szDevice, mi.szDevice, sizeof(info->szDevice)/sizeof(WCHAR));
1343
1344 /* FIXME: how to get these values? */
1345 info->szDescription[0] = 0;
1346 info->dwVendorId = 0;
1347 info->dwDeviceId = 0;
1348 info->dwSubSysId = 0;
1349 info->dwRevision = 0;
1350 }
1351
1352 args->arraysize--;
1353 }
1354
1355 args->numdev++;
1356 return TRUE;
1357 }
1358
VMR7MonitorConfig_QueryInterface(IVMRMonitorConfig * iface,REFIID riid,LPVOID * ppv)1359 static HRESULT WINAPI VMR7MonitorConfig_QueryInterface(IVMRMonitorConfig *iface, REFIID riid,
1360 LPVOID * ppv)
1361 {
1362 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1363 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1364 }
1365
VMR7MonitorConfig_AddRef(IVMRMonitorConfig * iface)1366 static ULONG WINAPI VMR7MonitorConfig_AddRef(IVMRMonitorConfig *iface)
1367 {
1368 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1369 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1370 }
1371
VMR7MonitorConfig_Release(IVMRMonitorConfig * iface)1372 static ULONG WINAPI VMR7MonitorConfig_Release(IVMRMonitorConfig *iface)
1373 {
1374 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1375 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1376 }
1377
VMR7MonitorConfig_SetMonitor(IVMRMonitorConfig * iface,const VMRGUID * pGUID)1378 static HRESULT WINAPI VMR7MonitorConfig_SetMonitor(IVMRMonitorConfig *iface, const VMRGUID *pGUID)
1379 {
1380 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1381
1382 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1383
1384 if (!pGUID)
1385 return E_POINTER;
1386
1387 return S_OK;
1388 }
1389
VMR7MonitorConfig_GetMonitor(IVMRMonitorConfig * iface,VMRGUID * pGUID)1390 static HRESULT WINAPI VMR7MonitorConfig_GetMonitor(IVMRMonitorConfig *iface, VMRGUID *pGUID)
1391 {
1392 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1393
1394 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1395
1396 if (!pGUID)
1397 return E_POINTER;
1398
1399 pGUID->pGUID = NULL; /* default DirectDraw device */
1400 return S_OK;
1401 }
1402
VMR7MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig * iface,const VMRGUID * pGUID)1403 static HRESULT WINAPI VMR7MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig *iface,
1404 const VMRGUID *pGUID)
1405 {
1406 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1407
1408 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1409
1410 if (!pGUID)
1411 return E_POINTER;
1412
1413 return S_OK;
1414 }
1415
VMR7MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig * iface,VMRGUID * pGUID)1416 static HRESULT WINAPI VMR7MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig *iface, VMRGUID *pGUID)
1417 {
1418 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1419
1420 FIXME("(%p/%p)->(%p) stub\n", iface, This, pGUID);
1421
1422 if (!pGUID)
1423 return E_POINTER;
1424
1425 pGUID->pGUID = NULL; /* default DirectDraw device */
1426 return S_OK;
1427 }
1428
VMR7MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig * iface,VMRMONITORINFO * info,DWORD arraysize,DWORD * numdev)1429 static HRESULT WINAPI VMR7MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig *iface,
1430 VMRMONITORINFO *info, DWORD arraysize,
1431 DWORD *numdev)
1432 {
1433 struct quartz_vmr *This = impl_from_IVMRMonitorConfig(iface);
1434 struct get_available_monitors_args args;
1435
1436 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1437
1438 if (!numdev)
1439 return E_POINTER;
1440
1441 if (info && arraysize == 0)
1442 return E_INVALIDARG;
1443
1444 args.info7 = info;
1445 args.info9 = NULL;
1446 args.arraysize = arraysize;
1447 args.numdev = 0;
1448 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1449
1450 *numdev = args.numdev;
1451 return S_OK;
1452 }
1453
1454 static const IVMRMonitorConfigVtbl VMR7_MonitorConfig_Vtbl =
1455 {
1456 VMR7MonitorConfig_QueryInterface,
1457 VMR7MonitorConfig_AddRef,
1458 VMR7MonitorConfig_Release,
1459 VMR7MonitorConfig_SetMonitor,
1460 VMR7MonitorConfig_GetMonitor,
1461 VMR7MonitorConfig_SetDefaultMonitor,
1462 VMR7MonitorConfig_GetDefaultMonitor,
1463 VMR7MonitorConfig_GetAvailableMonitors
1464 };
1465
VMR9MonitorConfig_QueryInterface(IVMRMonitorConfig9 * iface,REFIID riid,LPVOID * ppv)1466 static HRESULT WINAPI VMR9MonitorConfig_QueryInterface(IVMRMonitorConfig9 *iface, REFIID riid,
1467 LPVOID * ppv)
1468 {
1469 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1470 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1471 }
1472
VMR9MonitorConfig_AddRef(IVMRMonitorConfig9 * iface)1473 static ULONG WINAPI VMR9MonitorConfig_AddRef(IVMRMonitorConfig9 *iface)
1474 {
1475 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1476 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1477 }
1478
VMR9MonitorConfig_Release(IVMRMonitorConfig9 * iface)1479 static ULONG WINAPI VMR9MonitorConfig_Release(IVMRMonitorConfig9 *iface)
1480 {
1481 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1482 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1483 }
1484
VMR9MonitorConfig_SetMonitor(IVMRMonitorConfig9 * iface,UINT uDev)1485 static HRESULT WINAPI VMR9MonitorConfig_SetMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1486 {
1487 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1488
1489 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1490
1491 return S_OK;
1492 }
1493
VMR9MonitorConfig_GetMonitor(IVMRMonitorConfig9 * iface,UINT * uDev)1494 static HRESULT WINAPI VMR9MonitorConfig_GetMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1495 {
1496 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1497
1498 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1499
1500 if (!uDev)
1501 return E_POINTER;
1502
1503 *uDev = 0;
1504 return S_OK;
1505 }
1506
VMR9MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig9 * iface,UINT uDev)1507 static HRESULT WINAPI VMR9MonitorConfig_SetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT uDev)
1508 {
1509 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1510
1511 FIXME("(%p/%p)->(%u) stub\n", iface, This, uDev);
1512
1513 return S_OK;
1514 }
1515
VMR9MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig9 * iface,UINT * uDev)1516 static HRESULT WINAPI VMR9MonitorConfig_GetDefaultMonitor(IVMRMonitorConfig9 *iface, UINT *uDev)
1517 {
1518 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1519
1520 FIXME("(%p/%p)->(%p) stub\n", iface, This, uDev);
1521
1522 if (!uDev)
1523 return E_POINTER;
1524
1525 *uDev = 0;
1526 return S_OK;
1527 }
1528
VMR9MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig9 * iface,VMR9MonitorInfo * info,DWORD arraysize,DWORD * numdev)1529 static HRESULT WINAPI VMR9MonitorConfig_GetAvailableMonitors(IVMRMonitorConfig9 *iface,
1530 VMR9MonitorInfo *info, DWORD arraysize,
1531 DWORD *numdev)
1532 {
1533 struct quartz_vmr *This = impl_from_IVMRMonitorConfig9(iface);
1534 struct get_available_monitors_args args;
1535
1536 FIXME("(%p/%p)->(%p, %u, %p) semi-stub\n", iface, This, info, arraysize, numdev);
1537
1538 if (!numdev)
1539 return E_POINTER;
1540
1541 if (info && arraysize == 0)
1542 return E_INVALIDARG;
1543
1544 args.info7 = NULL;
1545 args.info9 = info;
1546 args.arraysize = arraysize;
1547 args.numdev = 0;
1548 EnumDisplayMonitors(NULL, NULL, get_available_monitors_proc, (LPARAM)&args);
1549
1550 *numdev = args.numdev;
1551 return S_OK;
1552 }
1553
1554 static const IVMRMonitorConfig9Vtbl VMR9_MonitorConfig_Vtbl =
1555 {
1556 VMR9MonitorConfig_QueryInterface,
1557 VMR9MonitorConfig_AddRef,
1558 VMR9MonitorConfig_Release,
1559 VMR9MonitorConfig_SetMonitor,
1560 VMR9MonitorConfig_GetMonitor,
1561 VMR9MonitorConfig_SetDefaultMonitor,
1562 VMR9MonitorConfig_GetDefaultMonitor,
1563 VMR9MonitorConfig_GetAvailableMonitors
1564 };
1565
VMR9FilterConfig_QueryInterface(IVMRFilterConfig9 * iface,REFIID riid,LPVOID * ppv)1566 static HRESULT WINAPI VMR9FilterConfig_QueryInterface(IVMRFilterConfig9 *iface, REFIID riid, LPVOID * ppv)
1567 {
1568 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1569 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1570 }
1571
VMR9FilterConfig_AddRef(IVMRFilterConfig9 * iface)1572 static ULONG WINAPI VMR9FilterConfig_AddRef(IVMRFilterConfig9 *iface)
1573 {
1574 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1575 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1576 }
1577
VMR9FilterConfig_Release(IVMRFilterConfig9 * iface)1578 static ULONG WINAPI VMR9FilterConfig_Release(IVMRFilterConfig9 *iface)
1579 {
1580 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1581 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1582 }
1583
VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9 * iface,IVMRImageCompositor9 * compositor)1584 static HRESULT WINAPI VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9 *iface, IVMRImageCompositor9 *compositor)
1585 {
1586 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1587
1588 FIXME("(%p/%p)->(%p) stub\n", iface, This, compositor);
1589 return E_NOTIMPL;
1590 }
1591
VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9 * iface,DWORD max)1592 static HRESULT WINAPI VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD max)
1593 {
1594 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1595
1596 FIXME("(%p/%p)->(%u) stub\n", iface, This, max);
1597 return E_NOTIMPL;
1598 }
1599
VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9 * iface,DWORD * max)1600 static HRESULT WINAPI VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9 *iface, DWORD *max)
1601 {
1602 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1603
1604 FIXME("(%p/%p)->(%p) stub\n", iface, This, max);
1605 return E_NOTIMPL;
1606 }
1607
VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9 * iface,DWORD renderflags)1608 static HRESULT WINAPI VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD renderflags)
1609 {
1610 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1611
1612 FIXME("(%p/%p)->(%u) stub\n", iface, This, renderflags);
1613 return E_NOTIMPL;
1614 }
1615
VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9 * iface,DWORD * renderflags)1616 static HRESULT WINAPI VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9 *iface, DWORD *renderflags)
1617 {
1618 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1619
1620 FIXME("(%p/%p)->(%p) stub\n", iface, This, renderflags);
1621 return E_NOTIMPL;
1622 }
1623
VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 * iface,DWORD mode)1624 static HRESULT WINAPI VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9 *iface, DWORD mode)
1625 {
1626 HRESULT hr = S_OK;
1627 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1628
1629 TRACE("(%p/%p)->(%u)\n", iface, This, mode);
1630
1631 EnterCriticalSection(&This->renderer.filter.csFilter);
1632 if (This->mode)
1633 {
1634 LeaveCriticalSection(&This->renderer.filter.csFilter);
1635 return VFW_E_WRONG_STATE;
1636 }
1637
1638 if (This->allocator)
1639 IVMRSurfaceAllocatorEx9_Release(This->allocator);
1640 if (This->presenter)
1641 IVMRImagePresenter9_Release(This->presenter);
1642
1643 This->allocator = NULL;
1644 This->presenter = NULL;
1645
1646 switch (mode)
1647 {
1648 case VMR9Mode_Windowed:
1649 case VMR9Mode_Windowless:
1650 This->allocator_is_ex = 0;
1651 This->cookie = ~0;
1652
1653 hr = VMR9DefaultAllocatorPresenterImpl_create(This, (LPVOID*)&This->presenter);
1654 if (SUCCEEDED(hr))
1655 hr = IVMRImagePresenter9_QueryInterface(This->presenter, &IID_IVMRSurfaceAllocatorEx9, (LPVOID*)&This->allocator);
1656 if (FAILED(hr))
1657 {
1658 ERR("Unable to find Presenter interface\n");
1659 IVMRImagePresenter9_Release(This->presenter);
1660 This->allocator = NULL;
1661 This->presenter = NULL;
1662 }
1663 else
1664 hr = IVMRSurfaceAllocatorEx9_AdviseNotify(This->allocator, &This->IVMRSurfaceAllocatorNotify9_iface);
1665 break;
1666 case VMR9Mode_Renderless:
1667 break;
1668 default:
1669 LeaveCriticalSection(&This->renderer.filter.csFilter);
1670 return E_INVALIDARG;
1671 }
1672
1673 This->mode = mode;
1674 LeaveCriticalSection(&This->renderer.filter.csFilter);
1675 return hr;
1676 }
1677
VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9 * iface,DWORD * mode)1678 static HRESULT WINAPI VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9 *iface, DWORD *mode)
1679 {
1680 struct quartz_vmr *This = impl_from_IVMRFilterConfig9(iface);
1681
1682 TRACE("(%p/%p)->(%p)\n", iface, This, mode);
1683 if (!mode)
1684 return E_POINTER;
1685
1686 if (This->mode)
1687 *mode = This->mode;
1688 else
1689 *mode = VMR9Mode_Windowed;
1690
1691 return S_OK;
1692 }
1693
1694 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl =
1695 {
1696 VMR9FilterConfig_QueryInterface,
1697 VMR9FilterConfig_AddRef,
1698 VMR9FilterConfig_Release,
1699 VMR9FilterConfig_SetImageCompositor,
1700 VMR9FilterConfig_SetNumberOfStreams,
1701 VMR9FilterConfig_GetNumberOfStreams,
1702 VMR9FilterConfig_SetRenderingPrefs,
1703 VMR9FilterConfig_GetRenderingPrefs,
1704 VMR9FilterConfig_SetRenderingMode,
1705 VMR9FilterConfig_GetRenderingMode
1706 };
1707
VMR7WindowlessControl_QueryInterface(IVMRWindowlessControl * iface,REFIID riid,LPVOID * ppv)1708 static HRESULT WINAPI VMR7WindowlessControl_QueryInterface(IVMRWindowlessControl *iface, REFIID riid,
1709 LPVOID * ppv)
1710 {
1711 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1712 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1713 }
1714
VMR7WindowlessControl_AddRef(IVMRWindowlessControl * iface)1715 static ULONG WINAPI VMR7WindowlessControl_AddRef(IVMRWindowlessControl *iface)
1716 {
1717 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1718 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1719 }
1720
VMR7WindowlessControl_Release(IVMRWindowlessControl * iface)1721 static ULONG WINAPI VMR7WindowlessControl_Release(IVMRWindowlessControl *iface)
1722 {
1723 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1724 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1725 }
1726
VMR7WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl * iface,LONG * width,LONG * height,LONG * arwidth,LONG * arheight)1727 static HRESULT WINAPI VMR7WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl *iface,
1728 LONG *width, LONG *height,
1729 LONG *arwidth, LONG *arheight)
1730 {
1731 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1732 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1733
1734 if (!width || !height || !arwidth || !arheight)
1735 {
1736 ERR("Got no pointer\n");
1737 return E_POINTER;
1738 }
1739
1740 *width = This->bmiheader.biWidth;
1741 *height = This->bmiheader.biHeight;
1742 *arwidth = This->bmiheader.biWidth;
1743 *arheight = This->bmiheader.biHeight;
1744
1745 return S_OK;
1746 }
1747
VMR7WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl * iface,LONG * width,LONG * height)1748 static HRESULT WINAPI VMR7WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl *iface,
1749 LONG *width, LONG *height)
1750 {
1751 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1752
1753 FIXME("(%p/%p)->(...) stub\n", iface, This);
1754 return E_NOTIMPL;
1755 }
1756
VMR7WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl * iface,LONG * width,LONG * height)1757 static HRESULT WINAPI VMR7WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl *iface,
1758 LONG *width, LONG *height)
1759 {
1760 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1761
1762 FIXME("(%p/%p)->(...) stub\n", iface, This);
1763 return E_NOTIMPL;
1764 }
1765
VMR7WindowlessControl_SetVideoPosition(IVMRWindowlessControl * iface,const RECT * source,const RECT * dest)1766 static HRESULT WINAPI VMR7WindowlessControl_SetVideoPosition(IVMRWindowlessControl *iface,
1767 const RECT *source, const RECT *dest)
1768 {
1769 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1770
1771 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1772
1773 EnterCriticalSection(&This->renderer.filter.csFilter);
1774
1775 if (source)
1776 This->source_rect = *source;
1777 if (dest)
1778 {
1779 This->target_rect = *dest;
1780 if (This->baseControlWindow.baseWindow.hWnd)
1781 {
1782 FIXME("Output rectangle: %s\n", wine_dbgstr_rect(dest));
1783 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
1784 dest->left, dest->top, dest->right - dest->left, dest->bottom-dest->top,
1785 SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW);
1786 }
1787 }
1788
1789 LeaveCriticalSection(&This->renderer.filter.csFilter);
1790
1791 return S_OK;
1792 }
1793
VMR7WindowlessControl_GetVideoPosition(IVMRWindowlessControl * iface,RECT * source,RECT * dest)1794 static HRESULT WINAPI VMR7WindowlessControl_GetVideoPosition(IVMRWindowlessControl *iface,
1795 RECT *source, RECT *dest)
1796 {
1797 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1798
1799 if (source)
1800 *source = This->source_rect;
1801
1802 if (dest)
1803 *dest = This->target_rect;
1804
1805 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
1806 return S_OK;
1807 }
1808
VMR7WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl * iface,DWORD * mode)1809 static HRESULT WINAPI VMR7WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl *iface,
1810 DWORD *mode)
1811 {
1812 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1813
1814 FIXME("(%p/%p)->(...) stub\n", iface, This);
1815 return E_NOTIMPL;
1816 }
1817
VMR7WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl * iface,DWORD mode)1818 static HRESULT WINAPI VMR7WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl *iface,
1819 DWORD mode)
1820 {
1821 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1822
1823 FIXME("(%p/%p)->(...) stub\n", iface, This);
1824 return E_NOTIMPL;
1825 }
1826
VMR7WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl * iface,HWND hwnd)1827 static HRESULT WINAPI VMR7WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl *iface,
1828 HWND hwnd)
1829 {
1830 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1831
1832 FIXME("(%p/%p)->(...) stub\n", iface, This);
1833 return E_NOTIMPL;
1834 }
1835
VMR7WindowlessControl_RepaintVideo(IVMRWindowlessControl * iface,HWND hwnd,HDC hdc)1836 static HRESULT WINAPI VMR7WindowlessControl_RepaintVideo(IVMRWindowlessControl *iface,
1837 HWND hwnd, HDC hdc)
1838 {
1839 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1840
1841 FIXME("(%p/%p)->(...) stub\n", iface, This);
1842 return E_NOTIMPL;
1843 }
1844
VMR7WindowlessControl_DisplayModeChanged(IVMRWindowlessControl * iface)1845 static HRESULT WINAPI VMR7WindowlessControl_DisplayModeChanged(IVMRWindowlessControl *iface)
1846 {
1847 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1848
1849 FIXME("(%p/%p)->(...) stub\n", iface, This);
1850 return E_NOTIMPL;
1851 }
1852
VMR7WindowlessControl_GetCurrentImage(IVMRWindowlessControl * iface,BYTE ** dib)1853 static HRESULT WINAPI VMR7WindowlessControl_GetCurrentImage(IVMRWindowlessControl *iface,
1854 BYTE **dib)
1855 {
1856 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1857
1858 FIXME("(%p/%p)->(...) stub\n", iface, This);
1859 return E_NOTIMPL;
1860 }
1861
VMR7WindowlessControl_SetBorderColor(IVMRWindowlessControl * iface,COLORREF color)1862 static HRESULT WINAPI VMR7WindowlessControl_SetBorderColor(IVMRWindowlessControl *iface,
1863 COLORREF color)
1864 {
1865 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1866
1867 FIXME("(%p/%p)->(...) stub\n", iface, This);
1868 return E_NOTIMPL;
1869 }
1870
VMR7WindowlessControl_GetBorderColor(IVMRWindowlessControl * iface,COLORREF * color)1871 static HRESULT WINAPI VMR7WindowlessControl_GetBorderColor(IVMRWindowlessControl *iface,
1872 COLORREF *color)
1873 {
1874 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1875
1876 FIXME("(%p/%p)->(...) stub\n", iface, This);
1877 return E_NOTIMPL;
1878 }
1879
VMR7WindowlessControl_SetColorKey(IVMRWindowlessControl * iface,COLORREF color)1880 static HRESULT WINAPI VMR7WindowlessControl_SetColorKey(IVMRWindowlessControl *iface, COLORREF color)
1881 {
1882 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1883
1884 FIXME("(%p/%p)->(...) stub\n", iface, This);
1885 return E_NOTIMPL;
1886 }
1887
VMR7WindowlessControl_GetColorKey(IVMRWindowlessControl * iface,COLORREF * color)1888 static HRESULT WINAPI VMR7WindowlessControl_GetColorKey(IVMRWindowlessControl *iface, COLORREF *color)
1889 {
1890 struct quartz_vmr *This = impl_from_IVMRWindowlessControl(iface);
1891
1892 FIXME("(%p/%p)->(...) stub\n", iface, This);
1893 return E_NOTIMPL;
1894 }
1895
1896 static const IVMRWindowlessControlVtbl VMR7_WindowlessControl_Vtbl =
1897 {
1898 VMR7WindowlessControl_QueryInterface,
1899 VMR7WindowlessControl_AddRef,
1900 VMR7WindowlessControl_Release,
1901 VMR7WindowlessControl_GetNativeVideoSize,
1902 VMR7WindowlessControl_GetMinIdealVideoSize,
1903 VMR7WindowlessControl_GetMaxIdealVideoSize,
1904 VMR7WindowlessControl_SetVideoPosition,
1905 VMR7WindowlessControl_GetVideoPosition,
1906 VMR7WindowlessControl_GetAspectRatioMode,
1907 VMR7WindowlessControl_SetAspectRatioMode,
1908 VMR7WindowlessControl_SetVideoClippingWindow,
1909 VMR7WindowlessControl_RepaintVideo,
1910 VMR7WindowlessControl_DisplayModeChanged,
1911 VMR7WindowlessControl_GetCurrentImage,
1912 VMR7WindowlessControl_SetBorderColor,
1913 VMR7WindowlessControl_GetBorderColor,
1914 VMR7WindowlessControl_SetColorKey,
1915 VMR7WindowlessControl_GetColorKey
1916 };
1917
VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9 * iface,REFIID riid,LPVOID * ppv)1918 static HRESULT WINAPI VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9 *iface, REFIID riid, LPVOID * ppv)
1919 {
1920 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1921 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
1922 }
1923
VMR9WindowlessControl_AddRef(IVMRWindowlessControl9 * iface)1924 static ULONG WINAPI VMR9WindowlessControl_AddRef(IVMRWindowlessControl9 *iface)
1925 {
1926 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1927 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
1928 }
1929
VMR9WindowlessControl_Release(IVMRWindowlessControl9 * iface)1930 static ULONG WINAPI VMR9WindowlessControl_Release(IVMRWindowlessControl9 *iface)
1931 {
1932 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1933 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
1934 }
1935
VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9 * iface,LONG * width,LONG * height,LONG * arwidth,LONG * arheight)1936 static HRESULT WINAPI VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height, LONG *arwidth, LONG *arheight)
1937 {
1938 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1939 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface, This, width, height, arwidth, arheight);
1940
1941 if (!width || !height || !arwidth || !arheight)
1942 {
1943 ERR("Got no pointer\n");
1944 return E_POINTER;
1945 }
1946
1947 *width = This->bmiheader.biWidth;
1948 *height = This->bmiheader.biHeight;
1949 *arwidth = This->bmiheader.biWidth;
1950 *arheight = This->bmiheader.biHeight;
1951
1952 return S_OK;
1953 }
1954
VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9 * iface,LONG * width,LONG * height)1955 static HRESULT WINAPI VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1956 {
1957 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1958
1959 FIXME("(%p/%p)->(...) stub\n", iface, This);
1960 return E_NOTIMPL;
1961 }
1962
VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9 * iface,LONG * width,LONG * height)1963 static HRESULT WINAPI VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9 *iface, LONG *width, LONG *height)
1964 {
1965 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1966
1967 FIXME("(%p/%p)->(...) stub\n", iface, This);
1968 return E_NOTIMPL;
1969 }
1970
VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9 * iface,const RECT * source,const RECT * dest)1971 static HRESULT WINAPI VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9 *iface, const RECT *source, const RECT *dest)
1972 {
1973 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
1974
1975 TRACE("(%p/%p)->(%p, %p)\n", iface, This, source, dest);
1976
1977 EnterCriticalSection(&This->renderer.filter.csFilter);
1978
1979 if (source)
1980 This->source_rect = *source;
1981 if (dest)
1982 {
1983 This->target_rect = *dest;
1984 if (This->baseControlWindow.baseWindow.hWnd)
1985 {
1986 FIXME("Output rectangle: %s\n", wine_dbgstr_rect(dest));
1987 SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL, dest->left, dest->top, dest->right - dest->left,
1988 dest->bottom-dest->top, SWP_NOACTIVATE|SWP_NOCOPYBITS|SWP_NOOWNERZORDER|SWP_NOREDRAW);
1989 }
1990 }
1991
1992 LeaveCriticalSection(&This->renderer.filter.csFilter);
1993
1994 return S_OK;
1995 }
1996
VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9 * iface,RECT * source,RECT * dest)1997 static HRESULT WINAPI VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9 *iface, RECT *source, RECT *dest)
1998 {
1999 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2000
2001 if (source)
2002 *source = This->source_rect;
2003
2004 if (dest)
2005 *dest = This->target_rect;
2006
2007 FIXME("(%p/%p)->(%p/%p) stub\n", iface, This, source, dest);
2008 return S_OK;
2009 }
2010
VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9 * iface,DWORD * mode)2011 static HRESULT WINAPI VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD *mode)
2012 {
2013 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2014
2015 FIXME("(%p/%p)->(...) stub\n", iface, This);
2016 return E_NOTIMPL;
2017 }
2018
VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9 * iface,DWORD mode)2019 static HRESULT WINAPI VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9 *iface, DWORD mode)
2020 {
2021 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2022
2023 FIXME("(%p/%p)->(...) stub\n", iface, This);
2024 return E_NOTIMPL;
2025 }
2026
VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9 * iface,HWND hwnd)2027 static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9 *iface, HWND hwnd)
2028 {
2029 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2030
2031 TRACE("(%p/%p)->(%p)\n", iface, This, hwnd);
2032
2033 EnterCriticalSection(&This->renderer.filter.csFilter);
2034 This->hWndClippingWindow = hwnd;
2035 VMR9_maybe_init(This, FALSE);
2036 if (!hwnd)
2037 IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie);
2038 LeaveCriticalSection(&This->renderer.filter.csFilter);
2039 return S_OK;
2040 }
2041
VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9 * iface,HWND hwnd,HDC hdc)2042 static HRESULT WINAPI VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9 *iface, HWND hwnd, HDC hdc)
2043 {
2044 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2045 HRESULT hr;
2046
2047 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2048
2049 EnterCriticalSection(&This->renderer.filter.csFilter);
2050 if (hwnd != This->hWndClippingWindow && hwnd != This->baseControlWindow.baseWindow.hWnd)
2051 {
2052 ERR("Not handling changing windows yet!!!\n");
2053 LeaveCriticalSection(&This->renderer.filter.csFilter);
2054 return S_OK;
2055 }
2056
2057 if (!This->allocator_d3d9_dev)
2058 {
2059 ERR("No d3d9 device!\n");
2060 LeaveCriticalSection(&This->renderer.filter.csFilter);
2061 return VFW_E_WRONG_STATE;
2062 }
2063
2064 /* Windowless extension */
2065 hr = IDirect3DDevice9_Present(This->allocator_d3d9_dev, NULL, NULL, This->baseControlWindow.baseWindow.hWnd, NULL);
2066 LeaveCriticalSection(&This->renderer.filter.csFilter);
2067
2068 return hr;
2069 }
2070
VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9 * iface)2071 static HRESULT WINAPI VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9 *iface)
2072 {
2073 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2074
2075 FIXME("(%p/%p)->(...) stub\n", iface, This);
2076 return E_NOTIMPL;
2077 }
2078
VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9 * iface,BYTE ** dib)2079 static HRESULT WINAPI VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9 *iface, BYTE **dib)
2080 {
2081 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2082
2083 FIXME("(%p/%p)->(...) stub\n", iface, This);
2084 return E_NOTIMPL;
2085 }
2086
VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9 * iface,COLORREF color)2087 static HRESULT WINAPI VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9 *iface, COLORREF color)
2088 {
2089 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2090
2091 FIXME("(%p/%p)->(...) stub\n", iface, This);
2092 return E_NOTIMPL;
2093 }
2094
VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9 * iface,COLORREF * color)2095 static HRESULT WINAPI VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9 *iface, COLORREF *color)
2096 {
2097 struct quartz_vmr *This = impl_from_IVMRWindowlessControl9(iface);
2098
2099 FIXME("(%p/%p)->(...) stub\n", iface, This);
2100 return E_NOTIMPL;
2101 }
2102
2103 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl =
2104 {
2105 VMR9WindowlessControl_QueryInterface,
2106 VMR9WindowlessControl_AddRef,
2107 VMR9WindowlessControl_Release,
2108 VMR9WindowlessControl_GetNativeVideoSize,
2109 VMR9WindowlessControl_GetMinIdealVideoSize,
2110 VMR9WindowlessControl_GetMaxIdealVideoSize,
2111 VMR9WindowlessControl_SetVideoPosition,
2112 VMR9WindowlessControl_GetVideoPosition,
2113 VMR9WindowlessControl_GetAspectRatioMode,
2114 VMR9WindowlessControl_SetAspectRatioMode,
2115 VMR9WindowlessControl_SetVideoClippingWindow,
2116 VMR9WindowlessControl_RepaintVideo,
2117 VMR9WindowlessControl_DisplayModeChanged,
2118 VMR9WindowlessControl_GetCurrentImage,
2119 VMR9WindowlessControl_SetBorderColor,
2120 VMR9WindowlessControl_GetBorderColor
2121 };
2122
VMR7SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify * iface,REFIID riid,LPVOID * ppv)2123 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify *iface,
2124 REFIID riid, LPVOID * ppv)
2125 {
2126 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2127 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
2128 }
2129
VMR7SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify * iface)2130 static ULONG WINAPI VMR7SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify *iface)
2131 {
2132 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2133 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
2134 }
2135
VMR7SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify * iface)2136 static ULONG WINAPI VMR7SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify *iface)
2137 {
2138 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2139 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
2140 }
2141
VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify * iface,DWORD_PTR id,IVMRSurfaceAllocator * alloc)2142 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify *iface,
2143 DWORD_PTR id,
2144 IVMRSurfaceAllocator *alloc)
2145 {
2146 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2147
2148 FIXME("(%p/%p)->(...) stub\n", iface, This);
2149 return E_NOTIMPL;
2150 }
2151
VMR7SurfaceAllocatorNotify_SetDDrawDevice(IVMRSurfaceAllocatorNotify * iface,IDirectDraw7 * device,HMONITOR monitor)2152 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
2153 IDirectDraw7 *device, HMONITOR monitor)
2154 {
2155 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2156
2157 FIXME("(%p/%p)->(...) stub\n", iface, This);
2158 return E_NOTIMPL;
2159 }
2160
VMR7SurfaceAllocatorNotify_ChangeDDrawDevice(IVMRSurfaceAllocatorNotify * iface,IDirectDraw7 * device,HMONITOR monitor)2161 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_ChangeDDrawDevice(IVMRSurfaceAllocatorNotify *iface,
2162 IDirectDraw7 *device, HMONITOR monitor)
2163 {
2164 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2165
2166 FIXME("(%p/%p)->(...) stub\n", iface, This);
2167 return E_NOTIMPL;
2168 }
2169
VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces(IVMRSurfaceAllocatorNotify * iface)2170 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces(IVMRSurfaceAllocatorNotify *iface)
2171 {
2172 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2173
2174 FIXME("(%p/%p)->(...) stub\n", iface, This);
2175 return E_NOTIMPL;
2176 }
2177
VMR7SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify * iface,LONG code,LONG_PTR param1,LONG_PTR param2)2178 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify *iface, LONG code,
2179 LONG_PTR param1, LONG_PTR param2)
2180 {
2181 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2182
2183 FIXME("(%p/%p)->(...) stub\n", iface, This);
2184 return E_NOTIMPL;
2185 }
2186
VMR7SurfaceAllocatorNotify_SetBorderColor(IVMRSurfaceAllocatorNotify * iface,COLORREF clrBorder)2187 static HRESULT WINAPI VMR7SurfaceAllocatorNotify_SetBorderColor(IVMRSurfaceAllocatorNotify *iface,
2188 COLORREF clrBorder)
2189 {
2190 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify(iface);
2191
2192 FIXME("(%p/%p)->(...) stub\n", iface, This);
2193 return E_NOTIMPL;
2194 }
2195
2196 static const IVMRSurfaceAllocatorNotifyVtbl VMR7_SurfaceAllocatorNotify_Vtbl =
2197 {
2198 VMR7SurfaceAllocatorNotify_QueryInterface,
2199 VMR7SurfaceAllocatorNotify_AddRef,
2200 VMR7SurfaceAllocatorNotify_Release,
2201 VMR7SurfaceAllocatorNotify_AdviseSurfaceAllocator,
2202 VMR7SurfaceAllocatorNotify_SetDDrawDevice,
2203 VMR7SurfaceAllocatorNotify_ChangeDDrawDevice,
2204 VMR7SurfaceAllocatorNotify_RestoreDDrawSurfaces,
2205 VMR7SurfaceAllocatorNotify_NotifyEvent,
2206 VMR7SurfaceAllocatorNotify_SetBorderColor
2207 };
2208
VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9 * iface,REFIID riid,LPVOID * ppv)2209 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9 *iface, REFIID riid, LPVOID * ppv)
2210 {
2211 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2212 return VMR9_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppv);
2213 }
2214
VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9 * iface)2215 static ULONG WINAPI VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9 *iface)
2216 {
2217 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2218 return VMR9_AddRef(&This->renderer.filter.IBaseFilter_iface);
2219 }
2220
VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9 * iface)2221 static ULONG WINAPI VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9 *iface)
2222 {
2223 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2224 return VMR9_Release(&This->renderer.filter.IBaseFilter_iface);
2225 }
2226
VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9 * iface,DWORD_PTR id,IVMRSurfaceAllocator9 * alloc)2227 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9 *iface, DWORD_PTR id, IVMRSurfaceAllocator9 *alloc)
2228 {
2229 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2230
2231 /* FIXME: This code is not tested!!! */
2232 FIXME("(%p/%p)->(...) stub\n", iface, This);
2233 This->cookie = id;
2234
2235 if (This->presenter)
2236 return VFW_E_WRONG_STATE;
2237
2238 if (FAILED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRImagePresenter9, (void **)&This->presenter)))
2239 return E_NOINTERFACE;
2240
2241 if (SUCCEEDED(IVMRSurfaceAllocator9_QueryInterface(alloc, &IID_IVMRSurfaceAllocatorEx9, (void **)&This->allocator)))
2242 This->allocator_is_ex = 1;
2243 else
2244 {
2245 This->allocator = (IVMRSurfaceAllocatorEx9 *)alloc;
2246 IVMRSurfaceAllocator9_AddRef(alloc);
2247 This->allocator_is_ex = 0;
2248 }
2249
2250 return S_OK;
2251 }
2252
VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9 * iface,IDirect3DDevice9 * device,HMONITOR monitor)2253 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
2254 {
2255 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2256
2257 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2258 if (This->allocator_d3d9_dev)
2259 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
2260 This->allocator_d3d9_dev = device;
2261 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
2262 This->allocator_mon = monitor;
2263
2264 return S_OK;
2265 }
2266
VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9 * iface,IDirect3DDevice9 * device,HMONITOR monitor)2267 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9 *iface, IDirect3DDevice9 *device, HMONITOR monitor)
2268 {
2269 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2270
2271 FIXME("(%p/%p)->(...) semi-stub\n", iface, This);
2272 if (This->allocator_d3d9_dev)
2273 IDirect3DDevice9_Release(This->allocator_d3d9_dev);
2274 This->allocator_d3d9_dev = device;
2275 IDirect3DDevice9_AddRef(This->allocator_d3d9_dev);
2276 This->allocator_mon = monitor;
2277
2278 return S_OK;
2279 }
2280
VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9 * iface,VMR9AllocationInfo * allocinfo,DWORD * numbuffers,IDirect3DSurface9 ** surface)2281 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9 *iface, VMR9AllocationInfo *allocinfo, DWORD *numbuffers, IDirect3DSurface9 **surface)
2282 {
2283 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2284 DWORD i;
2285 HRESULT hr = S_OK;
2286
2287 FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface, This, allocinfo, numbuffers, (numbuffers ? *numbuffers : 0), surface);
2288
2289 if (!allocinfo || !numbuffers || !surface)
2290 return E_POINTER;
2291
2292 if (!*numbuffers || *numbuffers < allocinfo->MinBuffers)
2293 {
2294 ERR("Invalid number of buffers?\n");
2295 return E_INVALIDARG;
2296 }
2297
2298 if (!This->allocator_d3d9_dev)
2299 {
2300 ERR("No direct3d device when requested to allocate a surface!\n");
2301 return VFW_E_WRONG_STATE;
2302 }
2303
2304 if (allocinfo->dwFlags & VMR9AllocFlag_OffscreenSurface)
2305 {
2306 ERR("Creating offscreen surface\n");
2307 for (i = 0; i < *numbuffers; ++i)
2308 {
2309 hr = IDirect3DDevice9_CreateOffscreenPlainSurface(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight,
2310 allocinfo->Format, allocinfo->Pool, &surface[i], NULL);
2311 if (FAILED(hr))
2312 break;
2313 }
2314 }
2315 else if (allocinfo->dwFlags & VMR9AllocFlag_TextureSurface)
2316 {
2317 TRACE("Creating texture surface\n");
2318 for (i = 0; i < *numbuffers; ++i)
2319 {
2320 IDirect3DTexture9 *texture;
2321
2322 hr = IDirect3DDevice9_CreateTexture(This->allocator_d3d9_dev, allocinfo->dwWidth, allocinfo->dwHeight, 1, 0,
2323 allocinfo->Format, allocinfo->Pool, &texture, NULL);
2324 if (FAILED(hr))
2325 break;
2326 IDirect3DTexture9_GetSurfaceLevel(texture, 0, &surface[i]);
2327 IDirect3DTexture9_Release(texture);
2328 }
2329 }
2330 else
2331 {
2332 FIXME("Could not allocate for type %08x\n", allocinfo->dwFlags);
2333 return E_NOTIMPL;
2334 }
2335
2336 if (i >= allocinfo->MinBuffers)
2337 {
2338 hr = S_OK;
2339 *numbuffers = i;
2340 }
2341 else
2342 {
2343 for ( ; i > 0; --i) IDirect3DSurface9_Release(surface[i - 1]);
2344 *numbuffers = 0;
2345 }
2346 return hr;
2347 }
2348
VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9 * iface,LONG code,LONG_PTR param1,LONG_PTR param2)2349 static HRESULT WINAPI VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9 *iface, LONG code, LONG_PTR param1, LONG_PTR param2)
2350 {
2351 struct quartz_vmr *This = impl_from_IVMRSurfaceAllocatorNotify9(iface);
2352
2353 FIXME("(%p/%p)->(...) stub\n", iface, This);
2354 return E_NOTIMPL;
2355 }
2356
2357 static const IVMRSurfaceAllocatorNotify9Vtbl VMR9_SurfaceAllocatorNotify_Vtbl =
2358 {
2359 VMR9SurfaceAllocatorNotify_QueryInterface,
2360 VMR9SurfaceAllocatorNotify_AddRef,
2361 VMR9SurfaceAllocatorNotify_Release,
2362 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator,
2363 VMR9SurfaceAllocatorNotify_SetD3DDevice,
2364 VMR9SurfaceAllocatorNotify_ChangeD3DDevice,
2365 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper,
2366 VMR9SurfaceAllocatorNotify_NotifyEvent
2367 };
2368
vmr_create(IUnknown * outer_unk,LPVOID * ppv,const CLSID * clsid)2369 static HRESULT vmr_create(IUnknown *outer_unk, LPVOID *ppv, const CLSID *clsid)
2370 {
2371 HRESULT hr;
2372 struct quartz_vmr* pVMR;
2373
2374 TRACE("(%p, %p)\n", outer_unk, ppv);
2375
2376 *ppv = NULL;
2377
2378 pVMR = CoTaskMemAlloc(sizeof(struct quartz_vmr));
2379
2380 pVMR->hD3d9 = LoadLibraryA("d3d9.dll");
2381 if (!pVMR->hD3d9 )
2382 {
2383 WARN("Could not load d3d9.dll\n");
2384 CoTaskMemFree(pVMR);
2385 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
2386 }
2387
2388 pVMR->outer_unk = outer_unk;
2389 pVMR->bUnkOuterValid = FALSE;
2390 pVMR->bAggregatable = FALSE;
2391 pVMR->IUnknown_inner.lpVtbl = &IInner_VTable;
2392 pVMR->IAMCertifiedOutputProtection_iface.lpVtbl = &IAMCertifiedOutputProtection_Vtbl;
2393 pVMR->IAMFilterMiscFlags_iface.lpVtbl = &IAMFilterMiscFlags_Vtbl;
2394
2395 pVMR->mode = 0;
2396 pVMR->allocator_d3d9_dev = NULL;
2397 pVMR->allocator_mon= NULL;
2398 pVMR->num_surfaces = pVMR->cur_surface = 0;
2399 pVMR->allocator = NULL;
2400 pVMR->presenter = NULL;
2401 pVMR->hWndClippingWindow = NULL;
2402 pVMR->IVMRFilterConfig_iface.lpVtbl = &VMR7_FilterConfig_Vtbl;
2403 pVMR->IVMRFilterConfig9_iface.lpVtbl = &VMR9_FilterConfig_Vtbl;
2404 pVMR->IVMRMonitorConfig_iface.lpVtbl = &VMR7_MonitorConfig_Vtbl;
2405 pVMR->IVMRMonitorConfig9_iface.lpVtbl = &VMR9_MonitorConfig_Vtbl;
2406 pVMR->IVMRSurfaceAllocatorNotify_iface.lpVtbl = &VMR7_SurfaceAllocatorNotify_Vtbl;
2407 pVMR->IVMRSurfaceAllocatorNotify9_iface.lpVtbl = &VMR9_SurfaceAllocatorNotify_Vtbl;
2408 pVMR->IVMRWindowlessControl_iface.lpVtbl = &VMR7_WindowlessControl_Vtbl;
2409 pVMR->IVMRWindowlessControl9_iface.lpVtbl = &VMR9_WindowlessControl_Vtbl;
2410
2411 if (IsEqualGUID(clsid, &CLSID_VideoMixingRenderer))
2412 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer,
2413 (DWORD_PTR)(__FILE__ ": VMR7Impl.csFilter"), &BaseFuncTable);
2414 else
2415 hr = BaseRenderer_Init(&pVMR->renderer, &VMR_Vtbl, outer_unk, &CLSID_VideoMixingRenderer9,
2416 (DWORD_PTR)(__FILE__ ": VMR9Impl.csFilter"), &BaseFuncTable);
2417
2418 if (FAILED(hr))
2419 goto fail;
2420
2421 hr = BaseControlWindow_Init(&pVMR->baseControlWindow, &IVideoWindow_VTable, &pVMR->renderer.filter,
2422 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin,
2423 &renderer_BaseWindowFuncTable);
2424 if (FAILED(hr))
2425 goto fail;
2426
2427 hr = BaseControlVideo_Init(&pVMR->baseControlVideo, &IBasicVideo_VTable, &pVMR->renderer.filter,
2428 &pVMR->renderer.filter.csFilter, &pVMR->renderer.pInputPin->pin,
2429 &renderer_BaseControlVideoFuncTable);
2430 if (FAILED(hr))
2431 goto fail;
2432
2433 *ppv = (LPVOID)pVMR;
2434 ZeroMemory(&pVMR->source_rect, sizeof(RECT));
2435 ZeroMemory(&pVMR->target_rect, sizeof(RECT));
2436 TRACE("Created at %p\n", pVMR);
2437 return hr;
2438
2439 fail:
2440 BaseRendererImpl_Release(&pVMR->renderer.filter.IBaseFilter_iface);
2441 FreeLibrary(pVMR->hD3d9);
2442 CoTaskMemFree(pVMR);
2443 return hr;
2444 }
2445
VMR7Impl_create(IUnknown * outer_unk,LPVOID * ppv)2446 HRESULT VMR7Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2447 {
2448 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer);
2449 }
2450
VMR9Impl_create(IUnknown * outer_unk,LPVOID * ppv)2451 HRESULT VMR9Impl_create(IUnknown *outer_unk, LPVOID *ppv)
2452 {
2453 return vmr_create(outer_unk, ppv, &CLSID_VideoMixingRenderer9);
2454 }
2455
2456
VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 * iface,REFIID riid,LPVOID * ppv)2457 static HRESULT WINAPI VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9 *iface, REFIID riid, LPVOID * ppv)
2458 {
2459 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2460 TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv);
2461
2462 *ppv = NULL;
2463
2464 if (IsEqualIID(riid, &IID_IUnknown))
2465 *ppv = (LPVOID)&(This->IVMRImagePresenter9_iface);
2466 else if (IsEqualIID(riid, &IID_IVMRImagePresenter9))
2467 *ppv = &This->IVMRImagePresenter9_iface;
2468 else if (IsEqualIID(riid, &IID_IVMRSurfaceAllocatorEx9))
2469 *ppv = &This->IVMRSurfaceAllocatorEx9_iface;
2470
2471 if (*ppv)
2472 {
2473 IUnknown_AddRef((IUnknown *)(*ppv));
2474 return S_OK;
2475 }
2476
2477 FIXME("No interface for %s\n", debugstr_guid(riid));
2478
2479 return E_NOINTERFACE;
2480 }
2481
VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 * iface)2482 static ULONG WINAPI VMR9_ImagePresenter_AddRef(IVMRImagePresenter9 *iface)
2483 {
2484 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2485 ULONG refCount = InterlockedIncrement(&This->refCount);
2486
2487 TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
2488
2489 return refCount;
2490 }
2491
VMR9_ImagePresenter_Release(IVMRImagePresenter9 * iface)2492 static ULONG WINAPI VMR9_ImagePresenter_Release(IVMRImagePresenter9 *iface)
2493 {
2494 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2495 ULONG refCount = InterlockedDecrement(&This->refCount);
2496
2497 TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
2498
2499 if (!refCount)
2500 {
2501 DWORD i;
2502 TRACE("Destroying\n");
2503 CloseHandle(This->ack);
2504 IDirect3D9_Release(This->d3d9_ptr);
2505
2506 TRACE("Number of surfaces: %u\n", This->num_surfaces);
2507 for (i = 0; i < This->num_surfaces; ++i)
2508 {
2509 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2510 TRACE("Releasing surface %p\n", surface);
2511 if (surface)
2512 IDirect3DSurface9_Release(surface);
2513 }
2514
2515 CoTaskMemFree(This->d3d9_surfaces);
2516 This->d3d9_surfaces = NULL;
2517 This->num_surfaces = 0;
2518 if (This->d3d9_vertex)
2519 {
2520 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2521 This->d3d9_vertex = NULL;
2522 }
2523 CoTaskMemFree(This);
2524 return 0;
2525 }
2526 return refCount;
2527 }
2528
VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 * iface,DWORD_PTR id)2529 static HRESULT WINAPI VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2530 {
2531 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2532
2533 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2534 return S_OK;
2535 }
2536
VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 * iface,DWORD_PTR id)2537 static HRESULT WINAPI VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9 *iface, DWORD_PTR id)
2538 {
2539 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2540
2541 TRACE("(%p/%p/%p)->(...) stub\n", iface, This,This->pVMR9);
2542 return S_OK;
2543 }
2544
2545 #define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
2546 struct VERTEX { float x, y, z, rhw, u, v; };
2547
VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl * This,IDirect3DSurface9 * surface)2548 static HRESULT VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2549 {
2550 IDirect3DTexture9 *texture = NULL;
2551 HRESULT hr;
2552
2553 hr = IDirect3DDevice9_SetFVF(This->d3d9_dev, USED_FVF);
2554 if (FAILED(hr))
2555 {
2556 FIXME("SetFVF: %08x\n", hr);
2557 return hr;
2558 }
2559
2560 hr = IDirect3DDevice9_SetStreamSource(This->d3d9_dev, 0, This->d3d9_vertex, 0, sizeof(struct VERTEX));
2561 if (FAILED(hr))
2562 {
2563 FIXME("SetStreamSource: %08x\n", hr);
2564 return hr;
2565 }
2566
2567 hr = IDirect3DSurface9_GetContainer(surface, &IID_IDirect3DTexture9, (void **) &texture);
2568 if (FAILED(hr))
2569 {
2570 FIXME("IDirect3DSurface9_GetContainer failed\n");
2571 return hr;
2572 }
2573 hr = IDirect3DDevice9_SetTexture(This->d3d9_dev, 0, (IDirect3DBaseTexture9 *)texture);
2574 IDirect3DTexture9_Release(texture);
2575 if (FAILED(hr))
2576 {
2577 FIXME("SetTexture: %08x\n", hr);
2578 return hr;
2579 }
2580
2581 hr = IDirect3DDevice9_DrawPrimitive(This->d3d9_dev, D3DPT_TRIANGLESTRIP, 0, 2);
2582 if (FAILED(hr))
2583 {
2584 FIXME("DrawPrimitive: %08x\n", hr);
2585 return hr;
2586 }
2587
2588 return S_OK;
2589 }
2590
VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl * This,IDirect3DSurface9 * surface)2591 static HRESULT VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl *This, IDirect3DSurface9 *surface)
2592 {
2593 HRESULT hr;
2594 IDirect3DSurface9 *target = NULL;
2595 RECT target_rect;
2596
2597 hr = IDirect3DDevice9_GetBackBuffer(This->d3d9_dev, 0, 0, D3DBACKBUFFER_TYPE_MONO, &target);
2598 if (FAILED(hr))
2599 {
2600 ERR("IDirect3DDevice9_GetBackBuffer -- %08x\n", hr);
2601 return hr;
2602 }
2603
2604 /* Move rect to origin and flip it */
2605 SetRect(&target_rect, 0, This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top,
2606 This->pVMR9->target_rect.right - This->pVMR9->target_rect.left, 0);
2607
2608 hr = IDirect3DDevice9_StretchRect(This->d3d9_dev, surface, &This->pVMR9->source_rect, target, &target_rect, D3DTEXF_LINEAR);
2609 if (FAILED(hr))
2610 ERR("IDirect3DDevice9_StretchRect -- %08x\n", hr);
2611 IDirect3DSurface9_Release(target);
2612
2613 return hr;
2614 }
2615
VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 * iface,DWORD_PTR id,VMR9PresentationInfo * info)2616 static HRESULT WINAPI VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9 *iface, DWORD_PTR id, VMR9PresentationInfo *info)
2617 {
2618 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRImagePresenter9(iface);
2619 HRESULT hr;
2620 RECT output;
2621 BOOL render = FALSE;
2622
2623 TRACE("(%p/%p/%p)->(...) stub\n", iface, This, This->pVMR9);
2624 GetWindowRect(This->pVMR9->baseControlWindow.baseWindow.hWnd, &output);
2625 TRACE("Output rectangle: %s\n", wine_dbgstr_rect(&output));
2626
2627 /* This might happen if we don't have active focus (eg on a different virtual desktop) */
2628 if (!This->d3d9_dev)
2629 return S_OK;
2630
2631 /* Display image here */
2632 hr = IDirect3DDevice9_Clear(This->d3d9_dev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
2633 if (FAILED(hr))
2634 FIXME("hr: %08x\n", hr);
2635 hr = IDirect3DDevice9_BeginScene(This->d3d9_dev);
2636 if (SUCCEEDED(hr))
2637 {
2638 if (This->d3d9_vertex)
2639 hr = VMR9_ImagePresenter_PresentTexture(This, info->lpSurf);
2640 else
2641 hr = VMR9_ImagePresenter_PresentOffscreenSurface(This, info->lpSurf);
2642 render = SUCCEEDED(hr);
2643 }
2644 else
2645 FIXME("BeginScene: %08x\n", hr);
2646 hr = IDirect3DDevice9_EndScene(This->d3d9_dev);
2647 if (render && SUCCEEDED(hr))
2648 {
2649 hr = IDirect3DDevice9_Present(This->d3d9_dev, NULL, NULL, This->pVMR9->baseControlWindow.baseWindow.hWnd, NULL);
2650 if (FAILED(hr))
2651 FIXME("Presenting image: %08x\n", hr);
2652 }
2653
2654 return S_OK;
2655 }
2656
2657 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter =
2658 {
2659 VMR9_ImagePresenter_QueryInterface,
2660 VMR9_ImagePresenter_AddRef,
2661 VMR9_ImagePresenter_Release,
2662 VMR9_ImagePresenter_StartPresenting,
2663 VMR9_ImagePresenter_StopPresenting,
2664 VMR9_ImagePresenter_PresentImage
2665 };
2666
VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9 * iface,REFIID riid,LPVOID * ppv)2667 static HRESULT WINAPI VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9 *iface, REFIID riid, LPVOID * ppv)
2668 {
2669 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2670
2671 return VMR9_ImagePresenter_QueryInterface(&This->IVMRImagePresenter9_iface, riid, ppv);
2672 }
2673
VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9 * iface)2674 static ULONG WINAPI VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9 *iface)
2675 {
2676 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2677
2678 return VMR9_ImagePresenter_AddRef(&This->IVMRImagePresenter9_iface);
2679 }
2680
VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9 * iface)2681 static ULONG WINAPI VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9 *iface)
2682 {
2683 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2684
2685 return VMR9_ImagePresenter_Release(&This->IVMRImagePresenter9_iface);
2686 }
2687
VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl * This,VMR9AllocationInfo * allocinfo)2688 static HRESULT VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *allocinfo)
2689 {
2690 D3DCAPS9 caps;
2691 UINT width, height;
2692 HRESULT hr;
2693
2694 if (!(allocinfo->dwFlags & VMR9AllocFlag_TextureSurface))
2695 /* Only needed for texture surfaces */
2696 return S_OK;
2697
2698 hr = IDirect3DDevice9_GetDeviceCaps(This->d3d9_dev, &caps);
2699 if (FAILED(hr))
2700 return hr;
2701
2702 if (!(caps.TextureCaps & D3DPTEXTURECAPS_POW2) || (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY))
2703 {
2704 width = allocinfo->dwWidth;
2705 height = allocinfo->dwHeight;
2706 }
2707 else
2708 {
2709 width = height = 1;
2710 while (width < allocinfo->dwWidth)
2711 width *= 2;
2712
2713 while (height < allocinfo->dwHeight)
2714 height *= 2;
2715 FIXME("NPOW2 support missing, not using proper surfaces!\n");
2716 }
2717
2718 if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
2719 {
2720 if (height > width)
2721 width = height;
2722 else
2723 height = width;
2724 FIXME("Square texture support required..\n");
2725 }
2726
2727 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF, allocinfo->Pool, &This->d3d9_vertex, NULL);
2728 if (FAILED(hr))
2729 {
2730 ERR("Couldn't create vertex buffer: %08x\n", hr);
2731 return hr;
2732 }
2733
2734 This->reset = TRUE;
2735 allocinfo->dwHeight = height;
2736 allocinfo->dwWidth = width;
2737
2738 return hr;
2739 }
2740
MessageLoop(LPVOID lpParameter)2741 static DWORD WINAPI MessageLoop(LPVOID lpParameter)
2742 {
2743 MSG msg;
2744 BOOL fGotMessage;
2745 VMR9DefaultAllocatorPresenterImpl *This = lpParameter;
2746
2747 TRACE("Starting message loop\n");
2748
2749 if (FAILED(BaseWindowImpl_PrepareWindow(&This->pVMR9->baseControlWindow.baseWindow)))
2750 {
2751 FIXME("Failed to prepare window\n");
2752 return FALSE;
2753 }
2754
2755 SetEvent(This->ack);
2756 while ((fGotMessage = GetMessageW(&msg, NULL, 0, 0)) != 0 && fGotMessage != -1)
2757 {
2758 TranslateMessage(&msg);
2759 DispatchMessageW(&msg);
2760 }
2761
2762 TRACE("End of message loop\n");
2763
2764 return 0;
2765 }
2766
d3d9_adapter_from_hwnd(IDirect3D9 * d3d9,HWND hwnd,HMONITOR * mon_out)2767 static UINT d3d9_adapter_from_hwnd(IDirect3D9 *d3d9, HWND hwnd, HMONITOR *mon_out)
2768 {
2769 UINT d3d9_adapter;
2770 HMONITOR mon;
2771
2772 mon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONULL);
2773 if (!mon)
2774 d3d9_adapter = 0;
2775 else
2776 {
2777 for (d3d9_adapter = 0; d3d9_adapter < IDirect3D9_GetAdapterCount(d3d9); ++d3d9_adapter)
2778 {
2779 if (mon == IDirect3D9_GetAdapterMonitor(d3d9, d3d9_adapter))
2780 break;
2781 }
2782 if (d3d9_adapter >= IDirect3D9_GetAdapterCount(d3d9))
2783 d3d9_adapter = 0;
2784 }
2785 if (mon_out)
2786 *mon_out = mon;
2787 return d3d9_adapter;
2788 }
2789
CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl * This,VMR9AllocationInfo * info,DWORD * numbuffers)2790 static BOOL CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl *This, VMR9AllocationInfo *info, DWORD *numbuffers)
2791 {
2792 D3DPRESENT_PARAMETERS d3dpp;
2793 DWORD d3d9_adapter;
2794 HRESULT hr;
2795
2796 TRACE("(%p)->()\n", This);
2797
2798 This->hWndThread = CreateThread(NULL, 0, MessageLoop, This, 0, &This->tid);
2799 if (!This->hWndThread)
2800 return FALSE;
2801
2802 WaitForSingleObject(This->ack, INFINITE);
2803
2804 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd) return FALSE;
2805
2806 /* Obtain a monitor and d3d9 device */
2807 d3d9_adapter = d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon);
2808
2809 /* Now try to create the d3d9 device */
2810 ZeroMemory(&d3dpp, sizeof(d3dpp));
2811 d3dpp.Windowed = TRUE;
2812 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2813 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2814 d3dpp.BackBufferHeight = This->pVMR9->target_rect.bottom - This->pVMR9->target_rect.top;
2815 d3dpp.BackBufferWidth = This->pVMR9->target_rect.right - This->pVMR9->target_rect.left;
2816
2817 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter, D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev);
2818 if (FAILED(hr))
2819 {
2820 ERR("Could not create device: %08x\n", hr);
2821 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2822 return FALSE;
2823 }
2824 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2825
2826 This->d3d9_surfaces = CoTaskMemAlloc(*numbuffers * sizeof(IDirect3DSurface9 *));
2827 ZeroMemory(This->d3d9_surfaces, *numbuffers * sizeof(IDirect3DSurface9 *));
2828
2829 hr = VMR9_SurfaceAllocator_SetAllocationSettings(This, info);
2830 if (FAILED(hr))
2831 ERR("Setting allocation settings failed: %08x\n", hr);
2832
2833 if (SUCCEEDED(hr))
2834 {
2835 hr = IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, info, numbuffers, This->d3d9_surfaces);
2836 if (FAILED(hr))
2837 ERR("Allocating surfaces failed: %08x\n", hr);
2838 }
2839
2840 if (FAILED(hr))
2841 {
2842 IVMRSurfaceAllocatorEx9_TerminateDevice(This->pVMR9->allocator, This->pVMR9->cookie);
2843 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2844 return FALSE;
2845 }
2846
2847 This->num_surfaces = *numbuffers;
2848
2849 return TRUE;
2850 }
2851
VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9 * iface,DWORD_PTR id,VMR9AllocationInfo * allocinfo,DWORD * numbuffers)2852 static HRESULT WINAPI VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, VMR9AllocationInfo *allocinfo, DWORD *numbuffers)
2853 {
2854 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2855
2856 if (This->pVMR9->mode != VMR9Mode_Windowed && !This->pVMR9->hWndClippingWindow)
2857 {
2858 ERR("No window set\n");
2859 return VFW_E_WRONG_STATE;
2860 }
2861
2862 This->info = *allocinfo;
2863
2864 if (!CreateRenderingWindow(This, allocinfo, numbuffers))
2865 {
2866 ERR("Failed to create rendering window, expect no output!\n");
2867 return VFW_E_WRONG_STATE;
2868 }
2869
2870 return S_OK;
2871 }
2872
VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9 * iface,DWORD_PTR id)2873 static HRESULT WINAPI VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id)
2874 {
2875 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
2876
2877 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
2878 {
2879 return S_OK;
2880 }
2881
2882 SendMessageW(This->pVMR9->baseControlWindow.baseWindow.hWnd, WM_CLOSE, 0, 0);
2883 PostThreadMessageW(This->tid, WM_QUIT, 0, 0);
2884 WaitForSingleObject(This->hWndThread, INFINITE);
2885 This->hWndThread = NULL;
2886 BaseWindowImpl_DoneWithWindow(&This->pVMR9->baseControlWindow.baseWindow);
2887
2888 return S_OK;
2889 }
2890
2891 /* Recreate all surfaces (If allocated as D3DPOOL_DEFAULT) and survive! */
VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl * This)2892 static HRESULT VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl *This)
2893 {
2894 struct VERTEX t_vert[4];
2895 UINT width, height;
2896 unsigned int i;
2897 void *bits = NULL;
2898 D3DPRESENT_PARAMETERS d3dpp;
2899 HRESULT hr;
2900
2901 if (!This->pVMR9->baseControlWindow.baseWindow.hWnd)
2902 {
2903 ERR("No window\n");
2904 return E_FAIL;
2905 }
2906
2907 if (!This->d3d9_surfaces || !This->reset)
2908 return S_OK;
2909
2910 This->reset = FALSE;
2911 TRACE("RESETTING\n");
2912 if (This->d3d9_vertex)
2913 {
2914 IDirect3DVertexBuffer9_Release(This->d3d9_vertex);
2915 This->d3d9_vertex = NULL;
2916 }
2917
2918 for (i = 0; i < This->num_surfaces; ++i)
2919 {
2920 IDirect3DSurface9 *surface = This->d3d9_surfaces[i];
2921 TRACE("Releasing surface %p\n", surface);
2922 if (surface)
2923 IDirect3DSurface9_Release(surface);
2924 }
2925 ZeroMemory(This->d3d9_surfaces, sizeof(IDirect3DSurface9 *) * This->num_surfaces);
2926
2927 /* Now try to create the d3d9 device */
2928 ZeroMemory(&d3dpp, sizeof(d3dpp));
2929 d3dpp.Windowed = TRUE;
2930 d3dpp.hDeviceWindow = This->pVMR9->baseControlWindow.baseWindow.hWnd;
2931 d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
2932
2933 if (This->d3d9_dev)
2934 IDirect3DDevice9_Release(This->d3d9_dev);
2935 This->d3d9_dev = NULL;
2936 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon), D3DDEVTYPE_HAL, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev);
2937 if (FAILED(hr))
2938 {
2939 hr = IDirect3D9_CreateDevice(This->d3d9_ptr, d3d9_adapter_from_hwnd(This->d3d9_ptr, This->pVMR9->baseControlWindow.baseWindow.hWnd, &This->hMon), D3DDEVTYPE_HAL, NULL, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &This->d3d9_dev);
2940 if (FAILED(hr))
2941 {
2942 ERR("--> Creating device: %08x\n", hr);
2943 return S_OK;
2944 }
2945 }
2946 IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(This->SurfaceAllocatorNotify, This->d3d9_dev, This->hMon);
2947
2948 IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This->SurfaceAllocatorNotify, &This->info, &This->num_surfaces, This->d3d9_surfaces);
2949
2950 This->reset = FALSE;
2951
2952 if (!(This->info.dwFlags & VMR9AllocFlag_TextureSurface))
2953 return S_OK;
2954
2955 hr = IDirect3DDevice9_CreateVertexBuffer(This->d3d9_dev, 4 * sizeof(struct VERTEX), D3DUSAGE_WRITEONLY, USED_FVF,
2956 This->info.Pool, &This->d3d9_vertex, NULL);
2957
2958 width = This->info.dwWidth;
2959 height = This->info.dwHeight;
2960
2961 for (i = 0; i < sizeof(t_vert) / sizeof(t_vert[0]); ++i)
2962 {
2963 if (i % 2)
2964 {
2965 t_vert[i].x = (float)This->pVMR9->target_rect.right - (float)This->pVMR9->target_rect.left - 0.5f;
2966 t_vert[i].u = (float)This->pVMR9->source_rect.right / (float)width;
2967 }
2968 else
2969 {
2970 t_vert[i].x = -0.5f;
2971 t_vert[i].u = (float)This->pVMR9->source_rect.left / (float)width;
2972 }
2973
2974 if (i % 4 < 2)
2975 {
2976 t_vert[i].y = -0.5f;
2977 t_vert[i].v = (float)This->pVMR9->source_rect.bottom / (float)height;
2978 }
2979 else
2980 {
2981 t_vert[i].y = (float)This->pVMR9->target_rect.bottom - (float)This->pVMR9->target_rect.top - 0.5f;
2982 t_vert[i].v = (float)This->pVMR9->source_rect.top / (float)height;
2983 }
2984 t_vert[i].z = 0.0f;
2985 t_vert[i].rhw = 1.0f;
2986 }
2987
2988 FIXME("Vertex rectangle:\n");
2989 FIXME("X, Y: %f, %f\n", t_vert[0].x, t_vert[0].y);
2990 FIXME("X, Y: %f, %f\n", t_vert[3].x, t_vert[3].y);
2991 FIXME("TOP, LEFT: %f, %f\n", t_vert[0].u, t_vert[0].v);
2992 FIXME("DOWN, BOTTOM: %f, %f\n", t_vert[3].u, t_vert[3].v);
2993
2994 IDirect3DVertexBuffer9_Lock(This->d3d9_vertex, 0, sizeof(t_vert), &bits, 0);
2995 memcpy(bits, t_vert, sizeof(t_vert));
2996 IDirect3DVertexBuffer9_Unlock(This->d3d9_vertex);
2997
2998 return S_OK;
2999 }
3000
VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9 * iface,DWORD_PTR id,DWORD surfaceindex,DWORD flags,IDirect3DSurface9 ** surface)3001 static HRESULT WINAPI VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9 *iface, DWORD_PTR id, DWORD surfaceindex, DWORD flags, IDirect3DSurface9 **surface)
3002 {
3003 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
3004
3005 /* Update everything first, this is needed because the surface might be destroyed in the reset */
3006 if (!This->d3d9_dev)
3007 {
3008 TRACE("Device has left me!\n");
3009 return E_FAIL;
3010 }
3011
3012 VMR9_SurfaceAllocator_UpdateDeviceReset(This);
3013
3014 if (surfaceindex >= This->num_surfaces)
3015 {
3016 ERR("surfaceindex is greater than num_surfaces\n");
3017 return E_FAIL;
3018 }
3019 *surface = This->d3d9_surfaces[surfaceindex];
3020 IDirect3DSurface9_AddRef(*surface);
3021
3022 return S_OK;
3023 }
3024
VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9 * iface,IVMRSurfaceAllocatorNotify9 * allocnotify)3025 static HRESULT WINAPI VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9 *iface, IVMRSurfaceAllocatorNotify9 *allocnotify)
3026 {
3027 VMR9DefaultAllocatorPresenterImpl *This = impl_from_IVMRSurfaceAllocatorEx9(iface);
3028
3029 TRACE("(%p/%p)->(...)\n", iface, This);
3030
3031 /* No AddRef taken here or the base VMR9 filter would never be destroyed */
3032 This->SurfaceAllocatorNotify = allocnotify;
3033 return S_OK;
3034 }
3035
3036 static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator =
3037 {
3038 VMR9_SurfaceAllocator_QueryInterface,
3039 VMR9_SurfaceAllocator_AddRef,
3040 VMR9_SurfaceAllocator_Release,
3041 VMR9_SurfaceAllocator_InitializeDevice,
3042 VMR9_SurfaceAllocator_TerminateDevice,
3043 VMR9_SurfaceAllocator_GetSurface,
3044 VMR9_SurfaceAllocator_AdviseNotify,
3045 NULL /* This isn't the SurfaceAllocatorEx type yet, working on it */
3046 };
3047
init_d3d9(HMODULE d3d9_handle)3048 static IDirect3D9 *init_d3d9(HMODULE d3d9_handle)
3049 {
3050 IDirect3D9 * (__stdcall * d3d9_create)(UINT SDKVersion);
3051
3052 d3d9_create = (void *)GetProcAddress(d3d9_handle, "Direct3DCreate9");
3053 if (!d3d9_create) return NULL;
3054
3055 return d3d9_create(D3D_SDK_VERSION);
3056 }
3057
VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr * parent,LPVOID * ppv)3058 static HRESULT VMR9DefaultAllocatorPresenterImpl_create(struct quartz_vmr *parent, LPVOID * ppv)
3059 {
3060 HRESULT hr = S_OK;
3061 int i;
3062 VMR9DefaultAllocatorPresenterImpl* This;
3063
3064 This = CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl));
3065 if (!This)
3066 return E_OUTOFMEMORY;
3067
3068 This->d3d9_ptr = init_d3d9(parent->hD3d9);
3069 if (!This->d3d9_ptr)
3070 {
3071 WARN("Could not initialize d3d9.dll\n");
3072 CoTaskMemFree(This);
3073 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
3074 }
3075
3076 i = 0;
3077 do
3078 {
3079 D3DDISPLAYMODE mode;
3080
3081 hr = IDirect3D9_EnumAdapterModes(This->d3d9_ptr, i++, D3DFMT_X8R8G8B8, 0, &mode);
3082 if (hr == D3DERR_INVALIDCALL) break; /* out of adapters */
3083 } while (FAILED(hr));
3084 if (FAILED(hr))
3085 ERR("HR: %08x\n", hr);
3086 if (hr == D3DERR_NOTAVAILABLE)
3087 {
3088 ERR("Format not supported\n");
3089 IDirect3D9_Release(This->d3d9_ptr);
3090 CoTaskMemFree(This);
3091 return VFW_E_DDRAW_CAPS_NOT_SUITABLE;
3092 }
3093
3094 This->IVMRImagePresenter9_iface.lpVtbl = &VMR9_ImagePresenter;
3095 This->IVMRSurfaceAllocatorEx9_iface.lpVtbl = &VMR9_SurfaceAllocator;
3096
3097 This->refCount = 1;
3098 This->pVMR9 = parent;
3099 This->d3d9_surfaces = NULL;
3100 This->d3d9_dev = NULL;
3101 This->hMon = 0;
3102 This->d3d9_vertex = NULL;
3103 This->num_surfaces = 0;
3104 This->hWndThread = NULL;
3105 This->ack = CreateEventW(NULL, 0, 0, NULL);
3106 This->SurfaceAllocatorNotify = NULL;
3107 This->reset = FALSE;
3108
3109 *ppv = &This->IVMRImagePresenter9_iface;
3110 return S_OK;
3111 }
3112