2 * Video Renderer (Fullscreen and Windowed using Direct Draw)
4 * Copyright 2004 Christian Costa
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define NONAMELESSSTRUCT
24 #define NONAMELESSUNION
25 #include "quartz_private.h"
26 #include "control_private.h"
41 #include "wine/unicode.h"
42 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(quartz
);
46 static BOOL wnd_class_registered
= FALSE
;
48 static const WCHAR wcsInputPinName
[] = {'i','n','p','u','t',' ','p','i','n',0};
50 static const IBaseFilterVtbl VideoRenderer_Vtbl
;
51 static const IUnknownVtbl IInner_VTable
;
52 static const IBasicVideoVtbl IBasicVideo_VTable
;
53 static const IVideoWindowVtbl IVideoWindow_VTable
;
54 static const IPinVtbl VideoRenderer_InputPin_Vtbl
;
55 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl
;
56 static const IQualityControlVtbl VideoRenderer_QualityControl_Vtbl
= {
57 QualityControlImpl_QueryInterface
,
58 QualityControlImpl_AddRef
,
59 QualityControlImpl_Release
,
60 QualityControlImpl_Notify
,
61 QualityControlImpl_SetSink
64 typedef struct VideoRendererImpl
67 const IBasicVideoVtbl
* IBasicVideo_vtbl
;
68 const IVideoWindowVtbl
* IVideoWindow_vtbl
;
69 const IUnknownVtbl
* IInner_vtbl
;
70 const IAMFilterMiscFlagsVtbl
*IAMFilterMiscFlags_vtbl
;
71 IUnknown
*seekthru_unk
;
72 QualityControlImpl qcimpl
;
74 BaseInputPin
*pInputPin
;
97 /* During pause we can hold a single sample, for use in GetCurrentImage */
98 IMediaSample
*sample_held
;
101 static LRESULT CALLBACK
VideoWndProcW(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
103 VideoRendererImpl
* pVideoRenderer
= (VideoRendererImpl
*)GetWindowLongPtrW(hwnd
, 0);
104 LPRECT lprect
= (LPRECT
)lParam
;
106 if (pVideoRenderer
&& pVideoRenderer
->hWndMsgDrain
)
112 case WM_LBUTTONDBLCLK
:
115 case WM_MBUTTONDBLCLK
:
118 case WM_MOUSEACTIVATE
:
120 case WM_NCLBUTTONDBLCLK
:
121 case WM_NCLBUTTONDOWN
:
123 case WM_NCMBUTTONDBLCLK
:
124 case WM_NCMBUTTONDOWN
:
127 case WM_NCRBUTTONDBLCLK
:
128 case WM_NCRBUTTONDOWN
:
130 case WM_RBUTTONDBLCLK
:
133 PostMessageW(pVideoRenderer
->hWndMsgDrain
, uMsg
, wParam
, lParam
);
143 /* TRACE("WM_SIZING %d %d %d %d\n", lprect->left, lprect->top, lprect->right, lprect->bottom); */
144 SetWindowPos(hwnd
, NULL
, lprect
->left
, lprect
->top
, lprect
->right
- lprect
->left
, lprect
->bottom
- lprect
->top
, SWP_NOZORDER
);
145 GetClientRect(hwnd
, &pVideoRenderer
->DestRect
);
146 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
147 pVideoRenderer
->DestRect
.left
,
148 pVideoRenderer
->DestRect
.top
,
149 pVideoRenderer
->DestRect
.right
- pVideoRenderer
->DestRect
.left
,
150 pVideoRenderer
->DestRect
.bottom
- pVideoRenderer
->DestRect
.top
);
153 TRACE("WM_SIZE %d %d\n", LOWORD(lParam
), HIWORD(lParam
));
154 GetClientRect(hwnd
, &pVideoRenderer
->DestRect
);
155 TRACE("WM_SIZING: DestRect=(%d,%d),(%d,%d)\n",
156 pVideoRenderer
->DestRect
.left
,
157 pVideoRenderer
->DestRect
.top
,
158 pVideoRenderer
->DestRect
.right
- pVideoRenderer
->DestRect
.left
,
159 pVideoRenderer
->DestRect
.bottom
- pVideoRenderer
->DestRect
.top
);
162 return DefWindowProcW(hwnd
, uMsg
, wParam
, lParam
);
167 static const WCHAR classnameW
[] = { 'W','i','n','e',' ','A','c','t','i','v','e','M','o','v','i','e',' ','C','l','a','s','s',0 };
168 static const WCHAR windownameW
[] = { 'A','c','t','i','v','e','M','o','v','i','e',' ','W','i','n','d','o','w',0 };
170 static BOOL
video_register_windowclass(void) {
172 if (wnd_class_registered
)
176 winclass
.lpfnWndProc
= VideoWndProcW
;
177 winclass
.cbClsExtra
= 0;
178 winclass
.cbWndExtra
= sizeof(VideoRendererImpl
*);
179 winclass
.hInstance
= NULL
;
180 winclass
.hIcon
= NULL
;
181 winclass
.hCursor
= NULL
;
182 winclass
.hbrBackground
= GetStockObject(BLACK_BRUSH
);
183 winclass
.lpszMenuName
= NULL
;
184 winclass
.lpszClassName
= classnameW
;
185 if (!RegisterClassW(&winclass
))
187 ERR("Unable to register window class: %u\n", GetLastError());
190 wnd_class_registered
= 1;
194 void video_unregister_windowclass(void) {
195 if (!wnd_class_registered
)
197 UnregisterClassW(classnameW
, NULL
);
200 static BOOL
CreateRenderingWindow(VideoRendererImpl
* This
)
202 TRACE("(%p)->()\n", This
);
203 if (!video_register_windowclass())
205 This
->hWnd
= CreateWindowExW(0, classnameW
, windownameW
, WS_SIZEBOX
,
206 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, NULL
,
211 ERR("Unable to create window\n");
215 SetWindowLongPtrW(This
->hWnd
, 0, (LONG_PTR
)This
);
220 static DWORD WINAPI
MessageLoop(LPVOID lpParameter
)
222 VideoRendererImpl
* This
= lpParameter
;
226 TRACE("Starting message loop\n");
228 if (!CreateRenderingWindow(This
))
230 This
->ThreadResult
= FALSE
;
231 SetEvent(This
->hEvent
);
235 This
->ThreadResult
= TRUE
;
236 SetEvent(This
->hEvent
);
238 while ((fGotMessage
= GetMessageW(&msg
, NULL
, 0, 0)) != 0 && fGotMessage
!= -1)
240 TranslateMessage(&msg
);
241 DispatchMessageW(&msg
);
244 TRACE("End of message loop\n");
249 static BOOL
CreateRenderingSubsystem(VideoRendererImpl
* This
)
251 This
->hEvent
= CreateEventW(NULL
, TRUE
, FALSE
, NULL
);
255 This
->hThread
= CreateThread(NULL
, 0, MessageLoop
, This
, 0, &This
->ThreadID
);
258 CloseHandle(This
->hEvent
);
262 WaitForSingleObject(This
->hEvent
, INFINITE
);
264 if (!This
->ThreadResult
)
266 CloseHandle(This
->hEvent
);
267 CloseHandle(This
->hThread
);
274 static void VideoRenderer_AutoShowWindow(VideoRendererImpl
*This
) {
275 if (!This
->init
&& (!This
->WindowPos
.right
|| !This
->WindowPos
.top
))
277 DWORD style
= GetWindowLongW(This
->hWnd
, GWL_STYLE
);
278 DWORD style_ex
= GetWindowLongW(This
->hWnd
, GWL_EXSTYLE
);
280 if (!This
->WindowPos
.right
)
282 This
->WindowPos
.left
= This
->SourceRect
.left
;
283 This
->WindowPos
.right
= This
->SourceRect
.right
;
285 if (!This
->WindowPos
.bottom
)
287 This
->WindowPos
.top
= This
->SourceRect
.top
;
288 This
->WindowPos
.bottom
= This
->SourceRect
.bottom
;
291 AdjustWindowRectEx(&This
->WindowPos
, style
, TRUE
, style_ex
);
293 TRACE("WindowPos: %d %d %d %d\n", This
->WindowPos
.left
, This
->WindowPos
.top
, This
->WindowPos
.right
, This
->WindowPos
.bottom
);
294 SetWindowPos(This
->hWnd
, NULL
,
295 This
->WindowPos
.left
,
297 This
->WindowPos
.right
- This
->WindowPos
.left
,
298 This
->WindowPos
.bottom
- This
->WindowPos
.top
,
299 SWP_NOZORDER
|SWP_NOMOVE
|SWP_DEFERERASE
);
301 GetClientRect(This
->hWnd
, &This
->DestRect
);
303 else if (!This
->init
)
304 This
->DestRect
= This
->WindowPos
;
307 ShowWindow(This
->hWnd
, SW_SHOW
);
310 static DWORD
VideoRenderer_SendSampleData(VideoRendererImpl
* This
, LPBYTE data
, DWORD size
)
316 BITMAPINFOHEADER
*bmiHeader
;
318 TRACE("(%p)->(%p, %d)\n", This
, data
, size
);
320 sdesc
.dwSize
= sizeof(sdesc
);
321 hr
= IPin_ConnectionMediaType((IPin
*)This
->pInputPin
, &amt
);
323 ERR("Unable to retrieve media type\n");
327 if (IsEqualIID(&amt
.formattype
, &FORMAT_VideoInfo
))
329 bmiHeader
= &((VIDEOINFOHEADER
*)amt
.pbFormat
)->bmiHeader
;
331 else if (IsEqualIID(&amt
.formattype
, &FORMAT_VideoInfo2
))
333 bmiHeader
= &((VIDEOINFOHEADER2
*)amt
.pbFormat
)->bmiHeader
;
337 FIXME("Unknown type %s\n", debugstr_guid(&amt
.subtype
));
338 return VFW_E_RUNTIME_ERROR
;
341 TRACE("biSize = %d\n", bmiHeader
->biSize
);
342 TRACE("biWidth = %d\n", bmiHeader
->biWidth
);
343 TRACE("biHeight = %d\n", bmiHeader
->biHeight
);
344 TRACE("biPlanes = %d\n", bmiHeader
->biPlanes
);
345 TRACE("biBitCount = %d\n", bmiHeader
->biBitCount
);
346 TRACE("biCompression = %s\n", debugstr_an((LPSTR
)&(bmiHeader
->biCompression
), 4));
347 TRACE("biSizeImage = %d\n", bmiHeader
->biSizeImage
);
349 hDC
= GetDC(This
->hWnd
);
352 ERR("Cannot get DC from window!\n");
356 TRACE("Src Rect: %d %d %d %d\n", This
->SourceRect
.left
, This
->SourceRect
.top
, This
->SourceRect
.right
, This
->SourceRect
.bottom
);
357 TRACE("Dst Rect: %d %d %d %d\n", This
->DestRect
.left
, This
->DestRect
.top
, This
->DestRect
.right
, This
->DestRect
.bottom
);
359 StretchDIBits(hDC
, This
->DestRect
.left
, This
->DestRect
.top
, This
->DestRect
.right
-This
->DestRect
.left
,
360 This
->DestRect
.bottom
- This
->DestRect
.top
, This
->SourceRect
.left
, This
->SourceRect
.top
,
361 This
->SourceRect
.right
- This
->SourceRect
.left
, This
->SourceRect
.bottom
- This
->SourceRect
.top
,
362 data
, (BITMAPINFO
*)bmiHeader
, DIB_RGB_COLORS
, SRCCOPY
);
364 ReleaseDC(This
->hWnd
, hDC
);
369 static HRESULT WINAPI
VideoRenderer_Receive(BaseInputPin
* pin
, IMediaSample
* pSample
)
371 VideoRendererImpl
*This
= (VideoRendererImpl
*)pin
->pin
.pinInfo
.pFilter
;
372 LPBYTE pbSrcStream
= NULL
;
373 LONG cbSrcStream
= 0;
374 REFERENCE_TIME tStart
, tStop
;
377 TRACE("(%p)->(%p)\n", pin
, pSample
);
379 EnterCriticalSection(&This
->filter
.csFilter
);
381 if (This
->pInputPin
->flushing
|| This
->pInputPin
->end_of_stream
)
383 LeaveCriticalSection(&This
->filter
.csFilter
);
387 if (This
->filter
.state
== State_Stopped
)
389 LeaveCriticalSection(&This
->filter
.csFilter
);
390 return VFW_E_WRONG_STATE
;
393 if (IMediaSample_GetMediaTime(pSample
, &tStart
, &tStop
) == S_OK
)
394 MediaSeekingPassThru_RegisterMediaTime(This
->seekthru_unk
, tStart
);
396 /* Preroll means the sample isn't shown, this is used for key frames and things like that */
397 if (IMediaSample_IsPreroll(pSample
) == S_OK
) {
398 LeaveCriticalSection(&This
->filter
.csFilter
);
402 hr
= IMediaSample_GetPointer(pSample
, &pbSrcStream
);
405 ERR("Cannot get pointer to sample data (%x)\n", hr
);
406 LeaveCriticalSection(&This
->filter
.csFilter
);
410 cbSrcStream
= IMediaSample_GetActualDataLength(pSample
);
412 TRACE("val %p %d\n", pbSrcStream
, cbSrcStream
);
414 #if 0 /* For debugging purpose */
417 for(i
= 0; i
< cbSrcStream
; i
++)
419 if ((i
!=0) && !(i
%16))
421 TRACE("%02x ", pbSrcStream
[i
]);
427 SetEvent(This
->hEvent
);
428 if (This
->filter
.state
== State_Paused
)
430 VideoRenderer_SendSampleData(This
, pbSrcStream
, cbSrcStream
);
431 This
->sample_held
= pSample
;
432 LeaveCriticalSection(&This
->filter
.csFilter
);
433 WaitForSingleObject(This
->blocked
, INFINITE
);
434 EnterCriticalSection(&This
->filter
.csFilter
);
435 SetEvent(This
->hEvent
);
436 This
->sample_held
= NULL
;
437 if (This
->filter
.state
== State_Paused
)
440 LeaveCriticalSection(&This
->filter
.csFilter
);
443 if (This
->filter
.state
== State_Stopped
)
445 LeaveCriticalSection(&This
->filter
.csFilter
);
446 return VFW_E_WRONG_STATE
;
449 hr
= QualityControlRender_WaitFor(&This
->qcimpl
, pSample
, This
->blocked
);
451 QualityControlRender_BeginRender(&This
->qcimpl
);
452 VideoRenderer_SendSampleData(This
, pbSrcStream
, cbSrcStream
);
453 QualityControlRender_EndRender(&This
->qcimpl
);
455 QualityControlRender_DoQOS(&This
->qcimpl
);
457 LeaveCriticalSection(&This
->filter
.csFilter
);
461 static HRESULT WINAPI
VideoRenderer_CheckMediaType(BasePin
*iface
, const AM_MEDIA_TYPE
* pmt
)
463 BaseInputPin
* pin
= (BaseInputPin
*)iface
;
464 VideoRendererImpl
*This
= (VideoRendererImpl
*)pin
->pin
.pinInfo
.pFilter
;
466 if (!IsEqualIID(&pmt
->majortype
, &MEDIATYPE_Video
))
469 if (IsEqualIID(&pmt
->subtype
, &MEDIASUBTYPE_RGB32
) ||
470 IsEqualIID(&pmt
->subtype
, &MEDIASUBTYPE_RGB24
) ||
471 IsEqualIID(&pmt
->subtype
, &MEDIASUBTYPE_RGB565
) ||
472 IsEqualIID(&pmt
->subtype
, &MEDIASUBTYPE_RGB8
))
476 if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo
))
478 VIDEOINFOHEADER
*format
= (VIDEOINFOHEADER
*)pmt
->pbFormat
;
479 This
->SourceRect
.left
= 0;
480 This
->SourceRect
.top
= 0;
481 This
->SourceRect
.right
= This
->VideoWidth
= format
->bmiHeader
.biWidth
;
482 height
= format
->bmiHeader
.biHeight
;
484 This
->SourceRect
.bottom
= This
->VideoHeight
= -height
;
486 This
->SourceRect
.bottom
= This
->VideoHeight
= height
;
488 else if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo2
))
490 VIDEOINFOHEADER2
*format2
= (VIDEOINFOHEADER2
*)pmt
->pbFormat
;
492 This
->SourceRect
.left
= 0;
493 This
->SourceRect
.top
= 0;
494 This
->SourceRect
.right
= This
->VideoWidth
= format2
->bmiHeader
.biWidth
;
495 height
= format2
->bmiHeader
.biHeight
;
497 This
->SourceRect
.bottom
= This
->VideoHeight
= -height
;
499 This
->SourceRect
.bottom
= This
->VideoHeight
= height
;
503 WARN("Format type %s not supported\n", debugstr_guid(&pmt
->formattype
));
511 static IPin
* WINAPI
VideoRenderer_GetPin(BaseFilter
*iface
, int pos
)
513 VideoRendererImpl
*This
= (VideoRendererImpl
*)iface
;
515 if (pos
>= 1 || pos
< 0)
518 IPin_AddRef((IPin
*)This
->pInputPin
);
519 return (IPin
*)This
->pInputPin
;
522 static LONG WINAPI
VideoRenderer_GetPinCount(BaseFilter
*iface
)
527 static const BaseFilterFuncTable BaseFuncTable
= {
528 VideoRenderer_GetPin
,
529 VideoRenderer_GetPinCount
532 static const BasePinFuncTable input_BaseFuncTable
= {
533 VideoRenderer_CheckMediaType
,
535 BasePinImpl_GetMediaTypeVersion
,
536 BasePinImpl_GetMediaType
539 static const BaseInputPinFuncTable input_BaseInputFuncTable
= {
540 VideoRenderer_Receive
543 HRESULT
VideoRenderer_create(IUnknown
* pUnkOuter
, LPVOID
* ppv
)
547 VideoRendererImpl
* pVideoRenderer
;
548 ISeekingPassThru
*passthru
;
550 TRACE("(%p, %p)\n", pUnkOuter
, ppv
);
554 pVideoRenderer
= CoTaskMemAlloc(sizeof(VideoRendererImpl
));
555 pVideoRenderer
->pUnkOuter
= pUnkOuter
;
556 pVideoRenderer
->bUnkOuterValid
= FALSE
;
557 pVideoRenderer
->bAggregatable
= FALSE
;
558 pVideoRenderer
->IInner_vtbl
= &IInner_VTable
;
559 pVideoRenderer
->IAMFilterMiscFlags_vtbl
= &IAMFilterMiscFlags_Vtbl
;
561 BaseFilter_Init(&pVideoRenderer
->filter
, &VideoRenderer_Vtbl
, &CLSID_VideoRenderer
, (DWORD_PTR
)(__FILE__
": VideoRendererImpl.csFilter"), &BaseFuncTable
);
563 pVideoRenderer
->IBasicVideo_vtbl
= &IBasicVideo_VTable
;
564 pVideoRenderer
->IVideoWindow_vtbl
= &IVideoWindow_VTable
;
566 pVideoRenderer
->init
= 0;
567 pVideoRenderer
->AutoShow
= 1;
568 ZeroMemory(&pVideoRenderer
->SourceRect
, sizeof(RECT
));
569 ZeroMemory(&pVideoRenderer
->DestRect
, sizeof(RECT
));
570 ZeroMemory(&pVideoRenderer
->WindowPos
, sizeof(RECT
));
571 pVideoRenderer
->hWndMsgDrain
= pVideoRenderer
->hWndOwner
= NULL
;
572 pVideoRenderer
->WindowStyle
= WS_OVERLAPPED
;
574 /* construct input pin */
575 piInput
.dir
= PINDIR_INPUT
;
576 piInput
.pFilter
= (IBaseFilter
*)pVideoRenderer
;
577 lstrcpynW(piInput
.achName
, wcsInputPinName
, sizeof(piInput
.achName
) / sizeof(piInput
.achName
[0]));
579 hr
= BaseInputPin_Construct(&VideoRenderer_InputPin_Vtbl
, &piInput
, &input_BaseFuncTable
, &input_BaseInputFuncTable
, &pVideoRenderer
->filter
.csFilter
, NULL
, (IPin
**)&pVideoRenderer
->pInputPin
);
583 hr
= CoCreateInstance(&CLSID_SeekingPassThru
, pUnkOuter
? pUnkOuter
: (IUnknown
*)&pVideoRenderer
->IInner_vtbl
, CLSCTX_INPROC_SERVER
, &IID_IUnknown
, (void**)&pVideoRenderer
->seekthru_unk
);
585 IPin_Release((IPin
*)pVideoRenderer
->pInputPin
);
588 IUnknown_QueryInterface(pVideoRenderer
->seekthru_unk
, &IID_ISeekingPassThru
, (void**)&passthru
);
589 ISeekingPassThru_Init(passthru
, TRUE
, (IPin
*)pVideoRenderer
->pInputPin
);
590 ISeekingPassThru_Release(passthru
);
591 pVideoRenderer
->sample_held
= NULL
;
592 *ppv
= pVideoRenderer
;
597 QualityControlImpl_init(&pVideoRenderer
->qcimpl
, (IPin
*)pVideoRenderer
->pInputPin
, (IBaseFilter
*)pVideoRenderer
);
598 pVideoRenderer
->qcimpl
.lpVtbl
= &VideoRenderer_QualityControl_Vtbl
;
600 if (!CreateRenderingSubsystem(pVideoRenderer
))
603 pVideoRenderer
->blocked
= CreateEventW(NULL
, FALSE
, FALSE
, NULL
);
604 if (!pVideoRenderer
->blocked
)
606 hr
= HRESULT_FROM_WIN32(GetLastError());
607 IUnknown_Release((IUnknown
*)pVideoRenderer
);
612 BaseFilterImpl_Release((IBaseFilter
*)pVideoRenderer
);
613 CoTaskMemFree(pVideoRenderer
);
617 HRESULT
VideoRendererDefault_create(IUnknown
* pUnkOuter
, LPVOID
* ppv
)
619 /* TODO: Attempt to use the VMR-7 renderer instead when possible */
620 return VideoRenderer_create(pUnkOuter
, ppv
);
623 static HRESULT WINAPI
VideoRendererInner_QueryInterface(IUnknown
* iface
, REFIID riid
, LPVOID
* ppv
)
625 ICOM_THIS_MULTI(VideoRendererImpl
, IInner_vtbl
, iface
);
626 TRACE("(%p/%p)->(%s, %p)\n", This
, iface
, qzdebugstr_guid(riid
), ppv
);
628 if (This
->bAggregatable
)
629 This
->bUnkOuterValid
= TRUE
;
633 if (IsEqualIID(riid
, &IID_IUnknown
))
634 *ppv
= &This
->IInner_vtbl
;
635 else if (IsEqualIID(riid
, &IID_IPersist
))
637 else if (IsEqualIID(riid
, &IID_IMediaFilter
))
639 else if (IsEqualIID(riid
, &IID_IBaseFilter
))
641 else if (IsEqualIID(riid
, &IID_IBasicVideo
))
642 *ppv
= &This
->IBasicVideo_vtbl
;
643 else if (IsEqualIID(riid
, &IID_IVideoWindow
))
644 *ppv
= &This
->IVideoWindow_vtbl
;
645 else if (IsEqualIID(riid
, &IID_IMediaSeeking
))
646 return IUnknown_QueryInterface(This
->seekthru_unk
, riid
, ppv
);
647 else if (IsEqualIID(riid
, &IID_IAMFilterMiscFlags
))
648 *ppv
= &This
->IAMFilterMiscFlags_vtbl
;
649 else if (IsEqualIID(riid
, &IID_IQualityControl
))
650 *ppv
= &This
->qcimpl
;
654 IUnknown_AddRef((IUnknown
*)(*ppv
));
658 if (!IsEqualIID(riid
, &IID_IPin
))
659 FIXME("No interface for %s!\n", qzdebugstr_guid(riid
));
661 return E_NOINTERFACE
;
664 static ULONG WINAPI
VideoRendererInner_AddRef(IUnknown
* iface
)
666 ICOM_THIS_MULTI(VideoRendererImpl
, IInner_vtbl
, iface
);
667 ULONG refCount
= InterlockedIncrement(&This
->filter
.refCount
);
669 TRACE("(%p/%p)->() AddRef from %d\n", This
, iface
, refCount
- 1);
674 static ULONG WINAPI
VideoRendererInner_Release(IUnknown
* iface
)
676 ICOM_THIS_MULTI(VideoRendererImpl
, IInner_vtbl
, iface
);
677 ULONG refCount
= InterlockedDecrement(&This
->filter
.refCount
);
679 TRACE("(%p/%p)->() Release from %d\n", This
, iface
, refCount
+ 1);
686 SendMessageW(This
->hWnd
, WM_CLOSE
, 0, 0);
687 PostThreadMessageW(This
->ThreadID
, WM_QUIT
, 0, 0);
688 WaitForSingleObject(This
->hThread
, INFINITE
);
689 CloseHandle(This
->hThread
);
690 CloseHandle(This
->hEvent
);
692 if (SUCCEEDED(IPin_ConnectedTo((IPin
*)This
->pInputPin
, &pConnectedTo
)))
694 IPin_Disconnect(pConnectedTo
);
695 IPin_Release(pConnectedTo
);
697 IPin_Disconnect((IPin
*)This
->pInputPin
);
699 IPin_Release((IPin
*)This
->pInputPin
);
701 This
->filter
.lpVtbl
= NULL
;
702 IUnknown_Release(This
->seekthru_unk
);
703 This
->filter
.csFilter
.DebugInfo
->Spare
[0] = 0;
704 DeleteCriticalSection(&This
->filter
.csFilter
);
706 TRACE("Destroying Video Renderer\n");
715 static const IUnknownVtbl IInner_VTable
=
717 VideoRendererInner_QueryInterface
,
718 VideoRendererInner_AddRef
,
719 VideoRendererInner_Release
722 static HRESULT WINAPI
VideoRenderer_QueryInterface(IBaseFilter
* iface
, REFIID riid
, LPVOID
* ppv
)
724 VideoRendererImpl
*This
= (VideoRendererImpl
*)iface
;
726 if (This
->bAggregatable
)
727 This
->bUnkOuterValid
= TRUE
;
731 if (This
->bAggregatable
)
732 return IUnknown_QueryInterface(This
->pUnkOuter
, riid
, ppv
);
734 if (IsEqualIID(riid
, &IID_IUnknown
))
738 IUnknown_AddRef((IUnknown
*)&(This
->IInner_vtbl
));
739 hr
= IUnknown_QueryInterface((IUnknown
*)&(This
->IInner_vtbl
), riid
, ppv
);
740 IUnknown_Release((IUnknown
*)&(This
->IInner_vtbl
));
741 This
->bAggregatable
= TRUE
;
746 return E_NOINTERFACE
;
749 return IUnknown_QueryInterface((IUnknown
*)&(This
->IInner_vtbl
), riid
, ppv
);
752 static ULONG WINAPI
VideoRenderer_AddRef(IBaseFilter
* iface
)
754 VideoRendererImpl
*This
= (VideoRendererImpl
*)iface
;
756 if (This
->pUnkOuter
&& This
->bUnkOuterValid
)
757 return IUnknown_AddRef(This
->pUnkOuter
);
758 return IUnknown_AddRef((IUnknown
*)&(This
->IInner_vtbl
));
761 static ULONG WINAPI
VideoRenderer_Release(IBaseFilter
* iface
)
763 VideoRendererImpl
*This
= (VideoRendererImpl
*)iface
;
765 if (This
->pUnkOuter
&& This
->bUnkOuterValid
)
766 return IUnknown_Release(This
->pUnkOuter
);
767 return IUnknown_Release((IUnknown
*)&(This
->IInner_vtbl
));
770 /** IMediaFilter methods **/
772 static HRESULT WINAPI
VideoRenderer_Stop(IBaseFilter
* iface
)
774 VideoRendererImpl
*This
= (VideoRendererImpl
*)iface
;
776 TRACE("(%p/%p)->()\n", This
, iface
);
778 EnterCriticalSection(&This
->filter
.csFilter
);
780 This
->filter
.state
= State_Stopped
;
781 SetEvent(This
->hEvent
);
782 SetEvent(This
->blocked
);
783 MediaSeekingPassThru_ResetMediaTime(This
->seekthru_unk
);
786 RedrawWindow(This
->hWnd
, NULL
, NULL
, RDW_INVALIDATE
|RDW_ERASE
);
788 LeaveCriticalSection(&This
->filter
.csFilter
);
793 static HRESULT WINAPI
VideoRenderer_Pause(IBaseFilter
* iface
)
795 VideoRendererImpl
*This
= (VideoRendererImpl
*)iface
;
797 TRACE("(%p/%p)->()\n", This
, iface
);
799 EnterCriticalSection(&This
->filter
.csFilter
);
800 if (This
->filter
.state
!= State_Paused
)
802 if (This
->filter
.state
== State_Stopped
)
804 This
->pInputPin
->end_of_stream
= 0;
805 ResetEvent(This
->hEvent
);
806 VideoRenderer_AutoShowWindow(This
);
809 This
->filter
.state
= State_Paused
;
810 ResetEvent(This
->blocked
);
812 LeaveCriticalSection(&This
->filter
.csFilter
);
817 static HRESULT WINAPI
VideoRenderer_SetSyncSource(IBaseFilter
*iface
, IReferenceClock
*clock
) {
818 VideoRendererImpl
*This
= (VideoRendererImpl
*)iface
;
821 EnterCriticalSection(&This
->filter
.csFilter
);
822 QualityControlRender_SetClock(&This
->qcimpl
, clock
);
823 hr
= BaseFilterImpl_SetSyncSource(iface
, clock
);
824 LeaveCriticalSection(&This
->filter
.csFilter
);
828 static HRESULT WINAPI
VideoRenderer_Run(IBaseFilter
* iface
, REFERENCE_TIME tStart
)
831 VideoRendererImpl
*This
= (VideoRendererImpl
*)iface
;
833 TRACE("(%p/%p)->(%s)\n", This
, iface
, wine_dbgstr_longlong(tStart
));
835 EnterCriticalSection(&This
->filter
.csFilter
);
836 This
->filter
.rtStreamStart
= tStart
;
837 if (This
->filter
.state
== State_Running
)
839 QualityControlRender_Start(&This
->qcimpl
, tStart
);
840 if (This
->pInputPin
->pin
.pConnectedTo
&& (This
->filter
.state
== State_Stopped
|| !This
->pInputPin
->end_of_stream
))
842 if (This
->filter
.state
== State_Stopped
)
844 ResetEvent(This
->hEvent
);
845 VideoRenderer_AutoShowWindow(This
);
846 This
->pInputPin
->end_of_stream
= 0;
848 SetEvent(This
->blocked
);
849 } else if (This
->filter
.filterInfo
.pGraph
) {
850 IMediaEventSink
*pEventSink
;
851 hr
= IFilterGraph_QueryInterface(This
->filter
.filterInfo
.pGraph
, &IID_IMediaEventSink
, (LPVOID
*)&pEventSink
);
854 hr
= IMediaEventSink_Notify(pEventSink
, EC_COMPLETE
, S_OK
, (LONG_PTR
)This
);
855 IMediaEventSink_Release(pEventSink
);
860 This
->filter
.state
= State_Running
;
862 LeaveCriticalSection(&This
->filter
.csFilter
);
867 static HRESULT WINAPI
VideoRenderer_GetState(IBaseFilter
* iface
, DWORD dwMilliSecsTimeout
, FILTER_STATE
*pState
)
869 VideoRendererImpl
*This
= (VideoRendererImpl
*)iface
;
872 TRACE("(%p/%p)->(%d, %p)\n", This
, iface
, dwMilliSecsTimeout
, pState
);
874 if (WaitForSingleObject(This
->hEvent
, dwMilliSecsTimeout
) == WAIT_TIMEOUT
)
875 hr
= VFW_S_STATE_INTERMEDIATE
;
879 BaseFilterImpl_GetState(iface
, dwMilliSecsTimeout
, pState
);
884 /** IBaseFilter implementation **/
886 static HRESULT WINAPI
VideoRenderer_FindPin(IBaseFilter
* iface
, LPCWSTR Id
, IPin
**ppPin
)
888 VideoRendererImpl
*This
= (VideoRendererImpl
*)iface
;
890 FIXME("(%p/%p)->(%p,%p): stub !!!\n", This
, iface
, debugstr_w(Id
), ppPin
);
892 /* FIXME: critical section */
897 static const IBaseFilterVtbl VideoRenderer_Vtbl
=
899 VideoRenderer_QueryInterface
,
900 VideoRenderer_AddRef
,
901 VideoRenderer_Release
,
902 BaseFilterImpl_GetClassID
,
906 VideoRenderer_GetState
,
907 VideoRenderer_SetSyncSource
,
908 BaseFilterImpl_GetSyncSource
,
909 BaseFilterImpl_EnumPins
,
910 VideoRenderer_FindPin
,
911 BaseFilterImpl_QueryFilterInfo
,
912 BaseFilterImpl_JoinFilterGraph
,
913 BaseFilterImpl_QueryVendorInfo
916 static HRESULT WINAPI
VideoRenderer_InputPin_EndOfStream(IPin
* iface
)
918 BaseInputPin
* This
= (BaseInputPin
*)iface
;
919 VideoRendererImpl
*pFilter
;
920 IMediaEventSink
* pEventSink
;
923 TRACE("(%p/%p)->()\n", This
, iface
);
925 EnterCriticalSection(This
->pin
.pCritSec
);
926 pFilter
= (VideoRendererImpl
*)This
->pin
.pinInfo
.pFilter
;
927 if (This
->flushing
|| This
->end_of_stream
)
929 hr
= IFilterGraph_QueryInterface(pFilter
->filter
.filterInfo
.pGraph
, &IID_IMediaEventSink
, (LPVOID
*)&pEventSink
);
932 hr
= IMediaEventSink_Notify(pEventSink
, EC_COMPLETE
, S_OK
, (LONG_PTR
)pFilter
);
933 IMediaEventSink_Release(pEventSink
);
935 MediaSeekingPassThru_EOS(pFilter
->seekthru_unk
);
936 This
->end_of_stream
= 1;
938 LeaveCriticalSection(This
->pin
.pCritSec
);
943 static HRESULT WINAPI
VideoRenderer_InputPin_BeginFlush(IPin
* iface
)
945 BaseInputPin
* This
= (BaseInputPin
*)iface
;
946 VideoRendererImpl
*pVideoRenderer
= (VideoRendererImpl
*)This
->pin
.pinInfo
.pFilter
;
948 TRACE("(%p/%p)->()\n", This
, iface
);
950 SetEvent(pVideoRenderer
->blocked
);
951 return BaseInputPinImpl_BeginFlush(iface
);
954 static HRESULT WINAPI
VideoRenderer_InputPin_EndFlush(IPin
* iface
)
956 BaseInputPin
* This
= (BaseInputPin
*)iface
;
957 VideoRendererImpl
*pVideoRenderer
= (VideoRendererImpl
*)This
->pin
.pinInfo
.pFilter
;
960 TRACE("(%p/%p)->()\n", This
, iface
);
962 EnterCriticalSection(This
->pin
.pCritSec
);
964 if (pVideoRenderer
->sample_held
) {
965 SetEvent(pVideoRenderer
->blocked
);
966 ResetEvent(pVideoRenderer
->hEvent
);
967 LeaveCriticalSection(This
->pin
.pCritSec
);
968 WaitForSingleObject(pVideoRenderer
->hEvent
, INFINITE
);
969 EnterCriticalSection(This
->pin
.pCritSec
);
970 ResetEvent(pVideoRenderer
->blocked
);
972 if (pVideoRenderer
->filter
.state
== State_Paused
) {
973 ResetEvent(pVideoRenderer
->blocked
);
974 ResetEvent(pVideoRenderer
->hEvent
);
977 QualityControlRender_Start(&pVideoRenderer
->qcimpl
, pVideoRenderer
->filter
.rtStreamStart
);
978 hr
= BaseInputPinImpl_EndFlush(iface
);
979 LeaveCriticalSection(This
->pin
.pCritSec
);
980 MediaSeekingPassThru_ResetMediaTime(pVideoRenderer
->seekthru_unk
);
985 static const IPinVtbl VideoRenderer_InputPin_Vtbl
=
987 BaseInputPinImpl_QueryInterface
,
989 BaseInputPinImpl_Release
,
990 BaseInputPinImpl_Connect
,
991 BaseInputPinImpl_ReceiveConnection
,
992 BasePinImpl_Disconnect
,
993 BasePinImpl_ConnectedTo
,
994 BasePinImpl_ConnectionMediaType
,
995 BasePinImpl_QueryPinInfo
,
996 BasePinImpl_QueryDirection
,
998 BaseInputPinImpl_QueryAccept
,
999 BasePinImpl_EnumMediaTypes
,
1000 BasePinImpl_QueryInternalConnections
,
1001 VideoRenderer_InputPin_EndOfStream
,
1002 VideoRenderer_InputPin_BeginFlush
,
1003 VideoRenderer_InputPin_EndFlush
,
1004 BaseInputPinImpl_NewSegment
1007 /*** IUnknown methods ***/
1008 static HRESULT WINAPI
Basicvideo_QueryInterface(IBasicVideo
*iface
,
1011 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1013 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
1015 return VideoRenderer_QueryInterface((IBaseFilter
*)This
, riid
, ppvObj
);
1018 static ULONG WINAPI
Basicvideo_AddRef(IBasicVideo
*iface
) {
1019 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1021 TRACE("(%p/%p)->()\n", This
, iface
);
1023 return VideoRenderer_AddRef((IBaseFilter
*)This
);
1026 static ULONG WINAPI
Basicvideo_Release(IBasicVideo
*iface
) {
1027 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1029 TRACE("(%p/%p)->()\n", This
, iface
);
1031 return VideoRenderer_Release((IBaseFilter
*)This
);
1034 /*** IDispatch methods ***/
1035 static HRESULT WINAPI
Basicvideo_GetTypeInfoCount(IBasicVideo
*iface
,
1037 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1039 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, pctinfo
);
1044 static HRESULT WINAPI
Basicvideo_GetTypeInfo(IBasicVideo
*iface
,
1047 ITypeInfo
**ppTInfo
) {
1048 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1050 FIXME("(%p/%p)->(%d, %d, %p): stub !!!\n", This
, iface
, iTInfo
, lcid
, ppTInfo
);
1055 static HRESULT WINAPI
Basicvideo_GetIDsOfNames(IBasicVideo
*iface
,
1061 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1063 FIXME("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This
, iface
, debugstr_guid(riid
), riid
, rgszNames
, cNames
, lcid
, rgDispId
);
1068 static HRESULT WINAPI
Basicvideo_Invoke(IBasicVideo
*iface
,
1069 DISPID dispIdMember
,
1073 DISPPARAMS
*pDispParams
,
1075 EXCEPINFO
*pExepInfo
,
1077 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1079 FIXME("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This
, iface
, dispIdMember
, debugstr_guid(riid
), riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExepInfo
, puArgErr
);
1084 /*** IBasicVideo methods ***/
1085 static HRESULT WINAPI
Basicvideo_get_AvgTimePerFrame(IBasicVideo
*iface
,
1086 REFTIME
*pAvgTimePerFrame
) {
1088 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1090 if (!This
->pInputPin
->pin
.pConnectedTo
)
1091 return VFW_E_NOT_CONNECTED
;
1093 TRACE("(%p/%p)->(%p)\n", This
, iface
, pAvgTimePerFrame
);
1095 pmt
= &This
->pInputPin
->pin
.mtCurrent
;
1096 if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo
)) {
1097 VIDEOINFOHEADER
*vih
= (VIDEOINFOHEADER
*)pmt
->pbFormat
;
1098 *pAvgTimePerFrame
= vih
->AvgTimePerFrame
;
1099 } else if (IsEqualIID(&pmt
->formattype
, &FORMAT_VideoInfo2
)) {
1100 VIDEOINFOHEADER2
*vih
= (VIDEOINFOHEADER2
*)pmt
->pbFormat
;
1101 *pAvgTimePerFrame
= vih
->AvgTimePerFrame
;
1103 ERR("Unknown format type %s\n", qzdebugstr_guid(&pmt
->formattype
));
1104 *pAvgTimePerFrame
= 0;
1109 static HRESULT WINAPI
Basicvideo_get_BitRate(IBasicVideo
*iface
,
1111 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1113 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, pBitRate
);
1118 static HRESULT WINAPI
Basicvideo_get_BitErrorRate(IBasicVideo
*iface
,
1119 LONG
*pBitErrorRate
) {
1120 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1122 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, pBitErrorRate
);
1127 static HRESULT WINAPI
Basicvideo_get_VideoWidth(IBasicVideo
*iface
,
1128 LONG
*pVideoWidth
) {
1129 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1131 TRACE("(%p/%p)->(%p)\n", This
, iface
, pVideoWidth
);
1133 *pVideoWidth
= This
->VideoWidth
;
1138 static HRESULT WINAPI
Basicvideo_get_VideoHeight(IBasicVideo
*iface
,
1139 LONG
*pVideoHeight
) {
1140 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1142 TRACE("(%p/%p)->(%p)\n", This
, iface
, pVideoHeight
);
1144 *pVideoHeight
= This
->VideoHeight
;
1149 static HRESULT WINAPI
Basicvideo_put_SourceLeft(IBasicVideo
*iface
,
1151 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1153 TRACE("(%p/%p)->(%d)\n", This
, iface
, SourceLeft
);
1155 This
->SourceRect
.left
= SourceLeft
;
1160 static HRESULT WINAPI
Basicvideo_get_SourceLeft(IBasicVideo
*iface
,
1161 LONG
*pSourceLeft
) {
1162 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1164 TRACE("(%p/%p)->(%p)\n", This
, iface
, pSourceLeft
);
1166 *pSourceLeft
= This
->SourceRect
.left
;
1171 static HRESULT WINAPI
Basicvideo_put_SourceWidth(IBasicVideo
*iface
,
1173 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1175 TRACE("(%p/%p)->(%d)\n", This
, iface
, SourceWidth
);
1177 This
->SourceRect
.right
= This
->SourceRect
.left
+ SourceWidth
;
1182 static HRESULT WINAPI
Basicvideo_get_SourceWidth(IBasicVideo
*iface
,
1183 LONG
*pSourceWidth
) {
1184 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1186 TRACE("(%p/%p)->(%p)\n", This
, iface
, pSourceWidth
);
1188 *pSourceWidth
= This
->SourceRect
.right
- This
->SourceRect
.left
;
1193 static HRESULT WINAPI
Basicvideo_put_SourceTop(IBasicVideo
*iface
,
1195 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1197 TRACE("(%p/%p)->(%d)\n", This
, iface
, SourceTop
);
1199 This
->SourceRect
.top
= SourceTop
;
1204 static HRESULT WINAPI
Basicvideo_get_SourceTop(IBasicVideo
*iface
,
1206 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1208 TRACE("(%p/%p)->(%p)\n", This
, iface
, pSourceTop
);
1210 *pSourceTop
= This
->SourceRect
.top
;
1215 static HRESULT WINAPI
Basicvideo_put_SourceHeight(IBasicVideo
*iface
,
1216 LONG SourceHeight
) {
1217 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1219 TRACE("(%p/%p)->(%d)\n", This
, iface
, SourceHeight
);
1221 This
->SourceRect
.bottom
= This
->SourceRect
.top
+ SourceHeight
;
1226 static HRESULT WINAPI
Basicvideo_get_SourceHeight(IBasicVideo
*iface
,
1227 LONG
*pSourceHeight
) {
1228 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1230 TRACE("(%p/%p)->(%p)\n", This
, iface
, pSourceHeight
);
1232 *pSourceHeight
= This
->SourceRect
.bottom
- This
->SourceRect
.top
;
1237 static HRESULT WINAPI
Basicvideo_put_DestinationLeft(IBasicVideo
*iface
,
1238 LONG DestinationLeft
) {
1239 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1241 TRACE("(%p/%p)->(%d)\n", This
, iface
, DestinationLeft
);
1243 This
->DestRect
.left
= DestinationLeft
;
1248 static HRESULT WINAPI
Basicvideo_get_DestinationLeft(IBasicVideo
*iface
,
1249 LONG
*pDestinationLeft
) {
1250 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1252 TRACE("(%p/%p)->(%p)\n", This
, iface
, pDestinationLeft
);
1254 *pDestinationLeft
= This
->DestRect
.left
;
1259 static HRESULT WINAPI
Basicvideo_put_DestinationWidth(IBasicVideo
*iface
,
1260 LONG DestinationWidth
) {
1261 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1263 TRACE("(%p/%p)->(%d)\n", This
, iface
, DestinationWidth
);
1265 This
->DestRect
.right
= This
->DestRect
.left
+ DestinationWidth
;
1270 static HRESULT WINAPI
Basicvideo_get_DestinationWidth(IBasicVideo
*iface
,
1271 LONG
*pDestinationWidth
) {
1272 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1274 TRACE("(%p/%p)->(%p)\n", This
, iface
, pDestinationWidth
);
1276 *pDestinationWidth
= This
->DestRect
.right
- This
->DestRect
.left
;
1281 static HRESULT WINAPI
Basicvideo_put_DestinationTop(IBasicVideo
*iface
,
1282 LONG DestinationTop
) {
1283 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1285 TRACE("(%p/%p)->(%d)\n", This
, iface
, DestinationTop
);
1287 This
->DestRect
.top
= DestinationTop
;
1292 static HRESULT WINAPI
Basicvideo_get_DestinationTop(IBasicVideo
*iface
,
1293 LONG
*pDestinationTop
) {
1294 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1296 TRACE("(%p/%p)->(%p)\n", This
, iface
, pDestinationTop
);
1298 *pDestinationTop
= This
->DestRect
.top
;
1303 static HRESULT WINAPI
Basicvideo_put_DestinationHeight(IBasicVideo
*iface
,
1304 LONG DestinationHeight
) {
1305 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1307 TRACE("(%p/%p)->(%d)\n", This
, iface
, DestinationHeight
);
1309 This
->DestRect
.right
= This
->DestRect
.left
+ DestinationHeight
;
1314 static HRESULT WINAPI
Basicvideo_get_DestinationHeight(IBasicVideo
*iface
,
1315 LONG
*pDestinationHeight
) {
1316 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1318 TRACE("(%p/%p)->(%p)\n", This
, iface
, pDestinationHeight
);
1320 *pDestinationHeight
= This
->DestRect
.right
- This
->DestRect
.left
;
1325 static HRESULT WINAPI
Basicvideo_SetSourcePosition(IBasicVideo
*iface
,
1330 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1332 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This
, iface
, Left
, Top
, Width
, Height
);
1334 This
->SourceRect
.left
= Left
;
1335 This
->SourceRect
.top
= Top
;
1336 This
->SourceRect
.right
= Left
+ Width
;
1337 This
->SourceRect
.bottom
= Top
+ Height
;
1342 static HRESULT WINAPI
Basicvideo_GetSourcePosition(IBasicVideo
*iface
,
1347 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1349 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This
, iface
, pLeft
, pTop
, pWidth
, pHeight
);
1351 *pLeft
= This
->SourceRect
.left
;
1352 *pTop
= This
->SourceRect
.top
;
1353 *pWidth
= This
->SourceRect
.right
- This
->SourceRect
.left
;
1354 *pHeight
= This
->SourceRect
.bottom
- This
->SourceRect
.top
;
1359 static HRESULT WINAPI
Basicvideo_SetDefaultSourcePosition(IBasicVideo
*iface
) {
1360 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1362 TRACE("(%p/%p)->()\n", This
, iface
);
1364 This
->SourceRect
.left
= 0;
1365 This
->SourceRect
.top
= 0;
1366 This
->SourceRect
.right
= This
->VideoWidth
;
1367 This
->SourceRect
.bottom
= This
->VideoHeight
;
1372 static HRESULT WINAPI
Basicvideo_SetDestinationPosition(IBasicVideo
*iface
,
1377 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1379 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This
, iface
, Left
, Top
, Width
, Height
);
1381 This
->DestRect
.left
= Left
;
1382 This
->DestRect
.top
= Top
;
1383 This
->DestRect
.right
= Left
+ Width
;
1384 This
->DestRect
.bottom
= Top
+ Height
;
1389 static HRESULT WINAPI
Basicvideo_GetDestinationPosition(IBasicVideo
*iface
,
1394 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1396 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This
, iface
, pLeft
, pTop
, pWidth
, pHeight
);
1398 *pLeft
= This
->DestRect
.left
;
1399 *pTop
= This
->DestRect
.top
;
1400 *pWidth
= This
->DestRect
.right
- This
->DestRect
.left
;
1401 *pHeight
= This
->DestRect
.bottom
- This
->DestRect
.top
;
1406 static HRESULT WINAPI
Basicvideo_SetDefaultDestinationPosition(IBasicVideo
*iface
) {
1407 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1410 TRACE("(%p/%p)->()\n", This
, iface
);
1412 if (!GetClientRect(This
->hWnd
, &rect
))
1415 This
->SourceRect
.left
= 0;
1416 This
->SourceRect
.top
= 0;
1417 This
->SourceRect
.right
= rect
.right
;
1418 This
->SourceRect
.bottom
= rect
.bottom
;
1423 static HRESULT WINAPI
Basicvideo_GetVideoSize(IBasicVideo
*iface
,
1426 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1428 TRACE("(%p/%p)->(%p, %p)\n", This
, iface
, pWidth
, pHeight
);
1430 *pWidth
= This
->VideoWidth
;
1431 *pHeight
= This
->VideoHeight
;
1436 static HRESULT WINAPI
Basicvideo_GetVideoPaletteEntries(IBasicVideo
*iface
,
1441 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1443 TRACE("(%p/%p)->(%d, %d, %p, %p)\n", This
, iface
, StartIndex
, Entries
, pRetrieved
, pPalette
);
1447 return VFW_E_NO_PALETTE_AVAILABLE
;
1450 static HRESULT WINAPI
Basicvideo_GetCurrentImage(IBasicVideo
*iface
,
1453 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1454 BITMAPINFOHEADER
*bmiHeader
;
1456 AM_MEDIA_TYPE
*amt
= &This
->pInputPin
->pin
.mtCurrent
;
1459 FIXME("(%p/%p)->(%p, %p): partial stub\n", This
, iface
, pBufferSize
, pDIBImage
);
1461 EnterCriticalSection(&This
->filter
.csFilter
);
1463 if (!This
->sample_held
)
1465 LeaveCriticalSection(&This
->filter
.csFilter
);
1466 return (This
->filter
.state
== State_Paused
? E_UNEXPECTED
: VFW_E_NOT_PAUSED
);
1469 if (IsEqualIID(&amt
->formattype
, &FORMAT_VideoInfo
))
1471 bmiHeader
= &((VIDEOINFOHEADER
*)amt
->pbFormat
)->bmiHeader
;
1473 else if (IsEqualIID(&amt
->formattype
, &FORMAT_VideoInfo2
))
1475 bmiHeader
= &((VIDEOINFOHEADER2
*)amt
->pbFormat
)->bmiHeader
;
1479 FIXME("Unknown type %s\n", debugstr_guid(&amt
->subtype
));
1480 LeaveCriticalSection(&This
->filter
.csFilter
);
1481 return VFW_E_RUNTIME_ERROR
;
1484 needed_size
= bmiHeader
->biSize
;
1485 needed_size
+= IMediaSample_GetActualDataLength(This
->sample_held
);
1489 *pBufferSize
= needed_size
;
1490 LeaveCriticalSection(&This
->filter
.csFilter
);
1494 if (needed_size
< *pBufferSize
)
1496 ERR("Buffer too small %u/%u\n", needed_size
, *pBufferSize
);
1497 LeaveCriticalSection(&This
->filter
.csFilter
);
1500 *pBufferSize
= needed_size
;
1502 memcpy(pDIBImage
, bmiHeader
, bmiHeader
->biSize
);
1503 IMediaSample_GetPointer(This
->sample_held
, (BYTE
**)&ptr
);
1504 memcpy((char *)pDIBImage
+ bmiHeader
->biSize
, ptr
, IMediaSample_GetActualDataLength(This
->sample_held
));
1506 LeaveCriticalSection(&This
->filter
.csFilter
);
1511 static HRESULT WINAPI
Basicvideo_IsUsingDefaultSource(IBasicVideo
*iface
) {
1512 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1514 FIXME("(%p/%p)->(): stub !!!\n", This
, iface
);
1519 static HRESULT WINAPI
Basicvideo_IsUsingDefaultDestination(IBasicVideo
*iface
) {
1520 ICOM_THIS_MULTI(VideoRendererImpl
, IBasicVideo_vtbl
, iface
);
1522 FIXME("(%p/%p)->(): stub !!!\n", This
, iface
);
1528 static const IBasicVideoVtbl IBasicVideo_VTable
=
1530 Basicvideo_QueryInterface
,
1533 Basicvideo_GetTypeInfoCount
,
1534 Basicvideo_GetTypeInfo
,
1535 Basicvideo_GetIDsOfNames
,
1537 Basicvideo_get_AvgTimePerFrame
,
1538 Basicvideo_get_BitRate
,
1539 Basicvideo_get_BitErrorRate
,
1540 Basicvideo_get_VideoWidth
,
1541 Basicvideo_get_VideoHeight
,
1542 Basicvideo_put_SourceLeft
,
1543 Basicvideo_get_SourceLeft
,
1544 Basicvideo_put_SourceWidth
,
1545 Basicvideo_get_SourceWidth
,
1546 Basicvideo_put_SourceTop
,
1547 Basicvideo_get_SourceTop
,
1548 Basicvideo_put_SourceHeight
,
1549 Basicvideo_get_SourceHeight
,
1550 Basicvideo_put_DestinationLeft
,
1551 Basicvideo_get_DestinationLeft
,
1552 Basicvideo_put_DestinationWidth
,
1553 Basicvideo_get_DestinationWidth
,
1554 Basicvideo_put_DestinationTop
,
1555 Basicvideo_get_DestinationTop
,
1556 Basicvideo_put_DestinationHeight
,
1557 Basicvideo_get_DestinationHeight
,
1558 Basicvideo_SetSourcePosition
,
1559 Basicvideo_GetSourcePosition
,
1560 Basicvideo_SetDefaultSourcePosition
,
1561 Basicvideo_SetDestinationPosition
,
1562 Basicvideo_GetDestinationPosition
,
1563 Basicvideo_SetDefaultDestinationPosition
,
1564 Basicvideo_GetVideoSize
,
1565 Basicvideo_GetVideoPaletteEntries
,
1566 Basicvideo_GetCurrentImage
,
1567 Basicvideo_IsUsingDefaultSource
,
1568 Basicvideo_IsUsingDefaultDestination
1572 /*** IUnknown methods ***/
1573 static HRESULT WINAPI
Videowindow_QueryInterface(IVideoWindow
*iface
,
1576 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1578 TRACE("(%p/%p)->(%s (%p), %p)\n", This
, iface
, debugstr_guid(riid
), riid
, ppvObj
);
1580 return VideoRenderer_QueryInterface((IBaseFilter
*)This
, riid
, ppvObj
);
1583 static ULONG WINAPI
Videowindow_AddRef(IVideoWindow
*iface
) {
1584 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1586 TRACE("(%p/%p)->()\n", This
, iface
);
1588 return VideoRenderer_AddRef((IBaseFilter
*)This
);
1591 static ULONG WINAPI
Videowindow_Release(IVideoWindow
*iface
) {
1592 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1594 TRACE("(%p/%p)->()\n", This
, iface
);
1596 return VideoRenderer_Release((IBaseFilter
*)This
);
1599 /*** IDispatch methods ***/
1600 static HRESULT WINAPI
Videowindow_GetTypeInfoCount(IVideoWindow
*iface
,
1602 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1604 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, pctinfo
);
1609 static HRESULT WINAPI
Videowindow_GetTypeInfo(IVideoWindow
*iface
,
1612 ITypeInfo
**ppTInfo
) {
1613 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1615 FIXME("(%p/%p)->(%d, %d, %p): stub !!!\n", This
, iface
, iTInfo
, lcid
, ppTInfo
);
1620 static HRESULT WINAPI
Videowindow_GetIDsOfNames(IVideoWindow
*iface
,
1626 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1628 FIXME("(%p/%p)->(%s (%p), %p, %d, %d, %p): stub !!!\n", This
, iface
, debugstr_guid(riid
), riid
, rgszNames
, cNames
, lcid
, rgDispId
);
1633 static HRESULT WINAPI
Videowindow_Invoke(IVideoWindow
*iface
,
1634 DISPID dispIdMember
,
1638 DISPPARAMS
*pDispParams
,
1640 EXCEPINFO
*pExepInfo
,
1642 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1644 FIXME("(%p/%p)->(%d, %s (%p), %d, %04x, %p, %p, %p, %p): stub !!!\n", This
, iface
, dispIdMember
, debugstr_guid(riid
), riid
, lcid
, wFlags
, pDispParams
, pVarResult
, pExepInfo
, puArgErr
);
1649 /*** IVideoWindow methods ***/
1650 static HRESULT WINAPI
Videowindow_put_Caption(IVideoWindow
*iface
,
1652 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1654 TRACE("(%p/%p)->(%s (%p))\n", This
, iface
, debugstr_w(strCaption
), strCaption
);
1656 if (!SetWindowTextW(This
->hWnd
, strCaption
))
1662 static HRESULT WINAPI
Videowindow_get_Caption(IVideoWindow
*iface
,
1664 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1666 TRACE("(%p/%p)->(%p)\n", This
, iface
, strCaption
);
1668 GetWindowTextW(This
->hWnd
, (LPWSTR
)strCaption
, 100);
1673 static HRESULT WINAPI
Videowindow_put_WindowStyle(IVideoWindow
*iface
,
1675 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1678 old
= GetWindowLongW(This
->hWnd
, GWL_STYLE
);
1680 TRACE("(%p/%p)->(%x -> %x)\n", This
, iface
, old
, WindowStyle
);
1682 if (WindowStyle
& (WS_DISABLED
|WS_HSCROLL
|WS_ICONIC
|WS_MAXIMIZE
|WS_MINIMIZE
|WS_VSCROLL
))
1683 return E_INVALIDARG
;
1685 SetWindowLongW(This
->hWnd
, GWL_STYLE
, WindowStyle
);
1686 SetWindowPos(This
->hWnd
,0,0,0,0,0,SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOZORDER
);
1687 This
->WindowStyle
= WindowStyle
;
1692 static HRESULT WINAPI
Videowindow_get_WindowStyle(IVideoWindow
*iface
,
1693 LONG
*WindowStyle
) {
1694 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1696 TRACE("(%p/%p)->(%p)\n", This
, iface
, WindowStyle
);
1698 *WindowStyle
= This
->WindowStyle
;
1703 static HRESULT WINAPI
Videowindow_put_WindowStyleEx(IVideoWindow
*iface
,
1704 LONG WindowStyleEx
) {
1705 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1707 TRACE("(%p/%p)->(%d)\n", This
, iface
, WindowStyleEx
);
1709 if (!SetWindowLongW(This
->hWnd
, GWL_EXSTYLE
, WindowStyleEx
))
1715 static HRESULT WINAPI
Videowindow_get_WindowStyleEx(IVideoWindow
*iface
,
1716 LONG
*WindowStyleEx
) {
1717 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1719 TRACE("(%p/%p)->(%p)\n", This
, iface
, WindowStyleEx
);
1721 *WindowStyleEx
= GetWindowLongW(This
->hWnd
, GWL_EXSTYLE
);
1726 static HRESULT WINAPI
Videowindow_put_AutoShow(IVideoWindow
*iface
,
1728 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1730 TRACE("(%p/%p)->(%d)\n", This
, iface
, AutoShow
);
1732 This
->AutoShow
= AutoShow
;
1737 static HRESULT WINAPI
Videowindow_get_AutoShow(IVideoWindow
*iface
,
1739 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1741 TRACE("(%p/%p)->(%p)\n", This
, iface
, AutoShow
);
1743 *AutoShow
= This
->AutoShow
;
1748 static HRESULT WINAPI
Videowindow_put_WindowState(IVideoWindow
*iface
,
1750 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1752 TRACE("(%p/%p)->(%d)\n", This
, iface
, WindowState
);
1753 ShowWindow(This
->hWnd
, WindowState
);
1757 static HRESULT WINAPI
Videowindow_get_WindowState(IVideoWindow
*iface
,
1758 LONG
*WindowState
) {
1759 WINDOWPLACEMENT place
;
1760 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1762 place
.length
= sizeof(place
);
1763 GetWindowPlacement(This
->hWnd
, &place
);
1764 TRACE("(%p/%p)->(%p)\n", This
, iface
, WindowState
);
1765 *WindowState
= place
.showCmd
;
1770 static HRESULT WINAPI
Videowindow_put_BackgroundPalette(IVideoWindow
*iface
,
1771 LONG BackgroundPalette
) {
1772 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1774 FIXME("(%p/%p)->(%d): stub !!!\n", This
, iface
, BackgroundPalette
);
1779 static HRESULT WINAPI
Videowindow_get_BackgroundPalette(IVideoWindow
*iface
,
1780 LONG
*pBackgroundPalette
) {
1781 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1783 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, pBackgroundPalette
);
1788 static HRESULT WINAPI
Videowindow_put_Visible(IVideoWindow
*iface
,
1790 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1792 TRACE("(%p/%p)->(%d)\n", This
, iface
, Visible
);
1794 ShowWindow(This
->hWnd
, Visible
? SW_SHOW
: SW_HIDE
);
1799 static HRESULT WINAPI
Videowindow_get_Visible(IVideoWindow
*iface
,
1801 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1803 TRACE("(%p/%p)->(%p)\n", This
, iface
, pVisible
);
1805 *pVisible
= IsWindowVisible(This
->hWnd
);
1810 static HRESULT WINAPI
Videowindow_put_Left(IVideoWindow
*iface
,
1812 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1814 TRACE("(%p/%p)->(%d)\n", This
, iface
, Left
);
1816 if (!SetWindowPos(This
->hWnd
, NULL
, Left
, This
->WindowPos
.top
, 0, 0, SWP_NOZORDER
|SWP_NOSIZE
))
1819 This
->WindowPos
.left
= Left
;
1824 static HRESULT WINAPI
Videowindow_get_Left(IVideoWindow
*iface
,
1826 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1828 TRACE("(%p/%p)->(%p)\n", This
, iface
, pLeft
);
1830 *pLeft
= This
->WindowPos
.left
;
1835 static HRESULT WINAPI
Videowindow_put_Width(IVideoWindow
*iface
,
1837 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1839 TRACE("(%p/%p)->(%d)\n", This
, iface
, Width
);
1841 if (!SetWindowPos(This
->hWnd
, NULL
, 0, 0, Width
, This
->WindowPos
.bottom
-This
->WindowPos
.top
, SWP_NOZORDER
|SWP_NOMOVE
))
1844 This
->WindowPos
.right
= This
->WindowPos
.left
+ Width
;
1849 static HRESULT WINAPI
Videowindow_get_Width(IVideoWindow
*iface
,
1851 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1853 TRACE("(%p/%p)->(%p)\n", This
, iface
, pWidth
);
1855 *pWidth
= This
->WindowPos
.right
- This
->WindowPos
.left
;
1860 static HRESULT WINAPI
Videowindow_put_Top(IVideoWindow
*iface
,
1862 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1864 TRACE("(%p/%p)->(%d)\n", This
, iface
, Top
);
1866 if (!SetWindowPos(This
->hWnd
, NULL
, This
->WindowPos
.left
, Top
, 0, 0, SWP_NOZORDER
|SWP_NOSIZE
))
1869 This
->WindowPos
.top
= Top
;
1874 static HRESULT WINAPI
Videowindow_get_Top(IVideoWindow
*iface
,
1876 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1878 TRACE("(%p/%p)->(%p)\n", This
, iface
, pTop
);
1880 *pTop
= This
->WindowPos
.top
;
1885 static HRESULT WINAPI
Videowindow_put_Height(IVideoWindow
*iface
,
1887 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1889 TRACE("(%p/%p)->(%d)\n", This
, iface
, Height
);
1891 if (!SetWindowPos(This
->hWnd
, NULL
, 0, 0, This
->WindowPos
.right
-This
->WindowPos
.left
, Height
, SWP_NOZORDER
|SWP_NOMOVE
))
1894 This
->WindowPos
.bottom
= This
->WindowPos
.top
+ Height
;
1899 static HRESULT WINAPI
Videowindow_get_Height(IVideoWindow
*iface
,
1901 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1903 TRACE("(%p/%p)->(%p)\n", This
, iface
, pHeight
);
1905 *pHeight
= This
->WindowPos
.bottom
- This
->WindowPos
.top
;
1910 static HRESULT WINAPI
Videowindow_put_Owner(IVideoWindow
*iface
,
1912 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1914 TRACE("(%p/%p)->(%08x)\n", This
, iface
, (DWORD
) Owner
);
1916 This
->hWndOwner
= (HWND
)Owner
;
1917 SetParent(This
->hWnd
, This
->hWndOwner
);
1918 if (This
->WindowStyle
& WS_CHILD
)
1920 LONG old
= GetWindowLongW(This
->hWnd
, GWL_STYLE
);
1921 if (old
!= This
->WindowStyle
)
1923 SetWindowLongW(This
->hWnd
, GWL_STYLE
, This
->WindowStyle
);
1924 SetWindowPos(This
->hWnd
,0,0,0,0,0,SWP_FRAMECHANGED
|SWP_NOSIZE
|SWP_NOZORDER
);
1931 static HRESULT WINAPI
Videowindow_get_Owner(IVideoWindow
*iface
,
1933 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1935 TRACE("(%p/%p)->(%p)\n", This
, iface
, Owner
);
1937 *(HWND
*)Owner
= This
->hWndOwner
;
1942 static HRESULT WINAPI
Videowindow_put_MessageDrain(IVideoWindow
*iface
,
1944 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1946 TRACE("(%p/%p)->(%08x)\n", This
, iface
, (DWORD
) Drain
);
1948 This
->hWndMsgDrain
= (HWND
)Drain
;
1953 static HRESULT WINAPI
Videowindow_get_MessageDrain(IVideoWindow
*iface
,
1955 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1957 TRACE("(%p/%p)->(%p)\n", This
, iface
, Drain
);
1959 *Drain
= (OAHWND
)This
->hWndMsgDrain
;
1964 static HRESULT WINAPI
Videowindow_get_BorderColor(IVideoWindow
*iface
,
1966 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1968 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, Color
);
1973 static HRESULT WINAPI
Videowindow_put_BorderColor(IVideoWindow
*iface
,
1975 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1977 FIXME("(%p/%p)->(%d): stub !!!\n", This
, iface
, Color
);
1982 static HRESULT WINAPI
Videowindow_get_FullScreenMode(IVideoWindow
*iface
,
1983 LONG
*FullScreenMode
) {
1984 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1986 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, FullScreenMode
);
1991 static HRESULT WINAPI
Videowindow_put_FullScreenMode(IVideoWindow
*iface
,
1992 LONG FullScreenMode
) {
1993 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
1995 FIXME("(%p/%p)->(%d): stub !!!\n", This
, iface
, FullScreenMode
);
1997 if (FullScreenMode
) {
1998 ShowWindow(This
->hWnd
, SW_HIDE
);
1999 SetParent(This
->hWnd
, 0);
2000 SetWindowLongW(This
->hWnd
, GWL_STYLE
, WS_POPUP
);
2001 SetWindowPos(This
->hWnd
,HWND_TOP
,0,0,GetSystemMetrics(SM_CXSCREEN
),GetSystemMetrics(SM_CYSCREEN
),SWP_SHOWWINDOW
);
2002 GetWindowRect(This
->hWnd
, &This
->DestRect
);
2003 This
->WindowPos
= This
->DestRect
;
2005 ShowWindow(This
->hWnd
, SW_HIDE
);
2006 SetParent(This
->hWnd
, This
->hWndOwner
);
2007 SetWindowLongW(This
->hWnd
, GWL_STYLE
, This
->WindowStyle
);
2008 GetClientRect(This
->hWnd
, &This
->DestRect
);
2009 SetWindowPos(This
->hWnd
,0,This
->DestRect
.left
,This
->DestRect
.top
,This
->DestRect
.right
,This
->DestRect
.bottom
,SWP_NOZORDER
|SWP_SHOWWINDOW
);
2010 This
->WindowPos
= This
->DestRect
;
2016 static HRESULT WINAPI
Videowindow_SetWindowForeground(IVideoWindow
*iface
,
2018 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
2023 TRACE("(%p/%p)->(%d)\n", This
, iface
, Focus
);
2025 if ((Focus
!= FALSE
) && (Focus
!= TRUE
))
2026 return E_INVALIDARG
;
2028 hr
= IPin_ConnectedTo((IPin
*)This
->pInputPin
, &pPin
);
2029 if ((hr
!= S_OK
) || !pPin
)
2030 return VFW_E_NOT_CONNECTED
;
2033 ret
= SetForegroundWindow(This
->hWnd
);
2035 ret
= SetWindowPos(This
->hWnd
, HWND_TOP
, 0, 0, 0, 0, SWP_NOMOVE
|SWP_NOSIZE
);
2043 static HRESULT WINAPI
Videowindow_NotifyOwnerMessage(IVideoWindow
*iface
,
2048 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
2050 TRACE("(%p/%p)->(%08lx, %d, %08lx, %08lx)\n", This
, iface
, hwnd
, uMsg
, wParam
, lParam
);
2052 if (!PostMessageW(This
->hWnd
, uMsg
, wParam
, lParam
))
2058 static HRESULT WINAPI
Videowindow_SetWindowPosition(IVideoWindow
*iface
,
2063 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
2065 TRACE("(%p/%p)->(%d, %d, %d, %d)\n", This
, iface
, Left
, Top
, Width
, Height
);
2067 if (!SetWindowPos(This
->hWnd
, NULL
, Left
, Top
, Width
, Height
, SWP_NOZORDER
))
2070 This
->WindowPos
.left
= Left
;
2071 This
->WindowPos
.top
= Top
;
2072 This
->WindowPos
.right
= Left
+ Width
;
2073 This
->WindowPos
.bottom
= Top
+ Height
;
2078 static HRESULT WINAPI
Videowindow_GetWindowPosition(IVideoWindow
*iface
,
2083 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
2085 TRACE("(%p/%p)->(%p, %p, %p, %p)\n", This
, iface
, pLeft
, pTop
, pWidth
, pHeight
);
2087 *pLeft
= This
->WindowPos
.left
;
2088 *pTop
= This
->WindowPos
.top
;
2089 *pWidth
= This
->WindowPos
.right
- This
->WindowPos
.left
;
2090 *pHeight
= This
->WindowPos
.bottom
- This
->WindowPos
.top
;
2095 static HRESULT WINAPI
Videowindow_GetMinIdealImageSize(IVideoWindow
*iface
,
2098 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
2100 FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This
, iface
, pWidth
, pHeight
);
2102 *pWidth
= This
->VideoWidth
;
2103 *pHeight
= This
->VideoHeight
;
2108 static HRESULT WINAPI
Videowindow_GetMaxIdealImageSize(IVideoWindow
*iface
,
2111 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
2113 FIXME("(%p/%p)->(%p, %p): semi stub !!!\n", This
, iface
, pWidth
, pHeight
);
2115 *pWidth
= This
->VideoWidth
;
2116 *pHeight
= This
->VideoHeight
;
2121 static HRESULT WINAPI
Videowindow_GetRestorePosition(IVideoWindow
*iface
,
2126 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
2128 FIXME("(%p/%p)->(%p, %p, %p, %p): stub !!!\n", This
, iface
, pLeft
, pTop
, pWidth
, pHeight
);
2133 static HRESULT WINAPI
Videowindow_HideCursor(IVideoWindow
*iface
,
2135 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
2137 FIXME("(%p/%p)->(%d): stub !!!\n", This
, iface
, HideCursor
);
2142 static HRESULT WINAPI
Videowindow_IsCursorHidden(IVideoWindow
*iface
,
2143 LONG
*CursorHidden
) {
2144 ICOM_THIS_MULTI(VideoRendererImpl
, IVideoWindow_vtbl
, iface
);
2146 FIXME("(%p/%p)->(%p): stub !!!\n", This
, iface
, CursorHidden
);
2151 static const IVideoWindowVtbl IVideoWindow_VTable
=
2153 Videowindow_QueryInterface
,
2155 Videowindow_Release
,
2156 Videowindow_GetTypeInfoCount
,
2157 Videowindow_GetTypeInfo
,
2158 Videowindow_GetIDsOfNames
,
2160 Videowindow_put_Caption
,
2161 Videowindow_get_Caption
,
2162 Videowindow_put_WindowStyle
,
2163 Videowindow_get_WindowStyle
,
2164 Videowindow_put_WindowStyleEx
,
2165 Videowindow_get_WindowStyleEx
,
2166 Videowindow_put_AutoShow
,
2167 Videowindow_get_AutoShow
,
2168 Videowindow_put_WindowState
,
2169 Videowindow_get_WindowState
,
2170 Videowindow_put_BackgroundPalette
,
2171 Videowindow_get_BackgroundPalette
,
2172 Videowindow_put_Visible
,
2173 Videowindow_get_Visible
,
2174 Videowindow_put_Left
,
2175 Videowindow_get_Left
,
2176 Videowindow_put_Width
,
2177 Videowindow_get_Width
,
2178 Videowindow_put_Top
,
2179 Videowindow_get_Top
,
2180 Videowindow_put_Height
,
2181 Videowindow_get_Height
,
2182 Videowindow_put_Owner
,
2183 Videowindow_get_Owner
,
2184 Videowindow_put_MessageDrain
,
2185 Videowindow_get_MessageDrain
,
2186 Videowindow_get_BorderColor
,
2187 Videowindow_put_BorderColor
,
2188 Videowindow_get_FullScreenMode
,
2189 Videowindow_put_FullScreenMode
,
2190 Videowindow_SetWindowForeground
,
2191 Videowindow_NotifyOwnerMessage
,
2192 Videowindow_SetWindowPosition
,
2193 Videowindow_GetWindowPosition
,
2194 Videowindow_GetMinIdealImageSize
,
2195 Videowindow_GetMaxIdealImageSize
,
2196 Videowindow_GetRestorePosition
,
2197 Videowindow_HideCursor
,
2198 Videowindow_IsCursorHidden
2201 static VideoRendererImpl
*from_IAMFilterMiscFlags(IAMFilterMiscFlags
*iface
) {
2202 return (VideoRendererImpl
*)((char*)iface
- offsetof(VideoRendererImpl
, IAMFilterMiscFlags_vtbl
));
2205 static HRESULT WINAPI
AMFilterMiscFlags_QueryInterface(IAMFilterMiscFlags
*iface
, REFIID riid
, void **ppv
) {
2206 VideoRendererImpl
*This
= from_IAMFilterMiscFlags(iface
);
2207 return IUnknown_QueryInterface((IUnknown
*)This
, riid
, ppv
);
2210 static ULONG WINAPI
AMFilterMiscFlags_AddRef(IAMFilterMiscFlags
*iface
) {
2211 VideoRendererImpl
*This
= from_IAMFilterMiscFlags(iface
);
2212 return IUnknown_AddRef((IUnknown
*)This
);
2215 static ULONG WINAPI
AMFilterMiscFlags_Release(IAMFilterMiscFlags
*iface
) {
2216 VideoRendererImpl
*This
= from_IAMFilterMiscFlags(iface
);
2217 return IUnknown_Release((IUnknown
*)This
);
2220 static ULONG WINAPI
AMFilterMiscFlags_GetMiscFlags(IAMFilterMiscFlags
*iface
) {
2221 return AM_FILTER_MISC_FLAGS_IS_RENDERER
;
2224 static const IAMFilterMiscFlagsVtbl IAMFilterMiscFlags_Vtbl
= {
2225 AMFilterMiscFlags_QueryInterface
,
2226 AMFilterMiscFlags_AddRef
,
2227 AMFilterMiscFlags_Release
,
2228 AMFilterMiscFlags_GetMiscFlags