2 * Video Mixing Renderer for dx9
4 * Copyright 2004 Christian Costa
5 * Copyright 2008 Maarten Lankhorst
6 * Copyright 2012 Aric Stewart
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #define NONAMELESSSTRUCT
26 #define NONAMELESSUNION
27 #include "quartz_private.h"
43 #include "wine/unicode.h"
44 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
50 BaseRenderer renderer
;
51 BaseControlWindow baseControlWindow
;
52 BaseControlVideo baseControlVideo
;
54 IUnknown IUnknown_inner
;
55 IAMFilterMiscFlags IAMFilterMiscFlags_iface
;
56 IVMRFilterConfig9 IVMRFilterConfig9_iface
;
57 IVMRWindowlessControl9 IVMRWindowlessControl9_iface
;
58 IVMRSurfaceAllocatorNotify9 IVMRSurfaceAllocatorNotify9_iface
;
60 IVMRSurfaceAllocatorEx9
*allocator
;
61 IVMRImagePresenter9
*presenter
;
65 * The Video Mixing Renderer supports 3 modes, renderless, windowless and windowed
66 * What I do is implement windowless as a special case of renderless, and then
67 * windowed also as a special case of windowless. This is probably the easiest way.
70 BITMAPINFOHEADER bmiheader
;
77 /* Presentation related members */
78 IDirect3DDevice9
*allocator_d3d9_dev
;
79 HMONITOR allocator_mon
;
84 /* for Windowless Mode */
85 HWND hWndClippingWindow
;
93 static inline VMR9Impl
*impl_from_inner_IUnknown(IUnknown
*iface
)
95 return CONTAINING_RECORD(iface
, VMR9Impl
, IUnknown_inner
);
98 static inline VMR9Impl
*impl_from_BaseWindow( BaseWindow
*wnd
)
100 return CONTAINING_RECORD(wnd
, VMR9Impl
, baseControlWindow
.baseWindow
);
103 static inline VMR9Impl
*impl_from_IVideoWindow( IVideoWindow
*iface
)
105 return CONTAINING_RECORD(iface
, VMR9Impl
, baseControlWindow
.IVideoWindow_iface
);
108 static inline VMR9Impl
*impl_from_BaseControlVideo( BaseControlVideo
*cvid
)
110 return CONTAINING_RECORD(cvid
, VMR9Impl
, baseControlVideo
);
113 static inline VMR9Impl
*impl_from_IBasicVideo( IBasicVideo
*iface
)
115 return CONTAINING_RECORD(iface
, VMR9Impl
, baseControlVideo
.IBasicVideo_iface
);
118 static inline VMR9Impl
*impl_from_IAMFilterMiscFlags( IAMFilterMiscFlags
*iface
)
120 return CONTAINING_RECORD(iface
, VMR9Impl
, IAMFilterMiscFlags_iface
);
123 static inline VMR9Impl
*impl_from_IVMRFilterConfig9( IVMRFilterConfig9
*iface
)
125 return CONTAINING_RECORD(iface
, VMR9Impl
, IVMRFilterConfig9_iface
);
128 static inline VMR9Impl
*impl_from_IVMRWindowlessControl9( IVMRWindowlessControl9
*iface
)
130 return CONTAINING_RECORD(iface
, VMR9Impl
, IVMRWindowlessControl9_iface
);
133 static inline VMR9Impl
*impl_from_IVMRSurfaceAllocatorNotify9( IVMRSurfaceAllocatorNotify9
*iface
)
135 return CONTAINING_RECORD(iface
, VMR9Impl
, IVMRSurfaceAllocatorNotify9_iface
);
140 IVMRImagePresenter9 IVMRImagePresenter9_iface
;
141 IVMRSurfaceAllocatorEx9 IVMRSurfaceAllocatorEx9_iface
;
149 IDirect3DDevice9
*d3d9_dev
;
150 IDirect3D9
*d3d9_ptr
;
151 IDirect3DSurface9
**d3d9_surfaces
;
152 IDirect3DVertexBuffer9
*d3d9_vertex
;
157 VMR9AllocationInfo info
;
160 IVMRSurfaceAllocatorNotify9
*SurfaceAllocatorNotify
;
161 } VMR9DefaultAllocatorPresenterImpl
;
163 static inline VMR9DefaultAllocatorPresenterImpl
*impl_from_IVMRImagePresenter9( IVMRImagePresenter9
*iface
)
165 return CONTAINING_RECORD(iface
, VMR9DefaultAllocatorPresenterImpl
, IVMRImagePresenter9_iface
);
168 static inline VMR9DefaultAllocatorPresenterImpl
*impl_from_IVMRSurfaceAllocatorEx9( IVMRSurfaceAllocatorEx9
*iface
)
170 return CONTAINING_RECORD(iface
, VMR9DefaultAllocatorPresenterImpl
, IVMRSurfaceAllocatorEx9_iface
);
173 static HRESULT
VMR9DefaultAllocatorPresenterImpl_create(VMR9Impl
*parent
, LPVOID
* ppv
);
175 static DWORD
VMR9_SendSampleData(VMR9Impl
*This
, VMR9PresentationInfo
*info
, LPBYTE data
, DWORD size
)
181 BITMAPINFOHEADER
*bmiHeader
;
184 TRACE("%p %p %d\n", This
, data
, size
);
186 amt
= &This
->renderer
.pInputPin
->pin
.mtCurrent
;
188 if (IsEqualIID(&amt
->formattype
, &FORMAT_VideoInfo
))
190 bmiHeader
= &((VIDEOINFOHEADER
*)amt
->pbFormat
)->bmiHeader
;
192 else if (IsEqualIID(&amt
->formattype
, &FORMAT_VideoInfo2
))
194 bmiHeader
= &((VIDEOINFOHEADER2
*)amt
->pbFormat
)->bmiHeader
;
198 FIXME("Unknown type %s\n", debugstr_guid(&amt
->subtype
));
199 return VFW_E_RUNTIME_ERROR
;
202 TRACE("biSize = %d\n", bmiHeader
->biSize
);
203 TRACE("biWidth = %d\n", bmiHeader
->biWidth
);
204 TRACE("biHeight = %d\n", bmiHeader
->biHeight
);
205 TRACE("biPlanes = %d\n", bmiHeader
->biPlanes
);
206 TRACE("biBitCount = %d\n", bmiHeader
->biBitCount
);
207 TRACE("biCompression = %s\n", debugstr_an((LPSTR
)&(bmiHeader
->biCompression
), 4));
208 TRACE("biSizeImage = %d\n", bmiHeader
->biSizeImage
);
210 width
= bmiHeader
->biWidth
;
211 height
= bmiHeader
->biHeight
;
213 TRACE("Src Rect: %d %d %d %d\n", This
->source_rect
.left
, This
->source_rect
.top
, This
->source_rect
.right
, This
->source_rect
.bottom
);
214 TRACE("Dst Rect: %d %d %d %d\n", This
->target_rect
.left
, This
->target_rect
.top
, This
->target_rect
.right
, This
->target_rect
.bottom
);
216 hr
= IDirect3DSurface9_LockRect(info
->lpSurf
, &lock
, NULL
, D3DLOCK_DISCARD
);
219 ERR("IDirect3DSurface9_LockRect failed (%x)\n",hr
);
223 if (lock
.Pitch
!= width
* bmiHeader
->biBitCount
/ 8)
225 WARN("Slow path! %u/%u\n", lock
.Pitch
, width
* bmiHeader
->biBitCount
/8);
229 memcpy(lock
.pBits
, data
, width
* bmiHeader
->biBitCount
/ 8);
230 data
= data
+ width
* bmiHeader
->biBitCount
/ 8;
231 lock
.pBits
= (char *)lock
.pBits
+ lock
.Pitch
;
234 else memcpy(lock
.pBits
, data
, size
);
236 IDirect3DSurface9_UnlockRect(info
->lpSurf
);
238 hr
= IVMRImagePresenter9_PresentImage(This
->presenter
, This
->cookie
, info
);
242 static HRESULT WINAPI
VMR9_DoRenderSample(BaseRenderer
*iface
, IMediaSample
* pSample
)
244 VMR9Impl
*This
= (VMR9Impl
*)iface
;
245 LPBYTE pbSrcStream
= NULL
;
246 long cbSrcStream
= 0;
247 REFERENCE_TIME tStart
, tStop
;
248 VMR9PresentationInfo info
;
251 TRACE("%p %p\n", iface
, pSample
);
253 /* It is possible that there is no device at this point */
255 if (!This
->allocator
|| !This
->presenter
)
257 ERR("NO PRESENTER!!\n");
261 hr
= IMediaSample_GetTime(pSample
, &tStart
, &tStop
);
263 info
.dwFlags
= VMR9Sample_SrcDstRectsValid
;
265 info
.dwFlags
= VMR9Sample_SrcDstRectsValid
| VMR9Sample_TimeValid
;
267 if (IMediaSample_IsDiscontinuity(pSample
) == S_OK
)
268 info
.dwFlags
|= VMR9Sample_Discontinuity
;
270 if (IMediaSample_IsPreroll(pSample
) == S_OK
)
271 info
.dwFlags
|= VMR9Sample_Preroll
;
273 if (IMediaSample_IsSyncPoint(pSample
) == S_OK
)
274 info
.dwFlags
|= VMR9Sample_SyncPoint
;
276 /* If we render ourselves, and this is a preroll sample, discard it */
277 if (This
->baseControlWindow
.baseWindow
.hWnd
&& (info
.dwFlags
& VMR9Sample_Preroll
))
282 hr
= IMediaSample_GetPointer(pSample
, &pbSrcStream
);
285 ERR("Cannot get pointer to sample data (%x)\n", hr
);
289 cbSrcStream
= IMediaSample_GetActualDataLength(pSample
);
291 info
.rtStart
= tStart
;
293 info
.szAspectRatio
.cx
= This
->bmiheader
.biWidth
;
294 info
.szAspectRatio
.cy
= This
->bmiheader
.biHeight
;
296 hr
= IVMRSurfaceAllocatorEx9_GetSurface(This
->allocator
, This
->cookie
, (++This
->cur_surface
)%This
->num_surfaces
, 0, &info
.lpSurf
);
301 VMR9_SendSampleData(This
, &info
, pbSrcStream
, cbSrcStream
);
302 IDirect3DSurface9_Release(info
.lpSurf
);
307 static HRESULT WINAPI
VMR9_CheckMediaType(BaseRenderer
*iface
, const AM_MEDIA_TYPE
* pmt
)
309 VMR9Impl
*This
= (VMR9Impl
*)iface
;
311 if (!IsEqualIID(&pmt
->majortype
, &MEDIATYPE_Video
) || !pmt
->pbFormat
)
314 /* Ignore subtype, test for bicompression instead */
315 if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo
))
317 VIDEOINFOHEADER
*format
= (VIDEOINFOHEADER
*)pmt
->pbFormat
;
319 This
->bmiheader
= format
->bmiHeader
;
320 TRACE("Resolution: %dx%d\n", format
->bmiHeader
.biWidth
, format
->bmiHeader
.biHeight
);
321 This
->source_rect
.right
= This
->VideoWidth
= format
->bmiHeader
.biWidth
;
322 This
->source_rect
.bottom
= This
->VideoHeight
= format
->bmiHeader
.biHeight
;
323 This
->source_rect
.top
= This
->source_rect
.left
= 0;
325 else if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo2
))
327 VIDEOINFOHEADER2
*format
= (VIDEOINFOHEADER2
*)pmt
->pbFormat
;
329 This
->bmiheader
= format
->bmiHeader
;
331 TRACE("Resolution: %dx%d\n", format
->bmiHeader
.biWidth
, format
->bmiHeader
.biHeight
);
332 This
->source_rect
.right
= This
->VideoWidth
= format
->bmiHeader
.biWidth
;
333 This
->source_rect
.bottom
= This
->VideoHeight
= format
->bmiHeader
.biHeight
;
334 This
->source_rect
.top
= This
->source_rect
.left
= 0;
338 ERR("Format type %s not supported\n", debugstr_guid(&pmt
->formattype
));
341 if (This
->bmiheader
.biCompression
)
346 static HRESULT
VMR9_maybe_init(VMR9Impl
*This
, BOOL force
)
348 VMR9AllocationInfo info
;
352 TRACE("my mode: %u, my window: %p, my last window: %p\n", This
->mode
, This
->baseControlWindow
.baseWindow
.hWnd
, This
->hWndClippingWindow
);
353 if (This
->baseControlWindow
.baseWindow
.hWnd
|| !This
->renderer
.pInputPin
->pin
.pConnectedTo
)
356 if (This
->mode
== VMR9Mode_Windowless
&& !This
->hWndClippingWindow
)
357 return (force
? VFW_E_RUNTIME_ERROR
: S_OK
);
359 TRACE("Initializing\n");
360 info
.dwFlags
= VMR9AllocFlag_TextureSurface
;
361 info
.dwHeight
= This
->source_rect
.bottom
;
362 info
.dwWidth
= This
->source_rect
.right
;
363 info
.Pool
= D3DPOOL_DEFAULT
;
365 FIXME("Reduce ratio to least common denominator\n");
366 info
.szAspectRatio
.cx
= info
.dwWidth
;
367 info
.szAspectRatio
.cy
= info
.dwHeight
;
368 info
.szNativeSize
.cx
= This
->bmiheader
.biWidth
;
369 info
.szNativeSize
.cy
= This
->bmiheader
.biHeight
;
372 switch (This
->bmiheader
.biBitCount
)
374 case 8: info
.Format
= D3DFMT_R3G3B2
; break;
375 case 15: info
.Format
= D3DFMT_X1R5G5B5
; break;
376 case 16: info
.Format
= D3DFMT_R5G6B5
; break;
377 case 24: info
.Format
= D3DFMT_R8G8B8
; break;
378 case 32: info
.Format
= D3DFMT_X8R8G8B8
; break;
380 FIXME("Unknown bpp %u\n", This
->bmiheader
.biBitCount
);
384 This
->cur_surface
= 0;
385 if (This
->num_surfaces
)
387 ERR("num_surfaces or d3d9_surfaces not 0\n");
391 hr
= IVMRSurfaceAllocatorEx9_InitializeDevice(This
->allocator
, This
->cookie
, &info
, &buffers
);
394 This
->source_rect
.left
= This
->source_rect
.top
= 0;
395 This
->source_rect
.right
= This
->bmiheader
.biWidth
;
396 This
->source_rect
.bottom
= This
->bmiheader
.biHeight
;
398 This
->num_surfaces
= buffers
;
403 static VOID WINAPI
VMR9_OnStartStreaming(BaseRenderer
* iface
)
405 VMR9Impl
*This
= (VMR9Impl
*)iface
;
407 TRACE("(%p)\n", This
);
409 VMR9_maybe_init(This
, TRUE
);
410 IVMRImagePresenter9_StartPresenting(This
->presenter
, This
->cookie
);
411 SetWindowPos(This
->baseControlWindow
.baseWindow
.hWnd
, NULL
,
412 This
->source_rect
.left
,
413 This
->source_rect
.top
,
414 This
->source_rect
.right
- This
->source_rect
.left
,
415 This
->source_rect
.bottom
- This
->source_rect
.top
,
416 SWP_NOZORDER
|SWP_NOMOVE
|SWP_DEFERERASE
);
417 ShowWindow(This
->baseControlWindow
.baseWindow
.hWnd
, SW_SHOW
);
418 GetClientRect(This
->baseControlWindow
.baseWindow
.hWnd
, &This
->target_rect
);
421 static VOID WINAPI
VMR9_OnStopStreaming(BaseRenderer
* iface
)
423 VMR9Impl
*This
= (VMR9Impl
*)iface
;
425 TRACE("(%p)\n", This
);
427 if (This
->renderer
.filter
.state
== State_Running
)
428 IVMRImagePresenter9_StopPresenting(This
->presenter
, This
->cookie
);
431 static HRESULT WINAPI
VMR9_ShouldDrawSampleNow(BaseRenderer
*This
, IMediaSample
*pSample
, REFERENCE_TIME
*pStartTime
, REFERENCE_TIME
*pEndTime
)
433 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
434 if (IMediaSample_IsPreroll(pSample
) == S_OK
)
439 static HRESULT WINAPI
VMR9_CompleteConnect(BaseRenderer
*This
, IPin
*pReceivePin
)
441 VMR9Impl
*pVMR9
= (VMR9Impl
*)This
;
444 TRACE("(%p)\n", This
);
446 if (!pVMR9
->mode
&& SUCCEEDED(hr
))
447 hr
= IVMRFilterConfig9_SetRenderingMode(&pVMR9
->IVMRFilterConfig9_iface
, VMR9Mode_Windowed
);
450 hr
= VMR9_maybe_init(pVMR9
, FALSE
);
455 static HRESULT WINAPI
VMR9_BreakConnect(BaseRenderer
*This
)
457 VMR9Impl
*pVMR9
= (VMR9Impl
*)This
;
462 if (This
->pInputPin
->pin
.pConnectedTo
&& pVMR9
->allocator
&& pVMR9
->presenter
)
464 if (pVMR9
->renderer
.filter
.state
!= State_Stopped
)
466 ERR("Disconnecting while not stopped! UNTESTED!!\n");
468 if (pVMR9
->renderer
.filter
.state
== State_Running
)
469 hr
= IVMRImagePresenter9_StopPresenting(pVMR9
->presenter
, pVMR9
->cookie
);
470 IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9
->allocator
, pVMR9
->cookie
);
471 pVMR9
->num_surfaces
= 0;
476 static const BaseRendererFuncTable BaseFuncTable
= {
483 VMR9_OnStartStreaming
,
484 VMR9_OnStopStreaming
,
488 VMR9_ShouldDrawSampleNow
,
491 VMR9_CompleteConnect
,
498 static LPWSTR WINAPI
VMR9_GetClassWindowStyles(BaseWindow
*This
, DWORD
*pClassStyles
, DWORD
*pWindowStyles
, DWORD
*pWindowStylesEx
)
500 static WCHAR classnameW
[] = { 'I','V','M','R','9',' ','C','l','a','s','s', 0 };
503 *pWindowStyles
= WS_SIZEBOX
;
504 *pWindowStylesEx
= 0;
509 static RECT WINAPI
VMR9_GetDefaultRect(BaseWindow
*This
)
511 VMR9Impl
* pVMR9
= impl_from_BaseWindow(This
);
514 defRect
.left
= defRect
.top
= 0;
515 defRect
.right
= pVMR9
->VideoWidth
;
516 defRect
.bottom
= pVMR9
->VideoHeight
;
521 static BOOL WINAPI
VMR9_OnSize(BaseWindow
*This
, LONG Width
, LONG Height
)
523 VMR9Impl
* pVMR9
= impl_from_BaseWindow(This
);
525 TRACE("WM_SIZE %d %d\n", Width
, Height
);
526 GetClientRect(This
->hWnd
, &pVMR9
->target_rect
);
527 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
528 pVMR9
->target_rect
.left
,
529 pVMR9
->target_rect
.top
,
530 pVMR9
->target_rect
.right
- pVMR9
->target_rect
.left
,
531 pVMR9
->target_rect
.bottom
- pVMR9
->target_rect
.top
);
532 return BaseWindowImpl_OnSize(This
, Width
, Height
);
535 static const BaseWindowFuncTable renderer_BaseWindowFuncTable
= {
536 VMR9_GetClassWindowStyles
,
539 BaseControlWindowImpl_PossiblyEatMessage
,
543 static HRESULT WINAPI
VMR9_GetSourceRect(BaseControlVideo
* This
, RECT
*pSourceRect
)
545 VMR9Impl
* pVMR9
= impl_from_BaseControlVideo(This
);
546 CopyRect(pSourceRect
,&pVMR9
->source_rect
);
550 static HRESULT WINAPI
VMR9_GetStaticImage(BaseControlVideo
* This
, LONG
*pBufferSize
, LONG
*pDIBImage
)
552 VMR9Impl
* pVMR9
= impl_from_BaseControlVideo(This
);
553 BITMAPINFOHEADER
*bmiHeader
;
555 AM_MEDIA_TYPE
*amt
= &pVMR9
->renderer
.pInputPin
->pin
.mtCurrent
;
558 FIXME("(%p/%p)->(%p, %p): partial stub\n", pVMR9
, This
, pBufferSize
, pDIBImage
);
560 EnterCriticalSection(&pVMR9
->renderer
.filter
.csFilter
);
562 if (!pVMR9
->renderer
.pMediaSample
)
564 LeaveCriticalSection(&pVMR9
->renderer
.filter
.csFilter
);
565 return (pVMR9
->renderer
.filter
.state
== State_Paused
? E_UNEXPECTED
: VFW_E_NOT_PAUSED
);
568 if (IsEqualIID(&amt
->formattype
, &FORMAT_VideoInfo
))
570 bmiHeader
= &((VIDEOINFOHEADER
*)amt
->pbFormat
)->bmiHeader
;
572 else if (IsEqualIID(&amt
->formattype
, &FORMAT_VideoInfo2
))
574 bmiHeader
= &((VIDEOINFOHEADER2
*)amt
->pbFormat
)->bmiHeader
;
578 FIXME("Unknown type %s\n", debugstr_guid(&amt
->subtype
));
579 LeaveCriticalSection(&pVMR9
->renderer
.filter
.csFilter
);
580 return VFW_E_RUNTIME_ERROR
;
583 needed_size
= bmiHeader
->biSize
;
584 needed_size
+= IMediaSample_GetActualDataLength(pVMR9
->renderer
.pMediaSample
);
588 *pBufferSize
= needed_size
;
589 LeaveCriticalSection(&pVMR9
->renderer
.filter
.csFilter
);
593 if (needed_size
< *pBufferSize
)
595 ERR("Buffer too small %u/%u\n", needed_size
, *pBufferSize
);
596 LeaveCriticalSection(&pVMR9
->renderer
.filter
.csFilter
);
599 *pBufferSize
= needed_size
;
601 memcpy(pDIBImage
, bmiHeader
, bmiHeader
->biSize
);
602 IMediaSample_GetPointer(pVMR9
->renderer
.pMediaSample
, (BYTE
**)&ptr
);
603 memcpy((char *)pDIBImage
+ bmiHeader
->biSize
, ptr
, IMediaSample_GetActualDataLength(pVMR9
->renderer
.pMediaSample
));
605 LeaveCriticalSection(&pVMR9
->renderer
.filter
.csFilter
);
609 static HRESULT WINAPI
VMR9_GetTargetRect(BaseControlVideo
* This
, RECT
*pTargetRect
)
611 VMR9Impl
* pVMR9
= impl_from_BaseControlVideo(This
);
612 CopyRect(pTargetRect
,&pVMR9
->target_rect
);
616 static VIDEOINFOHEADER
* WINAPI
VMR9_GetVideoFormat(BaseControlVideo
* This
)
618 VMR9Impl
* pVMR9
= impl_from_BaseControlVideo(This
);
621 TRACE("(%p/%p)\n", pVMR9
, This
);
623 pmt
= &pVMR9
->renderer
.pInputPin
->pin
.mtCurrent
;
624 if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo
)) {
625 return (VIDEOINFOHEADER
*)pmt
->pbFormat
;
626 } else if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo2
)) {
627 static VIDEOINFOHEADER vih
;
628 VIDEOINFOHEADER2
*vih2
= (VIDEOINFOHEADER2
*)pmt
->pbFormat
;
629 memcpy(&vih
,vih2
,sizeof(VIDEOINFOHEADER
));
630 memcpy(&vih
.bmiHeader
, &vih2
->bmiHeader
, sizeof(BITMAPINFOHEADER
));
633 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt
->formattype
));
638 static HRESULT WINAPI
VMR9_IsDefaultSourceRect(BaseControlVideo
* This
)
640 VMR9Impl
* pVMR9
= impl_from_BaseControlVideo(This
);
641 FIXME("(%p/%p)->(): stub !!!\n", pVMR9
, This
);
646 static HRESULT WINAPI
VMR9_IsDefaultTargetRect(BaseControlVideo
* This
)
648 VMR9Impl
* pVMR9
= impl_from_BaseControlVideo(This
);
649 FIXME("(%p/%p)->(): stub !!!\n", pVMR9
, This
);
654 static HRESULT WINAPI
VMR9_SetDefaultSourceRect(BaseControlVideo
* This
)
656 VMR9Impl
* pVMR9
= impl_from_BaseControlVideo(This
);
658 pVMR9
->source_rect
.left
= 0;
659 pVMR9
->source_rect
.top
= 0;
660 pVMR9
->source_rect
.right
= pVMR9
->VideoWidth
;
661 pVMR9
->source_rect
.bottom
= pVMR9
->VideoHeight
;
666 static HRESULT WINAPI
VMR9_SetDefaultTargetRect(BaseControlVideo
* This
)
669 VMR9Impl
* pVMR9
= impl_from_BaseControlVideo(This
);
671 if (!GetClientRect(pVMR9
->baseControlWindow
.baseWindow
.hWnd
, &rect
))
674 pVMR9
->target_rect
.left
= 0;
675 pVMR9
->target_rect
.top
= 0;
676 pVMR9
->target_rect
.right
= rect
.right
;
677 pVMR9
->target_rect
.bottom
= rect
.bottom
;
682 static HRESULT WINAPI
VMR9_SetSourceRect(BaseControlVideo
* This
, RECT
*pSourceRect
)
684 VMR9Impl
* pVMR9
= impl_from_BaseControlVideo(This
);
685 CopyRect(&pVMR9
->source_rect
,pSourceRect
);
689 static HRESULT WINAPI
VMR9_SetTargetRect(BaseControlVideo
* This
, RECT
*pTargetRect
)
691 VMR9Impl
* pVMR9
= impl_from_BaseControlVideo(This
);
692 CopyRect(&pVMR9
->target_rect
,pTargetRect
);
696 static const BaseControlVideoFuncTable renderer_BaseControlVideoFuncTable
= {
701 VMR9_IsDefaultSourceRect
,
702 VMR9_IsDefaultTargetRect
,
703 VMR9_SetDefaultSourceRect
,
704 VMR9_SetDefaultTargetRect
,
709 static HRESULT WINAPI
VMR9Inner_QueryInterface(IUnknown
* iface
, REFIID riid
, LPVOID
* ppv
)
711 VMR9Impl
*This
= impl_from_inner_IUnknown(iface
);
712 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, qzdebugstr_guid(riid
), ppv
);
714 if (This
->bAggregatable
)
715 This
->bUnkOuterValid
= TRUE
;
719 if (IsEqualIID(riid
, &IID_IUnknown
))
720 *ppv
= &This
->IUnknown_inner
;
721 else if (IsEqualIID(riid
, &IID_IVideoWindow
))
722 *ppv
= &This
->baseControlWindow
.IVideoWindow_iface
;
723 else if (IsEqualIID(riid
, &IID_IBasicVideo
))
724 *ppv
= &This
->baseControlVideo
.IBasicVideo_iface
;
725 else if (IsEqualIID(riid
, &IID_IAMFilterMiscFlags
))
726 *ppv
= &This
->IAMFilterMiscFlags_iface
;
727 else if (IsEqualIID(riid
, &IID_IVMRFilterConfig9
))
728 *ppv
= &This
->IVMRFilterConfig9_iface
;
729 else if (IsEqualIID(riid
, &IID_IVMRWindowlessControl9
) && This
->mode
== VMR9Mode_Windowless
)
730 *ppv
= &This
->IVMRWindowlessControl9_iface
;
731 else if (IsEqualIID(riid
, &IID_IVMRSurfaceAllocatorNotify9
) && This
->mode
== VMR9Mode_Renderless
)
732 *ppv
= &This
->IVMRSurfaceAllocatorNotify9_iface
;
736 hr
= BaseRendererImpl_QueryInterface(&This
->renderer
.filter
.IBaseFilter_iface
, riid
, ppv
);
743 IUnknown_AddRef((IUnknown
*)(*ppv
));
747 else if (IsEqualIID(riid
, &IID_IBasicVideo2
))
748 FIXME("No interface for IID_IBasicVideo2\n");
749 else if (IsEqualIID(riid
, &IID_IVMRWindowlessControl9
))
751 else if (IsEqualIID(riid
, &IID_IVMRSurfaceAllocatorNotify9
))
753 else if (IsEqualIID(riid
, &IID_IMediaPosition
))
754 FIXME("No interface for IID_IMediaPosition\n");
755 else if (IsEqualIID(riid
, &IID_IQualProp
))
756 FIXME("No interface for IID_IQualProp\n");
757 else if (IsEqualIID(riid
, &IID_IVMRAspectRatioControl9
))
758 FIXME("No interface for IID_IVMRAspectRatioControl9\n");
759 else if (IsEqualIID(riid
, &IID_IVMRDeinterlaceControl9
))
760 FIXME("No interface for IID_IVMRDeinterlaceControl9\n");
761 else if (IsEqualIID(riid
, &IID_IVMRMixerBitmap9
))
762 FIXME("No interface for IID_IVMRMixerBitmap9\n");
763 else if (IsEqualIID(riid
, &IID_IVMRMonitorConfig9
))
764 FIXME("No interface for IID_IVMRMonitorConfig9\n");
765 else if (IsEqualIID(riid
, &IID_IVMRMixerControl9
))
766 FIXME("No interface for IID_IVMRMixerControl9\n");
768 FIXME("No interface for %s\n", debugstr_guid(riid
));
770 return E_NOINTERFACE
;
773 static ULONG WINAPI
VMR9Inner_AddRef(IUnknown
* iface
)
775 VMR9Impl
*This
= impl_from_inner_IUnknown(iface
);
776 ULONG refCount
= BaseFilterImpl_AddRef(&This
->renderer
.filter
.IBaseFilter_iface
);
778 TRACE("(%p/%p)->() AddRef from %d\n", This
, iface
, refCount
- 1);
783 static ULONG WINAPI
VMR9Inner_Release(IUnknown
* iface
)
785 VMR9Impl
*This
= impl_from_inner_IUnknown(iface
);
786 ULONG refCount
= BaseRendererImpl_Release(&This
->renderer
.filter
.IBaseFilter_iface
);
788 TRACE("(%p/%p)->() Release from %d\n", This
, iface
, refCount
+ 1);
792 TRACE("Destroying\n");
793 BaseControlWindow_Destroy(&This
->baseControlWindow
);
794 CloseHandle(This
->hD3d9
);
797 IVMRSurfaceAllocatorEx9_Release(This
->allocator
);
799 IVMRImagePresenter9_Release(This
->presenter
);
801 This
->num_surfaces
= 0;
802 if (This
->allocator_d3d9_dev
)
804 IDirect3DDevice9_Release(This
->allocator_d3d9_dev
);
805 This
->allocator_d3d9_dev
= NULL
;
813 static const IUnknownVtbl IInner_VTable
=
815 VMR9Inner_QueryInterface
,
820 static HRESULT WINAPI
VMR9_QueryInterface(IBaseFilter
* iface
, REFIID riid
, LPVOID
* ppv
)
822 VMR9Impl
*This
= (VMR9Impl
*)iface
;
824 if (This
->bAggregatable
)
825 This
->bUnkOuterValid
= TRUE
;
829 if (This
->bAggregatable
)
830 return IUnknown_QueryInterface(This
->outer_unk
, riid
, ppv
);
832 if (IsEqualIID(riid
, &IID_IUnknown
))
836 IUnknown_AddRef(&This
->IUnknown_inner
);
837 hr
= IUnknown_QueryInterface(&This
->IUnknown_inner
, riid
, ppv
);
838 IUnknown_Release(&This
->IUnknown_inner
);
839 This
->bAggregatable
= TRUE
;
844 return E_NOINTERFACE
;
847 return IUnknown_QueryInterface(&This
->IUnknown_inner
, riid
, ppv
);
850 static ULONG WINAPI
VMR9_AddRef(IBaseFilter
* iface
)
852 VMR9Impl
*This
= (VMR9Impl
*)iface
;
855 if (This
->outer_unk
&& This
->bUnkOuterValid
)
856 ret
= IUnknown_AddRef(This
->outer_unk
);
858 ret
= IUnknown_AddRef(&This
->IUnknown_inner
);
860 TRACE("(%p)->AddRef from %d\n", iface
, ret
- 1);
865 static ULONG WINAPI
VMR9_Release(IBaseFilter
* iface
)
867 VMR9Impl
*This
= (VMR9Impl
*)iface
;
870 if (This
->outer_unk
&& This
->bUnkOuterValid
)
871 ret
= IUnknown_Release(This
->outer_unk
);
873 ret
= IUnknown_Release(&This
->IUnknown_inner
);
875 TRACE("(%p)->Release from %d\n", iface
, ret
+ 1);
882 static const IBaseFilterVtbl VMR9_Vtbl
=
887 BaseFilterImpl_GetClassID
,
888 BaseRendererImpl_Stop
,
889 BaseRendererImpl_Pause
,
890 BaseRendererImpl_Run
,
891 BaseRendererImpl_GetState
,
892 BaseRendererImpl_SetSyncSource
,
893 BaseFilterImpl_GetSyncSource
,
894 BaseFilterImpl_EnumPins
,
895 BaseRendererImpl_FindPin
,
896 BaseFilterImpl_QueryFilterInfo
,
897 BaseFilterImpl_JoinFilterGraph
,
898 BaseFilterImpl_QueryVendorInfo
901 /*** IUnknown methods ***/
902 static HRESULT WINAPI
Videowindow_QueryInterface(IVideoWindow
*iface
, REFIID riid
, LPVOID
*ppvObj
)
904 VMR9Impl
*This
= impl_from_IVideoWindow(iface
);
906 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
908 return VMR9_QueryInterface(&This
->renderer
.filter
.IBaseFilter_iface
, riid
, ppvObj
);
911 static ULONG WINAPI
Videowindow_AddRef(IVideoWindow
*iface
)
913 VMR9Impl
*This
= impl_from_IVideoWindow(iface
);
915 TRACE("(%p/%p)->()\n", This
, iface
);
917 return VMR9_AddRef(&This
->renderer
.filter
.IBaseFilter_iface
);
920 static ULONG WINAPI
Videowindow_Release(IVideoWindow
*iface
)
922 VMR9Impl
*This
= impl_from_IVideoWindow(iface
);
924 TRACE("(%p/%p)->()\n", This
, iface
);
926 return VMR9_Release(&This
->renderer
.filter
.IBaseFilter_iface
);
929 static const IVideoWindowVtbl IVideoWindow_VTable
=
931 Videowindow_QueryInterface
,
934 BaseControlWindowImpl_GetTypeInfoCount
,
935 BaseControlWindowImpl_GetTypeInfo
,
936 BaseControlWindowImpl_GetIDsOfNames
,
937 BaseControlWindowImpl_Invoke
,
938 BaseControlWindowImpl_put_Caption
,
939 BaseControlWindowImpl_get_Caption
,
940 BaseControlWindowImpl_put_WindowStyle
,
941 BaseControlWindowImpl_get_WindowStyle
,
942 BaseControlWindowImpl_put_WindowStyleEx
,
943 BaseControlWindowImpl_get_WindowStyleEx
,
944 BaseControlWindowImpl_put_AutoShow
,
945 BaseControlWindowImpl_get_AutoShow
,
946 BaseControlWindowImpl_put_WindowState
,
947 BaseControlWindowImpl_get_WindowState
,
948 BaseControlWindowImpl_put_BackgroundPalette
,
949 BaseControlWindowImpl_get_BackgroundPalette
,
950 BaseControlWindowImpl_put_Visible
,
951 BaseControlWindowImpl_get_Visible
,
952 BaseControlWindowImpl_put_Left
,
953 BaseControlWindowImpl_get_Left
,
954 BaseControlWindowImpl_put_Width
,
955 BaseControlWindowImpl_get_Width
,
956 BaseControlWindowImpl_put_Top
,
957 BaseControlWindowImpl_get_Top
,
958 BaseControlWindowImpl_put_Height
,
959 BaseControlWindowImpl_get_Height
,
960 BaseControlWindowImpl_put_Owner
,
961 BaseControlWindowImpl_get_Owner
,
962 BaseControlWindowImpl_put_MessageDrain
,
963 BaseControlWindowImpl_get_MessageDrain
,
964 BaseControlWindowImpl_get_BorderColor
,
965 BaseControlWindowImpl_put_BorderColor
,
966 BaseControlWindowImpl_get_FullScreenMode
,
967 BaseControlWindowImpl_put_FullScreenMode
,
968 BaseControlWindowImpl_SetWindowForeground
,
969 BaseControlWindowImpl_NotifyOwnerMessage
,
970 BaseControlWindowImpl_SetWindowPosition
,
971 BaseControlWindowImpl_GetWindowPosition
,
972 BaseControlWindowImpl_GetMinIdealImageSize
,
973 BaseControlWindowImpl_GetMaxIdealImageSize
,
974 BaseControlWindowImpl_GetRestorePosition
,
975 BaseControlWindowImpl_HideCursor
,
976 BaseControlWindowImpl_IsCursorHidden
979 /*** IUnknown methods ***/
980 static HRESULT WINAPI
Basicvideo_QueryInterface(IBasicVideo
*iface
, REFIID riid
, LPVOID
* ppvObj
)
982 VMR9Impl
*This
= impl_from_IBasicVideo(iface
);
984 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
986 return VMR9_QueryInterface(&This
->renderer
.filter
.IBaseFilter_iface
, riid
, ppvObj
);
989 static ULONG WINAPI
Basicvideo_AddRef(IBasicVideo
*iface
)
991 VMR9Impl
*This
= impl_from_IBasicVideo(iface
);
993 TRACE("(%p/%p)->()\n", This
, iface
);
995 return VMR9_AddRef(&This
->renderer
.filter
.IBaseFilter_iface
);
998 static ULONG WINAPI
Basicvideo_Release(IBasicVideo
*iface
)
1000 VMR9Impl
*This
= impl_from_IBasicVideo(iface
);
1002 TRACE("(%p/%p)->()\n", This
, iface
);
1004 return VMR9_Release(&This
->renderer
.filter
.IBaseFilter_iface
);
1007 static const IBasicVideoVtbl IBasicVideo_VTable
=
1009 Basicvideo_QueryInterface
,
1012 BaseControlVideoImpl_GetTypeInfoCount
,
1013 BaseControlVideoImpl_GetTypeInfo
,
1014 BaseControlVideoImpl_GetIDsOfNames
,
1015 BaseControlVideoImpl_Invoke
,
1016 BaseControlVideoImpl_get_AvgTimePerFrame
,
1017 BaseControlVideoImpl_get_BitRate
,
1018 BaseControlVideoImpl_get_BitErrorRate
,
1019 BaseControlVideoImpl_get_VideoWidth
,
1020 BaseControlVideoImpl_get_VideoHeight
,
1021 BaseControlVideoImpl_put_SourceLeft
,
1022 BaseControlVideoImpl_get_SourceLeft
,
1023 BaseControlVideoImpl_put_SourceWidth
,
1024 BaseControlVideoImpl_get_SourceWidth
,
1025 BaseControlVideoImpl_put_SourceTop
,
1026 BaseControlVideoImpl_get_SourceTop
,
1027 BaseControlVideoImpl_put_SourceHeight
,
1028 BaseControlVideoImpl_get_SourceHeight
,
1029 BaseControlVideoImpl_put_DestinationLeft
,
1030 BaseControlVideoImpl_get_DestinationLeft
,
1031 BaseControlVideoImpl_put_DestinationWidth
,
1032 BaseControlVideoImpl_get_DestinationWidth
,
1033 BaseControlVideoImpl_put_DestinationTop
,
1034 BaseControlVideoImpl_get_DestinationTop
,
1035 BaseControlVideoImpl_put_DestinationHeight
,
1036 BaseControlVideoImpl_get_DestinationHeight
,
1037 BaseControlVideoImpl_SetSourcePosition
,
1038 BaseControlVideoImpl_GetSourcePosition
,
1039 BaseControlVideoImpl_SetDefaultSourcePosition
,
1040 BaseControlVideoImpl_SetDestinationPosition
,
1041 BaseControlVideoImpl_GetDestinationPosition
,
1042 BaseControlVideoImpl_SetDefaultDestinationPosition
,
1043 BaseControlVideoImpl_GetVideoSize
,
1044 BaseControlVideoImpl_GetVideoPaletteEntries
,
1045 BaseControlVideoImpl_GetCurrentImage
,
1046 BaseControlVideoImpl_IsUsingDefaultSource
,
1047 BaseControlVideoImpl_IsUsingDefaultDestination
1050 static HRESULT WINAPI
AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags
*iface
, REFIID riid
, void **ppv
) {
1051 VMR9Impl
*This
= impl_from_IAMFilterMiscFlags(iface
);
1052 return VMR9_QueryInterface(&This
->renderer
.filter
.IBaseFilter_iface
, riid
, ppv
);
1055 static ULONG WINAPI
AMFilterMiscFlags_AddRef(IAMFilterMiscFlags
*iface
) {
1056 VMR9Impl
*This
= impl_from_IAMFilterMiscFlags(iface
);
1057 return VMR9_AddRef(&This
->renderer
.filter
.IBaseFilter_iface
);
1060 static ULONG WINAPI
AMFilterMiscFlags_Release(IAMFilterMiscFlags
*iface
) {
1061 VMR9Impl
*This
= impl_from_IAMFilterMiscFlags(iface
);
1062 return VMR9_Release(&This
->renderer
.filter
.IBaseFilter_iface
);
1065 static ULONG WINAPI
AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags
*iface
) {
1066 return AM_FILTER_MISC_FLAGS_IS_RENDERER
;
1069 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl
= {
1070 AMFilterMiscFlags_QueryInterface
,
1071 AMFilterMiscFlags_AddRef
,
1072 AMFilterMiscFlags_Release
,
1073 AMFilterMiscFlags_GetMiscFlags
1076 static HRESULT WINAPI
VMR9FilterConfig_QueryInterface(IVMRFilterConfig9
*iface
, REFIID riid
, LPVOID
* ppv
)
1078 VMR9Impl
*This
= impl_from_IVMRFilterConfig9(iface
);
1079 return VMR9_QueryInterface(&This
->renderer
.filter
.IBaseFilter_iface
, riid
, ppv
);
1082 static ULONG WINAPI
VMR9FilterConfig_AddRef(IVMRFilterConfig9
*iface
)
1084 VMR9Impl
*This
= impl_from_IVMRFilterConfig9(iface
);
1085 return VMR9_AddRef(&This
->renderer
.filter
.IBaseFilter_iface
);
1088 static ULONG WINAPI
VMR9FilterConfig_Release(IVMRFilterConfig9
*iface
)
1090 VMR9Impl
*This
= impl_from_IVMRFilterConfig9(iface
);
1091 return VMR9_Release(&This
->renderer
.filter
.IBaseFilter_iface
);
1094 static HRESULT WINAPI
VMR9FilterConfig_SetImageCompositor(IVMRFilterConfig9
*iface
, IVMRImageCompositor9
*compositor
)
1096 VMR9Impl
*This
= impl_from_IVMRFilterConfig9(iface
);
1098 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, compositor
);
1102 static HRESULT WINAPI
VMR9FilterConfig_SetNumberOfStreams(IVMRFilterConfig9
*iface
, DWORD max
)
1104 VMR9Impl
*This
= impl_from_IVMRFilterConfig9(iface
);
1106 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, max
);
1110 static HRESULT WINAPI
VMR9FilterConfig_GetNumberOfStreams(IVMRFilterConfig9
*iface
, DWORD
*max
)
1112 VMR9Impl
*This
= impl_from_IVMRFilterConfig9(iface
);
1114 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, max
);
1118 static HRESULT WINAPI
VMR9FilterConfig_SetRenderingPrefs(IVMRFilterConfig9
*iface
, DWORD renderflags
)
1120 VMR9Impl
*This
= impl_from_IVMRFilterConfig9(iface
);
1122 FIXME("(%p/%p)->(%u) stub\n", iface
, This
, renderflags
);
1126 static HRESULT WINAPI
VMR9FilterConfig_GetRenderingPrefs(IVMRFilterConfig9
*iface
, DWORD
*renderflags
)
1128 VMR9Impl
*This
= impl_from_IVMRFilterConfig9(iface
);
1130 FIXME("(%p/%p)->(%p) stub\n", iface
, This
, renderflags
);
1134 static HRESULT WINAPI
VMR9FilterConfig_SetRenderingMode(IVMRFilterConfig9
*iface
, DWORD mode
)
1137 VMR9Impl
*This
= impl_from_IVMRFilterConfig9(iface
);
1139 TRACE("(%p/%p)->(%u)\n", iface
, This
, mode
);
1141 EnterCriticalSection(&This
->renderer
.filter
.csFilter
);
1144 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1145 return VFW_E_WRONG_STATE
;
1148 if (This
->allocator
)
1149 IVMRSurfaceAllocatorEx9_Release(This
->allocator
);
1150 if (This
->presenter
)
1151 IVMRImagePresenter9_Release(This
->presenter
);
1153 This
->allocator
= NULL
;
1154 This
->presenter
= NULL
;
1158 case VMR9Mode_Windowed
:
1159 case VMR9Mode_Windowless
:
1160 This
->allocator_is_ex
= 0;
1163 hr
= VMR9DefaultAllocatorPresenterImpl_create(This
, (LPVOID
*)&This
->presenter
);
1165 hr
= IVMRImagePresenter9_QueryInterface(This
->presenter
, &IID_IVMRSurfaceAllocatorEx9
, (LPVOID
*)&This
->allocator
);
1168 ERR("Unable to find Presenter interface\n");
1169 IVMRImagePresenter9_Release(This
->presenter
);
1170 This
->allocator
= NULL
;
1171 This
->presenter
= NULL
;
1174 hr
= IVMRSurfaceAllocatorEx9_AdviseNotify(This
->allocator
, &This
->IVMRSurfaceAllocatorNotify9_iface
);
1176 case VMR9Mode_Renderless
:
1179 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1180 return E_INVALIDARG
;
1184 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1188 static HRESULT WINAPI
VMR9FilterConfig_GetRenderingMode(IVMRFilterConfig9
*iface
, DWORD
*mode
)
1190 VMR9Impl
*This
= impl_from_IVMRFilterConfig9(iface
);
1192 TRACE("(%p/%p)->(%p) stub\n", iface
, This
, mode
);
1199 *mode
= VMR9Mode_Windowed
;
1204 static const IVMRFilterConfig9Vtbl VMR9_FilterConfig_Vtbl
=
1206 VMR9FilterConfig_QueryInterface
,
1207 VMR9FilterConfig_AddRef
,
1208 VMR9FilterConfig_Release
,
1209 VMR9FilterConfig_SetImageCompositor
,
1210 VMR9FilterConfig_SetNumberOfStreams
,
1211 VMR9FilterConfig_GetNumberOfStreams
,
1212 VMR9FilterConfig_SetRenderingPrefs
,
1213 VMR9FilterConfig_GetRenderingPrefs
,
1214 VMR9FilterConfig_SetRenderingMode
,
1215 VMR9FilterConfig_GetRenderingMode
1218 static HRESULT WINAPI
VMR9WindowlessControl_QueryInterface(IVMRWindowlessControl9
*iface
, REFIID riid
, LPVOID
* ppv
)
1220 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1221 return VMR9_QueryInterface(&This
->renderer
.filter
.IBaseFilter_iface
, riid
, ppv
);
1224 static ULONG WINAPI
VMR9WindowlessControl_AddRef(IVMRWindowlessControl9
*iface
)
1226 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1227 return VMR9_AddRef(&This
->renderer
.filter
.IBaseFilter_iface
);
1230 static ULONG WINAPI
VMR9WindowlessControl_Release(IVMRWindowlessControl9
*iface
)
1232 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1233 return VMR9_Release(&This
->renderer
.filter
.IBaseFilter_iface
);
1236 static HRESULT WINAPI
VMR9WindowlessControl_GetNativeVideoSize(IVMRWindowlessControl9
*iface
, LONG
*width
, LONG
*height
, LONG
*arwidth
, LONG
*arheight
)
1238 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1239 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", iface
, This
, width
, height
, arwidth
, arheight
);
1241 if (!width
|| !height
|| !arwidth
|| !arheight
)
1243 ERR("Got no pointer\n");
1247 *width
= This
->bmiheader
.biWidth
;
1248 *height
= This
->bmiheader
.biHeight
;
1249 *arwidth
= This
->bmiheader
.biWidth
;
1250 *arheight
= This
->bmiheader
.biHeight
;
1255 static HRESULT WINAPI
VMR9WindowlessControl_GetMinIdealVideoSize(IVMRWindowlessControl9
*iface
, LONG
*width
, LONG
*height
)
1257 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1259 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1263 static HRESULT WINAPI
VMR9WindowlessControl_GetMaxIdealVideoSize(IVMRWindowlessControl9
*iface
, LONG
*width
, LONG
*height
)
1265 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1267 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1271 static HRESULT WINAPI
VMR9WindowlessControl_SetVideoPosition(IVMRWindowlessControl9
*iface
, const RECT
*source
, const RECT
*dest
)
1273 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1275 TRACE("(%p/%p)->(%p, %p)\n", iface
, This
, source
, dest
);
1277 EnterCriticalSection(&This
->renderer
.filter
.csFilter
);
1280 This
->source_rect
= *source
;
1283 This
->target_rect
= *dest
;
1284 if (This
->baseControlWindow
.baseWindow
.hWnd
)
1286 FIXME("Output rectangle: starting at %dx%d, up to point %dx%d\n", dest
->left
, dest
->top
, dest
->right
, dest
->bottom
);
1287 SetWindowPos(This
->baseControlWindow
.baseWindow
.hWnd
, NULL
, dest
->left
, dest
->top
, dest
->right
- dest
->left
,
1288 dest
->bottom
-dest
->top
, SWP_NOACTIVATE
|SWP_NOCOPYBITS
|SWP_NOOWNERZORDER
|SWP_NOREDRAW
);
1292 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1297 static HRESULT WINAPI
VMR9WindowlessControl_GetVideoPosition(IVMRWindowlessControl9
*iface
, RECT
*source
, RECT
*dest
)
1299 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1302 *source
= This
->source_rect
;
1305 *dest
= This
->target_rect
;
1307 FIXME("(%p/%p)->(%p/%p) stub\n", iface
, This
, source
, dest
);
1311 static HRESULT WINAPI
VMR9WindowlessControl_GetAspectRatioMode(IVMRWindowlessControl9
*iface
, DWORD
*mode
)
1313 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1315 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1319 static HRESULT WINAPI
VMR9WindowlessControl_SetAspectRatioMode(IVMRWindowlessControl9
*iface
, DWORD mode
)
1321 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1323 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1327 static HRESULT WINAPI
VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowlessControl9
*iface
, HWND hwnd
)
1329 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1331 TRACE("(%p/%p)->(%p)\n", iface
, This
, hwnd
);
1333 EnterCriticalSection(&This
->renderer
.filter
.csFilter
);
1334 This
->hWndClippingWindow
= hwnd
;
1335 VMR9_maybe_init(This
, FALSE
);
1337 IVMRSurfaceAllocatorEx9_TerminateDevice(This
->allocator
, This
->cookie
);
1338 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1342 static HRESULT WINAPI
VMR9WindowlessControl_RepaintVideo(IVMRWindowlessControl9
*iface
, HWND hwnd
, HDC hdc
)
1344 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1347 FIXME("(%p/%p)->(...) semi-stub\n", iface
, This
);
1349 EnterCriticalSection(&This
->renderer
.filter
.csFilter
);
1350 if (hwnd
!= This
->hWndClippingWindow
&& hwnd
!= This
->baseControlWindow
.baseWindow
.hWnd
)
1352 ERR("Not handling changing windows yet!!!\n");
1353 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1357 if (!This
->allocator_d3d9_dev
)
1359 ERR("No d3d9 device!\n");
1360 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1361 return VFW_E_WRONG_STATE
;
1364 /* Windowless extension */
1365 hr
= IDirect3DDevice9_Present(This
->allocator_d3d9_dev
, NULL
, NULL
, This
->baseControlWindow
.baseWindow
.hWnd
, NULL
);
1366 LeaveCriticalSection(&This
->renderer
.filter
.csFilter
);
1371 static HRESULT WINAPI
VMR9WindowlessControl_DisplayModeChanged(IVMRWindowlessControl9
*iface
)
1373 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1375 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1379 static HRESULT WINAPI
VMR9WindowlessControl_GetCurrentImage(IVMRWindowlessControl9
*iface
, BYTE
**dib
)
1381 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1383 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1387 static HRESULT WINAPI
VMR9WindowlessControl_SetBorderColor(IVMRWindowlessControl9
*iface
, COLORREF color
)
1389 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1391 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1395 static HRESULT WINAPI
VMR9WindowlessControl_GetBorderColor(IVMRWindowlessControl9
*iface
, COLORREF
*color
)
1397 VMR9Impl
*This
= impl_from_IVMRWindowlessControl9(iface
);
1399 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1403 static const IVMRWindowlessControl9Vtbl VMR9_WindowlessControl_Vtbl
=
1405 VMR9WindowlessControl_QueryInterface
,
1406 VMR9WindowlessControl_AddRef
,
1407 VMR9WindowlessControl_Release
,
1408 VMR9WindowlessControl_GetNativeVideoSize
,
1409 VMR9WindowlessControl_GetMinIdealVideoSize
,
1410 VMR9WindowlessControl_GetMaxIdealVideoSize
,
1411 VMR9WindowlessControl_SetVideoPosition
,
1412 VMR9WindowlessControl_GetVideoPosition
,
1413 VMR9WindowlessControl_GetAspectRatioMode
,
1414 VMR9WindowlessControl_SetAspectRatioMode
,
1415 VMR9WindowlessControl_SetVideoClippingWindow
,
1416 VMR9WindowlessControl_RepaintVideo
,
1417 VMR9WindowlessControl_DisplayModeChanged
,
1418 VMR9WindowlessControl_GetCurrentImage
,
1419 VMR9WindowlessControl_SetBorderColor
,
1420 VMR9WindowlessControl_GetBorderColor
1423 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_QueryInterface(IVMRSurfaceAllocatorNotify9
*iface
, REFIID riid
, LPVOID
* ppv
)
1425 VMR9Impl
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1426 return VMR9_QueryInterface(&This
->renderer
.filter
.IBaseFilter_iface
, riid
, ppv
);
1429 static ULONG WINAPI
VMR9SurfaceAllocatorNotify_AddRef(IVMRSurfaceAllocatorNotify9
*iface
)
1431 VMR9Impl
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1432 return VMR9_AddRef(&This
->renderer
.filter
.IBaseFilter_iface
);
1435 static ULONG WINAPI
VMR9SurfaceAllocatorNotify_Release(IVMRSurfaceAllocatorNotify9
*iface
)
1437 VMR9Impl
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1438 return VMR9_Release(&This
->renderer
.filter
.IBaseFilter_iface
);
1441 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator(IVMRSurfaceAllocatorNotify9
*iface
, DWORD_PTR id
, IVMRSurfaceAllocator9
*alloc
)
1443 VMR9Impl
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1445 /* FIXME: This code is not tested!!! */
1446 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1449 if (This
->presenter
)
1450 return VFW_E_WRONG_STATE
;
1452 if (FAILED(IVMRSurfaceAllocator9_QueryInterface(alloc
, &IID_IVMRImagePresenter9
, (void **)&This
->presenter
)))
1453 return E_NOINTERFACE
;
1455 if (SUCCEEDED(IVMRSurfaceAllocator9_QueryInterface(alloc
, &IID_IVMRSurfaceAllocatorEx9
, (void **)&This
->allocator
)))
1456 This
->allocator_is_ex
= 1;
1459 This
->allocator
= (IVMRSurfaceAllocatorEx9
*)alloc
;
1460 IVMRSurfaceAllocator9_AddRef(alloc
);
1461 This
->allocator_is_ex
= 0;
1467 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_SetD3DDevice(IVMRSurfaceAllocatorNotify9
*iface
, IDirect3DDevice9
*device
, HMONITOR monitor
)
1469 VMR9Impl
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1471 FIXME("(%p/%p)->(...) semi-stub\n", iface
, This
);
1472 if (This
->allocator_d3d9_dev
)
1473 IDirect3DDevice9_Release(This
->allocator_d3d9_dev
);
1474 This
->allocator_d3d9_dev
= device
;
1475 IDirect3DDevice9_AddRef(This
->allocator_d3d9_dev
);
1476 This
->allocator_mon
= monitor
;
1481 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_ChangeD3DDevice(IVMRSurfaceAllocatorNotify9
*iface
, IDirect3DDevice9
*device
, HMONITOR monitor
)
1483 VMR9Impl
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1485 FIXME("(%p/%p)->(...) semi-stub\n", iface
, This
);
1486 if (This
->allocator_d3d9_dev
)
1487 IDirect3DDevice9_Release(This
->allocator_d3d9_dev
);
1488 This
->allocator_d3d9_dev
= device
;
1489 IDirect3DDevice9_AddRef(This
->allocator_d3d9_dev
);
1490 This
->allocator_mon
= monitor
;
1495 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper(IVMRSurfaceAllocatorNotify9
*iface
, VMR9AllocationInfo
*allocinfo
, DWORD
*numbuffers
, IDirect3DSurface9
**surface
)
1497 VMR9Impl
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1501 FIXME("(%p/%p)->(%p, %p => %u, %p) semi-stub\n", iface
, This
, allocinfo
, numbuffers
, (numbuffers
? *numbuffers
: 0), surface
);
1503 if (!allocinfo
|| !numbuffers
|| !surface
)
1506 if (!*numbuffers
|| *numbuffers
< allocinfo
->MinBuffers
)
1508 ERR("Invalid number of buffers?\n");
1509 return E_INVALIDARG
;
1512 if (!This
->allocator_d3d9_dev
)
1514 ERR("No direct3d device when requested to allocate a surface!\n");
1515 return VFW_E_WRONG_STATE
;
1518 if (allocinfo
->dwFlags
& VMR9AllocFlag_OffscreenSurface
)
1520 ERR("Creating offscreen surface\n");
1521 for (i
= 0; i
< *numbuffers
; ++i
)
1523 hr
= IDirect3DDevice9_CreateOffscreenPlainSurface(This
->allocator_d3d9_dev
, allocinfo
->dwWidth
, allocinfo
->dwHeight
,
1524 allocinfo
->Format
, allocinfo
->Pool
, &surface
[i
], NULL
);
1529 else if (allocinfo
->dwFlags
& VMR9AllocFlag_TextureSurface
)
1531 TRACE("Creating texture surface\n");
1532 for (i
= 0; i
< *numbuffers
; ++i
)
1534 IDirect3DTexture9
*texture
;
1536 hr
= IDirect3DDevice9_CreateTexture(This
->allocator_d3d9_dev
, allocinfo
->dwWidth
, allocinfo
->dwHeight
, 1, 0,
1537 allocinfo
->Format
, allocinfo
->Pool
, &texture
, NULL
);
1540 IDirect3DTexture9_GetSurfaceLevel(texture
, 0, &surface
[i
]);
1541 IDirect3DTexture9_Release(texture
);
1546 FIXME("Could not allocate for type %08x\n", allocinfo
->dwFlags
);
1550 if (i
>= allocinfo
->MinBuffers
)
1557 for ( ; i
> 0; --i
) IDirect3DSurface9_Release(surface
[i
- 1]);
1563 static HRESULT WINAPI
VMR9SurfaceAllocatorNotify_NotifyEvent(IVMRSurfaceAllocatorNotify9
*iface
, LONG code
, LONG_PTR param1
, LONG_PTR param2
)
1565 VMR9Impl
*This
= impl_from_IVMRSurfaceAllocatorNotify9(iface
);
1567 FIXME("(%p/%p)->(...) stub\n", iface
, This
);
1571 static const IVMRSurfaceAllocatorNotify9Vtbl IVMRSurfaceAllocatorNotify9_Vtbl
=
1573 VMR9SurfaceAllocatorNotify_QueryInterface
,
1574 VMR9SurfaceAllocatorNotify_AddRef
,
1575 VMR9SurfaceAllocatorNotify_Release
,
1576 VMR9SurfaceAllocatorNotify_AdviseSurfaceAllocator
,
1577 VMR9SurfaceAllocatorNotify_SetD3DDevice
,
1578 VMR9SurfaceAllocatorNotify_ChangeD3DDevice
,
1579 VMR9SurfaceAllocatorNotify_AllocateSurfaceHelper
,
1580 VMR9SurfaceAllocatorNotify_NotifyEvent
1583 HRESULT
VMR9Impl_create(IUnknown
* outer_unk
, LPVOID
* ppv
)
1588 TRACE("(%p, %p)\n", outer_unk
, ppv
);
1592 pVMR9
= CoTaskMemAlloc(sizeof(VMR9Impl
));
1594 pVMR9
->hD3d9
= LoadLibraryA("d3d9.dll");
1597 WARN("Could not load d3d9.dll\n");
1598 CoTaskMemFree(pVMR9
);
1599 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
1602 pVMR9
->outer_unk
= outer_unk
;
1603 pVMR9
->bUnkOuterValid
= FALSE
;
1604 pVMR9
->bAggregatable
= FALSE
;
1605 pVMR9
->IUnknown_inner
.lpVtbl
= &IInner_VTable
;
1606 pVMR9
->IAMFilterMiscFlags_iface
.lpVtbl
= &IAMFilterMiscFlags_Vtbl
;
1609 pVMR9
->allocator_d3d9_dev
= NULL
;
1610 pVMR9
->allocator_mon
= NULL
;
1611 pVMR9
->num_surfaces
= pVMR9
->cur_surface
= 0;
1612 pVMR9
->allocator
= NULL
;
1613 pVMR9
->presenter
= NULL
;
1614 pVMR9
->hWndClippingWindow
= NULL
;
1615 pVMR9
->IVMRFilterConfig9_iface
.lpVtbl
= &VMR9_FilterConfig_Vtbl
;
1616 pVMR9
->IVMRWindowlessControl9_iface
.lpVtbl
= &VMR9_WindowlessControl_Vtbl
;
1617 pVMR9
->IVMRSurfaceAllocatorNotify9_iface
.lpVtbl
= &IVMRSurfaceAllocatorNotify9_Vtbl
;
1619 hr
= BaseRenderer_Init(&pVMR9
->renderer
, &VMR9_Vtbl
, outer_unk
, &CLSID_VideoMixingRenderer9
, (DWORD_PTR
)(__FILE__
": VMR9Impl.csFilter"), &BaseFuncTable
);
1623 hr
= BaseControlWindow_Init(&pVMR9
->baseControlWindow
, &IVideoWindow_VTable
, &pVMR9
->renderer
.filter
, &pVMR9
->renderer
.filter
.csFilter
, &pVMR9
->renderer
.pInputPin
->pin
, &renderer_BaseWindowFuncTable
);
1627 hr
= BaseControlVideo_Init(&pVMR9
->baseControlVideo
, &IBasicVideo_VTable
, &pVMR9
->renderer
.filter
, &pVMR9
->renderer
.filter
.csFilter
, &pVMR9
->renderer
.pInputPin
->pin
, &renderer_BaseControlVideoFuncTable
);
1631 *ppv
= (LPVOID
)pVMR9
;
1632 ZeroMemory(&pVMR9
->source_rect
, sizeof(RECT
));
1633 ZeroMemory(&pVMR9
->target_rect
, sizeof(RECT
));
1634 TRACE("Created at %p\n", pVMR9
);
1638 BaseRendererImpl_Release(&pVMR9
->renderer
.filter
.IBaseFilter_iface
);
1639 CloseHandle(pVMR9
->hD3d9
);
1640 CoTaskMemFree(pVMR9
);
1646 static HRESULT WINAPI
VMR9_ImagePresenter_QueryInterface(IVMRImagePresenter9
*iface
, REFIID riid
, LPVOID
* ppv
)
1648 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
1649 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, qzdebugstr_guid(riid
), ppv
);
1653 if (IsEqualIID(riid
, &IID_IUnknown
))
1654 *ppv
= (LPVOID
)&(This
->IVMRImagePresenter9_iface
);
1655 else if (IsEqualIID(riid
, &IID_IVMRImagePresenter9
))
1656 *ppv
= &This
->IVMRImagePresenter9_iface
;
1657 else if (IsEqualIID(riid
, &IID_IVMRSurfaceAllocatorEx9
))
1658 *ppv
= &This
->IVMRSurfaceAllocatorEx9_iface
;
1662 IUnknown_AddRef((IUnknown
*)(*ppv
));
1666 FIXME("No interface for %s\n", debugstr_guid(riid
));
1668 return E_NOINTERFACE
;
1671 static ULONG WINAPI
VMR9_ImagePresenter_AddRef(IVMRImagePresenter9
*iface
)
1673 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
1674 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
1676 TRACE("(%p)->() AddRef from %d\n", iface
, refCount
- 1);
1681 static ULONG WINAPI
VMR9_ImagePresenter_Release(IVMRImagePresenter9
*iface
)
1683 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
1684 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
1686 TRACE("(%p)->() Release from %d\n", iface
, refCount
+ 1);
1691 TRACE("Destroying\n");
1692 CloseHandle(This
->ack
);
1693 IDirect3D9_Release(This
->d3d9_ptr
);
1695 TRACE("Number of surfaces: %u\n", This
->num_surfaces
);
1696 for (i
= 0; i
< This
->num_surfaces
; ++i
)
1698 IDirect3DSurface9
*surface
= This
->d3d9_surfaces
[i
];
1699 TRACE("Releasing surface %p\n", surface
);
1701 IDirect3DSurface9_Release(surface
);
1704 CoTaskMemFree(This
->d3d9_surfaces
);
1705 This
->d3d9_surfaces
= NULL
;
1706 This
->num_surfaces
= 0;
1707 if (This
->d3d9_vertex
)
1709 IDirect3DVertexBuffer9_Release(This
->d3d9_vertex
);
1710 This
->d3d9_vertex
= NULL
;
1712 CoTaskMemFree(This
);
1718 static HRESULT WINAPI
VMR9_ImagePresenter_StartPresenting(IVMRImagePresenter9
*iface
, DWORD_PTR id
)
1720 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
1722 TRACE("(%p/%p/%p)->(...) stub\n", iface
, This
,This
->pVMR9
);
1726 static HRESULT WINAPI
VMR9_ImagePresenter_StopPresenting(IVMRImagePresenter9
*iface
, DWORD_PTR id
)
1728 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
1730 TRACE("(%p/%p/%p)->(...) stub\n", iface
, This
,This
->pVMR9
);
1734 #define USED_FVF (D3DFVF_XYZRHW | D3DFVF_TEX1)
1735 struct VERTEX
{ float x
, y
, z
, rhw
, u
, v
; };
1737 static HRESULT
VMR9_ImagePresenter_PresentTexture(VMR9DefaultAllocatorPresenterImpl
*This
, IDirect3DSurface9
*surface
)
1739 IDirect3DTexture9
*texture
= NULL
;
1742 hr
= IDirect3DDevice9_SetFVF(This
->d3d9_dev
, USED_FVF
);
1745 FIXME("SetFVF: %08x\n", hr
);
1749 hr
= IDirect3DDevice9_SetStreamSource(This
->d3d9_dev
, 0, This
->d3d9_vertex
, 0, sizeof(struct VERTEX
));
1752 FIXME("SetStreamSource: %08x\n", hr
);
1756 hr
= IDirect3DSurface9_GetContainer(surface
, &IID_IDirect3DTexture9
, (void **) &texture
);
1759 FIXME("IDirect3DSurface9_GetContainer failed\n");
1762 hr
= IDirect3DDevice9_SetTexture(This
->d3d9_dev
, 0, (IDirect3DBaseTexture9
*)texture
);
1763 IDirect3DTexture9_Release(texture
);
1766 FIXME("SetTexture: %08x\n", hr
);
1770 hr
= IDirect3DDevice9_DrawPrimitive(This
->d3d9_dev
, D3DPT_TRIANGLESTRIP
, 0, 2);
1773 FIXME("DrawPrimitive: %08x\n", hr
);
1780 static HRESULT
VMR9_ImagePresenter_PresentOffscreenSurface(VMR9DefaultAllocatorPresenterImpl
*This
, IDirect3DSurface9
*surface
)
1783 IDirect3DSurface9
*target
= NULL
;
1786 hr
= IDirect3DDevice9_GetBackBuffer(This
->d3d9_dev
, 0, 0, D3DBACKBUFFER_TYPE_MONO
, &target
);
1789 ERR("IDirect3DDevice9_GetBackBuffer -- %08x\n", hr
);
1793 target_rect
= This
->pVMR9
->target_rect
;
1794 target_rect
.right
-= target_rect
.left
;
1795 target_rect
.bottom
-= target_rect
.top
;
1796 target_rect
.left
= target_rect
.top
= 0;
1799 target_rect
.top
= target_rect
.bottom
;
1800 target_rect
.bottom
= 0;
1802 hr
= IDirect3DDevice9_StretchRect(This
->d3d9_dev
, surface
, &This
->pVMR9
->source_rect
, target
, &target_rect
, D3DTEXF_LINEAR
);
1804 ERR("IDirect3DDevice9_StretchRect -- %08x\n", hr
);
1805 IDirect3DSurface9_Release(target
);
1810 static HRESULT WINAPI
VMR9_ImagePresenter_PresentImage(IVMRImagePresenter9
*iface
, DWORD_PTR id
, VMR9PresentationInfo
*info
)
1812 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRImagePresenter9(iface
);
1815 BOOL render
= FALSE
;
1817 TRACE("(%p/%p/%p)->(...) stub\n", iface
, This
, This
->pVMR9
);
1818 GetWindowRect(This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
, &output
);
1819 TRACE("Output rectangle: starting at %dx%d, up to point %dx%d\n", output
.left
, output
.top
, output
.right
, output
.bottom
);
1821 /* This might happen if we don't have active focus (eg on a different virtual desktop) */
1822 if (!This
->d3d9_dev
)
1825 /* Display image here */
1826 hr
= IDirect3DDevice9_Clear(This
->d3d9_dev
, 0, NULL
, D3DCLEAR_TARGET
, D3DCOLOR_XRGB(0, 0, 0), 1.0f
, 0);
1828 FIXME("hr: %08x\n", hr
);
1829 hr
= IDirect3DDevice9_BeginScene(This
->d3d9_dev
);
1832 if (This
->d3d9_vertex
)
1833 hr
= VMR9_ImagePresenter_PresentTexture(This
, info
->lpSurf
);
1835 hr
= VMR9_ImagePresenter_PresentOffscreenSurface(This
, info
->lpSurf
);
1836 render
= SUCCEEDED(hr
);
1839 FIXME("BeginScene: %08x\n", hr
);
1840 hr
= IDirect3DDevice9_EndScene(This
->d3d9_dev
);
1841 if (render
&& SUCCEEDED(hr
))
1843 hr
= IDirect3DDevice9_Present(This
->d3d9_dev
, NULL
, NULL
, This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
, NULL
);
1845 FIXME("Presenting image: %08x\n", hr
);
1851 static const IVMRImagePresenter9Vtbl VMR9_ImagePresenter
=
1853 VMR9_ImagePresenter_QueryInterface
,
1854 VMR9_ImagePresenter_AddRef
,
1855 VMR9_ImagePresenter_Release
,
1856 VMR9_ImagePresenter_StartPresenting
,
1857 VMR9_ImagePresenter_StopPresenting
,
1858 VMR9_ImagePresenter_PresentImage
1861 static HRESULT WINAPI
VMR9_SurfaceAllocator_QueryInterface(IVMRSurfaceAllocatorEx9
*iface
, REFIID riid
, LPVOID
* ppv
)
1863 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
1865 return VMR9_ImagePresenter_QueryInterface(&This
->IVMRImagePresenter9_iface
, riid
, ppv
);
1868 static ULONG WINAPI
VMR9_SurfaceAllocator_AddRef(IVMRSurfaceAllocatorEx9
*iface
)
1870 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
1872 return VMR9_ImagePresenter_AddRef(&This
->IVMRImagePresenter9_iface
);
1875 static ULONG WINAPI
VMR9_SurfaceAllocator_Release(IVMRSurfaceAllocatorEx9
*iface
)
1877 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
1879 return VMR9_ImagePresenter_Release(&This
->IVMRImagePresenter9_iface
);
1882 static HRESULT
VMR9_SurfaceAllocator_SetAllocationSettings(VMR9DefaultAllocatorPresenterImpl
*This
, VMR9AllocationInfo
*allocinfo
)
1888 if (!(allocinfo
->dwFlags
& VMR9AllocFlag_TextureSurface
))
1889 /* Only needed for texture surfaces */
1892 hr
= IDirect3DDevice9_GetDeviceCaps(This
->d3d9_dev
, &caps
);
1896 if (!(caps
.TextureCaps
& D3DPTEXTURECAPS_POW2
) || (caps
.TextureCaps
& D3DPTEXTURECAPS_SQUAREONLY
))
1898 width
= allocinfo
->dwWidth
;
1899 height
= allocinfo
->dwHeight
;
1904 while (width
< allocinfo
->dwWidth
)
1907 while (height
< allocinfo
->dwHeight
)
1909 FIXME("NPOW2 support missing, not using proper surfaces!\n");
1912 if (caps
.TextureCaps
& D3DPTEXTURECAPS_SQUAREONLY
)
1918 FIXME("Square texture support required..\n");
1921 hr
= IDirect3DDevice9_CreateVertexBuffer(This
->d3d9_dev
, 4 * sizeof(struct VERTEX
), D3DUSAGE_WRITEONLY
, USED_FVF
, allocinfo
->Pool
, &This
->d3d9_vertex
, NULL
);
1924 ERR("Couldn't create vertex buffer: %08x\n", hr
);
1929 allocinfo
->dwHeight
= height
;
1930 allocinfo
->dwWidth
= width
;
1935 static DWORD WINAPI
MessageLoop(LPVOID lpParameter
)
1939 VMR9DefaultAllocatorPresenterImpl
*This
= lpParameter
;
1941 TRACE("Starting message loop\n");
1943 if (FAILED(BaseWindowImpl_PrepareWindow(&This
->pVMR9
->baseControlWindow
.baseWindow
)))
1945 FIXME("Failed to prepare window\n");
1949 SetEvent(This
->ack
);
1950 while ((fGotMessage
= GetMessageW(&msg
, NULL
, 0, 0)) != 0 && fGotMessage
!= -1)
1952 TranslateMessage(&msg
);
1953 DispatchMessageW(&msg
);
1956 TRACE("End of message loop\n");
1961 static UINT
d3d9_adapter_from_hwnd(IDirect3D9
*d3d9
, HWND hwnd
, HMONITOR
*mon_out
)
1966 mon
= MonitorFromWindow(hwnd
, MONITOR_DEFAULTTONULL
);
1971 for (d3d9_adapter
= 0; d3d9_adapter
< IDirect3D9_GetAdapterCount(d3d9
); ++d3d9_adapter
)
1973 if (mon
== IDirect3D9_GetAdapterMonitor(d3d9
, d3d9_adapter
))
1976 if (d3d9_adapter
>= IDirect3D9_GetAdapterCount(d3d9
))
1981 return d3d9_adapter
;
1984 static BOOL
CreateRenderingWindow(VMR9DefaultAllocatorPresenterImpl
*This
, VMR9AllocationInfo
*info
, DWORD
*numbuffers
)
1986 D3DPRESENT_PARAMETERS d3dpp
;
1990 TRACE("(%p)->()\n", This
);
1992 This
->hWndThread
= CreateThread(NULL
, 0, MessageLoop
, This
, 0, &This
->tid
);
1993 if (!This
->hWndThread
)
1996 WaitForSingleObject(This
->ack
, INFINITE
);
1998 if (!This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
) return FALSE
;
2000 /* Obtain a monitor and d3d9 device */
2001 d3d9_adapter
= d3d9_adapter_from_hwnd(This
->d3d9_ptr
, This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
, &This
->hMon
);
2003 /* Now try to create the d3d9 device */
2004 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
2005 d3dpp
.Windowed
= TRUE
;
2006 d3dpp
.hDeviceWindow
= This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
;
2007 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2008 d3dpp
.BackBufferHeight
= This
->pVMR9
->target_rect
.bottom
- This
->pVMR9
->target_rect
.top
;
2009 d3dpp
.BackBufferWidth
= This
->pVMR9
->target_rect
.right
- This
->pVMR9
->target_rect
.left
;
2011 hr
= IDirect3D9_CreateDevice(This
->d3d9_ptr
, d3d9_adapter
, D3DDEVTYPE_HAL
, NULL
, D3DCREATE_MIXED_VERTEXPROCESSING
, &d3dpp
, &This
->d3d9_dev
);
2014 ERR("Could not create device: %08x\n", hr
);
2015 BaseWindowImpl_DoneWithWindow(&This
->pVMR9
->baseControlWindow
.baseWindow
);
2018 IVMRSurfaceAllocatorNotify9_SetD3DDevice(This
->SurfaceAllocatorNotify
, This
->d3d9_dev
, This
->hMon
);
2020 This
->d3d9_surfaces
= CoTaskMemAlloc(*numbuffers
* sizeof(IDirect3DSurface9
*));
2021 ZeroMemory(This
->d3d9_surfaces
, *numbuffers
* sizeof(IDirect3DSurface9
*));
2023 hr
= VMR9_SurfaceAllocator_SetAllocationSettings(This
, info
);
2025 ERR("Setting allocation settings failed: %08x\n", hr
);
2029 hr
= IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This
->SurfaceAllocatorNotify
, info
, numbuffers
, This
->d3d9_surfaces
);
2031 ERR("Allocating surfaces failed: %08x\n", hr
);
2036 IVMRSurfaceAllocatorEx9_TerminateDevice(This
->pVMR9
->allocator
, This
->pVMR9
->cookie
);
2037 BaseWindowImpl_DoneWithWindow(&This
->pVMR9
->baseControlWindow
.baseWindow
);
2041 This
->num_surfaces
= *numbuffers
;
2046 static HRESULT WINAPI
VMR9_SurfaceAllocator_InitializeDevice(IVMRSurfaceAllocatorEx9
*iface
, DWORD_PTR id
, VMR9AllocationInfo
*allocinfo
, DWORD
*numbuffers
)
2048 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
2050 if (This
->pVMR9
->mode
!= VMR9Mode_Windowed
&& !This
->pVMR9
->hWndClippingWindow
)
2052 ERR("No window set\n");
2053 return VFW_E_WRONG_STATE
;
2056 This
->info
= *allocinfo
;
2058 if (!CreateRenderingWindow(This
, allocinfo
, numbuffers
))
2060 ERR("Failed to create rendering window, expect no output!\n");
2061 return VFW_E_WRONG_STATE
;
2067 static HRESULT WINAPI
VMR9_SurfaceAllocator_TerminateDevice(IVMRSurfaceAllocatorEx9
*iface
, DWORD_PTR id
)
2069 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
2071 if (!This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
)
2076 SendMessageW(This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
, WM_CLOSE
, 0, 0);
2077 PostThreadMessageW(This
->tid
, WM_QUIT
, 0, 0);
2078 WaitForSingleObject(This
->hWndThread
, INFINITE
);
2079 This
->hWndThread
= NULL
;
2080 BaseWindowImpl_DoneWithWindow(&This
->pVMR9
->baseControlWindow
.baseWindow
);
2085 /* Recreate all surfaces (If allocated as D3DPOOL_DEFAULT) and survive! */
2086 static HRESULT
VMR9_SurfaceAllocator_UpdateDeviceReset(VMR9DefaultAllocatorPresenterImpl
*This
)
2088 struct VERTEX t_vert
[4];
2092 D3DPRESENT_PARAMETERS d3dpp
;
2095 if (!This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
)
2101 if (!This
->d3d9_surfaces
|| !This
->reset
)
2104 This
->reset
= FALSE
;
2105 TRACE("RESETTING\n");
2106 if (This
->d3d9_vertex
)
2108 IDirect3DVertexBuffer9_Release(This
->d3d9_vertex
);
2109 This
->d3d9_vertex
= NULL
;
2112 for (i
= 0; i
< This
->num_surfaces
; ++i
)
2114 IDirect3DSurface9
*surface
= This
->d3d9_surfaces
[i
];
2115 TRACE("Releasing surface %p\n", surface
);
2117 IDirect3DSurface9_Release(surface
);
2119 ZeroMemory(This
->d3d9_surfaces
, sizeof(IDirect3DSurface9
*) * This
->num_surfaces
);
2121 /* Now try to create the d3d9 device */
2122 ZeroMemory(&d3dpp
, sizeof(d3dpp
));
2123 d3dpp
.Windowed
= TRUE
;
2124 d3dpp
.hDeviceWindow
= This
->pVMR9
->baseControlWindow
.baseWindow
.hWnd
;
2125 d3dpp
.SwapEffect
= D3DSWAPEFFECT_DISCARD
;
2128 IDirect3DDevice9_Release(This
->d3d9_dev
);
2129 This
->d3d9_dev
= NULL
;
2130 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
);
2133 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
);
2136 ERR("--> Creating device: %08x\n", hr
);
2140 IVMRSurfaceAllocatorNotify9_ChangeD3DDevice(This
->SurfaceAllocatorNotify
, This
->d3d9_dev
, This
->hMon
);
2142 IVMRSurfaceAllocatorNotify9_AllocateSurfaceHelper(This
->SurfaceAllocatorNotify
, &This
->info
, &This
->num_surfaces
, This
->d3d9_surfaces
);
2144 This
->reset
= FALSE
;
2146 if (!(This
->info
.dwFlags
& VMR9AllocFlag_TextureSurface
))
2149 hr
= IDirect3DDevice9_CreateVertexBuffer(This
->d3d9_dev
, 4 * sizeof(struct VERTEX
), D3DUSAGE_WRITEONLY
, USED_FVF
,
2150 This
->info
.Pool
, &This
->d3d9_vertex
, NULL
);
2152 width
= This
->info
.dwWidth
;
2153 height
= This
->info
.dwHeight
;
2155 for (i
= 0; i
< sizeof(t_vert
) / sizeof(t_vert
[0]); ++i
)
2159 t_vert
[i
].x
= (float)This
->pVMR9
->target_rect
.right
- (float)This
->pVMR9
->target_rect
.left
- 0.5f
;
2160 t_vert
[i
].u
= (float)This
->pVMR9
->source_rect
.right
/ (float)width
;
2164 t_vert
[i
].x
= -0.5f
;
2165 t_vert
[i
].u
= (float)This
->pVMR9
->source_rect
.left
/ (float)width
;
2170 t_vert
[i
].y
= -0.5f
;
2171 t_vert
[i
].v
= (float)This
->pVMR9
->source_rect
.bottom
/ (float)height
;
2175 t_vert
[i
].y
= (float)This
->pVMR9
->target_rect
.bottom
- (float)This
->pVMR9
->target_rect
.top
- 0.5f
;
2176 t_vert
[i
].v
= (float)This
->pVMR9
->source_rect
.top
/ (float)height
;
2179 t_vert
[i
].rhw
= 1.0f
;
2182 FIXME("Vertex rectangle:\n");
2183 FIXME("X, Y: %f, %f\n", t_vert
[0].x
, t_vert
[0].y
);
2184 FIXME("X, Y: %f, %f\n", t_vert
[3].x
, t_vert
[3].y
);
2185 FIXME("TOP, LEFT: %f, %f\n", t_vert
[0].u
, t_vert
[0].v
);
2186 FIXME("DOWN, BOTTOM: %f, %f\n", t_vert
[3].u
, t_vert
[3].v
);
2188 IDirect3DVertexBuffer9_Lock(This
->d3d9_vertex
, 0, sizeof(t_vert
), &bits
, 0);
2189 memcpy(bits
, t_vert
, sizeof(t_vert
));
2190 IDirect3DVertexBuffer9_Unlock(This
->d3d9_vertex
);
2195 static HRESULT WINAPI
VMR9_SurfaceAllocator_GetSurface(IVMRSurfaceAllocatorEx9
*iface
, DWORD_PTR id
, DWORD surfaceindex
, DWORD flags
, IDirect3DSurface9
**surface
)
2197 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
2199 /* Update everything first, this is needed because the surface might be destroyed in the reset */
2200 if (!This
->d3d9_dev
)
2202 TRACE("Device has left me!\n");
2206 VMR9_SurfaceAllocator_UpdateDeviceReset(This
);
2208 if (surfaceindex
>= This
->num_surfaces
)
2210 ERR("surfaceindex is greater than num_surfaces\n");
2213 *surface
= This
->d3d9_surfaces
[surfaceindex
];
2214 IDirect3DSurface9_AddRef(*surface
);
2219 static HRESULT WINAPI
VMR9_SurfaceAllocator_AdviseNotify(IVMRSurfaceAllocatorEx9
*iface
, IVMRSurfaceAllocatorNotify9
*allocnotify
)
2221 VMR9DefaultAllocatorPresenterImpl
*This
= impl_from_IVMRSurfaceAllocatorEx9(iface
);
2223 TRACE("(%p/%p)->(...)\n", iface
, This
);
2225 /* No AddRef taken here or the base VMR9 filter would never be destroied */
2226 This
->SurfaceAllocatorNotify
= allocnotify
;
2230 static const IVMRSurfaceAllocatorEx9Vtbl VMR9_SurfaceAllocator
=
2232 VMR9_SurfaceAllocator_QueryInterface
,
2233 VMR9_SurfaceAllocator_AddRef
,
2234 VMR9_SurfaceAllocator_Release
,
2235 VMR9_SurfaceAllocator_InitializeDevice
,
2236 VMR9_SurfaceAllocator_TerminateDevice
,
2237 VMR9_SurfaceAllocator_GetSurface
,
2238 VMR9_SurfaceAllocator_AdviseNotify
,
2239 NULL
/* This isn't the SurfaceAllocatorEx type yet, working on it */
2242 static IDirect3D9
*init_d3d9(HMODULE d3d9_handle
)
2244 IDirect3D9
* (__stdcall
* d3d9_create
)(UINT SDKVersion
);
2246 d3d9_create
= (void *)GetProcAddress(d3d9_handle
, "Direct3DCreate9");
2247 if (!d3d9_create
) return NULL
;
2249 return d3d9_create(D3D_SDK_VERSION
);
2252 static HRESULT
VMR9DefaultAllocatorPresenterImpl_create(VMR9Impl
*parent
, LPVOID
* ppv
)
2256 VMR9DefaultAllocatorPresenterImpl
* This
;
2258 This
= CoTaskMemAlloc(sizeof(VMR9DefaultAllocatorPresenterImpl
));
2260 return E_OUTOFMEMORY
;
2262 This
->d3d9_ptr
= init_d3d9(parent
->hD3d9
);
2263 if (!This
->d3d9_ptr
)
2265 WARN("Could not initialize d3d9.dll\n");
2266 CoTaskMemFree(This
);
2267 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
2273 D3DDISPLAYMODE mode
;
2275 hr
= IDirect3D9_EnumAdapterModes(This
->d3d9_ptr
, i
++, D3DFMT_X8R8G8B8
, 0, &mode
);
2276 } while (FAILED(hr
));
2278 ERR("HR: %08x\n", hr
);
2279 if (hr
== D3DERR_NOTAVAILABLE
)
2281 ERR("Format not supported\n");
2282 IDirect3D9_Release(This
->d3d9_ptr
);
2283 CoTaskMemFree(This
);
2284 return VFW_E_DDRAW_CAPS_NOT_SUITABLE
;
2287 This
->IVMRImagePresenter9_iface
.lpVtbl
= &VMR9_ImagePresenter
;
2288 This
->IVMRSurfaceAllocatorEx9_iface
.lpVtbl
= &VMR9_SurfaceAllocator
;
2291 This
->pVMR9
= parent
;
2292 This
->d3d9_surfaces
= NULL
;
2293 This
->d3d9_dev
= NULL
;
2295 This
->d3d9_vertex
= NULL
;
2296 This
->num_surfaces
= 0;
2297 This
->hWndThread
= NULL
;
2298 This
->ack
= CreateEventW(NULL
, 0, 0, NULL
);
2299 This
->SurfaceAllocatorNotify
= NULL
;
2300 This
->reset
= FALSE
;